Merge "Add fingerprint strings" into sc-dev
diff --git a/Android.bp b/Android.bp
index ee5e992..4f0559b 100644
--- a/Android.bp
+++ b/Android.bp
@@ -401,6 +401,13 @@
         ":platform-compat-native-aidl",
 
         // AIDL sources from external directories
+        ":android.hardware.security.keymint-V1-java-source",
+        ":android.hardware.security.secureclock-V1-java-source",
+        ":android.security.apc-java-source",
+        ":android.security.authorization-java-source",
+        ":android.security.maintenance-java-source",
+        ":android.security.vpnprofilestore-java-source",
+        ":android.system.keystore2-V1-java-source",
         ":credstore_aidl",
         ":dumpstate_aidl",
         ":framework_native_aidl",
@@ -417,6 +424,7 @@
         ":libbluetooth-binder-aidl",
         ":libcamera_client_aidl",
         ":libcamera_client_framework_aidl",
+        ":packagemanager_aidl",
         ":libupdate_engine_aidl",
         ":resourcemanager_aidl",
         ":storaged_aidl",
@@ -458,6 +466,7 @@
     static_libs: [
         "android.net.ipsec.ike.stubs.module_lib",
         "framework-appsearch.stubs.module_lib",
+        "framework-connectivity.stubs.module_lib",
         "framework-graphics.stubs.module_lib",
         "framework-media.stubs.module_lib",
         "framework-mediaprovider.stubs.module_lib",
@@ -480,6 +489,7 @@
         "android.net.ipsec.ike.impl",
         "framework-minus-apex",
         "framework-appsearch.impl",
+        "framework-connectivity.impl",
         "framework-graphics.impl",
         "framework-mediaprovider.impl",
         "framework-permission.impl",
@@ -500,15 +510,6 @@
     ],
 }
 
-filegroup {
-    name: "framework-all-sources",
-    srcs: [
-        ":framework-mime-sources",
-        ":framework-non-updatable-sources",
-        ":framework-updatable-sources",
-    ],
-}
-
 // AIDL files under these paths are mixture of public and private ones.
 // They shouldn't be exported across module boundaries.
 java_defaults {
@@ -582,13 +583,7 @@
         "android.hardware.vibrator-V1.2-java",
         "android.hardware.vibrator-V1.3-java",
         "android.hardware.vibrator-V2-java",
-        "android.security.apc-java",
-        "android.security.authorization-java",
-        "android.security.maintenance-java",
-        "android.security.vpnprofilestore-java",
-        "android.system.keystore2-V1-java",
         "android.system.suspend.control.internal-java",
-        "cameraprotosnano",
         "devicepolicyprotosnano",
 
         "com.android.sysprop.apex",
@@ -642,14 +637,17 @@
     defaults: ["framework-aidl-export-defaults"],
     srcs: [
         ":framework-non-updatable-sources",
-        ":framework-connectivity-sources",
         "core/java/**/*.logtags",
     ],
     // See comment on framework-atb-backward-compatibility module below
     exclude_srcs: ["core/java/android/content/pm/AndroidTestBaseUpdater.java"],
     aidl: {
         generate_get_transaction_name: true,
-        local_include_dirs: ["media/aidl"],
+        local_include_dirs: [
+            "media/aidl",
+            // TODO: move to include_dirs when migrated to packages/modules
+            "packages/Connectivity/framework/aidl-export",
+        ],
         include_dirs: ["frameworks/av/aidl"],
     },
     dxflags: [
@@ -668,7 +666,6 @@
         // TODO: remove gps_debug and protolog.conf.json when the build system propagates "required" properly.
         "gps_debug.conf",
         "icu4j-platform-compat-config",
-        "libcore-platform-compat-config",
         "protolog.conf.json.gz",
         "services-platform-compat-config",
         "documents-ui-compat-config",
@@ -703,8 +700,6 @@
     apex_available: ["//apex_available:platform"],
     visibility: [
         "//frameworks/base",
-        // TODO: remove when framework-connectivity can build against API
-        "//frameworks/base/packages/Connectivity/framework",
         // TODO(b/147128803) remove the below lines
         "//frameworks/base/apex/appsearch/framework",
         "//frameworks/base/apex/blobstore/framework",
@@ -743,6 +738,7 @@
     static_libs: [
         "app-compat-annotations",
         "framework-minus-apex",
+        "framework-connectivity.impl", // TODO(b/182859030): should be removed
         "framework-appsearch.impl", // TODO(b/146218515): should be removed
         "framework-updatable-stubs-module_libs_api",
     ],
@@ -854,10 +850,14 @@
     srcs: [
         "core/java/android/annotation/AnyThread.java",
         "core/java/android/annotation/AppIdInt.java",
-        "core/java/android/annotation/CallSuper.java",
+        "core/java/android/annotation/BytesLong.java",
         "core/java/android/annotation/CallbackExecutor.java",
+        "core/java/android/annotation/CallSuper.java",
         "core/java/android/annotation/CheckResult.java",
         "core/java/android/annotation/CurrentTimeMillisLong.java",
+        "core/java/android/annotation/CurrentTimeSecondsLong.java",
+        "core/java/android/annotation/DrawableRes.java",
+        "core/java/android/annotation/DurationMillisLong.java",
         "core/java/android/annotation/Hide.java",
         "core/java/android/annotation/IntDef.java",
         "core/java/android/annotation/IntRange.java",
@@ -875,8 +875,8 @@
         "core/java/android/annotation/UserIdInt.java",
         "core/java/android/annotation/WorkerThread.java",
         "core/java/com/android/internal/annotations/GuardedBy.java",
-        "core/java/com/android/internal/annotations/VisibleForTesting.java",
         "core/java/com/android/internal/annotations/Immutable.java",
+        "core/java/com/android/internal/annotations/VisibleForTesting.java",
     ],
 }
 
@@ -890,7 +890,6 @@
     name: "framework-ike-shared-srcs",
     visibility: ["//packages/modules/IPsec"],
     srcs: [
-        "core/java/android/annotation/StringDef.java",
         "core/java/android/net/annotations/PolicyDirection.java",
         "core/java/com/android/internal/util/HexDump.java",
         "core/java/com/android/internal/util/IState.java",
@@ -1364,36 +1363,6 @@
     ],
 }
 
-filegroup {
-    name: "framework-media-annotation-srcs",
-    srcs: [
-        ":framework-annotations",
-        "core/java/android/annotation/CallbackExecutor.java",
-        "core/java/android/annotation/CallSuper.java",
-        "core/java/android/annotation/DrawableRes.java",
-        "core/java/android/annotation/LongDef.java",
-        "core/java/android/annotation/StringDef.java",
-    ],
-}
-
-filegroup {
-    name: "framework-mediaprovider-annotation-sources",
-    srcs: [
-        ":framework-annotations",
-        "core/java/android/annotation/BytesLong.java",
-        "core/java/android/annotation/CurrentTimeSecondsLong.java",
-        "core/java/android/annotation/DurationMillisLong.java",
-    ],
-}
-
-// Creates an index of AIDL methods; used for adding UnsupportedAppUsage
-// annotations to private apis
-aidl_mapping {
-    name: "framework-aidl-mappings",
-    srcs: [":framework-all-sources"],
-    output: "framework-aidl-mappings.txt",
-}
-
 // Avoid including Parcelable classes as we don't want to have two copies of
 // Parcelable cross the libraries. This is used by telephony-common (frameworks/opt/telephony)
 // and TeleService app (packages/services/Telephony).
@@ -1461,7 +1430,7 @@
     ],
     libs: [
         "framework-annotations-lib",
-        "framework-connectivity",
+        "framework-connectivity.stubs.module_lib",
         "unsupportedappusage",
     ],
     visibility: [
diff --git a/StubLibraries.bp b/StubLibraries.bp
index c61f7c6..9b43749 100644
--- a/StubLibraries.bp
+++ b/StubLibraries.bp
@@ -449,6 +449,7 @@
         "core/java/android/os/RemoteException.java",
         "core/java/android/util/AndroidException.java",
     ],
+    libs: ["framework-annotations-lib"],
     installable: false,
     sdk_version: "core_platform",
     annotations_enabled: true,
@@ -462,7 +463,7 @@
 java_library_static {
     name: "hwbinder.stubs",
     sdk_version: "core_current",
-    libs: ["stub-annotations"],
+    libs: ["framework-annotations-lib"],
     srcs: [
         ":hwbinder-stubs-docs",
     ],
diff --git a/apex/appsearch/framework/api/current.txt b/apex/appsearch/framework/api/current.txt
index e08d22c..5acfe6a 100644
--- a/apex/appsearch/framework/api/current.txt
+++ b/apex/appsearch/framework/api/current.txt
@@ -8,6 +8,14 @@
     method public boolean isSuccess();
   }
 
+  public static final class AppSearchBatchResult.Builder<KeyType, ValueType> {
+    ctor public AppSearchBatchResult.Builder();
+    method @NonNull public android.app.appsearch.AppSearchBatchResult<KeyType,ValueType> build();
+    method @NonNull public android.app.appsearch.AppSearchBatchResult.Builder<KeyType,ValueType> setFailure(@NonNull KeyType, int, @Nullable String);
+    method @NonNull public android.app.appsearch.AppSearchBatchResult.Builder<KeyType,ValueType> setResult(@NonNull KeyType, @NonNull android.app.appsearch.AppSearchResult<ValueType>);
+    method @NonNull public android.app.appsearch.AppSearchBatchResult.Builder<KeyType,ValueType> setSuccess(@NonNull KeyType, @Nullable ValueType);
+  }
+
   public class AppSearchManager {
     method public void createGlobalSearchSession(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.appsearch.AppSearchResult<android.app.appsearch.GlobalSearchSession>>);
     method public void createSearchSession(@NonNull android.app.appsearch.AppSearchManager.SearchContext, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.appsearch.AppSearchResult<android.app.appsearch.AppSearchSession>>);
@@ -18,10 +26,8 @@
   }
 
   public static final class AppSearchManager.SearchContext.Builder {
-    ctor @Deprecated public AppSearchManager.SearchContext.Builder();
     ctor public AppSearchManager.SearchContext.Builder(@NonNull String);
     method @NonNull public android.app.appsearch.AppSearchManager.SearchContext build();
-    method @Deprecated @NonNull public android.app.appsearch.AppSearchManager.SearchContext.Builder setDatabaseName(@NonNull String);
   }
 
   public final class AppSearchResult<ValueType> {
@@ -29,6 +35,8 @@
     method public int getResultCode();
     method @Nullable public ValueType getResultValue();
     method public boolean isSuccess();
+    method @NonNull public static <ValueType> android.app.appsearch.AppSearchResult<ValueType> newFailedResult(int, @Nullable String);
+    method @NonNull public static <ValueType> android.app.appsearch.AppSearchResult<ValueType> newSuccessfulResult(@Nullable ValueType);
     field public static final int RESULT_INTERNAL_ERROR = 2; // 0x2
     field public static final int RESULT_INVALID_ARGUMENT = 3; // 0x3
     field public static final int RESULT_INVALID_SCHEMA = 7; // 0x7
@@ -36,13 +44,13 @@
     field public static final int RESULT_NOT_FOUND = 6; // 0x6
     field public static final int RESULT_OK = 0; // 0x0
     field public static final int RESULT_OUT_OF_SPACE = 5; // 0x5
+    field public static final int RESULT_SECURITY_ERROR = 8; // 0x8
     field public static final int RESULT_UNKNOWN_ERROR = 1; // 0x1
   }
 
   public final class AppSearchSchema {
     method @NonNull public java.util.List<android.app.appsearch.AppSearchSchema.PropertyConfig> getProperties();
     method @NonNull public String getSchemaType();
-    method @IntRange(from=0) public int getVersion();
   }
 
   public static final class AppSearchSchema.BooleanPropertyConfig extends android.app.appsearch.AppSearchSchema.PropertyConfig {
@@ -58,7 +66,6 @@
     ctor public AppSearchSchema.Builder(@NonNull String);
     method @NonNull public android.app.appsearch.AppSearchSchema.Builder addProperty(@NonNull android.app.appsearch.AppSearchSchema.PropertyConfig);
     method @NonNull public android.app.appsearch.AppSearchSchema build();
-    method @NonNull public android.app.appsearch.AppSearchSchema.Builder setVersion(@IntRange(from=0) int);
   }
 
   public static final class AppSearchSchema.BytesPropertyConfig extends android.app.appsearch.AppSearchSchema.PropertyConfig {
@@ -130,13 +137,15 @@
   public final class AppSearchSession implements java.io.Closeable {
     method public void close();
     method public void getByUri(@NonNull android.app.appsearch.GetByUriRequest, @NonNull java.util.concurrent.Executor, @NonNull android.app.appsearch.BatchResultCallback<java.lang.String,android.app.appsearch.GenericDocument>);
-    method public void getSchema(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.appsearch.AppSearchResult<java.util.Set<android.app.appsearch.AppSearchSchema>>>);
+    method public void getNamespaces(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.appsearch.AppSearchResult<java.util.Set<java.lang.String>>>);
+    method public void getSchema(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.appsearch.AppSearchResult<android.app.appsearch.GetSchemaResponse>>);
+    method public void getStorageInfo(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.appsearch.AppSearchResult<android.app.appsearch.StorageInfo>>);
     method public void put(@NonNull android.app.appsearch.PutDocumentsRequest, @NonNull java.util.concurrent.Executor, @NonNull android.app.appsearch.BatchResultCallback<java.lang.String,java.lang.Void>);
     method public void remove(@NonNull android.app.appsearch.RemoveByUriRequest, @NonNull java.util.concurrent.Executor, @NonNull android.app.appsearch.BatchResultCallback<java.lang.String,java.lang.Void>);
     method public void remove(@NonNull String, @NonNull android.app.appsearch.SearchSpec, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.appsearch.AppSearchResult<java.lang.Void>>);
     method public void reportUsage(@NonNull android.app.appsearch.ReportUsageRequest, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.appsearch.AppSearchResult<java.lang.Void>>);
     method @NonNull public android.app.appsearch.SearchResults search(@NonNull String, @NonNull android.app.appsearch.SearchSpec);
-    method public void setSchema(@NonNull android.app.appsearch.SetSchemaRequest, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.appsearch.AppSearchResult<android.app.appsearch.SetSchemaResponse>>);
+    method public void setSchema(@NonNull android.app.appsearch.SetSchemaRequest, @NonNull java.util.concurrent.Executor, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.appsearch.AppSearchResult<android.app.appsearch.SetSchemaResponse>>);
   }
 
   public interface BatchResultCallback<KeyType, ValueType> {
@@ -167,15 +176,12 @@
     method public int getScore();
     method public long getTtlMillis();
     method @NonNull public String getUri();
-    field @Deprecated public static final String DEFAULT_NAMESPACE = "";
   }
 
   public static class GenericDocument.Builder<BuilderType extends android.app.appsearch.GenericDocument.Builder> {
-    ctor @Deprecated public GenericDocument.Builder(@NonNull String, @NonNull String);
     ctor public GenericDocument.Builder(@NonNull String, @NonNull String, @NonNull String);
     method @NonNull public android.app.appsearch.GenericDocument build();
     method @NonNull public BuilderType setCreationTimestampMillis(long);
-    method @Deprecated @NonNull public BuilderType setNamespace(@NonNull String);
     method @NonNull public BuilderType setPropertyBoolean(@NonNull String, @NonNull boolean...);
     method @NonNull public BuilderType setPropertyBytes(@NonNull String, @NonNull byte[]...);
     method @NonNull public BuilderType setPropertyDocument(@NonNull String, @NonNull android.app.appsearch.GenericDocument...);
@@ -194,25 +200,36 @@
   }
 
   public static final class GetByUriRequest.Builder {
-    ctor @Deprecated public GetByUriRequest.Builder();
     ctor public GetByUriRequest.Builder(@NonNull String);
     method @NonNull public android.app.appsearch.GetByUriRequest.Builder addProjection(@NonNull String, @NonNull java.util.Collection<java.lang.String>);
     method @NonNull public android.app.appsearch.GetByUriRequest.Builder addUris(@NonNull java.lang.String...);
     method @NonNull public android.app.appsearch.GetByUriRequest.Builder addUris(@NonNull java.util.Collection<java.lang.String>);
     method @NonNull public android.app.appsearch.GetByUriRequest build();
-    method @Deprecated @NonNull public android.app.appsearch.GetByUriRequest.Builder setNamespace(@NonNull String);
+  }
+
+  public class GetSchemaResponse {
+    method @NonNull public java.util.Set<android.app.appsearch.AppSearchSchema> getSchemas();
+    method @IntRange(from=0) public int getVersion();
+  }
+
+  public static final class GetSchemaResponse.Builder {
+    ctor public GetSchemaResponse.Builder();
+    method @NonNull public android.app.appsearch.GetSchemaResponse.Builder addSchema(@NonNull android.app.appsearch.AppSearchSchema);
+    method @NonNull public android.app.appsearch.GetSchemaResponse build();
+    method @NonNull public android.app.appsearch.GetSchemaResponse.Builder setVersion(@IntRange(from=0) int);
   }
 
   public class GlobalSearchSession implements java.io.Closeable {
     method public void close();
+    method public void reportSystemUsage(@NonNull android.app.appsearch.ReportSystemUsageRequest, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.appsearch.AppSearchResult<java.lang.Void>>);
     method @NonNull public android.app.appsearch.SearchResults search(@NonNull String, @NonNull android.app.appsearch.SearchSpec);
   }
 
   public abstract class Migrator {
     ctor public Migrator();
-    ctor public Migrator(int);
     method @NonNull @WorkerThread public abstract android.app.appsearch.GenericDocument onDowngrade(int, int, @NonNull android.app.appsearch.GenericDocument);
     method @NonNull @WorkerThread public abstract android.app.appsearch.GenericDocument onUpgrade(int, int, @NonNull android.app.appsearch.GenericDocument);
+    method public abstract boolean shouldMigrate(int, int);
   }
 
   public class PackageIdentifier {
@@ -238,12 +255,25 @@
   }
 
   public static final class RemoveByUriRequest.Builder {
-    ctor @Deprecated public RemoveByUriRequest.Builder();
     ctor public RemoveByUriRequest.Builder(@NonNull String);
     method @NonNull public android.app.appsearch.RemoveByUriRequest.Builder addUris(@NonNull java.lang.String...);
     method @NonNull public android.app.appsearch.RemoveByUriRequest.Builder addUris(@NonNull java.util.Collection<java.lang.String>);
     method @NonNull public android.app.appsearch.RemoveByUriRequest build();
-    method @Deprecated @NonNull public android.app.appsearch.RemoveByUriRequest.Builder setNamespace(@NonNull String);
+  }
+
+  public final class ReportSystemUsageRequest {
+    method @NonNull public String getDatabaseName();
+    method @NonNull public String getNamespace();
+    method @NonNull public String getPackageName();
+    method @NonNull public String getUri();
+    method public long getUsageTimeMillis();
+  }
+
+  public static final class ReportSystemUsageRequest.Builder {
+    ctor public ReportSystemUsageRequest.Builder(@NonNull String, @NonNull String, @NonNull String);
+    method @NonNull public android.app.appsearch.ReportSystemUsageRequest build();
+    method @NonNull public android.app.appsearch.ReportSystemUsageRequest.Builder setUri(@NonNull String);
+    method @NonNull public android.app.appsearch.ReportSystemUsageRequest.Builder setUsageTimeMillis(long);
   }
 
   public final class ReportUsageRequest {
@@ -253,20 +283,18 @@
   }
 
   public static final class ReportUsageRequest.Builder {
-    ctor @Deprecated public ReportUsageRequest.Builder();
     ctor public ReportUsageRequest.Builder(@NonNull String);
     method @NonNull public android.app.appsearch.ReportUsageRequest build();
-    method @Deprecated @NonNull public android.app.appsearch.ReportUsageRequest.Builder setNamespace(@NonNull String);
     method @NonNull public android.app.appsearch.ReportUsageRequest.Builder setUri(@NonNull String);
     method @NonNull public android.app.appsearch.ReportUsageRequest.Builder setUsageTimeMillis(long);
   }
 
   public final class SearchResult {
     method @NonNull public String getDatabaseName();
-    method @Deprecated @NonNull public android.app.appsearch.GenericDocument getDocument();
     method @NonNull public android.app.appsearch.GenericDocument getGenericDocument();
     method @NonNull public java.util.List<android.app.appsearch.SearchResult.MatchInfo> getMatches();
     method @NonNull public String getPackageName();
+    method public double getRankingSignal();
   }
 
   public static final class SearchResult.Builder {
@@ -274,16 +302,15 @@
     method @NonNull public android.app.appsearch.SearchResult.Builder addMatch(@NonNull android.app.appsearch.SearchResult.MatchInfo);
     method @NonNull public android.app.appsearch.SearchResult build();
     method @NonNull public android.app.appsearch.SearchResult.Builder setGenericDocument(@NonNull android.app.appsearch.GenericDocument);
+    method @NonNull public android.app.appsearch.SearchResult.Builder setRankingSignal(double);
   }
 
   public static final class SearchResult.MatchInfo {
     method @NonNull public CharSequence getExactMatch();
-    method @Deprecated @NonNull public android.app.appsearch.SearchResult.MatchRange getExactMatchPosition();
     method @NonNull public android.app.appsearch.SearchResult.MatchRange getExactMatchRange();
     method @NonNull public String getFullText();
     method @NonNull public String getPropertyPath();
     method @NonNull public CharSequence getSnippet();
-    method @Deprecated @NonNull public android.app.appsearch.SearchResult.MatchRange getSnippetPosition();
     method @NonNull public android.app.appsearch.SearchResult.MatchRange getSnippetRange();
   }
 
@@ -315,9 +342,13 @@
     method @NonNull public java.util.Map<java.lang.String,java.util.List<java.lang.String>> getProjections();
     method public int getRankingStrategy();
     method public int getResultCountPerPage();
+    method public int getResultGroupingLimit();
+    method public int getResultGroupingTypeFlags();
     method public int getSnippetCount();
     method public int getSnippetCountPerProperty();
     method public int getTermMatch();
+    field public static final int GROUPING_TYPE_PER_NAMESPACE = 2; // 0x2
+    field public static final int GROUPING_TYPE_PER_PACKAGE = 1; // 0x1
     field public static final int ORDER_ASCENDING = 1; // 0x1
     field public static final int ORDER_DESCENDING = 0; // 0x0
     field public static final String PROJECTION_SCHEMA_TYPE_WILDCARD = "*";
@@ -325,6 +356,8 @@
     field public static final int RANKING_STRATEGY_DOCUMENT_SCORE = 1; // 0x1
     field public static final int RANKING_STRATEGY_NONE = 0; // 0x0
     field public static final int RANKING_STRATEGY_RELEVANCE_SCORE = 3; // 0x3
+    field public static final int RANKING_STRATEGY_SYSTEM_USAGE_COUNT = 6; // 0x6
+    field public static final int RANKING_STRATEGY_SYSTEM_USAGE_LAST_USED_TIMESTAMP = 7; // 0x7
     field public static final int RANKING_STRATEGY_USAGE_COUNT = 4; // 0x4
     field public static final int RANKING_STRATEGY_USAGE_LAST_USED_TIMESTAMP = 5; // 0x5
     field public static final int TERM_MATCH_EXACT_ONLY = 1; // 0x1
@@ -345,6 +378,7 @@
     method @NonNull public android.app.appsearch.SearchSpec.Builder setOrder(int);
     method @NonNull public android.app.appsearch.SearchSpec.Builder setRankingStrategy(int);
     method @NonNull public android.app.appsearch.SearchSpec.Builder setResultCountPerPage(@IntRange(from=0, to=android.app.appsearch.SearchSpec.MAX_NUM_PER_PAGE) int);
+    method @NonNull public android.app.appsearch.SearchSpec.Builder setResultGrouping(int, int);
     method @NonNull public android.app.appsearch.SearchSpec.Builder setSnippetCount(@IntRange(from=0, to=android.app.appsearch.SearchSpec.MAX_SNIPPET_COUNT) int);
     method @NonNull public android.app.appsearch.SearchSpec.Builder setSnippetCountPerProperty(@IntRange(from=0, to=android.app.appsearch.SearchSpec.MAX_SNIPPET_PER_PROPERTY_COUNT) int);
     method @NonNull public android.app.appsearch.SearchSpec.Builder setTermMatch(int);
@@ -354,8 +388,8 @@
     method @NonNull public java.util.Map<java.lang.String,android.app.appsearch.Migrator> getMigrators();
     method @NonNull public java.util.Set<android.app.appsearch.AppSearchSchema> getSchemas();
     method @NonNull public java.util.Set<java.lang.String> getSchemasNotDisplayedBySystem();
-    method @Deprecated @NonNull public java.util.Set<java.lang.String> getSchemasNotVisibleToSystemUi();
     method @NonNull public java.util.Map<java.lang.String,java.util.Set<android.app.appsearch.PackageIdentifier>> getSchemasVisibleToPackages();
+    method @IntRange(from=1) public int getVersion();
     method public boolean isForceOverride();
   }
 
@@ -366,9 +400,10 @@
     method @NonNull public android.app.appsearch.SetSchemaRequest build();
     method @NonNull public android.app.appsearch.SetSchemaRequest.Builder setForceOverride(boolean);
     method @NonNull public android.app.appsearch.SetSchemaRequest.Builder setMigrator(@NonNull String, @NonNull android.app.appsearch.Migrator);
+    method @NonNull public android.app.appsearch.SetSchemaRequest.Builder setMigrators(@NonNull java.util.Map<java.lang.String,android.app.appsearch.Migrator>);
     method @NonNull public android.app.appsearch.SetSchemaRequest.Builder setSchemaTypeDisplayedBySystem(@NonNull String, boolean);
     method @NonNull public android.app.appsearch.SetSchemaRequest.Builder setSchemaTypeVisibilityForPackage(@NonNull String, boolean, @NonNull android.app.appsearch.PackageIdentifier);
-    method @Deprecated @NonNull public android.app.appsearch.SetSchemaRequest.Builder setSchemaTypeVisibilityForSystemUi(@NonNull String, boolean);
+    method @NonNull public android.app.appsearch.SetSchemaRequest.Builder setVersion(@IntRange(from=1) int);
   }
 
   public class SetSchemaResponse {
@@ -407,6 +442,20 @@
     method @NonNull public android.app.appsearch.SetSchemaResponse.MigrationFailure.Builder setUri(@NonNull String);
   }
 
+  public class StorageInfo {
+    method public int getAliveDocumentsCount();
+    method public int getAliveNamespacesCount();
+    method public long getSizeBytes();
+  }
+
+  public static final class StorageInfo.Builder {
+    ctor public StorageInfo.Builder();
+    method @NonNull public android.app.appsearch.StorageInfo build();
+    method @NonNull public android.app.appsearch.StorageInfo.Builder setAliveDocumentsCount(int);
+    method @NonNull public android.app.appsearch.StorageInfo.Builder setAliveNamespacesCount(int);
+    method @NonNull public android.app.appsearch.StorageInfo.Builder setSizeBytes(long);
+  }
+
 }
 
 package android.app.appsearch.exceptions {
diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchBatchResult.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchBatchResult.java
index 31ab259..35cea3e 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/AppSearchBatchResult.java
+++ b/apex/appsearch/framework/java/android/app/appsearch/AppSearchBatchResult.java
@@ -30,10 +30,10 @@
 /**
  * Provides results for AppSearch batch operations which encompass multiple documents.
  *
- * <p>Individual results of a batch operation are separated into two maps: one for successes and one
- * for failures. For successes, {@link #getSuccesses()} will return a map of keys to instances of
- * the value type. For failures, {@link #getFailures()} will return a map of keys to {@link
- * AppSearchResult} objects.
+ * <p>Individual results of a batch operation are separated into two maps: one for successes and
+ * one for failures. For successes, {@link #getSuccesses()} will return a map of keys to
+ * instances of the value type. For failures, {@link #getFailures()} will return a map of keys to
+ * {@link AppSearchResult} objects.
  *
  * <p>Alternatively, {@link #getAll()} returns a map of keys to {@link AppSearchResult} objects for
  * both successes and failures.
@@ -97,8 +97,8 @@
     }
 
     /**
-     * Returns a {@link Map} of keys mapped to instances of {@link AppSearchResult} for all failed
-     * individual results.
+     * Returns a {@link Map} of keys mapped to instances of {@link AppSearchResult} for all
+     * failed individual results.
      *
      * <p>The values of the {@link Map} will not be {@code null}.
      */
@@ -120,7 +120,6 @@
 
     /**
      * Asserts that this {@link AppSearchBatchResult} has no failures.
-     *
      * @hide
      */
     public void checkSuccess() {
@@ -162,8 +161,6 @@
      * Builder for {@link AppSearchBatchResult} objects.
      *
      * <p>Once {@link #build} is called, the instance can no longer be used.
-     *
-     * @hide
      */
     public static final class Builder<KeyType, ValueType> {
         private final Map<KeyType, ValueType> mSuccesses = new ArrayMap<>();
@@ -178,6 +175,7 @@
          *
          * @throws IllegalStateException if the builder has already been used.
          */
+        @SuppressWarnings("MissingGetterMatchingBuilder")  // See getSuccesses
         @NonNull
         public Builder<KeyType, ValueType> setSuccess(
                 @NonNull KeyType key, @Nullable ValueType result) {
@@ -193,6 +191,7 @@
          *
          * @throws IllegalStateException if the builder has already been used.
          */
+        @SuppressWarnings("MissingGetterMatchingBuilder")  // See getFailures
         @NonNull
         public Builder<KeyType, ValueType> setFailure(
                 @NonNull KeyType key,
@@ -210,6 +209,7 @@
          *
          * @throws IllegalStateException if the builder has already been used.
          */
+        @SuppressWarnings("MissingGetterMatchingBuilder")  // See getAll
         @NonNull
         public Builder<KeyType, ValueType> setResult(
                 @NonNull KeyType key, @NonNull AppSearchResult<ValueType> result) {
diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java
index 0c6b86b..9776827 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java
+++ b/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java
@@ -147,22 +147,10 @@
 
         /** Builder for {@link SearchContext} objects. */
         public static final class Builder {
-            private String mDatabaseName;
+            private final String mDatabaseName;
             private boolean mBuilt = false;
 
             /**
-             * TODO(b/181887768): This method exists only for dogfooder transition and must be
-             * removed.
-             *
-             * @deprecated Please supply the databaseName in {@link #Builder(String)} instead. This
-             *     method exists only for dogfooder transition and must be removed.
-             */
-            @Deprecated
-            public Builder() {
-                mDatabaseName = "";
-            }
-
-            /**
              * Creates a new {@link SearchContext.Builder}.
              *
              * <p>{@link AppSearchSession} will create or open a database under the given name.
@@ -182,37 +170,6 @@
                 mDatabaseName = databaseName;
             }
 
-            /**
-             * Sets the name of the database associated with {@link AppSearchSession}.
-             *
-             * <p>{@link AppSearchSession} will create or open a database under the given name.
-             *
-             * <p>Databases with different names are fully separate with distinct types, namespaces,
-             * and data.
-             *
-             * <p>Database name cannot contain {@code '/'}.
-             *
-             * <p>If not specified, defaults to the empty string.
-             *
-             * <p>TODO(b/181887768): This method exists only for dogfooder transition and must be
-             * removed.
-             *
-             * @param databaseName The name of the database.
-             * @throws IllegalArgumentException if the databaseName contains {@code '/'}.
-             * @deprecated Please supply the databaseName in {@link #Builder(String)} instead. This
-             *     method exists only for dogfooder transition and must be removed.
-             */
-            @Deprecated
-            @NonNull
-            public Builder setDatabaseName(@NonNull String databaseName) {
-                Preconditions.checkState(!mBuilt, "Builder has already been used");
-                Objects.requireNonNull(databaseName);
-                Preconditions.checkArgument(
-                        !databaseName.contains("/"), "Database name cannot contain '/'");
-                mDatabaseName = databaseName;
-                return this;
-            }
-
             /** Builds a {@link SearchContext} instance. */
             @NonNull
             public SearchContext build() {
diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchMigrationHelper.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchMigrationHelper.java
new file mode 100644
index 0000000..e585d91
--- /dev/null
+++ b/apex/appsearch/framework/java/android/app/appsearch/AppSearchMigrationHelper.java
@@ -0,0 +1,256 @@
+/*
+ * 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 android.app.appsearch;
+
+import static android.os.ParcelFileDescriptor.MODE_READ_ONLY;
+import static android.os.ParcelFileDescriptor.MODE_WRITE_ONLY;
+
+import android.annotation.NonNull;
+import android.annotation.UserIdInt;
+import android.annotation.WorkerThread;
+import android.app.appsearch.exceptions.AppSearchException;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+
+import com.android.internal.infra.AndroidFuture;
+
+import java.io.Closeable;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.EOFException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.ExecutionException;
+
+/**
+ * The helper class for {@link AppSearchSchema} migration.
+ *
+ * <p>It will query and migrate {@link GenericDocument} in given type to a new version.
+ * @hide
+ */
+public class AppSearchMigrationHelper implements Closeable {
+    private final IAppSearchManager mService;
+    private final String mPackageName;
+    private final String mDatabaseName;
+    private final int mUserId;
+    private final File mMigratedFile;
+    private final Map<String, Integer> mCurrentVersionMap;
+    private final Map<String, Integer> mFinalVersionMap;
+    private boolean mAreDocumentsMigrated = false;
+
+    AppSearchMigrationHelper(@NonNull IAppSearchManager service,
+            @UserIdInt int userId,
+            @NonNull Map<String, Integer> currentVersionMap,
+            @NonNull Map<String, Integer> finalVersionMap,
+            @NonNull String packageName,
+            @NonNull String databaseName) throws IOException {
+        mService = Objects.requireNonNull(service);
+        mCurrentVersionMap = Objects.requireNonNull(currentVersionMap);
+        mFinalVersionMap = Objects.requireNonNull(finalVersionMap);
+        mPackageName = Objects.requireNonNull(packageName);
+        mDatabaseName = Objects.requireNonNull(databaseName);
+        mUserId = userId;
+        mMigratedFile = File.createTempFile(/*prefix=*/"appsearch", /*suffix=*/null);
+    }
+
+    /**
+     * Queries all documents that need to be migrated to a different version and transform
+     * documents to that version by passing them to the provided {@link Migrator}.
+     *
+     * <p>The method will be executed on the executor provided to
+     * {@link AppSearchSession#setSchema}.
+     *
+     * @param schemaType The schema type that needs to be updated and whose {@link GenericDocument}
+     *                   need to be migrated.
+     * @param migrator The {@link Migrator} that will upgrade or downgrade a {@link
+     *     GenericDocument} to new version.
+     */
+    @WorkerThread
+    public void queryAndTransform(@NonNull String schemaType, @NonNull Migrator migrator)
+            throws IOException, AppSearchException, InterruptedException, ExecutionException {
+        File queryFile = File.createTempFile(/*prefix=*/"appsearch", /*suffix=*/null);
+        try (ParcelFileDescriptor fileDescriptor =
+                     ParcelFileDescriptor.open(queryFile, MODE_WRITE_ONLY)) {
+            AndroidFuture<AppSearchResult<Void>> androidFuture = new AndroidFuture<>();
+            mService.writeQueryResultsToFile(mPackageName, mDatabaseName,
+                    fileDescriptor,
+                    /*queryExpression=*/ "",
+                    new SearchSpec.Builder()
+                            .addFilterSchemas(schemaType)
+                            .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
+                            .build().getBundle(),
+                    mUserId,
+                    new IAppSearchResultCallback.Stub() {
+                        @Override
+                        public void onResult(AppSearchResult result) throws RemoteException {
+                            androidFuture.complete(result);
+                        }
+                    });
+            AppSearchResult<Void> result = androidFuture.get();
+            if (!result.isSuccess()) {
+                throw new AppSearchException(result.getResultCode(), result.getErrorMessage());
+            }
+            readAndTransform(queryFile, migrator);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        } finally {
+            queryFile.delete();
+        }
+    }
+
+    /**
+     * Puts all {@link GenericDocument} migrated from the previous call to
+     * {@link #queryAndTransform} into AppSearch.
+     *
+     * <p> This method should be only called once.
+     *
+     * @param responseBuilder a SetSchemaResponse builder whose result will be returned by this
+     *                        function with any
+     *                        {@link android.app.appsearch.SetSchemaResponse.MigrationFailure}
+     *                        added in.
+     * @return the {@link SetSchemaResponse} for {@link AppSearchSession#setSchema} call.
+     */
+    @NonNull
+    AppSearchResult<SetSchemaResponse> putMigratedDocuments(
+            @NonNull SetSchemaResponse.Builder responseBuilder) {
+        if (!mAreDocumentsMigrated) {
+            return AppSearchResult.newSuccessfulResult(responseBuilder.build());
+        }
+        try (ParcelFileDescriptor fileDescriptor =
+                     ParcelFileDescriptor.open(mMigratedFile, MODE_READ_ONLY)) {
+            AndroidFuture<AppSearchResult<List<Bundle>>> androidFuture = new AndroidFuture<>();
+            mService.putDocumentsFromFile(mPackageName, mDatabaseName, fileDescriptor, mUserId,
+                    new IAppSearchResultCallback.Stub() {
+                        @Override
+                        public void onResult(AppSearchResult result) throws RemoteException {
+                            androidFuture.complete(result);
+                        }
+                    });
+            AppSearchResult<List<Bundle>> result = androidFuture.get();
+            if (!result.isSuccess()) {
+                return AppSearchResult.newFailedResult(result);
+            }
+            List<Bundle> migratedFailureBundles = result.getResultValue();
+            for (int i = 0; i < migratedFailureBundles.size(); i++) {
+                responseBuilder.addMigrationFailure(
+                        new SetSchemaResponse.MigrationFailure(migratedFailureBundles.get(i)));
+            }
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        } catch (Throwable t) {
+            return AppSearchResult.throwableToFailedResult(t);
+        } finally {
+            mMigratedFile.delete();
+        }
+        return AppSearchResult.newSuccessfulResult(responseBuilder.build());
+    }
+
+    /**
+     * Reads all saved {@link GenericDocument}s from the given {@link File}.
+     *
+     * <p>Transforms those {@link GenericDocument}s to the final version.
+     *
+     * <p>Save migrated {@link GenericDocument}s to the {@link #mMigratedFile}.
+     */
+    private void readAndTransform(@NonNull File file, @NonNull Migrator migrator)
+            throws IOException {
+        try (DataInputStream inputStream = new DataInputStream(new FileInputStream(file));
+             DataOutputStream outputStream = new DataOutputStream(new FileOutputStream(
+                     mMigratedFile, /*append=*/ true))) {
+            GenericDocument document;
+            while (true) {
+                try {
+                    document = readDocumentFromInputStream(inputStream);
+                } catch (EOFException e) {
+                    break;
+                    // Nothing wrong. We just finished reading.
+                }
+
+                int currentVersion = mCurrentVersionMap.get(document.getSchemaType());
+                int finalVersion = mFinalVersionMap.get(document.getSchemaType());
+
+                GenericDocument newDocument;
+                if (currentVersion < finalVersion) {
+                    newDocument = migrator.onUpgrade(currentVersion, finalVersion, document);
+                } else {
+                    // currentVersion == finalVersion case won't trigger migration and get here.
+                    newDocument = migrator.onDowngrade(currentVersion, finalVersion, document);
+                }
+                writeBundleToOutputStream(outputStream, newDocument.getBundle());
+            }
+            mAreDocumentsMigrated = true;
+        }
+    }
+
+    /**
+     * Reads the {@link Bundle} of a {@link GenericDocument} from given {@link DataInputStream}.
+     *
+     * @param inputStream The inputStream to read from
+     *
+     * @throws IOException        on read failure.
+     * @throws EOFException       if {@link java.io.InputStream} reaches the end.
+     */
+    @NonNull
+    public static GenericDocument readDocumentFromInputStream(
+            @NonNull DataInputStream inputStream) throws IOException {
+        int length = inputStream.readInt();
+        if (length == 0) {
+            throw new EOFException();
+        }
+        byte[] serializedMessage = new byte[length];
+        inputStream.read(serializedMessage);
+
+        Parcel parcel = Parcel.obtain();
+        try {
+            parcel.unmarshall(serializedMessage, 0, serializedMessage.length);
+            parcel.setDataPosition(0);
+            Bundle bundle = parcel.readBundle();
+            return new GenericDocument(bundle);
+        } finally {
+            parcel.recycle();
+        }
+    }
+
+    /**
+     * Serializes a {@link Bundle} and writes into the given {@link DataOutputStream}.
+     */
+    public static void writeBundleToOutputStream(
+            @NonNull DataOutputStream outputStream, @NonNull Bundle bundle)
+            throws IOException {
+        Parcel parcel = Parcel.obtain();
+        try {
+            parcel.writeBundle(bundle);
+            byte[] serializedMessage = parcel.marshall();
+            outputStream.writeInt(serializedMessage.length);
+            outputStream.write(serializedMessage);
+        } finally {
+            parcel.recycle();
+        }
+    }
+
+    @Override
+    public void close() throws IOException {
+        mMigratedFile.delete();
+    }
+}
diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchResult.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchResult.java
index 440f633..b66837d 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/AppSearchResult.java
+++ b/apex/appsearch/framework/java/android/app/appsearch/AppSearchResult.java
@@ -24,6 +24,8 @@
 import android.os.Parcelable;
 import android.util.Log;
 
+import com.android.internal.util.Preconditions;
+
 import java.io.IOException;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -37,20 +39,19 @@
 public final class AppSearchResult<ValueType> implements Parcelable {
     /**
      * Result codes from {@link AppSearchSession} methods.
-     *
      * @hide
      */
-    @IntDef(
-            value = {
-                RESULT_OK,
-                RESULT_UNKNOWN_ERROR,
-                RESULT_INTERNAL_ERROR,
-                RESULT_INVALID_ARGUMENT,
-                RESULT_IO_ERROR,
-                RESULT_OUT_OF_SPACE,
-                RESULT_NOT_FOUND,
-                RESULT_INVALID_SCHEMA,
-            })
+    @IntDef(value = {
+            RESULT_OK,
+            RESULT_UNKNOWN_ERROR,
+            RESULT_INTERNAL_ERROR,
+            RESULT_INVALID_ARGUMENT,
+            RESULT_IO_ERROR,
+            RESULT_OUT_OF_SPACE,
+            RESULT_NOT_FOUND,
+            RESULT_INVALID_SCHEMA,
+            RESULT_SECURITY_ERROR,
+    })
     @Retention(RetentionPolicy.SOURCE)
     public @interface ResultCode {}
 
@@ -90,6 +91,9 @@
     /** The caller supplied a schema which is invalid or incompatible with the previous schema. */
     public static final int RESULT_INVALID_SCHEMA = 7;
 
+    /** The caller requested an operation it does not have privileges for. */
+    public static final int RESULT_SECURITY_ERROR = 8;
+
     private final @ResultCode int mResultCode;
     @Nullable private final ValueType mResultValue;
     @Nullable private final String mErrorMessage;
@@ -148,8 +152,8 @@
      *
      * <p>If {@link #isSuccess} is {@code true}, the error message is always {@code null}. The error
      * message may be {@code null} even if {@link #isSuccess} is {@code false}. See the
-     * documentation of the particular {@link AppSearchSession} call producing this {@link
-     * AppSearchResult} for what is returned by {@link #getErrorMessage}.
+     * documentation of the particular {@link AppSearchSession} call producing this
+     * {@link AppSearchResult} for what is returned by {@link #getErrorMessage}.
      */
     @Nullable
     public String getErrorMessage() {
@@ -208,8 +212,6 @@
 
     /**
      * Creates a new successful {@link AppSearchResult}.
-     *
-     * @hide
      */
     @NonNull
     public static <ValueType> AppSearchResult<ValueType> newSuccessfulResult(
@@ -219,8 +221,6 @@
 
     /**
      * Creates a new failed {@link AppSearchResult}.
-     *
-     * @hide
      */
     @NonNull
     public static <ValueType> AppSearchResult<ValueType> newFailedResult(
@@ -228,6 +228,20 @@
         return new AppSearchResult<>(resultCode, /*resultValue=*/ null, errorMessage);
     }
 
+    /**
+     * Creates a new failed {@link AppSearchResult} by a AppSearchResult in another type.
+     *
+     * @hide
+     */
+    @NonNull
+    public static <ValueType> AppSearchResult<ValueType> newFailedResult(
+            @NonNull AppSearchResult<?> otherFailedResult) {
+        Preconditions.checkState(!otherFailedResult.isSuccess(),
+                "Cannot convert a success result to a failed result");
+        return AppSearchResult.newFailedResult(
+                otherFailedResult.getResultCode(), otherFailedResult.getErrorMessage());
+    }
+
     /** @hide */
     @NonNull
     public static <ValueType> AppSearchResult<ValueType> throwableToFailedResult(
diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java
index 9ea73a9..4dd1b79 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java
+++ b/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java
@@ -19,6 +19,8 @@
 import android.annotation.CallbackExecutor;
 import android.annotation.NonNull;
 import android.annotation.UserIdInt;
+import android.app.appsearch.exceptions.AppSearchException;
+import android.app.appsearch.util.SchemaMigrationUtil;
 import android.os.Bundle;
 import android.os.ParcelableException;
 import android.os.RemoteException;
@@ -26,6 +28,7 @@
 import android.util.ArraySet;
 import android.util.Log;
 
+import com.android.internal.infra.AndroidFuture;
 import com.android.internal.util.Preconditions;
 
 import java.io.Closeable;
@@ -45,15 +48,16 @@
  */
 public final class AppSearchSession implements Closeable {
     private static final String TAG = "AppSearchSession";
+
     private final String mPackageName;
     private final String mDatabaseName;
     @UserIdInt
     private final int mUserId;
     private final IAppSearchManager mService;
+
     private boolean mIsMutated = false;
     private boolean mIsClosed = false;
 
-
     /**
      * Creates a search session for the client, defined by the {@code userId} and
      * {@code packageName}.
@@ -111,7 +115,9 @@
      * no-op call.
      *
      * @param request the schema to set or update the AppSearch database to.
-     * @param executor Executor on which to invoke the callback.
+     * @param workExecutor Executor on which to schedule heavy client-side background work such as
+     *                     transforming documents.
+     * @param callbackExecutor Executor on which to invoke the callback.
      * @param callback Callback to receive errors resulting from setting the schema. If the
      *                 operation succeeds, the callback will be invoked with {@code null}.
      */
@@ -119,10 +125,12 @@
     //  exposed.
     public void setSchema(
             @NonNull SetSchemaRequest request,
-            @NonNull @CallbackExecutor Executor executor,
+            @NonNull Executor workExecutor,
+            @NonNull @CallbackExecutor Executor callbackExecutor,
             @NonNull Consumer<AppSearchResult<SetSchemaResponse>> callback) {
         Objects.requireNonNull(request);
-        Objects.requireNonNull(executor);
+        Objects.requireNonNull(workExecutor);
+        Objects.requireNonNull(callbackExecutor);
         Objects.requireNonNull(callback);
         Preconditions.checkState(!mIsClosed, "AppSearchSession has already been closed");
         List<Bundle> schemaBundles = new ArrayList<>(request.getSchemas().size());
@@ -139,33 +147,25 @@
             }
             schemasPackageAccessibleBundles.put(entry.getKey(), packageIdentifierBundles);
         }
-        try {
-            mService.setSchema(
-                    mPackageName,
-                    mDatabaseName,
+
+        // No need to trigger migration if user never set migrator
+        if (request.getMigrators().isEmpty()) {
+            setSchemaNoMigrations(
+                    request,
                     schemaBundles,
-                    new ArrayList<>(request.getSchemasNotDisplayedBySystem()),
                     schemasPackageAccessibleBundles,
-                    request.isForceOverride(),
-                    mUserId,
-                    new IAppSearchResultCallback.Stub() {
-                        public void onResult(AppSearchResult result) {
-                            executor.execute(() -> {
-                                if (result.isSuccess()) {
-                                    callback.accept(
-                                            // TODO(b/177266929) implement Migration in platform.
-                                            AppSearchResult.newSuccessfulResult(
-                                                    new SetSchemaResponse.Builder().build()));
-                                } else {
-                                    callback.accept(result);
-                                }
-                            });
-                        }
-                    });
-            mIsMutated = true;
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
+                    callbackExecutor,
+                    callback);
+        } else {
+            setSchemaWithMigrations(
+                    request,
+                    schemaBundles,
+                    schemasPackageAccessibleBundles,
+                    workExecutor,
+                    callbackExecutor,
+                    callback);
         }
+        mIsMutated = true;
     }
 
     /**
@@ -176,7 +176,7 @@
      */
     public void getSchema(
             @NonNull @CallbackExecutor Executor executor,
-            @NonNull Consumer<AppSearchResult<Set<AppSearchSchema>>> callback) {
+            @NonNull Consumer<AppSearchResult<GetSchemaResponse>> callback) {
         Objects.requireNonNull(executor);
         Objects.requireNonNull(callback);
         Preconditions.checkState(!mIsClosed, "AppSearchSession has already been closed");
@@ -189,14 +189,46 @@
                         public void onResult(AppSearchResult result) {
                             executor.execute(() -> {
                                 if (result.isSuccess()) {
-                                    List<Bundle> schemaBundles =
-                                            (List<Bundle>) result.getResultValue();
-                                    Set<AppSearchSchema> schemas = new ArraySet<>(
-                                            schemaBundles.size());
-                                    for (int i = 0; i < schemaBundles.size(); i++) {
-                                        schemas.add(new AppSearchSchema(schemaBundles.get(i)));
-                                    }
-                                    callback.accept(AppSearchResult.newSuccessfulResult(schemas));
+                                    Bundle responseBundle = (Bundle) result.getResultValue();
+                                    GetSchemaResponse response =
+                                            new GetSchemaResponse(responseBundle);
+                                    callback.accept(AppSearchResult.newSuccessfulResult(response));
+                                } else {
+                                    callback.accept(result);
+                                }
+                            });
+                        }
+                    });
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Retrieves the set of all namespaces in the current database with at least one document.
+     *
+     * @param executor        Executor on which to invoke the callback.
+     * @param callback        Callback to receive the namespaces.
+     */
+    public void getNamespaces(
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull Consumer<AppSearchResult<Set<String>>> callback) {
+        Objects.requireNonNull(executor);
+        Objects.requireNonNull(callback);
+        Preconditions.checkState(!mIsClosed, "AppSearchSession has already been closed");
+        try {
+            mService.getNamespaces(
+                    mPackageName,
+                    mDatabaseName,
+                    mUserId,
+                    new IAppSearchResultCallback.Stub() {
+                        public void onResult(AppSearchResult result) {
+                            executor.execute(() -> {
+                                if (result.isSuccess()) {
+                                    Set<String> namespaces =
+                                            new ArraySet<>((List<String>) result.getResultValue());
+                                    callback.accept(
+                                            AppSearchResult.newSuccessfulResult(namespaces));
                                 } else {
                                     callback.accept(result);
                                 }
@@ -297,8 +329,7 @@
 
                                 // Translate successful results
                                 for (Map.Entry<String, Bundle> bundleEntry :
-                                        (Set<Map.Entry<String, Bundle>>)
-                                                result.getSuccesses().entrySet()) {
+                                        ((Map<String, Bundle>) result.getSuccesses()).entrySet()) {
                                     GenericDocument document;
                                     try {
                                         document = new GenericDocument(bundleEntry.getValue());
@@ -317,8 +348,8 @@
 
                                 // Translate failed results
                                 for (Map.Entry<String, AppSearchResult<Bundle>> bundleEntry :
-                                        (Set<Map.Entry<String, AppSearchResult<Bundle>>>)
-                                                result.getFailures().entrySet()) {
+                                        ((Map<String, AppSearchResult<Bundle>>)
+                                                result.getFailures()).entrySet()) {
                                     documentResultBuilder.setFailure(
                                             bundleEntry.getKey(),
                                             bundleEntry.getValue().getResultCode(),
@@ -437,6 +468,7 @@
                     request.getNamespace(),
                     request.getUri(),
                     request.getUsageTimeMillis(),
+                    /*systemUsage=*/ false,
                     mUserId,
                     new IAppSearchResultCallback.Stub() {
                         public void onResult(AppSearchResult result) {
@@ -541,6 +573,45 @@
     }
 
     /**
+     * Gets the storage info for this {@link AppSearchSession} database.
+     *
+     * <p>This may take time proportional to the number of documents and may be inefficient to
+     * call repeatedly.
+     *
+     * @param executor        Executor on which to invoke the callback.
+     * @param callback        Callback to receive the storage info.
+     */
+    public void getStorageInfo(
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull Consumer<AppSearchResult<StorageInfo>> callback) {
+        Objects.requireNonNull(executor);
+        Objects.requireNonNull(callback);
+        Preconditions.checkState(!mIsClosed, "AppSearchSession has already been closed");
+        try {
+            mService.getStorageInfo(
+                    mPackageName,
+                    mDatabaseName,
+                    mUserId,
+                    new IAppSearchResultCallback.Stub() {
+                        public void onResult(AppSearchResult result) {
+                            executor.execute(() -> {
+                                if (result.isSuccess()) {
+                                    Bundle responseBundle = (Bundle) result.getResultValue();
+                                    StorageInfo response =
+                                            new StorageInfo(responseBundle);
+                                    callback.accept(AppSearchResult.newSuccessfulResult(response));
+                                } else {
+                                    callback.accept(result);
+                                }
+                            });
+                        }
+                    });
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Closes the {@link AppSearchSession} to persist all schema and document updates, additions,
      * and deletes to disk.
      */
@@ -555,4 +626,217 @@
             }
         }
     }
+
+    /**
+     * Set schema to Icing for no-migration scenario.
+     *
+     * <p>We only need one time {@link #setSchema} call for no-migration scenario by using the
+     * forceoverride in the request.
+     */
+    private void setSchemaNoMigrations(
+            @NonNull SetSchemaRequest request,
+            @NonNull List<Bundle> schemaBundles,
+            @NonNull Map<String, List<Bundle>> schemasPackageAccessibleBundles,
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull Consumer<AppSearchResult<SetSchemaResponse>> callback) {
+        try {
+            mService.setSchema(
+                    mPackageName,
+                    mDatabaseName,
+                    schemaBundles,
+                    new ArrayList<>(request.getSchemasNotDisplayedBySystem()),
+                    schemasPackageAccessibleBundles,
+                    request.isForceOverride(),
+                    mUserId,
+                    request.getVersion(),
+                    new IAppSearchResultCallback.Stub() {
+                        public void onResult(AppSearchResult result) {
+                            executor.execute(() -> {
+                                if (result.isSuccess()) {
+                                    try {
+                                        SetSchemaResponse setSchemaResponse =
+                                                new SetSchemaResponse(
+                                                        (Bundle) result.getResultValue());
+                                        if (!request.isForceOverride()) {
+                                            // Throw exception if there is any deleted types or
+                                            // incompatible types. That's the only case we swallowed
+                                            // in the AppSearchImpl#setSchema().
+                                            checkDeletedAndIncompatible(
+                                                    setSchemaResponse.getDeletedTypes(),
+                                                    setSchemaResponse.getIncompatibleTypes());
+                                        }
+                                        callback.accept(AppSearchResult
+                                                .newSuccessfulResult(setSchemaResponse));
+                                    } catch (Throwable t) {
+                                        callback.accept(AppSearchResult.throwableToFailedResult(t));
+                                    }
+                                } else {
+                                    callback.accept(result);
+                                }
+                            });
+                        }
+                    });
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Set schema to Icing for migration scenario.
+     *
+     * <p>First time {@link #setSchema} call with forceOverride is false gives us all incompatible
+     * changes. After trigger migrations, the second time call {@link #setSchema} will actually
+     * apply the changes.
+     */
+    private void setSchemaWithMigrations(
+            @NonNull SetSchemaRequest request,
+            @NonNull List<Bundle> schemaBundles,
+            @NonNull Map<String, List<Bundle>> schemasPackageAccessibleBundles,
+            @NonNull Executor workExecutor,
+            @NonNull @CallbackExecutor Executor callbackExecutor,
+            @NonNull Consumer<AppSearchResult<SetSchemaResponse>> callback) {
+        workExecutor.execute(() -> {
+            try {
+                // Migration process
+                // 1. Generate the current and the final version map.
+                AndroidFuture<AppSearchResult<GetSchemaResponse>> getSchemaFuture =
+                        new AndroidFuture<>();
+                getSchema(callbackExecutor, getSchemaFuture::complete);
+                AppSearchResult<GetSchemaResponse> getSchemaResult = getSchemaFuture.get();
+                if (!getSchemaResult.isSuccess()) {
+                    callbackExecutor.execute(() ->
+                            callback.accept(AppSearchResult.newFailedResult(getSchemaResult)));
+                    return;
+                }
+                GetSchemaResponse getSchemaResponse = getSchemaResult.getResultValue();
+                Set<AppSearchSchema> currentSchemas = getSchemaResponse.getSchemas();
+                Map<String, Integer> currentVersionMap = SchemaMigrationUtil.buildVersionMap(
+                        currentSchemas, getSchemaResponse.getVersion());
+                Map<String, Integer> finalVersionMap = SchemaMigrationUtil.buildVersionMap(
+                        request.getSchemas(), request.getVersion());
+
+                // 2. SetSchema with forceOverride=false, to retrieve the list of
+                // incompatible/deleted types.
+                AndroidFuture<AppSearchResult<Bundle>> setSchemaFuture = new AndroidFuture<>();
+                mService.setSchema(
+                        mPackageName,
+                        mDatabaseName,
+                        schemaBundles,
+                        new ArrayList<>(request.getSchemasNotDisplayedBySystem()),
+                        schemasPackageAccessibleBundles,
+                        /*forceOverride=*/ false,
+                        mUserId,
+                        request.getVersion(),
+                        new IAppSearchResultCallback.Stub() {
+                            public void onResult(AppSearchResult result) {
+                                setSchemaFuture.complete(result);
+                            }
+                        });
+                AppSearchResult<Bundle> setSchemaResult = setSchemaFuture.get();
+                if (!setSchemaResult.isSuccess()) {
+                    callbackExecutor.execute(() ->
+                            callback.accept(AppSearchResult.newFailedResult(setSchemaResult)));
+                    return;
+                }
+                SetSchemaResponse setSchemaResponse =
+                        new SetSchemaResponse(setSchemaResult.getResultValue());
+
+                // 1. If forceOverride is false, check that all incompatible types will be migrated.
+                // If some aren't we must throw an error, rather than proceeding and deleting those
+                // types.
+                if (!request.isForceOverride()) {
+                    Set<String> unmigratedTypes =
+                            SchemaMigrationUtil.getUnmigratedIncompatibleTypes(
+                                    setSchemaResponse.getIncompatibleTypes(),
+                                    request.getMigrators(),
+                                    currentVersionMap,
+                                    finalVersionMap);
+
+                    // check if there are any unmigrated types or deleted types. If there are, we
+                    // will throw an exception.
+                    // Since the force override is false, the schema will not have been set if there
+                    // are any incompatible or deleted types.
+                    checkDeletedAndIncompatible(
+                            setSchemaResponse.getDeletedTypes(), unmigratedTypes);
+                }
+
+                try (AppSearchMigrationHelper migrationHelper =
+                             new AppSearchMigrationHelper(
+                                     mService, mUserId, currentVersionMap, finalVersionMap,
+                                     mPackageName, mDatabaseName)) {
+                    Map<String, Migrator> migratorMap = request.getMigrators();
+
+                    // 2. Trigger migration for all migrators.
+                    // TODO(b/177266929) trigger migration for all types together rather than
+                    //  separately.
+                    Set<String> migratedTypes = new ArraySet<>();
+                    for (Map.Entry<String, Migrator> entry : migratorMap.entrySet()) {
+                        String schemaType = entry.getKey();
+                        Migrator migrator = entry.getValue();
+                        if (SchemaMigrationUtil.shouldTriggerMigration(
+                                schemaType, migrator, currentVersionMap, finalVersionMap)) {
+                            migrationHelper.queryAndTransform(schemaType, migrator);
+                            migratedTypes.add(schemaType);
+                        }
+                    }
+
+                    // 3. SetSchema a second time with forceOverride=true if the first attempted
+                    // failed.
+                    if (!setSchemaResponse.getIncompatibleTypes().isEmpty()
+                            || !setSchemaResponse.getDeletedTypes().isEmpty()) {
+                        AndroidFuture<AppSearchResult<Bundle>> setSchema2Future =
+                                new AndroidFuture<>();
+                        // only trigger second setSchema() call if the first one is fail.
+                        mService.setSchema(
+                                mPackageName,
+                                mDatabaseName,
+                                schemaBundles,
+                                new ArrayList<>(request.getSchemasNotDisplayedBySystem()),
+                                schemasPackageAccessibleBundles,
+                                /*forceOverride=*/ true,
+                                request.getVersion(),
+                                mUserId,
+                                new IAppSearchResultCallback.Stub() {
+                                    @Override
+                                    public void onResult(AppSearchResult result) {
+                                        setSchema2Future.complete(result);
+                                    }
+                                });
+                        AppSearchResult<Bundle> setSchema2Result = setSchema2Future.get();
+                        if (!setSchema2Result.isSuccess()) {
+                            // we failed to set the schema in second time with forceOverride = true,
+                            // which is an impossible case. Since we only swallow the incompatible
+                            // error in the first setSchema call, all other errors will be thrown at
+                            // the first time.
+                            callbackExecutor.execute(() -> callback.accept(
+                                    AppSearchResult.newFailedResult(setSchemaResult)));
+                            return;
+                        }
+                    }
+
+                    SetSchemaResponse.Builder responseBuilder = setSchemaResponse.toBuilder()
+                            .addMigratedTypes(migratedTypes);
+                    AppSearchResult<SetSchemaResponse> putResult =
+                            migrationHelper.putMigratedDocuments(responseBuilder);
+                    callbackExecutor.execute(() -> callback.accept(putResult));
+                }
+            } catch (Throwable t) {
+                callbackExecutor.execute(() -> callback.accept(
+                        AppSearchResult.throwableToFailedResult(t)));
+            }
+        });
+    }
+
+    /**  Checks the setSchema() call won't delete any types or has incompatible types. */
+    //TODO(b/177266929) move this method to util
+    private void checkDeletedAndIncompatible(Set<String> deletedTypes,
+            Set<String> incompatibleTypes)
+            throws AppSearchException {
+        if (!deletedTypes.isEmpty() || !incompatibleTypes.isEmpty()) {
+            String newMessage = "Schema is incompatible."
+                    + "\n  Deleted types: " + deletedTypes
+                    + "\n  Incompatible types: " + incompatibleTypes;
+            throw new AppSearchException(AppSearchResult.RESULT_INVALID_SCHEMA, newMessage);
+        }
+    }
 }
diff --git a/apex/appsearch/framework/java/android/app/appsearch/GlobalSearchSession.java b/apex/appsearch/framework/java/android/app/appsearch/GlobalSearchSession.java
index fb63e16..b30ed50 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/GlobalSearchSession.java
+++ b/apex/appsearch/framework/java/android/app/appsearch/GlobalSearchSession.java
@@ -21,6 +21,7 @@
 import android.annotation.NonNull;
 import android.annotation.UserIdInt;
 import android.os.RemoteException;
+import android.util.Log;
 
 import com.android.internal.util.Preconditions;
 
@@ -35,14 +36,15 @@
  * <p>Apps can retrieve indexed documents through the {@link #search} API.
  */
 public class GlobalSearchSession implements Closeable {
-
-    private final IAppSearchManager mService;
-
-    @UserIdInt
-    private final int mUserId;
-    private boolean mIsClosed = false;
+    private static final String TAG = "AppSearchGlobalSearchSe";
 
     private final String mPackageName;
+    @UserIdInt
+    private final int mUserId;
+    private final IAppSearchManager mService;
+
+    private boolean mIsMutated = false;
+    private boolean mIsClosed = false;
 
     /**
      * Creates a search session for the client, defined by the {@code userId} and
@@ -117,9 +119,66 @@
                 searchSpec, mUserId);
     }
 
-    /** Closes the {@link GlobalSearchSession}. */
+    /**
+     * Reports that a particular document has been used from a system surface.
+     *
+     * <p>See {@link AppSearchSession#reportUsage} for a general description of document usage, as
+     * well as an API that can be used by the app itself.
+     *
+     * <p>Usage reported via this method is accounted separately from usage reported via
+     * {@link AppSearchSession#reportUsage} and may be accessed using the constants
+     * {@link SearchSpec#RANKING_STRATEGY_SYSTEM_USAGE_COUNT} and
+     * {@link SearchSpec#RANKING_STRATEGY_SYSTEM_USAGE_LAST_USED_TIMESTAMP}.
+     *
+     * @param request The usage reporting request.
+     * @param executor Executor on which to invoke the callback.
+     * @param callback Callback to receive errors. If the operation succeeds, the callback will be
+     *                 invoked with an {@link AppSearchResult} whose value is {@code null}. The
+     *                 callback will be invoked with an {@link AppSearchResult} of
+     *                 {@link AppSearchResult#RESULT_SECURITY_ERROR} if this API is invoked by an
+     *                 app which is not part of the system.
+     */
+    public void reportSystemUsage(
+            @NonNull ReportSystemUsageRequest request,
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull Consumer<AppSearchResult<Void>> callback) {
+        Objects.requireNonNull(request);
+        Objects.requireNonNull(executor);
+        Objects.requireNonNull(callback);
+        Preconditions.checkState(!mIsClosed, "GlobalSearchSession has already been closed");
+        try {
+            mService.reportUsage(
+                    request.getPackageName(),
+                    request.getDatabaseName(),
+                    request.getNamespace(),
+                    request.getUri(),
+                    request.getUsageTimeMillis(),
+                    /*systemUsage=*/ true,
+                    mUserId,
+                    new IAppSearchResultCallback.Stub() {
+                        public void onResult(AppSearchResult result) {
+                            executor.execute(() -> callback.accept(result));
+                        }
+                    });
+            mIsMutated = true;
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Closes the {@link GlobalSearchSession}. Persists all mutations, including usage reports, to
+     * disk.
+     */
     @Override
     public void close() {
-        mIsClosed = true;
+        if (mIsMutated && !mIsClosed) {
+            try {
+                mService.persistToDisk(mUserId);
+                mIsClosed = true;
+            } catch (RemoteException e) {
+                Log.e(TAG, "Unable to close the GlobalSearchSession", e);
+            }
+        }
     }
 }
diff --git a/apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl b/apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl
index ba27762..a8ac27c 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl
+++ b/apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl
@@ -21,6 +21,7 @@
 import android.app.appsearch.AppSearchResult;
 import android.app.appsearch.IAppSearchBatchResultCallback;
 import android.app.appsearch.IAppSearchResultCallback;
+import android.os.ParcelFileDescriptor;
 import com.android.internal.infra.AndroidFuture;
 
 parcelable SearchResults;
@@ -41,7 +42,8 @@
      *     incompatible documents will be deleted.
      * @param userId Id of the calling user
      * @param callback {@link IAppSearchResultCallback#onResult} will be called with an
-     *     {@link AppSearchResult}&lt;{@link Void}&gt;.
+     *     {@link AppSearchResult}&lt;{@link Bundle}&gt;, where the value are
+     *     {@link SetSchemaResponse} bundle.
      */
     void setSchema(
         in String packageName,
@@ -51,6 +53,7 @@
         in Map<String, List<Bundle>> schemasPackageAccessibleBundles,
         boolean forceOverride,
         in int userId,
+        in int schemaVersion,
         in IAppSearchResultCallback callback);
 
     /**
@@ -60,8 +63,7 @@
      * @param databaseName  The name of the database to retrieve.
      * @param userId Id of the calling user
      * @param callback {@link IAppSearchResultCallback#onResult} will be called with an
-     *     {@link AppSearchResult}&lt;{@link List}&lt;{@link Bundle}&gt;&gt;, where the value are
-     *     AppSearchSchema bundle.
+     *     {@link AppSearchResult}&lt;{@link Bundle}&gt; where the bundle is a GetSchemaResponse.
      */
     void getSchema(
         in String packageName,
@@ -70,6 +72,21 @@
         in IAppSearchResultCallback callback);
 
     /**
+     * Retrieves the set of all namespaces in the current database with at least one document.
+     *
+     * @param packageName The name of the package that owns the schema.
+     * @param databaseName  The name of the database to retrieve.
+     * @param userId Id of the calling user
+     * @param callback {@link IAppSearchResultCallback#onResult} will be called with an
+     *     {@link AppSearchResult}&lt;{@link List}&lt;{@link String}&gt;&gt;.
+     */
+    void getNamespaces(
+        in String packageName,
+        in String databaseName,
+        in int userId,
+        in IAppSearchResultCallback callback);
+
+    /**
      * Inserts documents into the index.
      *
      * @param packageName The name of the package that owns this document.
@@ -174,6 +191,47 @@
     void invalidateNextPageToken(in long nextPageToken, in int userId);
 
     /**
+    * Searches a document based on a given specifications.
+    *
+    * <p>Documents will be save to the given ParcelFileDescriptor
+    *
+    * @param packageName The name of the package to query over.
+    * @param databaseName The databaseName this query for.
+    * @param fileDescriptor The ParcelFileDescriptor where documents should be written to.
+    * @param queryExpression String to search for.
+    * @param searchSpecBundle SearchSpec bundle.
+    * @param userId Id of the calling user.
+    * @param callback {@link IAppSearchResultCallback#onResult} will be called with an
+    *        {@link AppSearchResult}&lt;{@code null}&gt;.
+    */
+    void writeQueryResultsToFile(
+        in String packageName,
+        in String databaseName,
+        in ParcelFileDescriptor fileDescriptor,
+        in String queryExpression,
+        in Bundle searchSpecBundle,
+        in int userId,
+        in IAppSearchResultCallback callback);
+
+    /**
+    * Inserts documents from the given file into the index.
+    *
+    * @param packageName The name of the package that owns this document.
+    * @param databaseName  The name of the database where this document lives.
+    * @param fileDescriptor The ParcelFileDescriptor where documents should be read from.
+    * @param userId Id of the calling user.
+    * @param callback {@link IAppSearchResultCallback#onResult} will be called with an
+    *     {@link AppSearchResult}&lt;{@link List}&lt;{@link Bundle}&gt;&gt;, where the value are
+    *     MigrationFailure bundles.
+    */
+    void putDocumentsFromFile(
+        in String packageName,
+        in String databaseName,
+        in ParcelFileDescriptor fileDescriptor,
+        in int userId,
+        in IAppSearchResultCallback callback);
+
+    /**
      * Reports usage of a particular document by URI and namespace.
      *
      * <p>A usage report represents an event in which a user interacted with or viewed a document.
@@ -190,6 +248,7 @@
      * @param namespace Namespace the document being used belongs to.
      * @param uri URI of the document being used.
      * @param usageTimeMillis The timestamp at which the document was used.
+     * @param systemUsage Whether the usage was reported by a system app against another app's doc.
      * @param userId Id of the calling user
      * @param callback {@link IAppSearchResultCallback#onResult} will be called with an
      *     {@link AppSearchResult}&lt;{@link Void}&gt;.
@@ -200,6 +259,7 @@
          in String namespace,
          in String uri,
          in long usageTimeMillis,
+         in boolean systemUsage,
          in int userId,
          in IAppSearchResultCallback callback);
 
@@ -247,6 +307,22 @@
         in IAppSearchResultCallback callback);
 
     /**
+     * Gets the storage info.
+     *
+     * @param packageName The name of the package to get the storage info for.
+     * @param databaseName The databaseName to get the storage info for.
+     * @param userId Id of the calling user
+     * @param callback {@link IAppSearchResultCallback#onResult} will be called with an
+     *     {@link AppSearchResult}&lt;{@link Bundle}&gt;, where the value is a
+     *     {@link StorageInfo}.
+     */
+    void getStorageInfo(
+        in String packageName,
+        in String databaseName,
+        in int userId,
+        in IAppSearchResultCallback callback);
+
+    /**
      * Persists all update/delete requests to the disk.
      *
      * @param userId Id of the calling user
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchSchema.java b/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchSchema.java
index 55f0c80..a8048dc 100644
--- a/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchSchema.java
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchSchema.java
@@ -17,7 +17,6 @@
 package android.app.appsearch;
 
 import android.annotation.IntDef;
-import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.appsearch.exceptions.IllegalSchemaException;
@@ -46,7 +45,6 @@
  */
 public final class AppSearchSchema {
     private static final String SCHEMA_TYPE_FIELD = "schemaType";
-    private static final String VERSION_FIELD = "version";
     private static final String PROPERTIES_FIELD = "properties";
 
     private final Bundle mBundle;
@@ -78,11 +76,6 @@
         return mBundle.getString(SCHEMA_TYPE_FIELD, "");
     }
 
-    /** Returns the version of this {@link AppSearchSchema}. */
-    public @IntRange(from = 0) int getVersion() {
-        return mBundle.getInt(VERSION_FIELD);
-    }
-
     /**
      * Returns the list of {@link PropertyConfig}s that are part of this schema.
      *
@@ -115,15 +108,12 @@
         if (!getSchemaType().equals(otherSchema.getSchemaType())) {
             return false;
         }
-        if (getVersion() != otherSchema.getVersion()) {
-            return false;
-        }
         return getProperties().equals(otherSchema.getProperties());
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(getSchemaType(), getVersion(), getProperties());
+        return Objects.hash(getSchemaType(), getProperties());
     }
 
     /** Builder for {@link AppSearchSchema objects}. */
@@ -131,7 +121,6 @@
         private final String mSchemaType;
         private final ArrayList<Bundle> mPropertyBundles = new ArrayList<>();
         private final Set<String> mPropertyNames = new ArraySet<>();
-        private int mVersion;
         private boolean mBuilt = false;
 
         /** Creates a new {@link AppSearchSchema.Builder}. */
@@ -154,42 +143,6 @@
         }
 
         /**
-         * Sets the version number of the {@link AppSearchSchema}.
-         *
-         * <p>The {@link AppSearchSession} database can only ever hold documents for one version of
-         * a {@link AppSearchSchema} type at a time.
-         *
-         * <p>Setting a version number that is different from the version number of the schema
-         * currently stored in AppSearch will result in AppSearch calling the {@link Migrator}
-         * provided to {@link AppSearchSession#setSchema} to migrate the documents already in
-         * AppSearch from the previous version to the one set in this request. The version number
-         * can be updated without any other changes to the schema.
-         *
-         * <p>The version number can stay the same, increase, or decrease relative to the current
-         * version number of the {@link AppSearchSchema} type that is already stored in the {@link
-         * AppSearchSession} database.
-         *
-         * <p>The version number will be updated if the {@link SetSchemaRequest} contains
-         * backwards-compatible changes or {@link SetSchemaRequest.Builder#setForceOverride} method
-         * is set to {@code true}.
-         *
-         * @param version A non-negative int number represents the version of this {@link
-         *     AppSearchSchema}, default version is 0.
-         * @throws IllegalStateException if the version is negative or the builder has already been
-         *     used.
-         * @see AppSearchSession#setSchema
-         * @see Migrator
-         * @see SetSchemaRequest.Builder#setMigrator
-         */
-        @NonNull
-        public AppSearchSchema.Builder setVersion(@IntRange(from = 0) int version) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
-            Preconditions.checkArgumentNonnegative(version);
-            mVersion = version;
-            return this;
-        }
-
-        /**
          * Constructs a new {@link AppSearchSchema} from the contents of this builder.
          *
          * <p>After calling this method, the builder must no longer be used.
@@ -199,7 +152,6 @@
             Preconditions.checkState(!mBuilt, "Builder has already been used");
             Bundle bundle = new Bundle();
             bundle.putString(AppSearchSchema.SCHEMA_TYPE_FIELD, mSchemaType);
-            bundle.putInt(AppSearchSchema.VERSION_FIELD, mVersion);
             bundle.putParcelableArrayList(AppSearchSchema.PROPERTIES_FIELD, mPropertyBundles);
             mBuilt = true;
             return new AppSearchSchema(bundle);
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/GenericDocument.java b/apex/appsearch/framework/java/external/android/app/appsearch/GenericDocument.java
index 4ce95ea..8c9d950 100644
--- a/apex/appsearch/framework/java/external/android/app/appsearch/GenericDocument.java
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/GenericDocument.java
@@ -46,15 +46,6 @@
 public class GenericDocument {
     private static final String TAG = "AppSearchGenericDocumen";
 
-    /**
-     * The default empty namespace.
-     *
-     * <p>TODO(b/181887768): This exists only for dogfooder transition and must be removed.
-     *
-     * @deprecated This exists only for dogfooder transition and must be removed.
-     */
-    @Deprecated public static final String DEFAULT_NAMESPACE = "";
-
     /** The maximum number of elements in a repeatable field. */
     private static final int MAX_REPEATED_PROPERTY_LENGTH = 100;
 
@@ -585,41 +576,6 @@
          *
          * <p>Once {@link #build} is called, the instance can no longer be used.
          *
-         * <p>TODO(b/181887768): This method exists only for dogfooder transition and must be
-         * removed.
-         *
-         * @param uri the URI to set for the {@link GenericDocument}.
-         * @param schemaType the {@link AppSearchSchema} type of the {@link GenericDocument}. The
-         *     provided {@code schemaType} must be defined using {@link AppSearchSession#setSchema}
-         *     prior to inserting a document of this {@code schemaType} into the AppSearch index
-         *     using {@link AppSearchSession#put}. Otherwise, the document will be rejected by
-         *     {@link AppSearchSession#put} with result code {@link
-         *     AppSearchResult#RESULT_NOT_FOUND}.
-         * @deprecated Please supply the namespace in {@link #Builder(String, String, String)}
-         *     instead. This method exists only for dogfooder transition and must be removed.
-         */
-        @Deprecated
-        @SuppressWarnings("unchecked")
-        public Builder(@NonNull String uri, @NonNull String schemaType) {
-            Preconditions.checkNotNull(uri);
-            Preconditions.checkNotNull(schemaType);
-            mBuilderTypeInstance = (BuilderType) this;
-            mBundle.putString(GenericDocument.URI_FIELD, uri);
-            mBundle.putString(GenericDocument.SCHEMA_TYPE_FIELD, schemaType);
-            mBundle.putString(GenericDocument.NAMESPACE_FIELD, DEFAULT_NAMESPACE);
-            // Set current timestamp for creation timestamp by default.
-            mBundle.putLong(
-                    GenericDocument.CREATION_TIMESTAMP_MILLIS_FIELD, System.currentTimeMillis());
-            mBundle.putLong(GenericDocument.TTL_MILLIS_FIELD, DEFAULT_TTL_MILLIS);
-            mBundle.putInt(GenericDocument.SCORE_FIELD, DEFAULT_SCORE);
-            mBundle.putBundle(PROPERTIES_FIELD, mProperties);
-        }
-
-        /**
-         * Creates a new {@link GenericDocument.Builder}.
-         *
-         * <p>Once {@link #build} is called, the instance can no longer be used.
-         *
          * <p>URIs are unique within a namespace.
          *
          * <p>The number of namespaces per app should be kept small for efficiency reasons.
@@ -651,29 +607,6 @@
         }
 
         /**
-         * Sets the app-defined namespace this document resides in. No special values are reserved
-         * or understood by the infrastructure.
-         *
-         * <p>URIs are unique within a namespace.
-         *
-         * <p>The number of namespaces per app should be kept small for efficiency reasons.
-         *
-         * <p>TODO(b/181887768): This method exists only for dogfooder transition and must be
-         * removed.
-         *
-         * @throws IllegalStateException if the builder has already been used.
-         * @deprecated Please supply the namespace in {@link #Builder(String, String, String)}
-         *     instead. This method exists only for dogfooder transition and must be removed.
-         */
-        @Deprecated
-        @NonNull
-        public BuilderType setNamespace(@NonNull String namespace) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
-            mBundle.putString(GenericDocument.NAMESPACE_FIELD, namespace);
-            return mBuilderTypeInstance;
-        }
-
-        /**
          * Sets the score of the {@link GenericDocument}.
          *
          * <p>The score is a query-independent measure of the document's quality, relative to other
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/GetByUriRequest.java b/apex/appsearch/framework/java/external/android/app/appsearch/GetByUriRequest.java
index 6881a27..1719e14 100644
--- a/apex/appsearch/framework/java/external/android/app/appsearch/GetByUriRequest.java
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/GetByUriRequest.java
@@ -107,49 +107,17 @@
      * <p>Once {@link #build} is called, the instance can no longer be used.
      */
     public static final class Builder {
-        private String mNamespace;
+        private final String mNamespace;
         private final Set<String> mUris = new ArraySet<>();
         private final Map<String, List<String>> mProjectionTypePropertyPaths = new ArrayMap<>();
         private boolean mBuilt = false;
 
-        /**
-         * TODO(b/181887768): This method exists only for dogfooder transition and must be removed.
-         *
-         * @deprecated Please supply the namespace in {@link #Builder(String)} instead. This method
-         *     exists only for dogfooder transition and must be removed.
-         */
-        @Deprecated
-        public Builder() {
-            mNamespace = GenericDocument.DEFAULT_NAMESPACE;
-        }
-
         /** Creates a {@link GetByUriRequest.Builder} instance. */
         public Builder(@NonNull String namespace) {
             mNamespace = Preconditions.checkNotNull(namespace);
         }
 
         /**
-         * Sets the namespace to retrieve documents for.
-         *
-         * <p>If this is not called, the namespace defaults to an empty string.
-         *
-         * <p>TODO(b/181887768): This method exists only for dogfooder transition and must be
-         * removed.
-         *
-         * @throws IllegalStateException if the builder has already been used.
-         * @deprecated Please supply the namespace in {@link #Builder(String)} instead. This method
-         *     exists only for dogfooder transition and must
-         */
-        @Deprecated
-        @NonNull
-        public Builder setNamespace(@NonNull String namespace) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
-            Preconditions.checkNotNull(namespace);
-            mNamespace = namespace;
-            return this;
-        }
-
-        /**
          * Adds one or more URIs to the request.
          *
          * @throws IllegalStateException if the builder has already been used.
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/GetSchemaResponse.java b/apex/appsearch/framework/java/external/android/app/appsearch/GetSchemaResponse.java
new file mode 100644
index 0000000..1f56ef3
--- /dev/null
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/GetSchemaResponse.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.appsearch;
+
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.os.Bundle;
+import android.util.ArraySet;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.ArrayList;
+import java.util.Set;
+
+/** The response class of {@link AppSearchSession#getSchema} */
+public class GetSchemaResponse {
+    private static final String VERSION_FIELD = "version";
+    private static final String SCHEMAS_FIELD = "schemas";
+
+    private final Bundle mBundle;
+
+    GetSchemaResponse(@NonNull Bundle bundle) {
+        mBundle = Preconditions.checkNotNull(bundle);
+    }
+
+    /**
+     * Returns the {@link Bundle} populated by this builder.
+     *
+     * @hide
+     */
+    @NonNull
+    public Bundle getBundle() {
+        return mBundle;
+    }
+
+    /**
+     * Returns the overall database schema version.
+     *
+     * <p>If the database is empty, 0 will be returned.
+     */
+    @IntRange(from = 0)
+    public int getVersion() {
+        return mBundle.getInt(VERSION_FIELD);
+    }
+
+    /**
+     * Return the schemas most recently successfully provided to {@link AppSearchSession#setSchema}.
+     *
+     * <p>It is inefficient to call this method repeatedly.
+     */
+    @NonNull
+    public Set<AppSearchSchema> getSchemas() {
+        ArrayList<Bundle> schemaBundles = mBundle.getParcelableArrayList(SCHEMAS_FIELD);
+        Set<AppSearchSchema> schemas = new ArraySet<>(schemaBundles.size());
+        for (int i = 0; i < schemaBundles.size(); i++) {
+            schemas.add(new AppSearchSchema(schemaBundles.get(i)));
+        }
+        return schemas;
+    }
+
+    /** Builder for {@link GetSchemaResponse} objects. */
+    public static final class Builder {
+        private int mVersion;
+        private boolean mBuilt = false;
+        private final ArrayList<Bundle> mSchemaBundles = new ArrayList<>();
+
+        /**
+         * Sets the database overall schema version.
+         *
+         * <p>Default version is 0
+         */
+        @NonNull
+        public Builder setVersion(@IntRange(from = 0) int version) {
+            mVersion = version;
+            return this;
+        }
+
+        /** Adds one {@link AppSearchSchema} to the schema list. */
+        @NonNull
+        public Builder addSchema(@NonNull AppSearchSchema schema) {
+            mSchemaBundles.add(schema.getBundle());
+            return this;
+        }
+
+        /** Builds a {@link GetSchemaResponse} object. */
+        @NonNull
+        public GetSchemaResponse build() {
+            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            Bundle bundle = new Bundle();
+            bundle.putInt(VERSION_FIELD, mVersion);
+            bundle.putParcelableArrayList(SCHEMAS_FIELD, mSchemaBundles);
+            mBuilt = true;
+            return new GetSchemaResponse(bundle);
+        }
+    }
+}
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/Migrator.java b/apex/appsearch/framework/java/external/android/app/appsearch/Migrator.java
index 5ae9a41..511b42a 100644
--- a/apex/appsearch/framework/java/external/android/app/appsearch/Migrator.java
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/Migrator.java
@@ -19,8 +19,6 @@
 import android.annotation.NonNull;
 import android.annotation.WorkerThread;
 
-import com.android.internal.util.Preconditions;
-
 /**
  * A migrator class to translate {@link GenericDocument} from different version of {@link
  * AppSearchSchema}
@@ -37,37 +35,14 @@
  * documents won't have any observable changes.
  */
 public abstract class Migrator {
-    private final int mStartVersion;
-
     /**
-     * Creates a {@link Migrator} will trigger migration for any version less than the final version
-     * in the new schema.
-     */
-    public Migrator() {
-        this(/*startVersion=*/ 0);
-    }
-
-    /**
-     * Creates a {@link Migrator} with a non-negative start version.
+     * Returns {@code true} if this migrator's source type needs to be migrated to update from
+     * currentVersion to finalVersion.
      *
-     * <p>Providing 0 will trigger migration for any version less than the final version in the new
-     * schema.
-     *
-     * @param startVersion The migration will be only triggered for those versions greater or equal
-     *     to the given startVersion.
+     * <p>Migration won't be triggered if currentVersion is equal to finalVersion even if {@link
+     * #shouldMigrate} return true;
      */
-    public Migrator(int startVersion) {
-        Preconditions.checkArgumentNonnegative(startVersion);
-        mStartVersion = startVersion;
-    }
-
-    /**
-     * @return {@code True} if the current version need to be migrated.
-     * @hide
-     */
-    public boolean shouldMigrateToFinalVersion(int currentVersion, int finalVersion) {
-        return currentVersion >= mStartVersion && currentVersion != finalVersion;
-    }
+    public abstract boolean shouldMigrate(int currentVersion, int finalVersion);
 
     /**
      * Migrates {@link GenericDocument} to a newer version of {@link AppSearchSchema}.
@@ -75,17 +50,22 @@
      * <p>This method will be invoked only if the {@link SetSchemaRequest} is setting a higher
      * version number than the current {@link AppSearchSchema} saved in AppSearch.
      *
-     * <p>This method will be invoked on the background worker thread.
+     * <p>If this {@link Migrator} is provided to cover a compatible schema change via {@link
+     * AppSearchSession#setSchema}, documents under the old version won't be removed unless you use
+     * the same URI.
+     *
+     * <p>This method will be invoked on the background worker thread provided via {@link
+     * AppSearchSession#setSchema}.
      *
      * @param currentVersion The current version of the document's schema.
-     * @param targetVersion The final version that documents need to be migrated to.
+     * @param finalVersion The final version that documents need to be migrated to.
      * @param document The {@link GenericDocument} need to be translated to new version.
      * @return A {@link GenericDocument} in new version.
      */
     @WorkerThread
     @NonNull
     public abstract GenericDocument onUpgrade(
-            int currentVersion, int targetVersion, @NonNull GenericDocument document);
+            int currentVersion, int finalVersion, @NonNull GenericDocument document);
 
     /**
      * Migrates {@link GenericDocument} to an older version of {@link AppSearchSchema}.
@@ -93,15 +73,19 @@
      * <p>This method will be invoked only if the {@link SetSchemaRequest} is setting a lower
      * version number than the current {@link AppSearchSchema} saved in AppSearch.
      *
+     * <p>If this {@link Migrator} is provided to cover a compatible schema change via {@link
+     * AppSearchSession#setSchema}, documents under the old version won't be removed unless you use
+     * the same URI.
+     *
      * <p>This method will be invoked on the background worker thread.
      *
      * @param currentVersion The current version of the document's schema.
-     * @param targetVersion The final version that documents need to be migrated to.
+     * @param finalVersion The final version that documents need to be migrated to.
      * @param document The {@link GenericDocument} need to be translated to new version.
      * @return A {@link GenericDocument} in new version.
      */
     @WorkerThread
     @NonNull
     public abstract GenericDocument onDowngrade(
-            int currentVersion, int targetVersion, @NonNull GenericDocument document);
+            int currentVersion, int finalVersion, @NonNull GenericDocument document);
 }
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/RemoveByUriRequest.java b/apex/appsearch/framework/java/external/android/app/appsearch/RemoveByUriRequest.java
index 455cf3a..8da68c0 100644
--- a/apex/appsearch/framework/java/external/android/app/appsearch/RemoveByUriRequest.java
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/RemoveByUriRequest.java
@@ -59,48 +59,16 @@
      * <p>Once {@link #build} is called, the instance can no longer be used.
      */
     public static final class Builder {
-        private String mNamespace;
+        private final String mNamespace;
         private final Set<String> mUris = new ArraySet<>();
         private boolean mBuilt = false;
 
-        /**
-         * TODO(b/181887768): This method exists only for dogfooder transition and must be removed.
-         *
-         * @deprecated Please supply the namespace in {@link #Builder(String)} instead. This method
-         *     exists only for dogfooder transition and must be removed.
-         */
-        @Deprecated
-        public Builder() {
-            mNamespace = GenericDocument.DEFAULT_NAMESPACE;
-        }
-
         /** Creates a {@link RemoveByUriRequest.Builder} instance. */
         public Builder(@NonNull String namespace) {
             mNamespace = Preconditions.checkNotNull(namespace);
         }
 
         /**
-         * Sets the namespace to remove documents for.
-         *
-         * <p>If this is not set, it defaults to an empty string.
-         *
-         * <p>TODO(b/181887768): This method exists only for dogfooder transition and must be
-         * removed.
-         *
-         * @throws IllegalStateException if the builder has already been used.
-         * @deprecated Please supply the namespace in {@link #Builder(String)} instead. This method
-         *     exists only for dogfooder transition and must
-         */
-        @Deprecated
-        @NonNull
-        public Builder setNamespace(@NonNull String namespace) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
-            Preconditions.checkNotNull(namespace);
-            mNamespace = namespace;
-            return this;
-        }
-
-        /**
          * Adds one or more URIs to the request.
          *
          * @throws IllegalStateException if the builder has already been used.
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/ReportSystemUsageRequest.java b/apex/appsearch/framework/java/external/android/app/appsearch/ReportSystemUsageRequest.java
new file mode 100644
index 0000000..2e152f8
--- /dev/null
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/ReportSystemUsageRequest.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.appsearch;
+
+import android.annotation.NonNull;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * A request to report usage of a document owned by another app from a system UI surface.
+ *
+ * <p>Usage reported in this way is measured separately from usage reported via {@link
+ * AppSearchSession#reportUsage}.
+ *
+ * <p>See {@link GlobalSearchSession#reportSystemUsage} for a detailed description of usage
+ * reporting.
+ */
+public final class ReportSystemUsageRequest {
+    private final String mPackageName;
+    private final String mDatabase;
+    private final String mNamespace;
+    private final String mUri;
+    private final long mUsageTimeMillis;
+
+    ReportSystemUsageRequest(
+            @NonNull String packageName,
+            @NonNull String database,
+            @NonNull String namespace,
+            @NonNull String uri,
+            long usageTimeMillis) {
+        mPackageName = Preconditions.checkNotNull(packageName);
+        mDatabase = Preconditions.checkNotNull(database);
+        mNamespace = Preconditions.checkNotNull(namespace);
+        mUri = Preconditions.checkNotNull(uri);
+        mUsageTimeMillis = usageTimeMillis;
+    }
+
+    /** Returns the package name of the app which owns the document that was used. */
+    @NonNull
+    public String getPackageName() {
+        return mPackageName;
+    }
+
+    /** Returns the database in which the document that was used resides. */
+    @NonNull
+    public String getDatabaseName() {
+        return mDatabase;
+    }
+
+    /** Returns the namespace of the document that was used. */
+    @NonNull
+    public String getNamespace() {
+        return mNamespace;
+    }
+
+    /** Returns the URI of document that was used. */
+    @NonNull
+    public String getUri() {
+        return mUri;
+    }
+
+    /**
+     * Returns the timestamp in milliseconds of the usage report (the time at which the document was
+     * used).
+     *
+     * <p>The value is in the {@link System#currentTimeMillis} time base.
+     */
+    public long getUsageTimeMillis() {
+        return mUsageTimeMillis;
+    }
+
+    /** Builder for {@link ReportSystemUsageRequest} objects. */
+    public static final class Builder {
+        private final String mPackageName;
+        private final String mDatabase;
+        private final String mNamespace;
+        private String mUri;
+        private Long mUsageTimeMillis;
+        private boolean mBuilt = false;
+
+        /** Creates a {@link ReportSystemUsageRequest.Builder} instance. */
+        public Builder(
+                @NonNull String packageName, @NonNull String database, @NonNull String namespace) {
+            mPackageName = Preconditions.checkNotNull(packageName);
+            mDatabase = Preconditions.checkNotNull(database);
+            mNamespace = Preconditions.checkNotNull(namespace);
+        }
+
+        /**
+         * Sets the URI of the document being used.
+         *
+         * <p>This field is required.
+         *
+         * @throws IllegalStateException if the builder has already been used
+         */
+        @NonNull
+        public ReportSystemUsageRequest.Builder setUri(@NonNull String uri) {
+            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            Preconditions.checkNotNull(uri);
+            mUri = uri;
+            return this;
+        }
+
+        /**
+         * Sets the timestamp in milliseconds of the usage report (the time at which the document
+         * was used).
+         *
+         * <p>The value is in the {@link System#currentTimeMillis} time base.
+         *
+         * <p>If unset, this defaults to the current timestamp at the time that the {@link
+         * ReportSystemUsageRequest} is constructed.
+         *
+         * @throws IllegalStateException if the builder has already been used
+         */
+        @NonNull
+        public ReportSystemUsageRequest.Builder setUsageTimeMillis(long usageTimeMillis) {
+            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            mUsageTimeMillis = usageTimeMillis;
+            return this;
+        }
+
+        /**
+         * Builds a new {@link ReportSystemUsageRequest}.
+         *
+         * @throws NullPointerException if {@link #setUri} has never been called
+         * @throws IllegalStateException if the builder has already been used
+         */
+        @NonNull
+        public ReportSystemUsageRequest build() {
+            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            Preconditions.checkNotNull(mUri, "ReportUsageRequest is missing a URI");
+            if (mUsageTimeMillis == null) {
+                mUsageTimeMillis = System.currentTimeMillis();
+            }
+            mBuilt = true;
+            return new ReportSystemUsageRequest(
+                    mPackageName, mDatabase, mNamespace, mUri, mUsageTimeMillis);
+        }
+    }
+}
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/ReportUsageRequest.java b/apex/appsearch/framework/java/external/android/app/appsearch/ReportUsageRequest.java
index 2cd08c6..646e73c 100644
--- a/apex/appsearch/framework/java/external/android/app/appsearch/ReportUsageRequest.java
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/ReportUsageRequest.java
@@ -62,49 +62,17 @@
 
     /** Builder for {@link ReportUsageRequest} objects. */
     public static final class Builder {
-        private String mNamespace;
+        private final String mNamespace;
         private String mUri;
         private Long mUsageTimeMillis;
         private boolean mBuilt = false;
 
-        /**
-         * TODO(b/181887768): This method exists only for dogfooder transition and must be removed.
-         *
-         * @deprecated Please supply the namespace in {@link #Builder(String)} instead. This method
-         *     exists only for dogfooder transition and must be removed.
-         */
-        @Deprecated
-        public Builder() {
-            mNamespace = GenericDocument.DEFAULT_NAMESPACE;
-        }
-
         /** Creates a {@link ReportUsageRequest.Builder} instance. */
         public Builder(@NonNull String namespace) {
             mNamespace = Preconditions.checkNotNull(namespace);
         }
 
         /**
-         * Sets which namespace the document being used belongs to.
-         *
-         * <p>If this is not set, it defaults to an empty string.
-         *
-         * <p>TODO(b/181887768): This method exists only for dogfooder transition and must be
-         * removed.
-         *
-         * @throws IllegalStateException if the builder has already been used
-         * @deprecated Please supply the namespace in {@link #Builder(String)} instead. This method
-         *     exists only for dogfooder transition and must
-         */
-        @Deprecated
-        @NonNull
-        public ReportUsageRequest.Builder setNamespace(@NonNull String namespace) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
-            Preconditions.checkNotNull(namespace);
-            mNamespace = namespace;
-            return this;
-        }
-
-        /**
          * Sets the URI of the document being used.
          *
          * <p>This field is required.
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/SearchResult.java b/apex/appsearch/framework/java/external/android/app/appsearch/SearchResult.java
index cb20849..55a228d 100644
--- a/apex/appsearch/framework/java/external/android/app/appsearch/SearchResult.java
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/SearchResult.java
@@ -47,6 +47,7 @@
     static final String MATCHES_FIELD = "matches";
     static final String PACKAGE_NAME_FIELD = "packageName";
     static final String DATABASE_NAME_FIELD = "databaseName";
+    static final String RANKING_SIGNAL_FIELD = "rankingSignal";
 
     @NonNull private final Bundle mBundle;
 
@@ -67,13 +68,6 @@
         return mBundle;
     }
 
-    /** @deprecated TODO(b/181887768): This method exists only for dogfooder transition. */
-    @NonNull
-    @Deprecated
-    public GenericDocument getDocument() {
-        return getGenericDocument();
-    }
-
     /**
      * Contains the matching {@link GenericDocument}.
      *
@@ -131,6 +125,36 @@
         return Preconditions.checkNotNull(mBundle.getString(DATABASE_NAME_FIELD));
     }
 
+    /**
+     * Returns the ranking signal of the {@link GenericDocument}, according to the ranking strategy
+     * set in {@link SearchSpec.Builder#setRankingStrategy(int)}.
+     *
+     * <p>The meaning of the ranking signal and its value is determined by the selected ranking
+     * strategy:
+     *
+     * <ul>
+     *   <li>{@link SearchSpec#RANKING_STRATEGY_NONE} - this value will be 0
+     *   <li>{@link SearchSpec#RANKING_STRATEGY_DOCUMENT_SCORE} - the value returned by calling
+     *       {@link GenericDocument#getScore()} on the document returned by {@link
+     *       #getGenericDocument()}
+     *   <li>{@link SearchSpec#RANKING_STRATEGY_CREATION_TIMESTAMP} - the value returned by calling
+     *       {@link GenericDocument#getCreationTimestampMillis()} on the document returned by {@link
+     *       #getGenericDocument()}
+     *   <li>{@link SearchSpec#RANKING_STRATEGY_RELEVANCE_SCORE} - an arbitrary double value where a
+     *       higher value means more relevant
+     *   <li>{@link SearchSpec#RANKING_STRATEGY_USAGE_COUNT} - the number of times usage has been
+     *       reported for the document returned by {@link #getGenericDocument()}
+     *   <li>{@link SearchSpec#RANKING_STRATEGY_USAGE_LAST_USED_TIMESTAMP} - the timestamp of the
+     *       most recent usage that has been reported for the document returned by {@link
+     *       #getGenericDocument()}
+     * </ul>
+     *
+     * @return Ranking signal of the document
+     */
+    public double getRankingSignal() {
+        return mBundle.getDouble(RANKING_SIGNAL_FIELD);
+    }
+
     /** Builder for {@link SearchResult} objects. */
     public static final class Builder {
         private final Bundle mBundle = new Bundle();
@@ -173,6 +197,14 @@
             return this;
         }
 
+        /** Sets the ranking signal of the matched document in this SearchResult. */
+        @NonNull
+        public Builder setRankingSignal(double rankingSignal) {
+            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            mBundle.putDouble(RANKING_SIGNAL_FIELD, rankingSignal);
+            return this;
+        }
+
         /**
          * Constructs a new {@link SearchResult}.
          *
@@ -316,13 +348,6 @@
             return mFullText;
         }
 
-        /** @deprecated TODO(b/181887768): This method exists only for dogfooder transition. */
-        @NonNull
-        @Deprecated
-        public MatchRange getExactMatchPosition() {
-            return getExactMatchRange();
-        }
-
         /**
          * Gets the exact {@link MatchRange} corresponding to the given entry.
          *
@@ -349,13 +374,6 @@
             return getSubstring(getExactMatchRange());
         }
 
-        /** @deprecated TODO(b/181887768): This method exists only for dogfooder transition. */
-        @NonNull
-        @Deprecated
-        public MatchRange getSnippetPosition() {
-            return getSnippetRange();
-        }
-
         /**
          * Gets the snippet {@link MatchRange} corresponding to the given entry.
          *
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/SearchSpec.java b/apex/appsearch/framework/java/external/android/app/appsearch/SearchSpec.java
index 7888c8d..19d9430 100644
--- a/apex/appsearch/framework/java/external/android/app/appsearch/SearchSpec.java
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/SearchSpec.java
@@ -19,6 +19,7 @@
 import android.annotation.IntDef;
 import android.annotation.IntRange;
 import android.annotation.NonNull;
+import android.annotation.SuppressLint;
 import android.app.appsearch.exceptions.IllegalSearchSpecException;
 import android.os.Bundle;
 import android.util.ArrayMap;
@@ -58,6 +59,8 @@
     static final String SNIPPET_COUNT_PER_PROPERTY_FIELD = "snippetCountPerProperty";
     static final String MAX_SNIPPET_FIELD = "maxSnippet";
     static final String PROJECTION_TYPE_PROPERTY_PATHS_FIELD = "projectionTypeFieldMasks";
+    static final String RESULT_GROUPING_TYPE_FLAGS = "resultGroupingTypeFlags";
+    static final String RESULT_GROUPING_LIMIT = "resultGroupingLimit";
 
     /** @hide */
     public static final int DEFAULT_NUM_PER_PAGE = 10;
@@ -107,7 +110,9 @@
                 RANKING_STRATEGY_CREATION_TIMESTAMP,
                 RANKING_STRATEGY_RELEVANCE_SCORE,
                 RANKING_STRATEGY_USAGE_COUNT,
-                RANKING_STRATEGY_USAGE_LAST_USED_TIMESTAMP
+                RANKING_STRATEGY_USAGE_LAST_USED_TIMESTAMP,
+                RANKING_STRATEGY_SYSTEM_USAGE_COUNT,
+                RANKING_STRATEGY_SYSTEM_USAGE_LAST_USED_TIMESTAMP,
             })
     @Retention(RetentionPolicy.SOURCE)
     public @interface RankingStrategy {}
@@ -120,10 +125,14 @@
     public static final int RANKING_STRATEGY_CREATION_TIMESTAMP = 2;
     /** Ranked by document relevance score. */
     public static final int RANKING_STRATEGY_RELEVANCE_SCORE = 3;
-    /** Ranked by number of usages. */
+    /** Ranked by number of usages, as reported by the app. */
     public static final int RANKING_STRATEGY_USAGE_COUNT = 4;
-    /** Ranked by timestamp of last usage. */
+    /** Ranked by timestamp of last usage, as reported by the app. */
     public static final int RANKING_STRATEGY_USAGE_LAST_USED_TIMESTAMP = 5;
+    /** Ranked by number of usages from a system UI surface. */
+    public static final int RANKING_STRATEGY_SYSTEM_USAGE_COUNT = 6;
+    /** Ranked by timestamp of last usage from a system UI surface. */
+    public static final int RANKING_STRATEGY_SYSTEM_USAGE_LAST_USED_TIMESTAMP = 7;
 
     /**
      * Order for query result.
@@ -141,6 +150,28 @@
     /** Search results will be returned in an ascending order. */
     public static final int ORDER_ASCENDING = 1;
 
+    /**
+     * Grouping type for result limits.
+     *
+     * @hide
+     */
+    @IntDef(
+            flag = true,
+            value = {GROUPING_TYPE_PER_PACKAGE, GROUPING_TYPE_PER_NAMESPACE})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface GroupingType {}
+
+    /**
+     * Results should be grouped together by package for the purpose of enforcing a limit on the
+     * number of results returned per package.
+     */
+    public static final int GROUPING_TYPE_PER_PACKAGE = 0b01;
+    /**
+     * Results should be grouped together by namespace for the purpose of enforcing a limit on the
+     * number of results returned per namespace.
+     */
+    public static final int GROUPING_TYPE_PER_NAMESPACE = 0b10;
+
     private final Bundle mBundle;
 
     /** @hide */
@@ -259,6 +290,24 @@
         return typePropertyPathsMap;
     }
 
+    /**
+     * Get the type of grouping limit to apply, or 0 if {@link Builder#setResultGrouping} was not
+     * called.
+     */
+    public @GroupingType int getResultGroupingTypeFlags() {
+        return mBundle.getInt(RESULT_GROUPING_TYPE_FLAGS);
+    }
+
+    /**
+     * Get the maximum number of results to return for each group.
+     *
+     * @return the maximum number of results to return for each group or Integer.MAX_VALUE if {@link
+     *     Builder#setResultGrouping(int, int)} was not called.
+     */
+    public int getResultGroupingLimit() {
+        return mBundle.getInt(RESULT_GROUPING_LIMIT, Integer.MAX_VALUE);
+    }
+
     /** Builder for {@link SearchSpec objects}. */
     public static final class Builder {
 
@@ -391,7 +440,7 @@
             Preconditions.checkArgumentInRange(
                     rankingStrategy,
                     RANKING_STRATEGY_NONE,
-                    RANKING_STRATEGY_USAGE_LAST_USED_TIMESTAMP,
+                    RANKING_STRATEGY_SYSTEM_USAGE_LAST_USED_TIMESTAMP,
                     "Result ranking strategy");
             mBundle.putInt(RANKING_STRATEGY_FIELD, rankingStrategy);
             return this;
@@ -549,6 +598,34 @@
         }
 
         /**
+         * Set the maximum number of results to return for each group, where groups are defined by
+         * grouping type.
+         *
+         * <p>Calling this method will override any previous calls. So calling
+         * setResultGrouping(GROUPING_TYPE_PER_PACKAGE, 7) and then calling
+         * setResultGrouping(GROUPING_TYPE_PER_PACKAGE, 2) will result in only the latter, a limit
+         * of two results per package, being applied. Or calling setResultGrouping
+         * (GROUPING_TYPE_PER_PACKAGE, 1) and then calling setResultGrouping
+         * (GROUPING_TYPE_PER_PACKAGE | GROUPING_PER_NAMESPACE, 5) will result in five results per
+         * package per namespace.
+         *
+         * @param groupingTypeFlags One or more combination of grouping types.
+         * @param limit Number of results to return per {@code groupingTypeFlags}.
+         * @throws IllegalArgumentException if groupingTypeFlags is zero.
+         */
+        // Individual parameters available from getResultGroupingTypeFlags and
+        // getResultGroupingLimit
+        @SuppressLint("MissingGetterMatchingBuilder")
+        @NonNull
+        public Builder setResultGrouping(@GroupingType int groupingTypeFlags, int limit) {
+            Preconditions.checkState(
+                    groupingTypeFlags != 0, "Result grouping type cannot be zero.");
+            mBundle.putInt(RESULT_GROUPING_TYPE_FLAGS, groupingTypeFlags);
+            mBundle.putInt(RESULT_GROUPING_LIMIT, limit);
+            return this;
+        }
+
+        /**
          * Constructs a new {@link SearchSpec} from the contents of this builder.
          *
          * <p>After calling this method, the builder must no longer be used.
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/SetSchemaRequest.java b/apex/appsearch/framework/java/external/android/app/appsearch/SetSchemaRequest.java
index c1eedcd..1324451 100644
--- a/apex/appsearch/framework/java/external/android/app/appsearch/SetSchemaRequest.java
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/SetSchemaRequest.java
@@ -16,6 +16,7 @@
 
 package android.app.appsearch;
 
+import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.annotation.SuppressLint;
 import android.util.ArrayMap;
@@ -84,18 +85,21 @@
     private final Map<String, Set<PackageIdentifier>> mSchemasVisibleToPackages;
     private final Map<String, Migrator> mMigrators;
     private final boolean mForceOverride;
+    private final int mVersion;
 
     SetSchemaRequest(
             @NonNull Set<AppSearchSchema> schemas,
             @NonNull Set<String> schemasNotDisplayedBySystem,
             @NonNull Map<String, Set<PackageIdentifier>> schemasVisibleToPackages,
             @NonNull Map<String, Migrator> migrators,
-            boolean forceOverride) {
+            boolean forceOverride,
+            int version) {
         mSchemas = Preconditions.checkNotNull(schemas);
         mSchemasNotDisplayedBySystem = Preconditions.checkNotNull(schemasNotDisplayedBySystem);
         mSchemasVisibleToPackages = Preconditions.checkNotNull(schemasVisibleToPackages);
         mMigrators = Preconditions.checkNotNull(migrators);
         mForceOverride = forceOverride;
+        mVersion = version;
     }
 
     /** Returns the {@link AppSearchSchema} types that are part of this request. */
@@ -105,16 +109,6 @@
     }
 
     /**
-     * TODO(b/181887768): This method exists only for dogfooder transition and must be removed.
-     * @deprecated This method exists only for dogfooder transition and must be removed.
-     */
-    @Deprecated
-    @NonNull
-    public Set<String> getSchemasNotVisibleToSystemUi() {
-        return getSchemasNotDisplayedBySystem();
-    }
-
-    /**
      * Returns all the schema types that are opted out of being displayed and visible on any system
      * UI surface.
      */
@@ -166,6 +160,12 @@
         return mForceOverride;
     }
 
+    /** Returns the database overall schema version. */
+    @IntRange(from = 1)
+    public int getVersion() {
+        return mVersion;
+    }
+
     /**
      * Builder for {@link SetSchemaRequest} objects.
      *
@@ -178,6 +178,7 @@
                 new ArrayMap<>();
         private final Map<String, Migrator> mMigrators = new ArrayMap<>();
         private boolean mForceOverride = false;
+        private int mVersion = 1;
         private boolean mBuilt = false;
 
         /**
@@ -211,17 +212,6 @@
         }
 
         /**
-         * TODO(b/181887768): This method exists only for dogfooder transition and must be removed.
-         * @deprecated This method exists only for dogfooder transition and must be removed.
-         */
-        @Deprecated
-        @NonNull
-        public Builder setSchemaTypeVisibilityForSystemUi(
-                @NonNull String schemaType, boolean displayed) {
-            return setSchemaTypeDisplayedBySystem(schemaType, displayed);
-        }
-
-        /**
          * Sets whether or not documents from the provided {@code schemaType} will be displayed and
          * visible on any system UI surface.
          *
@@ -323,6 +313,19 @@
         }
 
         /**
+         * Sets {@link Migrator}s.
+         *
+         * @param migrators A {@link Map} of migrators that translate a document from its old
+         *     version to a new incompatible version.
+         */
+        @NonNull
+        public Builder setMigrators(@NonNull Map<String, Migrator> migrators) {
+            Preconditions.checkNotNull(migrators);
+            mMigrators.putAll(migrators);
+            return this;
+        }
+
+        /**
          * Sets whether or not to override the current schema in the {@link AppSearchSession}
          * database.
          *
@@ -340,6 +343,37 @@
         }
 
         /**
+         * Sets the version number of the overall {@link AppSearchSchema} in the database.
+         *
+         * <p>The {@link AppSearchSession} database can only ever hold documents for one version at
+         * a time.
+         *
+         * <p>Setting a version number that is different from the version number currently stored in
+         * AppSearch will result in AppSearch calling the {@link Migrator}s provided to {@link
+         * AppSearchSession#setSchema} to migrate the documents already in AppSearch from the
+         * previous version to the one set in this request. The version number can be updated
+         * without any other changes to the set of schemas.
+         *
+         * <p>The version number can stay the same, increase, or decrease relative to the current
+         * version number that is already stored in the {@link AppSearchSession} database.
+         *
+         * @param version A positive integer representing the version of the entire set of schemas
+         *     represents the version of the whole schema in the {@link AppSearchSession} database,
+         *     default version is 1.
+         * @throws IllegalStateException if the version is negative or the builder has already been
+         *     used.
+         * @see AppSearchSession#setSchema
+         * @see Migrator
+         * @see SetSchemaRequest.Builder#setMigrator
+         */
+        @NonNull
+        public Builder setVersion(@IntRange(from = 1) int version) {
+            Preconditions.checkArgument(version >= 1, "Version must be a positive number.");
+            mVersion = version;
+            return this;
+        }
+
+        /**
          * Builds a new {@link SetSchemaRequest} object.
          *
          * @throws IllegalArgumentException if schema types were referenced, but the corresponding
@@ -372,7 +406,8 @@
                     mSchemasNotDisplayedBySystem,
                     mSchemasVisibleToPackages,
                     mMigrators,
-                    mForceOverride);
+                    mForceOverride,
+                    mVersion);
         }
     }
 }
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/StorageInfo.java b/apex/appsearch/framework/java/external/android/app/appsearch/StorageInfo.java
new file mode 100644
index 0000000..dc04cf3
--- /dev/null
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/StorageInfo.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.appsearch;
+
+import android.annotation.NonNull;
+import android.os.Bundle;
+
+import com.android.internal.util.Preconditions;
+
+/** The response class of {@code AppSearchSession#getStorageInfo}. */
+public class StorageInfo {
+
+    private static final String SIZE_BYTES_FIELD = "sizeBytes";
+    private static final String ALIVE_DOCUMENTS_COUNT = "aliveDocumentsCount";
+    private static final String ALIVE_NAMESPACES_COUNT = "aliveNamespacesCount";
+
+    private final Bundle mBundle;
+
+    StorageInfo(@NonNull Bundle bundle) {
+        mBundle = Preconditions.checkNotNull(bundle);
+    }
+
+    /**
+     * Returns the {@link Bundle} populated by this builder.
+     *
+     * @hide
+     */
+    @NonNull
+    public Bundle getBundle() {
+        return mBundle;
+    }
+
+    /** Returns the estimated size of the session's database in bytes. */
+    public long getSizeBytes() {
+        return mBundle.getLong(SIZE_BYTES_FIELD);
+    }
+
+    /**
+     * Returns the number of alive documents in the current session.
+     *
+     * <p>Alive documents are documents that haven't been deleted and haven't exceeded the ttl as
+     * set in {@link GenericDocument.Builder#setTtlMillis}.
+     */
+    public int getAliveDocumentsCount() {
+        return mBundle.getInt(ALIVE_DOCUMENTS_COUNT);
+    }
+
+    /**
+     * Returns the number of namespaces that have at least one alive document in the current
+     * session's database.
+     *
+     * <p>Alive documents are documents that haven't been deleted and haven't exceeded the ttl as
+     * set in {@link GenericDocument.Builder#setTtlMillis}.
+     */
+    public int getAliveNamespacesCount() {
+        return mBundle.getInt(ALIVE_NAMESPACES_COUNT);
+    }
+
+    /** Builder for {@link StorageInfo} objects. */
+    public static final class Builder {
+        private final Bundle mBundle = new Bundle();
+        private boolean mBuilt = false;
+
+        /** Sets the size in bytes. */
+        @NonNull
+        public StorageInfo.Builder setSizeBytes(long sizeBytes) {
+            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            mBundle.putLong(SIZE_BYTES_FIELD, sizeBytes);
+            return this;
+        }
+
+        /** Sets the number of alive documents. */
+        @NonNull
+        public StorageInfo.Builder setAliveDocumentsCount(int numAliveDocuments) {
+            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            mBundle.putInt(ALIVE_DOCUMENTS_COUNT, numAliveDocuments);
+            return this;
+        }
+
+        /** Sets the number of alive namespaces. */
+        @NonNull
+        public StorageInfo.Builder setAliveNamespacesCount(int numAliveNamespaces) {
+            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            mBundle.putInt(ALIVE_NAMESPACES_COUNT, numAliveNamespaces);
+            return this;
+        }
+
+        /** Builds a {@link StorageInfo} object. */
+        @NonNull
+        public StorageInfo build() {
+            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            mBuilt = true;
+            return new StorageInfo(mBundle);
+        }
+    }
+}
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/util/SchemaMigrationUtil.java b/apex/appsearch/framework/java/external/android/app/appsearch/util/SchemaMigrationUtil.java
index fae8ad4..c9473bd 100644
--- a/apex/appsearch/framework/java/external/android/app/appsearch/util/SchemaMigrationUtil.java
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/util/SchemaMigrationUtil.java
@@ -70,7 +70,7 @@
             // we don't have migrator or won't trigger migration for this schema type.
             Migrator migrator = migrators.get(unmigratedSchemaType);
             if (migrator == null
-                    || !migrator.shouldMigrateToFinalVersion(currentVersion, finalVersion)) {
+                    || !migrator.shouldMigrate(currentVersion, finalVersion)) {
                 unmigratedSchemaTypes.add(unmigratedSchemaType);
             }
         }
@@ -102,16 +102,17 @@
                             + schemaType
                             + ", but the schema doesn't exist in the request.");
         }
-        return migrator.shouldMigrateToFinalVersion(currentVersion, finalVersion);
+        return migrator.shouldMigrate(currentVersion, finalVersion);
     }
 
     /** Builds a Map of SchemaType and its version of given set of {@link AppSearchSchema}. */
+    //TODO(b/182620003) remove this method once support migrate to another type
     @NonNull
     public static Map<String, Integer> buildVersionMap(
-            @NonNull Collection<AppSearchSchema> schemas) {
+            @NonNull Collection<AppSearchSchema> schemas, int version) {
         Map<String, Integer> currentVersionMap = new ArrayMap<>(schemas.size());
         for (AppSearchSchema currentSchema : schemas) {
-            currentVersionMap.put(currentSchema.getSchemaType(), currentSchema.getVersion());
+            currentVersionMap.put(currentSchema.getSchemaType(), version);
         }
         return currentVersionMap;
     }
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
index 2806974..991dda7 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
@@ -21,19 +21,24 @@
 import android.annotation.UserIdInt;
 import android.app.ActivityManager;
 import android.app.appsearch.AppSearchBatchResult;
+import android.app.appsearch.AppSearchMigrationHelper;
 import android.app.appsearch.AppSearchResult;
 import android.app.appsearch.AppSearchSchema;
 import android.app.appsearch.GenericDocument;
+import android.app.appsearch.GetSchemaResponse;
 import android.app.appsearch.IAppSearchBatchResultCallback;
 import android.app.appsearch.IAppSearchManager;
 import android.app.appsearch.IAppSearchResultCallback;
 import android.app.appsearch.PackageIdentifier;
 import android.app.appsearch.SearchResultPage;
 import android.app.appsearch.SearchSpec;
+import android.app.appsearch.SetSchemaResponse;
+import android.app.appsearch.StorageInfo;
 import android.content.Context;
 import android.content.pm.PackageManagerInternal;
 import android.os.Binder;
 import android.os.Bundle;
+import android.os.ParcelFileDescriptor;
 import android.os.ParcelableException;
 import android.os.RemoteException;
 import android.os.UserHandle;
@@ -48,6 +53,11 @@
 import com.android.server.SystemService;
 import com.android.server.appsearch.external.localstorage.AppSearchImpl;
 
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.EOFException;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
@@ -96,6 +106,7 @@
                 @NonNull Map<String, List<Bundle>> schemasPackageAccessibleBundles,
                 boolean forceOverride,
                 @UserIdInt int userId,
+                int schemaVersion,
                 @NonNull IAppSearchResultCallback callback) {
             Preconditions.checkNotNull(packageName);
             Preconditions.checkNotNull(databaseName);
@@ -123,15 +134,16 @@
                     schemasPackageAccessible.put(entry.getKey(), packageIdentifiers);
                 }
                 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUserId);
-                impl.setSchema(
+                SetSchemaResponse setSchemaResponse = impl.setSchema(
                         packageName,
                         databaseName,
                         schemas,
                         schemasNotDisplayedBySystem,
                         schemasPackageAccessible,
-                        forceOverride);
-                invokeCallbackOnResult(
-                        callback, AppSearchResult.newSuccessfulResult(/*result=*/ null));
+                        forceOverride,
+                        schemaVersion);
+                invokeCallbackOnResult(callback,
+                        AppSearchResult.newSuccessfulResult(setSchemaResponse.getBundle()));
             } catch (Throwable t) {
                 invokeCallbackOnError(callback, t);
             } finally {
@@ -156,13 +168,35 @@
                 verifyCallingPackage(callingUid, packageName);
                 AppSearchImpl impl =
                         mImplInstanceManager.getAppSearchImpl(callingUserId);
-                List<AppSearchSchema> schemas = impl.getSchema(packageName, databaseName);
-                List<Bundle> schemaBundles = new ArrayList<>(schemas.size());
-                for (int i = 0; i < schemas.size(); i++) {
-                    schemaBundles.add(schemas.get(i).getBundle());
-                }
+                GetSchemaResponse response = impl.getSchema(packageName, databaseName);
                 invokeCallbackOnResult(
-                        callback, AppSearchResult.newSuccessfulResult(schemaBundles));
+                        callback, AppSearchResult.newSuccessfulResult(response.getBundle()));
+            } catch (Throwable t) {
+                invokeCallbackOnError(callback, t);
+            } finally {
+                Binder.restoreCallingIdentity(callingIdentity);
+            }
+        }
+
+        @Override
+        public void getNamespaces(
+                @NonNull String packageName,
+                @NonNull String databaseName,
+                @UserIdInt int userId,
+                @NonNull IAppSearchResultCallback callback) {
+            Preconditions.checkNotNull(packageName);
+            Preconditions.checkNotNull(databaseName);
+            Preconditions.checkNotNull(callback);
+            int callingUid = Binder.getCallingUidOrThrow();
+            int callingUserId = handleIncomingUser(userId, callingUid);
+            final long callingIdentity = Binder.clearCallingIdentity();
+            try {
+                verifyUserUnlocked(callingUserId);
+                verifyCallingPackage(callingUid, packageName);
+                AppSearchImpl impl =
+                        mImplInstanceManager.getAppSearchImpl(callingUserId);
+                List<String> namespaces = impl.getNamespaces(packageName, databaseName);
+                invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(namespaces));
             } catch (Throwable t) {
                 invokeCallbackOnError(callback, t);
             } finally {
@@ -374,12 +408,105 @@
         }
 
         @Override
+        public void writeQueryResultsToFile(
+                @NonNull String packageName,
+                @NonNull String databaseName,
+                @NonNull ParcelFileDescriptor fileDescriptor,
+                @NonNull String queryExpression,
+                @NonNull Bundle searchSpecBundle,
+                @UserIdInt int userId,
+                @NonNull IAppSearchResultCallback callback) {
+            int callingUid = Binder.getCallingUid();
+            int callingUserId = handleIncomingUser(userId, callingUid);
+            final long callingIdentity = Binder.clearCallingIdentity();
+            try {
+                verifyCallingPackage(callingUid, packageName);
+                AppSearchImpl impl =
+                        mImplInstanceManager.getAppSearchImpl(callingUserId);
+                // we don't need to append the file. The file is always brand new.
+                try (DataOutputStream outputStream = new DataOutputStream(
+                        new FileOutputStream(fileDescriptor.getFileDescriptor()))) {
+                    SearchResultPage searchResultPage = impl.query(
+                            packageName,
+                            databaseName,
+                            queryExpression,
+                            new SearchSpec(searchSpecBundle));
+                    while (!searchResultPage.getResults().isEmpty()) {
+                        for (int i = 0; i < searchResultPage.getResults().size(); i++) {
+                            AppSearchMigrationHelper.writeBundleToOutputStream(
+                                    outputStream, searchResultPage.getResults().get(i)
+                                            .getGenericDocument().getBundle());
+                        }
+                        searchResultPage = impl.getNextPage(searchResultPage.getNextPageToken());
+                    }
+                }
+                invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
+            } catch (Throwable t) {
+                invokeCallbackOnError(callback, t);
+            } finally {
+                Binder.restoreCallingIdentity(callingIdentity);
+            }
+        }
+
+        @Override
+        public void putDocumentsFromFile(
+                @NonNull String packageName,
+                @NonNull String databaseName,
+                @NonNull ParcelFileDescriptor fileDescriptor,
+                @UserIdInt int userId,
+                @NonNull IAppSearchResultCallback callback) {
+            int callingUid = Binder.getCallingUid();
+            int callingUserId = handleIncomingUser(userId, callingUid);
+            final long callingIdentity = Binder.clearCallingIdentity();
+            try {
+                verifyCallingPackage(callingUid, packageName);
+                AppSearchImpl impl =
+                        mImplInstanceManager.getAppSearchImpl(callingUserId);
+
+                GenericDocument document;
+                ArrayList<Bundle> migrationFailureBundles = new ArrayList<>();
+                try (DataInputStream inputStream = new DataInputStream(
+                        new FileInputStream(fileDescriptor.getFileDescriptor()))) {
+                    while (true) {
+                        try {
+                            document = AppSearchMigrationHelper
+                                    .readDocumentFromInputStream(inputStream);
+                        } catch (EOFException e) {
+                            // nothing wrong, we just finish the reading.
+                            break;
+                        }
+                        try {
+                            impl.putDocument(packageName, databaseName, document, /*logger=*/ null);
+                        } catch (Throwable t) {
+                            migrationFailureBundles.add(
+                                    new SetSchemaResponse.MigrationFailure.Builder()
+                                            .setNamespace(document.getNamespace())
+                                            .setSchemaType(document.getSchemaType())
+                                            .setUri(document.getUri())
+                                            .setAppSearchResult(
+                                                    AppSearchResult.throwableToFailedResult(t))
+                                            .build().getBundle());
+                        }
+                    }
+                }
+                impl.persistToDisk();
+                invokeCallbackOnResult(callback,
+                        AppSearchResult.newSuccessfulResult(migrationFailureBundles));
+            } catch (Throwable t) {
+                invokeCallbackOnError(callback, t);
+            } finally {
+                Binder.restoreCallingIdentity(callingIdentity);
+            }
+        }
+
+        @Override
         public void reportUsage(
                 @NonNull String packageName,
                 @NonNull String databaseName,
                 @NonNull String namespace,
                 @NonNull String uri,
                 long usageTimeMillis,
+                boolean systemUsage,
                 @UserIdInt int userId,
                 @NonNull IAppSearchResultCallback callback) {
             Objects.requireNonNull(databaseName);
@@ -391,9 +518,16 @@
             final long callingIdentity = Binder.clearCallingIdentity();
             try {
                 verifyUserUnlocked(callingUserId);
+
+                if (systemUsage) {
+                    // TODO(b/183031844): Validate that the call comes from the system
+                }
+
                 AppSearchImpl impl =
                         mImplInstanceManager.getAppSearchImpl(callingUserId);
-                impl.reportUsage(packageName, databaseName, namespace, uri, usageTimeMillis);
+                impl.reportUsage(
+                        packageName, databaseName, namespace, uri,
+                        usageTimeMillis, systemUsage);
                 invokeCallbackOnResult(
                         callback, AppSearchResult.newSuccessfulResult(/*result=*/ null));
             } catch (Throwable t) {
@@ -477,6 +611,34 @@
         }
 
         @Override
+        public void getStorageInfo(
+                @NonNull String packageName,
+                @NonNull String databaseName,
+                @UserIdInt int userId,
+                @NonNull IAppSearchResultCallback callback) {
+            Preconditions.checkNotNull(packageName);
+            Preconditions.checkNotNull(databaseName);
+            Preconditions.checkNotNull(callback);
+            int callingUid = Binder.getCallingUid();
+            int callingUserId = handleIncomingUser(userId, callingUid);
+            final long callingIdentity = Binder.clearCallingIdentity();
+            try {
+                verifyUserUnlocked(callingUserId);
+                verifyCallingPackage(callingUid, packageName);
+                AppSearchImpl impl =
+                        mImplInstanceManager.getAppSearchImpl(callingUserId);
+                StorageInfo storageInfo = impl.getStorageInfoForDatabase(packageName, databaseName);
+                Bundle storageInfoBundle = storageInfo.getBundle();
+                invokeCallbackOnResult(
+                        callback, AppSearchResult.newSuccessfulResult(storageInfoBundle));
+            } catch (Throwable t) {
+                invokeCallbackOnError(callback, t);
+            } finally {
+                Binder.restoreCallingIdentity(callingIdentity);
+            }
+        }
+
+        @Override
         public void persistToDisk(@UserIdInt int userId) {
             int callingUid = Binder.getCallingUidOrThrow();
             int callingUserId = handleIncomingUser(userId, callingUid);
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/ImplInstanceManager.java b/apex/appsearch/service/java/com/android/server/appsearch/ImplInstanceManager.java
index 8c953d1..cacf880 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/ImplInstanceManager.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/ImplInstanceManager.java
@@ -25,7 +25,6 @@
 import android.content.pm.PackageManager;
 import android.os.Environment;
 import android.os.UserHandle;
-import android.os.storage.StorageManager;
 import android.util.SparseArray;
 
 import com.android.internal.R;
@@ -130,11 +129,7 @@
 
     private static File getAppSearchDir(@NonNull Context context, @UserIdInt int userId) {
         // See com.android.internal.app.ChooserActivity::getPinnedSharedPrefs
-        //TODO(b/177685938):Switch from getDataUserCePackageDirectory to getDataSystemCeDirectory
-        File userCeDir =
-                Environment.getDataUserCePackageDirectory(
-                        StorageManager.UUID_PRIVATE_INTERNAL, userId, context.getPackageName());
-        return new File(userCeDir, APP_SEARCH_DIR);
+        return new File(Environment.getDataSystemCeDirectory(userId), APP_SEARCH_DIR);
     }
 
     /**
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/VisibilityStore.java b/apex/appsearch/service/java/com/android/server/appsearch/VisibilityStore.java
index ad94a0a..1ed26d6 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/VisibilityStore.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/VisibilityStore.java
@@ -24,6 +24,7 @@
 import android.app.appsearch.AppSearchResult;
 import android.app.appsearch.AppSearchSchema;
 import android.app.appsearch.GenericDocument;
+import android.app.appsearch.GetSchemaResponse;
 import android.app.appsearch.PackageIdentifier;
 import android.app.appsearch.exceptions.AppSearchException;
 import android.content.Context;
@@ -73,6 +74,9 @@
     /** Schema type for documents that hold AppSearch's metadata, e.g. visibility settings */
     private static final String VISIBILITY_TYPE = "VisibilityType";
 
+    /** Version for the visibility schema */
+    private static final int SCHEMA_VERSION = 0;
+
     /**
      * Property that holds the list of platform-hidden schemas, as part of the visibility settings.
      */
@@ -152,7 +156,7 @@
             AppSearchImpl.createPrefix(PACKAGE_NAME, DATABASE_NAME);
 
     /** Namespace of documents that contain visibility settings */
-    private static final String NAMESPACE = GenericDocument.DEFAULT_NAMESPACE;
+    private static final String NAMESPACE = "";
 
     /**
      * Prefix to add to all visibility document uri's. IcingSearchEngine doesn't allow empty uri's.
@@ -218,11 +222,10 @@
      * @throws AppSearchException AppSearchException on AppSearchImpl error.
      */
     public void initialize() throws AppSearchException {
-        List<AppSearchSchema> schemas = mAppSearchImpl.getSchema(PACKAGE_NAME, DATABASE_NAME);
+        GetSchemaResponse getSchemaResponse = mAppSearchImpl.getSchema(PACKAGE_NAME, DATABASE_NAME);
         boolean hasVisibilityType = false;
         boolean hasPackageAccessibleType = false;
-        for (int i = 0; i < schemas.size(); i++) {
-            AppSearchSchema schema = schemas.get(i);
+        for (AppSearchSchema schema : getSchemaResponse.getSchemas()) {
             if (schema.getSchemaType().equals(VISIBILITY_TYPE)) {
                 hasVisibilityType = true;
             } else if (schema.getSchemaType().equals(PACKAGE_ACCESSIBLE_TYPE)) {
@@ -242,7 +245,8 @@
                     Arrays.asList(VISIBILITY_SCHEMA, PACKAGE_ACCESSIBLE_SCHEMA),
                     /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
                     /*schemasPackageAccessible=*/ Collections.emptyMap(),
-                    /*forceOverride=*/ false);
+                    /*forceOverride=*/ false,
+                    /*version=*/ SCHEMA_VERSION);
         }
 
         // Populate visibility settings set
@@ -333,9 +337,9 @@
         Preconditions.checkNotNull(schemasPackageAccessible);
 
         // Persist the document
-        GenericDocument.Builder visibilityDocument =
-                new GenericDocument.Builder(/*uri=*/ addUriPrefix(prefix), VISIBILITY_TYPE)
-                        .setNamespace(NAMESPACE);
+        GenericDocument.Builder<?> visibilityDocument =
+                new GenericDocument.Builder<>(
+                        NAMESPACE, /*uri=*/ addUriPrefix(prefix), VISIBILITY_TYPE);
         if (!schemasNotPlatformSurfaceable.isEmpty()) {
             visibilityDocument.setPropertyString(
                     NOT_PLATFORM_SURFACEABLE_PROPERTY,
@@ -347,17 +351,16 @@
         for (Map.Entry<String, List<PackageIdentifier>> entry :
                 schemasPackageAccessible.entrySet()) {
             for (int i = 0; i < entry.getValue().size(); i++) {
-                GenericDocument packageAccessibleDocument =
-                        new GenericDocument.Builder(/*uri=*/ "", PACKAGE_ACCESSIBLE_TYPE)
-                                .setNamespace(NAMESPACE)
-                                .setPropertyString(
-                                        PACKAGE_NAME_PROPERTY,
-                                        entry.getValue().get(i).getPackageName())
-                                .setPropertyBytes(
-                                        SHA_256_CERT_PROPERTY,
-                                        entry.getValue().get(i).getSha256Certificate())
-                                .setPropertyString(ACCESSIBLE_SCHEMA_PROPERTY, entry.getKey())
-                                .build();
+                GenericDocument packageAccessibleDocument = new GenericDocument.Builder<>(
+                        NAMESPACE, /*uri=*/ "", PACKAGE_ACCESSIBLE_TYPE)
+                        .setPropertyString(
+                                PACKAGE_NAME_PROPERTY,
+                                entry.getValue().get(i).getPackageName())
+                        .setPropertyBytes(
+                                SHA_256_CERT_PROPERTY,
+                                entry.getValue().get(i).getSha256Certificate())
+                        .setPropertyString(ACCESSIBLE_SCHEMA_PROPERTY, entry.getKey())
+                        .build();
                 packageAccessibleDocuments.add(packageAccessibleDocument);
             }
             schemaToPackageIdentifierMap.put(entry.getKey(), new ArraySet<>(entry.getValue()));
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java
index 5e8760e..de9d609 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java
@@ -23,10 +23,12 @@
 import android.app.appsearch.AppSearchSchema;
 import android.app.appsearch.GenericDocument;
 import android.app.appsearch.GetByUriRequest;
+import android.app.appsearch.GetSchemaResponse;
 import android.app.appsearch.PackageIdentifier;
 import android.app.appsearch.SearchResultPage;
 import android.app.appsearch.SearchSpec;
 import android.app.appsearch.SetSchemaResponse;
+import android.app.appsearch.StorageInfo;
 import android.app.appsearch.exceptions.AppSearchException;
 import android.content.Context;
 import android.os.Bundle;
@@ -51,6 +53,7 @@
 import com.google.android.icing.proto.DeleteByQueryResultProto;
 import com.google.android.icing.proto.DeleteResultProto;
 import com.google.android.icing.proto.DocumentProto;
+import com.google.android.icing.proto.DocumentStorageInfoProto;
 import com.google.android.icing.proto.GetAllNamespacesResultProto;
 import com.google.android.icing.proto.GetOptimizeInfoResultProto;
 import com.google.android.icing.proto.GetResultProto;
@@ -58,8 +61,10 @@
 import com.google.android.icing.proto.GetSchemaResultProto;
 import com.google.android.icing.proto.IcingSearchEngineOptions;
 import com.google.android.icing.proto.InitializeResultProto;
+import com.google.android.icing.proto.NamespaceStorageInfoProto;
 import com.google.android.icing.proto.OptimizeResultProto;
 import com.google.android.icing.proto.PersistToDiskResultProto;
+import com.google.android.icing.proto.PersistType;
 import com.google.android.icing.proto.PropertyConfigProto;
 import com.google.android.icing.proto.PropertyProto;
 import com.google.android.icing.proto.PutResultProto;
@@ -73,6 +78,7 @@
 import com.google.android.icing.proto.SearchSpecProto;
 import com.google.android.icing.proto.SetSchemaResultProto;
 import com.google.android.icing.proto.StatusProto;
+import com.google.android.icing.proto.StorageInfoResultProto;
 import com.google.android.icing.proto.TypePropertyMask;
 import com.google.android.icing.proto.UsageReport;
 
@@ -295,11 +301,12 @@
      * @param schemasPackageAccessible Schema types that are visible to the specified packages.
      * @param forceOverride Whether to force-apply the schema even if it is incompatible. Documents
      *     which do not comply with the new schema will be deleted.
+     * @param version The overall version number of the request.
+     * @return The response contains deleted schema types and incompatible schema types of this
+     *     call.
      * @throws AppSearchException On IcingSearchEngine error. If the status code is
      *     FAILED_PRECONDITION for the incompatible change, the exception will be converted to the
      *     SetSchemaResponse.
-     * @return The response contains deleted schema types and incompatible schema types of this
-     *     call.
      */
     @NonNull
     public SetSchemaResponse setSchema(
@@ -308,7 +315,8 @@
             @NonNull List<AppSearchSchema> schemas,
             @NonNull List<String> schemasNotPlatformSurfaceable,
             @NonNull Map<String, List<PackageIdentifier>> schemasPackageAccessible,
-            boolean forceOverride)
+            boolean forceOverride,
+            int version)
             throws AppSearchException {
         mReadWriteLock.writeLock().lock();
         try {
@@ -320,7 +328,7 @@
             for (int i = 0; i < schemas.size(); i++) {
                 AppSearchSchema schema = schemas.get(i);
                 SchemaTypeConfigProto schemaTypeProto =
-                        SchemaToProtoConverter.toSchemaTypeConfigProto(schema);
+                        SchemaToProtoConverter.toSchemaTypeConfigProto(schema, version);
                 newSchemaBuilder.addTypes(schemaTypeProto);
             }
 
@@ -394,8 +402,8 @@
      * @throws AppSearchException on IcingSearchEngine error.
      */
     @NonNull
-    public List<AppSearchSchema> getSchema(
-            @NonNull String packageName, @NonNull String databaseName) throws AppSearchException {
+    public GetSchemaResponse getSchema(@NonNull String packageName, @NonNull String databaseName)
+            throws AppSearchException {
         mReadWriteLock.readLock().lock();
         try {
             throwIfClosedLocked();
@@ -403,7 +411,12 @@
             SchemaProto fullSchema = getSchemaProtoLocked();
 
             String prefix = createPrefix(packageName, databaseName);
-            List<AppSearchSchema> result = new ArrayList<>();
+            GetSchemaResponse.Builder responseBuilder = new GetSchemaResponse.Builder();
+            if (!fullSchema.getTypesList().isEmpty()) {
+                // TODO(b/183050495) find a place to store the version for the database, rather
+                // than read from a schema.
+                responseBuilder.setVersion(fullSchema.getTypes(0).getVersion());
+            }
             for (int i = 0; i < fullSchema.getTypesCount(); i++) {
                 String typePrefix = getPrefix(fullSchema.getTypes(i).getSchemaType());
                 if (!prefix.equals(typePrefix)) {
@@ -431,9 +444,44 @@
 
                 AppSearchSchema schema =
                         SchemaToProtoConverter.toAppSearchSchema(typeConfigBuilder);
-                result.add(schema);
+                responseBuilder.addSchema(schema);
             }
-            return result;
+            return responseBuilder.build();
+        } finally {
+            mReadWriteLock.readLock().unlock();
+        }
+    }
+
+    /**
+     * Retrieves the list of namespaces with at least one document for this package name, database.
+     *
+     * <p>This method belongs to query group.
+     *
+     * @param packageName Package name that owns this schema
+     * @param databaseName The name of the database where this schema lives.
+     * @throws AppSearchException on IcingSearchEngine error.
+     */
+    @NonNull
+    public List<String> getNamespaces(@NonNull String packageName, @NonNull String databaseName)
+            throws AppSearchException {
+        mReadWriteLock.readLock().lock();
+        try {
+            throwIfClosedLocked();
+            // We can't just use mNamespaceMap here because we have no way to prune namespaces from
+            // mNamespaceMap when they have no more documents (e.g. after setting schema to empty or
+            // using deleteByQuery).
+            GetAllNamespacesResultProto getAllNamespacesResultProto =
+                    mIcingSearchEngineLocked.getAllNamespaces();
+            checkSuccess(getAllNamespacesResultProto.getStatus());
+            String prefix = createPrefix(packageName, databaseName);
+            List<String> results = new ArrayList<>();
+            for (int i = 0; i < getAllNamespacesResultProto.getNamespacesCount(); i++) {
+                String prefixedNamespace = getAllNamespacesResultProto.getNamespaces(i);
+                if (prefixedNamespace.startsWith(prefix)) {
+                    results.add(prefixedNamespace.substring(prefix.length()));
+                }
+            }
+            return results;
         } finally {
             mReadWriteLock.readLock().unlock();
         }
@@ -749,6 +797,18 @@
         ResultSpecProto.Builder resultSpecBuilder =
                 SearchSpecToProtoConverter.toResultSpecProto(searchSpec).toBuilder();
 
+        int groupingType = searchSpec.getResultGroupingTypeFlags();
+        if ((groupingType & SearchSpec.GROUPING_TYPE_PER_PACKAGE) != 0
+                && (groupingType & SearchSpec.GROUPING_TYPE_PER_NAMESPACE) != 0) {
+            addPerPackagePerNamespaceResultGroupingsLocked(
+                    resultSpecBuilder, prefixes, searchSpec.getResultGroupingLimit());
+        } else if ((groupingType & SearchSpec.GROUPING_TYPE_PER_PACKAGE) != 0) {
+            addPerPackageResultGroupingsLocked(
+                    resultSpecBuilder, prefixes, searchSpec.getResultGroupingLimit());
+        } else if ((groupingType & SearchSpec.GROUPING_TYPE_PER_NAMESPACE) != 0) {
+            addPerNamespaceResultGroupingsLocked(
+                    resultSpecBuilder, prefixes, searchSpec.getResultGroupingLimit());
+        }
         rewriteResultSpecForPrefixesLocked(resultSpecBuilder, prefixes, allowedPrefixedSchemas);
 
         ScoringSpecProto scoringSpec = SearchSpecToProtoConverter.toScoringSpecProto(searchSpec);
@@ -810,19 +870,24 @@
             @NonNull String databaseName,
             @NonNull String namespace,
             @NonNull String uri,
-            long usageTimestampMillis)
+            long usageTimestampMillis,
+            boolean systemUsage)
             throws AppSearchException {
         mReadWriteLock.writeLock().lock();
         try {
             throwIfClosedLocked();
 
             String prefixedNamespace = createPrefix(packageName, databaseName) + namespace;
+            UsageReport.UsageType usageType =
+                    systemUsage
+                            ? UsageReport.UsageType.USAGE_TYPE2
+                            : UsageReport.UsageType.USAGE_TYPE1;
             UsageReport report =
                     UsageReport.newBuilder()
                             .setDocumentNamespace(prefixedNamespace)
                             .setDocumentUri(uri)
                             .setUsageTimestampMs(usageTimestampMillis)
-                            .setUsageType(UsageReport.UsageType.USAGE_TYPE1)
+                            .setUsageType(usageType)
                             .build();
 
             ReportUsageResultProto result = mIcingSearchEngineLocked.reportUsage(report);
@@ -919,6 +984,124 @@
         }
     }
 
+    /** Estimates the storage usage info for a specific package. */
+    @NonNull
+    public StorageInfo getStorageInfoForPackage(@NonNull String packageName)
+            throws AppSearchException {
+        mReadWriteLock.readLock().lock();
+        try {
+            throwIfClosedLocked();
+
+            Map<String, Set<String>> packageToDatabases = getPackageToDatabases();
+            Set<String> databases = packageToDatabases.get(packageName);
+            if (databases == null) {
+                // Package doesn't exist, no storage info to report
+                return new StorageInfo.Builder().build();
+            }
+
+            // Accumulate all the namespaces we're interested in.
+            Set<String> wantedPrefixedNamespaces = new ArraySet<>();
+            for (String database : databases) {
+                Set<String> prefixedNamespaces =
+                        mNamespaceMapLocked.get(createPrefix(packageName, database));
+                if (prefixedNamespaces != null) {
+                    wantedPrefixedNamespaces.addAll(prefixedNamespaces);
+                }
+            }
+            if (wantedPrefixedNamespaces.isEmpty()) {
+                return new StorageInfo.Builder().build();
+            }
+
+            return getStorageInfoForNamespacesLocked(wantedPrefixedNamespaces);
+        } finally {
+            mReadWriteLock.readLock().unlock();
+        }
+    }
+
+    /** Estimates the storage usage info for a specific database in a package. */
+    @NonNull
+    public StorageInfo getStorageInfoForDatabase(
+            @NonNull String packageName, @NonNull String databaseName) throws AppSearchException {
+        mReadWriteLock.readLock().lock();
+        try {
+            throwIfClosedLocked();
+
+            Map<String, Set<String>> packageToDatabases = getPackageToDatabases();
+            Set<String> databases = packageToDatabases.get(packageName);
+            if (databases == null) {
+                // Package doesn't exist, no storage info to report
+                return new StorageInfo.Builder().build();
+            }
+            if (!databases.contains(databaseName)) {
+                // Database doesn't exist, no storage info to report
+                return new StorageInfo.Builder().build();
+            }
+
+            Set<String> wantedPrefixedNamespaces =
+                    mNamespaceMapLocked.get(createPrefix(packageName, databaseName));
+            if (wantedPrefixedNamespaces == null || wantedPrefixedNamespaces.isEmpty()) {
+                return new StorageInfo.Builder().build();
+            }
+
+            return getStorageInfoForNamespacesLocked(wantedPrefixedNamespaces);
+        } finally {
+            mReadWriteLock.readLock().unlock();
+        }
+    }
+
+    @GuardedBy("mReadWriteLock")
+    @NonNull
+    private StorageInfo getStorageInfoForNamespacesLocked(@NonNull Set<String> prefixedNamespaces)
+            throws AppSearchException {
+        StorageInfoResultProto storageInfoResult = mIcingSearchEngineLocked.getStorageInfo();
+        checkSuccess(storageInfoResult.getStatus());
+        if (!storageInfoResult.hasStorageInfo()
+                || !storageInfoResult.getStorageInfo().hasDocumentStorageInfo()) {
+            return new StorageInfo.Builder().build();
+        }
+        long totalStorageSize = storageInfoResult.getStorageInfo().getTotalStorageSize();
+
+        DocumentStorageInfoProto documentStorageInfo =
+                storageInfoResult.getStorageInfo().getDocumentStorageInfo();
+        int totalDocuments =
+                documentStorageInfo.getNumAliveDocuments()
+                        + documentStorageInfo.getNumExpiredDocuments();
+
+        if (totalStorageSize == 0 || totalDocuments == 0) {
+            // Maybe we can exit early and also avoid a divide by 0 error.
+            return new StorageInfo.Builder().build();
+        }
+
+        // Accumulate stats across the package's namespaces.
+        int aliveDocuments = 0;
+        int expiredDocuments = 0;
+        int aliveNamespaces = 0;
+        List<NamespaceStorageInfoProto> namespaceStorageInfos =
+                documentStorageInfo.getNamespaceStorageInfoList();
+        for (int i = 0; i < namespaceStorageInfos.size(); i++) {
+            NamespaceStorageInfoProto namespaceStorageInfo = namespaceStorageInfos.get(i);
+            // The namespace from icing lib is already the prefixed format
+            if (prefixedNamespaces.contains(namespaceStorageInfo.getNamespace())) {
+                if (namespaceStorageInfo.getNumAliveDocuments() > 0) {
+                    aliveNamespaces++;
+                    aliveDocuments += namespaceStorageInfo.getNumAliveDocuments();
+                }
+                expiredDocuments += namespaceStorageInfo.getNumExpiredDocuments();
+            }
+        }
+        int namespaceDocuments = aliveDocuments + expiredDocuments;
+
+        // Since we don't have the exact size of all the documents, we do an estimation. Note
+        // that while the total storage takes into account schema, index, etc. in addition to
+        // documents, we'll only calculate the percentage based on number of documents a
+        // client has.
+        return new StorageInfo.Builder()
+                .setSizeBytes((long) (namespaceDocuments * 1.0 / totalDocuments * totalStorageSize))
+                .setAliveDocumentsCount(aliveDocuments)
+                .setAliveNamespacesCount(aliveNamespaces)
+                .build();
+    }
+
     /**
      * Persists all update/delete requests to the disk.
      *
@@ -937,7 +1120,7 @@
             throwIfClosedLocked();
 
             PersistToDiskResultProto persistToDiskResultProto =
-                    mIcingSearchEngineLocked.persistToDisk();
+                    mIcingSearchEngineLocked.persistToDisk(PersistType.Code.FULL);
             checkSuccess(persistToDiskResultProto.getStatus());
         } finally {
             mReadWriteLock.writeLock().unlock();
@@ -1275,6 +1458,153 @@
                 .addAllTypePropertyMasks(prefixedTypePropertyMasks);
     }
 
+    /**
+     * Adds result groupings for each namespace in each package being queried for.
+     *
+     * <p>This method should be only called in query methods and get the READ lock to keep thread
+     * safety.
+     *
+     * @param resultSpecBuilder ResultSpecs as specified by client
+     * @param prefixes Prefixes that we should prepend to all our filters
+     * @param maxNumResults The maximum number of results for each grouping to support.
+     */
+    @GuardedBy("mReadWriteLock")
+    private void addPerPackagePerNamespaceResultGroupingsLocked(
+            @NonNull ResultSpecProto.Builder resultSpecBuilder,
+            @NonNull Set<String> prefixes,
+            int maxNumResults) {
+        Set<String> existingPrefixes = new ArraySet<>(mNamespaceMapLocked.keySet());
+        existingPrefixes.retainAll(prefixes);
+
+        // Create a map for package+namespace to prefixedNamespaces. This is NOT necessarily the
+        // same as the list of namespaces. If one package has multiple databases, each with the same
+        // namespace, then those should be grouped together.
+        Map<String, List<String>> packageAndNamespaceToNamespaces = new ArrayMap<>();
+        for (String prefix : existingPrefixes) {
+            Set<String> prefixedNamespaces = mNamespaceMapLocked.get(prefix);
+            String packageName = getPackageName(prefix);
+            // Create a new prefix without the database name. This will allow us to group namespaces
+            // that have the same name and package but a different database name together.
+            String emptyDatabasePrefix = createPrefix(packageName, /*databaseName*/ "");
+            for (String prefixedNamespace : prefixedNamespaces) {
+                String namespace;
+                try {
+                    namespace = removePrefix(prefixedNamespace);
+                } catch (AppSearchException e) {
+                    // This should never happen. Skip this namespace if it does.
+                    Log.e(TAG, "Prefixed namespace " + prefixedNamespace + " is malformed.");
+                    continue;
+                }
+                String emptyDatabasePrefixedNamespace = emptyDatabasePrefix + namespace;
+                List<String> namespaceList =
+                        packageAndNamespaceToNamespaces.get(emptyDatabasePrefixedNamespace);
+                if (namespaceList == null) {
+                    namespaceList = new ArrayList<>();
+                    packageAndNamespaceToNamespaces.put(
+                            emptyDatabasePrefixedNamespace, namespaceList);
+                }
+                namespaceList.add(prefixedNamespace);
+            }
+        }
+
+        for (List<String> namespaces : packageAndNamespaceToNamespaces.values()) {
+            resultSpecBuilder.addResultGroupings(
+                    ResultSpecProto.ResultGrouping.newBuilder()
+                            .addAllNamespaces(namespaces)
+                            .setMaxResults(maxNumResults));
+        }
+    }
+
+    /**
+     * Adds result groupings for each package being queried for.
+     *
+     * <p>This method should be only called in query methods and get the READ lock to keep thread
+     * safety.
+     *
+     * @param resultSpecBuilder ResultSpecs as specified by client
+     * @param prefixes Prefixes that we should prepend to all our filters
+     * @param maxNumResults The maximum number of results for each grouping to support.
+     */
+    @GuardedBy("mReadWriteLock")
+    private void addPerPackageResultGroupingsLocked(
+            @NonNull ResultSpecProto.Builder resultSpecBuilder,
+            @NonNull Set<String> prefixes,
+            int maxNumResults) {
+        Set<String> existingPrefixes = new ArraySet<>(mNamespaceMapLocked.keySet());
+        existingPrefixes.retainAll(prefixes);
+
+        // Build up a map of package to namespaces.
+        Map<String, List<String>> packageToNamespacesMap = new ArrayMap<>();
+        for (String prefix : existingPrefixes) {
+            Set<String> prefixedNamespaces = mNamespaceMapLocked.get(prefix);
+            String packageName = getPackageName(prefix);
+            List<String> packageNamespaceList = packageToNamespacesMap.get(packageName);
+            if (packageNamespaceList == null) {
+                packageNamespaceList = new ArrayList<>();
+                packageToNamespacesMap.put(packageName, packageNamespaceList);
+            }
+            packageNamespaceList.addAll(prefixedNamespaces);
+        }
+
+        for (List<String> prefixedNamespaces : packageToNamespacesMap.values()) {
+            resultSpecBuilder.addResultGroupings(
+                    ResultSpecProto.ResultGrouping.newBuilder()
+                            .addAllNamespaces(prefixedNamespaces)
+                            .setMaxResults(maxNumResults));
+        }
+    }
+
+    /**
+     * Adds result groupings for each namespace being queried for.
+     *
+     * <p>This method should be only called in query methods and get the READ lock to keep thread
+     * safety.
+     *
+     * @param resultSpecBuilder ResultSpecs as specified by client
+     * @param prefixes Prefixes that we should prepend to all our filters
+     * @param maxNumResults The maximum number of results for each grouping to support.
+     */
+    @GuardedBy("mReadWriteLock")
+    private void addPerNamespaceResultGroupingsLocked(
+            @NonNull ResultSpecProto.Builder resultSpecBuilder,
+            @NonNull Set<String> prefixes,
+            int maxNumResults) {
+        Set<String> existingPrefixes = new ArraySet<>(mNamespaceMapLocked.keySet());
+        existingPrefixes.retainAll(prefixes);
+
+        // Create a map of namespace to prefixedNamespaces. This is NOT necessarily the
+        // same as the list of namespaces. If a namespace exists under different packages and/or
+        // different databases, they should still be grouped together.
+        Map<String, List<String>> namespaceToPrefixedNamespaces = new ArrayMap<>();
+        for (String prefix : existingPrefixes) {
+            Set<String> prefixedNamespaces = mNamespaceMapLocked.get(prefix);
+            for (String prefixedNamespace : prefixedNamespaces) {
+                String namespace;
+                try {
+                    namespace = removePrefix(prefixedNamespace);
+                } catch (AppSearchException e) {
+                    // This should never happen. Skip this namespace if it does.
+                    Log.e(TAG, "Prefixed namespace " + prefixedNamespace + " is malformed.");
+                    continue;
+                }
+                List<String> groupedPrefixedNamespaces =
+                        namespaceToPrefixedNamespaces.get(namespace);
+                if (groupedPrefixedNamespaces == null) {
+                    groupedPrefixedNamespaces = new ArrayList<>();
+                    namespaceToPrefixedNamespaces.put(namespace, groupedPrefixedNamespaces);
+                }
+                groupedPrefixedNamespaces.add(prefixedNamespace);
+            }
+        }
+
+        for (List<String> namespaces : namespaceToPrefixedNamespaces.values()) {
+            resultSpecBuilder.addResultGroupings(
+                    ResultSpecProto.ResultGrouping.newBuilder()
+                            .addAllNamespaces(namespaces)
+                            .setMaxResults(maxNumResults));
+        }
+    }
+
     @VisibleForTesting
     @GuardedBy("mReadWriteLock")
     SchemaProto getSchemaProtoLocked() throws AppSearchException {
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverter.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverter.java
index ce1c9f4..800b073 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverter.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverter.java
@@ -46,12 +46,13 @@
      * SchemaTypeConfigProto}.
      */
     @NonNull
-    public static SchemaTypeConfigProto toSchemaTypeConfigProto(@NonNull AppSearchSchema schema) {
+    public static SchemaTypeConfigProto toSchemaTypeConfigProto(
+            @NonNull AppSearchSchema schema, int version) {
         Preconditions.checkNotNull(schema);
         SchemaTypeConfigProto.Builder protoBuilder =
                 SchemaTypeConfigProto.newBuilder()
                         .setSchemaType(schema.getSchemaType())
-                        .setVersion(schema.getVersion());
+                        .setVersion(version);
         List<AppSearchSchema.PropertyConfig> properties = schema.getProperties();
         for (int i = 0; i < properties.size(); i++) {
             PropertyConfigProto propertyProto = toPropertyConfigProto(properties.get(i));
@@ -116,8 +117,7 @@
     @NonNull
     public static AppSearchSchema toAppSearchSchema(@NonNull SchemaTypeConfigProtoOrBuilder proto) {
         Preconditions.checkNotNull(proto);
-        AppSearchSchema.Builder builder =
-                new AppSearchSchema.Builder(proto.getSchemaType()).setVersion(proto.getVersion());
+        AppSearchSchema.Builder builder = new AppSearchSchema.Builder(proto.getSchemaType());
         List<PropertyConfigProto> properties = proto.getPropertiesList();
         for (int i = 0; i < properties.size(); i++) {
             AppSearchSchema.PropertyConfig propertyConfig = toPropertyConfig(properties.get(i));
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SearchResultToProtoConverter.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SearchResultToProtoConverter.java
index 1d8db72..bf7e533 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SearchResultToProtoConverter.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SearchResultToProtoConverter.java
@@ -87,7 +87,9 @@
         GenericDocument document =
                 GenericDocumentToProtoConverter.toGenericDocument(proto.getDocument());
         SearchResult.Builder builder =
-                new SearchResult.Builder(packageName, databaseName).setGenericDocument(document);
+                new SearchResult.Builder(packageName, databaseName)
+                        .setGenericDocument(document)
+                        .setRankingSignal(proto.getScore());
         if (proto.hasSnippet()) {
             for (int i = 0; i < proto.getSnippet().getEntriesCount(); i++) {
                 SnippetProto.EntryProto entry = proto.getSnippet().getEntries(i);
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SearchSpecToProtoConverter.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SearchSpecToProtoConverter.java
index 3b5e275..d9e8adb 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SearchSpecToProtoConverter.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SearchSpecToProtoConverter.java
@@ -104,6 +104,10 @@
                 return ScoringSpecProto.RankingStrategy.Code.USAGE_TYPE1_COUNT;
             case SearchSpec.RANKING_STRATEGY_USAGE_LAST_USED_TIMESTAMP:
                 return ScoringSpecProto.RankingStrategy.Code.USAGE_TYPE1_LAST_USED_TIMESTAMP;
+            case SearchSpec.RANKING_STRATEGY_SYSTEM_USAGE_COUNT:
+                return ScoringSpecProto.RankingStrategy.Code.USAGE_TYPE2_COUNT;
+            case SearchSpec.RANKING_STRATEGY_SYSTEM_USAGE_LAST_USED_TIMESTAMP:
+                return ScoringSpecProto.RankingStrategy.Code.USAGE_TYPE2_LAST_USED_TIMESTAMP;
             default:
                 throw new IllegalArgumentException(
                         "Invalid result ranking strategy: " + rankingStrategyCode);
diff --git a/apex/appsearch/synced_jetpack_changeid.txt b/apex/appsearch/synced_jetpack_changeid.txt
index 0952215..58f430b 100644
--- a/apex/appsearch/synced_jetpack_changeid.txt
+++ b/apex/appsearch/synced_jetpack_changeid.txt
@@ -1 +1 @@
-I723a9d7b5e64329ab25b6d7627f3b2d222c31ac7
+Ie11a0555775a0ab2a39f6ce6d0d8a7b735c416ce
diff --git a/apex/appsearch/testing/java/com/android/server/appsearch/testing/AppSearchSessionShimImpl.java b/apex/appsearch/testing/java/com/android/server/appsearch/testing/AppSearchSessionShimImpl.java
index 9ef6e0b..f0de496 100644
--- a/apex/appsearch/testing/java/com/android/server/appsearch/testing/AppSearchSessionShimImpl.java
+++ b/apex/appsearch/testing/java/com/android/server/appsearch/testing/AppSearchSessionShimImpl.java
@@ -20,12 +20,12 @@
 import android.app.appsearch.AppSearchBatchResult;
 import android.app.appsearch.AppSearchManager;
 import android.app.appsearch.AppSearchResult;
-import android.app.appsearch.AppSearchSchema;
 import android.app.appsearch.AppSearchSession;
 import android.app.appsearch.AppSearchSessionShim;
 import android.app.appsearch.BatchResultCallback;
 import android.app.appsearch.GenericDocument;
 import android.app.appsearch.GetByUriRequest;
+import android.app.appsearch.GetSchemaResponse;
 import android.app.appsearch.PutDocumentsRequest;
 import android.app.appsearch.RemoveByUriRequest;
 import android.app.appsearch.ReportUsageRequest;
@@ -34,6 +34,7 @@
 import android.app.appsearch.SearchSpec;
 import android.app.appsearch.SetSchemaRequest;
 import android.app.appsearch.SetSchemaResponse;
+import android.app.appsearch.StorageInfo;
 import android.app.appsearch.exceptions.AppSearchException;
 import android.content.Context;
 
@@ -88,18 +89,26 @@
     @NonNull
     public ListenableFuture<SetSchemaResponse> setSchema(@NonNull SetSchemaRequest request) {
         SettableFuture<AppSearchResult<SetSchemaResponse>> future = SettableFuture.create();
-        mAppSearchSession.setSchema(request, mExecutor, future::set);
+        mAppSearchSession.setSchema(request, mExecutor, mExecutor, future::set);
         return Futures.transformAsync(future, this::transformResult, mExecutor);
     }
 
     @Override
     @NonNull
-    public ListenableFuture<Set<AppSearchSchema>> getSchema() {
-        SettableFuture<AppSearchResult<Set<AppSearchSchema>>> future = SettableFuture.create();
+    public ListenableFuture<GetSchemaResponse> getSchema() {
+        SettableFuture<AppSearchResult<GetSchemaResponse>> future = SettableFuture.create();
         mAppSearchSession.getSchema(mExecutor, future::set);
         return Futures.transformAsync(future, this::transformResult, mExecutor);
     }
 
+    @NonNull
+    @Override
+    public ListenableFuture<Set<String>> getNamespaces() {
+        SettableFuture<AppSearchResult<Set<String>>> future = SettableFuture.create();
+        mAppSearchSession.getNamespaces(mExecutor, future::set);
+        return Futures.transformAsync(future, this::transformResult, mExecutor);
+    }
+
     @Override
     @NonNull
     public ListenableFuture<AppSearchBatchResult<String, Void>> put(
@@ -154,6 +163,14 @@
         return Futures.transformAsync(future, this::transformResult, mExecutor);
     }
 
+    @NonNull
+    @Override
+    public ListenableFuture<StorageInfo> getStorageInfo() {
+        SettableFuture<AppSearchResult<StorageInfo>> future = SettableFuture.create();
+        mAppSearchSession.getStorageInfo(mExecutor, future::set);
+        return Futures.transformAsync(future, this::transformResult, mExecutor);
+    }
+
     @Override
     public void close() {
         mAppSearchSession.close();
diff --git a/apex/appsearch/testing/java/com/android/server/appsearch/testing/GlobalSearchSessionShimImpl.java b/apex/appsearch/testing/java/com/android/server/appsearch/testing/GlobalSearchSessionShimImpl.java
index 69a4c18..5042ce0 100644
--- a/apex/appsearch/testing/java/com/android/server/appsearch/testing/GlobalSearchSessionShimImpl.java
+++ b/apex/appsearch/testing/java/com/android/server/appsearch/testing/GlobalSearchSessionShimImpl.java
@@ -21,9 +21,11 @@
 import android.app.appsearch.AppSearchResult;
 import android.app.appsearch.GlobalSearchSession;
 import android.app.appsearch.GlobalSearchSessionShim;
+import android.app.appsearch.ReportSystemUsageRequest;
 import android.app.appsearch.SearchResults;
 import android.app.appsearch.SearchResultsShim;
 import android.app.appsearch.SearchSpec;
+import android.app.appsearch.exceptions.AppSearchException;
 import android.content.Context;
 
 import androidx.test.core.app.ApplicationProvider;
@@ -79,8 +81,24 @@
         return new SearchResultsShimImpl(searchResults, mExecutor);
     }
 
+    @NonNull
+    @Override
+    public ListenableFuture<Void> reportSystemUsage(@NonNull ReportSystemUsageRequest request) {
+        SettableFuture<AppSearchResult<Void>> future = SettableFuture.create();
+        mGlobalSearchSession.reportSystemUsage(request, mExecutor, future::set);
+        return Futures.transformAsync(future, this::transformResult, mExecutor);
+    }
+
     @Override
     public void close() {
         mGlobalSearchSession.close();
     }
+
+    private <T> ListenableFuture<T> transformResult(
+            @NonNull AppSearchResult<T> result) throws AppSearchException {
+        if (!result.isSuccess()) {
+            throw new AppSearchException(result.getResultCode(), result.getErrorMessage());
+        }
+        return Futures.immediateFuture(result.getResultValue());
+    }
 }
diff --git a/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/AppSearchSessionShim.java b/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/AppSearchSessionShim.java
index 1428fb1..2069043 100644
--- a/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/AppSearchSessionShim.java
+++ b/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/AppSearchSessionShim.java
@@ -52,12 +52,20 @@
     /**
      * Retrieves the schema most recently successfully provided to {@link #setSchema}.
      *
-     * @return The pending result of performing this operation.
+     * @return The pending {@link GetSchemaResponse} of performing this operation.
      */
     // This call hits disk; async API prevents us from treating these calls as properties.
     @SuppressLint("KotlinPropertyAccess")
     @NonNull
-    ListenableFuture<Set<AppSearchSchema>> getSchema();
+    ListenableFuture<GetSchemaResponse> getSchema();
+
+    /**
+     * Retrieves the set of all namespaces in the current database with at least one document.
+     *
+     * @return The pending result of performing this operation.
+     */
+    @NonNull
+    ListenableFuture<Set<String>> getNamespaces();
 
     /**
      * Indexes documents into the {@link AppSearchSessionShim} database.
@@ -214,6 +222,17 @@
     ListenableFuture<Void> remove(@NonNull String queryExpression, @NonNull SearchSpec searchSpec);
 
     /**
+     * Gets the storage info for this {@link AppSearchSessionShim} database.
+     *
+     * <p>This may take time proportional to the number of documents and may be inefficient to call
+     * repeatedly.
+     *
+     * @return a {@link ListenableFuture} which resolves to a {@link StorageInfo} object.
+     */
+    @NonNull
+    ListenableFuture<StorageInfo> getStorageInfo();
+
+    /**
      * Flush all schema and document updates, additions, and deletes to disk if possible.
      *
      * @return The pending result of performing this operation. {@link
diff --git a/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/AppSearchTestUtils.java b/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/AppSearchTestUtils.java
index 4a3c7a5..fd4734c 100644
--- a/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/AppSearchTestUtils.java
+++ b/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/AppSearchTestUtils.java
@@ -73,14 +73,22 @@
 
     public static List<GenericDocument> convertSearchResultsToDocuments(
             SearchResultsShim searchResults) throws Exception {
-        List<SearchResult> results = searchResults.getNextPage().get();
-        List<GenericDocument> documents = new ArrayList<>();
-        while (results.size() > 0) {
-            for (SearchResult result : results) {
-                documents.add(result.getGenericDocument());
-            }
-            results = searchResults.getNextPage().get();
+        List<SearchResult> results = retrieveAllSearchResults(searchResults);
+        List<GenericDocument> documents = new ArrayList<>(results.size());
+        for (SearchResult result : results) {
+            documents.add(result.getGenericDocument());
         }
         return documents;
     }
+
+    public static List<SearchResult> retrieveAllSearchResults(SearchResultsShim searchResults)
+            throws Exception {
+        List<SearchResult> page = searchResults.getNextPage().get();
+        List<SearchResult> results = new ArrayList<>();
+        while (!page.isEmpty()) {
+            results.addAll(page);
+            page = searchResults.getNextPage().get();
+        }
+        return results;
+    }
 }
diff --git a/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/GlobalSearchSessionShim.java b/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/GlobalSearchSessionShim.java
index 440050f..f39916e 100644
--- a/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/GlobalSearchSessionShim.java
+++ b/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/GlobalSearchSessionShim.java
@@ -18,6 +18,8 @@
 
 import android.annotation.NonNull;
 
+import com.google.common.util.concurrent.ListenableFuture;
+
 import java.io.Closeable;
 
 /**
@@ -51,6 +53,26 @@
     @NonNull
     SearchResultsShim search(@NonNull String queryExpression, @NonNull SearchSpec searchSpec);
 
+    /**
+     * Reports that a particular document has been used from a system surface.
+     *
+     * <p>See {@link AppSearchSessionShim#reportUsage} for a general description of document usage,
+     * as well as an API that can be used by the app itself.
+     *
+     * <p>Usage reported via this method is accounted separately from usage reported via {@link
+     * AppSearchSessionShim#reportUsage} and may be accessed using the constants {@link
+     * SearchSpec#RANKING_STRATEGY_SYSTEM_USAGE_COUNT} and {@link
+     * SearchSpec#RANKING_STRATEGY_SYSTEM_USAGE_LAST_USED_TIMESTAMP}.
+     *
+     * @return The pending result of performing this operation which resolves to {@code null} on
+     *     success. The pending result will be completed with an {@link
+     *     android.app.appsearch.exceptions.AppSearchException} with a code of {@link
+     *     AppSearchResult#RESULT_SECURITY_ERROR} if this API is invoked by an app which is not part
+     *     of the system.
+     */
+    @NonNull
+    ListenableFuture<Void> reportSystemUsage(@NonNull ReportSystemUsageRequest request);
+
     /** Closes the {@link GlobalSearchSessionShim}. */
     @Override
     void close();
diff --git a/apex/blobstore/framework/java/android/app/blob/BlobStoreManager.java b/apex/blobstore/framework/java/android/app/blob/BlobStoreManager.java
index 38500af..22ee501 100644
--- a/apex/blobstore/framework/java/android/app/blob/BlobStoreManager.java
+++ b/apex/blobstore/framework/java/android/app/blob/BlobStoreManager.java
@@ -258,7 +258,8 @@
     public @NonNull ParcelFileDescriptor openBlob(@NonNull BlobHandle blobHandle)
             throws IOException {
         try {
-            return mService.openBlob(blobHandle, mContext.getOpPackageName());
+            return mService.openBlob(blobHandle, mContext.getOpPackageName(),
+                    mContext.getAttributionTag());
         } catch (ParcelableException e) {
             e.maybeRethrow(IOException.class);
             throw new RuntimeException(e);
@@ -315,7 +316,7 @@
             @CurrentTimeMillisLong long leaseExpiryTimeMillis) throws IOException {
         try {
             mService.acquireLease(blobHandle, descriptionResId, null, leaseExpiryTimeMillis,
-                    mContext.getOpPackageName());
+                    mContext.getOpPackageName(), mContext.getAttributionTag());
         } catch (ParcelableException e) {
             e.maybeRethrow(IOException.class);
             e.maybeRethrow(LimitExceededException.class);
@@ -378,7 +379,7 @@
             @CurrentTimeMillisLong long leaseExpiryTimeMillis) throws IOException {
         try {
             mService.acquireLease(blobHandle, INVALID_RES_ID, description, leaseExpiryTimeMillis,
-                    mContext.getOpPackageName());
+                    mContext.getOpPackageName(), mContext.getAttributionTag());
         } catch (ParcelableException e) {
             e.maybeRethrow(IOException.class);
             e.maybeRethrow(LimitExceededException.class);
@@ -497,7 +498,8 @@
      */
     public void releaseLease(@NonNull BlobHandle blobHandle) throws IOException {
         try {
-            mService.releaseLease(blobHandle, mContext.getOpPackageName());
+            mService.releaseLease(blobHandle, mContext.getOpPackageName(),
+                    mContext.getAttributionTag());
         } catch (ParcelableException e) {
             e.maybeRethrow(IOException.class);
             throw new RuntimeException(e);
@@ -602,7 +604,8 @@
     @Nullable
     public LeaseInfo getLeaseInfo(@NonNull BlobHandle blobHandle) throws IOException {
         try {
-            return mService.getLeaseInfo(blobHandle, mContext.getOpPackageName());
+            return mService.getLeaseInfo(blobHandle, mContext.getOpPackageName(),
+                    mContext.getAttributionTag());
         } catch (ParcelableException e) {
             e.maybeRethrow(IOException.class);
             throw new RuntimeException(e);
@@ -897,6 +900,64 @@
         }
 
         /**
+         * Allow apps with location permission to access this blob data once it is committed using
+         * a {@link BlobHandle} representing the blob.
+         *
+         * <p> This needs to be called before committing the blob using
+         * {@link #commit(Executor, Consumer)}.
+         *
+         * Note that if a caller allows access to the blob using this API in addition to other APIs
+         * like {@link #allowPackageAccess(String, byte[])}, then apps satisfying any one of these
+         * access conditions will be allowed to access the blob.
+         *
+         * @param permissionName the name of the location permission that needs to be granted
+         *                       for the app. This can be either one of
+         *                       {@link android.Manifest.permission#ACCESS_FINE_LOCATION} or
+         *                       {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}.
+         *
+         * @throws IOException when there is an I/O error while changing the access.
+         * @throws SecurityException when the caller is not the owner of the session.
+         * @throws IllegalStateException when the caller tries to change access for a blob which is
+         *                               already committed.
+         */
+        public void allowPackagesWithLocationPermission(@NonNull String permissionName)
+                throws IOException {
+            try {
+                mSession.allowPackagesWithLocationPermission(permissionName);
+            } catch (ParcelableException e) {
+                e.maybeRethrow(IOException.class);
+                throw new RuntimeException(e);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+
+        /**
+         * Returns {@code true} if access has been allowed for apps with location permission by
+         * using {@link #allowPackagesWithLocationPermission(String)}.
+         *
+         * @param permissionName the name of the location permission that needs to be granted
+         *                       for the app. This can be either one of
+         *                       {@link android.Manifest.permission#ACCESS_FINE_LOCATION} or
+         *                       {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}.
+         *
+         * @throws IOException when there is an I/O error while getting the access type.
+         * @throws IllegalStateException when the caller tries to get access type from a session
+         *                               which is closed or abandoned.
+         */
+        public boolean arePackagesWithLocationPermissionAllowed(@NonNull String permissionName)
+                throws IOException {
+            try {
+                return mSession.arePackagesWithLocationPermissionAllowed(permissionName);
+            } catch (ParcelableException e) {
+                e.maybeRethrow(IOException.class);
+                throw new RuntimeException(e);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+
+        /**
          * Commit the file that was written so far to this session to the blob store maintained by
          * the system.
          *
diff --git a/apex/blobstore/framework/java/android/app/blob/IBlobStoreManager.aidl b/apex/blobstore/framework/java/android/app/blob/IBlobStoreManager.aidl
index 39a9fb4..db6cb5c9 100644
--- a/apex/blobstore/framework/java/android/app/blob/IBlobStoreManager.aidl
+++ b/apex/blobstore/framework/java/android/app/blob/IBlobStoreManager.aidl
@@ -25,12 +25,13 @@
 interface IBlobStoreManager {
     long createSession(in BlobHandle handle, in String packageName);
     IBlobStoreSession openSession(long sessionId, in String packageName);
-    ParcelFileDescriptor openBlob(in BlobHandle handle, in String packageName);
+    ParcelFileDescriptor openBlob(in BlobHandle handle, in String packageName,
+           in String attributionTag);
     void abandonSession(long sessionId, in String packageName);
 
     void acquireLease(in BlobHandle handle, int descriptionResId, in CharSequence description,
-            long leaseTimeoutMillis, in String packageName);
-    void releaseLease(in BlobHandle handle, in String packageName);
+            long leaseTimeoutMillis, in String packageName, in String attributionTag);
+    void releaseLease(in BlobHandle handle, in String packageName, in String attributionTag);
     long getRemainingLeaseQuotaBytes(String packageName);
 
     void waitForIdle(in RemoteCallback callback);
@@ -39,5 +40,6 @@
     void deleteBlob(long blobId);
 
     List<BlobHandle> getLeasedBlobs(in String packageName);
-    LeaseInfo getLeaseInfo(in BlobHandle blobHandle, in String packageName);
+    LeaseInfo getLeaseInfo(in BlobHandle blobHandle, in String packageName,
+            in String attributionTag);
 }
\ No newline at end of file
diff --git a/apex/blobstore/framework/java/android/app/blob/IBlobStoreSession.aidl b/apex/blobstore/framework/java/android/app/blob/IBlobStoreSession.aidl
index 4035b96..e3ccfb8 100644
--- a/apex/blobstore/framework/java/android/app/blob/IBlobStoreSession.aidl
+++ b/apex/blobstore/framework/java/android/app/blob/IBlobStoreSession.aidl
@@ -26,10 +26,12 @@
     void allowPackageAccess(in String packageName, in byte[] certificate);
     void allowSameSignatureAccess();
     void allowPublicAccess();
+    void allowPackagesWithLocationPermission(in String permissionName);
 
     boolean isPackageAccessAllowed(in String packageName, in byte[] certificate);
     boolean isSameSignatureAccessAllowed();
     boolean isPublicAccessAllowed();
+    boolean arePackagesWithLocationPermissionAllowed(in String permissionName);
 
     long getSize();
     void close();
diff --git a/apex/blobstore/framework/java/android/app/blob/XmlTags.java b/apex/blobstore/framework/java/android/app/blob/XmlTags.java
index bfc5826..6e4b2f7 100644
--- a/apex/blobstore/framework/java/android/app/blob/XmlTags.java
+++ b/apex/blobstore/framework/java/android/app/blob/XmlTags.java
@@ -38,6 +38,7 @@
     public static final String ATTR_TYPE = "t";
     public static final String TAG_ALLOWED_PACKAGE = "wl";
     public static final String ATTR_CERTIFICATE = "ct";
+    public static final String TAG_ALLOWED_PERMISSION = "ap";
 
     // For BlobHandle
     public static final String TAG_BLOB_HANDLE = "bh";
@@ -55,4 +56,7 @@
     public static final String TAG_LEASEE = "l";
     public static final String ATTR_DESCRIPTION_RES_NAME = "rn";
     public static final String ATTR_DESCRIPTION = "d";
+
+    // Generic
+    public static final String ATTR_VALUE = "val";
 }
diff --git a/apex/blobstore/service/java/com/android/server/blob/BlobAccessMode.java b/apex/blobstore/service/java/com/android/server/blob/BlobAccessMode.java
index 4a527ad..ca588c5 100644
--- a/apex/blobstore/service/java/com/android/server/blob/BlobAccessMode.java
+++ b/apex/blobstore/service/java/com/android/server/blob/BlobAccessMode.java
@@ -15,18 +15,29 @@
  */
 package com.android.server.blob;
 
+import static android.Manifest.permission.ACCESS_COARSE_LOCATION;
+import static android.Manifest.permission.ACCESS_FINE_LOCATION;
 import static android.app.blob.XmlTags.ATTR_CERTIFICATE;
 import static android.app.blob.XmlTags.ATTR_PACKAGE;
 import static android.app.blob.XmlTags.ATTR_TYPE;
+import static android.app.blob.XmlTags.ATTR_VALUE;
 import static android.app.blob.XmlTags.TAG_ALLOWED_PACKAGE;
+import static android.app.blob.XmlTags.TAG_ALLOWED_PERMISSION;
+
+import static com.android.server.blob.BlobStoreConfig.TAG;
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.AppOpsManager;
 import android.content.Context;
 import android.content.pm.PackageManager;
+import android.os.UserHandle;
+import android.permission.PermissionManager;
 import android.util.ArraySet;
 import android.util.Base64;
 import android.util.DebugUtils;
+import android.util.Slog;
 
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.XmlUtils;
@@ -53,21 +64,27 @@
             ACCESS_TYPE_PUBLIC,
             ACCESS_TYPE_SAME_SIGNATURE,
             ACCESS_TYPE_ALLOWLIST,
+            ACCESS_TYPE_LOCATION_PERMISSION,
     })
     @interface AccessType {}
     public static final int ACCESS_TYPE_PRIVATE = 1 << 0;
     public static final int ACCESS_TYPE_PUBLIC = 1 << 1;
     public static final int ACCESS_TYPE_SAME_SIGNATURE = 1 << 2;
     public static final int ACCESS_TYPE_ALLOWLIST = 1 << 3;
+    public static final int ACCESS_TYPE_LOCATION_PERMISSION = 1 << 4;
 
     private int mAccessType = ACCESS_TYPE_PRIVATE;
 
     private final ArraySet<PackageIdentifier> mAllowedPackages = new ArraySet<>();
+    private final ArraySet<String> mAllowedPermissions = new ArraySet<>();
 
     void allow(BlobAccessMode other) {
         if ((other.mAccessType & ACCESS_TYPE_ALLOWLIST) != 0) {
             mAllowedPackages.addAll(other.mAllowedPackages);
         }
+        if ((other.mAccessType & ACCESS_TYPE_LOCATION_PERMISSION) != 0) {
+            mAllowedPermissions.addAll(other.mAllowedPermissions);
+        }
         mAccessType |= other.mAccessType;
     }
 
@@ -84,6 +101,11 @@
         mAllowedPackages.add(PackageIdentifier.create(packageName, certificate));
     }
 
+    void allowPackagesWithLocationPermission(@NonNull String permissionName) {
+        mAccessType |= ACCESS_TYPE_LOCATION_PERMISSION;
+        mAllowedPermissions.add(permissionName);
+    }
+
     boolean isPublicAccessAllowed() {
         return (mAccessType & ACCESS_TYPE_PUBLIC) != 0;
     }
@@ -99,8 +121,15 @@
         return mAllowedPackages.contains(PackageIdentifier.create(packageName, certificate));
     }
 
-    boolean isAccessAllowedForCaller(Context context,
-            @NonNull String callingPackage, @NonNull String committerPackage) {
+    boolean arePackagesWithLocationPermissionAllowed(@NonNull String permissionName) {
+        if ((mAccessType & ACCESS_TYPE_LOCATION_PERMISSION) == 0) {
+            return false;
+        }
+        return mAllowedPermissions.contains(permissionName);
+    }
+
+    boolean isAccessAllowedForCaller(Context context, @NonNull String callingPackage,
+            @NonNull String committerPackage, int callingUid, @Nullable String attributionTag) {
         if ((mAccessType & ACCESS_TYPE_PUBLIC) != 0) {
             return true;
         }
@@ -124,9 +153,37 @@
             }
         }
 
+        if ((mAccessType & ACCESS_TYPE_LOCATION_PERMISSION) != 0) {
+            final AppOpsManager appOpsManager = context.getSystemService(AppOpsManager.class);
+            for (int i = 0; i < mAllowedPermissions.size(); ++i) {
+                final String permission = mAllowedPermissions.valueAt(i);
+                if (PermissionManager.checkPackageNamePermission(permission, callingPackage,
+                        UserHandle.getUserId(callingUid)) != PackageManager.PERMISSION_GRANTED) {
+                    continue;
+                }
+                // TODO: Add appropriate message
+                if (appOpsManager.noteOpNoThrow(getAppOp(permission), callingUid, callingPackage,
+                        attributionTag, null /* message */) == AppOpsManager.MODE_ALLOWED) {
+                    return true;
+                }
+            }
+        }
+
         return false;
     }
 
+    private static String getAppOp(String permission) {
+        switch (permission) {
+            case ACCESS_FINE_LOCATION:
+                return AppOpsManager.OPSTR_FINE_LOCATION;
+            case ACCESS_COARSE_LOCATION:
+                return AppOpsManager.OPSTR_COARSE_LOCATION;
+            default:
+                Slog.w(TAG, "Unknown permission found: " + permission);
+                return null;
+        }
+    }
+
     int getAccessType() {
         return mAccessType;
     }
@@ -148,6 +205,16 @@
             }
             fout.decreaseIndent();
         }
+        fout.print("Allowed permissions:");
+        if (mAllowedPermissions.isEmpty()) {
+            fout.println(" (Empty)");
+        } else {
+            fout.increaseIndent();
+            for (int i = 0, count = mAllowedPermissions.size(); i < count; ++i) {
+                fout.println(mAllowedPermissions.valueAt(i).toString());
+            }
+            fout.decreaseIndent();
+        }
     }
 
     void writeToXml(@NonNull XmlSerializer out) throws IOException {
@@ -159,6 +226,12 @@
             XmlUtils.writeByteArrayAttribute(out, ATTR_CERTIFICATE, packageIdentifier.certificate);
             out.endTag(null, TAG_ALLOWED_PACKAGE);
         }
+        for (int i = 0, count = mAllowedPermissions.size(); i < count; ++i) {
+            out.startTag(null, TAG_ALLOWED_PERMISSION);
+            final String permission = mAllowedPermissions.valueAt(i);
+            XmlUtils.writeStringAttribute(out, ATTR_VALUE, permission);
+            out.endTag(null, TAG_ALLOWED_PERMISSION);
+        }
     }
 
     @NonNull
@@ -176,6 +249,10 @@
                 final byte[] certificate = XmlUtils.readByteArrayAttribute(in, ATTR_CERTIFICATE);
                 blobAccessMode.allowPackageAccess(packageName, certificate);
             }
+            if (TAG_ALLOWED_PERMISSION.equals(in.getName())) {
+                final String permission = XmlUtils.readStringAttribute(in, ATTR_VALUE);
+                blobAccessMode.allowPackagesWithLocationPermission(permission);
+            }
         }
         return blobAccessMode;
     }
diff --git a/apex/blobstore/service/java/com/android/server/blob/BlobMetadata.java b/apex/blobstore/service/java/com/android/server/blob/BlobMetadata.java
index fb02e96..8b12beb 100644
--- a/apex/blobstore/service/java/com/android/server/blob/BlobMetadata.java
+++ b/apex/blobstore/service/java/com/android/server/blob/BlobMetadata.java
@@ -229,7 +229,8 @@
         return getBlobFile().length();
     }
 
-    boolean isAccessAllowedForCaller(@NonNull String callingPackage, int callingUid) {
+    boolean isAccessAllowedForCaller(@NonNull String callingPackage, int callingUid,
+            @Nullable String attributionTag) {
         // Don't allow the blob to be accessed after it's expiry time has passed.
         if (getBlobHandle().isExpired()) {
             return false;
@@ -254,7 +255,7 @@
                 // Check if the caller is allowed access as per the access mode specified
                 // by the committer.
                 if (committer.blobAccessMode.isAccessAllowedForCaller(mContext,
-                        callingPackage, committer.packageName)) {
+                        callingPackage, committer.packageName, callingUid, attributionTag)) {
                     return true;
                 }
             }
diff --git a/apex/blobstore/service/java/com/android/server/blob/BlobStoreIdleJobService.java b/apex/blobstore/service/java/com/android/server/blob/BlobStoreIdleJobService.java
index 999860f..e65abcf 100644
--- a/apex/blobstore/service/java/com/android/server/blob/BlobStoreIdleJobService.java
+++ b/apex/blobstore/service/java/com/android/server/blob/BlobStoreIdleJobService.java
@@ -48,7 +48,8 @@
     @Override
     public boolean onStopJob(final JobParameters params) {
         Slog.d(TAG, "Idle maintenance job is stopped; id=" + params.getJobId()
-                + ", reason=" + JobParameters.getReasonCodeDescription(params.getStopReason()));
+                + ", reason="
+                + JobParameters.getLegacyReasonCodeDescription(params.getLegacyStopReason()));
         return false;
     }
 
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 f77f6c6..0e73547 100644
--- a/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java
+++ b/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java
@@ -402,12 +402,12 @@
     }
 
     private ParcelFileDescriptor openBlobInternal(BlobHandle blobHandle, int callingUid,
-            String callingPackage) throws IOException {
+            String callingPackage, String attributionTag) throws IOException {
         synchronized (mBlobsLock) {
             final BlobMetadata blobMetadata = getUserBlobsLocked(UserHandle.getUserId(callingUid))
                     .get(blobHandle);
             if (blobMetadata == null || !blobMetadata.isAccessAllowedForCaller(
-                    callingPackage, callingUid)) {
+                    callingPackage, callingUid, attributionTag)) {
                 if (blobMetadata == null) {
                     FrameworkStatsLog.write(FrameworkStatsLog.BLOB_OPENED, callingUid,
                             INVALID_BLOB_ID, INVALID_BLOB_SIZE,
@@ -455,7 +455,7 @@
 
     private void acquireLeaseInternal(BlobHandle blobHandle, int descriptionResId,
             CharSequence description, long leaseExpiryTimeMillis,
-            int callingUid, String callingPackage) {
+            int callingUid, String callingPackage, String attributionTag) {
         synchronized (mBlobsLock) {
             final int leasesCount = getLeasedBlobsCountLocked(callingUid, callingPackage);
             if (leasesCount >= getMaxLeasedBlobs()) {
@@ -468,7 +468,7 @@
             final BlobMetadata blobMetadata = getUserBlobsLocked(UserHandle.getUserId(callingUid))
                     .get(blobHandle);
             if (blobMetadata == null || !blobMetadata.isAccessAllowedForCaller(
-                    callingPackage, callingUid)) {
+                    callingPackage, callingUid, attributionTag)) {
                 if (blobMetadata == null) {
                     FrameworkStatsLog.write(FrameworkStatsLog.BLOB_LEASED, callingUid,
                             INVALID_BLOB_ID, INVALID_BLOB_SIZE,
@@ -527,13 +527,13 @@
     }
 
     private void releaseLeaseInternal(BlobHandle blobHandle, int callingUid,
-            String callingPackage) {
+            String callingPackage, String attributionTag) {
         synchronized (mBlobsLock) {
             final ArrayMap<BlobHandle, BlobMetadata> userBlobs =
                     getUserBlobsLocked(UserHandle.getUserId(callingUid));
             final BlobMetadata blobMetadata = userBlobs.get(blobHandle);
             if (blobMetadata == null || !blobMetadata.isAccessAllowedForCaller(
-                    callingPackage, callingUid)) {
+                    callingPackage, callingUid, attributionTag)) {
                 throw new SecurityException("Caller not allowed to access " + blobHandle
                         + "; callingUid=" + callingUid + ", callingPackage=" + callingPackage);
             }
@@ -634,12 +634,12 @@
     }
 
     private LeaseInfo getLeaseInfoInternal(BlobHandle blobHandle,
-            int callingUid, @NonNull String callingPackage) {
+            int callingUid, @NonNull String callingPackage, String attributionTag) {
         synchronized (mBlobsLock) {
             final BlobMetadata blobMetadata = getUserBlobsLocked(UserHandle.getUserId(callingUid))
                     .get(blobHandle);
             if (blobMetadata == null || !blobMetadata.isAccessAllowedForCaller(
-                    callingPackage, callingUid)) {
+                    callingPackage, callingUid, attributionTag)) {
                 throw new SecurityException("Caller not allowed to access " + blobHandle
                         + "; callingUid=" + callingUid + ", callingPackage=" + callingPackage);
             }
@@ -1465,7 +1465,7 @@
 
         @Override
         public ParcelFileDescriptor openBlob(@NonNull BlobHandle blobHandle,
-                @NonNull String packageName) {
+                @NonNull String packageName, @Nullable String attributionTag) {
             Objects.requireNonNull(blobHandle, "blobHandle must not be null");
             blobHandle.assertIsValid();
             Objects.requireNonNull(packageName, "packageName must not be null");
@@ -1480,7 +1480,7 @@
             }
 
             try {
-                return openBlobInternal(blobHandle, callingUid, packageName);
+                return openBlobInternal(blobHandle, callingUid, packageName, attributionTag);
             } catch (IOException e) {
                 throw ExceptionUtils.wrap(e);
             }
@@ -1489,7 +1489,8 @@
         @Override
         public void acquireLease(@NonNull BlobHandle blobHandle, @IdRes int descriptionResId,
                 @Nullable CharSequence description,
-                @CurrentTimeSecondsLong long leaseExpiryTimeMillis, @NonNull String packageName) {
+                @CurrentTimeSecondsLong long leaseExpiryTimeMillis, @NonNull String packageName,
+                @Nullable String attributionTag) {
             Objects.requireNonNull(blobHandle, "blobHandle must not be null");
             blobHandle.assertIsValid();
             Preconditions.checkArgument(
@@ -1513,7 +1514,7 @@
 
             try {
                 acquireLeaseInternal(blobHandle, descriptionResId, description,
-                        leaseExpiryTimeMillis, callingUid, packageName);
+                        leaseExpiryTimeMillis, callingUid, packageName, attributionTag);
             } catch (Resources.NotFoundException e) {
                 throw new IllegalArgumentException(e);
             } catch (LimitExceededException e) {
@@ -1522,7 +1523,8 @@
         }
 
         @Override
-        public void releaseLease(@NonNull BlobHandle blobHandle, @NonNull String packageName) {
+        public void releaseLease(@NonNull BlobHandle blobHandle, @NonNull String packageName,
+                @Nullable String attributionTag) {
             Objects.requireNonNull(blobHandle, "blobHandle must not be null");
             blobHandle.assertIsValid();
             Objects.requireNonNull(packageName, "packageName must not be null");
@@ -1536,7 +1538,7 @@
                         + "callingUid=" + callingUid + ", callingPackage=" + packageName);
             }
 
-            releaseLeaseInternal(blobHandle, callingUid, packageName);
+            releaseLeaseInternal(blobHandle, callingUid, packageName, attributionTag);
         }
 
         @Override
@@ -1606,7 +1608,8 @@
 
         @Override
         @Nullable
-        public LeaseInfo getLeaseInfo(@NonNull BlobHandle blobHandle, @NonNull String packageName) {
+        public LeaseInfo getLeaseInfo(@NonNull BlobHandle blobHandle, @NonNull String packageName,
+                @Nullable String attributionTag) {
             Objects.requireNonNull(blobHandle, "blobHandle must not be null");
             blobHandle.assertIsValid();
             Objects.requireNonNull(packageName, "packageName must not be null");
@@ -1620,7 +1623,7 @@
                         + "callingUid=" + callingUid + ", callingPackage=" + packageName);
             }
 
-            return getLeaseInfoInternal(blobHandle, callingUid, packageName);
+            return getLeaseInfoInternal(blobHandle, callingUid, packageName, attributionTag);
         }
 
         @Override
diff --git a/apex/blobstore/service/java/com/android/server/blob/BlobStoreSession.java b/apex/blobstore/service/java/com/android/server/blob/BlobStoreSession.java
index fe68882..2c3f682 100644
--- a/apex/blobstore/service/java/com/android/server/blob/BlobStoreSession.java
+++ b/apex/blobstore/service/java/com/android/server/blob/BlobStoreSession.java
@@ -15,6 +15,8 @@
  */
 package com.android.server.blob;
 
+import static android.Manifest.permission.ACCESS_COARSE_LOCATION;
+import static android.Manifest.permission.ACCESS_FINE_LOCATION;
 import static android.app.blob.BlobStoreManager.COMMIT_RESULT_ERROR;
 import static android.app.blob.XmlTags.ATTR_CREATION_TIME_MS;
 import static android.app.blob.XmlTags.ATTR_ID;
@@ -366,6 +368,21 @@
     }
 
     @Override
+    public void allowPackagesWithLocationPermission(@NonNull String permissionName) {
+        assertCallerIsOwner();
+        Preconditions.checkArgument(ACCESS_FINE_LOCATION.equals(permissionName)
+                        || ACCESS_COARSE_LOCATION.equals(permissionName),
+                "permissionName is unknown: " + permissionName);
+        synchronized (mSessionLock) {
+            if (mState != STATE_OPENED) {
+                throw new IllegalStateException("Not allowed to change access type in state: "
+                        + stateToString(mState));
+            }
+            mBlobAccessMode.allowPackagesWithLocationPermission(permissionName);
+        }
+    }
+
+    @Override
     public boolean isPackageAccessAllowed(@NonNull String packageName,
             @NonNull byte[] certificate) {
         assertCallerIsOwner();
@@ -406,6 +423,21 @@
     }
 
     @Override
+    public boolean arePackagesWithLocationPermissionAllowed(@NonNull String permissionName) {
+        assertCallerIsOwner();
+        Preconditions.checkArgument(ACCESS_FINE_LOCATION.equals(permissionName)
+                        || ACCESS_COARSE_LOCATION.equals(permissionName),
+                "permissionName is unknown: " + permissionName);
+        synchronized (mSessionLock) {
+            if (mState != STATE_OPENED) {
+                throw new IllegalStateException("Not allowed to change access type in state: "
+                        + stateToString(mState));
+            }
+            return mBlobAccessMode.arePackagesWithLocationPermissionAllowed(permissionName);
+        }
+    }
+
+    @Override
     public void close() {
         closeSession(STATE_CLOSED, false /* sendCallback */);
     }
diff --git a/apex/jobscheduler/framework/Android.bp b/apex/jobscheduler/framework/Android.bp
index b51c2aa..f766fcf 100644
--- a/apex/jobscheduler/framework/Android.bp
+++ b/apex/jobscheduler/framework/Android.bp
@@ -32,6 +32,7 @@
     },
     libs: [
         "app-compat-annotations",
+        "framework-connectivity.stubs.module_lib",
         "framework-minus-apex",
         "unsupportedappusage",
     ],
diff --git a/apex/jobscheduler/framework/java/android/app/AlarmManager.java b/apex/jobscheduler/framework/java/android/app/AlarmManager.java
index 78c5b15..3ea1922 100644
--- a/apex/jobscheduler/framework/java/android/app/AlarmManager.java
+++ b/apex/jobscheduler/framework/java/android/app/AlarmManager.java
@@ -18,6 +18,7 @@
 
 import android.Manifest;
 import android.annotation.IntDef;
+import android.annotation.NonNull;
 import android.annotation.RequiresPermission;
 import android.annotation.SdkConstant;
 import android.annotation.SystemApi;
@@ -29,6 +30,7 @@
 import android.content.Intent;
 import android.os.Build;
 import android.os.Handler;
+import android.os.HandlerExecutor;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.RemoteException;
@@ -42,7 +44,9 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.ref.WeakReference;
+import java.util.Objects;
 import java.util.WeakHashMap;
+import java.util.concurrent.Executor;
 
 /**
  * This class provides access to the system alarm services.  These allow you
@@ -194,6 +198,15 @@
     public static final int FLAG_ALLOW_WHILE_IDLE_COMPAT = 1 << 5;
 
     /**
+     * Flag for alarms: Used to mark prioritized alarms. These alarms will get to execute while idle
+     * and can be sent separately from other alarms that may be already due at the time.
+     * These alarms can be set via
+     * {@link #setPrioritized(int, long, long, String, Executor, OnAlarmListener)}
+     * @hide
+     */
+    public static final int FLAG_PRIORITIZE = 1 << 6;
+
+    /**
      * For apps targeting {@link Build.VERSION_CODES#S} or above, APIs
      * {@link #setExactAndAllowWhileIdle(int, long, PendingIntent)} and
      * {@link #setAlarmClock(AlarmClockInfo, PendingIntent)} will require holding a new
@@ -227,15 +240,15 @@
 
     final class ListenerWrapper extends IAlarmListener.Stub implements Runnable {
         final OnAlarmListener mListener;
-        Handler mHandler;
+        Executor mExecutor;
         IAlarmCompleteListener mCompletion;
 
         public ListenerWrapper(OnAlarmListener listener) {
             mListener = listener;
         }
 
-        public void setHandler(Handler h) {
-           mHandler = h;
+        void setExecutor(Executor e) {
+            mExecutor = e;
         }
 
         public void cancel() {
@@ -250,7 +263,7 @@
         public void doAlarm(IAlarmCompleteListener alarmManager) {
             mCompletion = alarmManager;
 
-            mHandler.post(this);
+            mExecutor.execute(this);
         }
 
         @Override
@@ -368,7 +381,7 @@
      */
     public void set(@AlarmType int type, long triggerAtMillis, PendingIntent operation) {
         setImpl(type, triggerAtMillis, legacyExactLength(), 0, 0, operation, null, null,
-                null, null, null);
+                (Handler) null, null, null);
     }
 
     /**
@@ -457,7 +470,7 @@
     public void setRepeating(@AlarmType int type, long triggerAtMillis,
             long intervalMillis, PendingIntent operation) {
         setImpl(type, triggerAtMillis, legacyExactLength(), intervalMillis, 0, operation,
-                null, null, null, null, null);
+                null, null, (Handler) null, null, null);
     }
 
     /**
@@ -507,7 +520,7 @@
     public void setWindow(@AlarmType int type, long windowStartMillis, long windowLengthMillis,
             PendingIntent operation) {
         setImpl(type, windowStartMillis, windowLengthMillis, 0, 0, operation,
-                null, null, null, null, null);
+                null, null, (Handler) null, null, null);
     }
 
     /**
@@ -526,6 +539,53 @@
     }
 
     /**
+     * Schedule an alarm that is prioritized by the system while the device is in power saving modes
+     * such as battery saver and device idle (doze).
+     *
+     * <p>
+     * Apps that use this are not guaranteed to get all alarms as requested during power saving
+     * modes, i.e. the system may still impose restrictions on how frequently these alarms will go
+     * off for a particular application, like requiring a certain minimum duration be elapsed
+     * between consecutive alarms. This duration will be normally be in the order of a few minutes.
+     *
+     * <p>
+     * When the system wakes up to deliver these alarms, it may not deliver any of the other pending
+     * alarms set earlier by the calling app, even the special ones set via
+     * {@link #setAndAllowWhileIdle(int, long, PendingIntent)} or
+     * {@link #setExactAndAllowWhileIdle(int, long, PendingIntent)}. So the caller should not
+     * expect these to arrive in any relative order to its other alarms.
+     *
+     * @param type type of alarm
+     * @param windowStartMillis The earliest time, in milliseconds, that the alarm should
+     *        be delivered, expressed in the appropriate clock's units (depending on the alarm
+     *        type).
+     * @param windowLengthMillis The length of the requested delivery window,
+     *        in milliseconds.  The alarm will be delivered no later than this many
+     *        milliseconds after {@code windowStartMillis}.  Note that this parameter
+     *        is a <i>duration,</i> not the timestamp of the end of the window.
+     * @param tag string describing the alarm, used for logging and battery-use
+     *         attribution
+     * @param listener {@link OnAlarmListener} instance whose
+     *         {@link OnAlarmListener#onAlarm() onAlarm()} method will be
+     *         called when the alarm time is reached.  A given OnAlarmListener instance can
+     *         only be the target of a single pending alarm, just as a given PendingIntent
+     *         can only be used with one alarm at a time.
+     * @param executor {@link Executor} on which to execute the listener's onAlarm()
+     *         callback.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.SCHEDULE_PRIORITIZED_ALARM)
+    public void setPrioritized(@AlarmType int type, long windowStartMillis, long windowLengthMillis,
+            @NonNull String tag, @NonNull Executor executor, @NonNull OnAlarmListener listener) {
+        Objects.requireNonNull(executor);
+        Objects.requireNonNull(tag);
+        Objects.requireNonNull(listener);
+        setImpl(type, windowStartMillis, windowLengthMillis, 0, FLAG_PRIORITIZE, null, listener,
+                tag, executor, null, null);
+    }
+
+    /**
      * Schedule an alarm to be delivered precisely at the stated time.
      *
      * <p>
@@ -565,7 +625,7 @@
      */
     @RequiresPermission(value = Manifest.permission.SCHEDULE_EXACT_ALARM, conditional = true)
     public void setExact(@AlarmType int type, long triggerAtMillis, PendingIntent operation) {
-        setImpl(type, triggerAtMillis, WINDOW_EXACT, 0, 0, operation, null, null, null,
+        setImpl(type, triggerAtMillis, WINDOW_EXACT, 0, 0, operation, null, null, (Handler) null,
                 null, null);
     }
 
@@ -645,7 +705,7 @@
     @RequiresPermission(Manifest.permission.SCHEDULE_EXACT_ALARM)
     public void setAlarmClock(AlarmClockInfo info, PendingIntent operation) {
         setImpl(RTC_WAKEUP, info.getTriggerTime(), WINDOW_EXACT, 0, 0, operation,
-                null, null, null, null, info);
+                null, null, (Handler) null, null, info);
     }
 
     /** @hide */
@@ -654,7 +714,7 @@
     public void set(@AlarmType int type, long triggerAtMillis, long windowMillis,
             long intervalMillis, PendingIntent operation, WorkSource workSource) {
         setImpl(type, triggerAtMillis, windowMillis, intervalMillis, 0, operation, null, null,
-                null, workSource, null);
+                (Handler) null, workSource, null);
     }
 
     /**
@@ -698,6 +758,15 @@
             long intervalMillis, int flags, PendingIntent operation, final OnAlarmListener listener,
             String listenerTag, Handler targetHandler, WorkSource workSource,
             AlarmClockInfo alarmClock) {
+        final Handler handlerToUse = (targetHandler != null) ? targetHandler : mMainThreadHandler;
+        setImpl(type, triggerAtMillis, windowMillis, intervalMillis, flags, operation, listener,
+                listenerTag, new HandlerExecutor(handlerToUse), workSource, alarmClock);
+    }
+
+    private void setImpl(@AlarmType int type, long triggerAtMillis, long windowMillis,
+            long intervalMillis, int flags, PendingIntent operation, final OnAlarmListener listener,
+            String listenerTag, Executor targetExecutor, WorkSource workSource,
+            AlarmClockInfo alarmClock) {
         if (triggerAtMillis < 0) {
             /* NOTYET
             if (mAlwaysExact) {
@@ -726,9 +795,7 @@
                     sWrappers.put(listener, new WeakReference<>(recipientWrapper));
                 }
             }
-
-            final Handler handler = (targetHandler != null) ? targetHandler : mMainThreadHandler;
-            recipientWrapper.setHandler(handler);
+            recipientWrapper.setExecutor(targetExecutor);
         }
 
         try {
@@ -834,7 +901,7 @@
     public void setInexactRepeating(@AlarmType int type, long triggerAtMillis,
             long intervalMillis, PendingIntent operation) {
         setImpl(type, triggerAtMillis, WINDOW_HEURISTIC, intervalMillis, 0, operation, null,
-                null, null, null, null);
+                null, (Handler) null, null, null);
     }
 
     /**
@@ -884,7 +951,7 @@
     public void setAndAllowWhileIdle(@AlarmType int type, long triggerAtMillis,
             PendingIntent operation) {
         setImpl(type, triggerAtMillis, WINDOW_HEURISTIC, 0, FLAG_ALLOW_WHILE_IDLE,
-                operation, null, null, null, null, null);
+                operation, null, null, (Handler) null, null, null);
     }
 
     /**
@@ -945,7 +1012,7 @@
     public void setExactAndAllowWhileIdle(@AlarmType int type, long triggerAtMillis,
             PendingIntent operation) {
         setImpl(type, triggerAtMillis, WINDOW_EXACT, 0, FLAG_ALLOW_WHILE_IDLE, operation,
-                null, null, null, null, null);
+                null, null, (Handler) null, null, null);
     }
 
     /**
diff --git a/apex/jobscheduler/framework/java/android/app/job/JobInfo.java b/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
index 4c8ab93..5729385 100644
--- a/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
+++ b/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
@@ -1021,6 +1021,41 @@
             mJobId = jobId;
         }
 
+        /**
+         * Creates a new Builder of JobInfo from an existing instance.
+         * @hide
+         */
+        public Builder(@NonNull JobInfo job) {
+            mJobId = job.getId();
+            mJobService = job.getService();
+            mExtras = job.getExtras();
+            mTransientExtras = job.getTransientExtras();
+            mClipData = job.getClipData();
+            mClipGrantFlags = job.getClipGrantFlags();
+            mPriority = job.getPriority();
+            mFlags = job.getFlags();
+            mConstraintFlags = job.getConstraintFlags();
+            mNetworkRequest = job.getRequiredNetwork();
+            mNetworkDownloadBytes = job.getEstimatedNetworkDownloadBytes();
+            mNetworkUploadBytes = job.getEstimatedNetworkUploadBytes();
+            mTriggerContentUris = job.getTriggerContentUris() != null
+                    ? new ArrayList<>(Arrays.asList(job.getTriggerContentUris())) : null;
+            mTriggerContentUpdateDelay = job.getTriggerContentUpdateDelay();
+            mTriggerContentMaxDelay = job.getTriggerContentMaxDelay();
+            mIsPersisted = job.isPersisted();
+            mMinLatencyMillis = job.getMinLatencyMillis();
+            mMaxExecutionDelayMillis = job.getMaxExecutionDelayMillis();
+            mIsPeriodic = job.isPeriodic();
+            mHasEarlyConstraint = job.hasEarlyConstraint();
+            mHasLateConstraint = job.hasLateConstraint();
+            mIntervalMillis = job.getIntervalMillis();
+            mFlexMillis = job.getFlexMillis();
+            mInitialBackoffMillis = job.getInitialBackoffMillis();
+            // mBackoffPolicySet isn't set but it's fine since this is copying from an already valid
+            // job.
+            mBackoffPolicy = job.getBackoffPolicy();
+        }
+
         /** @hide */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
         public Builder setPriority(int priority) {
@@ -1462,7 +1497,7 @@
          * <ol>
          *     <li>Run as soon as possible</li>
          *     <li>Be less restricted during Doze and battery saver</li>
-         *     <li>Have the same network access as foreground services</li>
+         *     <li>Bypass Doze, app standby, and battery saver network restrictions</li>
          *     <li>Be less likely to be killed than regular jobs</li>
          *     <li>Be subject to background location throttling</li>
          * </ol>
@@ -1483,7 +1518,7 @@
          *
          * <p>
          * Assuming all constraints remain satisfied (including ideal system load conditions),
-         * expedited jobs are guaranteed to have a minimum allowed runtime of 1 minute. If your
+         * expedited jobs will have a maximum execution time of at least 1 minute. If your
          * app has remaining expedited job quota, then the expedited job <i>may</i> potentially run
          * longer until remaining quota is used up. Just like with regular jobs, quota is not
          * consumed while the app is on top and visible to the user.
diff --git a/apex/jobscheduler/framework/java/android/app/job/JobParameters.java b/apex/jobscheduler/framework/java/android/app/job/JobParameters.java
index 0d3e001..60f6475 100644
--- a/apex/jobscheduler/framework/java/android/app/job/JobParameters.java
+++ b/apex/jobscheduler/framework/java/android/app/job/JobParameters.java
@@ -16,10 +16,14 @@
 
 package android.app.job;
 
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.ActivityManager;
+import android.app.usage.UsageStatsManager;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.ClipData;
+import android.content.pm.PackageManager;
 import android.net.Network;
 import android.net.NetworkRequest;
 import android.net.Uri;
@@ -30,6 +34,9 @@
 import android.os.PersistableBundle;
 import android.os.RemoteException;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * Contains the parameters used to configure/identify your job. You do not create this object
  * yourself, instead it is handed in to your application by the System.
@@ -82,7 +89,7 @@
      */
     // TODO(142420609): make it @SystemApi for mainline
     @NonNull
-    public static String getReasonCodeDescription(int reasonCode) {
+    public static String getLegacyReasonCodeDescription(int reasonCode) {
         switch (reasonCode) {
             case REASON_CANCELED: return "canceled";
             case REASON_CONSTRAINTS_NOT_SATISFIED: return "constraints";
@@ -96,12 +103,119 @@
     }
 
     /** @hide */
-    // @SystemApi TODO make it a system api for mainline
+    // TODO: move current users of legacy reasons to new public reasons
     @NonNull
     public static int[] getJobStopReasonCodes() {
         return JOB_STOP_REASON_CODES;
     }
 
+    /**
+     * There is no reason the job is stopped. This is the value returned from the JobParameters
+     * object passed to {@link JobService#onStartJob(JobParameters)}.
+     */
+    public static final int STOP_REASON_UNDEFINED = 0;
+    /**
+     * The job was cancelled directly by the app, either by calling
+     * {@link JobScheduler#cancel(int)}, {@link JobScheduler#cancelAll()}, or by scheduling a
+     * new job with the same job ID.
+     */
+    public static final int STOP_REASON_CANCELLED_BY_APP = 1;
+    /** The job was stopped to run a higher priority job of the app. */
+    public static final int STOP_REASON_PREEMPT = 2;
+    /**
+     * The job used up its maximum execution time and timed out. Each individual job has a maximum
+     * execution time limit, regardless of how much total quota the app has. See the note on
+     * {@link JobScheduler} for the execution time limits.
+     */
+    public static final int STOP_REASON_TIMEOUT = 3;
+    /**
+     * The device state (eg. Doze, battery saver, memory usage, etc) requires JobScheduler stop this
+     * job.
+     */
+    public static final int STOP_REASON_DEVICE_STATE = 4;
+    /**
+     * The requested battery-not-low constraint is no longer satisfied.
+     *
+     * @see JobInfo.Builder#setRequiresBatteryNotLow(boolean)
+     */
+    public static final int STOP_REASON_CONSTRAINT_BATTERY_NOT_LOW = 5;
+    /**
+     * The requested charging constraint is no longer satisfied.
+     *
+     * @see JobInfo.Builder#setRequiresCharging(boolean)
+     */
+    public static final int STOP_REASON_CONSTRAINT_CHARGING = 6;
+    /**
+     * The requested connectivity constraint is no longer satisfied.
+     *
+     * @see JobInfo.Builder#setRequiredNetwork(NetworkRequest)
+     * @see JobInfo.Builder#setRequiredNetworkType(int)
+     */
+    public static final int STOP_REASON_CONSTRAINT_CONNECTIVITY = 7;
+    /**
+     * The requested idle constraint is no longer satisfied.
+     *
+     * @see JobInfo.Builder#setRequiresDeviceIdle(boolean)
+     */
+    public static final int STOP_REASON_CONSTRAINT_DEVICE_IDLE = 8;
+    /**
+     * The requested storage-not-low constraint is no longer satisfied.
+     *
+     * @see JobInfo.Builder#setRequiresStorageNotLow(boolean)
+     */
+    public static final int STOP_REASON_CONSTRAINT_STORAGE_NOT_LOW = 9;
+    /**
+     * The app has consumed all of its current quota. Each app is assigned a quota of how much
+     * it can run jobs within a certain time frame. The quota is informed, in part, by app standby
+     * buckets. Once an app has used up all of its quota, it won't be able to start jobs until
+     * quota is replenished, is changed, or is temporarily not applied.
+     *
+     * @see UsageStatsManager#getAppStandbyBucket()
+     */
+    public static final int STOP_REASON_QUOTA = 10;
+    /**
+     * The app is restricted from running in the background.
+     *
+     * @see ActivityManager#isBackgroundRestricted()
+     * @see PackageManager#isInstantApp()
+     */
+    public static final int STOP_REASON_BACKGROUND_RESTRICTION = 11;
+    /**
+     * The current standby bucket requires that the job stop now.
+     *
+     * @see UsageStatsManager#STANDBY_BUCKET_RESTRICTED
+     */
+    public static final int STOP_REASON_APP_STANDBY = 12;
+    /**
+     * The user stopped the job. This can happen either through force-stop, or via adb shell
+     * commands.
+     */
+    public static final int STOP_REASON_USER = 13;
+    /** The system is doing some processing that requires stopping this job. */
+    public static final int STOP_REASON_SYSTEM_PROCESSING = 14;
+
+    /** @hide */
+    @IntDef(prefix = {"STOP_REASON_"}, value = {
+            STOP_REASON_UNDEFINED,
+            STOP_REASON_CANCELLED_BY_APP,
+            STOP_REASON_PREEMPT,
+            STOP_REASON_TIMEOUT,
+            STOP_REASON_DEVICE_STATE,
+            STOP_REASON_CONSTRAINT_BATTERY_NOT_LOW,
+            STOP_REASON_CONSTRAINT_CHARGING,
+            STOP_REASON_CONSTRAINT_CONNECTIVITY,
+            STOP_REASON_CONSTRAINT_DEVICE_IDLE,
+            STOP_REASON_CONSTRAINT_STORAGE_NOT_LOW,
+            STOP_REASON_QUOTA,
+            STOP_REASON_BACKGROUND_RESTRICTION,
+            STOP_REASON_APP_STANDBY,
+            STOP_REASON_USER,
+            STOP_REASON_SYSTEM_PROCESSING,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface StopReason {
+    }
+
     @UnsupportedAppUsage
     private final int jobId;
     private final PersistableBundle extras;
@@ -116,7 +230,8 @@
     private final String[] mTriggeredContentAuthorities;
     private final Network network;
 
-    private int stopReason; // Default value of stopReason is REASON_CANCELED
+    private int mStopReason = STOP_REASON_UNDEFINED;
+    private int mLegacyStopReason; // Default value of stopReason is REASON_CANCELED
     private String debugStopReason; // Human readable stop reason for debugging.
 
     /** @hide */
@@ -145,15 +260,23 @@
     }
 
     /**
-     * Reason onStopJob() was called on this job.
-     * @hide
+     * @return The reason {@link JobService#onStopJob(JobParameters)} was called on this job. Will
+     * be {@link #STOP_REASON_UNDEFINED} if {@link JobService#onStopJob(JobParameters)} has not
+     * yet been called.
      */
+    @StopReason
     public int getStopReason() {
-        return stopReason;
+        return mStopReason;
+    }
+
+    /** @hide */
+    public int getLegacyStopReason() {
+        return mLegacyStopReason;
     }
 
     /**
      * Reason onStopJob() was called on this job.
+     *
      * @hide
      */
     public String getDebugStopReason() {
@@ -368,13 +491,16 @@
         } else {
             network = null;
         }
-        stopReason = in.readInt();
+        mStopReason = in.readInt();
+        mLegacyStopReason = in.readInt();
         debugStopReason = in.readString();
     }
 
     /** @hide */
-    public void setStopReason(int reason, String debugStopReason) {
-        stopReason = reason;
+    public void setStopReason(@StopReason int reason, int legacyStopReason,
+            String debugStopReason) {
+        mStopReason = reason;
+        mLegacyStopReason = legacyStopReason;
         this.debugStopReason = debugStopReason;
     }
 
@@ -406,7 +532,8 @@
         } else {
             dest.writeInt(0);
         }
-        dest.writeInt(stopReason);
+        dest.writeInt(mStopReason);
+        dest.writeInt(mLegacyStopReason);
         dest.writeString(debugStopReason);
     }
 
diff --git a/apex/jobscheduler/framework/java/android/app/job/JobService.java b/apex/jobscheduler/framework/java/android/app/job/JobService.java
index 0f3d299..fa7a2d3 100644
--- a/apex/jobscheduler/framework/java/android/app/job/JobService.java
+++ b/apex/jobscheduler/framework/java/android/app/job/JobService.java
@@ -139,19 +139,23 @@
      * Once this method is called, you no longer need to call
      * {@link #jobFinished(JobParameters, boolean)}.
      *
-     * <p>This will happen if the requirements specified at schedule time are no longer met. For
+     * <p>This may happen if the requirements specified at schedule time are no longer met. For
      * example you may have requested WiFi with
      * {@link android.app.job.JobInfo.Builder#setRequiredNetworkType(int)}, yet while your
      * job was executing the user toggled WiFi. Another example is if you had specified
-     * {@link android.app.job.JobInfo.Builder#setRequiresDeviceIdle(boolean)}, and the phone left its
-     * idle maintenance window. You are solely responsible for the behavior of your application
-     * upon receipt of this message; your app will likely start to misbehave if you ignore it.
+     * {@link android.app.job.JobInfo.Builder#setRequiresDeviceIdle(boolean)}, and the phone left
+     * its idle maintenance window. There are many other reasons a job can be stopped early besides
+     * constraints no longer being satisfied. {@link JobParameters#getStopReason()} will return the
+     * reason this method was called. You are solely responsible for the behavior of your
+     * application upon receipt of this message; your app will likely start to misbehave if you
+     * ignore it.
      * <p>
      * Once this method returns (or times out), the system releases the wakelock that it is holding
      * on behalf of the job.</p>
      *
-     * @param params The parameters identifying this job, as supplied to
-     *               the job in the {@link #onStartJob(JobParameters)} callback.
+     * @param params The parameters identifying this job, similar to what was supplied to the job in
+     *               the {@link #onStartJob(JobParameters)} callback, but with the stop reason
+     *               included.
      * @return {@code true} to indicate to the JobManager whether you'd like to reschedule
      * this job based on the retry criteria provided at job creation-time; or {@code false}
      * to end the job entirely.  Regardless of the value returned, your job must stop executing.
diff --git a/apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java b/apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java
index 88f21a5..cb1fccf 100644
--- a/apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java
+++ b/apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java
@@ -40,9 +40,9 @@
 /**
  * Interface to access and modify the permanent and temporary power save allow list. The two lists
  * are kept separately. Apps placed on the permanent allow list are only removed via an explicit
- * {@link #removeFromAllowList(String)} call. Apps allow-listed by default by the system cannot be
- * removed. Apps placed on the temporary allow list are removed from that allow list after a
- * predetermined amount of time.
+ * {@link #removeFromPermanentAllowList(String)} call. Apps allow-listed by default by the system
+ * cannot be removed. Apps placed on the temporary allow list are removed from that allow list after
+ * a predetermined amount of time.
  *
  * @hide
  */
@@ -83,6 +83,12 @@
     }
 
     /**
+     * Does not place the app on any temporary allow list. Nullifies the previous call to
+     * {@link android.app.BroadcastOptions#setTemporaryAppAllowlist(long, int, int, String)}.
+     * Note: this will not remove the receiver app from the temp allow list.
+     */
+    public static final int TEMPORARY_ALLOW_LIST_TYPE_NONE = -1;
+    /**
      * Allow the temp allow list behavior, plus allow foreground service start from background.
      */
     public static final int TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED = 0;
@@ -96,6 +102,7 @@
      * @hide
      */
     @IntDef(flag = true, prefix = { "TEMPORARY_ALLOW_LIST_TYPE_" }, value = {
+            TEMPORARY_ALLOW_LIST_TYPE_NONE,
             TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
             TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED,
     })
@@ -378,6 +385,8 @@
 
     /**
      * Add the specified package to the permanent power save allow list.
+     *
+     * @hide
      */
     @RequiresPermission(android.Manifest.permission.DEVICE_POWER)
     public void addToPermanentAllowList(@NonNull String packageName) {
@@ -386,6 +395,8 @@
 
     /**
      * Add the specified packages to the permanent power save allow list.
+     *
+     * @hide
      */
     @RequiresPermission(android.Manifest.permission.DEVICE_POWER)
     public void addToPermanentAllowList(@NonNull List<String> packageNames) {
@@ -405,6 +416,7 @@
      * @hide
      */
     @NonNull
+    @RequiresPermission(android.Manifest.permission.DEVICE_POWER)
     public int[] getAllowListedAppIds(boolean includingIdle) {
         try {
             if (includingIdle) {
@@ -443,9 +455,10 @@
      * removed. Apps allow-listed by default by the system cannot be removed.
      *
      * @param packageName The app to remove from the allow list
+     * @hide
      */
     @RequiresPermission(android.Manifest.permission.DEVICE_POWER)
-    public void removeFromAllowList(@NonNull String packageName) {
+    public void removeFromPermanentAllowList(@NonNull String packageName) {
         try {
             mService.removePowerSaveWhitelistApp(packageName);
         } catch (RemoteException e) {
@@ -463,8 +476,8 @@
      */
     @UserHandleAware
     @RequiresPermission(android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST)
-    public void addToTemporaryAllowList(@NonNull String packageName, long durationMs,
-            @ReasonCode int reasonCode, @Nullable String reason) {
+    public void addToTemporaryAllowList(@NonNull String packageName, @ReasonCode int reasonCode,
+            @Nullable String reason, long durationMs) {
         try {
             mService.addPowerSaveTempWhitelistApp(packageName, durationMs, mContext.getUserId(),
                     reasonCode, reason);
@@ -488,7 +501,7 @@
     @UserHandleAware
     @RequiresPermission(android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST)
     public long addToTemporaryAllowListForEvent(@NonNull String packageName,
-            @AllowListEvent int event, @ReasonCode int reasonCode, @Nullable String reason) {
+            @ReasonCode int reasonCode, @Nullable String reason, @AllowListEvent int event) {
         try {
             switch (event) {
                 case EVENT_MMS:
diff --git a/apex/jobscheduler/framework/java/android/os/PowerWhitelistManager.java b/apex/jobscheduler/framework/java/android/os/PowerWhitelistManager.java
index eba39c7..07231b0 100644
--- a/apex/jobscheduler/framework/java/android/os/PowerWhitelistManager.java
+++ b/apex/jobscheduler/framework/java/android/os/PowerWhitelistManager.java
@@ -439,12 +439,12 @@
      * whitelisted by default by the system cannot be removed.
      *
      * @param packageName The app to remove from the whitelist
-     * @deprecated Use {@link PowerExemptionManager#removeFromAllowList(String)} instead
+     * @deprecated Use {@link PowerExemptionManager#removeFromPermanentAllowList(String)} instead
      */
     @Deprecated
     @RequiresPermission(android.Manifest.permission.DEVICE_POWER)
     public void removeFromWhitelist(@NonNull String packageName) {
-        mPowerExemptionManager.removeFromAllowList(packageName);
+        mPowerExemptionManager.removeFromPermanentAllowList(packageName);
     }
 
     /**
@@ -455,13 +455,13 @@
      * @param reasonCode one of {@link ReasonCode}, use {@link #REASON_UNKNOWN} if not sure.
      * @param reason a optional human readable reason string, could be null or empty string.
      * @deprecated Use {@link PowerExemptionManager#addToTemporaryAllowList(
-     *             String, long, int, String)} instead
+     *             String, int, String, long)} instead
      */
     @Deprecated
     @RequiresPermission(android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST)
     public void whitelistAppTemporarily(@NonNull String packageName, long durationMs,
             @ReasonCode int reasonCode, @Nullable String reason) {
-        mPowerExemptionManager.addToTemporaryAllowList(packageName, durationMs, reasonCode, reason);
+        mPowerExemptionManager.addToTemporaryAllowList(packageName, reasonCode, reason, durationMs);
     }
 
     /**
@@ -470,13 +470,13 @@
      * @param packageName The package to add to the temp whitelist
      * @param durationMs  How long to keep the app on the temp whitelist for (in milliseconds)
      * @deprecated Use {@link PowerExemptionManager#addToTemporaryAllowList(
-     *             String, long, int, String)} instead
+     *             String, int, String, long)} instead
      */
     @Deprecated
     @RequiresPermission(android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST)
     public void whitelistAppTemporarily(@NonNull String packageName, long durationMs) {
         mPowerExemptionManager.addToTemporaryAllowList(
-                packageName, durationMs, REASON_UNKNOWN, packageName);
+                packageName, REASON_UNKNOWN, packageName, durationMs);
     }
 
     /**
@@ -490,14 +490,14 @@
      *                    used for logging purposes. Could be null or empty string.
      * @return The duration (in milliseconds) that the app is whitelisted for
      * @deprecated Use {@link PowerExemptionManager#addToTemporaryAllowListForEvent(
-     *             String, int, int, String)} instead
+     *             String, int, String, int)} instead
      */
     @Deprecated
     @RequiresPermission(android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST)
     public long whitelistAppTemporarilyForEvent(@NonNull String packageName,
             @WhitelistEvent int event, @Nullable String reason) {
         return mPowerExemptionManager.addToTemporaryAllowListForEvent(
-                packageName, event, REASON_UNKNOWN, reason);
+                packageName, REASON_UNKNOWN, reason, event);
     }
 
     /**
@@ -512,14 +512,14 @@
      *                    used for logging purposes. Could be null or empty string.
      * @return The duration (in milliseconds) that the app is whitelisted for
      * @deprecated Use {@link PowerExemptionManager#addToTemporaryAllowListForEvent(
-     *             String, int, int, String)} instead
+     *             String, int, String, int)} instead
      */
     @Deprecated
     @RequiresPermission(android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST)
     public long whitelistAppTemporarilyForEvent(@NonNull String packageName,
             @WhitelistEvent int event, @ReasonCode int reasonCode, @Nullable String reason) {
         return mPowerExemptionManager.addToTemporaryAllowListForEvent(
-                packageName, event, reasonCode, reason);
+                packageName, reasonCode, reason, event);
     }
 
     /**
diff --git a/apex/jobscheduler/framework/java/com/android/server/DeviceIdleInternal.java b/apex/jobscheduler/framework/java/com/android/server/DeviceIdleInternal.java
index 9bd57a1..a9ca5cf 100644
--- a/apex/jobscheduler/framework/java/com/android/server/DeviceIdleInternal.java
+++ b/apex/jobscheduler/framework/java/com/android/server/DeviceIdleInternal.java
@@ -17,9 +17,9 @@
 package com.android.server;
 
 import android.annotation.Nullable;
-import android.os.PowerWhitelistManager;
-import android.os.PowerWhitelistManager.ReasonCode;
-import android.os.PowerWhitelistManager.TempAllowListType;
+import android.os.PowerExemptionManager;
+import android.os.PowerExemptionManager.ReasonCode;
+import android.os.PowerExemptionManager.TempAllowListType;
 
 import com.android.server.deviceidle.IDeviceIdleConstraint;
 
@@ -35,7 +35,7 @@
 
     /**
      * Same as {@link #addPowerSaveTempWhitelistApp(int, String, long, int, boolean, int, String)}
-     * with {@link PowerWhitelistManager#TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED}.
+     * with {@link PowerExemptionManager#TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED}.
      */
     void addPowerSaveTempWhitelistApp(int callingUid, String packageName,
             long durationMs, int userId, boolean sync, @ReasonCode int reasonCode,
diff --git a/apex/jobscheduler/framework/java/com/android/server/job/JobSchedulerInternal.java b/apex/jobscheduler/framework/java/com/android/server/job/JobSchedulerInternal.java
index 7833a03..6ae91a0 100644
--- a/apex/jobscheduler/framework/java/com/android/server/job/JobSchedulerInternal.java
+++ b/apex/jobscheduler/framework/java/com/android/server/job/JobSchedulerInternal.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.app.job.JobInfo;
+import android.app.job.JobParameters;
 import android.util.proto.ProtoOutputStream;
 
 import java.util.List;
@@ -36,7 +37,7 @@
     /**
      * Cancel the jobs for a given uid (e.g. when app data is cleared)
      */
-    void cancelJobsForUid(int uid, String reason);
+    void cancelJobsForUid(int uid, @JobParameters.StopReason int reason, String debugReason);
 
     /**
      * These are for activity manager to communicate to use what is currently performing backups.
diff --git a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
index 667fc60..57c8300 100644
--- a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
+++ b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
@@ -16,9 +16,9 @@
 
 package com.android.server;
 
-import static android.os.PowerWhitelistManager.REASON_SHELL;
-import static android.os.PowerWhitelistManager.REASON_UNKNOWN;
-import static android.os.PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED;
+import static android.os.PowerExemptionManager.REASON_SHELL;
+import static android.os.PowerExemptionManager.REASON_UNKNOWN;
+import static android.os.PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED;
 import static android.os.Process.INVALID_UID;
 
 import android.Manifest;
@@ -58,11 +58,11 @@
 import android.os.IDeviceIdleController;
 import android.os.Looper;
 import android.os.Message;
+import android.os.PowerExemptionManager.ReasonCode;
+import android.os.PowerExemptionManager.TempAllowListType;
 import android.os.PowerManager;
 import android.os.PowerManager.ServiceType;
 import android.os.PowerManagerInternal;
-import android.os.PowerWhitelistManager.ReasonCode;
-import android.os.PowerWhitelistManager.TempAllowListType;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.ResultReceiver;
@@ -1947,7 +1947,7 @@
                 long durationMs, int userId, boolean sync, @ReasonCode int reasonCode,
                 @Nullable String reason) {
             addPowerSaveTempAllowlistAppInternal(callingUid, packageName, durationMs,
-                    TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
+                    TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
                     userId, sync, reasonCode, reason);
         }
 
@@ -2706,7 +2706,7 @@
         final long token = Binder.clearCallingIdentity();
         try {
             addPowerSaveTempAllowlistAppInternal(callingUid,
-                    packageName, duration, TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
+                    packageName, duration, TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
                     userId, true, reasonCode, reason);
         } finally {
             Binder.restoreCallingIdentity(token);
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
index 58fc874..3c9496f 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
@@ -23,6 +23,7 @@
 import static android.app.AlarmManager.FLAG_ALLOW_WHILE_IDLE_COMPAT;
 import static android.app.AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED;
 import static android.app.AlarmManager.FLAG_IDLE_UNTIL;
+import static android.app.AlarmManager.FLAG_PRIORITIZE;
 import static android.app.AlarmManager.FLAG_WAKE_FROM_IDLE;
 import static android.app.AlarmManager.INTERVAL_DAY;
 import static android.app.AlarmManager.INTERVAL_HOUR;
@@ -100,6 +101,7 @@
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
 import android.util.SparseIntArray;
+import android.util.SparseLongArray;
 import android.util.TimeUtils;
 import android.util.proto.ProtoOutputStream;
 
@@ -221,6 +223,7 @@
     AlarmHandler mHandler;
     AppWakeupHistory mAppWakeupHistory;
     AppWakeupHistory mAllowWhileIdleHistory;
+    private final SparseLongArray mLastPriorityAlarmDispatch = new SparseLongArray();
     ClockReceiver mClockReceiver;
     final DeliveryTracker mDeliveryTracker = new DeliveryTracker();
     IBinder.DeathRecipient mListenerDeathRecipient;
@@ -432,6 +435,8 @@
 
         @VisibleForTesting
         static final String KEY_CRASH_NON_CLOCK_APPS = "crash_non_clock_apps";
+        @VisibleForTesting
+        static final String KEY_PRIORITY_ALARM_DELAY = "priority_alarm_delay";
 
         private static final long DEFAULT_MIN_FUTURITY = 5 * 1000;
         private static final long DEFAULT_MIN_INTERVAL = 60 * 1000;
@@ -470,6 +475,8 @@
         // TODO (b/171306433): Change to true by default.
         private static final boolean DEFAULT_CRASH_NON_CLOCK_APPS = false;
 
+        private static final long DEFAULT_PRIORITY_ALARM_DELAY = 9 * 60_000;
+
         // Minimum futurity of a new alarm
         public long MIN_FUTURITY = DEFAULT_MIN_FUTURITY;
 
@@ -525,6 +532,12 @@
          */
         public boolean CRASH_NON_CLOCK_APPS = DEFAULT_CRASH_NON_CLOCK_APPS;
 
+        /**
+         * Minimum delay between two slots that an app can get for their prioritized alarms, while
+         * the device is in doze.
+         */
+        public long PRIORITY_ALARM_DELAY = DEFAULT_PRIORITY_ALARM_DELAY;
+
         private long mLastAllowWhileIdleWhitelistDuration = -1;
 
         Constants() {
@@ -662,6 +675,10 @@
                             CRASH_NON_CLOCK_APPS = properties.getBoolean(KEY_CRASH_NON_CLOCK_APPS,
                                     DEFAULT_CRASH_NON_CLOCK_APPS);
                             break;
+                        case KEY_PRIORITY_ALARM_DELAY:
+                            PRIORITY_ALARM_DELAY = properties.getLong(KEY_PRIORITY_ALARM_DELAY,
+                                    DEFAULT_PRIORITY_ALARM_DELAY);
+                            break;
                         default:
                             if (name.startsWith(KEY_PREFIX_STANDBY_QUOTA) && !standbyQuotaUpdated) {
                                 // The quotas need to be updated in order, so we can't just rely
@@ -809,6 +826,11 @@
             pw.print(KEY_CRASH_NON_CLOCK_APPS, CRASH_NON_CLOCK_APPS);
             pw.println();
 
+            pw.print(KEY_PRIORITY_ALARM_DELAY);
+            pw.print("=");
+            TimeUtils.formatDuration(PRIORITY_ALARM_DELAY, pw);
+            pw.println();
+
             pw.decreaseIndent();
         }
 
@@ -1794,6 +1816,11 @@
                 batterySaverPolicyElapsed = mAllowWhileIdleHistory.getNthLastWakeupForPackage(
                         alarm.sourcePackage, userId, quota) + window;
             }
+        } else if ((alarm.flags & FLAG_PRIORITIZE) != 0) {
+            final long lastDispatch = mLastPriorityAlarmDispatch.get(alarm.creatorUid, 0);
+            batterySaverPolicyElapsed = (lastDispatch == 0)
+                    ? nowElapsed
+                    : lastDispatch + mConstants.PRIORITY_ALARM_DELAY;
         } else {
             // Not allowed.
             batterySaverPolicyElapsed = nowElapsed + INDEFINITE_DELAY;
@@ -1849,6 +1876,12 @@
                         alarm.sourcePackage, userId, quota) + window;
                 deviceIdlePolicyTime = Math.min(whenInQuota, mPendingIdleUntil.getWhenElapsed());
             }
+        } else if ((alarm.flags & FLAG_PRIORITIZE) != 0) {
+            final long lastDispatch = mLastPriorityAlarmDispatch.get(alarm.creatorUid, 0);
+            final long whenAllowed = (lastDispatch == 0)
+                    ? nowElapsed
+                    : lastDispatch + mConstants.PRIORITY_ALARM_DELAY;
+            deviceIdlePolicyTime = Math.min(whenAllowed, mPendingIdleUntil.getWhenElapsed());
         } else {
             // Not allowed.
             deviceIdlePolicyTime = mPendingIdleUntil.getWhenElapsed();
@@ -2025,7 +2058,12 @@
             // make sure the caller is allowed to use the requested kind of alarm, and also
             // decide what quota and broadcast options to use.
             Bundle idleOptions = null;
-            if (exact || allowWhileIdle) {
+            if ((flags & FLAG_PRIORITIZE) != 0) {
+                getContext().enforcePermission(
+                        Manifest.permission.SCHEDULE_PRIORITIZED_ALARM,
+                        Binder.getCallingPid(), callingUid, "AlarmManager.setPrioritized");
+                flags &= ~(FLAG_ALLOW_WHILE_IDLE | FLAG_ALLOW_WHILE_IDLE_COMPAT);
+            } else if (exact || allowWhileIdle) {
                 final boolean needsPermission;
                 boolean lowerQuota;
                 if (CompatChanges.isChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION,
@@ -2107,6 +2145,7 @@
                 flags |= FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED;
                 flags &= ~FLAG_ALLOW_WHILE_IDLE;
                 flags &= ~FLAG_ALLOW_WHILE_IDLE_COMPAT;
+                flags &= ~FLAG_PRIORITIZE;
                 idleOptions = null;
             }
 
@@ -2489,6 +2528,19 @@
             pw.println("Allow while idle history:");
             mAllowWhileIdleHistory.dump(pw, nowELAPSED);
 
+            if (mLastPriorityAlarmDispatch.size() > 0) {
+                pw.println("Last priority alarm dispatches:");
+                pw.increaseIndent();
+                for (int i = 0; i < mLastPriorityAlarmDispatch.size(); i++) {
+                    pw.print("UID: ");
+                    UserHandle.formatUid(pw, mLastPriorityAlarmDispatch.keyAt(i));
+                    pw.print(": ");
+                    TimeUtils.formatDuration(mLastPriorityAlarmDispatch.valueAt(i), nowELAPSED, pw);
+                    pw.println();
+                }
+                pw.decreaseIndent();
+            }
+
             if (mLog.dump(pw, "Recent problems:")) {
                 pw.println();
             }
@@ -3303,6 +3355,11 @@
                 mPendingBackgroundAlarms.removeAt(i);
             }
         }
+        for (int i = mLastPriorityAlarmDispatch.size() - 1; i >= 0; i--) {
+            if (UserHandle.getUserId(mLastPriorityAlarmDispatch.keyAt(i)) == userHandle) {
+                mLastPriorityAlarmDispatch.removeAt(i);
+            }
+        }
         if (mNextWakeFromIdle != null && whichAlarms.test(mNextWakeFromIdle)) {
             mNextWakeFromIdle = mAlarmStore.getNextWakeFromIdleAlarm();
             if (mPendingIdleUntil != null) {
@@ -4103,6 +4160,7 @@
             IntentFilter sdFilter = new IntentFilter();
             sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
             sdFilter.addAction(Intent.ACTION_USER_STOPPED);
+            sdFilter.addAction(Intent.ACTION_UID_REMOVED);
             getContext().registerReceiver(this, sdFilter);
         }
 
@@ -4132,6 +4190,9 @@
                             mAllowWhileIdleHistory.removeForUser(userHandle);
                         }
                         return;
+                    case Intent.ACTION_UID_REMOVED:
+                        mLastPriorityAlarmDispatch.delete(uid);
+                        return;
                     case Intent.ACTION_PACKAGE_REMOVED:
                         if (intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
                             // This package is being updated; don't kill its alarms.
@@ -4522,11 +4583,11 @@
             if (inflight.isBroadcast()) {
                 notifyBroadcastAlarmPendingLocked(alarm.uid);
             }
-            if (isAllowedWhileIdleRestricted(alarm)) {
-                final boolean doze = (mPendingIdleUntil != null);
-                final boolean batterySaver = (mAppStateTracker != null
-                        && mAppStateTracker.isForceAllAppsStandbyEnabled());
-                if (doze || batterySaver) {
+            final boolean doze = (mPendingIdleUntil != null);
+            final boolean batterySaver = (mAppStateTracker != null
+                    && mAppStateTracker.isForceAllAppsStandbyEnabled());
+            if (doze || batterySaver) {
+                if (isAllowedWhileIdleRestricted(alarm)) {
                     // Record the last time this uid handled an ALLOW_WHILE_IDLE alarm while the
                     // device was in doze or battery saver.
                     mAllowWhileIdleHistory.recordAlarmForPackage(alarm.sourcePackage,
@@ -4538,6 +4599,16 @@
                         return (doze && adjustDeliveryTimeBasedOnDeviceIdle(a))
                                 || (batterySaver && adjustDeliveryTimeBasedOnBatterySaver(a));
                     });
+                } else if ((alarm.flags & FLAG_PRIORITIZE) != 0) {
+                    mLastPriorityAlarmDispatch.put(alarm.creatorUid, nowELAPSED);
+                    mAlarmStore.updateAlarmDeliveries(a -> {
+                        if (a.creatorUid != alarm.creatorUid
+                                || (alarm.flags & FLAG_PRIORITIZE) == 0) {
+                            return false;
+                        }
+                        return (doze && adjustDeliveryTimeBasedOnDeviceIdle(a))
+                                || (batterySaver && adjustDeliveryTimeBasedOnBatterySaver(a));
+                    });
                 }
                 if (RECORD_DEVICE_IDLE_ALARMS) {
                     IdleDispatchEntry ent = new IdleDispatchEntry();
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java b/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java
index b958c3f..d94d638 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java
@@ -266,6 +266,8 @@
 
     String[] mRecycledPreemptReasonForContext = new String[MAX_JOB_CONTEXTS_COUNT];
 
+    int[] mRecycledPreemptReasonCodeForContext = new int[MAX_JOB_CONTEXTS_COUNT];
+
     String[] mRecycledShouldStopJobReason = new String[MAX_JOB_CONTEXTS_COUNT];
 
     private final ArraySet<JobStatus> mRunningJobs = new ArraySet<>();
@@ -505,6 +507,7 @@
         int[] preferredUidForContext = mRecycledPreferredUidForContext;
         int[] workTypeForContext = mRecycledWorkTypeForContext;
         String[] preemptReasonForContext = mRecycledPreemptReasonForContext;
+        int[] preemptReasonCodeForContext = mRecycledPreemptReasonCodeForContext;
         String[] shouldStopJobReason = mRecycledShouldStopJobReason;
 
         updateCounterConfigLocked();
@@ -528,6 +531,7 @@
             slotChanged[i] = false;
             preferredUidForContext[i] = js.getPreferredUid();
             preemptReasonForContext[i] = null;
+            preemptReasonCodeForContext[i] = JobParameters.STOP_REASON_UNDEFINED;
             shouldStopJobReason[i] = shouldStopRunningJobLocked(js);
         }
         if (DEBUG) {
@@ -551,6 +555,7 @@
             int allWorkTypes = getJobWorkTypes(nextPending);
             int workType = mWorkCountTracker.canJobStart(allWorkTypes);
             boolean startingJob = false;
+            int preemptReasonCode = JobParameters.STOP_REASON_UNDEFINED;
             String preemptReason = null;
             // TODO(141645789): rewrite this to look at empty contexts first so we don't
             // unnecessarily preempt
@@ -582,6 +587,7 @@
                         // assign the new job to this context since we'll reassign when the
                         // preempted job finally stops.
                         preemptReason = reason;
+                        preemptReasonCode = JobParameters.STOP_REASON_DEVICE_STATE;
                     }
                     continue;
                 }
@@ -597,6 +603,7 @@
                     minPriorityForPreemption = jobPriority;
                     selectedContextId = j;
                     preemptReason = "higher priority job found";
+                    preemptReasonCode = JobParameters.STOP_REASON_PREEMPT;
                     // In this case, we're just going to preempt a low priority job, we're not
                     // actually starting a job, so don't set startingJob.
                 }
@@ -604,6 +611,7 @@
             if (selectedContextId != -1) {
                 contextIdToJobMap[selectedContextId] = nextPending;
                 slotChanged[selectedContextId] = true;
+                preemptReasonCodeForContext[selectedContextId] = preemptReasonCode;
                 preemptReasonForContext[selectedContextId] = preemptReason;
             }
             if (startingJob) {
@@ -631,8 +639,13 @@
                     }
                     // preferredUid will be set to uid of currently running job.
                     activeServices.get(i).cancelExecutingJobLocked(
+                            preemptReasonCodeForContext[i],
                             JobParameters.REASON_PREEMPT, preemptReasonForContext[i]);
-                    preservePreferredUid = true;
+                    // Only preserve the UID if we're preempting for the same UID. If we're stopping
+                    // the job because something is pending (eg. EJs), then we shouldn't preserve
+                    // the UID.
+                    preservePreferredUid =
+                            preemptReasonCodeForContext[i] == JobParameters.STOP_REASON_PREEMPT;
                 } else {
                     final JobStatus pendingJob = contextIdToJobMap[i];
                     if (DEBUG) {
@@ -657,7 +670,8 @@
             final JobStatus jobStatus = jsc.getRunningJobLocked();
 
             if (jobStatus != null && !jsc.isWithinExecutionGuaranteeTime()) {
-                jsc.cancelExecutingJobLocked(JobParameters.REASON_TIMEOUT, debugReason);
+                jsc.cancelExecutingJobLocked(JobParameters.STOP_REASON_DEVICE_STATE,
+                        JobParameters.REASON_TIMEOUT, debugReason);
             }
         }
     }
@@ -877,7 +891,7 @@
         }
 
         // Only expedited jobs can replace expedited jobs.
-        if (js.shouldTreatAsExpeditedJob()) {
+        if (js.shouldTreatAsExpeditedJob() || js.startedAsExpeditedJob) {
             // Keep fg/bg user distinction.
             if (workType == WORK_TYPE_BGUSER_IMPORTANT || workType == WORK_TYPE_BGUSER) {
                 // Let any important bg user job replace a bg user expedited job.
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobPackageTracker.java b/apex/jobscheduler/service/java/com/android/server/job/JobPackageTracker.java
index 6ffac91..02f9129 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobPackageTracker.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobPackageTracker.java
@@ -374,7 +374,7 @@
                             pw.print(pe.stopReasons.valueAt(k));
                             pw.print("x ");
                             pw.print(JobParameters
-                                    .getReasonCodeDescription(pe.stopReasons.keyAt(k)));
+                                    .getLegacyReasonCodeDescription(pe.stopReasons.keyAt(k)));
                         }
                         pw.println();
                     }
@@ -621,7 +621,7 @@
                 if (reason != null) {
                     pw.print(mEventReasons[index]);
                 } else {
-                    pw.print(JobParameters.getReasonCodeDescription(
+                    pw.print(JobParameters.getLegacyReasonCodeDescription(
                             (mEventCmds[index] & EVENT_STOP_REASON_MASK)
                                     >> EVENT_STOP_REASON_SHIFT));
                 }
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
index 2b08ba5..a452fbc 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
@@ -746,8 +746,11 @@
                                             Slog.d(TAG, "Removing jobs for package " + pkgName
                                                     + " in user " + userId);
                                         }
+                                        // By the time we get here, the process should have already
+                                        // been stopped, so the app wouldn't get the stop reason,
+                                        // so just put USER instead of UNINSTALL or DISABLED.
                                         cancelJobsForPackageAndUid(pkgName, pkgUid,
-                                                "app disabled");
+                                                JobParameters.STOP_REASON_USER, "app disabled");
                                     }
                                 } catch (RemoteException|IllegalArgumentException e) {
                                     /*
@@ -785,7 +788,11 @@
                     if (DEBUG) {
                         Slog.d(TAG, "Removing jobs for uid: " + uidRemoved);
                     }
-                    cancelJobsForPackageAndUid(pkgName, uidRemoved, "app uninstalled");
+                    // By the time we get here, the process should have already
+                    // been stopped, so the app wouldn't get the stop reason,
+                    // so just put USER instead of UNINSTALL or DISABLED.
+                    cancelJobsForPackageAndUid(pkgName, uidRemoved,
+                            JobParameters.STOP_REASON_USER, "app uninstalled");
                     synchronized (mLock) {
                         for (int c = 0; c < mControllers.size(); ++c) {
                             mControllers.get(c).onAppRemovedLocked(pkgName, pkgUid);
@@ -837,7 +844,8 @@
                     if (DEBUG) {
                         Slog.d(TAG, "Removing jobs for pkg " + pkgName + " at uid " + pkgUid);
                     }
-                    cancelJobsForPackageAndUid(pkgName, pkgUid, "app force stopped");
+                    cancelJobsForPackageAndUid(pkgName, pkgUid,
+                            JobParameters.STOP_REASON_USER, "app force stopped");
                 }
             }
         }
@@ -924,8 +932,7 @@
         final String servicePkg = job.getService().getPackageName();
         if (job.isPersisted() && (packageName == null || packageName.equals(servicePkg))) {
             // Only limit schedule calls for persisted jobs scheduled by the app itself.
-            final String pkg =
-                    packageName == null ? job.getService().getPackageName() : packageName;
+            final String pkg = packageName == null ? servicePkg : packageName;
             if (!mQuotaTracker.isWithinQuota(userId, pkg, QUOTA_TRACKER_SCHEDULE_PERSISTED_TAG)) {
                 if (mQuotaTracker.isWithinQuota(userId, pkg, QUOTA_TRACKER_SCHEDULE_LOGGED)) {
                     // Don't log too frequently
@@ -972,14 +979,10 @@
             mQuotaTracker.noteEvent(userId, pkg, QUOTA_TRACKER_SCHEDULE_PERSISTED_TAG);
         }
 
-        try {
-            if (ActivityManager.getService().isAppStartModeDisabled(uId,
-                    job.getService().getPackageName())) {
-                Slog.w(TAG, "Not scheduling job " + uId + ":" + job.toString()
-                        + " -- package not allowed to start");
-                return JobScheduler.RESULT_FAILURE;
-            }
-        } catch (RemoteException e) {
+        if (mActivityManagerInternal.isAppStartModeDisabled(uId, servicePkg)) {
+            Slog.w(TAG, "Not scheduling job " + uId + ":" + job.toString()
+                    + " -- package not allowed to start");
+            return JobScheduler.RESULT_FAILURE;
         }
 
         synchronized (mLock) {
@@ -1029,7 +1032,8 @@
 
             if (toCancel != null) {
                 // Implicitly replaces the existing job record with the new instance
-                cancelJobImplLocked(toCancel, jobStatus, "job rescheduled by app");
+                cancelJobImplLocked(toCancel, jobStatus, JobParameters.STOP_REASON_CANCELLED_BY_APP,
+                        "job rescheduled by app");
             } else {
                 startTrackingJobLocked(jobStatus, null);
             }
@@ -1042,7 +1046,7 @@
             FrameworkStatsLog.write_non_chained(FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED,
                     uId, null, jobStatus.getBatteryName(),
                     FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED__STATE__SCHEDULED,
-                    JobProtoEnums.STOP_REASON_CANCELLED, jobStatus.getStandbyBucket(),
+                    JobProtoEnums.STOP_REASON_UNKNOWN, jobStatus.getStandbyBucket(),
                     jobStatus.getJobId(),
                     jobStatus.hasChargingConstraint(),
                     jobStatus.hasBatteryNotLowConstraint(),
@@ -1051,7 +1055,9 @@
                     jobStatus.hasDeadlineConstraint(),
                     jobStatus.hasIdleConstraint(),
                     jobStatus.hasConnectivityConstraint(),
-                    jobStatus.hasContentTriggerConstraint());
+                    jobStatus.hasContentTriggerConstraint(),
+                    jobStatus.isRequestedExpeditedJob(),
+                    /* isRunningAsExpeditedJob */ false);
 
             // If the job is immediately ready to run, then we can just immediately
             // put it in the pending list and try to schedule it.  This is especially
@@ -1105,7 +1111,10 @@
             final List<JobStatus> jobsForUser = mJobs.getJobsByUser(userHandle);
             for (int i=0; i<jobsForUser.size(); i++) {
                 JobStatus toRemove = jobsForUser.get(i);
-                cancelJobImplLocked(toRemove, null, "user removed");
+                // By the time we get here, the process should have already been stopped, so the
+                // app wouldn't get the stop reason, so just put USER instead of UNINSTALL.
+                cancelJobImplLocked(toRemove, null, JobParameters.STOP_REASON_USER,
+                        "user removed");
             }
         }
     }
@@ -1117,7 +1126,8 @@
         }
     }
 
-    void cancelJobsForPackageAndUid(String pkgName, int uid, String reason) {
+    void cancelJobsForPackageAndUid(String pkgName, int uid, @JobParameters.StopReason int reason,
+            String debugReason) {
         if ("android".equals(pkgName)) {
             Slog.wtfStack(TAG, "Can't cancel all jobs for system package");
             return;
@@ -1127,7 +1137,7 @@
             for (int i = jobsForUid.size() - 1; i >= 0; i--) {
                 final JobStatus job = jobsForUid.get(i);
                 if (job.getSourcePackageName().equals(pkgName)) {
-                    cancelJobImplLocked(job, null, reason);
+                    cancelJobImplLocked(job, null, reason, debugReason);
                 }
             }
         }
@@ -1137,10 +1147,11 @@
      * Entry point from client to cancel all jobs originating from their uid.
      * This will remove the job from the master list, and cancel the job if it was staged for
      * execution or being executed.
-     * @param uid Uid to check against for removal of a job.
      *
+     * @param uid Uid to check against for removal of a job.
      */
-    public boolean cancelJobsForUid(int uid, String reason) {
+    public boolean cancelJobsForUid(int uid, @JobParameters.StopReason int reason,
+            String debugReason) {
         if (uid == Process.SYSTEM_UID) {
             Slog.wtfStack(TAG, "Can't cancel all jobs for system uid");
             return false;
@@ -1151,7 +1162,7 @@
             final List<JobStatus> jobsForUid = mJobs.getJobsByUid(uid);
             for (int i=0; i<jobsForUid.size(); i++) {
                 JobStatus toRemove = jobsForUid.get(i);
-                cancelJobImplLocked(toRemove, null, reason);
+                cancelJobImplLocked(toRemove, null, reason, debugReason);
                 jobsCanceled = true;
             }
         }
@@ -1162,15 +1173,17 @@
      * Entry point from client to cancel the job corresponding to the jobId provided.
      * This will remove the job from the master list, and cancel the job if it was staged for
      * execution or being executed.
-     * @param uid Uid of the calling client.
+     *
+     * @param uid   Uid of the calling client.
      * @param jobId Id of the job, provided at schedule-time.
      */
-    public boolean cancelJob(int uid, int jobId, int callingUid) {
+    private boolean cancelJob(int uid, int jobId, int callingUid,
+            @JobParameters.StopReason int reason) {
         JobStatus toCancel;
         synchronized (mLock) {
             toCancel = mJobs.getJobByUidAndJobId(uid, jobId);
             if (toCancel != null) {
-                cancelJobImplLocked(toCancel, null,
+                cancelJobImplLocked(toCancel, null, reason,
                         "cancel() called by app, callingUid=" + callingUid
                         + " uid=" + uid + " jobId=" + jobId);
             }
@@ -1184,7 +1197,8 @@
      * {@code incomingJob} is non-null, it replaces {@code cancelled} in the store of
      * currently scheduled jobs.
      */
-    private void cancelJobImplLocked(JobStatus cancelled, JobStatus incomingJob, String reason) {
+    private void cancelJobImplLocked(JobStatus cancelled, JobStatus incomingJob,
+            @JobParameters.StopReason int reason, String debugReason) {
         if (DEBUG) Slog.d(TAG, "CANCEL: " + cancelled.toShortString());
         cancelled.unprepareLocked();
         stopTrackingJobLocked(cancelled, incomingJob, true /* writeBack */);
@@ -1193,7 +1207,8 @@
             mJobPackageTracker.noteNonpending(cancelled);
         }
         // Cancel if running.
-        stopJobOnServiceContextLocked(cancelled, JobParameters.REASON_CANCELED, reason);
+        stopJobOnServiceContextLocked(cancelled, reason, JobParameters.REASON_CANCELED,
+                debugReason);
         // If this is a replacement, bring in the new version of the job
         if (incomingJob != null) {
             if (DEBUG) Slog.i(TAG, "Tracking replacement job " + incomingJob.toShortString());
@@ -1232,7 +1247,8 @@
                     JobServiceContext jsc = mActiveServices.get(i);
                     final JobStatus executing = jsc.getRunningJobLocked();
                     if (executing != null && !executing.canRunInDoze()) {
-                        jsc.cancelExecutingJobLocked(JobParameters.REASON_DEVICE_IDLE,
+                        jsc.cancelExecutingJobLocked(JobParameters.STOP_REASON_DEVICE_STATE,
+                                JobParameters.REASON_DEVICE_IDLE,
                                 "cancelled due to doze");
                     }
                 }
@@ -1430,7 +1446,8 @@
                 if (DEBUG) {
                     Slog.v(TAG, "  replacing " + oldJob + " with " + newJob);
                 }
-                cancelJobImplLocked(oldJob, newJob, "deferred rtc calculation");
+                cancelJobImplLocked(oldJob, newJob, JobParameters.STOP_REASON_SYSTEM_PROCESSING,
+                        "deferred rtc calculation");
             }
         }
     };
@@ -1550,12 +1567,13 @@
         return removed;
     }
 
-    private boolean stopJobOnServiceContextLocked(JobStatus job, int reason, String debugReason) {
+    private boolean stopJobOnServiceContextLocked(JobStatus job,
+            @JobParameters.StopReason int reason, int legacyReason, String debugReason) {
         for (int i=0; i<mActiveServices.size(); i++) {
             JobServiceContext jsc = mActiveServices.get(i);
             final JobStatus executing = jsc.getRunningJobLocked();
             if (executing != null && executing.matches(job.getUid(), job.getJobId())) {
-                jsc.cancelExecutingJobLocked(reason, debugReason);
+                jsc.cancelExecutingJobLocked(reason, legacyReason, debugReason);
                 return true;
             }
         }
@@ -1880,7 +1898,7 @@
                         queueReadyJobsForExecutionLocked();
                         break;
                     case MSG_STOP_JOB:
-                        cancelJobImplLocked((JobStatus) message.obj, null,
+                        cancelJobImplLocked((JobStatus) message.obj, null, message.arg1,
                                 "app no longer allowed to run");
                         break;
 
@@ -1895,7 +1913,9 @@
                         final boolean disabled = message.arg2 != 0;
                         updateUidState(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
                         if (disabled) {
-                            cancelJobsForUid(uid, "uid gone");
+                            cancelJobsForUid(uid,
+                                    JobParameters.STOP_REASON_BACKGROUND_RESTRICTION,
+                                    "uid gone");
                         }
                         synchronized (mLock) {
                             mDeviceIdleJobsController.setUidActiveLocked(uid, false);
@@ -1913,7 +1933,9 @@
                         final int uid = message.arg1;
                         final boolean disabled = message.arg2 != 0;
                         if (disabled) {
-                            cancelJobsForUid(uid, "app uid idle");
+                            cancelJobsForUid(uid,
+                                    JobParameters.STOP_REASON_BACKGROUND_RESTRICTION,
+                                    "app uid idle");
                         }
                         synchronized (mLock) {
                             mDeviceIdleJobsController.setUidActiveLocked(uid, false);
@@ -1965,10 +1987,12 @@
                 if (running.getEffectiveStandbyBucket() == RESTRICTED_INDEX
                         && !running.areDynamicConstraintsSatisfied()) {
                     serviceContext.cancelExecutingJobLocked(
+                            running.getStopReason(),
                             JobParameters.REASON_RESTRICTED_BUCKET,
                             "cancelled due to restricted bucket");
                 } else {
                     serviceContext.cancelExecutingJobLocked(
+                            running.getStopReason(),
                             JobParameters.REASON_CONSTRAINTS_NOT_SATISFIED,
                             "cancelled due to unsatisfied constraints");
                 }
@@ -1977,7 +2001,9 @@
                 if (restriction != null) {
                     final int reason = restriction.getReason();
                     serviceContext.cancelExecutingJobLocked(reason,
-                            "restricted due to " + JobParameters.getReasonCodeDescription(reason));
+                            restriction.getLegacyReason(),
+                            "restricted due to " + JobParameters.getLegacyReasonCodeDescription(
+                                    reason));
                 }
             }
         }
@@ -2058,15 +2084,14 @@
         @Override
         public void accept(JobStatus job) {
             if (isReadyToBeExecutedLocked(job)) {
-                try {
-                    if (ActivityManager.getService().isAppStartModeDisabled(job.getUid(),
-                            job.getJob().getService().getPackageName())) {
-                        Slog.w(TAG, "Aborting job " + job.getUid() + ":"
-                                + job.getJob().toString() + " -- package not allowed to start");
-                        mHandler.obtainMessage(MSG_STOP_JOB, job).sendToTarget();
-                        return;
-                    }
-                } catch (RemoteException e) {
+                if (mActivityManagerInternal.isAppStartModeDisabled(job.getUid(),
+                        job.getJob().getService().getPackageName())) {
+                    Slog.w(TAG, "Aborting job " + job.getUid() + ":"
+                            + job.getJob().toString() + " -- package not allowed to start");
+                    mHandler.obtainMessage(MSG_STOP_JOB,
+                            JobParameters.STOP_REASON_BACKGROUND_RESTRICTION, 0, job)
+                            .sendToTarget();
+                    return;
                 }
 
                 final boolean shouldForceBatchJob;
@@ -2164,6 +2189,10 @@
      */
     @VisibleForTesting
     boolean isReadyToBeExecutedLocked(JobStatus job) {
+        return isReadyToBeExecutedLocked(job, true);
+    }
+
+    boolean isReadyToBeExecutedLocked(JobStatus job, boolean rejectActive) {
         final boolean jobReady = job.isReady();
 
         if (DEBUG) {
@@ -2202,7 +2231,7 @@
         }
 
         final boolean jobPending = mPendingJobs.contains(job);
-        final boolean jobActive = isCurrentlyActiveLocked(job);
+        final boolean jobActive = rejectActive && isCurrentlyActiveLocked(job);
 
         if (DEBUG) {
             Slog.v(TAG, "isReadyToBeExecutedLocked: " + job.toShortString()
@@ -2276,7 +2305,7 @@
         if (restriction != null) {
             if (DEBUG) {
                 Slog.v(TAG, "areComponentsInPlaceLocked: " + job.toShortString()
-                        + " restricted due to " + restriction.getReason());
+                        + " restricted due to " + restriction.getLegacyReason());
             }
             return false;
         }
@@ -2367,8 +2396,9 @@
         }
 
         @Override
-        public void cancelJobsForUid(int uid, String reason) {
-            JobSchedulerService.this.cancelJobsForUid(uid, reason);
+        public void cancelJobsForUid(int uid, @JobParameters.StopReason int reason,
+                String debugReason) {
+            JobSchedulerService.this.cancelJobsForUid(uid, reason, debugReason);
         }
 
         @Override
@@ -2706,6 +2736,7 @@
             final long ident = Binder.clearCallingIdentity();
             try {
                 JobSchedulerService.this.cancelJobsForUid(uid,
+                        JobParameters.STOP_REASON_CANCELLED_BY_APP,
                         "cancelAll() called by app, callingUid=" + uid);
             } finally {
                 Binder.restoreCallingIdentity(ident);
@@ -2718,7 +2749,8 @@
 
             final long ident = Binder.clearCallingIdentity();
             try {
-                JobSchedulerService.this.cancelJob(uid, jobId, uid);
+                JobSchedulerService.this.cancelJob(uid, jobId, uid,
+                        JobParameters.STOP_REASON_CANCELLED_BY_APP);
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
@@ -2924,12 +2956,13 @@
 
         if (!hasJobId) {
             pw.println("Canceling all jobs for " + pkgName + " in user " + userId);
-            if (!cancelJobsForUid(pkgUid, "cancel shell command for package")) {
+            if (!cancelJobsForUid(pkgUid, JobParameters.STOP_REASON_USER,
+                    "cancel shell command for package")) {
                 pw.println("No matching jobs found.");
             }
         } else {
             pw.println("Canceling job " + pkgName + "/#" + jobId + " in user " + userId);
-            if (!cancelJob(pkgUid, jobId, Process.SHELL_UID)) {
+            if (!cancelJob(pkgUid, jobId, Process.SHELL_UID, JobParameters.STOP_REASON_USER)) {
                 pw.println("No matching job found.");
             }
         }
@@ -3164,8 +3197,9 @@
                         for (int i = mJobRestrictions.size() - 1; i >= 0; i--) {
                             final JobRestriction restriction = mJobRestrictions.get(i);
                             if (restriction.isJobRestricted(job)) {
-                                final int reason = restriction.getReason();
-                                pw.print(" " + JobParameters.getReasonCodeDescription(reason));
+                                final int reason = restriction.getLegacyReason();
+                                pw.print(" ");
+                                pw.print(JobParameters.getLegacyReasonCodeDescription(reason));
                             }
                         }
                     } else {
@@ -3430,7 +3464,7 @@
                         final long restrictionsToken = proto.start(
                                 JobSchedulerServiceDumpProto.RegisteredJob.RESTRICTIONS);
                         proto.write(JobSchedulerServiceDumpProto.JobRestriction.REASON,
-                                restriction.getReason());
+                                restriction.getLegacyReason());
                         proto.write(JobSchedulerServiceDumpProto.JobRestriction.IS_RESTRICTING,
                                 restriction.isJobRestricted(job));
                         proto.end(restrictionsToken);
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java b/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
index 9ef46df..44b3e3e 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
@@ -151,6 +151,14 @@
     /** The absolute maximum amount of time the job can run */
     private long mMaxExecutionTimeMillis;
 
+    /**
+     * The stop reason for a pending cancel. If there's not pending cancel, then the value should be
+     * {@link JobParameters#STOP_REASON_UNDEFINED}.
+     */
+    private int mPendingStopReason = JobParameters.STOP_REASON_UNDEFINED;
+    private int mPendingLegacyStopReason;
+    private String mPendingDebugStopReason;
+
     // Debugging: reason this job was last stopped.
     public String mStoppedReason;
 
@@ -272,7 +280,7 @@
                 if (job.shouldTreatAsExpeditedJob()) {
                     bindFlags = Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND
                             | Context.BIND_ALMOST_PERCEPTIBLE
-                            | Context.BIND_ALLOW_NETWORK_ACCESS
+                            | Context.BIND_BYPASS_POWER_NETWORK_RESTRICTIONS
                             | Context.BIND_NOT_APP_COMPONENT_USAGE;
                 } else {
                     bindFlags = Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND
@@ -314,7 +322,9 @@
                     job.hasDeadlineConstraint(),
                     job.hasIdleConstraint(),
                     job.hasConnectivityConstraint(),
-                    job.hasContentTriggerConstraint());
+                    job.hasContentTriggerConstraint(),
+                    job.isRequestedExpeditedJob(),
+                    job.shouldTreatAsExpeditedJob());
             try {
                 mBatteryStats.noteJobStart(job.getBatteryName(), job.getSourceUid());
             } catch (RemoteException e) {
@@ -328,6 +338,7 @@
             mAvailable = false;
             mStoppedReason = null;
             mStoppedTime = 0;
+            job.startedAsExpeditedJob = job.shouldTreatAsExpeditedJob();
             return true;
         }
     }
@@ -354,8 +365,9 @@
 
     /** Called externally when a job that was scheduled for execution should be cancelled. */
     @GuardedBy("mLock")
-    void cancelExecutingJobLocked(int reason, @NonNull String debugReason) {
-        doCancelLocked(reason, debugReason);
+    void cancelExecutingJobLocked(@JobParameters.StopReason int reason,
+            int legacyStopReason, @NonNull String debugReason) {
+        doCancelLocked(reason, legacyStopReason, debugReason);
     }
 
     int getPreferredUid() {
@@ -387,7 +399,8 @@
                 && (pkgName == null || pkgName.equals(executing.getSourcePackageName()))
                 && (!matchJobId || jobId == executing.getJobId())) {
             if (mVerb == VERB_EXECUTING) {
-                mParams.setStopReason(JobParameters.REASON_TIMEOUT, reason);
+                mParams.setStopReason(JobParameters.STOP_REASON_TIMEOUT,
+                        JobParameters.REASON_TIMEOUT, reason);
                 sendStopMessageLocked("force timeout from shell");
                 return true;
             }
@@ -614,7 +627,8 @@
     }
 
     @GuardedBy("mLock")
-    private void doCancelLocked(int stopReasonCode, @Nullable String debugReason) {
+    private void doCancelLocked(@JobParameters.StopReason int stopReasonCode, int legacyStopReason,
+            @Nullable String debugReason) {
         if (mVerb == VERB_FINISHED) {
             if (DEBUG) {
                 Slog.d(TAG,
@@ -622,8 +636,21 @@
             }
             return;
         }
-        mParams.setStopReason(stopReasonCode, debugReason);
-        if (stopReasonCode == JobParameters.REASON_PREEMPT) {
+        if (mRunningJob.startedAsExpeditedJob
+                && stopReasonCode == JobParameters.STOP_REASON_QUOTA) {
+            // EJs should be able to run for at least the min upper limit regardless of quota.
+            final long earliestStopTimeElapsed =
+                    mExecutionStartTimeElapsed + mMinExecutionGuaranteeMillis;
+            final long nowElapsed = sElapsedRealtimeClock.millis();
+            if (nowElapsed < earliestStopTimeElapsed) {
+                mPendingStopReason = stopReasonCode;
+                mPendingLegacyStopReason = legacyStopReason;
+                mPendingDebugStopReason = debugReason;
+                return;
+            }
+        }
+        mParams.setStopReason(stopReasonCode, legacyStopReason, debugReason);
+        if (legacyStopReason == JobParameters.REASON_PREEMPT) {
             mPreferredUid = mRunningJob != null ? mRunningJob.getUid() :
                     NO_PREFERRED_UID;
         }
@@ -774,6 +801,23 @@
                 closeAndCleanupJobLocked(true /* needsReschedule */, "timed out while stopping");
                 break;
             case VERB_EXECUTING:
+                if (mPendingStopReason != JobParameters.STOP_REASON_UNDEFINED) {
+                    if (mService.isReadyToBeExecutedLocked(mRunningJob, false)) {
+                        // Job became ready again while we were waiting to stop it (for example,
+                        // the device was temporarily taken off the charger). Ignore the pending
+                        // stop and see what the manager says.
+                        mPendingStopReason = JobParameters.STOP_REASON_UNDEFINED;
+                        mPendingLegacyStopReason = 0;
+                        mPendingDebugStopReason = null;
+                    } else {
+                        Slog.i(TAG, "JS was waiting to stop this job."
+                                + " Sending onStop: " + getRunningJobNameLocked());
+                        mParams.setStopReason(mPendingStopReason, mPendingLegacyStopReason,
+                                mPendingDebugStopReason);
+                        sendStopMessageLocked(mPendingDebugStopReason);
+                        break;
+                    }
+                }
                 final long latestStopTimeElapsed =
                         mExecutionStartTimeElapsed + mMaxExecutionTimeMillis;
                 final long nowElapsed = sElapsedRealtimeClock.millis();
@@ -781,7 +825,8 @@
                     // Not an error - client ran out of time.
                     Slog.i(TAG, "Client timed out while executing (no jobFinished received)."
                             + " Sending onStop: " + getRunningJobNameLocked());
-                    mParams.setStopReason(JobParameters.REASON_TIMEOUT, "client timed out");
+                    mParams.setStopReason(JobParameters.STOP_REASON_TIMEOUT,
+                            JobParameters.REASON_TIMEOUT, "client timed out");
                     sendStopMessageLocked("timeout while executing");
                 } else {
                     // We've given the app the minimum execution time. See if we should stop it or
@@ -790,7 +835,11 @@
                     if (reason != null) {
                         Slog.i(TAG, "Stopping client after min execution time: "
                                 + getRunningJobNameLocked() + " because " + reason);
-                        mParams.setStopReason(JobParameters.REASON_TIMEOUT, reason);
+                        // Tell the developer we're stopping the job due to device state instead
+                        // of timeout since all of the reasons could equate to "the system needs
+                        // the resources the app is currently using."
+                        mParams.setStopReason(JobParameters.STOP_REASON_DEVICE_STATE,
+                                JobParameters.REASON_TIMEOUT, reason);
                         sendStopMessageLocked(reason);
                     } else {
                         Slog.i(TAG, "Letting " + getRunningJobNameLocked()
@@ -844,12 +893,12 @@
         }
         applyStoppedReasonLocked(reason);
         completedJob = mRunningJob;
-        final int stopReason = mParams.getStopReason();
-        mJobPackageTracker.noteInactive(completedJob, stopReason, reason);
+        final int legacyStopReason = mParams.getLegacyStopReason();
+        mJobPackageTracker.noteInactive(completedJob, legacyStopReason, reason);
         FrameworkStatsLog.write_non_chained(FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED,
                 completedJob.getSourceUid(), null, completedJob.getBatteryName(),
                 FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED__STATE__FINISHED,
-                stopReason, completedJob.getStandbyBucket(), completedJob.getJobId(),
+                legacyStopReason, completedJob.getStandbyBucket(), completedJob.getJobId(),
                 completedJob.hasChargingConstraint(),
                 completedJob.hasBatteryNotLowConstraint(),
                 completedJob.hasStorageNotLowConstraint(),
@@ -857,10 +906,12 @@
                 completedJob.hasDeadlineConstraint(),
                 completedJob.hasIdleConstraint(),
                 completedJob.hasConnectivityConstraint(),
-                completedJob.hasContentTriggerConstraint());
+                completedJob.hasContentTriggerConstraint(),
+                completedJob.isRequestedExpeditedJob(),
+                completedJob.startedAsExpeditedJob);
         try {
             mBatteryStats.noteJobFinish(mRunningJob.getBatteryName(), mRunningJob.getSourceUid(),
-                    stopReason);
+                    legacyStopReason);
         } catch (RemoteException e) {
             // Whatever.
         }
@@ -878,8 +929,11 @@
         mCancelled = false;
         service = null;
         mAvailable = true;
+        mPendingStopReason = JobParameters.STOP_REASON_UNDEFINED;
+        mPendingLegacyStopReason = 0;
+        mPendingDebugStopReason = null;
         removeOpTimeOutLocked();
-        mCompletedListener.onJobCompletedLocked(completedJob, stopReason, reschedule);
+        mCompletedListener.onJobCompletedLocked(completedJob, legacyStopReason, reschedule);
         mJobConcurrencyManager.onJobCompletedLocked(this, completedJob, workType);
     }
 
@@ -964,7 +1018,16 @@
             pw.print(", ");
             TimeUtils.formatDuration(
                     (mExecutionStartTimeElapsed + mMaxExecutionTimeMillis) - nowElapsed, pw);
-            pw.println("]");
+            pw.print("]");
+            if (mPendingStopReason != JobParameters.STOP_REASON_UNDEFINED) {
+                pw.print(" Pending stop because ");
+                pw.print(mPendingStopReason);
+                pw.print("/");
+                pw.print(mPendingLegacyStopReason);
+                pw.print("/");
+                pw.print(mPendingDebugStopReason);
+            }
+            pw.println();
             pw.decreaseIndent();
         }
     }
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobStore.java b/apex/jobscheduler/service/java/com/android/server/job/JobStore.java
index aa8d98c..9cd3a8f 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobStore.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobStore.java
@@ -541,18 +541,23 @@
         /**
          * Write out a tag with data identifying this job's constraints. If the constraint isn't here
          * it doesn't apply.
+         * TODO: b/183455312 Update this code to use proper serialization for NetworkRequest,
+         *       because currently store is not including everything (like, UIDs, bandwidth,
+         *       signal strength etc. are lost).
          */
         private void writeConstraintsToXml(XmlSerializer out, JobStatus jobStatus) throws IOException {
             out.startTag(null, XML_TAG_PARAMS_CONSTRAINTS);
             if (jobStatus.hasConnectivityConstraint()) {
                 final NetworkRequest network = jobStatus.getJob().getRequiredNetwork();
+                // STOPSHIP b/183071974: improve the scheme for backward compatibility and
+                // mainline cleanliness.
                 out.attribute(null, "net-capabilities", Long.toString(
-                        BitUtils.packBits(network.networkCapabilities.getCapabilities())));
+                        BitUtils.packBits(network.getCapabilities())));
                 out.attribute(null, "net-unwanted-capabilities", Long.toString(
-                        BitUtils.packBits(network.networkCapabilities.getUnwantedCapabilities())));
+                        BitUtils.packBits(network.getUnwantedCapabilities())));
 
                 out.attribute(null, "net-transport-types", Long.toString(
-                        BitUtils.packBits(network.networkCapabilities.getTransportTypes())));
+                        BitUtils.packBits(network.getTransportTypes())));
             }
             if (jobStatus.hasIdleConstraint()) {
                 out.attribute(null, "idle", Boolean.toString(true));
@@ -976,18 +981,23 @@
                     null, "net-unwanted-capabilities");
             final String netTransportTypes = parser.getAttributeValue(null, "net-transport-types");
             if (netCapabilities != null && netTransportTypes != null) {
-                final NetworkRequest request = new NetworkRequest.Builder().build();
+                final NetworkRequest.Builder builder = new NetworkRequest.Builder()
+                        .clearCapabilities();
                 final long unwantedCapabilities = netUnwantedCapabilities != null
                         ? Long.parseLong(netUnwantedCapabilities)
-                        : BitUtils.packBits(request.networkCapabilities.getUnwantedCapabilities());
-
+                        : BitUtils.packBits(builder.build().getUnwantedCapabilities());
                 // We're okay throwing NFE here; caught by caller
-                request.networkCapabilities.setCapabilities(
-                        BitUtils.unpackBits(Long.parseLong(netCapabilities)),
-                        BitUtils.unpackBits(unwantedCapabilities));
-                request.networkCapabilities.setTransportTypes(
-                        BitUtils.unpackBits(Long.parseLong(netTransportTypes)));
-                jobBuilder.setRequiredNetwork(request);
+                for (int capability : BitUtils.unpackBits(Long.parseLong(netCapabilities))) {
+                    builder.addCapability(capability);
+                }
+                for (int unwantedCapability : BitUtils.unpackBits(
+                        Long.parseLong(netUnwantedCapabilities))) {
+                    builder.addUnwantedCapability(unwantedCapability);
+                }
+                for (int transport : BitUtils.unpackBits(Long.parseLong(netTransportTypes))) {
+                    builder.addTransportType(transport);
+                }
+                jobBuilder.setRequiredNetwork(builder.build());
             } else {
                 // Read legacy values
                 val = parser.getAttributeValue(null, "connectivity");
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/BackgroundJobsController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/BackgroundJobsController.java
index a230b23..548a1ac 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/BackgroundJobsController.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/BackgroundJobsController.java
@@ -210,7 +210,8 @@
             jobStatus.maybeLogBucketMismatch();
         }
         boolean didChange =
-                jobStatus.setBackgroundNotRestrictedConstraintSatisfied(nowElapsed, canRun);
+                jobStatus.setBackgroundNotRestrictedConstraintSatisfied(nowElapsed, canRun,
+                        !mAppStateTracker.isRunAnyInBackgroundAppOpsAllowed(uid, packageName));
         didChange |= jobStatus.setUidActive(isActive);
         return didChange;
     }
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java
index 6e542f3..1e78ec3 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java
@@ -22,15 +22,13 @@
 import static com.android.server.job.JobSchedulerService.RESTRICTED_INDEX;
 import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.job.JobInfo;
 import android.net.ConnectivityManager;
 import android.net.ConnectivityManager.NetworkCallback;
-import android.net.INetworkPolicyListener;
 import android.net.Network;
 import android.net.NetworkCapabilities;
-import android.net.NetworkInfo;
-import android.net.NetworkPolicyManager;
 import android.net.NetworkRequest;
 import android.os.Handler;
 import android.os.Looper;
@@ -42,8 +40,10 @@
 import android.util.DataUnit;
 import android.util.IndentingPrintWriter;
 import android.util.Log;
+import android.util.Pools;
 import android.util.Slog;
 import android.util.SparseArray;
+import android.util.TimeUtils;
 import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.annotations.GuardedBy;
@@ -54,6 +54,9 @@
 import com.android.server.job.StateControllerProto;
 import com.android.server.net.NetworkPolicyManagerInternal;
 
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
 import java.util.Objects;
 import java.util.function.Predicate;
 
@@ -72,8 +75,15 @@
     private static final boolean DEBUG = JobSchedulerService.DEBUG
             || Log.isLoggable(TAG, Log.DEBUG);
 
+    // The networking stack has a hard limit so we can't make this configurable.
+    private static final int MAX_NETWORK_CALLBACKS = 50;
+    /**
+     * Minimum amount of time that should have elapsed before we'll update a {@link UidStats}
+     * instance.
+     */
+    private static final long MIN_STATS_UPDATE_INTERVAL_MS = 30_000L;
+
     private final ConnectivityManager mConnManager;
-    private final NetworkPolicyManager mNetPolicyManager;
     private final NetworkPolicyManagerInternal mNetPolicyManagerInternal;
 
     /** List of tracked jobs keyed by source UID. */
@@ -94,8 +104,69 @@
     @GuardedBy("mLock")
     private final ArrayMap<Network, NetworkCapabilities> mAvailableNetworks = new ArrayMap<>();
 
-    private static final int MSG_DATA_SAVER_TOGGLED = 0;
-    private static final int MSG_UID_RULES_CHANGES = 1;
+    private final SparseArray<UidDefaultNetworkCallback> mCurrentDefaultNetworkCallbacks =
+            new SparseArray<>();
+    private final Comparator<UidStats> mUidStatsComparator = new Comparator<UidStats>() {
+        private int prioritizeExistence(int v1, int v2) {
+            if (v1 > 0 && v2 > 0) {
+                return 0;
+            }
+            return v2 - v1;
+        }
+
+        @Override
+        public int compare(UidStats us1, UidStats us2) {
+            // TODO: build a better prioritization scheme
+            // Some things to use:
+            //   * Proc state
+            //   * IMPORTANT_WHILE_IN_FOREGROUND bit
+            final int runningPriority = prioritizeExistence(us1.numRunning, us2.numRunning);
+            if (runningPriority != 0) {
+                return runningPriority;
+            }
+            // Prioritize any UIDs that have jobs that would be ready ahead of UIDs that don't.
+            final int readyWithConnPriority =
+                    prioritizeExistence(us1.numReadyWithConnectivity, us2.numReadyWithConnectivity);
+            if (readyWithConnPriority != 0) {
+                return readyWithConnPriority;
+            }
+            // They both have jobs that would be ready. Prioritize the UIDs whose requested
+            // network is available ahead of UIDs that don't have their requested network available.
+            final int reqAvailPriority = prioritizeExistence(
+                    us1.numRequestedNetworkAvailable, us2.numRequestedNetworkAvailable);
+            if (reqAvailPriority != 0) {
+                return reqAvailPriority;
+            }
+            // They both have jobs with available networks. Prioritize based on:
+            //   1. (eventually) proc state
+            //   2. Existence of runnable EJs (not just requested)
+            //   3. Enqueue time
+            // TODO: maybe consider number of jobs
+            final int ejPriority = prioritizeExistence(us1.numEJs, us2.numEJs);
+            if (ejPriority != 0) {
+                return ejPriority;
+            }
+            // They both have EJs. Order them by EJ enqueue time to help provide low EJ latency.
+            if (us1.earliestEJEnqueueTime < us2.earliestEJEnqueueTime) {
+                return -1;
+            } else if (us1.earliestEJEnqueueTime > us2.earliestEJEnqueueTime) {
+                return 1;
+            }
+            if (us1.earliestEnqueueTime < us2.earliestEnqueueTime) {
+                return -1;
+            }
+            return us1.earliestEnqueueTime > us2.earliestEnqueueTime ? 1 : 0;
+        }
+    };
+    private final SparseArray<UidStats> mUidStats = new SparseArray<>();
+    private final Pools.Pool<UidDefaultNetworkCallback> mDefaultNetworkCallbackPool =
+            new Pools.SimplePool<>(MAX_NETWORK_CALLBACKS);
+    /**
+     * List of UidStats, sorted by priority as defined in {@link #mUidStatsComparator}. The sorting
+     * is only done in {@link #maybeAdjustRegisteredCallbacksLocked()} and may sometimes be stale.
+     */
+    private final List<UidStats> mSortedStats = new ArrayList<>();
+
     private static final int MSG_REEVALUATE_JOBS = 2;
 
     private final Handler mHandler;
@@ -105,22 +176,26 @@
         mHandler = new CcHandler(mContext.getMainLooper());
 
         mConnManager = mContext.getSystemService(ConnectivityManager.class);
-        mNetPolicyManager = mContext.getSystemService(NetworkPolicyManager.class);
         mNetPolicyManagerInternal = LocalServices.getService(NetworkPolicyManagerInternal.class);
 
         // We're interested in all network changes; internally we match these
         // network changes against the active network for each UID with jobs.
         final NetworkRequest request = new NetworkRequest.Builder().clearCapabilities().build();
         mConnManager.registerNetworkCallback(request, mNetworkCallback);
-
-        mNetPolicyManager.registerListener(mNetPolicyListener);
     }
 
     @GuardedBy("mLock")
     @Override
     public void maybeStartTrackingJobLocked(JobStatus jobStatus, JobStatus lastJob) {
         if (jobStatus.hasConnectivityConstraint()) {
-            updateConstraintsSatisfied(jobStatus);
+            UidStats uidStats = mUidStats.get(jobStatus.getSourceUid());
+            if (uidStats == null) {
+                uidStats = new UidStats(jobStatus.getSourceUid());
+                mUidStats.append(jobStatus.getSourceUid(), uidStats);
+            }
+            if (wouldBeReadyWithConstraintLocked(jobStatus, JobStatus.CONSTRAINT_CONNECTIVITY)) {
+                uidStats.numReadyWithConnectivity++;
+            }
             ArraySet<JobStatus> jobs = mTrackedJobs.get(jobStatus.getSourceUid());
             if (jobs == null) {
                 jobs = new ArraySet<>();
@@ -128,6 +203,16 @@
             }
             jobs.add(jobStatus);
             jobStatus.setTrackingController(JobStatus.TRACKING_CONNECTIVITY);
+            updateConstraintsSatisfied(jobStatus);
+        }
+    }
+
+    @GuardedBy("mLock")
+    @Override
+    public void prepareForExecutionLocked(JobStatus jobStatus) {
+        if (jobStatus.hasConnectivityConstraint()) {
+            UidStats uidStats = mUidStats.get(jobStatus.getSourceUid());
+            uidStats.numRunning++;
         }
     }
 
@@ -140,7 +225,13 @@
             if (jobs != null) {
                 jobs.remove(jobStatus);
             }
+            UidStats us = mUidStats.get(jobStatus.getSourceUid());
+            us.numReadyWithConnectivity--;
+            if (jobStatus.madeActive != 0) {
+                us.numRunning--;
+            }
             maybeRevokeStandbyExceptionLocked(jobStatus);
+            maybeAdjustRegisteredCallbacksLocked();
         }
     }
 
@@ -228,6 +319,8 @@
             return;
         }
 
+        UidStats uidStats = mUidStats.get(jobStatus.getSourceUid());
+
         if (jobStatus.shouldTreatAsExpeditedJob()) {
             if (!jobStatus.isConstraintSatisfied(JobStatus.CONSTRAINT_CONNECTIVITY)) {
                 // Don't request a direct hole through any of the firewalls. Instead, mark the
@@ -251,11 +344,15 @@
             if (DEBUG) {
                 Slog.i(TAG, "evaluateStateLocked finds job " + jobStatus + " would be ready.");
             }
+            uidStats.numReadyWithConnectivity++;
             requestStandbyExceptionLocked(jobStatus);
         } else {
             if (DEBUG) {
                 Slog.i(TAG, "evaluateStateLocked finds job " + jobStatus + " would not be ready.");
             }
+            // Don't decrement numReadyWithConnectivity here because we don't know if it was
+            // incremented for this job. The count will be set properly in
+            // maybeAdjustRegisteredCallbacksLocked().
             maybeRevokeStandbyExceptionLocked(jobStatus);
         }
     }
@@ -315,6 +412,30 @@
     @Override
     public void onAppRemovedLocked(String pkgName, int uid) {
         mTrackedJobs.delete(uid);
+        UidStats uidStats = mUidStats.removeReturnOld(uid);
+        unregisterDefaultNetworkCallbackLocked(uid, sElapsedRealtimeClock.millis());
+        mSortedStats.remove(uidStats);
+        registerPendingUidCallbacksLocked();
+    }
+
+    @GuardedBy("mLock")
+    @Override
+    public void onUserRemovedLocked(int userId) {
+        final long nowElapsed = sElapsedRealtimeClock.millis();
+        for (int u = mUidStats.size() - 1; u >= 0; --u) {
+            UidStats uidStats = mUidStats.valueAt(u);
+            if (UserHandle.getUserId(uidStats.uid) == userId) {
+                unregisterDefaultNetworkCallbackLocked(uidStats.uid, nowElapsed);
+                mSortedStats.remove(uidStats);
+                mUidStats.removeAt(u);
+            }
+        }
+        maybeAdjustRegisteredCallbacksLocked();
+    }
+
+    private boolean isUsable(NetworkCapabilities capabilities) {
+        return capabilities != null
+                && capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED);
     }
 
     /**
@@ -380,15 +501,23 @@
         }
     }
 
+    private static NetworkCapabilities.Builder copyCapabilities(
+            @NonNull final NetworkRequest request) {
+        final NetworkCapabilities.Builder builder = new NetworkCapabilities.Builder();
+        for (int transport : request.getTransportTypes()) builder.addTransportType(transport);
+        for (int capability : request.getCapabilities()) builder.addCapability(capability);
+        return builder;
+    }
+
     private static boolean isStrictSatisfied(JobStatus jobStatus, Network network,
             NetworkCapabilities capabilities, Constants constants) {
         // A restricted job that's out of quota MUST use an unmetered network.
         if (jobStatus.getEffectiveStandbyBucket() == RESTRICTED_INDEX
                 && !jobStatus.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_QUOTA)) {
-            final NetworkCapabilities required = new NetworkCapabilities.Builder(
-                    jobStatus.getJob().getRequiredNetwork().networkCapabilities)
-                    .addCapability(NET_CAPABILITY_NOT_METERED).build();
-            return required.satisfiedByNetworkCapabilities(capabilities);
+            final NetworkCapabilities.Builder builder =
+                    copyCapabilities(jobStatus.getJob().getRequiredNetwork());
+            builder.addCapability(NET_CAPABILITY_NOT_METERED);
+            return builder.build().satisfiedByNetworkCapabilities(capabilities);
         } else {
             return jobStatus.getJob().getRequiredNetwork().canBeSatisfiedBy(capabilities);
         }
@@ -402,10 +531,10 @@
         }
 
         // See if we match after relaxing any unmetered request
-        final NetworkCapabilities relaxed = new NetworkCapabilities.Builder(
-                jobStatus.getJob().getRequiredNetwork().networkCapabilities)
-                        .removeCapability(NET_CAPABILITY_NOT_METERED).build();
-        if (relaxed.satisfiedByNetworkCapabilities(capabilities)) {
+        final NetworkCapabilities.Builder builder =
+                copyCapabilities(jobStatus.getJob().getRequiredNetwork());
+        builder.removeCapability(NET_CAPABILITY_NOT_METERED);
+        if (builder.build().satisfiedByNetworkCapabilities(capabilities)) {
             // TODO: treat this as "maybe" response; need to check quotas
             return jobStatus.getFractionRunTime() > constants.CONN_PREFETCH_RELAX_FRAC;
         } else {
@@ -419,6 +548,8 @@
         // Zeroth, we gotta have a network to think about being satisfied
         if (network == null || capabilities == null) return false;
 
+        if (!isUsable(capabilities)) return false;
+
         // First, are we insane?
         if (isInsane(jobStatus, network, capabilities, constants)) return false;
 
@@ -434,6 +565,156 @@
         return false;
     }
 
+    @GuardedBy("mLock")
+    private void maybeRegisterDefaultNetworkCallbackLocked(JobStatus jobStatus) {
+        final int sourceUid = jobStatus.getSourceUid();
+        if (mCurrentDefaultNetworkCallbacks.contains(sourceUid)) {
+            return;
+        }
+        UidStats uidStats = mUidStats.get(sourceUid);
+        if (!mSortedStats.contains(uidStats)) {
+            mSortedStats.add(uidStats);
+        }
+        if (mCurrentDefaultNetworkCallbacks.size() >= MAX_NETWORK_CALLBACKS) {
+            // TODO: offload to handler
+            maybeAdjustRegisteredCallbacksLocked();
+            return;
+        }
+        registerPendingUidCallbacksLocked();
+    }
+
+    /**
+     * Register UID callbacks for UIDs that are next in line, based on the current order in {@link
+     * #mSortedStats}. This assumes that there are only registered callbacks for UIDs in the top
+     * {@value #MAX_NETWORK_CALLBACKS} UIDs and that the only UIDs missing callbacks are the lower
+     * priority ones.
+     */
+    @GuardedBy("mLock")
+    private void registerPendingUidCallbacksLocked() {
+        final int numCallbacks = mCurrentDefaultNetworkCallbacks.size();
+        final int numPending = mSortedStats.size();
+        if (numPending < numCallbacks) {
+            // This means there's a bug in the code >.<
+            Slog.wtf(TAG, "There are more registered callbacks than sorted UIDs: "
+                    + numCallbacks + " vs " + numPending);
+        }
+        for (int i = numCallbacks; i < numPending && i < MAX_NETWORK_CALLBACKS; ++i) {
+            UidStats uidStats = mSortedStats.get(i);
+            UidDefaultNetworkCallback callback = mDefaultNetworkCallbackPool.acquire();
+            if (callback == null) {
+                callback = new UidDefaultNetworkCallback();
+            }
+            callback.setUid(uidStats.uid);
+            mCurrentDefaultNetworkCallbacks.append(uidStats.uid, callback);
+            mConnManager.registerDefaultNetworkCallbackAsUid(uidStats.uid, callback, mHandler);
+        }
+    }
+
+    @GuardedBy("mLock")
+    private void maybeAdjustRegisteredCallbacksLocked() {
+        final int count = mUidStats.size();
+        if (count == mCurrentDefaultNetworkCallbacks.size()) {
+            // All of them are registered and there are no blocked UIDs.
+            // No point evaluating all UIDs.
+            return;
+        }
+        final long nowElapsed = sElapsedRealtimeClock.millis();
+        mSortedStats.clear();
+
+        for (int u = 0; u < mUidStats.size(); ++u) {
+            UidStats us = mUidStats.valueAt(u);
+            ArraySet<JobStatus> jobs = mTrackedJobs.get(us.uid);
+            if (jobs == null || jobs.size() == 0) {
+                unregisterDefaultNetworkCallbackLocked(us.uid, nowElapsed);
+                continue;
+            }
+
+            // We won't evaluate stats in the first 30 seconds after boot...That's probably okay.
+            if (us.lastUpdatedElapsed + MIN_STATS_UPDATE_INTERVAL_MS < nowElapsed) {
+                us.earliestEnqueueTime = Long.MAX_VALUE;
+                us.earliestEJEnqueueTime = Long.MAX_VALUE;
+                us.numReadyWithConnectivity = 0;
+                us.numRequestedNetworkAvailable = 0;
+                us.numRegular = 0;
+                us.numEJs = 0;
+
+                for (int j = 0; j < jobs.size(); ++j) {
+                    JobStatus job = jobs.valueAt(j);
+                    us.earliestEnqueueTime = Math.min(us.earliestEnqueueTime, job.enqueueTime);
+                    if (wouldBeReadyWithConstraintLocked(job, JobStatus.CONSTRAINT_CONNECTIVITY)) {
+                        us.numReadyWithConnectivity++;
+                        if (isNetworkAvailable(job)) {
+                            us.numRequestedNetworkAvailable++;
+                        }
+                    }
+                    if (job.shouldTreatAsExpeditedJob() || job.startedAsExpeditedJob) {
+                        us.numEJs++;
+                        us.earliestEJEnqueueTime =
+                                Math.min(us.earliestEJEnqueueTime, job.enqueueTime);
+                    } else {
+                        us.numRegular++;
+                    }
+                }
+
+                us.lastUpdatedElapsed = nowElapsed;
+            }
+            mSortedStats.add(us);
+        }
+
+        mSortedStats.sort(mUidStatsComparator);
+
+        boolean changed = false;
+        // Iterate in reverse order to remove existing callbacks before adding new ones.
+        for (int i = mSortedStats.size() - 1; i >= 0; --i) {
+            UidStats us = mSortedStats.get(i);
+            if (i >= MAX_NETWORK_CALLBACKS) {
+                changed |= unregisterDefaultNetworkCallbackLocked(us.uid, nowElapsed);
+            } else {
+                UidDefaultNetworkCallback defaultNetworkCallback =
+                        mCurrentDefaultNetworkCallbacks.get(us.uid);
+                if (defaultNetworkCallback == null) {
+                    // Not already registered.
+                    defaultNetworkCallback = mDefaultNetworkCallbackPool.acquire();
+                    if (defaultNetworkCallback == null) {
+                        defaultNetworkCallback = new UidDefaultNetworkCallback();
+                    }
+                    defaultNetworkCallback.setUid(us.uid);
+                    mCurrentDefaultNetworkCallbacks.append(us.uid, defaultNetworkCallback);
+                    mConnManager.registerDefaultNetworkCallbackAsUid(
+                            us.uid, defaultNetworkCallback, mHandler);
+                }
+            }
+        }
+        if (changed) {
+            mStateChangedListener.onControllerStateChanged();
+        }
+    }
+
+    @GuardedBy("mLock")
+    private boolean unregisterDefaultNetworkCallbackLocked(int uid, long nowElapsed) {
+        UidDefaultNetworkCallback defaultNetworkCallback = mCurrentDefaultNetworkCallbacks.get(uid);
+        if (defaultNetworkCallback == null) {
+            return false;
+        }
+        mCurrentDefaultNetworkCallbacks.remove(uid);
+        mConnManager.unregisterNetworkCallback(defaultNetworkCallback);
+        mDefaultNetworkCallbackPool.release(defaultNetworkCallback);
+        defaultNetworkCallback.clear();
+
+        boolean changed = false;
+        final ArraySet<JobStatus> jobs = mTrackedJobs.get(uid);
+        if (jobs != null) {
+            // Since we're unregistering the callback, we can no longer monitor
+            // changes to the app's network and so we should just mark the
+            // connectivity constraint as not satisfied.
+            for (int j = jobs.size() - 1; j >= 0; --j) {
+                changed |= updateConstraintsSatisfied(
+                        jobs.valueAt(j), nowElapsed, null, null);
+            }
+        }
+        return changed;
+    }
+
     @Nullable
     private NetworkCapabilities getNetworkCapabilities(@Nullable Network network) {
         if (network == null) {
@@ -442,43 +723,34 @@
         synchronized (mLock) {
             // There is technically a race here if the Network object is reused. This can happen
             // only if that Network disconnects and the auto-incrementing network ID in
-            // ConnectivityService wraps. This should no longer be a concern if/when we only make
+            // ConnectivityService wraps. This shouldn't be a concern since we only make
             // use of asynchronous calls.
-            if (mAvailableNetworks.get(network) != null) {
-                return mAvailableNetworks.get(network);
-            }
-
-            // This should almost never happen because any time a new network connects, the
-            // NetworkCallback would populate mAvailableNetworks. However, it's currently necessary
-            // because we also call synchronous methods such as getActiveNetworkForUid.
-            // TODO(134978280): remove after switching to callback-based APIs
-            final NetworkCapabilities capabilities = mConnManager.getNetworkCapabilities(network);
-            mAvailableNetworks.put(network, capabilities);
-            return capabilities;
+            return mAvailableNetworks.get(network);
         }
     }
 
     private boolean updateConstraintsSatisfied(JobStatus jobStatus) {
-        final Network network = mConnManager.getActiveNetworkForUid(
-                jobStatus.getSourceUid(), jobStatus.shouldIgnoreNetworkBlocking());
+        final long nowElapsed = sElapsedRealtimeClock.millis();
+        final UidDefaultNetworkCallback defaultNetworkCallback =
+                mCurrentDefaultNetworkCallbacks.get(jobStatus.getSourceUid());
+        if (defaultNetworkCallback == null) {
+            maybeRegisterDefaultNetworkCallbackLocked(jobStatus);
+            return updateConstraintsSatisfied(jobStatus, nowElapsed, null, null);
+        }
+        final Network network =
+                (jobStatus.shouldIgnoreNetworkBlocking() || !defaultNetworkCallback.mBlocked)
+                        ? defaultNetworkCallback.mDefaultNetwork : null;
         final NetworkCapabilities capabilities = getNetworkCapabilities(network);
-        return updateConstraintsSatisfied(jobStatus, sElapsedRealtimeClock.millis(),
-                network, capabilities);
+        return updateConstraintsSatisfied(jobStatus, nowElapsed, network, capabilities);
     }
 
     private boolean updateConstraintsSatisfied(JobStatus jobStatus, final long nowElapsed,
             Network network, NetworkCapabilities capabilities) {
-        // TODO: consider matching against non-active networks
+        // TODO: consider matching against non-default networks
 
-        final boolean ignoreBlocked = jobStatus.shouldIgnoreNetworkBlocking();
-        final NetworkInfo info = mConnManager.getNetworkInfoForUid(network,
-                jobStatus.getSourceUid(), ignoreBlocked);
-
-        final boolean connected = (info != null) && info.isConnected();
         final boolean satisfied = isSatisfied(jobStatus, network, capabilities, mConstants);
 
-        final boolean changed = jobStatus
-                .setConnectivityConstraintSatisfied(nowElapsed, connected && satisfied);
+        final boolean changed = jobStatus.setConnectivityConstraintSatisfied(nowElapsed, satisfied);
 
         // Pass along the evaluated network for job to use; prevents race
         // conditions as default routes change over time, and opens the door to
@@ -487,7 +759,7 @@
 
         if (DEBUG) {
             Slog.i(TAG, "Connectivity " + (changed ? "CHANGED" : "unchanged")
-                    + " for " + jobStatus + ": connected=" + connected
+                    + " for " + jobStatus + ": usable=" + isUsable(capabilities)
                     + " satisfied=" + satisfied);
         }
         return changed;
@@ -522,15 +794,24 @@
             return false;
         }
 
-        final Network network =
-                mConnManager.getActiveNetworkForUid(jobs.valueAt(0).getSourceUid(), false);
+        UidDefaultNetworkCallback defaultNetworkCallback =
+                mCurrentDefaultNetworkCallbacks.get(jobs.valueAt(0).getSourceUid());
+        if (defaultNetworkCallback == null) {
+            maybeRegisterDefaultNetworkCallbackLocked(jobs.valueAt(0));
+            return false;
+        }
+
+        final Network network = defaultNetworkCallback.mBlocked
+                ? null : defaultNetworkCallback.mDefaultNetwork;
         final NetworkCapabilities capabilities = getNetworkCapabilities(network);
         final boolean networkMatch = (filterNetwork == null
                 || Objects.equals(filterNetwork, network));
-        boolean exemptedLoaded = false;
-        Network exemptedNetwork = null;
-        NetworkCapabilities exemptedNetworkCapabilities = null;
-        boolean exemptedNetworkMatch = false;
+        // Ignore blocked
+        final Network exemptedNetwork = defaultNetworkCallback.mDefaultNetwork;
+        final NetworkCapabilities exemptedNetworkCapabilities =
+                getNetworkCapabilities(exemptedNetwork);
+        final boolean exemptedNetworkMatch =
+                (filterNetwork == null || Objects.equals(filterNetwork, exemptedNetwork));
 
         final long nowElapsed = sElapsedRealtimeClock.millis();
         boolean changed = false;
@@ -542,13 +823,6 @@
             boolean match = networkMatch;
 
             if (js.shouldIgnoreNetworkBlocking()) {
-                if (!exemptedLoaded) {
-                    exemptedLoaded = true;
-                    exemptedNetwork = mConnManager.getActiveNetworkForUid(js.getSourceUid(), true);
-                    exemptedNetworkCapabilities = getNetworkCapabilities(exemptedNetwork);
-                    exemptedNetworkMatch = (filterNetwork == null
-                            || Objects.equals(filterNetwork, exemptedNetwork));
-                }
                 net = exemptedNetwork;
                 netCap = exemptedNetworkCapabilities;
                 match = exemptedNetworkMatch;
@@ -603,6 +877,7 @@
                 mAvailableNetworks.put(network, capabilities);
             }
             updateTrackedJobs(-1, network);
+            maybeAdjustRegisteredCallbacksLocked();
         }
 
         @Override
@@ -612,26 +887,15 @@
             }
             synchronized (mLock) {
                 mAvailableNetworks.remove(network);
+                for (int u = 0; u < mCurrentDefaultNetworkCallbacks.size(); ++u) {
+                    UidDefaultNetworkCallback callback = mCurrentDefaultNetworkCallbacks.valueAt(u);
+                    if (Objects.equals(callback.mDefaultNetwork, network)) {
+                        callback.mDefaultNetwork = null;
+                    }
+                }
             }
             updateTrackedJobs(-1, network);
-        }
-    };
-
-    private final INetworkPolicyListener mNetPolicyListener = new NetworkPolicyManager.Listener() {
-        @Override
-        public void onRestrictBackgroundChanged(boolean restrictBackground) {
-            if (DEBUG) {
-                Slog.v(TAG, "onRestrictBackgroundChanged: " + restrictBackground);
-            }
-            mHandler.obtainMessage(MSG_DATA_SAVER_TOGGLED).sendToTarget();
-        }
-
-        @Override
-        public void onUidRulesChanged(int uid, int uidRules) {
-            if (DEBUG) {
-                Slog.v(TAG, "onUidRulesChanged: " + uid);
-            }
-            mHandler.obtainMessage(MSG_UID_RULES_CHANGES, uid, 0).sendToTarget();
+            maybeAdjustRegisteredCallbacksLocked();
         }
     };
 
@@ -644,24 +908,148 @@
         public void handleMessage(Message msg) {
             synchronized (mLock) {
                 switch (msg.what) {
-                    case MSG_DATA_SAVER_TOGGLED:
-                        updateTrackedJobs(-1, null);
-                        break;
-                    case MSG_UID_RULES_CHANGES:
-                        updateTrackedJobs(msg.arg1, null);
-                        break;
                     case MSG_REEVALUATE_JOBS:
                         updateTrackedJobs(-1, null);
                         break;
                 }
             }
         }
-    };
+    }
+
+    private class UidDefaultNetworkCallback extends NetworkCallback {
+        private int mUid;
+        @Nullable
+        private Network mDefaultNetwork;
+        private boolean mBlocked;
+
+        private void setUid(int uid) {
+            mUid = uid;
+            mDefaultNetwork = null;
+        }
+
+        private void clear() {
+            mDefaultNetwork = null;
+            mUid = UserHandle.USER_NULL;
+        }
+
+        @Override
+        public void onAvailable(Network network) {
+            if (DEBUG) Slog.v(TAG, "default-onAvailable(" + mUid + "): " + network);
+        }
+
+        @Override
+        public void onBlockedStatusChanged(Network network, boolean blocked) {
+            if (DEBUG) {
+                Slog.v(TAG, "default-onBlockedStatusChanged(" + mUid + "): "
+                        + network + " -> " + blocked);
+            }
+            if (mUid == UserHandle.USER_NULL) {
+                return;
+            }
+            synchronized (mLock) {
+                mDefaultNetwork = network;
+                mBlocked = blocked;
+            }
+            updateTrackedJobs(mUid, network);
+        }
+
+        // Network transitions have some complicated behavior that JS doesn't handle very well.
+        //
+        // * If the default network changes from A to B without A disconnecting, then we'll only
+        // get onAvailable(B) (and the subsequent onBlockedStatusChanged() call). Since we get
+        // the onBlockedStatusChanged() call, we re-evaluate the job, but keep it running
+        // (assuming the new network satisfies constraints). The app continues to use the old
+        // network (if they use the network object provided through JobParameters.getNetwork())
+        // because we don't notify them of the default network change. If the old network no
+        // longer satisfies requested constraints, then we have a problem. Depending on the order
+        // of calls, if the per-UID callback gets notified of the network change before the
+        // general callback gets notified of the capabilities change, then the job's network
+        // object will point to the new network and we won't stop the job, even though we told it
+        // to use the old network that no longer satisfies its constraints. This is the behavior
+        // we loosely had (ignoring race conditions between asynchronous and synchronous
+        // connectivity calls) when we were calling the synchronous getActiveNetworkForUid() API.
+        // However, we should fix it.
+        // TODO: stop jobs when the existing capabilities change after default network change
+        //
+        // * If the default network changes from A to B because A disconnected, then we'll get
+        // onLost(A) and then onAvailable(B). In this case, there will be a short period where JS
+        // doesn't think there's an available network for the job, so we'll stop the job even
+        // though onAvailable(B) will be called soon. One on hand, the app would have gotten a
+        // network error as well because of A's disconnect, and this will allow JS to provide the
+        // job with the new default network. On the other hand, we have to stop the job even
+        // though it could have continued running with the new network and the job has to deal
+        // with whatever backoff policy is set. For now, the current behavior is fine, but we may
+        // want to see if there's a way to have a smoother transition.
+
+        @Override
+        public void onLost(Network network) {
+            if (DEBUG) {
+                Slog.v(TAG, "default-onLost(" + mUid + "): " + network);
+            }
+            if (mUid == UserHandle.USER_NULL) {
+                return;
+            }
+            synchronized (mLock) {
+                if (Objects.equals(mDefaultNetwork, network)) {
+                    mDefaultNetwork = null;
+                }
+            }
+            updateTrackedJobs(mUid, network);
+        }
+
+        private void dumpLocked(IndentingPrintWriter pw) {
+            pw.print("UID: ");
+            pw.print(mUid);
+            pw.print("; ");
+            if (mDefaultNetwork == null) {
+                pw.print("No network");
+            } else {
+                pw.print("Network: ");
+                pw.print(mDefaultNetwork);
+                pw.print(" (blocked=");
+                pw.print(mBlocked);
+                pw.print(")");
+            }
+            pw.println();
+        }
+    }
+
+    private static class UidStats {
+        public final int uid;
+        public int numRunning;
+        public int numReadyWithConnectivity;
+        public int numRequestedNetworkAvailable;
+        public int numEJs;
+        public int numRegular;
+        public long earliestEnqueueTime;
+        public long earliestEJEnqueueTime;
+        public long lastUpdatedElapsed;
+
+        private UidStats(int uid) {
+            this.uid = uid;
+        }
+
+        private void dumpLocked(IndentingPrintWriter pw, final long nowElapsed) {
+            pw.print("UidStats{");
+            pw.print("uid", uid);
+            pw.print("#run", numRunning);
+            pw.print("#readyWithConn", numReadyWithConnectivity);
+            pw.print("#netAvail", numRequestedNetworkAvailable);
+            pw.print("#EJs", numEJs);
+            pw.print("#reg", numRegular);
+            pw.print("earliestEnqueue", earliestEnqueueTime);
+            pw.print("earliestEJEnqueue", earliestEJEnqueueTime);
+            pw.print("updated=");
+            TimeUtils.formatDuration(lastUpdatedElapsed - nowElapsed, pw);
+            pw.println("}");
+        }
+    }
 
     @GuardedBy("mLock")
     @Override
     public void dumpControllerStateLocked(IndentingPrintWriter pw,
             Predicate<JobStatus> predicate) {
+        final long nowElapsed = sElapsedRealtimeClock.millis();
 
         if (mRequestedWhitelistJobs.size() > 0) {
             pw.print("Requested standby exceptions:");
@@ -686,6 +1074,26 @@
         } else {
             pw.println("No available networks");
         }
+        pw.println();
+
+        pw.println("Current default network callbacks:");
+        pw.increaseIndent();
+        for (int i = 0; i < mCurrentDefaultNetworkCallbacks.size(); i++) {
+            mCurrentDefaultNetworkCallbacks.valueAt(i).dumpLocked(pw);
+        }
+        pw.decreaseIndent();
+        pw.println();
+
+        pw.println("UID Pecking Order:");
+        pw.increaseIndent();
+        for (int i = 0; i < mSortedStats.size(); ++i) {
+            pw.print(i);
+            pw.print(": ");
+            mSortedStats.get(i).dumpLocked(pw, nowElapsed);
+        }
+        pw.decreaseIndent();
+        pw.println();
+
         for (int i = 0; i < mTrackedJobs.size(); i++) {
             final ArraySet<JobStatus> jobs = mTrackedJobs.valueAt(i);
             for (int j = 0; j < jobs.size(); j++) {
@@ -716,13 +1124,6 @@
                     StateControllerProto.ConnectivityController.REQUESTED_STANDBY_EXCEPTION_UIDS,
                     mRequestedWhitelistJobs.keyAt(i));
         }
-        for (int i = 0; i < mAvailableNetworks.size(); i++) {
-            Network network = mAvailableNetworks.keyAt(i);
-            if (network != null) {
-                network.dumpDebug(proto,
-                        StateControllerProto.ConnectivityController.AVAILABLE_NETWORKS);
-            }
-        }
         for (int i = 0; i < mTrackedJobs.size(); i++) {
             final ArraySet<JobStatus> jobs = mTrackedJobs.valueAt(i);
             for (int j = 0; j < jobs.size(); j++) {
@@ -736,12 +1137,6 @@
                         StateControllerProto.ConnectivityController.TrackedJob.INFO);
                 proto.write(StateControllerProto.ConnectivityController.TrackedJob.SOURCE_UID,
                         js.getSourceUid());
-                NetworkRequest rn = js.getJob().getRequiredNetwork();
-                if (rn != null) {
-                    rn.dumpDebug(proto,
-                            StateControllerProto.ConnectivityController.TrackedJob
-                                    .REQUIRED_NETWORK);
-                }
                 proto.end(jsToken);
             }
         }
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
index bad8dc1..80e68e9 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
@@ -24,11 +24,13 @@
 
 import android.app.AppGlobals;
 import android.app.job.JobInfo;
+import android.app.job.JobParameters;
 import android.app.job.JobWorkItem;
 import android.content.ClipData;
 import android.content.ComponentName;
 import android.content.pm.ServiceInfo;
 import android.net.Network;
+import android.net.NetworkRequest;
 import android.net.Uri;
 import android.os.RemoteException;
 import android.os.UserHandle;
@@ -37,6 +39,7 @@
 import android.util.ArraySet;
 import android.util.IndentingPrintWriter;
 import android.util.Pair;
+import android.util.Range;
 import android.util.Slog;
 import android.util.TimeUtils;
 import android.util.proto.ProtoOutputStream;
@@ -54,6 +57,7 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.function.Predicate;
 
 /**
@@ -138,13 +142,14 @@
      * (Atom #21)
      * * CONSTRAINT_BACKGROUND_NOT_RESTRICTED can be inferred with BatterySaverModeStateChanged
      * (Atom #20)
+     * * CONSTRAINT_STORAGE_NOT_LOW can be inferred with LowStorageStateChanged (Atom #130)
      */
     private static final int STATSD_CONSTRAINTS_TO_LOG = CONSTRAINT_CONTENT_TRIGGER
             | CONSTRAINT_DEADLINE
             | CONSTRAINT_IDLE
-            | CONSTRAINT_STORAGE_NOT_LOW
             | CONSTRAINT_TIMING_DELAY
-            | CONSTRAINT_WITHIN_QUOTA;
+            | CONSTRAINT_WITHIN_QUOTA
+            | CONSTRAINT_WITHIN_EXPEDITED_QUOTA;
 
     // TODO(b/129954980)
     private static final boolean STATS_LOG_ENABLED = false;
@@ -324,6 +329,12 @@
     /** The evaluated priority of the job when it started running. */
     public int lastEvaluatedPriority;
 
+    /**
+     * Whether or not this particular JobStatus instance was treated as an EJ when it started
+     * running. This isn't copied over when a job is rescheduled.
+     */
+    public boolean startedAsExpeditedJob = false;
+
     // If non-null, this is work that has been enqueued for the job.
     public ArrayList<JobWorkItem> pendingWork;
 
@@ -353,6 +364,9 @@
      */
     private long mLastFailedRunTime;
 
+    /** Whether or not the app is background restricted by the user (FAS). */
+    private boolean mIsUserBgRestricted;
+
     /**
      * Transient: when a job is inflated from disk before we have a reliable RTC clock time,
      * we retain the canonical (delay, deadline) scheduling tuple read out of the persistent
@@ -409,6 +423,9 @@
     /** The job's dynamic requirements have been satisfied. */
     private boolean mReadyDynamicSatisfied;
 
+    /** The reason a job most recently went from ready to not ready. */
+    private int mReasonReadyToUnready = JobParameters.STOP_REASON_UNDEFINED;
+
     /** Provide a handle to the service that this job will be run on. */
     public int getServiceToken() {
         return callingUid;
@@ -520,8 +537,15 @@
             // Later, when we check if a given network satisfies the required
             // network, we need to know the UID that is requesting it, so push
             // our source UID into place.
-            job.getRequiredNetwork().networkCapabilities.setSingleUid(this.sourceUid);
+            final JobInfo.Builder builder = new JobInfo.Builder(job);
+            final NetworkRequest.Builder requestBuilder =
+                    new NetworkRequest.Builder(job.getRequiredNetwork());
+            requestBuilder.setUids(
+                    Collections.singleton(new Range<Integer>(this.sourceUid, this.sourceUid)));
+            builder.setRequiredNetwork(requestBuilder.build());
+            job = builder.build();
         }
+
         final JobSchedulerInternal jsi = LocalServices.getService(JobSchedulerInternal.class);
         mHasMediaBackupExemption = !job.hasLateConstraint() && exemptedMediaUrisOnly
                 && requiresNetwork && this.sourcePackageName.equals(jsi.getMediaBackupPackage());
@@ -1042,6 +1066,11 @@
         mOriginalLatestRunTimeElapsedMillis = latestRunTimeElapsed;
     }
 
+    @JobParameters.StopReason
+    public int getStopReason() {
+        return mReasonReadyToUnready;
+    }
+
     /**
      * Return the fractional position of "now" within the "run time" window of
      * this job.
@@ -1100,18 +1129,19 @@
      */
     public boolean canRunInDoze() {
         return (getFlags() & JobInfo.FLAG_WILL_BE_FOREGROUND) != 0
-                || (shouldTreatAsExpeditedJob()
+                || ((shouldTreatAsExpeditedJob() || startedAsExpeditedJob)
                 && (mDynamicConstraints & CONSTRAINT_DEVICE_NOT_DOZING) == 0);
     }
 
     boolean canRunInBatterySaver() {
         return (getInternalFlags() & INTERNAL_FLAG_HAS_FOREGROUND_EXEMPTION) != 0
-                || (shouldTreatAsExpeditedJob()
+                || ((shouldTreatAsExpeditedJob() || startedAsExpeditedJob)
                 && (mDynamicConstraints & CONSTRAINT_BACKGROUND_NOT_RESTRICTED) == 0);
     }
 
     boolean shouldIgnoreNetworkBlocking() {
-        return (getFlags() & JobInfo.FLAG_WILL_BE_FOREGROUND) != 0 || shouldTreatAsExpeditedJob();
+        return (getFlags() & JobInfo.FLAG_WILL_BE_FOREGROUND) != 0
+                || (shouldTreatAsExpeditedJob() || startedAsExpeditedJob);
     }
 
     /** @return true if the constraint was changed, false otherwise. */
@@ -1172,7 +1202,9 @@
     }
 
     /** @return true if the constraint was changed, false otherwise. */
-    boolean setBackgroundNotRestrictedConstraintSatisfied(final long nowElapsed, boolean state) {
+    boolean setBackgroundNotRestrictedConstraintSatisfied(final long nowElapsed, boolean state,
+            boolean isUserBgRestricted) {
+        mIsUserBgRestricted = isUserBgRestricted;
         if (setConstraintSatisfied(CONSTRAINT_BACKGROUND_NOT_RESTRICTED, nowElapsed, state)) {
             // The constraint was changed. Update the ready flag.
             mReadyNotRestrictedInBg = state;
@@ -1226,6 +1258,7 @@
                     "Constraint " + constraint + " is " + (!state ? "NOT " : "") + "satisfied for "
                             + toShortString());
         }
+        final boolean wasReady = !state && isReady();
         satisfiedConstraints = (satisfiedConstraints&~constraint) | (state ? constraint : 0);
         mSatisfiedConstraintsOfInterest = satisfiedConstraints & CONSTRAINTS_OF_INTEREST;
         mReadyDynamicSatisfied = mDynamicConstraints != 0
@@ -1244,9 +1277,81 @@
         mConstraintChangeHistoryIndex =
                 (mConstraintChangeHistoryIndex + 1) % NUM_CONSTRAINT_CHANGE_HISTORY;
 
+        // Can't use isReady() directly since "cache booleans" haven't updated yet.
+        final boolean isReady = readinessStatusWithConstraint(constraint, state);
+        if (wasReady && !isReady) {
+            mReasonReadyToUnready = constraintToStopReason(constraint);
+        } else if (!wasReady && isReady) {
+            mReasonReadyToUnready = JobParameters.STOP_REASON_UNDEFINED;
+        }
+
         return true;
     }
 
+    @JobParameters.StopReason
+    private int constraintToStopReason(int constraint) {
+        switch (constraint) {
+            case CONSTRAINT_BATTERY_NOT_LOW:
+                if ((requiredConstraints & constraint) != 0) {
+                    // The developer requested this constraint, so it makes sense to return the
+                    // explicit constraint reason.
+                    return JobParameters.STOP_REASON_CONSTRAINT_BATTERY_NOT_LOW;
+                }
+                // Hard-coding right now since the current dynamic constraint sets don't overlap
+                // TODO: return based on active dynamic constraint sets when they start overlapping
+                return JobParameters.STOP_REASON_APP_STANDBY;
+            case CONSTRAINT_CHARGING:
+                if ((requiredConstraints & constraint) != 0) {
+                    // The developer requested this constraint, so it makes sense to return the
+                    // explicit constraint reason.
+                    return JobParameters.STOP_REASON_CONSTRAINT_CHARGING;
+                }
+                // Hard-coding right now since the current dynamic constraint sets don't overlap
+                // TODO: return based on active dynamic constraint sets when they start overlapping
+                return JobParameters.STOP_REASON_APP_STANDBY;
+            case CONSTRAINT_CONNECTIVITY:
+                return JobParameters.STOP_REASON_CONSTRAINT_CONNECTIVITY;
+            case CONSTRAINT_IDLE:
+                if ((requiredConstraints & constraint) != 0) {
+                    // The developer requested this constraint, so it makes sense to return the
+                    // explicit constraint reason.
+                    return JobParameters.STOP_REASON_CONSTRAINT_DEVICE_IDLE;
+                }
+                // Hard-coding right now since the current dynamic constraint sets don't overlap
+                // TODO: return based on active dynamic constraint sets when they start overlapping
+                return JobParameters.STOP_REASON_APP_STANDBY;
+            case CONSTRAINT_STORAGE_NOT_LOW:
+                return JobParameters.STOP_REASON_CONSTRAINT_STORAGE_NOT_LOW;
+
+            case CONSTRAINT_BACKGROUND_NOT_RESTRICTED:
+                // The BACKGROUND_NOT_RESTRICTED constraint could be dissatisfied either because
+                // the app is background restricted, or because we're restricting background work
+                // in battery saver. Assume that background restriction is the reason apps that
+                // are background restricted have their jobs stopped, and battery saver otherwise.
+                // This has the benefit of being consistent for background restricted apps
+                // (they'll always get BACKGROUND_RESTRICTION) as the reason, regardless of
+                // battery saver state.
+                if (mIsUserBgRestricted) {
+                    return JobParameters.STOP_REASON_BACKGROUND_RESTRICTION;
+                }
+                return JobParameters.STOP_REASON_DEVICE_STATE;
+            case CONSTRAINT_DEVICE_NOT_DOZING:
+                return JobParameters.STOP_REASON_DEVICE_STATE;
+
+            case CONSTRAINT_WITHIN_QUOTA:
+            case CONSTRAINT_WITHIN_EXPEDITED_QUOTA:
+                return JobParameters.STOP_REASON_QUOTA;
+
+            // These should never be stop reasons since they can never go from true to false.
+            case CONSTRAINT_CONTENT_TRIGGER:
+            case CONSTRAINT_DEADLINE:
+            case CONSTRAINT_TIMING_DELAY:
+            default:
+                Slog.wtf(TAG, "Unsupported constraint (" + constraint + ") --stop reason mapping");
+                return JobParameters.STOP_REASON_UNDEFINED;
+        }
+    }
+
     boolean isConstraintSatisfied(int constraint) {
         return (satisfiedConstraints&constraint) != 0;
     }
@@ -1330,33 +1435,42 @@
      * granted, based on its requirements.
      */
     boolean wouldBeReadyWithConstraint(int constraint) {
+        return readinessStatusWithConstraint(constraint, true);
+    }
+
+    private boolean readinessStatusWithConstraint(int constraint, boolean value) {
         boolean oldValue = false;
         int satisfied = mSatisfiedConstraintsOfInterest;
         switch (constraint) {
             case CONSTRAINT_BACKGROUND_NOT_RESTRICTED:
                 oldValue = mReadyNotRestrictedInBg;
-                mReadyNotRestrictedInBg = true;
+                mReadyNotRestrictedInBg = value;
                 break;
             case CONSTRAINT_DEADLINE:
                 oldValue = mReadyDeadlineSatisfied;
-                mReadyDeadlineSatisfied = true;
+                mReadyDeadlineSatisfied = value;
                 break;
             case CONSTRAINT_DEVICE_NOT_DOZING:
                 oldValue = mReadyNotDozing;
-                mReadyNotDozing = true;
+                mReadyNotDozing = value;
                 break;
             case CONSTRAINT_WITHIN_QUOTA:
                 oldValue = mReadyWithinQuota;
-                mReadyWithinQuota = true;
+                mReadyWithinQuota = value;
                 break;
             case CONSTRAINT_WITHIN_EXPEDITED_QUOTA:
                 oldValue = mReadyWithinExpeditedQuota;
-                mReadyWithinExpeditedQuota = true;
+                mReadyWithinExpeditedQuota = value;
                 break;
             default:
-                satisfied |= constraint;
+                if (value) {
+                    satisfied |= constraint;
+                } else {
+                    satisfied &= ~constraint;
+                }
                 mReadyDynamicSatisfied = mDynamicConstraints != 0
                         && mDynamicConstraints == (satisfied & mDynamicConstraints);
+
                 break;
         }
 
@@ -1926,7 +2040,10 @@
         pw.println(serviceInfo != null);
         if ((getFlags() & JobInfo.FLAG_EXPEDITED) != 0) {
             pw.print("readyWithinExpeditedQuota: ");
-            pw.println(mReadyWithinExpeditedQuota);
+            pw.print(mReadyWithinExpeditedQuota);
+            pw.print(" (started as EJ: ");
+            pw.print(startedAsExpeditedJob);
+            pw.println(")");
         }
         pw.decreaseIndent();
 
@@ -2065,9 +2182,6 @@
             if (uriPerms != null) {
                 uriPerms.dump(proto, JobStatusDumpProto.JobInfo.GRANTED_URI_PERMISSIONS);
             }
-            if (job.getRequiredNetwork() != null) {
-                job.getRequiredNetwork().dumpDebug(proto, JobStatusDumpProto.JobInfo.REQUIRED_NETWORK);
-            }
             if (mTotalNetworkDownloadBytes != JobInfo.NETWORK_BYTES_UNKNOWN) {
                 proto.write(JobStatusDumpProto.JobInfo.TOTAL_NETWORK_DOWNLOAD_BYTES,
                         mTotalNetworkDownloadBytes);
@@ -2156,10 +2270,6 @@
             }
         }
 
-        if (network != null) {
-            network.dumpDebug(proto, JobStatusDumpProto.NETWORK);
-        }
-
         if (pendingWork != null) {
             for (int i = 0; i < pendingWork.size(); i++) {
                 dumpJobWorkItem(proto, JobStatusDumpProto.PENDING_WORK, pendingWork.get(i));
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 2b79969..91189e4 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
@@ -849,10 +849,9 @@
             return true;
         }
         // A job is within quota if one of the following is true:
-        //   1. it's already running (already executing expedited jobs should be allowed to finish)
-        //   2. the app is currently in the foreground
-        //   3. the app overall is within its quota
-        //   4. It's on the temp allowlist (or within the grace period)
+        //   1. the app is currently in the foreground
+        //   2. the app overall is within its quota
+        //   3. It's on the temp allowlist (or within the grace period)
         if (isTopStartedJobLocked(jobStatus) || isUidInForeground(jobStatus.getSourceUid())) {
             return true;
         }
@@ -873,13 +872,6 @@
             return true;
         }
 
-        Timer ejTimer = mEJPkgTimers.get(jobStatus.getSourceUserId(),
-                jobStatus.getSourcePackageName());
-        // Any already executing expedited jobs should be allowed to finish.
-        if (ejTimer != null && ejTimer.isRunning(jobStatus)) {
-            return true;
-        }
-
         return 0 < getRemainingEJExecutionTimeLocked(
                 jobStatus.getSourceUserId(), jobStatus.getSourcePackageName());
     }
@@ -4153,6 +4145,8 @@
                 pw.print(", ");
                 if (js.shouldTreatAsExpeditedJob()) {
                     pw.print("within EJ quota");
+                } else if (js.startedAsExpeditedJob) {
+                    pw.print("out of EJ quota");
                 } else if (js.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_QUOTA)) {
                     pw.print("within regular quota");
                 } else {
@@ -4163,6 +4157,8 @@
                     pw.print(getRemainingEJExecutionTimeLocked(
                             js.getSourceUserId(), js.getSourcePackageName()));
                     pw.print("ms remaining in EJ quota");
+                } else if (js.startedAsExpeditedJob) {
+                    pw.print("should be stopped after min execution time");
                 } else {
                     pw.print(getRemainingExecutionTimeLocked(js));
                     pw.print("ms remaining in quota");
diff --git a/apex/jobscheduler/service/java/com/android/server/job/restrictions/JobRestriction.java b/apex/jobscheduler/service/java/com/android/server/job/restrictions/JobRestriction.java
index ac59f95..2962b10 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/restrictions/JobRestriction.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/restrictions/JobRestriction.java
@@ -17,6 +17,7 @@
 package com.android.server.job.restrictions;
 
 import android.app.job.JobInfo;
+import android.app.job.JobParameters;
 import android.util.IndentingPrintWriter;
 import android.util.proto.ProtoOutputStream;
 
@@ -26,9 +27,8 @@
 /**
  * Used by {@link JobSchedulerService} to impose additional restrictions regarding whether jobs
  * should be scheduled or not based on the state of the system/device.
- * Every restriction is associated with exactly one reason (from {@link
- * android.app.job.JobParameters#JOB_STOP_REASON_CODES}), which could be retrieved using {@link
- * #getReason()}.
+ * Every restriction is associated with exactly one stop reason, which could be retrieved using
+ * {@link #getReason()} (and the legacy reason via {@link #getLegacyReason()}).
  * Note, that this is not taken into account for the jobs that have priority
  * {@link JobInfo#PRIORITY_FOREGROUND_APP} or higher.
  */
@@ -36,10 +36,13 @@
 
     final JobSchedulerService mService;
     private final int mReason;
+    private final int mLegacyReason;
 
-    JobRestriction(JobSchedulerService service, int reason) {
+    JobRestriction(JobSchedulerService service, @JobParameters.StopReason int reason,
+            int legacyReason) {
         mService = service;
         mReason = reason;
+        mLegacyReason = legacyReason;
     }
 
     /**
@@ -66,7 +69,12 @@
     public abstract void dumpConstants(ProtoOutputStream proto);
 
     /** @return reason code for the Restriction. */
+    @JobParameters.StopReason
     public final int getReason() {
         return mReason;
     }
+
+    public final int getLegacyReason() {
+        return mLegacyReason;
+    }
 }
diff --git a/apex/jobscheduler/service/java/com/android/server/job/restrictions/ThermalStatusRestriction.java b/apex/jobscheduler/service/java/com/android/server/job/restrictions/ThermalStatusRestriction.java
index 954a5b8..8b699e9 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/restrictions/ThermalStatusRestriction.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/restrictions/ThermalStatusRestriction.java
@@ -34,7 +34,7 @@
     private PowerManager mPowerManager;
 
     public ThermalStatusRestriction(JobSchedulerService service) {
-        super(service, JobParameters.REASON_DEVICE_THERMAL);
+        super(service, JobParameters.STOP_REASON_DEVICE_STATE, JobParameters.REASON_DEVICE_THERMAL);
     }
 
     @Override
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 24f7b37..a62e258 100644
--- a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
+++ b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
@@ -190,7 +190,7 @@
                     ONE_HOUR,
                     ONE_HOUR,
                     2 * ONE_HOUR,
-                    4 * ONE_DAY
+                    4 * ONE_HOUR
             };
 
     private static final int[] THRESHOLD_BUCKETS = {
diff --git a/apex/media/framework/Android.bp b/apex/media/framework/Android.bp
index 20ce133..3cf585e 100644
--- a/apex/media/framework/Android.bp
+++ b/apex/media/framework/Android.bp
@@ -41,9 +41,7 @@
     installable: true,
 
     sdk_version: "module_current",
-    libs: [
-        "framework_media_annotation",
-    ],
+    libs: ["framework-annotations-lib"],
     static_libs: [
         "exoplayer2-extractor",
         "mediatranscoding_aidl_interface-java",
@@ -138,20 +136,9 @@
     api_lint: {
         enabled: false,
     },
-
-    libs: [
-        "framework_media_annotation",
-    ],
     impl_library_visibility: ["//frameworks/av/apex:__subpackages__"],
 }
 
-java_library {
-    name: "framework_media_annotation",
-    srcs: [":framework-media-annotation-srcs"],
-    installable: false,
-    sdk_version: "core_current",
-}
-
 cc_library_shared {
     name: "libmediaparser-jni",
     srcs: [
diff --git a/apex/media/framework/api/current.txt b/apex/media/framework/api/current.txt
index 80698f7..bebf019 100644
--- a/apex/media/framework/api/current.txt
+++ b/apex/media/framework/api/current.txt
@@ -69,10 +69,12 @@
     method public boolean advance(@NonNull android.media.MediaParser.SeekableInputReader) throws java.io.IOException;
     method @NonNull public static android.media.MediaParser create(@NonNull android.media.MediaParser.OutputConsumer, @NonNull java.lang.String...);
     method @NonNull public static android.media.MediaParser createByName(@NonNull String, @NonNull android.media.MediaParser.OutputConsumer);
+    method @NonNull public android.media.metrics.LogSessionId getLogSessionId();
     method @NonNull public String getParserName();
     method @NonNull public static java.util.List<java.lang.String> getParserNames(@NonNull android.media.MediaFormat);
     method public void release();
     method public void seek(@NonNull android.media.MediaParser.SeekPoint);
+    method public void setLogSessionId(@NonNull android.media.metrics.LogSessionId);
     method @NonNull public android.media.MediaParser setParameter(@NonNull String, @NonNull Object);
     method public boolean supportsParameter(@NonNull String);
     field public static final String PARAMETER_ADTS_ENABLE_CBR_SEEKING = "android.media.mediaparser.adts.enableCbrSeeking";
diff --git a/apex/media/framework/api/system-current.txt b/apex/media/framework/api/system-current.txt
index ad68169..8d83309 100644
--- a/apex/media/framework/api/system-current.txt
+++ b/apex/media/framework/api/system-current.txt
@@ -25,7 +25,9 @@
   }
 
   public static final class MediaTranscodeManager.TranscodingSession {
+    method public void addClientUid(int);
     method public void cancel();
+    method @NonNull public java.util.List<java.lang.Integer> getClientUids();
     method public int getErrorCode();
     method @IntRange(from=0, to=100) public int getProgress();
     method public int getResult();
diff --git a/apex/media/framework/java/android/media/MediaParser.java b/apex/media/framework/java/android/media/MediaParser.java
index 8bdca76..cff422d 100644
--- a/apex/media/framework/java/android/media/MediaParser.java
+++ b/apex/media/framework/java/android/media/MediaParser.java
@@ -21,6 +21,7 @@
 import android.annotation.Nullable;
 import android.annotation.StringDef;
 import android.media.MediaCodec.CryptoInfo;
+import android.media.metrics.LogSessionId;
 import android.os.Build;
 import android.text.TextUtils;
 import android.util.Log;
@@ -74,6 +75,7 @@
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.UUID;
 import java.util.concurrent.ThreadLocalRandom;
 import java.util.function.Function;
@@ -1066,6 +1068,7 @@
     private boolean mReleased;
 
     // MediaMetrics fields.
+    @NonNull private LogSessionId mLogSessionId = LogSessionId.LOG_SESSION_ID_NONE;
     private final boolean mCreatedByName;
     private final SparseArray<Format> mTrackFormats;
     private String mLastObservedExceptionName;
@@ -1328,6 +1331,7 @@
                                 MEDIAMETRICS_PARAMETER_LIST_MAX_LENGTH));
 
         nativeSubmitMetrics(
+                // TODO: mLogSessionId,
                 mParserName,
                 mCreatedByName,
                 String.join(MEDIAMETRICS_ELEMENT_SEPARATOR, mParserNamesPool),
@@ -1341,6 +1345,15 @@
                 videoHeight);
     }
 
+    public void setLogSessionId(@NonNull LogSessionId sessionId) {
+        this.mLogSessionId = Objects.requireNonNull(sessionId);
+    }
+
+    @NonNull
+    public LogSessionId getLogSessionId() {
+        return mLogSessionId;
+    }
+
     // Private methods.
 
     private MediaParser(
@@ -2184,6 +2197,7 @@
     // Native methods.
 
     private native void nativeSubmitMetrics(
+            // TODO: String logSessionId,
             String parserName,
             boolean createdByName,
             String parserPool,
diff --git a/apex/media/framework/java/android/media/MediaTranscodeManager.java b/apex/media/framework/java/android/media/MediaTranscodeManager.java
index 7f4685e..fef4865 100644
--- a/apex/media/framework/java/android/media/MediaTranscodeManager.java
+++ b/apex/media/framework/java/android/media/MediaTranscodeManager.java
@@ -1352,6 +1352,8 @@
         private @TranscodingSessionErrorCode int mErrorCode = ERROR_NONE;
         @GuardedBy("mLock")
         private boolean mHasRetried = false;
+        @GuardedBy("mLock")
+        private @NonNull List<Integer> mClientUidList = new ArrayList<>();
         // The original request that associated with this session.
         private final TranscodingRequest mRequest;
 
@@ -1370,6 +1372,7 @@
             mListenerExecutor = executor;
             mListener = listener;
             mRequest = request;
+            mClientUidList.add(request.getClientUid());
         }
 
         /**
@@ -1515,6 +1518,36 @@
         }
 
         /**
+         * Adds a client uid that is also waiting for this transcoding session.
+         * <p>
+         * Only privilege caller with android.permission.WRITE_MEDIA_STORAGE could add the
+         * uid. Note that the permission check happens on the service side upon starting the
+         * transcoding. If the client does not have the permission, the transcoding will fail.
+         */
+        public void addClientUid(int uid) {
+            if (uid < 0) {
+                throw new IllegalArgumentException("Invalid Uid");
+            }
+            synchronized (mLock) {
+                if (!mClientUidList.contains(uid)) {
+                    // see ag/14023202 for implementation
+                    mClientUidList.add(uid);
+                }
+            }
+        }
+
+        /**
+         * Query all the client that waiting for this transcoding session
+         * @return a list containing all the client uids.
+         */
+        @NonNull
+        public List<Integer> getClientUids() {
+            synchronized (mLock) {
+                return mClientUidList;
+            }
+        }
+
+        /**
          * Gets sessionId of the transcoding session.
          * @return session id.
          */
diff --git a/cmds/content/src/com/android/commands/content/Content.java b/cmds/content/src/com/android/commands/content/Content.java
index ca1d598..f0ac530 100644
--- a/cmds/content/src/com/android/commands/content/Content.java
+++ b/cmds/content/src/com/android/commands/content/Content.java
@@ -19,6 +19,7 @@
 import android.app.ActivityManager;
 import android.app.ContentProviderHolder;
 import android.app.IActivityManager;
+import android.content.AttributionSource;
 import android.content.ContentResolver;
 import android.content.ContentValues;
 import android.content.IContentProvider;
@@ -562,7 +563,8 @@
 
         @Override
         public void onExecute(IContentProvider provider) throws Exception {
-            provider.insert(resolveCallingPackage(), null, mUri, mContentValues, mExtras);
+            provider.insert(new AttributionSource(Binder.getCallingUid(),
+                    resolveCallingPackage(), null), mUri, mContentValues, mExtras);
         }
     }
 
@@ -576,7 +578,8 @@
 
         @Override
         public void onExecute(IContentProvider provider) throws Exception {
-            provider.delete(resolveCallingPackage(), null, mUri, mExtras);
+            provider.delete(new AttributionSource(Binder.getCallingUid(),
+                    resolveCallingPackage(), null), mUri, mExtras);
         }
     }
 
@@ -593,7 +596,8 @@
 
         @Override
         public void onExecute(IContentProvider provider) throws Exception {
-            Bundle result = provider.call(null, null, mUri.getAuthority(), mMethod, mArg, mExtras);
+            Bundle result = provider.call(new AttributionSource(Binder.getCallingUid(),
+                    resolveCallingPackage(), null), mUri.getAuthority(), mMethod, mArg, mExtras);
             if (result != null) {
                 result.size(); // unpack
             }
@@ -620,7 +624,9 @@
 
         @Override
         public void onExecute(IContentProvider provider) throws Exception {
-            try (ParcelFileDescriptor fd = provider.openFile(null, null, mUri, "r", null, null)) {
+            try (ParcelFileDescriptor fd = provider.openFile(
+                    new AttributionSource(Binder.getCallingUid(),
+                    resolveCallingPackage(), null), mUri, "r", null)) {
                 FileUtils.copy(fd.getFileDescriptor(), FileDescriptor.out);
             }
         }
@@ -633,7 +639,8 @@
 
         @Override
         public void onExecute(IContentProvider provider) throws Exception {
-            try (ParcelFileDescriptor fd = provider.openFile(null, null, mUri, "w", null, null)) {
+            try (ParcelFileDescriptor fd = provider.openFile(new AttributionSource(
+                    Binder.getCallingUid(), resolveCallingPackage(), null), mUri, "w", null)) {
                 FileUtils.copy(FileDescriptor.in, fd.getFileDescriptor());
             }
         }
@@ -651,8 +658,8 @@
 
         @Override
         public void onExecute(IContentProvider provider) throws Exception {
-            Cursor cursor = provider.query(resolveCallingPackage(), null, mUri, mProjection,
-                    mExtras, null);
+            Cursor cursor = provider.query(new AttributionSource(Binder.getCallingUid(),
+                    resolveCallingPackage(), null), mUri, mProjection, mExtras, null);
             if (cursor == null) {
                 System.out.println("No result found.");
                 return;
@@ -716,7 +723,8 @@
 
         @Override
         public void onExecute(IContentProvider provider) throws Exception {
-            provider.update(resolveCallingPackage(), null, mUri, mValues, mExtras);
+            provider.update(new AttributionSource(Binder.getCallingUid(),
+                    resolveCallingPackage(), null), mUri, mValues, mExtras);
         }
     }
 
diff --git a/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/ShellUiAutomatorBridge.java b/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/ShellUiAutomatorBridge.java
index b23bf5d..bc95986 100644
--- a/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/ShellUiAutomatorBridge.java
+++ b/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/ShellUiAutomatorBridge.java
@@ -20,6 +20,7 @@
 import android.app.ContentProviderHolder;
 import android.app.IActivityManager;
 import android.app.UiAutomation;
+import android.content.AttributionSource;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.IContentProvider;
@@ -28,6 +29,7 @@
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.IPowerManager;
+import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
@@ -67,7 +69,8 @@
                     throw new IllegalStateException("Could not find provider: " + providerName);
                 }
                 provider = holder.provider;
-                cursor = provider.query(null, null, Settings.Secure.CONTENT_URI,
+                cursor = provider.query(new AttributionSource(Binder.getCallingUid(),
+                        resolveCallingPackage(), null), Settings.Secure.CONTENT_URI,
                         new String[] {
                             Settings.Secure.VALUE
                         },
@@ -123,4 +126,18 @@
         }
         return ret;
     }
+
+    private static String resolveCallingPackage() {
+        switch (Binder.getCallingUid()) {
+            case Process.ROOT_UID: {
+                return "root";
+            }
+            case Process.SHELL_UID: {
+                return "com.android.shell";
+            }
+            default: {
+                return null;
+            }
+        }
+    }
 }
diff --git a/core/api/current.txt b/core/api/current.txt
index 5fcafc7..f8654478 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -55,7 +55,9 @@
     field public static final String BIND_WALLPAPER = "android.permission.BIND_WALLPAPER";
     field public static final String BLUETOOTH = "android.permission.BLUETOOTH";
     field public static final String BLUETOOTH_ADMIN = "android.permission.BLUETOOTH_ADMIN";
+    field public static final String BLUETOOTH_CONNECT = "android.permission.BLUETOOTH_CONNECT";
     field public static final String BLUETOOTH_PRIVILEGED = "android.permission.BLUETOOTH_PRIVILEGED";
+    field public static final String BLUETOOTH_SCAN = "android.permission.BLUETOOTH_SCAN";
     field public static final String BODY_SENSORS = "android.permission.BODY_SENSORS";
     field public static final String BROADCAST_PACKAGE_REMOVED = "android.permission.BROADCAST_PACKAGE_REMOVED";
     field public static final String BROADCAST_SMS = "android.permission.BROADCAST_SMS";
@@ -166,6 +168,7 @@
     field public static final String TRANSMIT_IR = "android.permission.TRANSMIT_IR";
     field public static final String UNINSTALL_SHORTCUT = "com.android.launcher.permission.UNINSTALL_SHORTCUT";
     field public static final String UPDATE_DEVICE_STATS = "android.permission.UPDATE_DEVICE_STATS";
+    field public static final String UPDATE_PACKAGES_WITHOUT_USER_ACTION = "android.permission.UPDATE_PACKAGES_WITHOUT_USER_ACTION";
     field public static final String USE_BIOMETRIC = "android.permission.USE_BIOMETRIC";
     field @Deprecated public static final String USE_FINGERPRINT = "android.permission.USE_FINGERPRINT";
     field public static final String USE_FULL_SCREEN_INTENT = "android.permission.USE_FULL_SCREEN_INTENT";
@@ -194,6 +197,7 @@
     field public static final String CONTACTS = "android.permission-group.CONTACTS";
     field public static final String LOCATION = "android.permission-group.LOCATION";
     field public static final String MICROPHONE = "android.permission-group.MICROPHONE";
+    field public static final String NEARBY_DEVICES = "android.permission-group.NEARBY_DEVICES";
     field public static final String PHONE = "android.permission-group.PHONE";
     field public static final String SENSORS = "android.permission-group.SENSORS";
     field public static final String SMS = "android.permission-group.SMS";
@@ -863,6 +867,7 @@
     field public static final int keycode = 16842949; // 0x10100c5
     field public static final int killAfterRestore = 16843420; // 0x101029c
     field public static final int knownCerts = 16844330; // 0x101062a
+    field public static final int lStar = 16844359; // 0x1010647
     field public static final int label = 16842753; // 0x1010001
     field public static final int labelFor = 16843718; // 0x10103c6
     field @Deprecated public static final int labelTextSize = 16843317; // 0x1010235
@@ -1006,7 +1011,7 @@
     field public static final int multiArch = 16843918; // 0x101048e
     field public static final int multiprocess = 16842771; // 0x1010013
     field public static final int name = 16842755; // 0x1010003
-    field public static final int nativeHeapZeroInit = 16844325; // 0x1010625
+    field public static final int nativeHeapZeroInitialized = 16844325; // 0x1010625
     field public static final int navigationBarColor = 16843858; // 0x1010452
     field public static final int navigationBarDividerColor = 16844141; // 0x101056d
     field public static final int navigationContentDescription = 16843969; // 0x10104c1
@@ -1176,6 +1181,7 @@
     field public static final int reqNavigation = 16843306; // 0x101022a
     field public static final int reqTouchScreen = 16843303; // 0x1010227
     field public static final int requestLegacyExternalStorage = 16844291; // 0x1010603
+    field public static final int requestOptimizedExternalStorageAccess = 16844357; // 0x1010645
     field public static final int requireDeviceScreenOn = 16844317; // 0x101061d
     field public static final int requireDeviceUnlock = 16843756; // 0x10103ec
     field public static final int required = 16843406; // 0x101028e
@@ -1581,6 +1587,7 @@
     field public static final int useLevel = 16843167; // 0x101019f
     field public static final int userVisible = 16843409; // 0x1010291
     field public static final int usesCleartextTraffic = 16844012; // 0x10104ec
+    field public static final int usesPermissionFlags = 16844356; // 0x1010644
     field public static final int value = 16842788; // 0x1010024
     field public static final int valueFrom = 16843486; // 0x10102de
     field public static final int valueTo = 16843487; // 0x10102df
@@ -1728,42 +1735,66 @@
     field @Deprecated public static final int secondary_text_dark_nodisable = 17170438; // 0x1060006
     field @Deprecated public static final int secondary_text_light = 17170439; // 0x1060007
     field @Deprecated public static final int secondary_text_light_nodisable = 17170440; // 0x1060008
-    field public static final int system_neutral_0 = 17170485; // 0x1060035
-    field public static final int system_neutral_100 = 17170487; // 0x1060037
-    field public static final int system_neutral_1000 = 17170496; // 0x1060040
-    field public static final int system_neutral_200 = 17170488; // 0x1060038
-    field public static final int system_neutral_300 = 17170489; // 0x1060039
-    field public static final int system_neutral_400 = 17170490; // 0x106003a
-    field public static final int system_neutral_50 = 17170486; // 0x1060036
-    field public static final int system_neutral_500 = 17170491; // 0x106003b
-    field public static final int system_neutral_600 = 17170492; // 0x106003c
-    field public static final int system_neutral_700 = 17170493; // 0x106003d
-    field public static final int system_neutral_800 = 17170494; // 0x106003e
-    field public static final int system_neutral_900 = 17170495; // 0x106003f
-    field public static final int system_primary_0 = 17170461; // 0x106001d
-    field public static final int system_primary_100 = 17170463; // 0x106001f
-    field public static final int system_primary_1000 = 17170472; // 0x1060028
-    field public static final int system_primary_200 = 17170464; // 0x1060020
-    field public static final int system_primary_300 = 17170465; // 0x1060021
-    field public static final int system_primary_400 = 17170466; // 0x1060022
-    field public static final int system_primary_50 = 17170462; // 0x106001e
-    field public static final int system_primary_500 = 17170467; // 0x1060023
-    field public static final int system_primary_600 = 17170468; // 0x1060024
-    field public static final int system_primary_700 = 17170469; // 0x1060025
-    field public static final int system_primary_800 = 17170470; // 0x1060026
-    field public static final int system_primary_900 = 17170471; // 0x1060027
-    field public static final int system_secondary_0 = 17170473; // 0x1060029
-    field public static final int system_secondary_100 = 17170475; // 0x106002b
-    field public static final int system_secondary_1000 = 17170484; // 0x1060034
-    field public static final int system_secondary_200 = 17170476; // 0x106002c
-    field public static final int system_secondary_300 = 17170477; // 0x106002d
-    field public static final int system_secondary_400 = 17170478; // 0x106002e
-    field public static final int system_secondary_50 = 17170474; // 0x106002a
-    field public static final int system_secondary_500 = 17170479; // 0x106002f
-    field public static final int system_secondary_600 = 17170480; // 0x1060030
-    field public static final int system_secondary_700 = 17170481; // 0x1060031
-    field public static final int system_secondary_800 = 17170482; // 0x1060032
-    field public static final int system_secondary_900 = 17170483; // 0x1060033
+    field public static final int system_accent1_0 = 17170485; // 0x1060035
+    field public static final int system_accent1_100 = 17170487; // 0x1060037
+    field public static final int system_accent1_1000 = 17170496; // 0x1060040
+    field public static final int system_accent1_200 = 17170488; // 0x1060038
+    field public static final int system_accent1_300 = 17170489; // 0x1060039
+    field public static final int system_accent1_400 = 17170490; // 0x106003a
+    field public static final int system_accent1_50 = 17170486; // 0x1060036
+    field public static final int system_accent1_500 = 17170491; // 0x106003b
+    field public static final int system_accent1_600 = 17170492; // 0x106003c
+    field public static final int system_accent1_700 = 17170493; // 0x106003d
+    field public static final int system_accent1_800 = 17170494; // 0x106003e
+    field public static final int system_accent1_900 = 17170495; // 0x106003f
+    field public static final int system_accent2_0 = 17170497; // 0x1060041
+    field public static final int system_accent2_100 = 17170499; // 0x1060043
+    field public static final int system_accent2_1000 = 17170508; // 0x106004c
+    field public static final int system_accent2_200 = 17170500; // 0x1060044
+    field public static final int system_accent2_300 = 17170501; // 0x1060045
+    field public static final int system_accent2_400 = 17170502; // 0x1060046
+    field public static final int system_accent2_50 = 17170498; // 0x1060042
+    field public static final int system_accent2_500 = 17170503; // 0x1060047
+    field public static final int system_accent2_600 = 17170504; // 0x1060048
+    field public static final int system_accent2_700 = 17170505; // 0x1060049
+    field public static final int system_accent2_800 = 17170506; // 0x106004a
+    field public static final int system_accent2_900 = 17170507; // 0x106004b
+    field public static final int system_accent3_0 = 17170509; // 0x106004d
+    field public static final int system_accent3_100 = 17170511; // 0x106004f
+    field public static final int system_accent3_1000 = 17170520; // 0x1060058
+    field public static final int system_accent3_200 = 17170512; // 0x1060050
+    field public static final int system_accent3_300 = 17170513; // 0x1060051
+    field public static final int system_accent3_400 = 17170514; // 0x1060052
+    field public static final int system_accent3_50 = 17170510; // 0x106004e
+    field public static final int system_accent3_500 = 17170515; // 0x1060053
+    field public static final int system_accent3_600 = 17170516; // 0x1060054
+    field public static final int system_accent3_700 = 17170517; // 0x1060055
+    field public static final int system_accent3_800 = 17170518; // 0x1060056
+    field public static final int system_accent3_900 = 17170519; // 0x1060057
+    field public static final int system_neutral1_0 = 17170461; // 0x106001d
+    field public static final int system_neutral1_100 = 17170463; // 0x106001f
+    field public static final int system_neutral1_1000 = 17170472; // 0x1060028
+    field public static final int system_neutral1_200 = 17170464; // 0x1060020
+    field public static final int system_neutral1_300 = 17170465; // 0x1060021
+    field public static final int system_neutral1_400 = 17170466; // 0x1060022
+    field public static final int system_neutral1_50 = 17170462; // 0x106001e
+    field public static final int system_neutral1_500 = 17170467; // 0x1060023
+    field public static final int system_neutral1_600 = 17170468; // 0x1060024
+    field public static final int system_neutral1_700 = 17170469; // 0x1060025
+    field public static final int system_neutral1_800 = 17170470; // 0x1060026
+    field public static final int system_neutral1_900 = 17170471; // 0x1060027
+    field public static final int system_neutral2_0 = 17170473; // 0x1060029
+    field public static final int system_neutral2_100 = 17170475; // 0x106002b
+    field public static final int system_neutral2_1000 = 17170484; // 0x1060034
+    field public static final int system_neutral2_200 = 17170476; // 0x106002c
+    field public static final int system_neutral2_300 = 17170477; // 0x106002d
+    field public static final int system_neutral2_400 = 17170478; // 0x106002e
+    field public static final int system_neutral2_50 = 17170474; // 0x106002a
+    field public static final int system_neutral2_500 = 17170479; // 0x106002f
+    field public static final int system_neutral2_600 = 17170480; // 0x1060030
+    field public static final int system_neutral2_700 = 17170481; // 0x1060031
+    field public static final int system_neutral2_800 = 17170482; // 0x1060032
+    field public static final int system_neutral2_900 = 17170483; // 0x1060033
     field public static final int tab_indicator_text = 17170441; // 0x1060009
     field @Deprecated public static final int tertiary_text_dark = 17170448; // 0x1060010
     field @Deprecated public static final int tertiary_text_light = 17170449; // 0x1060011
@@ -5655,6 +5686,7 @@
     field public static final String EXTRA_PEOPLE_LIST = "android.people.list";
     field public static final String EXTRA_PICTURE = "android.picture";
     field public static final String EXTRA_PICTURE_CONTENT_DESCRIPTION = "android.pictureContentDescription";
+    field public static final String EXTRA_PICTURE_ICON = "android.pictureIcon";
     field public static final String EXTRA_PROGRESS = "android.progress";
     field public static final String EXTRA_PROGRESS_INDETERMINATE = "android.progressIndeterminate";
     field public static final String EXTRA_PROGRESS_MAX = "android.progressMax";
@@ -5685,6 +5717,9 @@
     field public static final int FLAG_ONGOING_EVENT = 2; // 0x2
     field public static final int FLAG_ONLY_ALERT_ONCE = 8; // 0x8
     field @Deprecated public static final int FLAG_SHOW_LIGHTS = 1; // 0x1
+    field public static final int FOREGROUND_SERVICE_DEFAULT = 0; // 0x0
+    field public static final int FOREGROUND_SERVICE_DEFERRED = 2; // 0x2
+    field public static final int FOREGROUND_SERVICE_IMMEDIATE = 1; // 0x1
     field public static final int GROUP_ALERT_ALL = 0; // 0x0
     field public static final int GROUP_ALERT_CHILDREN = 2; // 0x2
     field public static final int GROUP_ALERT_SUMMARY = 1; // 0x1
@@ -5803,8 +5838,9 @@
     method @NonNull public android.app.Notification.BigPictureStyle bigLargeIcon(@Nullable android.graphics.Bitmap);
     method @NonNull public android.app.Notification.BigPictureStyle bigLargeIcon(@Nullable android.graphics.drawable.Icon);
     method @NonNull public android.app.Notification.BigPictureStyle bigPicture(@Nullable android.graphics.Bitmap);
-    method @NonNull public android.app.Notification.BigPictureStyle bigPictureContentDescription(@Nullable CharSequence);
+    method @NonNull public android.app.Notification.BigPictureStyle bigPicture(@Nullable android.graphics.drawable.Icon);
     method @NonNull public android.app.Notification.BigPictureStyle setBigContentTitle(@Nullable CharSequence);
+    method @NonNull public android.app.Notification.BigPictureStyle setContentDescription(@Nullable CharSequence);
     method @NonNull public android.app.Notification.BigPictureStyle setSummaryText(@Nullable CharSequence);
     method @NonNull public android.app.Notification.BigPictureStyle showBigPictureWhenCollapsed(boolean);
   }
@@ -5887,6 +5923,7 @@
     method @NonNull public android.app.Notification.Builder setDeleteIntent(android.app.PendingIntent);
     method @NonNull public android.app.Notification.Builder setExtras(android.os.Bundle);
     method @NonNull public android.app.Notification.Builder setFlag(int, boolean);
+    method @NonNull public android.app.Notification.Builder setForegroundServiceBehavior(int);
     method @NonNull public android.app.Notification.Builder setFullScreenIntent(android.app.PendingIntent, boolean);
     method @NonNull public android.app.Notification.Builder setGroup(String);
     method @NonNull public android.app.Notification.Builder setGroupAlertBehavior(int);
@@ -5905,7 +5942,7 @@
     method @NonNull public android.app.Notification.Builder setRemoteInputHistory(CharSequence[]);
     method @NonNull public android.app.Notification.Builder setSettingsText(CharSequence);
     method @NonNull public android.app.Notification.Builder setShortcutId(String);
-    method @NonNull public android.app.Notification.Builder setShowForegroundImmediately(boolean);
+    method @Deprecated @NonNull public android.app.Notification.Builder setShowForegroundImmediately(boolean);
     method @NonNull public android.app.Notification.Builder setShowWhen(boolean);
     method @NonNull public android.app.Notification.Builder setSmallIcon(@DrawableRes int);
     method @NonNull public android.app.Notification.Builder setSmallIcon(@DrawableRes int, int);
@@ -6289,13 +6326,13 @@
     method public static android.app.PendingIntent getActivity(android.content.Context, int, android.content.Intent, int);
     method public static android.app.PendingIntent getActivity(android.content.Context, int, @NonNull android.content.Intent, int, @Nullable android.os.Bundle);
     method public static android.app.PendingIntent getBroadcast(android.content.Context, int, @NonNull android.content.Intent, int);
-    method @NonNull public String getCreatorPackage();
+    method @Nullable public String getCreatorPackage();
     method public int getCreatorUid();
     method @NonNull public android.os.UserHandle getCreatorUserHandle();
     method public static android.app.PendingIntent getForegroundService(android.content.Context, int, @NonNull android.content.Intent, int);
     method @NonNull public android.content.IntentSender getIntentSender();
     method public static android.app.PendingIntent getService(android.content.Context, int, @NonNull android.content.Intent, int);
-    method @Deprecated @NonNull public String getTargetPackage();
+    method @Deprecated @Nullable public String getTargetPackage();
     method public boolean isActivity();
     method public boolean isBroadcast();
     method public boolean isForegroundService();
@@ -6982,6 +7019,7 @@
     method public void onBugreportShared(@NonNull android.content.Context, @NonNull android.content.Intent, @NonNull String);
     method public void onBugreportSharingDeclined(@NonNull android.content.Context, @NonNull android.content.Intent);
     method @Nullable public String onChoosePrivateKeyAlias(@NonNull android.content.Context, @NonNull android.content.Intent, int, @Nullable android.net.Uri, @Nullable String);
+    method public void onComplianceAcknowledgementRequired(@NonNull android.content.Context, @NonNull android.content.Intent);
     method @Nullable public CharSequence onDisableRequested(@NonNull android.content.Context, @NonNull android.content.Intent);
     method public void onDisabled(@NonNull android.content.Context, @NonNull android.content.Intent);
     method public void onEnabled(@NonNull android.content.Context, @NonNull android.content.Intent);
@@ -7036,6 +7074,7 @@
   }
 
   public class DevicePolicyManager {
+    method public void acknowledgeDeviceCompliant();
     method public void addCrossProfileIntentFilter(@NonNull android.content.ComponentName, android.content.IntentFilter, int);
     method public boolean addCrossProfileWidgetProvider(@NonNull android.content.ComponentName, String);
     method public int addOverrideApn(@NonNull android.content.ComponentName, @NonNull android.telephony.data.ApnSetting);
@@ -7095,6 +7134,8 @@
     method public int getMaximumFailedPasswordsForWipe(@Nullable android.content.ComponentName);
     method public long getMaximumTimeToLock(@Nullable android.content.ComponentName);
     method @NonNull public java.util.List<java.lang.String> getMeteredDataDisabledPackages(@NonNull android.content.ComponentName);
+    method public int getNearbyAppStreamingPolicy();
+    method public int getNearbyNotificationStreamingPolicy();
     method @Deprecated @ColorInt public int getOrganizationColor(@NonNull android.content.ComponentName);
     method @Nullable public CharSequence getOrganizationName(@NonNull android.content.ComponentName);
     method public java.util.List<android.telephony.data.ApnSetting> getOverrideApns(@NonNull android.content.ComponentName);
@@ -7154,8 +7195,10 @@
     method public boolean isBackupServiceEnabled(@NonNull android.content.ComponentName);
     method @Deprecated public boolean isCallerApplicationRestrictionsManagingPackage();
     method public boolean isCommonCriteriaModeEnabled(@Nullable android.content.ComponentName);
+    method public boolean isComplianceAcknowledgementRequired();
     method public boolean isDeviceIdAttestationSupported();
     method public boolean isDeviceOwnerApp(String);
+    method public boolean isEnterpriseNetworkPreferenceEnabled();
     method public boolean isEphemeralUser(@NonNull android.content.ComponentName);
     method public boolean isKeyPairGrantedToWifiAuth(@NonNull String);
     method public boolean isLockTaskPermitted(String);
@@ -7163,7 +7206,6 @@
     method public boolean isManagedProfile(@NonNull android.content.ComponentName);
     method public boolean isMasterVolumeMuted(@NonNull android.content.ComponentName);
     method public boolean isNetworkLoggingEnabled(@Nullable android.content.ComponentName);
-    method public boolean isNetworkSlicingEnabled();
     method public boolean isOrganizationOwnedDeviceWithManagedProfile();
     method public boolean isOverrideApnEnabled(@NonNull android.content.ComponentName);
     method public boolean isPackageSuspended(@NonNull android.content.ComponentName, String) throws android.content.pm.PackageManager.NameNotFoundException;
@@ -7218,6 +7260,7 @@
     method public void setDelegatedScopes(@NonNull android.content.ComponentName, @NonNull String, @NonNull java.util.List<java.lang.String>);
     method public void setDeviceOwnerLockScreenInfo(@NonNull android.content.ComponentName, CharSequence);
     method public void setEndUserSessionMessage(@NonNull android.content.ComponentName, @Nullable CharSequence);
+    method public void setEnterpriseNetworkPreferenceEnabled(boolean);
     method public void setFactoryResetProtectionPolicy(@NonNull android.content.ComponentName, @Nullable android.app.admin.FactoryResetProtectionPolicy);
     method public int setGlobalPrivateDnsModeOpportunistic(@NonNull android.content.ComponentName);
     method @WorkerThread public int setGlobalPrivateDnsModeSpecifiedHost(@NonNull android.content.ComponentName, @NonNull String);
@@ -7236,8 +7279,9 @@
     method public void setMaximumFailedPasswordsForWipe(@NonNull android.content.ComponentName, int);
     method public void setMaximumTimeToLock(@NonNull android.content.ComponentName, long);
     method @NonNull public java.util.List<java.lang.String> setMeteredDataDisabledPackages(@NonNull android.content.ComponentName, @NonNull java.util.List<java.lang.String>);
+    method public void setNearbyAppStreamingPolicy(int);
+    method public void setNearbyNotificationStreamingPolicy(int);
     method public void setNetworkLoggingEnabled(@Nullable android.content.ComponentName, boolean);
-    method public void setNetworkSlicingEnabled(boolean);
     method @Deprecated public void setOrganizationColor(@NonNull android.content.ComponentName, int);
     method public void setOrganizationId(@NonNull String);
     method public void setOrganizationName(@NonNull android.content.ComponentName, @Nullable CharSequence);
@@ -7405,6 +7449,9 @@
     field public static final int LOCK_TASK_FEATURE_SYSTEM_INFO = 1; // 0x1
     field public static final int MAKE_USER_EPHEMERAL = 2; // 0x2
     field public static final String MIME_TYPE_PROVISIONING_NFC = "application/com.android.managedprovisioning";
+    field public static final int NEARBY_STREAMING_DISABLED = 0; // 0x0
+    field public static final int NEARBY_STREAMING_ENABLED = 1; // 0x1
+    field public static final int NEARBY_STREAMING_SAME_MANAGED_ACCOUNT_ONLY = 2; // 0x2
     field public static final int OPERATION_SAFETY_REASON_DRIVING_DISTRACTION = 1; // 0x1
     field public static final int PASSWORD_COMPLEXITY_HIGH = 327680; // 0x50000
     field public static final int PASSWORD_COMPLEXITY_LOW = 65536; // 0x10000
@@ -7834,8 +7881,10 @@
   public static class BlobStoreManager.Session implements java.io.Closeable {
     method public void abandon() throws java.io.IOException;
     method public void allowPackageAccess(@NonNull String, @NonNull byte[]) throws java.io.IOException;
+    method public void allowPackagesWithLocationPermission(@NonNull String) throws java.io.IOException;
     method public void allowPublicAccess() throws java.io.IOException;
     method public void allowSameSignatureAccess() throws java.io.IOException;
+    method public boolean arePackagesWithLocationPermissionAllowed(@NonNull String) throws java.io.IOException;
     method public void close() throws java.io.IOException;
     method public void commit(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>) throws java.io.IOException;
     method public long getSize() throws java.io.IOException;
@@ -7943,6 +7992,7 @@
     method @NonNull public android.os.PersistableBundle getExtras();
     method public int getJobId();
     method @Nullable public android.net.Network getNetwork();
+    method public int getStopReason();
     method @NonNull public android.os.Bundle getTransientExtras();
     method @Nullable public String[] getTriggeredContentAuthorities();
     method @Nullable public android.net.Uri[] getTriggeredContentUris();
@@ -7951,6 +8001,21 @@
     method public boolean isOverrideDeadlineExpired();
     method public void writeToParcel(android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.app.job.JobParameters> CREATOR;
+    field public static final int STOP_REASON_APP_STANDBY = 12; // 0xc
+    field public static final int STOP_REASON_BACKGROUND_RESTRICTION = 11; // 0xb
+    field public static final int STOP_REASON_CANCELLED_BY_APP = 1; // 0x1
+    field public static final int STOP_REASON_CONSTRAINT_BATTERY_NOT_LOW = 5; // 0x5
+    field public static final int STOP_REASON_CONSTRAINT_CHARGING = 6; // 0x6
+    field public static final int STOP_REASON_CONSTRAINT_CONNECTIVITY = 7; // 0x7
+    field public static final int STOP_REASON_CONSTRAINT_DEVICE_IDLE = 8; // 0x8
+    field public static final int STOP_REASON_CONSTRAINT_STORAGE_NOT_LOW = 9; // 0x9
+    field public static final int STOP_REASON_DEVICE_STATE = 4; // 0x4
+    field public static final int STOP_REASON_PREEMPT = 2; // 0x2
+    field public static final int STOP_REASON_QUOTA = 10; // 0xa
+    field public static final int STOP_REASON_SYSTEM_PROCESSING = 14; // 0xe
+    field public static final int STOP_REASON_TIMEOUT = 3; // 0x3
+    field public static final int STOP_REASON_UNDEFINED = 0; // 0x0
+    field public static final int STOP_REASON_USER = 13; // 0xd
   }
 
   public abstract class JobScheduler {
@@ -8953,6 +9018,7 @@
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public String getName();
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public int getType();
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public android.os.ParcelUuid[] getUuids();
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public boolean setAlias(@NonNull String);
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setPairingConfirmation(boolean);
     method public boolean setPin(byte[]);
     method public void writeToParcel(android.os.Parcel, int);
@@ -8966,6 +9032,8 @@
     field public static final String ACTION_NAME_CHANGED = "android.bluetooth.device.action.NAME_CHANGED";
     field public static final String ACTION_PAIRING_REQUEST = "android.bluetooth.device.action.PAIRING_REQUEST";
     field public static final String ACTION_UUID = "android.bluetooth.device.action.UUID";
+    field public static final int ADDRESS_TYPE_PUBLIC = 0; // 0x0
+    field public static final int ADDRESS_TYPE_RANDOM = 1; // 0x1
     field public static final int BOND_BONDED = 12; // 0xc
     field public static final int BOND_BONDING = 11; // 0xb
     field public static final int BOND_NONE = 10; // 0xa
@@ -9848,6 +9916,27 @@
     method @Deprecated public void setUpdateThrottle(long);
   }
 
+  public final class AttributionSource implements android.os.Parcelable {
+    method public boolean checkCallingUid();
+    method public int describeContents();
+    method public void enforceCallingUid();
+    method @Nullable public String getAttributionTag();
+    method @Nullable public android.content.AttributionSource getNext();
+    method @Nullable public String getPackageName();
+    method public int getUid();
+    method public boolean isTrusted(@NonNull android.content.Context);
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.content.AttributionSource> CREATOR;
+  }
+
+  public static final class AttributionSource.Builder {
+    ctor public AttributionSource.Builder(int);
+    method @NonNull public android.content.AttributionSource build();
+    method @NonNull public android.content.AttributionSource.Builder setAttributionTag(@NonNull String);
+    method @NonNull public android.content.AttributionSource.Builder setNext(@NonNull android.content.AttributionSource);
+    method @NonNull public android.content.AttributionSource.Builder setPackageName(@NonNull String);
+  }
+
   public abstract class BroadcastReceiver {
     ctor public BroadcastReceiver();
     method public final void abortBroadcast();
@@ -10017,6 +10106,7 @@
     method public abstract int delete(@NonNull android.net.Uri, @Nullable String, @Nullable String[]);
     method public int delete(@NonNull android.net.Uri, @Nullable android.os.Bundle);
     method public void dump(java.io.FileDescriptor, java.io.PrintWriter, String[]);
+    method @Nullable public final android.content.AttributionSource getCallingAttributionSource();
     method @Nullable public final String getCallingAttributionTag();
     method @Nullable public final String getCallingPackage();
     method @Nullable public final String getCallingPackageUnchecked();
@@ -10379,6 +10469,7 @@
     method public abstract android.content.Context getApplicationContext();
     method public abstract android.content.pm.ApplicationInfo getApplicationInfo();
     method public abstract android.content.res.AssetManager getAssets();
+    method @NonNull public android.content.AttributionSource getAttributionSource();
     method @Nullable public String getAttributionTag();
     method public abstract java.io.File getCacheDir();
     method public abstract ClassLoader getClassLoader();
@@ -10584,8 +10675,7 @@
 
   public final class ContextParams {
     method @Nullable public String getAttributionTag();
-    method @Nullable public String getReceiverAttributionTag();
-    method @Nullable public String getReceiverPackage();
+    method @Nullable public android.content.AttributionSource getNextAttributionSource();
   }
 
   public static final class ContextParams.Builder {
@@ -10593,7 +10683,7 @@
     ctor public ContextParams.Builder(@NonNull android.content.ContextParams);
     method @NonNull public android.content.ContextParams build();
     method @NonNull public android.content.ContextParams.Builder setAttributionTag(@Nullable String);
-    method @NonNull public android.content.ContextParams.Builder setReceiverPackage(@Nullable String, @Nullable String);
+    method @NonNull public android.content.ContextParams.Builder setNextAttributionSource(@NonNull android.content.AttributionSource);
   }
 
   public class ContextWrapper extends android.content.Context {
@@ -11814,7 +11904,7 @@
     method public static CharSequence getCategoryTitle(android.content.Context, int);
     method public int getGwpAsanMode();
     method public int getMemtagMode();
-    method @Nullable public Boolean isNativeHeapZeroInit();
+    method public int getNativeHeapZeroInitialized();
     method public boolean isProfileableByShell();
     method public boolean isResourceOverlay();
     method public boolean isVirtualPreload();
@@ -11869,6 +11959,9 @@
     field public static final int MEMTAG_DEFAULT = -1; // 0xffffffff
     field public static final int MEMTAG_OFF = 0; // 0x0
     field public static final int MEMTAG_SYNC = 2; // 0x2
+    field public static final int ZEROINIT_DEFAULT = -1; // 0xffffffff
+    field public static final int ZEROINIT_DISABLED = 0; // 0x0
+    field public static final int ZEROINIT_ENABLED = 1; // 0x1
     field public String appComponentFactory;
     field public String backupAgentName;
     field public int category;
@@ -12029,6 +12122,14 @@
     field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.InstallSourceInfo> CREATOR;
   }
 
+  public final class InstallationFile {
+    method public long getLengthBytes();
+    method public int getLocation();
+    method @Nullable public byte[] getMetadata();
+    method @NonNull public String getName();
+    method @Nullable public byte[] getSignature();
+  }
+
   public class InstrumentationInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
     ctor public InstrumentationInfo();
     ctor public InstrumentationInfo(android.content.pm.InstrumentationInfo);
@@ -12083,6 +12184,7 @@
     method @Nullable public android.content.IntentSender getShortcutConfigActivityIntent(@NonNull android.content.pm.LauncherActivityInfo);
     method public java.util.List<android.content.pm.LauncherActivityInfo> getShortcutConfigActivityList(@Nullable String, @NonNull android.os.UserHandle);
     method public android.graphics.drawable.Drawable getShortcutIconDrawable(@NonNull android.content.pm.ShortcutInfo, int);
+    method @Nullable public android.app.PendingIntent getShortcutIntent(@NonNull String, @NonNull String, @Nullable android.os.Bundle, @NonNull android.os.UserHandle);
     method @Nullable public java.util.List<android.content.pm.ShortcutInfo> getShortcuts(@NonNull android.content.pm.LauncherApps.ShortcutQuery, @NonNull android.os.UserHandle);
     method @Nullable public android.os.Bundle getSuspendedPackageLauncherExtras(String, android.os.UserHandle);
     method public boolean hasShortcutHostPermission();
@@ -12171,6 +12273,7 @@
     field public static final int INSTALL_LOCATION_INTERNAL_ONLY = 1; // 0x1
     field public static final int INSTALL_LOCATION_PREFER_EXTERNAL = 2; // 0x2
     field public static final int REQUESTED_PERMISSION_GRANTED = 2; // 0x2
+    field public static final int REQUESTED_PERMISSION_NEVER_FOR_LOCATION = 65536; // 0x10000
     field public android.content.pm.ActivityInfo[] activities;
     field public android.content.pm.ApplicationInfo applicationInfo;
     field @Nullable public android.content.pm.Attribution[] attributions;
@@ -12265,6 +12368,7 @@
     method @NonNull public java.io.InputStream openRead(@NonNull String) throws java.io.IOException;
     method @NonNull public java.io.OutputStream openWrite(@NonNull String, long, long) throws java.io.IOException;
     method public void removeChildSessionId(int);
+    method public void removeFile(int, @NonNull String);
     method public void removeSplit(@NonNull String) throws java.io.IOException;
     method @Deprecated public void setChecksums(@NonNull String, @NonNull java.util.List<android.content.pm.Checksum>, @Nullable byte[]) throws java.io.IOException;
     method public void setStagingProgress(float);
@@ -12298,6 +12402,7 @@
     method public int getParentSessionId();
     method public float getProgress();
     method @Nullable public android.net.Uri getReferrerUri();
+    method public int getRequireUserAction();
     method public int getSessionId();
     method public long getSize();
     method public int getStagedSessionErrorCode();
@@ -12322,6 +12427,9 @@
     field public static final int STAGED_SESSION_NO_ERROR = 0; // 0x0
     field public static final int STAGED_SESSION_UNKNOWN = 3; // 0x3
     field public static final int STAGED_SESSION_VERIFICATION_FAILED = 1; // 0x1
+    field public static final int USER_ACTION_NOT_REQUIRED = 2; // 0x2
+    field public static final int USER_ACTION_REQUIRED = 1; // 0x1
+    field public static final int USER_ACTION_UNSPECIFIED = 0; // 0x0
   }
 
   public static class PackageInstaller.SessionParams implements android.os.Parcelable {
@@ -12339,6 +12447,7 @@
     method public void setOriginatingUid(int);
     method public void setOriginatingUri(@Nullable android.net.Uri);
     method public void setReferrerUri(@Nullable android.net.Uri);
+    method public void setRequireUserAction(boolean);
     method public void setSize(long);
     method public void setWhitelistedRestrictedPermissions(@Nullable java.util.Set<java.lang.String>);
     method public void writeToParcel(android.os.Parcel, int);
@@ -12550,6 +12659,7 @@
     field public static final String FEATURE_FINGERPRINT = "android.hardware.fingerprint";
     field public static final String FEATURE_FREEFORM_WINDOW_MANAGEMENT = "android.software.freeform_window_management";
     field public static final String FEATURE_GAMEPAD = "android.hardware.gamepad";
+    field public static final String FEATURE_HARDWARE_KEYSTORE = "android.hardware.hardware_keystore";
     field public static final String FEATURE_HIFI_SENSORS = "android.hardware.sensor.hifi_sensors";
     field public static final String FEATURE_HOME_SCREEN = "android.software.home_screen";
     field public static final String FEATURE_IDENTITY_CREDENTIAL_HARDWARE = "android.hardware.identity_credential";
@@ -13100,6 +13210,7 @@
     method public boolean isStateful();
     method @NonNull public static android.content.res.ColorStateList valueOf(@ColorInt int);
     method @NonNull public android.content.res.ColorStateList withAlpha(int);
+    method @NonNull public android.content.res.ColorStateList withLStar(float);
     method public void writeToParcel(android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.content.res.ColorStateList> CREATOR;
   }
@@ -13322,7 +13433,8 @@
     method public void setTo(android.content.res.Resources.Theme);
   }
 
-  public class TypedArray {
+  public class TypedArray implements java.lang.AutoCloseable {
+    method public void close();
     method public boolean getBoolean(@StyleableRes int, boolean);
     method public int getChangingConfigurations();
     method @ColorInt public int getColor(@StyleableRes int, @ColorInt int);
@@ -17808,6 +17920,7 @@
     field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.String> INFO_VERSION;
     field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<android.util.Size[]> JPEG_AVAILABLE_THUMBNAIL_SIZES;
     field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<float[]> LENS_DISTORTION;
+    field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<float[]> LENS_DISTORTION_MAXIMUM_RESOLUTION;
     field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> LENS_FACING;
     field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<float[]> LENS_INFO_AVAILABLE_APERTURES;
     field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<float[]> LENS_INFO_AVAILABLE_FILTER_DENSITIES;
@@ -17817,6 +17930,7 @@
     field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Float> LENS_INFO_HYPERFOCAL_DISTANCE;
     field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Float> LENS_INFO_MINIMUM_FOCUS_DISTANCE;
     field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<float[]> LENS_INTRINSIC_CALIBRATION;
+    field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<float[]> LENS_INTRINSIC_CALIBRATION_MAXIMUM_RESOLUTION;
     field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> LENS_POSE_REFERENCE;
     field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<float[]> LENS_POSE_ROTATION;
     field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<float[]> LENS_POSE_TRANSLATION;
@@ -17836,9 +17950,11 @@
     field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> SCALER_CROPPING_TYPE;
     field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<android.util.Size> SCALER_DEFAULT_SECURE_IMAGE_SIZE;
     field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<android.hardware.camera2.params.MandatoryStreamCombination[]> SCALER_MANDATORY_CONCURRENT_STREAM_COMBINATIONS;
+    field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<android.hardware.camera2.params.MandatoryStreamCombination[]> SCALER_MANDATORY_MAXIMUM_RESOLUTION_STREAM_COMBINATIONS;
     field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<android.hardware.camera2.params.MandatoryStreamCombination[]> SCALER_MANDATORY_STREAM_COMBINATIONS;
     field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<android.hardware.camera2.params.MultiResolutionStreamConfigurationMap> SCALER_MULTI_RESOLUTION_STREAM_CONFIGURATION_MAP;
     field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<android.hardware.camera2.params.StreamConfigurationMap> SCALER_STREAM_CONFIGURATION_MAP;
+    field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<android.hardware.camera2.params.StreamConfigurationMap> SCALER_STREAM_CONFIGURATION_MAP_MAXIMUM_RESOLUTION;
     field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> SENSOR_AVAILABLE_TEST_PATTERN_MODES;
     field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<android.hardware.camera2.params.BlackLevelPattern> SENSOR_BLACK_LEVEL_PATTERN;
     field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<android.hardware.camera2.params.ColorSpaceTransform> SENSOR_CALIBRATION_TRANSFORM1;
@@ -17848,13 +17964,17 @@
     field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<android.hardware.camera2.params.ColorSpaceTransform> SENSOR_FORWARD_MATRIX1;
     field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<android.hardware.camera2.params.ColorSpaceTransform> SENSOR_FORWARD_MATRIX2;
     field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<android.graphics.Rect> SENSOR_INFO_ACTIVE_ARRAY_SIZE;
+    field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<android.graphics.Rect> SENSOR_INFO_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION;
+    field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<android.util.Size> SENSOR_INFO_BINNING_FACTOR;
     field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> SENSOR_INFO_COLOR_FILTER_ARRANGEMENT;
     field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<android.util.Range<java.lang.Long>> SENSOR_INFO_EXPOSURE_TIME_RANGE;
     field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Boolean> SENSOR_INFO_LENS_SHADING_APPLIED;
     field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Long> SENSOR_INFO_MAX_FRAME_DURATION;
     field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<android.util.SizeF> SENSOR_INFO_PHYSICAL_SIZE;
     field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<android.util.Size> SENSOR_INFO_PIXEL_ARRAY_SIZE;
+    field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<android.util.Size> SENSOR_INFO_PIXEL_ARRAY_SIZE_MAXIMUM_RESOLUTION;
     field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<android.graphics.Rect> SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE;
+    field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<android.graphics.Rect> SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION;
     field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<android.util.Range<java.lang.Integer>> SENSOR_INFO_SENSITIVITY_RANGE;
     field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> SENSOR_INFO_TIMESTAMP_SOURCE;
     field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> SENSOR_INFO_WHITE_LEVEL;
@@ -18151,8 +18271,10 @@
     field public static final int REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING = 4; // 0x4
     field public static final int REQUEST_AVAILABLE_CAPABILITIES_RAW = 3; // 0x3
     field public static final int REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS = 5; // 0x5
+    field public static final int REQUEST_AVAILABLE_CAPABILITIES_REMOSAIC_REPROCESSING = 17; // 0x11
     field public static final int REQUEST_AVAILABLE_CAPABILITIES_SECURE_IMAGE_DATA = 13; // 0xd
     field public static final int REQUEST_AVAILABLE_CAPABILITIES_SYSTEM_CAMERA = 14; // 0xe
+    field public static final int REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR = 16; // 0x10
     field public static final int REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING = 7; // 0x7
     field public static final int SCALER_CROPPING_TYPE_CENTER_ONLY = 0; // 0x0
     field public static final int SCALER_CROPPING_TYPE_FREEFORM = 1; // 0x1
@@ -18170,6 +18292,8 @@
     field public static final int SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGGB = 0; // 0x0
     field public static final int SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME = 1; // 0x1
     field public static final int SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN = 0; // 0x0
+    field public static final int SENSOR_PIXEL_MODE_DEFAULT = 0; // 0x0
+    field public static final int SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION = 1; // 0x1
     field public static final int SENSOR_REFERENCE_ILLUMINANT1_CLOUDY_WEATHER = 10; // 0xa
     field public static final int SENSOR_REFERENCE_ILLUMINANT1_COOL_WHITE_FLUORESCENT = 14; // 0xe
     field public static final int SENSOR_REFERENCE_ILLUMINANT1_D50 = 23; // 0x17
@@ -18299,6 +18423,7 @@
     field @NonNull public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> SCALER_ROTATE_AND_CROP;
     field @NonNull public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Long> SENSOR_EXPOSURE_TIME;
     field @NonNull public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Long> SENSOR_FRAME_DURATION;
+    field @NonNull public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> SENSOR_PIXEL_MODE;
     field @NonNull public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> SENSOR_SENSITIVITY;
     field @NonNull public static final android.hardware.camera2.CaptureRequest.Key<int[]> SENSOR_TEST_PATTERN_DATA;
     field @NonNull public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> SENSOR_TEST_PATTERN_MODE;
@@ -18402,6 +18527,8 @@
     field @NonNull public static final android.hardware.camera2.CaptureResult.Key<java.lang.Float> SENSOR_GREEN_SPLIT;
     field @NonNull public static final android.hardware.camera2.CaptureResult.Key<android.util.Rational[]> SENSOR_NEUTRAL_COLOR_POINT;
     field @NonNull public static final android.hardware.camera2.CaptureResult.Key<android.util.Pair<java.lang.Double,java.lang.Double>[]> SENSOR_NOISE_PROFILE;
+    field @NonNull public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> SENSOR_PIXEL_MODE;
+    field @NonNull public static final android.hardware.camera2.CaptureResult.Key<java.lang.Boolean> SENSOR_RAW_BINNING_FACTOR_USED;
     field @NonNull public static final android.hardware.camera2.CaptureResult.Key<java.lang.Long> SENSOR_ROLLING_SHUTTER_SKEW;
     field @NonNull public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> SENSOR_SENSITIVITY;
     field @NonNull public static final android.hardware.camera2.CaptureResult.Key<int[]> SENSOR_TEST_PATTERN_DATA;
@@ -18531,6 +18658,7 @@
     method @NonNull public java.util.List<android.util.Size> getAvailableSizes();
     method public int getFormat();
     method public boolean isInput();
+    method public boolean isUltraHighResolution();
   }
 
   public final class MeteringRectangle {
@@ -18576,6 +18704,7 @@
     ctor public OutputConfiguration(@NonNull android.view.Surface);
     ctor public OutputConfiguration(int, @NonNull android.view.Surface);
     ctor public OutputConfiguration(@NonNull android.util.Size, @NonNull Class<T>);
+    method public void addSensorPixelModeUsed(int);
     method public void addSurface(@NonNull android.view.Surface);
     method @NonNull public static java.util.Collection<android.hardware.camera2.params.OutputConfiguration> createInstancesForMultiResolutionOutput(@NonNull android.hardware.camera2.MultiResolutionImageReader);
     method public int describeContents();
@@ -18584,6 +18713,7 @@
     method @Nullable public android.view.Surface getSurface();
     method public int getSurfaceGroupId();
     method @NonNull public java.util.List<android.view.Surface> getSurfaces();
+    method public void removeSensorPixelModeUsed(int);
     method public void removeSurface(@NonNull android.view.Surface);
     method public void setPhysicalCameraId(@Nullable String);
     method public void writeToParcel(android.os.Parcel, int);
@@ -18712,9 +18842,14 @@
     method public android.view.Display getDisplay(int);
     method public android.view.Display[] getDisplays();
     method public android.view.Display[] getDisplays(String);
+    method public int getMatchContentFrameRateUserPreference();
     method public void registerDisplayListener(android.hardware.display.DisplayManager.DisplayListener, android.os.Handler);
     method public void unregisterDisplayListener(android.hardware.display.DisplayManager.DisplayListener);
     field public static final String DISPLAY_CATEGORY_PRESENTATION = "android.hardware.display.category.PRESENTATION";
+    field public static final int MATCH_CONTENT_FRAMERATE_ALWAYS = 2; // 0x2
+    field public static final int MATCH_CONTENT_FRAMERATE_NEVER = 0; // 0x0
+    field public static final int MATCH_CONTENT_FRAMERATE_SEAMLESSS_ONLY = 1; // 0x1
+    field public static final int MATCH_CONTENT_FRAMERATE_UNKNOWN = -1; // 0xffffffff
     field public static final int VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR = 16; // 0x10
     field public static final int VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY = 8; // 0x8
     field public static final int VIRTUAL_DISPLAY_FLAG_PRESENTATION = 2; // 0x2
@@ -19754,7 +19889,8 @@
     method public boolean hasSpeed();
     method public boolean hasSpeedAccuracy();
     method public boolean hasVerticalAccuracy();
-    method public boolean isFromMockProvider();
+    method @Deprecated public boolean isFromMockProvider();
+    method public boolean isMock();
     method @Deprecated public void removeAccuracy();
     method @Deprecated public void removeAltitude();
     method @Deprecated public void removeBearing();
@@ -19770,6 +19906,7 @@
     method public void setExtras(@Nullable android.os.Bundle);
     method public void setLatitude(double);
     method public void setLongitude(double);
+    method public void setMock(boolean);
     method public void setProvider(String);
     method public void setSpeed(float);
     method public void setSpeedAccuracyMetersPerSecond(float);
@@ -20048,6 +20185,14 @@
     method public android.media.AudioAttributes.Builder setUsage(int);
   }
 
+  public class AudioDescriptor {
+    method @NonNull public byte[] getDescriptor();
+    method public int getEncapsulationType();
+    method public int getStandard();
+    field public static final int STANDARD_EDID = 1; // 0x1
+    field public static final int STANDARD_NONE = 0; // 0x0
+  }
+
   public abstract class AudioDeviceCallback {
     ctor public AudioDeviceCallback();
     method public void onAudioDevicesAdded(android.media.AudioDeviceInfo[]);
@@ -20056,6 +20201,7 @@
 
   public final class AudioDeviceInfo {
     method @NonNull public String getAddress();
+    method @NonNull public java.util.List<android.media.AudioDescriptor> getAudioDescriptors();
     method @NonNull public java.util.List<android.media.AudioProfile> getAudioProfiles();
     method @NonNull public int[] getChannelCounts();
     method @NonNull public int[] getChannelIndexMasks();
@@ -20227,6 +20373,7 @@
     method @NonNull public java.util.List<android.media.AudioDeviceInfo> getAvailableCommunicationDevices();
     method @Nullable public android.media.AudioDeviceInfo getCommunicationDevice();
     method public android.media.AudioDeviceInfo[] getDevices(int);
+    method @RequiresPermission(android.Manifest.permission.WRITE_SETTINGS) public int getEncodedSurroundMode();
     method public java.util.List<android.media.MicrophoneInfo> getMicrophones() throws java.io.IOException;
     method public int getMode();
     method public String getParameters(String);
@@ -20249,6 +20396,7 @@
     method public static boolean isOffloadedPlaybackSupported(@NonNull android.media.AudioFormat, @NonNull android.media.AudioAttributes);
     method public boolean isSpeakerphoneOn();
     method public boolean isStreamMute(int);
+    method @RequiresPermission(android.Manifest.permission.WRITE_SETTINGS) public boolean isSurroundFormatEnabled(int);
     method public boolean isVolumeFixed();
     method @Deprecated public boolean isWiredHeadsetOn();
     method public void loadSoundEffects();
@@ -20268,6 +20416,7 @@
     method @Deprecated public void setBluetoothA2dpOn(boolean);
     method public void setBluetoothScoOn(boolean);
     method public boolean setCommunicationDevice(@NonNull android.media.AudioDeviceInfo);
+    method @RequiresPermission(android.Manifest.permission.WRITE_SETTINGS) public boolean setEncodedSurroundMode(int);
     method public void setMicrophoneMute(boolean);
     method public void setMode(int);
     method public void setParameters(String);
@@ -20277,6 +20426,7 @@
     method @Deprecated public void setStreamMute(int, boolean);
     method @Deprecated public void setStreamSolo(int, boolean);
     method public void setStreamVolume(int, int, int);
+    method @RequiresPermission(android.Manifest.permission.WRITE_SETTINGS) public boolean setSurroundFormatEnabled(int, boolean);
     method @Deprecated public void setVibrateSetting(int, int);
     method @Deprecated public void setWiredHeadsetOn(boolean);
     method @Deprecated public boolean shouldVibrate(int);
@@ -20315,6 +20465,10 @@
     field public static final int AUDIOFOCUS_REQUEST_FAILED = 0; // 0x0
     field public static final int AUDIOFOCUS_REQUEST_GRANTED = 1; // 0x1
     field public static final int AUDIO_SESSION_ID_GENERATE = 0; // 0x0
+    field public static final int ENCODED_SURROUND_OUTPUT_ALWAYS = 2; // 0x2
+    field public static final int ENCODED_SURROUND_OUTPUT_AUTO = 0; // 0x0
+    field public static final int ENCODED_SURROUND_OUTPUT_MANUAL = 3; // 0x3
+    field public static final int ENCODED_SURROUND_OUTPUT_NEVER = 1; // 0x1
     field public static final int ERROR = -1; // 0xffffffff
     field public static final int ERROR_DEAD_OBJECT = -6; // 0xfffffffa
     field public static final String EXTRA_AUDIO_PLUG_STATE = "android.media.extra.AUDIO_PLUG_STATE";
@@ -20510,8 +20664,11 @@
   public class AudioProfile {
     method @NonNull public int[] getChannelIndexMasks();
     method @NonNull public int[] getChannelMasks();
+    method public int getEncapsulationType();
     method public int getFormat();
     method @NonNull public int[] getSampleRates();
+    field public static final int AUDIO_ENCAPSULATION_TYPE_IEC61937 = 1; // 0x1
+    field public static final int AUDIO_ENCAPSULATION_TYPE_NONE = 0; // 0x0
   }
 
   public class AudioRecord implements android.media.AudioRecordingMonitor android.media.AudioRouting android.media.MicrophoneDirection {
@@ -20528,6 +20685,7 @@
     method public int getChannelConfiguration();
     method public int getChannelCount();
     method @NonNull public android.media.AudioFormat getFormat();
+    method @NonNull public android.media.metrics.LogSessionId getLogSessionId();
     method public android.os.PersistableBundle getMetrics();
     method public static int getMinBufferSize(int, int, int);
     method public int getNotificationMarkerPosition();
@@ -20550,6 +20708,7 @@
     method public void release();
     method public void removeOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener);
     method @Deprecated public void removeOnRoutingChangedListener(android.media.AudioRecord.OnRoutingChangedListener);
+    method public void setLogSessionId(@NonNull android.media.metrics.LogSessionId);
     method public int setNotificationMarkerPosition(int);
     method public int setPositionNotificationPeriod(int);
     method public boolean setPreferredDevice(android.media.AudioDeviceInfo);
@@ -20665,6 +20824,7 @@
     method public int getChannelCount();
     method public int getDualMonoMode();
     method @NonNull public android.media.AudioFormat getFormat();
+    method @NonNull public android.media.metrics.LogSessionId getLogSessionId();
     method public static float getMaxVolume();
     method public android.os.PersistableBundle getMetrics();
     method public static int getMinBufferSize(int, int, int);
@@ -20702,6 +20862,7 @@
     method public int setAuxEffectSendLevel(@FloatRange(from=0.0) float);
     method public int setBufferSizeInFrames(@IntRange(from=0) int);
     method public boolean setDualMonoMode(int);
+    method public void setLogSessionId(@NonNull android.media.metrics.LogSessionId);
     method public int setLoopPoints(@IntRange(from=0) int, @IntRange(from=0) int, @IntRange(from=0xffffffff) int);
     method public int setNotificationMarkerPosition(int);
     method public void setOffloadDelayPadding(@IntRange(from=0) int, @IntRange(from=0) int);
@@ -20800,6 +20961,7 @@
   public class CamcorderProfile {
     method public static android.media.CamcorderProfile get(int);
     method public static android.media.CamcorderProfile get(int, int);
+    method @Nullable public static android.media.EncoderProfiles getAll(@NonNull String, int);
     method public static boolean hasProfile(int);
     method public static boolean hasProfile(int, int);
     field public static final int QUALITY_1080P = 6; // 0x6
@@ -20880,6 +21042,32 @@
     field @NonNull public final java.util.UUID uuid;
   }
 
+  public class EncoderProfiles {
+    method @NonNull public java.util.List<android.media.EncoderProfiles.AudioProfile> getAudioProfiles();
+    method public int getDurationSeconds();
+    method public int getFileFormat();
+    method @NonNull public java.util.List<android.media.EncoderProfiles.VideoProfile> getVideoProfiles();
+  }
+
+  public static class EncoderProfiles.AudioProfile {
+    method public int getBitrate();
+    method public int getChannels();
+    method public int getCodec();
+    method @NonNull public String getMediaType();
+    method public int getProfile();
+    method public int getSampleRate();
+  }
+
+  public static class EncoderProfiles.VideoProfile {
+    method public int getBitrate();
+    method public int getCodec();
+    method public int getFrameRate();
+    method public int getHeight();
+    method @NonNull public String getMediaType();
+    method public int getProfile();
+    method public int getWidth();
+  }
+
   public class ExifInterface {
     ctor public ExifInterface(@NonNull java.io.File) throws java.io.IOException;
     ctor public ExifInterface(@NonNull String) throws java.io.IOException;
@@ -21256,7 +21444,7 @@
     method @NonNull public String getDiagnosticInfo();
   }
 
-  public final class MediaCodec implements android.media.metrics.PlaybackComponent {
+  public final class MediaCodec {
     method public void configure(@Nullable android.media.MediaFormat, @Nullable android.view.Surface, @Nullable android.media.MediaCrypto, int);
     method public void configure(@Nullable android.media.MediaFormat, @Nullable android.view.Surface, int, @Nullable android.media.MediaDescrambler);
     method @NonNull public static android.media.MediaCodec createByCodecName(@NonNull String) throws java.io.IOException;
@@ -21282,8 +21470,9 @@
     method @NonNull public android.media.MediaFormat getOutputFormat(int);
     method @NonNull public android.media.MediaCodec.OutputFrame getOutputFrame(int);
     method @Nullable public android.media.Image getOutputImage(int);
-    method public String getPlaybackId();
+    method @Nullable public android.media.MediaCodec.ParameterDescriptor getParameterDescriptor(@NonNull String);
     method @NonNull public android.media.MediaCodec.QueueRequest getQueueRequest(int);
+    method @NonNull public java.util.List<java.lang.String> getSupportedVendorParameters();
     method @Nullable public static android.media.Image mapHardwareBuffer(@NonNull android.hardware.HardwareBuffer);
     method public void queueInputBuffer(int, int, int, long, int) throws android.media.MediaCodec.CryptoException;
     method public void queueSecureInputBuffer(int, int, @NonNull android.media.MediaCodec.CryptoInfo, long, int) throws android.media.MediaCodec.CryptoException;
@@ -21295,14 +21484,16 @@
     method public void setCallback(@Nullable android.media.MediaCodec.Callback, @Nullable android.os.Handler);
     method public void setCallback(@Nullable android.media.MediaCodec.Callback);
     method public void setInputSurface(@NonNull android.view.Surface);
+    method public void setOnFirstTunnelFrameReadyListener(@Nullable android.os.Handler, @Nullable android.media.MediaCodec.OnFirstTunnelFrameReadyListener);
     method public void setOnFrameRenderedListener(@Nullable android.media.MediaCodec.OnFrameRenderedListener, @Nullable android.os.Handler);
     method public void setOutputSurface(@NonNull android.view.Surface);
     method public void setParameters(@Nullable android.os.Bundle);
-    method public void setPlaybackId(@NonNull String);
     method public void setVideoScalingMode(int);
     method public void signalEndOfInputStream();
     method public void start();
     method public void stop();
+    method public void subscribeToVendorParameters(@NonNull java.util.List<java.lang.String>);
+    method public void unsubscribeFromVendorParameters(@NonNull java.util.List<java.lang.String>);
     field public static final int BUFFER_FLAG_CODEC_CONFIG = 2; // 0x2
     field public static final int BUFFER_FLAG_END_OF_STREAM = 4; // 0x4
     field public static final int BUFFER_FLAG_KEY_FRAME = 1; // 0x1
@@ -21322,6 +21513,7 @@
     field public static final String PARAMETER_KEY_REQUEST_SYNC_FRAME = "request-sync";
     field public static final String PARAMETER_KEY_SUSPEND = "drop-input-frames";
     field public static final String PARAMETER_KEY_SUSPEND_TIME = "drop-start-time-us";
+    field public static final String PARAMETER_KEY_TUNNEL_PEEK = "tunnel-peek";
     field public static final String PARAMETER_KEY_VIDEO_BITRATE = "video-bitrate";
     field public static final int VIDEO_SCALING_MODE_SCALE_TO_FIT = 1; // 0x1
     field public static final int VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING = 2; // 0x2
@@ -21412,6 +21604,10 @@
     field public static final String WIDTH = "android.media.mediacodec.width";
   }
 
+  public static interface MediaCodec.OnFirstTunnelFrameReadyListener {
+    method public void onFirstTunnelFrameReady(@NonNull android.media.MediaCodec);
+  }
+
   public static interface MediaCodec.OnFrameRenderedListener {
     method public void onFrameRendered(@NonNull android.media.MediaCodec, long, long);
   }
@@ -21425,6 +21621,11 @@
     method public long getPresentationTimeUs();
   }
 
+  public static class MediaCodec.ParameterDescriptor {
+    method @NonNull public String getName();
+    method public int getType();
+  }
+
   public final class MediaCodec.QueueRequest {
     method public void queue();
     method @NonNull public android.media.MediaCodec.QueueRequest setByteBufferParameter(@NonNull String, @NonNull java.nio.ByteBuffer);
@@ -21532,6 +21733,7 @@
     field public static final String FEATURE_LowLatency = "low-latency";
     field public static final String FEATURE_MultipleFrames = "multiple-frames";
     field public static final String FEATURE_PartialFrame = "partial-frame";
+    field public static final String FEATURE_QpBounds = "qp-bounds";
     field public static final String FEATURE_SecurePlayback = "secure-playback";
     field public static final String FEATURE_TunneledPlayback = "tunneled-playback";
     field public int[] colorFormats;
@@ -21750,6 +21952,7 @@
     method public android.util.Range<java.lang.Integer> getQualityRange();
     method public boolean isBitrateModeSupported(int);
     field public static final int BITRATE_MODE_CBR = 2; // 0x2
+    field public static final int BITRATE_MODE_CBR_FD = 3; // 0x3
     field public static final int BITRATE_MODE_CQ = 0; // 0x0
     field public static final int BITRATE_MODE_VBR = 1; // 0x1
   }
@@ -21907,7 +22110,7 @@
     method @NonNull public java.util.List<byte[]> getOfflineLicenseKeySetIds();
     method public int getOfflineLicenseState(@NonNull byte[]);
     method public int getOpenSessionCount();
-    method @Nullable public android.media.metrics.PlaybackComponent getPlaybackComponent(@NonNull byte[]);
+    method @Nullable public android.media.MediaDrm.PlaybackComponent getPlaybackComponent(@NonNull byte[]);
     method @NonNull public byte[] getPropertyByteArray(String);
     method @NonNull public String getPropertyString(@NonNull String);
     method @NonNull public android.media.MediaDrm.ProvisionRequest getProvisionRequest();
@@ -22112,6 +22315,11 @@
     method public void onSessionLostState(@NonNull android.media.MediaDrm, @NonNull byte[]);
   }
 
+  public final class MediaDrm.PlaybackComponent {
+    method @NonNull public android.media.metrics.LogSessionId getLogSessionId();
+    method public void setLogSessionId(@NonNull android.media.metrics.LogSessionId);
+  }
+
   public static final class MediaDrm.ProvisionRequest {
     method @NonNull public byte[] getData();
     method @NonNull public String getDefaultUrl();
@@ -22144,6 +22352,7 @@
     method public long getCachedDuration();
     method public android.media.MediaExtractor.CasInfo getCasInfo(int);
     method public android.media.DrmInitData getDrmInitData();
+    method @NonNull public android.media.metrics.LogSessionId getLogSessionId();
     method public android.os.PersistableBundle getMetrics();
     method @Nullable public java.util.Map<java.util.UUID,byte[]> getPsshInfo();
     method public boolean getSampleCryptoInfo(@NonNull android.media.MediaCodec.CryptoInfo);
@@ -22165,6 +22374,7 @@
     method public void setDataSource(@NonNull android.content.res.AssetFileDescriptor) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;
     method public void setDataSource(@NonNull java.io.FileDescriptor) throws java.io.IOException;
     method public void setDataSource(@NonNull java.io.FileDescriptor, long, long) throws java.io.IOException;
+    method public void setLogSessionId(@NonNull android.media.metrics.LogSessionId);
     method public void setMediaCas(@NonNull android.media.MediaCas);
     method public void unselectTrack(int);
     field public static final int SAMPLE_FLAG_ENCRYPTED = 2; // 0x2
@@ -22768,6 +22978,7 @@
     method public java.util.List<android.media.MicrophoneInfo> getActiveMicrophones() throws java.io.IOException;
     method @Nullable public android.media.AudioRecordingConfiguration getActiveRecordingConfiguration();
     method public static final int getAudioSourceMax();
+    method @NonNull public android.media.metrics.LogSessionId getLogSessionId();
     method public int getMaxAmplitude() throws java.lang.IllegalStateException;
     method public android.os.PersistableBundle getMetrics();
     method public android.media.AudioDeviceInfo getPreferredDevice();
@@ -22784,12 +22995,14 @@
     method public void setAudioChannels(int);
     method public void setAudioEncoder(int) throws java.lang.IllegalStateException;
     method public void setAudioEncodingBitRate(int);
+    method public void setAudioProfile(@NonNull android.media.EncoderProfiles.AudioProfile);
     method public void setAudioSamplingRate(int);
     method public void setAudioSource(int) throws java.lang.IllegalStateException;
     method @Deprecated public void setCamera(android.hardware.Camera);
     method public void setCaptureRate(double);
     method public void setInputSurface(@NonNull android.view.Surface);
     method public void setLocation(float, float);
+    method public void setLogSessionId(@NonNull android.media.metrics.LogSessionId);
     method public void setMaxDuration(int) throws java.lang.IllegalArgumentException;
     method public void setMaxFileSize(long) throws java.lang.IllegalArgumentException;
     method public void setNextOutputFile(java.io.FileDescriptor) throws java.io.IOException;
@@ -22811,6 +23024,7 @@
     method public void setVideoEncodingBitRate(int);
     method public void setVideoEncodingProfileLevel(int, int);
     method public void setVideoFrameRate(int) throws java.lang.IllegalStateException;
+    method public void setVideoProfile(@NonNull android.media.EncoderProfiles.VideoProfile);
     method public void setVideoSize(int, int) throws java.lang.IllegalStateException;
     method public void setVideoSource(int) throws java.lang.IllegalStateException;
     method public void start() throws java.lang.IllegalStateException;
@@ -24416,11 +24630,18 @@
 
   public abstract class Event {
     ctor protected Event(long);
+    method @NonNull public android.os.Bundle getMetricsBundle();
     method @IntRange(from=0xffffffff) public long getTimeSinceCreatedMillis();
   }
 
+  public final class LogSessionId {
+    method @NonNull public String getStringId();
+    field @NonNull public static final android.media.metrics.LogSessionId LOG_SESSION_ID_NONE;
+  }
+
   public class MediaMetricsManager {
     method @NonNull public android.media.metrics.PlaybackSession createPlaybackSession();
+    method @NonNull public android.media.metrics.RecordingSession createRecordingSession();
     field public static final long INVALID_TIMESTAMP = -1L; // 0xffffffffffffffffL
   }
 
@@ -24435,32 +24656,57 @@
     field public static final int NETWORK_TYPE_5G_NSA = 7; // 0x7
     field public static final int NETWORK_TYPE_5G_SA = 8; // 0x8
     field public static final int NETWORK_TYPE_ETHERNET = 3; // 0x3
-    field public static final int NETWORK_TYPE_NONE = 0; // 0x0
+    field public static final int NETWORK_TYPE_OFFLINE = 9; // 0x9
     field public static final int NETWORK_TYPE_OTHER = 1; // 0x1
+    field public static final int NETWORK_TYPE_UNKNOWN = 0; // 0x0
     field public static final int NETWORK_TYPE_WIFI = 2; // 0x2
   }
 
   public static final class NetworkEvent.Builder {
     ctor public NetworkEvent.Builder();
     method @NonNull public android.media.metrics.NetworkEvent build();
+    method @NonNull public android.media.metrics.NetworkEvent.Builder setMetricsBundle(@NonNull android.os.Bundle);
     method @NonNull public android.media.metrics.NetworkEvent.Builder setNetworkType(int);
     method @NonNull public android.media.metrics.NetworkEvent.Builder setTimeSinceCreatedMillis(@IntRange(from=0xffffffff) long);
   }
 
-  public interface PlaybackComponent {
-    method @NonNull public String getPlaybackId();
-    method public void setPlaybackId(@NonNull String);
-  }
-
   public final class PlaybackErrorEvent extends android.media.metrics.Event implements android.os.Parcelable {
     method public int describeContents();
     method public int getErrorCode();
     method @IntRange(from=java.lang.Integer.MIN_VALUE, to=java.lang.Integer.MAX_VALUE) public int getSubErrorCode();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.media.metrics.PlaybackErrorEvent> CREATOR;
-    field public static final int ERROR_CODE_OTHER = 1; // 0x1
-    field public static final int ERROR_CODE_RUNTIME = 2; // 0x2
-    field public static final int ERROR_CODE_UNKNOWN = 0; // 0x0
+    field public static final int ERROR_AUDIOTRACK_INIT = 17; // 0x11
+    field public static final int ERROR_AUDIOTRACK_OTHER = 19; // 0x13
+    field public static final int ERROR_AUDIOTRACK_WRITE = 18; // 0x12
+    field public static final int ERROR_DECODER_DECODE = 14; // 0xe
+    field public static final int ERROR_DECODER_INIT = 13; // 0xd
+    field public static final int ERROR_DECODER_OOM = 15; // 0xf
+    field public static final int ERROR_DECODER_OTHER = 16; // 0x10
+    field public static final int ERROR_DRM_CONTENT_ERROR = 28; // 0x1c
+    field public static final int ERROR_DRM_DISALLOWED = 26; // 0x1a
+    field public static final int ERROR_DRM_LICENSE_ERROR = 25; // 0x19
+    field public static final int ERROR_DRM_OTHER = 30; // 0x1e
+    field public static final int ERROR_DRM_PROVISIONING_FAILED = 24; // 0x18
+    field public static final int ERROR_DRM_REVOKED = 29; // 0x1d
+    field public static final int ERROR_DRM_SYSTEM_ERROR = 27; // 0x1b
+    field public static final int ERROR_DRM_UNAVAILABLE = 23; // 0x17
+    field public static final int ERROR_MEDIA_MANIFEST = 10; // 0xa
+    field public static final int ERROR_MEDIA_OTHER = 12; // 0xc
+    field public static final int ERROR_MEDIA_PARSER = 11; // 0xb
+    field public static final int ERROR_NETWORK_BAD_STATUS = 5; // 0x5
+    field public static final int ERROR_NETWORK_CLOSED = 8; // 0x8
+    field public static final int ERROR_NETWORK_CONNECT = 4; // 0x4
+    field public static final int ERROR_NETWORK_DNS = 6; // 0x6
+    field public static final int ERROR_NETWORK_OFFLINE = 3; // 0x3
+    field public static final int ERROR_NETWORK_OTHER = 9; // 0x9
+    field public static final int ERROR_NETWORK_TIMEOUT = 7; // 0x7
+    field public static final int ERROR_OTHER = 1; // 0x1
+    field public static final int ERROR_PLAYER_BEHIND_LIVE_WINDOW = 21; // 0x15
+    field public static final int ERROR_PLAYER_OTHER = 22; // 0x16
+    field public static final int ERROR_PLAYER_REMOTE = 20; // 0x14
+    field public static final int ERROR_RUNTIME = 2; // 0x2
+    field public static final int ERROR_UNKNOWN = 0; // 0x0
   }
 
   public static final class PlaybackErrorEvent.Builder {
@@ -24468,6 +24714,7 @@
     method @NonNull public android.media.metrics.PlaybackErrorEvent build();
     method @NonNull public android.media.metrics.PlaybackErrorEvent.Builder setErrorCode(int);
     method @NonNull public android.media.metrics.PlaybackErrorEvent.Builder setException(@NonNull Exception);
+    method @NonNull public android.media.metrics.PlaybackErrorEvent.Builder setMetricsBundle(@NonNull android.os.Bundle);
     method @NonNull public android.media.metrics.PlaybackErrorEvent.Builder setSubErrorCode(@IntRange(from=java.lang.Integer.MIN_VALUE, to=java.lang.Integer.MAX_VALUE) int);
     method @NonNull public android.media.metrics.PlaybackErrorEvent.Builder setTimeSinceCreatedMillis(@IntRange(from=0xffffffff) long);
   }
@@ -24476,10 +24723,12 @@
     method public int describeContents();
     method @IntRange(from=0xffffffff, to=java.lang.Integer.MAX_VALUE) public int getAudioUnderrunCount();
     method public int getContentType();
+    method @NonNull public byte[] getDrmSessionId();
     method public int getDrmType();
     method @NonNull public long[] getExperimentIds();
     method @IntRange(from=0xffffffff) public long getLocalBytesRead();
     method @IntRange(from=0xffffffff) public long getMediaDurationMillis();
+    method @NonNull public android.os.Bundle getMetricsBundle();
     method @IntRange(from=0xffffffff) public long getNetworkBytesRead();
     method @IntRange(from=0xffffffff) public long getNetworkTransferDurationMillis();
     method public int getPlaybackType();
@@ -24490,9 +24739,10 @@
     method @IntRange(from=0xffffffff, to=java.lang.Integer.MAX_VALUE) public int getVideoFramesDropped();
     method @IntRange(from=0xffffffff, to=java.lang.Integer.MAX_VALUE) public int getVideoFramesPlayed();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field public static final int CONTENT_TYPE_AD = 1; // 0x1
-    field public static final int CONTENT_TYPE_MAIN = 0; // 0x0
-    field public static final int CONTENT_TYPE_OTHER = 2; // 0x2
+    field public static final int CONTENT_TYPE_AD = 2; // 0x2
+    field public static final int CONTENT_TYPE_MAIN = 1; // 0x1
+    field public static final int CONTENT_TYPE_OTHER = 3; // 0x3
+    field public static final int CONTENT_TYPE_UNKNOWN = 0; // 0x0
     field @NonNull public static final android.os.Parcelable.Creator<android.media.metrics.PlaybackMetrics> CREATOR;
     field public static final int DRM_TYPE_CLEARKEY = 6; // 0x6
     field public static final int DRM_TYPE_NONE = 0; // 0x0
@@ -24501,9 +24751,10 @@
     field public static final int DRM_TYPE_WIDEVINE_L1 = 3; // 0x3
     field public static final int DRM_TYPE_WIDEVINE_L3 = 4; // 0x4
     field public static final int DRM_TYPE_WV_L3_FALLBACK = 5; // 0x5
-    field public static final int PLAYBACK_TYPE_LIVE = 1; // 0x1
-    field public static final int PLAYBACK_TYPE_OTHER = 2; // 0x2
-    field public static final int PLAYBACK_TYPE_VOD = 0; // 0x0
+    field public static final int PLAYBACK_TYPE_LIVE = 2; // 0x2
+    field public static final int PLAYBACK_TYPE_OTHER = 3; // 0x3
+    field public static final int PLAYBACK_TYPE_UNKNOWN = 0; // 0x0
+    field public static final int PLAYBACK_TYPE_VOD = 1; // 0x1
     field public static final int STREAM_SOURCE_DEVICE = 2; // 0x2
     field public static final int STREAM_SOURCE_MIXED = 3; // 0x3
     field public static final int STREAM_SOURCE_NETWORK = 1; // 0x1
@@ -24522,9 +24773,11 @@
     method @NonNull public android.media.metrics.PlaybackMetrics build();
     method @NonNull public android.media.metrics.PlaybackMetrics.Builder setAudioUnderrunCount(@IntRange(from=0xffffffff, to=java.lang.Integer.MAX_VALUE) int);
     method @NonNull public android.media.metrics.PlaybackMetrics.Builder setContentType(int);
+    method @NonNull public android.media.metrics.PlaybackMetrics.Builder setDrmSessionId(@NonNull byte[]);
     method @NonNull public android.media.metrics.PlaybackMetrics.Builder setDrmType(int);
     method @NonNull public android.media.metrics.PlaybackMetrics.Builder setLocalBytesRead(@IntRange(from=0xffffffff) long);
     method @NonNull public android.media.metrics.PlaybackMetrics.Builder setMediaDurationMillis(@IntRange(from=0xffffffff) long);
+    method @NonNull public android.media.metrics.PlaybackMetrics.Builder setMetricsBundle(@NonNull android.os.Bundle);
     method @NonNull public android.media.metrics.PlaybackMetrics.Builder setNetworkBytesRead(@IntRange(from=0xffffffff) long);
     method @NonNull public android.media.metrics.PlaybackMetrics.Builder setNetworkTransferDurationMillis(@IntRange(from=0xffffffff) long);
     method @NonNull public android.media.metrics.PlaybackMetrics.Builder setPlaybackType(int);
@@ -24538,7 +24791,7 @@
 
   public final class PlaybackSession implements java.lang.AutoCloseable {
     method public void close();
-    method @NonNull public String getId();
+    method @NonNull public android.media.metrics.LogSessionId getSessionId();
     method public void reportNetworkEvent(@NonNull android.media.metrics.NetworkEvent);
     method public void reportPlaybackErrorEvent(@NonNull android.media.metrics.PlaybackErrorEvent);
     method public void reportPlaybackMetrics(@NonNull android.media.metrics.PlaybackMetrics);
@@ -24571,13 +24824,19 @@
   public static final class PlaybackStateEvent.Builder {
     ctor public PlaybackStateEvent.Builder();
     method @NonNull public android.media.metrics.PlaybackStateEvent build();
+    method @NonNull public android.media.metrics.PlaybackStateEvent.Builder setMetricsBundle(@NonNull android.os.Bundle);
     method @NonNull public android.media.metrics.PlaybackStateEvent.Builder setState(int);
     method @NonNull public android.media.metrics.PlaybackStateEvent.Builder setTimeSinceCreatedMillis(@IntRange(from=0xffffffff) long);
   }
 
+  public final class RecordingSession implements java.lang.AutoCloseable {
+    method public void close();
+    method @NonNull public android.media.metrics.LogSessionId getSessionId();
+  }
+
   public final class TrackChangeEvent extends android.media.metrics.Event implements android.os.Parcelable {
-    ctor public TrackChangeEvent(int, int, @Nullable String, @Nullable String, @Nullable String, int, long, int, @Nullable String, @Nullable String, int, int, int, int);
     method public int describeContents();
+    method @IntRange(from=0xffffffff, to=java.lang.Integer.MAX_VALUE) public int getAudioSampleRate();
     method @IntRange(from=0xffffffff, to=java.lang.Integer.MAX_VALUE) public int getBitrate();
     method @IntRange(from=0xffffffff, to=java.lang.Integer.MAX_VALUE) public int getChannelCount();
     method @Nullable public String getCodecName();
@@ -24586,10 +24845,10 @@
     method @Nullable public String getLanguage();
     method @Nullable public String getLanguageRegion();
     method @Nullable public String getSampleMimeType();
-    method @IntRange(from=0xffffffff, to=java.lang.Integer.MAX_VALUE) public int getSampleRate();
     method public int getTrackChangeReason();
     method public int getTrackState();
     method public int getTrackType();
+    method @FloatRange(from=0xffffffff, to=java.lang.Float.MAX_VALUE) public float getVideoFrameRate();
     method @IntRange(from=0xffffffff, to=java.lang.Integer.MAX_VALUE) public int getWidth();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.media.metrics.TrackChangeEvent> CREATOR;
@@ -24608,6 +24867,7 @@
   public static final class TrackChangeEvent.Builder {
     ctor public TrackChangeEvent.Builder(int);
     method @NonNull public android.media.metrics.TrackChangeEvent build();
+    method @NonNull public android.media.metrics.TrackChangeEvent.Builder setAudioSampleRate(@IntRange(from=0xffffffff, to=java.lang.Integer.MAX_VALUE) int);
     method @NonNull public android.media.metrics.TrackChangeEvent.Builder setBitrate(@IntRange(from=0xffffffff, to=java.lang.Integer.MAX_VALUE) int);
     method @NonNull public android.media.metrics.TrackChangeEvent.Builder setChannelCount(@IntRange(from=0xffffffff, to=java.lang.Integer.MAX_VALUE) int);
     method @NonNull public android.media.metrics.TrackChangeEvent.Builder setCodecName(@NonNull String);
@@ -24615,11 +24875,12 @@
     method @NonNull public android.media.metrics.TrackChangeEvent.Builder setHeight(@IntRange(from=0xffffffff, to=java.lang.Integer.MAX_VALUE) int);
     method @NonNull public android.media.metrics.TrackChangeEvent.Builder setLanguage(@NonNull String);
     method @NonNull public android.media.metrics.TrackChangeEvent.Builder setLanguageRegion(@NonNull String);
+    method @NonNull public android.media.metrics.TrackChangeEvent.Builder setMetricsBundle(@NonNull android.os.Bundle);
     method @NonNull public android.media.metrics.TrackChangeEvent.Builder setSampleMimeType(@NonNull String);
-    method @NonNull public android.media.metrics.TrackChangeEvent.Builder setSampleRate(@IntRange(from=0xffffffff, to=java.lang.Integer.MAX_VALUE) int);
     method @NonNull public android.media.metrics.TrackChangeEvent.Builder setTimeSinceCreatedMillis(@IntRange(from=0xffffffff) long);
     method @NonNull public android.media.metrics.TrackChangeEvent.Builder setTrackChangeReason(int);
     method @NonNull public android.media.metrics.TrackChangeEvent.Builder setTrackState(int);
+    method @NonNull public android.media.metrics.TrackChangeEvent.Builder setVideoFrameRate(@FloatRange(from=0xffffffff, to=java.lang.Float.MAX_VALUE) float);
     method @NonNull public android.media.metrics.TrackChangeEvent.Builder setWidth(@IntRange(from=0xffffffff, to=java.lang.Integer.MAX_VALUE) int);
   }
 
@@ -26860,7 +27121,7 @@
   public abstract static class VcnManager.VcnStatusCallback {
     ctor public VcnManager.VcnStatusCallback();
     method public abstract void onGatewayConnectionError(@NonNull int[], int, @Nullable Throwable);
-    method public abstract void onVcnStatusChanged(int);
+    method public abstract void onStatusChanged(int);
   }
 
 }
@@ -34784,6 +35045,7 @@
     field public static final String ACTION_APPLICATION_SETTINGS = "android.settings.APPLICATION_SETTINGS";
     field public static final String ACTION_APP_NOTIFICATION_BUBBLE_SETTINGS = "android.settings.APP_NOTIFICATION_BUBBLE_SETTINGS";
     field public static final String ACTION_APP_NOTIFICATION_SETTINGS = "android.settings.APP_NOTIFICATION_SETTINGS";
+    field public static final String ACTION_APP_OPEN_BY_DEFAULT_SETTINGS = "com.android.settings.APP_OPEN_BY_DEFAULT_SETTINGS";
     field public static final String ACTION_APP_SEARCH_SETTINGS = "android.settings.APP_SEARCH_SETTINGS";
     field public static final String ACTION_APP_USAGE_SETTINGS = "android.settings.action.APP_USAGE_SETTINGS";
     field public static final String ACTION_AUTO_ROTATE_SETTINGS = "android.settings.AUTO_ROTATE_SETTINGS";
@@ -34812,7 +35074,7 @@
     field public static final String ACTION_LOCATION_SOURCE_SETTINGS = "android.settings.LOCATION_SOURCE_SETTINGS";
     field public static final String ACTION_MANAGE_ALL_APPLICATIONS_SETTINGS = "android.settings.MANAGE_ALL_APPLICATIONS_SETTINGS";
     field public static final String ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION = "android.settings.MANAGE_ALL_FILES_ACCESS_PERMISSION";
-    field public static final String ACTION_MANAGE_ALL_SUBSCRIPTIONS_SETTINGS = "android.settings.MANAGE_ALL_SUBSCRIPTIONS_SETTINGS";
+    field public static final String ACTION_MANAGE_ALL_SIM_PROFILES_SETTINGS = "android.settings.MANAGE_ALL_SIM_PROFILES_SETTINGS";
     field public static final String ACTION_MANAGE_APPLICATIONS_SETTINGS = "android.settings.MANAGE_APPLICATIONS_SETTINGS";
     field public static final String ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION = "android.settings.MANAGE_APP_ALL_FILES_ACCESS_PERMISSION";
     field public static final String ACTION_MANAGE_DEFAULT_APPS_SETTINGS = "android.settings.MANAGE_DEFAULT_APPS_SETTINGS";
@@ -35443,6 +35705,9 @@
     method public static android.net.Uri getUriForSubscriptionIdAndField(int, String);
     field public static final String AUTHORITY = "service-state";
     field public static final android.net.Uri CONTENT_URI;
+    field public static final String DATA_NETWORK_TYPE = "data_network_type";
+    field public static final String DATA_REG_STATE = "data_reg_state";
+    field public static final String DUPLEX_MODE = "duplex_mode";
     field public static final String IS_MANUAL_NETWORK_SELECTION = "is_manual_network_selection";
     field public static final String VOICE_OPERATOR_NUMERIC = "voice_operator_numeric";
     field public static final String VOICE_REG_STATE = "voice_reg_state";
@@ -37350,6 +37615,7 @@
     method public void onDisconnected();
     method public abstract void onFillRequest(@NonNull android.service.autofill.FillRequest, @NonNull android.os.CancellationSignal, @NonNull android.service.autofill.FillCallback);
     method public abstract void onSaveRequest(@NonNull android.service.autofill.SaveRequest, @NonNull android.service.autofill.SaveCallback);
+    method public void onSavedDatasetsInfoRequest(@NonNull android.service.autofill.SavedDatasetsInfoCallback);
     field public static final String SERVICE_INTERFACE = "android.service.autofill.AutofillService";
     field public static final String SERVICE_META_DATA = "android.autofill";
   }
@@ -37625,6 +37891,22 @@
     field @NonNull public static final android.os.Parcelable.Creator<android.service.autofill.SaveRequest> CREATOR;
   }
 
+  public final class SavedDatasetsInfo {
+    ctor public SavedDatasetsInfo(@NonNull String, @IntRange(from=0) int);
+    method @IntRange(from=0) public int getCount();
+    method @NonNull public String getType();
+    field public static final String TYPE_OTHER = "other";
+    field public static final String TYPE_PASSWORDS = "passwords";
+  }
+
+  public interface SavedDatasetsInfoCallback {
+    method public void onError(int);
+    method public void onSuccess(@NonNull java.util.Set<android.service.autofill.SavedDatasetsInfo>);
+    field public static final int ERROR_NEEDS_USER_ACTION = 2; // 0x2
+    field public static final int ERROR_OTHER = 0; // 0x0
+    field public static final int ERROR_UNSUPPORTED = 1; // 0x1
+  }
+
   public final class TextValueSanitizer implements android.os.Parcelable android.service.autofill.Sanitizer {
     ctor public TextValueSanitizer(@NonNull java.util.regex.Pattern, @NonNull String);
     method public int describeContents();
@@ -38068,6 +38350,25 @@
 
 }
 
+package android.service.dataloader {
+
+  public abstract class DataLoaderService extends android.app.Service {
+    ctor public DataLoaderService();
+    method @NonNull public final android.os.IBinder onBind(@NonNull android.content.Intent);
+    method @Nullable public android.service.dataloader.DataLoaderService.DataLoader onCreateDataLoader(@NonNull android.content.pm.DataLoaderParams);
+  }
+
+  public static interface DataLoaderService.DataLoader {
+    method public boolean onCreate(@NonNull android.content.pm.DataLoaderParams, @NonNull android.service.dataloader.DataLoaderService.FileSystemConnector);
+    method public boolean onPrepareImage(@NonNull java.util.Collection<android.content.pm.InstallationFile>, @NonNull java.util.Collection<java.lang.String>);
+  }
+
+  public static final class DataLoaderService.FileSystemConnector {
+    method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void writeData(@NonNull String, long, long, @NonNull android.os.ParcelFileDescriptor) throws java.io.IOException;
+  }
+
+}
+
 package android.service.dreams {
 
   public class DreamService extends android.app.Service implements android.view.Window.Callback {
@@ -38269,6 +38570,8 @@
     field public static final int REASON_CANCEL = 2; // 0x2
     field public static final int REASON_CANCEL_ALL = 3; // 0x3
     field public static final int REASON_CHANNEL_BANNED = 17; // 0x11
+    field public static final int REASON_CHANNEL_REMOVED = 20; // 0x14
+    field public static final int REASON_CLEAR_DATA = 21; // 0x15
     field public static final int REASON_CLICK = 1; // 0x1
     field public static final int REASON_ERROR = 4; // 0x4
     field public static final int REASON_GROUP_OPTIMIZATION = 13; // 0xd
@@ -38815,6 +39118,7 @@
     method public void bufferReceived(byte[]) throws android.os.RemoteException;
     method public void endOfSpeech() throws android.os.RemoteException;
     method public void error(int) throws android.os.RemoteException;
+    method @NonNull public android.content.AttributionSource getCallingAttributionSource();
     method public int getCallingUid();
     method public void partialResults(android.os.Bundle) throws android.os.RemoteException;
     method public void readyForSpeech(android.os.Bundle) throws android.os.RemoteException;
@@ -39105,7 +39409,7 @@
     method public android.telecom.Call getParent();
     method public String getRemainingPostDialSequence();
     method @Nullable public android.telecom.Call.RttCall getRttCall();
-    method public int getState();
+    method @Deprecated public int getState();
     method public android.telecom.InCallService.VideoCall getVideoCall();
     method public void handoverTo(android.telecom.PhoneAccountHandle, int, android.os.Bundle);
     method public void hold();
@@ -39200,6 +39504,7 @@
     method public android.net.Uri getHandle();
     method public int getHandlePresentation();
     method public android.os.Bundle getIntentExtras();
+    method public final int getState();
     method public android.telecom.StatusHints getStatusHints();
     method public int getVideoState();
     method public static boolean hasProperty(int, int);
@@ -40007,6 +40312,7 @@
     field public static final int DURATION_MEDIUM = 2; // 0x2
     field public static final int DURATION_SHORT = 1; // 0x1
     field public static final int DURATION_VERY_SHORT = 0; // 0x0
+    field public static final long ENABLE_GET_CALL_STATE_PERMISSION_PROTECTION = 157233955L; // 0x95f3323L
     field public static final String EXTRA_CALL_BACK_NUMBER = "android.telecom.extra.CALL_BACK_NUMBER";
     field public static final String EXTRA_CALL_DISCONNECT_CAUSE = "android.telecom.extra.CALL_DISCONNECT_CAUSE";
     field public static final String EXTRA_CALL_DISCONNECT_MESSAGE = "android.telecom.extra.CALL_DISCONNECT_MESSAGE";
@@ -40439,6 +40745,7 @@
     field public static final String KEY_DISABLE_CHARGE_INDICATION_BOOL = "disable_charge_indication_bool";
     field public static final String KEY_DISABLE_SUPPLEMENTARY_SERVICES_IN_AIRPLANE_MODE_BOOL = "disable_supplementary_services_in_airplane_mode_bool";
     field public static final String KEY_DISCONNECT_CAUSE_PLAY_BUSYTONE_INT_ARRAY = "disconnect_cause_play_busytone_int_array";
+    field public static final String KEY_DISPLAY_CALL_STRENGTH_INDICATOR_BOOL = "display_call_strength_indicator_bool";
     field public static final String KEY_DISPLAY_HD_AUDIO_PROPERTY_BOOL = "display_hd_audio_property_bool";
     field public static final String KEY_DROP_VIDEO_CALL_WHEN_ANSWERING_AUDIO_CALL_BOOL = "drop_video_call_when_answering_audio_call_bool";
     field public static final String KEY_DTMF_TYPE_ENABLED_BOOL = "dtmf_type_enabled_bool";
@@ -40463,6 +40770,7 @@
     field public static final String KEY_HIDE_ENHANCED_4G_LTE_BOOL = "hide_enhanced_4g_lte_bool";
     field public static final String KEY_HIDE_IMS_APN_BOOL = "hide_ims_apn_bool";
     field public static final String KEY_HIDE_LTE_PLUS_DATA_ICON_BOOL = "hide_lte_plus_data_icon_bool";
+    field public static final String KEY_HIDE_NO_CALLING_INDICATOR_ON_DATA_NETWORK_BOOL = "hide_no_calling_indicator_on_data_network_bool";
     field public static final String KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL = "hide_preferred_network_type_bool";
     field public static final String KEY_HIDE_PRESET_APN_DETAILS_BOOL = "hide_preset_apn_details_bool";
     field public static final String KEY_HIDE_SIM_LOCK_SETTINGS_BOOL = "hide_sim_lock_settings_bool";
@@ -40628,6 +40936,7 @@
     field public static final String KEY_NON_RCS_CAPABILITIES_CACHE_EXPIRATION_SEC_INT = "ims.non_rcs_capabilities_cache_expiration_sec_int";
     field public static final String KEY_PREFIX = "ims.";
     field public static final String KEY_RCS_BULK_CAPABILITY_EXCHANGE_BOOL = "ims.rcs_bulk_capability_exchange_bool";
+    field public static final String KEY_RCS_FEATURE_TAG_ALLOWED_STRING_ARRAY = "ims.rcs_feature_tag_allowed_string_array";
     field public static final String KEY_WIFI_OFF_DEFERRING_TIME_MILLIS_INT = "ims.wifi_off_deferring_time_millis_int";
   }
 
@@ -41610,7 +41919,7 @@
     method @Deprecated public void onBarringInfoChanged(@NonNull android.telephony.BarringInfo);
     method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public void onCallDisconnectCauseChanged(int, int);
     method @Deprecated public void onCallForwardingIndicatorChanged(boolean);
-    method @Deprecated public void onCallStateChanged(int, String);
+    method @Deprecated @RequiresPermission(value=android.Manifest.permission.READ_PHONE_STATE, conditional=true) public void onCallStateChanged(int, String);
     method @Deprecated public void onCellInfoChanged(java.util.List<android.telephony.CellInfo>);
     method @Deprecated public void onCellLocationChanged(android.telephony.CellLocation);
     method @Deprecated public void onDataActivity(int);
@@ -41944,7 +42253,6 @@
     method public static int[] calculateLength(String, boolean);
     method @Deprecated public static android.telephony.SmsMessage createFromPdu(byte[]);
     method public static android.telephony.SmsMessage createFromPdu(byte[], String);
-    method @Nullable public static android.telephony.SmsMessage createSmsSubmitPdu(@NonNull byte[], boolean);
     method public String getDisplayMessageBody();
     method public String getDisplayOriginatingAddress();
     method public String getEmailBody();
@@ -42045,7 +42353,8 @@
     method public static int getDefaultSmsSubscriptionId();
     method public static int getDefaultSubscriptionId();
     method public static int getDefaultVoiceSubscriptionId();
-    method public int getDeviceToDeviceStatusSharing(int);
+    method @NonNull public java.util.List<android.net.Uri> getDeviceToDeviceStatusSharingContacts(int);
+    method public int getDeviceToDeviceStatusSharingPreference(int);
     method @NonNull @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public java.util.List<android.telephony.SubscriptionInfo> getOpportunisticSubscriptions();
     method public static int getSlotIndex(int);
     method @Nullable public int[] getSubscriptionIds(int);
@@ -42058,7 +42367,8 @@
     method public void removeOnOpportunisticSubscriptionsChangedListener(@NonNull android.telephony.SubscriptionManager.OnOpportunisticSubscriptionsChangedListener);
     method public void removeOnSubscriptionsChangedListener(android.telephony.SubscriptionManager.OnSubscriptionsChangedListener);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void removeSubscriptionsFromGroup(@NonNull java.util.List<java.lang.Integer>, @NonNull android.os.ParcelUuid);
-    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDeviceToDeviceStatusSharing(int, int);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDeviceToDeviceStatusSharingContacts(@NonNull java.util.List<android.net.Uri>, int);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDeviceToDeviceStatusSharingPreference(int, int);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setOpportunistic(boolean, int);
     method public void setSubscriptionOverrideCongested(int, boolean, long);
     method public void setSubscriptionOverrideCongested(int, boolean, @NonNull int[], long);
@@ -42073,8 +42383,9 @@
     field public static final int D2D_SHARING_ALL = 3; // 0x3
     field public static final int D2D_SHARING_ALL_CONTACTS = 1; // 0x1
     field public static final int D2D_SHARING_DISABLED = 0; // 0x0
-    field public static final int D2D_SHARING_STARRED_CONTACTS = 2; // 0x2
+    field public static final int D2D_SHARING_SELECTED_CONTACTS = 2; // 0x2
     field public static final String D2D_STATUS_SHARING = "d2d_sharing_status";
+    field public static final String D2D_STATUS_SHARING_SELECTED_CONTACTS = "d2d_sharing_contacts";
     field public static final int DATA_ROAMING_DISABLE = 0; // 0x0
     field public static final int DATA_ROAMING_ENABLE = 1; // 0x1
     field public static final int DEFAULT_SUBSCRIPTION_ID = 2147483647; // 0x7fffffff
@@ -42154,7 +42465,7 @@
   }
 
   public static interface TelephonyCallback.CallStateListener {
-    method public void onCallStateChanged(int);
+    method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public void onCallStateChanged(int);
   }
 
   public static interface TelephonyCallback.CarrierNetworkListener {
@@ -42182,7 +42493,7 @@
   }
 
   public static interface TelephonyCallback.DisplayInfoListener {
-    method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public void onDisplayInfoChanged(@NonNull android.telephony.TelephonyDisplayInfo);
+    method public void onDisplayInfoChanged(@NonNull android.telephony.TelephonyDisplayInfo);
   }
 
   public static interface TelephonyCallback.EmergencyNumberListListener {
@@ -42230,7 +42541,7 @@
     field public static final int OVERRIDE_NETWORK_TYPE_LTE_ADVANCED_PRO = 2; // 0x2
     field public static final int OVERRIDE_NETWORK_TYPE_LTE_CA = 1; // 0x1
     field public static final int OVERRIDE_NETWORK_TYPE_NONE = 0; // 0x0
-    field public static final int OVERRIDE_NETWORK_TYPE_NR_ADVANCED = 4; // 0x4
+    field public static final int OVERRIDE_NETWORK_TYPE_NR_ADVANCED = 5; // 0x5
     field public static final int OVERRIDE_NETWORK_TYPE_NR_NSA = 3; // 0x3
     field @Deprecated public static final int OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE = 4; // 0x4
   }
@@ -42244,7 +42555,8 @@
     method public int getActiveModemCount();
     method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public java.util.List<android.telephony.CellInfo> getAllCellInfo();
     method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public int getCallComposerStatus();
-    method public int getCallState();
+    method @Deprecated @RequiresPermission(value=android.Manifest.permission.READ_PHONE_STATE, conditional=true) public int getCallState();
+    method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public int getCallStateForSubscription();
     method public int getCardIdForDefaultEuicc();
     method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) @WorkerThread public android.os.PersistableBundle getCarrierConfig();
     method public int getCarrierIdFromSimMccMnc();
@@ -42278,8 +42590,10 @@
     method public String getNetworkOperator();
     method public String getNetworkOperatorName();
     method @RequiresPermission(anyOf={"android.permission.READ_PRIVILEGED_PHONE_STATE", android.Manifest.permission.READ_PRECISE_PHONE_STATE}) public int getNetworkSelectionMode();
+    method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void getNetworkSlicingConfiguration(@NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<android.telephony.data.SlicingConfig,android.telephony.TelephonyManager.SlicingException>);
     method public String getNetworkSpecifier();
     method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public int getNetworkType();
+    method @Nullable @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public android.telecom.PhoneAccountHandle getPhoneAccountHandle();
     method @Deprecated public int getPhoneCount();
     method public int getPhoneType();
     method @RequiresPermission(anyOf={"android.permission.READ_PRIVILEGED_PHONE_STATE", android.Manifest.permission.READ_PHONE_STATE}) public int getPreferredOpportunisticDataSubscription();
@@ -42316,6 +42630,7 @@
     method @Deprecated public String iccTransmitApduBasicChannel(int, int, int, int, int, String);
     method @Deprecated public String iccTransmitApduLogicalChannel(int, int, int, int, int, int, String);
     method public boolean isConcurrentVoiceAndDataSupported();
+    method public boolean isDataCapable();
     method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_NETWORK_STATE, android.Manifest.permission.READ_PHONE_STATE, "android.permission.READ_PRIVILEGED_PHONE_STATE"}) public boolean isDataConnectionAllowed();
     method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_NETWORK_STATE, android.Manifest.permission.MODIFY_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isDataEnabled();
     method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_NETWORK_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isDataEnabledForReason(int);
@@ -42389,6 +42704,7 @@
     field public static final int CALL_STATE_IDLE = 0; // 0x0
     field public static final int CALL_STATE_OFFHOOK = 2; // 0x2
     field public static final int CALL_STATE_RINGING = 1; // 0x1
+    field public static final String CAPABILITY_SLICING_CONFIG_SUPPORTED = "CAPABILITY_SLICING_CONFIG_SUPPORTED";
     field public static final int CDMA_ROAMING_MODE_AFFILIATED = 1; // 0x1
     field public static final int CDMA_ROAMING_MODE_ANY = 2; // 0x2
     field public static final int CDMA_ROAMING_MODE_HOME = 0; // 0x0
@@ -42524,6 +42840,13 @@
     field public static final int ERROR_TIMEOUT = 1; // 0x1
   }
 
+  public static class TelephonyManager.SlicingException extends java.lang.Exception {
+    ctor public TelephonyManager.SlicingException(int);
+    method public int getErrorCode();
+    field public static final int ERROR_MODEM_ERROR = 2; // 0x2
+    field public static final int ERROR_TIMEOUT = 1; // 0x1
+  }
+
   public abstract static class TelephonyManager.UssdResponseCallback {
     ctor public TelephonyManager.UssdResponseCallback();
     method public void onReceiveUssdResponse(android.telephony.TelephonyManager, String, CharSequence);
@@ -42658,6 +42981,7 @@
     field public static final int PROTOCOL_NON_IP = 4; // 0x4
     field public static final int PROTOCOL_PPP = 3; // 0x3
     field public static final int PROTOCOL_UNSTRUCTURED = 5; // 0x5
+    field public static final int TYPE_BIP = 8192; // 0x2000
     field public static final int TYPE_CBS = 128; // 0x80
     field public static final int TYPE_DEFAULT = 17; // 0x11
     field public static final int TYPE_DUN = 8; // 0x8
@@ -42669,6 +42993,7 @@
     field public static final int TYPE_MCX = 1024; // 0x400
     field public static final int TYPE_MMS = 2; // 0x2
     field public static final int TYPE_SUPL = 4; // 0x4
+    field public static final int TYPE_VSIM = 4096; // 0x1000
     field public static final int TYPE_XCAP = 2048; // 0x800
   }
 
@@ -42697,6 +43022,88 @@
     method @NonNull public android.telephony.data.ApnSetting.Builder setUser(@Nullable String);
   }
 
+  public final class NetworkSliceInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method @IntRange(from=0xffffffff, to=0xfffffe) public int getMappedHplmnSliceDifferentiator();
+    method public int getMappedHplmnSliceServiceType();
+    method @IntRange(from=0xffffffff, to=0xfffffe) public int getSliceDifferentiator();
+    method public int getSliceServiceType();
+    method public int getStatus();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.data.NetworkSliceInfo> CREATOR;
+    field public static final int SLICE_DIFFERENTIATOR_NO_SLICE = -1; // 0xffffffff
+    field public static final int SLICE_SERVICE_TYPE_EMBB = 1; // 0x1
+    field public static final int SLICE_SERVICE_TYPE_MIOT = 3; // 0x3
+    field public static final int SLICE_SERVICE_TYPE_NONE = 0; // 0x0
+    field public static final int SLICE_SERVICE_TYPE_URLLC = 2; // 0x2
+    field public static final int SLICE_STATUS_ALLOWED = 2; // 0x2
+    field public static final int SLICE_STATUS_CONFIGURED = 1; // 0x1
+    field public static final int SLICE_STATUS_DEFAULT_CONFIGURED = 5; // 0x5
+    field public static final int SLICE_STATUS_REJECTED_NOT_AVAILABLE_IN_PLMN = 3; // 0x3
+    field public static final int SLICE_STATUS_REJECTED_NOT_AVAILABLE_IN_REGISTERED_AREA = 4; // 0x4
+    field public static final int SLICE_STATUS_UNKNOWN = 0; // 0x0
+  }
+
+  public static final class NetworkSliceInfo.Builder {
+    ctor public NetworkSliceInfo.Builder();
+    method @NonNull public android.telephony.data.NetworkSliceInfo build();
+    method @NonNull public android.telephony.data.NetworkSliceInfo.Builder setMappedHplmnSliceDifferentiator(@IntRange(from=0xffffffff, to=0xfffffe) int);
+    method @NonNull public android.telephony.data.NetworkSliceInfo.Builder setMappedHplmnSliceServiceType(int);
+    method @NonNull public android.telephony.data.NetworkSliceInfo.Builder setSliceDifferentiator(@IntRange(from=0xffffffff, to=0xfffffe) int);
+    method @NonNull public android.telephony.data.NetworkSliceInfo.Builder setSliceServiceType(int);
+    method @NonNull public android.telephony.data.NetworkSliceInfo.Builder setStatus(int);
+  }
+
+  public final class RouteSelectionDescriptor implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public java.util.List<java.lang.String> getDataNetworkName();
+    method @IntRange(from=0x0, to=0xff) public int getPrecedence();
+    method public int getSessionType();
+    method @NonNull public java.util.List<android.telephony.data.NetworkSliceInfo> getSliceInfo();
+    method public int getSscMode();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.data.RouteSelectionDescriptor> CREATOR;
+    field public static final int ROUTE_SSC_MODE_1 = 1; // 0x1
+    field public static final int ROUTE_SSC_MODE_2 = 2; // 0x2
+    field public static final int ROUTE_SSC_MODE_3 = 3; // 0x3
+    field public static final int SESSION_TYPE_IPV4 = 0; // 0x0
+    field public static final int SESSION_TYPE_IPV4V6 = 2; // 0x2
+    field public static final int SESSION_TYPE_IPV6 = 1; // 0x1
+  }
+
+  public final class SlicingConfig implements android.os.Parcelable {
+    ctor public SlicingConfig();
+    method public int describeContents();
+    method @NonNull public java.util.List<android.telephony.data.NetworkSliceInfo> getSliceInfo();
+    method @NonNull public java.util.List<android.telephony.data.UrspRule> getUrspRules();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.data.SlicingConfig> CREATOR;
+  }
+
+  public final class TrafficDescriptor implements android.os.Parcelable {
+    method public int describeContents();
+    method @Nullable public String getDataNetworkName();
+    method @Nullable public String getOsAppId();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.data.TrafficDescriptor> CREATOR;
+  }
+
+  public static final class TrafficDescriptor.Builder {
+    ctor public TrafficDescriptor.Builder();
+    method @NonNull public android.telephony.data.TrafficDescriptor build();
+    method @NonNull public android.telephony.data.TrafficDescriptor.Builder setDataNetworkName(@NonNull String);
+    method @NonNull public android.telephony.data.TrafficDescriptor.Builder setOsAppId(@NonNull String);
+  }
+
+  public final class UrspRule implements android.os.Parcelable {
+    method public int describeContents();
+    method @IntRange(from=0x0, to=0xff) public int getPrecedence();
+    method @NonNull public java.util.List<android.telephony.data.RouteSelectionDescriptor> getRouteSelectionDescriptor();
+    method @NonNull public java.util.List<android.telephony.data.TrafficDescriptor> getTrafficDescriptors();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.data.UrspRule> CREATOR;
+  }
+
 }
 
 package android.telephony.emergency {
@@ -47889,6 +48296,7 @@
   }
 
   public static final class SurfaceControlViewHost.SurfacePackage implements android.os.Parcelable {
+    ctor public SurfaceControlViewHost.SurfacePackage(@NonNull android.view.SurfaceControlViewHost.SurfacePackage);
     method public int describeContents();
     method public void release();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
@@ -48107,6 +48515,7 @@
     method public boolean dispatchPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent);
     method public void dispatchProvideAutofillStructure(@NonNull android.view.ViewStructure, int);
     method public void dispatchProvideStructure(android.view.ViewStructure);
+    method public void dispatchRequestTranslation(@NonNull java.util.Map<android.view.autofill.AutofillId,long[]>, @NonNull int[], @Nullable android.view.translation.TranslationCapability, @NonNull java.util.List<android.view.translation.ViewTranslationRequest>);
     method protected void dispatchRestoreInstanceState(android.util.SparseArray<android.os.Parcelable>);
     method protected void dispatchSaveInstanceState(android.util.SparseArray<android.os.Parcelable>);
     method public void dispatchScrollCaptureSearch(@NonNull android.graphics.Rect, @NonNull android.graphics.Point, @NonNull java.util.function.Consumer<android.view.ScrollCaptureTarget>);
@@ -48302,6 +48711,7 @@
     method @Nullable public android.graphics.drawable.Drawable getVerticalScrollbarThumbDrawable();
     method @Nullable public android.graphics.drawable.Drawable getVerticalScrollbarTrackDrawable();
     method public int getVerticalScrollbarWidth();
+    method @Nullable public android.view.translation.ViewTranslationCallback getViewTranslationCallback();
     method public android.view.ViewTreeObserver getViewTreeObserver();
     method public int getVisibility();
     method public final int getWidth();
@@ -48401,6 +48811,8 @@
     method protected void onCreateContextMenu(android.view.ContextMenu);
     method protected int[] onCreateDrawableState(int);
     method public android.view.inputmethod.InputConnection onCreateInputConnection(android.view.inputmethod.EditorInfo);
+    method @Nullable public android.view.translation.ViewTranslationRequest onCreateTranslationRequest(@NonNull int[]);
+    method public void onCreateTranslationRequests(@NonNull long[], @NonNull int[], @NonNull java.util.function.Consumer<android.view.translation.ViewTranslationRequest>);
     method @CallSuper protected void onDetachedFromWindow();
     method protected void onDisplayHint(int);
     method public boolean onDragEvent(android.view.DragEvent);
@@ -48445,6 +48857,8 @@
     method public void onStartTemporaryDetach();
     method public boolean onTouchEvent(android.view.MotionEvent);
     method public boolean onTrackballEvent(android.view.MotionEvent);
+    method public void onTranslationResponse(@NonNull android.view.translation.ViewTranslationResponse);
+    method public void onTranslationResponse(@NonNull android.util.LongSparseArray<android.view.translation.ViewTranslationResponse>);
     method @CallSuper public void onVisibilityAggregated(boolean);
     method protected void onVisibilityChanged(@NonNull android.view.View, int);
     method public void onWindowFocusChanged(boolean);
@@ -48653,6 +49067,7 @@
     method public void setVerticalScrollbarPosition(int);
     method public void setVerticalScrollbarThumbDrawable(@Nullable android.graphics.drawable.Drawable);
     method public void setVerticalScrollbarTrackDrawable(@Nullable android.graphics.drawable.Drawable);
+    method public void setViewTranslationCallback(@NonNull android.view.translation.ViewTranslationCallback);
     method public void setVisibility(int);
     method @Deprecated public void setWillNotCacheDrawing(boolean);
     method public void setWillNotDraw(boolean);
@@ -51135,6 +51550,7 @@
     field public static final int DISPLAY_HASH_ERROR_INVALID_HASH_ALGORITHM = -5; // 0xfffffffb
     field public static final int DISPLAY_HASH_ERROR_MISSING_WINDOW = -3; // 0xfffffffd
     field public static final int DISPLAY_HASH_ERROR_NOT_VISIBLE_ON_SCREEN = -4; // 0xfffffffc
+    field public static final int DISPLAY_HASH_ERROR_TOO_MANY_REQUESTS = -6; // 0xfffffffa
     field public static final int DISPLAY_HASH_ERROR_UNKNOWN = -1; // 0xffffffff
   }
 
@@ -52332,9 +52748,49 @@
 
 package android.view.translation {
 
+  public final class TranslationCapability implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public android.view.translation.TranslationSpec getSourceSpec();
+    method public int getState();
+    method public int getSupportedTranslationFlags();
+    method @NonNull public android.view.translation.TranslationSpec getTargetSpec();
+    method public boolean isUiTranslationEnabled();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.view.translation.TranslationCapability> CREATOR;
+    field public static final int STATE_AVAILABLE_TO_DOWNLOAD = 1; // 0x1
+    field public static final int STATE_DOWNLOADING = 2; // 0x2
+    field public static final int STATE_ON_DEVICE = 3; // 0x3
+  }
+
+  public final class TranslationContext implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public android.view.translation.TranslationSpec getSourceSpec();
+    method @NonNull public android.view.translation.TranslationSpec getTargetSpec();
+    method public int getTranslationFlags();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.view.translation.TranslationContext> CREATOR;
+    field public static final int FLAG_DICTIONARY_DESCRIPTION = 4; // 0x4
+    field public static final int FLAG_LOW_LATENCY = 1; // 0x1
+    field public static final int FLAG_TRANSLITERATION = 2; // 0x2
+  }
+
+  public static final class TranslationContext.Builder {
+    ctor public TranslationContext.Builder(@NonNull android.view.translation.TranslationSpec, @NonNull android.view.translation.TranslationSpec);
+    method @NonNull public android.view.translation.TranslationContext build();
+    method @NonNull public android.view.translation.TranslationContext.Builder setTranslationFlags(int);
+  }
+
   public final class TranslationManager {
-    method @Nullable @WorkerThread public android.view.translation.Translator createTranslator(@NonNull android.view.translation.TranslationSpec, @NonNull android.view.translation.TranslationSpec);
-    method @NonNull @WorkerThread public java.util.List<java.lang.String> getSupportedLocales();
+    method public void addOnDeviceTranslationCapabilityUpdateListener(int, int, @NonNull android.app.PendingIntent);
+    method @Deprecated public void addTranslationCapabilityUpdateListener(int, int, @NonNull android.app.PendingIntent);
+    method @Nullable @WorkerThread public android.view.translation.Translator createOnDeviceTranslator(@NonNull android.view.translation.TranslationContext);
+    method @Deprecated @Nullable @WorkerThread public android.view.translation.Translator createTranslator(@NonNull android.view.translation.TranslationContext);
+    method @NonNull @WorkerThread public java.util.Set<android.view.translation.TranslationCapability> getOnDeviceTranslationCapabilities(int, int);
+    method @Nullable public android.app.PendingIntent getOnDeviceTranslationSettingsActivityIntent();
+    method @Deprecated @NonNull @WorkerThread public java.util.Set<android.view.translation.TranslationCapability> getTranslationCapabilities(int, int);
+    method @Deprecated @Nullable public android.app.PendingIntent getTranslationSettingsActivityIntent();
+    method public void removeOnDeviceTranslationCapabilityUpdateListener(int, int, @NonNull android.app.PendingIntent);
+    method @Deprecated public void removeTranslationCapabilityUpdateListener(int, int, @NonNull android.app.PendingIntent);
   }
 
   public final class TranslationRequest implements android.os.Parcelable {
@@ -52373,6 +52829,7 @@
     method @NonNull public android.util.SparseArray<android.view.translation.TranslationResponseValue> getTranslationResponseValues();
     method public int getTranslationStatus();
     method @NonNull public android.util.SparseArray<android.view.translation.ViewTranslationResponse> getViewTranslationResponses();
+    method public boolean isFinalResponse();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.view.translation.TranslationResponse> CREATOR;
     field public static final int TRANSLATION_STATUS_CONTEXT_UNSUPPORTED = 2; // 0x2
@@ -52383,6 +52840,7 @@
   public static final class TranslationResponse.Builder {
     ctor public TranslationResponse.Builder(int);
     method @NonNull public android.view.translation.TranslationResponse build();
+    method @NonNull public android.view.translation.TranslationResponse.Builder setFinalResponse(boolean);
     method @NonNull public android.view.translation.TranslationResponse.Builder setTranslationResponseValue(int, @NonNull android.view.translation.TranslationResponseValue);
     method @NonNull public android.view.translation.TranslationResponse.Builder setTranslationResponseValues(@NonNull android.util.SparseArray<android.view.translation.TranslationResponseValue>);
     method @NonNull public android.view.translation.TranslationResponse.Builder setTranslationStatus(int);
@@ -52424,7 +52882,7 @@
   public class Translator {
     method public void destroy();
     method public boolean isDestroyed();
-    method @Nullable @WorkerThread public android.view.translation.TranslationResponse translate(@NonNull android.view.translation.TranslationRequest);
+    method @Nullable public void translate(@NonNull android.view.translation.TranslationRequest, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.view.translation.TranslationResponse>);
   }
 
   public final class UiTranslationManager {
@@ -52438,6 +52896,12 @@
     method public void onStarted(@NonNull String, @NonNull String);
   }
 
+  @UiThread public interface ViewTranslationCallback {
+    method public boolean onClearTranslation(@NonNull android.view.View);
+    method public boolean onHideTranslation(@NonNull android.view.View);
+    method public boolean onShowTranslation(@NonNull android.view.View);
+  }
+
   public final class ViewTranslationRequest implements android.os.Parcelable {
     method public int describeContents();
     method @NonNull public android.view.autofill.AutofillId getAutofillId();
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index e3b7c88..4fb9926 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -196,19 +196,10 @@
     method @NonNull public static String blockedReasonsToString(int);
     method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public int getMultipathPreference(@NonNull android.net.Network);
     method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public int getRestrictBackgroundStatus(int);
-    method public static boolean isUidBlocked(int, boolean);
     method @RequiresPermission(android.Manifest.permission.OBSERVE_NETWORK_POLICY) public boolean isUidNetworkingBlocked(int, boolean);
     method @RequiresPermission(android.Manifest.permission.OBSERVE_NETWORK_POLICY) public boolean isUidRestrictedOnMeteredNetworks(int);
     method @RequiresPermission(android.Manifest.permission.OBSERVE_NETWORK_POLICY) public void registerNetworkPolicyCallback(@Nullable java.util.concurrent.Executor, @NonNull android.net.NetworkPolicyManager.NetworkPolicyCallback);
     method @RequiresPermission(android.Manifest.permission.OBSERVE_NETWORK_POLICY) public void unregisterNetworkPolicyCallback(@NonNull android.net.NetworkPolicyManager.NetworkPolicyCallback);
-    field public static final int BLOCKED_METERED_REASON_ADMIN_DISABLED = 262144; // 0x40000
-    field public static final int BLOCKED_METERED_REASON_DATA_SAVER = 65536; // 0x10000
-    field public static final int BLOCKED_METERED_REASON_USER_RESTRICTED = 131072; // 0x20000
-    field public static final int BLOCKED_REASON_APP_STANDBY = 4; // 0x4
-    field public static final int BLOCKED_REASON_BATTERY_SAVER = 1; // 0x1
-    field public static final int BLOCKED_REASON_DOZE = 2; // 0x2
-    field public static final int BLOCKED_REASON_NONE = 0; // 0x0
-    field public static final int BLOCKED_REASON_RESTRICTED_MODE = 8; // 0x8
   }
 
   public static interface NetworkPolicyManager.NetworkPolicyCallback {
@@ -309,7 +300,12 @@
   public class StorageManager {
     method public void notifyAppIoBlocked(@NonNull java.util.UUID, int, int, int);
     method public void notifyAppIoResumed(@NonNull java.util.UUID, int, int, int);
-    field public static final int APP_IO_BLOCKED_REASON_TRANSCODING = 0; // 0x0
+    field public static final int APP_IO_BLOCKED_REASON_TRANSCODING = 1; // 0x1
+    field public static final int APP_IO_BLOCKED_REASON_UNKNOWN = 0; // 0x0
+  }
+
+  public final class StorageVolume implements android.os.Parcelable {
+    method @NonNull public android.os.UserHandle getOwner();
   }
 
 }
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 8237f12..d0f9094 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -3,6 +3,7 @@
 
   public static final class Manifest.permission {
     field public static final String ACCESS_AMBIENT_LIGHT_STATS = "android.permission.ACCESS_AMBIENT_LIGHT_STATS";
+    field public static final String ACCESS_BLOBS_ACROSS_USERS = "android.permission.ACCESS_BLOBS_ACROSS_USERS";
     field public static final String ACCESS_BROADCAST_RADIO = "android.permission.ACCESS_BROADCAST_RADIO";
     field public static final String ACCESS_CACHE_FILESYSTEM = "android.permission.ACCESS_CACHE_FILESYSTEM";
     field public static final String ACCESS_CONTEXT_HUB = "android.permission.ACCESS_CONTEXT_HUB";
@@ -65,6 +66,7 @@
     field public static final String BIND_TV_REMOTE_SERVICE = "android.permission.BIND_TV_REMOTE_SERVICE";
     field public static final String BRICK = "android.permission.BRICK";
     field public static final String BRIGHTNESS_SLIDER_USAGE = "android.permission.BRIGHTNESS_SLIDER_USAGE";
+    field public static final String BROADCAST_CLOSE_SYSTEM_DIALOGS = "android.permission.BROADCAST_CLOSE_SYSTEM_DIALOGS";
     field @Deprecated public static final String BROADCAST_NETWORK_PRIVILEGED = "android.permission.BROADCAST_NETWORK_PRIVILEGED";
     field public static final String CAMERA_DISABLE_TRANSMIT_LED = "android.permission.CAMERA_DISABLE_TRANSMIT_LED";
     field public static final String CAMERA_OPEN_CLOSE_LISTENER = "android.permission.CAMERA_OPEN_CLOSE_LISTENER";
@@ -91,6 +93,7 @@
     field public static final String CREATE_USERS = "android.permission.CREATE_USERS";
     field public static final String CRYPT_KEEPER = "android.permission.CRYPT_KEEPER";
     field public static final String DEVICE_POWER = "android.permission.DEVICE_POWER";
+    field public static final String DISABLE_SYSTEM_SOUND_EFFECTS = "android.permission.DISABLE_SYSTEM_SOUND_EFFECTS";
     field public static final String DISPATCH_PROVISIONING_MESSAGE = "android.permission.DISPATCH_PROVISIONING_MESSAGE";
     field public static final String DOMAIN_VERIFICATION_AGENT = "android.permission.DOMAIN_VERIFICATION_AGENT";
     field public static final String ENTER_CAR_MODE_PRIORITIZED = "android.permission.ENTER_CAR_MODE_PRIORITIZED";
@@ -177,6 +180,7 @@
     field public static final String NETWORK_SIGNAL_STRENGTH_WAKEUP = "android.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP";
     field public static final String NETWORK_STACK = "android.permission.NETWORK_STACK";
     field public static final String NETWORK_STATS_PROVIDER = "android.permission.NETWORK_STATS_PROVIDER";
+    field public static final String NFC_SET_CONTROLLER_ALWAYS_ON = "android.permission.NFC_SET_CONTROLLER_ALWAYS_ON";
     field public static final String NOTIFICATION_DURING_SETUP = "android.permission.NOTIFICATION_DURING_SETUP";
     field public static final String NOTIFY_TV_INPUTS = "android.permission.NOTIFY_TV_INPUTS";
     field public static final String OBSERVE_APP_USAGE = "android.permission.OBSERVE_APP_USAGE";
@@ -184,6 +188,7 @@
     field public static final String OBSERVE_ROLE_HOLDERS = "android.permission.OBSERVE_ROLE_HOLDERS";
     field public static final String OBSERVE_SENSOR_PRIVACY = "android.permission.OBSERVE_SENSOR_PRIVACY";
     field public static final String OPEN_ACCESSIBILITY_DETAILS_SETTINGS = "android.permission.OPEN_ACCESSIBILITY_DETAILS_SETTINGS";
+    field public static final String OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD = "android.permission.OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD";
     field public static final String OVERRIDE_WIFI_CONFIG = "android.permission.OVERRIDE_WIFI_CONFIG";
     field public static final String PACKAGE_VERIFICATION_AGENT = "android.permission.PACKAGE_VERIFICATION_AGENT";
     field public static final String PACKET_KEEPALIVE_OFFLOAD = "android.permission.PACKET_KEEPALIVE_OFFLOAD";
@@ -241,6 +246,7 @@
     field public static final String REVIEW_ACCESSIBILITY_SERVICES = "android.permission.REVIEW_ACCESSIBILITY_SERVICES";
     field public static final String REVOKE_RUNTIME_PERMISSIONS = "android.permission.REVOKE_RUNTIME_PERMISSIONS";
     field public static final String ROTATE_SURFACE_FLINGER = "android.permission.ROTATE_SURFACE_FLINGER";
+    field public static final String SCHEDULE_PRIORITIZED_ALARM = "android.permission.SCHEDULE_PRIORITIZED_ALARM";
     field public static final String SCORE_NETWORKS = "android.permission.SCORE_NETWORKS";
     field public static final String SECURE_ELEMENT_PRIVILEGED_OPERATION = "android.permission.SECURE_ELEMENT_PRIVILEGED_OPERATION";
     field public static final String SEND_CATEGORY_CAR_NOTIFICATIONS = "android.permission.SEND_CATEGORY_CAR_NOTIFICATIONS";
@@ -266,6 +272,7 @@
     field public static final String STOP_APP_SWITCHES = "android.permission.STOP_APP_SWITCHES";
     field public static final String SUBSTITUTE_NOTIFICATION_APP_NAME = "android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME";
     field public static final String SUBSTITUTE_SHARE_TARGET_APP_NAME_AND_ICON = "android.permission.SUBSTITUTE_SHARE_TARGET_APP_NAME_AND_ICON";
+    field public static final String SUGGEST_EXTERNAL_TIME = "android.permission.SUGGEST_EXTERNAL_TIME";
     field public static final String SUSPEND_APPS = "android.permission.SUSPEND_APPS";
     field public static final String SYSTEM_APPLICATION_OVERLAY = "android.permission.SYSTEM_APPLICATION_OVERLAY";
     field public static final String SYSTEM_CAMERA = "android.permission.SYSTEM_CAMERA";
@@ -309,10 +316,12 @@
     field public static final int hotwordDetectionService = 16844326; // 0x1010626
     field public static final int isVrOnly = 16844152; // 0x1010578
     field public static final int minExtensionVersion = 16844305; // 0x1010611
+    field public static final int playHomeTransitionSound = 16844358; // 0x1010646
     field public static final int requiredSystemPropertyName = 16844133; // 0x1010565
     field public static final int requiredSystemPropertyValue = 16844134; // 0x1010566
     field public static final int sdkVersion = 16844304; // 0x1010610
     field public static final int supportsAmbientMode = 16844173; // 0x101058d
+    field public static final int throttleDurationMillis = 16844360; // 0x1010648
     field public static final int userRestriction = 16844164; // 0x1010584
   }
 
@@ -418,6 +427,7 @@
   public class AlarmManager {
     method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void set(int, long, long, long, android.app.PendingIntent, android.os.WorkSource);
     method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void set(int, long, long, long, android.app.AlarmManager.OnAlarmListener, android.os.Handler, android.os.WorkSource);
+    method @RequiresPermission(android.Manifest.permission.SCHEDULE_PRIORITIZED_ALARM) public void setPrioritized(int, long, long, @NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.app.AlarmManager.OnAlarmListener);
   }
 
   public class AppOpsManager {
@@ -588,7 +598,7 @@
 
   public static final class AppOpsManager.HistoricalPackageOps implements android.os.Parcelable {
     method public int describeContents();
-    method @Nullable public android.app.AppOpsManager.AttributedHistoricalOps getAttributedOps(@NonNull String);
+    method @Nullable public android.app.AppOpsManager.AttributedHistoricalOps getAttributedOps(@Nullable String);
     method @NonNull public android.app.AppOpsManager.AttributedHistoricalOps getAttributedOpsAt(@IntRange(from=0) int);
     method @IntRange(from=0) public int getAttributedOpsCount();
     method @Nullable public android.app.AppOpsManager.HistoricalOp getOp(@NonNull String);
@@ -698,6 +708,9 @@
     method @RequiresPermission(android.Manifest.permission.SHOW_KEYGUARD_MESSAGE) public void requestDismissKeyguard(@NonNull android.app.Activity, @Nullable CharSequence, @Nullable android.app.KeyguardManager.KeyguardDismissCallback);
     method @RequiresPermission("android.permission.SET_INITIAL_LOCK") public boolean setLock(int, @NonNull byte[], int);
     method @RequiresPermission(android.Manifest.permission.CONTROL_KEYGUARD_SECURE_NOTIFICATIONS) public void setPrivateNotificationsAllowed(boolean);
+    field public static final int PASSWORD = 0; // 0x0
+    field public static final int PATTERN = 2; // 0x2
+    field public static final int PIN = 1; // 0x1
   }
 
   public class Notification implements android.os.Parcelable {
@@ -944,6 +957,9 @@
     field @Deprecated public static final int PROVISIONING_TRIGGER_PERSISTENT_DEVICE_OWNER = 3; // 0x3
     field public static final int PROVISIONING_TRIGGER_QR_CODE = 2; // 0x2
     field public static final int PROVISIONING_TRIGGER_UNSPECIFIED = 0; // 0x0
+    field public static final String REQUIRED_APP_MANAGED_DEVICE = "android.app.REQUIRED_APP_MANAGED_DEVICE";
+    field public static final String REQUIRED_APP_MANAGED_PROFILE = "android.app.REQUIRED_APP_MANAGED_PROFILE";
+    field public static final String REQUIRED_APP_MANAGED_USER = "android.app.REQUIRED_APP_MANAGED_USER";
     field public static final int STATE_USER_PROFILE_COMPLETE = 4; // 0x4
     field public static final int STATE_USER_PROFILE_FINALIZED = 5; // 0x5
     field public static final int STATE_USER_SETUP_COMPLETE = 2; // 0x2
@@ -1191,12 +1207,14 @@
 
   public class RestoreSet implements android.os.Parcelable {
     ctor public RestoreSet();
-    ctor public RestoreSet(String, String, long);
+    ctor public RestoreSet(@Nullable String, @Nullable String, long);
+    ctor public RestoreSet(@Nullable String, @Nullable String, long, int);
     method public int describeContents();
     method public void writeToParcel(android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.app.backup.RestoreSet> CREATOR;
-    field public String device;
-    field public String name;
+    field public final int backupTransportFlags;
+    field @Nullable public String device;
+    field @Nullable public String name;
     field public long token;
   }
 
@@ -1214,6 +1232,21 @@
     method public static boolean isChangeEnabled(long);
     method @RequiresPermission(allOf={"android.permission.READ_COMPAT_CHANGE_CONFIG", "android.permission.LOG_COMPAT_CHANGE"}) public static boolean isChangeEnabled(long, @NonNull String, @NonNull android.os.UserHandle);
     method @RequiresPermission(allOf={"android.permission.READ_COMPAT_CHANGE_CONFIG", "android.permission.LOG_COMPAT_CHANGE"}) public static boolean isChangeEnabled(long, int);
+    method @RequiresPermission(android.Manifest.permission.OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD) public static void setPackageOverride(@NonNull String, @NonNull java.util.Map<java.lang.Long,android.app.compat.PackageOverride>);
+  }
+
+  public final class PackageOverride {
+    method public long getMaxVersionCode();
+    method public long getMinVersionCode();
+    method public boolean isEnabled();
+  }
+
+  public static final class PackageOverride.Builder {
+    ctor public PackageOverride.Builder();
+    method @NonNull public android.app.compat.PackageOverride build();
+    method @NonNull public android.app.compat.PackageOverride.Builder setEnabled(boolean);
+    method @NonNull public android.app.compat.PackageOverride.Builder setMaxVersionCode(long);
+    method @NonNull public android.app.compat.PackageOverride.Builder setMinVersionCode(long);
   }
 
 }
@@ -1702,10 +1735,20 @@
     field public static final int CAPABILITY_POSSESSED = 40; // 0x28
   }
 
+  public final class ExternalTimeSuggestion implements android.os.Parcelable {
+    ctor public ExternalTimeSuggestion(long, long);
+    method public void addDebugInfo(@NonNull java.lang.String...);
+    method public int describeContents();
+    method @NonNull public java.util.List<java.lang.String> getDebugInfo();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.app.time.ExternalTimeSuggestion> CREATOR;
+  }
+
   public final class TimeManager {
     method @RequiresPermission(android.Manifest.permission.MANAGE_TIME_AND_ZONE_DETECTION) public void addTimeZoneDetectorListener(@NonNull java.util.concurrent.Executor, @NonNull android.app.time.TimeManager.TimeZoneDetectorListener);
     method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_TIME_AND_ZONE_DETECTION) public android.app.time.TimeZoneCapabilitiesAndConfig getTimeZoneCapabilitiesAndConfig();
     method @RequiresPermission(android.Manifest.permission.MANAGE_TIME_AND_ZONE_DETECTION) public void removeTimeZoneDetectorListener(@NonNull android.app.time.TimeManager.TimeZoneDetectorListener);
+    method @RequiresPermission(android.Manifest.permission.SUGGEST_EXTERNAL_TIME) public void suggestExternalTime(@NonNull android.app.time.ExternalTimeSuggestion);
     method @RequiresPermission(android.Manifest.permission.MANAGE_TIME_AND_ZONE_DETECTION) public boolean updateTimeZoneConfiguration(@NonNull android.app.time.TimeZoneConfiguration);
   }
 
@@ -1831,7 +1874,8 @@
 
 package android.apphibernation {
 
-  public final class AppHibernationManager {
+  public class AppHibernationManager {
+    method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_APP_HIBERNATION) public java.util.List<java.lang.String> getHibernatingPackagesForUser();
     method @RequiresPermission(android.Manifest.permission.MANAGE_APP_HIBERNATION) public boolean isHibernatingForUser(@NonNull String);
     method @RequiresPermission(android.Manifest.permission.MANAGE_APP_HIBERNATION) public boolean isHibernatingGlobally(@NonNull String);
     method @RequiresPermission(android.Manifest.permission.MANAGE_APP_HIBERNATION) public void setHibernatingForUser(@NonNull String, boolean);
@@ -1943,7 +1987,6 @@
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean disconnect(android.bluetooth.BluetoothDevice);
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice);
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
-    method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean setPriority(android.bluetooth.BluetoothDevice, int);
   }
 
   public final class BluetoothHearingAid implements android.bluetooth.BluetoothProfile {
@@ -2138,7 +2181,19 @@
     field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.le.ResultStorageDescriptor> CREATOR;
   }
 
+  public final class ScanFilter implements android.os.Parcelable {
+    method public int getAddressType();
+    method @Nullable public byte[] getIrk();
+  }
+
+  public static final class ScanFilter.Builder {
+    method @NonNull public android.bluetooth.le.ScanFilter.Builder setDeviceAddress(@NonNull String, int);
+    method @NonNull public android.bluetooth.le.ScanFilter.Builder setDeviceAddress(@NonNull String, int, @NonNull byte[]);
+    field public static final int LEN_IRK_OCTETS = 16; // 0x10
+  }
+
   public final class ScanSettings implements android.os.Parcelable {
+    field public static final int SCAN_MODE_AMBIENT_DISCOVERY = 3; // 0x3
     field public static final int SCAN_RESULT_TYPE_ABBREVIATED = 1; // 0x1
     field public static final int SCAN_RESULT_TYPE_FULL = 0; // 0x0
   }
@@ -2158,6 +2213,8 @@
 package android.companion {
 
   public final class CompanionDeviceManager {
+    method @RequiresPermission("android.permission.ASSOCIATE_COMPANION_DEVICES") public boolean associate(@NonNull String, @NonNull android.net.MacAddress);
+    method @RequiresPermission("android.permission.MANAGE_COMPANION_DEVICES") public boolean canPairWithoutPrompt(@NonNull String, @NonNull String, int);
     method @RequiresPermission("android.permission.MANAGE_COMPANION_DEVICES") public boolean isDeviceAssociatedForWifiConnection(@NonNull String, @NonNull android.net.MacAddress, @NonNull android.os.UserHandle);
   }
 
@@ -2172,6 +2229,14 @@
     method @NonNull public java.io.File getDeviceProtectedDataDirForUser(@NonNull android.os.UserHandle);
   }
 
+  public final class AttributionSource implements android.os.Parcelable {
+    method @NonNull @RequiresPermission(android.Manifest.permission.RENOUNCE_PERMISSIONS) public java.util.Set<java.lang.String> getRenouncedPermissions();
+  }
+
+  public static final class AttributionSource.Builder {
+    method @NonNull @RequiresPermission(android.Manifest.permission.RENOUNCE_PERMISSIONS) public android.content.AttributionSource.Builder setRenouncedPermissions(@NonNull java.util.Set<java.lang.String>);
+  }
+
   public abstract class BroadcastReceiver {
     method @NonNull public final android.os.UserHandle getSendingUser();
   }
@@ -2246,11 +2311,11 @@
   }
 
   public final class ContextParams {
-    method @Nullable @RequiresPermission(android.Manifest.permission.RENOUNCE_PERMISSIONS) public java.util.Set<java.lang.String> getRenouncedPermissions();
+    method @NonNull @RequiresPermission(android.Manifest.permission.RENOUNCE_PERMISSIONS) public java.util.Set<java.lang.String> getRenouncedPermissions();
   }
 
   public static final class ContextParams.Builder {
-    method @NonNull @RequiresPermission(android.Manifest.permission.RENOUNCE_PERMISSIONS) public android.content.ContextParams.Builder setRenouncedPermissions(@Nullable java.util.Set<java.lang.String>);
+    method @NonNull @RequiresPermission(android.Manifest.permission.RENOUNCE_PERMISSIONS) public android.content.ContextParams.Builder setRenouncedPermissions(@NonNull java.util.Set<java.lang.String>);
   }
 
   public class ContextWrapper extends android.content.Context {
@@ -2424,6 +2489,7 @@
 package android.content.pm {
 
   public class ApplicationInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
+    method @Nullable public Boolean hasRequestOptimizedExternalStorageAccess();
     method public boolean isEncryptionAware();
     method public boolean isInstantApp();
     method public boolean isOem();
@@ -2437,14 +2503,6 @@
     method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_PROFILES) public void startActivity(@NonNull android.content.ComponentName, @NonNull android.os.UserHandle);
   }
 
-  public final class InstallationFile {
-    method public long getLengthBytes();
-    method public int getLocation();
-    method @Nullable public byte[] getMetadata();
-    method @NonNull public String getName();
-    method @Nullable public byte[] getSignature();
-  }
-
   public final class InstantAppInfo implements android.os.Parcelable {
     ctor public InstantAppInfo(android.content.pm.ApplicationInfo, String[], String[]);
     ctor public InstantAppInfo(String, CharSequence, String[], String[]);
@@ -2539,7 +2597,6 @@
 
   public static class PackageInstaller.Session implements java.io.Closeable {
     method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void commitTransferred(@NonNull android.content.IntentSender);
-    method public void removeFile(int, @NonNull String);
   }
 
   public static class PackageInstaller.SessionInfo implements android.os.Parcelable {
@@ -2783,7 +2840,9 @@
     method @NonNull public android.content.pm.SuspendDialogInfo.Builder setMessage(@StringRes int);
     method @NonNull public android.content.pm.SuspendDialogInfo.Builder setNeutralButtonAction(int);
     method @NonNull public android.content.pm.SuspendDialogInfo.Builder setNeutralButtonText(@StringRes int);
+    method @NonNull public android.content.pm.SuspendDialogInfo.Builder setNeutralButtonText(@NonNull String);
     method @NonNull public android.content.pm.SuspendDialogInfo.Builder setTitle(@StringRes int);
+    method @NonNull public android.content.pm.SuspendDialogInfo.Builder setTitle(@NonNull String);
   }
 
 }
@@ -2849,18 +2908,15 @@
   }
 
   public final class DomainVerificationManager {
-    method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.DOMAIN_VERIFICATION_AGENT, android.Manifest.permission.UPDATE_DOMAIN_VERIFICATION_USER_SELECTION}) public android.content.pm.verify.domain.DomainVerificationInfo getDomainVerificationInfo(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException;
+    method @Nullable @RequiresPermission(android.Manifest.permission.DOMAIN_VERIFICATION_AGENT) public android.content.pm.verify.domain.DomainVerificationInfo getDomainVerificationInfo(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException;
     method @NonNull @RequiresPermission(android.Manifest.permission.UPDATE_DOMAIN_VERIFICATION_USER_SELECTION) public java.util.List<android.content.pm.verify.domain.DomainOwner> getOwnersForDomain(@NonNull String);
     method @NonNull @RequiresPermission(android.Manifest.permission.DOMAIN_VERIFICATION_AGENT) public java.util.List<java.lang.String> queryValidVerificationPackageNames();
     method @RequiresPermission(android.Manifest.permission.UPDATE_DOMAIN_VERIFICATION_USER_SELECTION) public void setDomainVerificationLinkHandlingAllowed(@NonNull String, boolean) throws android.content.pm.PackageManager.NameNotFoundException;
-    method @RequiresPermission(android.Manifest.permission.DOMAIN_VERIFICATION_AGENT) public int setDomainVerificationStatus(@NonNull java.util.UUID, @NonNull java.util.Set<java.lang.String>, int) throws android.content.pm.PackageManager.NameNotFoundException;
-    method @RequiresPermission(android.Manifest.permission.UPDATE_DOMAIN_VERIFICATION_USER_SELECTION) public int setDomainVerificationUserSelection(@NonNull java.util.UUID, @NonNull java.util.Set<java.lang.String>, boolean) throws android.content.pm.PackageManager.NameNotFoundException;
+    method @CheckResult @RequiresPermission(android.Manifest.permission.DOMAIN_VERIFICATION_AGENT) public int setDomainVerificationStatus(@NonNull java.util.UUID, @NonNull java.util.Set<java.lang.String>, int) throws android.content.pm.PackageManager.NameNotFoundException;
+    method @CheckResult @RequiresPermission(android.Manifest.permission.UPDATE_DOMAIN_VERIFICATION_USER_SELECTION) public int setDomainVerificationUserSelection(@NonNull java.util.UUID, @NonNull java.util.Set<java.lang.String>, boolean) throws android.content.pm.PackageManager.NameNotFoundException;
     field public static final int ERROR_DOMAIN_SET_ID_INVALID = 1; // 0x1
-    field public static final int ERROR_DOMAIN_SET_ID_NULL = 2; // 0x2
-    field public static final int ERROR_DOMAIN_SET_NULL_OR_EMPTY = 3; // 0x3
-    field public static final int ERROR_INVALID_STATE_CODE = 6; // 0x6
-    field public static final int ERROR_UNABLE_TO_APPROVE = 5; // 0x5
-    field public static final int ERROR_UNKNOWN_DOMAIN = 4; // 0x4
+    field public static final int ERROR_UNABLE_TO_APPROVE = 3; // 0x3
+    field public static final int ERROR_UNKNOWN_DOMAIN = 2; // 0x2
     field public static final String EXTRA_VERIFICATION_REQUEST = "android.content.pm.verify.domain.extra.VERIFICATION_REQUEST";
     field public static final int STATUS_OK = 0; // 0x0
   }
@@ -4431,6 +4487,7 @@
     method public boolean hasLowPowerMode();
     method public boolean hasMeasurementCorrections();
     method public boolean hasMeasurementCorrectionsExcessPathLength();
+    method public boolean hasMeasurementCorrectionsForDriving();
     method public boolean hasMeasurementCorrectionsLosSats();
     method @Deprecated public boolean hasMeasurementCorrectionsReflectingPane();
     method public boolean hasMeasurementCorrectionsReflectingPlane();
@@ -4446,6 +4503,7 @@
     method @NonNull public android.location.GnssCapabilities.Builder setHasLowPowerMode(boolean);
     method @NonNull public android.location.GnssCapabilities.Builder setHasMeasurementCorrections(boolean);
     method @NonNull public android.location.GnssCapabilities.Builder setHasMeasurementCorrectionsExcessPathLength(boolean);
+    method @NonNull public android.location.GnssCapabilities.Builder setHasMeasurementCorrectionsForDriving(boolean);
     method @NonNull public android.location.GnssCapabilities.Builder setHasMeasurementCorrectionsLosSats(boolean);
     method @NonNull public android.location.GnssCapabilities.Builder setHasMeasurementCorrectionsReflectingPlane(boolean);
     method @NonNull public android.location.GnssCapabilities.Builder setHasMeasurementCorrelationVectors(boolean);
@@ -4804,7 +4862,7 @@
   public class Location implements android.os.Parcelable {
     method public boolean isComplete();
     method public void makeComplete();
-    method public void setIsFromMockProvider(boolean);
+    method @Deprecated public void setIsFromMockProvider(boolean);
     field @Deprecated public static final String EXTRA_NO_GPS_LOCATION = "noGPSLocation";
   }
 
@@ -5235,6 +5293,10 @@
     method @RequiresPermission(android.Manifest.permission.WRITE_SETTINGS) public static void ensureDefaultRingtones(@NonNull android.content.Context);
   }
 
+  public final class RouteDiscoveryPreference implements android.os.Parcelable {
+    field public static final android.media.RouteDiscoveryPreference EMPTY;
+  }
+
 }
 
 package android.media.audiofx {
@@ -5413,6 +5475,8 @@
   public final class MediaSessionManager {
     method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void addOnMediaKeyEventDispatchedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.session.MediaSessionManager.OnMediaKeyEventDispatchedListener);
     method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void addOnMediaKeyEventSessionChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.session.MediaSessionManager.OnMediaKeyEventSessionChangedListener);
+    method @Nullable @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public android.media.session.MediaSession.Token getMediaKeyEventSession();
+    method @NonNull @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public String getMediaKeyEventSessionPackageName();
     method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void removeOnMediaKeyEventDispatchedListener(@NonNull android.media.session.MediaSessionManager.OnMediaKeyEventDispatchedListener);
     method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void removeOnMediaKeyEventSessionChangedListener(@NonNull android.media.session.MediaSessionManager.OnMediaKeyEventSessionChangedListener);
     method @RequiresPermission(android.Manifest.permission.SET_MEDIA_KEY_LISTENER) public void setOnMediaKeyListener(android.media.session.MediaSessionManager.OnMediaKeyListener, @Nullable android.os.Handler);
@@ -7551,9 +7615,11 @@
     method public void notifyAlertReached();
     method public void notifyLimitReached();
     method public void notifyStatsUpdated(int, @NonNull android.net.NetworkStats, @NonNull android.net.NetworkStats);
+    method public void notifyWarningReached();
     method public abstract void onRequestStatsUpdate(int);
     method public abstract void onSetAlert(long);
     method public abstract void onSetLimit(@NonNull String, long);
+    method public void onSetWarningAndLimit(@NonNull String, long, long);
     field public static final int QUOTA_UNLIMITED = -1; // 0xffffffff
   }
 
@@ -7761,6 +7827,7 @@
     method @Nullable public android.net.wifi.nl80211.WifiNl80211Manager.TxPacketCounters getTxPacketCounters(@NonNull String);
     method @Nullable public static android.net.wifi.nl80211.WifiNl80211Manager.OemSecurityType parseOemSecurityTypeElement(int, int, @NonNull byte[]);
     method @Deprecated public boolean registerApCallback(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.nl80211.WifiNl80211Manager.SoftApCallback);
+    method public boolean registerCountryCodeChangeListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.nl80211.WifiNl80211Manager.CountryCodeChangeListener);
     method public void sendMgmtFrame(@NonNull String, @NonNull byte[], int, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.nl80211.WifiNl80211Manager.SendMgmtFrameCallback);
     method public void setOnServiceDeadCallback(@NonNull Runnable);
     method public boolean setupInterfaceForClientMode(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.nl80211.WifiNl80211Manager.ScanEventCallback, @NonNull android.net.wifi.nl80211.WifiNl80211Manager.ScanEventCallback);
@@ -7773,6 +7840,7 @@
     method public boolean tearDownClientInterface(@NonNull String);
     method public boolean tearDownInterfaces();
     method public boolean tearDownSoftApInterface(@NonNull String);
+    method public void unregisterCountryCodeChangeListener(@NonNull android.net.wifi.nl80211.WifiNl80211Manager.CountryCodeChangeListener);
     field public static final String SCANNING_PARAM_ENABLE_6GHZ_RNR = "android.net.wifi.nl80211.SCANNING_PARAM_ENABLE_6GHZ_RNR";
     field public static final int SCAN_TYPE_PNO_SCAN = 1; // 0x1
     field public static final int SCAN_TYPE_SINGLE_SCAN = 0; // 0x0
@@ -7783,6 +7851,10 @@
     field public static final int SEND_MGMT_FRAME_ERROR_UNKNOWN = 1; // 0x1
   }
 
+  public static interface WifiNl80211Manager.CountryCodeChangeListener {
+    method public void onChanged(@NonNull String);
+  }
+
   public static class WifiNl80211Manager.OemSecurityType {
     ctor public WifiNl80211Manager.OemSecurityType(int, @NonNull java.util.List<java.lang.Integer>, @NonNull java.util.List<java.lang.Integer>, int);
     field public final int groupCipher;
@@ -7836,10 +7908,10 @@
     method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enable();
     method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enableNdefPush();
     method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enableSecureNfc(boolean);
-    method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean isAlwaysOnEnabled();
-    method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean isAlwaysOnSupported();
+    method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public boolean isControllerAlwaysOn();
+    method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public boolean isControllerAlwaysOnSupported();
     method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean removeNfcUnlockHandler(android.nfc.NfcAdapter.NfcUnlockHandler);
-    method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean setAlwaysOn(boolean);
+    method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public boolean setControllerAlwaysOn(boolean);
     method public void setNdefPushMessage(android.nfc.NdefMessage, android.app.Activity, int);
     field public static final int FLAG_NDEF_PUSH_NO_CONFIRM = 1; // 0x1
   }
@@ -8252,11 +8324,8 @@
   }
 
   public class PowerExemptionManager {
-    method @RequiresPermission(android.Manifest.permission.DEVICE_POWER) public void addToPermanentAllowList(@NonNull String);
-    method @RequiresPermission(android.Manifest.permission.DEVICE_POWER) public void addToPermanentAllowList(@NonNull java.util.List<java.lang.String>);
-    method @RequiresPermission(android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST) public void addToTemporaryAllowList(@NonNull String, long, int, @Nullable String);
-    method @RequiresPermission(android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST) public long addToTemporaryAllowListForEvent(@NonNull String, int, int, @Nullable String);
-    method @RequiresPermission(android.Manifest.permission.DEVICE_POWER) public void removeFromAllowList(@NonNull String);
+    method @RequiresPermission(android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST) public void addToTemporaryAllowList(@NonNull String, int, @Nullable String, long);
+    method @RequiresPermission(android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST) public long addToTemporaryAllowListForEvent(@NonNull String, int, @Nullable String, int);
     field public static final int EVENT_MMS = 2; // 0x2
     field public static final int EVENT_SMS = 1; // 0x1
     field public static final int EVENT_UNSPECIFIED = 0; // 0x0
@@ -8269,6 +8338,7 @@
     field public static final int REASON_UNKNOWN = 0; // 0x0
     field public static final int TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED = 0; // 0x0
     field public static final int TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED = 1; // 0x1
+    field public static final int TEMPORARY_ALLOW_LIST_TYPE_NONE = -1; // 0xffffffff
   }
 
   public final class PowerManager {
@@ -8480,6 +8550,7 @@
     method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean hasRestrictedProfiles();
     method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.INTERACT_ACROSS_USERS}, conditional=true) public boolean hasUserRestrictionForUser(@NonNull String, @NonNull android.os.UserHandle);
     method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean isAdminUser();
+    method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.INTERACT_ACROSS_USERS}, conditional=true) public boolean isCloneProfile();
     method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public boolean isGuestUser();
     method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.INTERACT_ACROSS_USERS}, conditional=true) public boolean isManagedProfile(int);
     method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public boolean isPrimaryUser();
@@ -8493,6 +8564,7 @@
     method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public boolean removeUser(@NonNull android.os.UserHandle);
     method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public void setUserIcon(@NonNull android.graphics.Bitmap) throws android.os.UserManager.UserOperationException;
     method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public void setUserName(@Nullable String);
+    method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.INTERACT_ACROSS_USERS}, conditional=true) public boolean sharesMediaWithParent();
     field public static final String ACTION_USER_RESTRICTIONS_CHANGED = "android.os.action.USER_RESTRICTIONS_CHANGED";
     field @Deprecated public static final String DISALLOW_OEM_UNLOCK = "no_oem_unlock";
     field public static final String DISALLOW_RUN_IN_BACKGROUND = "no_run_in_background";
@@ -8506,6 +8578,7 @@
     field public static final int SWITCHABILITY_STATUS_USER_SWITCH_DISALLOWED = 2; // 0x2
     field public static final String USER_TYPE_FULL_SECONDARY = "android.os.usertype.full.SECONDARY";
     field public static final String USER_TYPE_FULL_SYSTEM = "android.os.usertype.full.SYSTEM";
+    field public static final String USER_TYPE_PROFILE_CLONE = "android.os.usertype.profile.CLONE";
     field public static final String USER_TYPE_PROFILE_MANAGED = "android.os.usertype.profile.MANAGED";
     field public static final String USER_TYPE_SYSTEM_HEADLESS = "android.os.usertype.system.HEADLESS";
   }
@@ -8653,9 +8726,15 @@
     method @WorkerThread public void allocateBytes(@NonNull java.util.UUID, long, @RequiresPermission int) throws java.io.IOException;
     method @WorkerThread public void allocateBytes(java.io.FileDescriptor, long, @RequiresPermission int) throws java.io.IOException;
     method @WorkerThread public long getAllocatableBytes(@NonNull java.util.UUID, @RequiresPermission int) throws java.io.IOException;
+    method @RequiresPermission(android.Manifest.permission.WRITE_MEDIA_STORAGE) public int getExternalStorageMountMode(int, @NonNull String);
     method public static boolean hasIsolatedStorage();
     method public void updateExternalStorageFileQuotaType(@NonNull java.io.File, int) throws java.io.IOException;
     field @RequiresPermission(android.Manifest.permission.ALLOCATE_AGGRESSIVE) public static final int FLAG_ALLOCATE_AGGRESSIVE = 1; // 0x1
+    field public static final int MOUNT_MODE_EXTERNAL_ANDROID_WRITABLE = 4; // 0x4
+    field public static final int MOUNT_MODE_EXTERNAL_DEFAULT = 1; // 0x1
+    field public static final int MOUNT_MODE_EXTERNAL_INSTALLER = 2; // 0x2
+    field public static final int MOUNT_MODE_EXTERNAL_NONE = 0; // 0x0
+    field public static final int MOUNT_MODE_EXTERNAL_PASS_THROUGH = 3; // 0x3
     field public static final int QUOTA_TYPE_MEDIA_AUDIO = 2; // 0x2
     field public static final int QUOTA_TYPE_MEDIA_IMAGE = 1; // 0x1
     field public static final int QUOTA_TYPE_MEDIA_NONE = 0; // 0x0
@@ -8902,6 +8981,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_APPSEARCH = "appsearch";
     field public static final String NAMESPACE_APP_COMPAT = "app_compat";
     field public static final String NAMESPACE_APP_HIBERNATION = "app_hibernation";
     field public static final String NAMESPACE_ATTENTION_MANAGER_SERVICE = "attention_manager_service";
@@ -8918,6 +8998,7 @@
     field public static final String NAMESPACE_GAME_DRIVER = "game_driver";
     field public static final String NAMESPACE_INPUT_NATIVE_BOOT = "input_native_boot";
     field public static final String NAMESPACE_INTELLIGENCE_ATTENTION = "intelligence_attention";
+    field public static final String NAMESPACE_MEDIA = "media";
     field public static final String NAMESPACE_MEDIA_NATIVE = "media_native";
     field public static final String NAMESPACE_NETD_NATIVE = "netd_native";
     field public static final String NAMESPACE_OTA = "ota";
@@ -8979,6 +9060,8 @@
     method @NonNull public static android.net.Uri setManageMode(@NonNull android.net.Uri);
     field public static final String ACTION_DOCUMENT_ROOT_SETTINGS = "android.provider.action.DOCUMENT_ROOT_SETTINGS";
     field public static final String ACTION_MANAGE_DOCUMENT = "android.provider.action.MANAGE_DOCUMENT";
+    field public static final String DOWNLOADS_PROVIDER_AUTHORITY = "downloads";
+    field public static final String EXTERNAL_STORAGE_PROVIDER_AUTHORITY = "com.android.externalstorage.documents";
     field public static final String EXTRA_SHOW_ADVANCED = "android.provider.extra.SHOW_ADVANCED";
   }
 
@@ -9686,24 +9769,6 @@
 
 }
 
-package android.service.dataloader {
-
-  public abstract class DataLoaderService extends android.app.Service {
-    ctor public DataLoaderService();
-    method @Nullable public android.service.dataloader.DataLoaderService.DataLoader onCreateDataLoader(@NonNull android.content.pm.DataLoaderParams);
-  }
-
-  public static interface DataLoaderService.DataLoader {
-    method public boolean onCreate(@NonNull android.content.pm.DataLoaderParams, @NonNull android.service.dataloader.DataLoaderService.FileSystemConnector);
-    method public boolean onPrepareImage(@NonNull java.util.Collection<android.content.pm.InstallationFile>, @NonNull java.util.Collection<java.lang.String>);
-  }
-
-  public static final class DataLoaderService.FileSystemConnector {
-    method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void writeData(@NonNull String, long, long, @NonNull android.os.ParcelFileDescriptor) throws java.io.IOException;
-  }
-
-}
-
 package android.service.displayhash {
 
   public final class DisplayHashParams implements android.os.Parcelable {
@@ -9730,6 +9795,7 @@
     method @NonNull public abstract java.util.Map<java.lang.String,android.service.displayhash.DisplayHashParams> onGetDisplayHashAlgorithms();
     method @Nullable public abstract android.view.displayhash.VerifiedDisplayHash onVerifyDisplayHash(@NonNull byte[], @NonNull android.view.displayhash.DisplayHash);
     field public static final String SERVICE_INTERFACE = "android.service.displayhash.DisplayHasherService";
+    field public static final String SERVICE_META_DATA = "android.displayhash.display_hasher_service";
   }
 
 }
@@ -10243,9 +10309,10 @@
     ctor public TranslationService();
     method @Nullable public final android.os.IBinder onBind(@NonNull android.content.Intent);
     method public void onConnected();
-    method public abstract void onCreateTranslationSession(@NonNull android.view.translation.TranslationSpec, @NonNull android.view.translation.TranslationSpec, int);
+    method public abstract void onCreateTranslationSession(@NonNull android.view.translation.TranslationContext, int);
     method public void onDisconnected();
     method public abstract void onFinishTranslationSession(int);
+    method public abstract void onTranslationCapabilitiesRequest(int, int, @NonNull java.util.function.Consumer<java.util.Set<android.view.translation.TranslationCapability>>);
     method public abstract void onTranslationRequest(@NonNull android.view.translation.TranslationRequest, int, @NonNull android.os.CancellationSignal, @NonNull android.service.translation.TranslationService.OnTranslationResultCallback);
     field public static final String SERVICE_INTERFACE = "android.service.translation.TranslationService";
     field public static final String SERVICE_META_DATA = "android.translation_service";
@@ -10293,7 +10360,7 @@
 
 package android.service.voice {
 
-  public class AlwaysOnHotwordDetector {
+  public class AlwaysOnHotwordDetector implements android.service.voice.HotwordDetector {
     method @Nullable public android.content.Intent createEnrollIntent();
     method @Nullable public android.content.Intent createReEnrollIntent();
     method @Nullable public android.content.Intent createUnEnrollIntent();
@@ -10303,10 +10370,12 @@
     method @Nullable @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public android.service.voice.AlwaysOnHotwordDetector.ModelParamRange queryParameter(int);
     method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public int setParameter(int, int);
     method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public boolean startRecognition(int);
+    method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public boolean startRecognition();
+    method @Nullable public boolean startRecognition(@NonNull android.os.ParcelFileDescriptor, @NonNull android.media.AudioFormat, @Nullable android.os.PersistableBundle);
     method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public boolean stopRecognition();
+    method public final void updateState(@Nullable android.os.PersistableBundle, @Nullable android.os.SharedMemory);
     field public static final int AUDIO_CAPABILITY_ECHO_CANCELLATION = 1; // 0x1
     field public static final int AUDIO_CAPABILITY_NOISE_SUPPRESSION = 2; // 0x2
-    field public static final int HOTWORD_DETECTION_FALSE_ALERT = 0; // 0x0
     field public static final int MODEL_PARAM_THRESHOLD_FACTOR = 0; // 0x0
     field public static final int RECOGNITION_FLAG_ALLOW_MULTIPLE_TRIGGERS = 2; // 0x2
     field public static final int RECOGNITION_FLAG_CAPTURE_TRIGGER_AUDIO = 1; // 0x1
@@ -10322,18 +10391,17 @@
     field @Deprecated public static final int STATE_KEYPHRASE_UNSUPPORTED = -1; // 0xffffffff
   }
 
-  public abstract static class AlwaysOnHotwordDetector.Callback {
+  public abstract static class AlwaysOnHotwordDetector.Callback implements android.service.voice.HotwordDetector.Callback {
     ctor public AlwaysOnHotwordDetector.Callback();
     method public abstract void onAvailabilityChanged(int);
-    method public abstract void onDetected(@NonNull android.service.voice.AlwaysOnHotwordDetector.EventPayload);
-    method public abstract void onError();
-    method public abstract void onRecognitionPaused();
-    method public abstract void onRecognitionResumed();
-    method public void onRejected(int);
+    method public void onHotwordDetectionServiceInitialized(int);
+    method public void onRejected(@Nullable android.service.voice.HotwordRejectedResult);
   }
 
   public static class AlwaysOnHotwordDetector.EventPayload {
+    method @Nullable public android.os.ParcelFileDescriptor getAudioStream();
     method @Nullable public android.media.AudioFormat getCaptureAudioFormat();
+    method @Nullable public android.service.voice.HotwordDetectedResult getHotwordDetectedResult();
     method @Nullable public byte[] getTriggerAudio();
   }
 
@@ -10371,23 +10439,41 @@
   public abstract class HotwordDetectionService extends android.app.Service {
     ctor public HotwordDetectionService();
     method @Nullable public final android.os.IBinder onBind(@NonNull android.content.Intent);
-    method public void onDetectFromDspSource(@NonNull android.os.ParcelFileDescriptor, @NonNull android.media.AudioFormat, long, @NonNull android.service.voice.HotwordDetectionService.DspHotwordDetectionCallback);
-    method public void onUpdateState(@Nullable android.os.Bundle, @Nullable android.os.SharedMemory);
+    method public void onDetect(@NonNull android.os.ParcelFileDescriptor, @NonNull android.media.AudioFormat, long, @NonNull android.service.voice.HotwordDetectionService.Callback);
+    method public void onDetect(@NonNull android.os.ParcelFileDescriptor, @NonNull android.media.AudioFormat, @NonNull android.service.voice.HotwordDetectionService.Callback);
+    method public void onDetect(@NonNull android.os.ParcelFileDescriptor, @NonNull android.media.AudioFormat, @Nullable android.os.PersistableBundle, @NonNull android.service.voice.HotwordDetectionService.Callback);
+    method public void onUpdateState(@Nullable android.os.PersistableBundle, @Nullable android.os.SharedMemory, long, @Nullable java.util.function.IntConsumer);
+    field public static final int INITIALIZATION_STATUS_CUSTOM_ERROR_1 = 1; // 0x1
+    field public static final int INITIALIZATION_STATUS_CUSTOM_ERROR_2 = 2; // 0x2
+    field public static final int INITIALIZATION_STATUS_SUCCESS = 0; // 0x0
+    field public static final int INITIALIZATION_STATUS_UNKNOWN = 100; // 0x64
     field public static final String SERVICE_INTERFACE = "android.service.voice.HotwordDetectionService";
   }
 
-  public static final class HotwordDetectionService.DspHotwordDetectionCallback {
-    method public void onDetected();
-    method public void onRejected();
+  public static final class HotwordDetectionService.Callback {
+    method public void onDetected(@Nullable android.service.voice.HotwordDetectedResult);
+    method public void onRejected(@Nullable android.service.voice.HotwordRejectedResult);
   }
 
   public interface HotwordDetector {
+    method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public boolean startRecognition();
+    method public boolean startRecognition(@NonNull android.os.ParcelFileDescriptor, @NonNull android.media.AudioFormat, @Nullable android.os.PersistableBundle);
+    method public boolean stopRecognition();
     field public static final int CONFIDENCE_LEVEL_HIGH = 3; // 0x3
     field public static final int CONFIDENCE_LEVEL_LOW = 1; // 0x1
     field public static final int CONFIDENCE_LEVEL_MEDIUM = 2; // 0x2
     field public static final int CONFIDENCE_LEVEL_NONE = 0; // 0x0
   }
 
+  public static interface HotwordDetector.Callback {
+    method public void onDetected(@NonNull android.service.voice.AlwaysOnHotwordDetector.EventPayload);
+    method public void onError();
+    method public void onHotwordDetectionServiceInitialized(int);
+    method public void onRecognitionPaused();
+    method public void onRecognitionResumed();
+    method public void onRejected(@Nullable android.service.voice.HotwordRejectedResult);
+  }
+
   public final class HotwordRejectedResult implements android.os.Parcelable {
     method public int describeContents();
     method public int getConfidenceLevel();
@@ -10397,7 +10483,8 @@
 
   public class VoiceInteractionService extends android.app.Service {
     method @NonNull public final android.service.voice.AlwaysOnHotwordDetector createAlwaysOnHotwordDetector(String, java.util.Locale, android.service.voice.AlwaysOnHotwordDetector.Callback);
-    method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_HOTWORD_DETECTION) public final android.service.voice.AlwaysOnHotwordDetector createAlwaysOnHotwordDetector(String, java.util.Locale, @Nullable android.os.Bundle, @Nullable android.os.SharedMemory, android.service.voice.AlwaysOnHotwordDetector.Callback);
+    method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_HOTWORD_DETECTION) public final android.service.voice.AlwaysOnHotwordDetector createAlwaysOnHotwordDetector(String, java.util.Locale, @Nullable android.os.PersistableBundle, @Nullable android.os.SharedMemory, android.service.voice.AlwaysOnHotwordDetector.Callback);
+    method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_HOTWORD_DETECTION) public final android.service.voice.HotwordDetector createHotwordDetector(@NonNull android.media.AudioFormat, @Nullable android.os.PersistableBundle, @Nullable android.os.SharedMemory, @NonNull android.service.voice.HotwordDetector.Callback);
     method @NonNull @RequiresPermission("android.permission.MANAGE_VOICE_KEYPHRASES") public final android.media.voice.KeyphraseModelManager createKeyphraseModelManager();
   }
 
@@ -10802,7 +10889,7 @@
     method public java.util.List<android.telecom.PhoneAccount> getAllPhoneAccounts();
     method public int getAllPhoneAccountsCount();
     method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.List<android.telecom.PhoneAccountHandle> getCallCapablePhoneAccounts(boolean);
-    method public int getCallState();
+    method @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}, conditional=true) public int getCallState();
     method public android.telecom.PhoneAccountHandle getConnectionManager();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getCurrentTtyMode();
     method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getDefaultDialerPackage(@NonNull android.os.UserHandle);
@@ -11055,7 +11142,8 @@
 
   public final class DataSpecificRegistrationInfo implements android.os.Parcelable {
     method public int describeContents();
-    method @NonNull public android.telephony.LteVopsSupportInfo getLteVopsSupportInfo();
+    method @Deprecated @NonNull public android.telephony.LteVopsSupportInfo getLteVopsSupportInfo();
+    method @Nullable public android.telephony.VopsSupportInfo getVopsSupportInfo();
     method public void writeToParcel(android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.telephony.DataSpecificRegistrationInfo> CREATOR;
   }
@@ -11100,14 +11188,16 @@
     field public static final int LCE_TYPE_SECONDARY = 1; // 0x1
   }
 
-  public final class LteVopsSupportInfo implements android.os.Parcelable {
+  public final class LteVopsSupportInfo extends android.telephony.VopsSupportInfo {
     ctor public LteVopsSupportInfo(int, int);
-    method public int describeContents();
     method public int getEmcBearerSupport();
     method public int getVopsSupport();
-    method public void writeToParcel(android.os.Parcel, int);
+    method public boolean isEmergencyServiceFallbackSupported();
+    method public boolean isEmergencyServiceSupported();
+    method public boolean isVopsSupported();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.telephony.LteVopsSupportInfo> CREATOR;
-    field public static final int LTE_STATUS_NOT_AVAILABLE = 1; // 0x1
+    field @Deprecated public static final int LTE_STATUS_NOT_AVAILABLE = 1; // 0x1
     field public static final int LTE_STATUS_NOT_SUPPORTED = 3; // 0x3
     field public static final int LTE_STATUS_SUPPORTED = 2; // 0x2
   }
@@ -11197,6 +11287,29 @@
     field public static final int RESULT_SUCCESS = 0; // 0x0
   }
 
+  public final class NrVopsSupportInfo extends android.telephony.VopsSupportInfo {
+    ctor public NrVopsSupportInfo(int, int, int);
+    method public int getEmcSupport();
+    method public int getEmfSupport();
+    method public int getVopsSupport();
+    method public boolean isEmergencyServiceFallbackSupported();
+    method public boolean isEmergencyServiceSupported();
+    method public boolean isVopsSupported();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.NrVopsSupportInfo> CREATOR;
+    field public static final int NR_STATUS_EMC_5GCN_ONLY = 1; // 0x1
+    field public static final int NR_STATUS_EMC_EUTRA_5GCN_ONLY = 2; // 0x2
+    field public static final int NR_STATUS_EMC_NOT_SUPPORTED = 0; // 0x0
+    field public static final int NR_STATUS_EMC_NR_EUTRA_5GCN = 3; // 0x3
+    field public static final int NR_STATUS_EMF_5GCN_ONLY = 1; // 0x1
+    field public static final int NR_STATUS_EMF_EUTRA_5GCN_ONLY = 2; // 0x2
+    field public static final int NR_STATUS_EMF_NOT_SUPPORTED = 0; // 0x0
+    field public static final int NR_STATUS_EMF_NR_EUTRA_5GCN = 3; // 0x3
+    field public static final int NR_STATUS_VOPS_3GPP_SUPPORTED = 1; // 0x1
+    field public static final int NR_STATUS_VOPS_NON_3GPP_SUPPORTED = 2; // 0x2
+    field public static final int NR_STATUS_VOPS_NOT_SUPPORTED = 0; // 0x0
+  }
+
   public interface NumberVerificationCallback {
     method public default void onCallReceived(@NonNull String);
     method public default void onVerificationFailed(int);
@@ -11211,12 +11324,11 @@
 
   public final class PhoneCapability implements android.os.Parcelable {
     method public int describeContents();
-    method public int getDeviceNrCapabilityBitmask();
-    method @IntRange(from=1) public int getMaxActiveInternetData();
-    method @IntRange(from=1) public int getMaxActivePacketSwitchedVoiceCalls();
+    method @NonNull public int[] getDeviceNrCapabilities();
+    method @IntRange(from=1) public int getMaxActiveDataSubscriptions();
+    method @IntRange(from=1) public int getMaxActiveVoiceSubscriptions();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.telephony.PhoneCapability> CREATOR;
-    field public static final int DEVICE_NR_CAPABILITY_NONE = 0; // 0x0
     field public static final int DEVICE_NR_CAPABILITY_NSA = 1; // 0x1
     field public static final int DEVICE_NR_CAPABILITY_SA = 2; // 0x2
   }
@@ -11862,6 +11974,7 @@
     field public static final String CAPABILITY_ALLOWED_NETWORK_TYPES_USED = "CAPABILITY_ALLOWED_NETWORK_TYPES_USED";
     field public static final String CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE = "CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE";
     field public static final String CAPABILITY_SECONDARY_LINK_BANDWIDTH_VISIBLE = "CAPABILITY_SECONDARY_LINK_BANDWIDTH_VISIBLE";
+    field public static final String CAPABILITY_THERMAL_MITIGATION_DATA_THROTTLING = "CAPABILITY_THERMAL_MITIGATION_DATA_THROTTLING";
     field public static final int CARRIER_PRIVILEGE_STATUS_ERROR_LOADING_RULES = -2; // 0xfffffffe
     field public static final int CARRIER_PRIVILEGE_STATUS_HAS_ACCESS = 1; // 0x1
     field public static final int CARRIER_PRIVILEGE_STATUS_NO_ACCESS = 0; // 0x0
@@ -12023,6 +12136,16 @@
     method public static final void setSmsFilterSettings(android.content.Context, android.telecom.PhoneAccountHandle, android.telephony.VisualVoicemailSmsFilterSettings);
   }
 
+  public abstract class VopsSupportInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method public abstract boolean equals(Object);
+    method public abstract int hashCode();
+    method public abstract boolean isEmergencyServiceFallbackSupported();
+    method public abstract boolean isEmergencyServiceSupported();
+    method public abstract boolean isVopsSupported();
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.VopsSupportInfo> CREATOR;
+  }
+
 }
 
 package android.telephony.cdma {
@@ -12052,6 +12175,7 @@
     method public static int getApnTypeInt(@NonNull String);
     method @NonNull public static String getApnTypeString(int);
     field public static final String TYPE_ALL_STRING = "*";
+    field public static final String TYPE_BIP_STRING = "bip";
     field public static final String TYPE_CBS_STRING = "cbs";
     field public static final String TYPE_DEFAULT_STRING = "default";
     field public static final String TYPE_DUN_STRING = "dun";
@@ -12063,6 +12187,7 @@
     field public static final String TYPE_MCX_STRING = "mcx";
     field public static final String TYPE_MMS_STRING = "mms";
     field public static final String TYPE_SUPL_STRING = "supl";
+    field public static final String TYPE_VSIM_STRING = "vsim";
     field public static final String TYPE_XCAP_STRING = "xcap";
   }
 
@@ -12212,40 +12337,28 @@
 
   public final class EpsBearerQosSessionAttributes implements android.os.Parcelable android.net.QosSessionAttributes {
     method public int describeContents();
-    method public long getGuaranteedDownlinkBitRate();
-    method public long getGuaranteedUplinkBitRate();
-    method public long getMaxDownlinkBitRate();
-    method public long getMaxUplinkBitRate();
-    method public int getQci();
+    method public long getGuaranteedDownlinkBitRateKbps();
+    method public long getGuaranteedUplinkBitRateKbps();
+    method public long getMaxDownlinkBitRateKbps();
+    method public long getMaxUplinkBitRateKbps();
+    method public int getQosIdentifier();
     method @NonNull public java.util.List<java.net.InetSocketAddress> getRemoteAddresses();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.telephony.data.EpsBearerQosSessionAttributes> CREATOR;
   }
 
-  public final class NetworkSliceInfo implements android.os.Parcelable {
+  public final class NrQosSessionAttributes implements android.os.Parcelable android.net.QosSessionAttributes {
     method public int describeContents();
-    method @IntRange(from=android.telephony.data.NetworkSliceInfo.MIN_SLICE_DIFFERENTIATOR, to=android.telephony.data.NetworkSliceInfo.MAX_SLICE_DIFFERENTIATOR) public int getMappedHplmnSliceDifferentiator();
-    method public int getMappedHplmnSliceServiceType();
-    method @IntRange(from=android.telephony.data.NetworkSliceInfo.MIN_SLICE_DIFFERENTIATOR, to=android.telephony.data.NetworkSliceInfo.MAX_SLICE_DIFFERENTIATOR) public int getSliceDifferentiator();
-    method public int getSliceServiceType();
+    method @NonNull public java.time.Duration getBitRateWindowDuration();
+    method public long getGuaranteedDownlinkBitRateKbps();
+    method public long getGuaranteedUplinkBitRateKbps();
+    method public long getMaxDownlinkBitRateKbps();
+    method public long getMaxUplinkBitRateKbps();
+    method @IntRange(from=1, to=63) public int getQosFlowIdentifier();
+    method public int getQosIdentifier();
+    method @NonNull public java.util.List<java.net.InetSocketAddress> getRemoteAddresses();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.data.NetworkSliceInfo> CREATOR;
-    field public static final int MAX_SLICE_DIFFERENTIATOR = 16777214; // 0xfffffe
-    field public static final int MIN_SLICE_DIFFERENTIATOR = -1; // 0xffffffff
-    field public static final int SLICE_DIFFERENTIATOR_NO_SLICE = -1; // 0xffffffff
-    field public static final int SLICE_SERVICE_TYPE_EMBB = 1; // 0x1
-    field public static final int SLICE_SERVICE_TYPE_MIOT = 3; // 0x3
-    field public static final int SLICE_SERVICE_TYPE_NONE = 0; // 0x0
-    field public static final int SLICE_SERVICE_TYPE_URLLC = 2; // 0x2
-  }
-
-  public static final class NetworkSliceInfo.Builder {
-    ctor public NetworkSliceInfo.Builder();
-    method @NonNull public android.telephony.data.NetworkSliceInfo build();
-    method @NonNull public android.telephony.data.NetworkSliceInfo.Builder setMappedHplmnSliceDifferentiator(@IntRange(from=android.telephony.data.NetworkSliceInfo.MIN_SLICE_DIFFERENTIATOR, to=android.telephony.data.NetworkSliceInfo.MAX_SLICE_DIFFERENTIATOR) int);
-    method @NonNull public android.telephony.data.NetworkSliceInfo.Builder setMappedHplmnSliceServiceType(int);
-    method @NonNull public android.telephony.data.NetworkSliceInfo.Builder setSliceDifferentiator(@IntRange(from=android.telephony.data.NetworkSliceInfo.MIN_SLICE_DIFFERENTIATOR, to=android.telephony.data.NetworkSliceInfo.MAX_SLICE_DIFFERENTIATOR) int);
-    method @NonNull public android.telephony.data.NetworkSliceInfo.Builder setSliceServiceType(int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.data.NrQosSessionAttributes> CREATOR;
   }
 
   public abstract class QualifiedNetworksService extends android.app.Service {
@@ -12290,15 +12403,6 @@
     method @NonNull public android.telephony.data.ThrottleStatus.Builder setTransportType(int);
   }
 
-  public final class TrafficDescriptor implements android.os.Parcelable {
-    ctor public TrafficDescriptor(@Nullable String, @Nullable String);
-    method public int describeContents();
-    method @Nullable public String getDnn();
-    method @Nullable public String getOsAppId();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.data.TrafficDescriptor> CREATOR;
-  }
-
 }
 
 package android.telephony.euicc {
@@ -13275,6 +13379,7 @@
     method @Nullable public android.telephony.ims.RcsContactPresenceTuple getCapabilityTuple(@NonNull String);
     method @NonNull public java.util.List<android.telephony.ims.RcsContactPresenceTuple> getCapabilityTuples();
     method @NonNull public android.net.Uri getContactUri();
+    method @NonNull public java.util.Set<java.lang.String> getFeatureTags();
     method public int getRequestResult();
     method public int getSourceType();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
@@ -13289,6 +13394,14 @@
     field public static final int SOURCE_TYPE_NETWORK = 0; // 0x0
   }
 
+  public static final class RcsContactUceCapability.OptionsBuilder {
+    ctor public RcsContactUceCapability.OptionsBuilder(@NonNull android.net.Uri);
+    method @NonNull public android.telephony.ims.RcsContactUceCapability.OptionsBuilder addFeatureTag(@NonNull String);
+    method @NonNull public android.telephony.ims.RcsContactUceCapability.OptionsBuilder addFeatureTags(@NonNull java.util.Set<java.lang.String>);
+    method @NonNull public android.telephony.ims.RcsContactUceCapability build();
+    method @NonNull public android.telephony.ims.RcsContactUceCapability.OptionsBuilder setRequestResult(int);
+  }
+
   public static final class RcsContactUceCapability.PresenceBuilder {
     ctor public RcsContactUceCapability.PresenceBuilder(@NonNull android.net.Uri, int, int);
     method @NonNull public android.telephony.ims.RcsContactUceCapability.PresenceBuilder addCapabilityTuple(@NonNull android.telephony.ims.RcsContactPresenceTuple);
@@ -13558,13 +13671,13 @@
     ctor @Deprecated public RcsFeature();
     ctor public RcsFeature(@NonNull java.util.concurrent.Executor);
     method public void changeEnabledCapabilities(@NonNull android.telephony.ims.feature.CapabilityChangeRequest, @NonNull android.telephony.ims.feature.ImsFeature.CapabilityCallbackProxy);
-    method @NonNull public android.telephony.ims.stub.RcsCapabilityExchangeImplBase createCapabilityExchangeImpl(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.stub.CapabilityExchangeEventListener);
+    method @NonNull public android.telephony.ims.stub.RcsCapabilityExchangeImplBase createCapabilityExchangeImpl(@NonNull android.telephony.ims.stub.CapabilityExchangeEventListener);
+    method public void destroyCapabilityExchangeImpl(@NonNull android.telephony.ims.stub.RcsCapabilityExchangeImplBase);
     method public final void notifyCapabilitiesStatusChanged(@NonNull android.telephony.ims.feature.RcsFeature.RcsImsCapabilities);
     method public void onFeatureReady();
     method public void onFeatureRemoved();
     method public boolean queryCapabilityConfiguration(int, int);
     method @NonNull public final android.telephony.ims.feature.RcsFeature.RcsImsCapabilities queryCapabilityStatus();
-    method public void removeCapabilityExchangeImpl(@NonNull android.telephony.ims.stub.RcsCapabilityExchangeImplBase);
   }
 
   public static class RcsFeature.RcsImsCapabilities extends android.telephony.ims.feature.ImsFeature.Capabilities {
@@ -13582,7 +13695,7 @@
 package android.telephony.ims.stub {
 
   public interface CapabilityExchangeEventListener {
-    method public void onRemoteCapabilityRequest(@NonNull android.net.Uri, @NonNull java.util.List<java.lang.String>, @NonNull android.telephony.ims.stub.CapabilityExchangeEventListener.OptionsRequestCallback) throws android.telephony.ims.ImsException;
+    method public void onRemoteCapabilityRequest(@NonNull android.net.Uri, @NonNull java.util.Set<java.lang.String>, @NonNull android.telephony.ims.stub.CapabilityExchangeEventListener.OptionsRequestCallback) throws android.telephony.ims.ImsException;
     method public void onRequestPublishCapabilities(int) throws android.telephony.ims.ImsException;
     method public void onUnpublish() throws android.telephony.ims.ImsException;
   }
@@ -13777,9 +13890,9 @@
   }
 
   public class RcsCapabilityExchangeImplBase {
-    ctor public RcsCapabilityExchangeImplBase(@NonNull java.util.concurrent.Executor);
+    ctor public RcsCapabilityExchangeImplBase();
     method public void publishCapabilities(@NonNull String, @NonNull android.telephony.ims.stub.RcsCapabilityExchangeImplBase.PublishResponseCallback);
-    method public void sendOptionsCapabilityRequest(@NonNull android.net.Uri, @NonNull java.util.List<java.lang.String>, @NonNull android.telephony.ims.stub.RcsCapabilityExchangeImplBase.OptionsResponseCallback);
+    method public void sendOptionsCapabilityRequest(@NonNull android.net.Uri, @NonNull java.util.Set<java.lang.String>, @NonNull android.telephony.ims.stub.RcsCapabilityExchangeImplBase.OptionsResponseCallback);
     method public void subscribeForCapabilities(@NonNull java.util.Collection<android.net.Uri>, @NonNull android.telephony.ims.stub.RcsCapabilityExchangeImplBase.SubscribeResponseCallback);
     field public static final int COMMAND_CODE_FETCH_ERROR = 3; // 0x3
     field public static final int COMMAND_CODE_GENERIC_FAILURE = 1; // 0x1
@@ -13995,7 +14108,7 @@
 package android.uwb {
 
   public final class AngleMeasurement implements android.os.Parcelable {
-    ctor public AngleMeasurement(double, double, double);
+    ctor public AngleMeasurement(@FloatRange(from=-3.141592653589793, to=3.141592653589793) double, @FloatRange(from=0.0, to=3.141592653589793) double, @FloatRange(from=0.0, to=1.0) double);
     method public int describeContents();
     method @FloatRange(from=0.0, to=1.0) public double getConfidenceLevel();
     method @FloatRange(from=0.0, to=3.141592653589793) public double getErrorRadians();
@@ -14239,14 +14352,14 @@
 
 package android.view.translation {
 
+  public final class TranslationCapability implements android.os.Parcelable {
+    ctor public TranslationCapability(int, @NonNull android.view.translation.TranslationSpec, @NonNull android.view.translation.TranslationSpec, boolean, int);
+  }
+
   public final class UiTranslationManager {
-    method @RequiresPermission(android.Manifest.permission.MANAGE_UI_TRANSLATION) public void finishTranslation(int);
     method @RequiresPermission(android.Manifest.permission.MANAGE_UI_TRANSLATION) public void finishTranslation(@NonNull android.app.assist.ActivityId);
-    method @RequiresPermission(android.Manifest.permission.MANAGE_UI_TRANSLATION) public void pauseTranslation(int);
     method @RequiresPermission(android.Manifest.permission.MANAGE_UI_TRANSLATION) public void pauseTranslation(@NonNull android.app.assist.ActivityId);
-    method @RequiresPermission(android.Manifest.permission.MANAGE_UI_TRANSLATION) public void resumeTranslation(int);
     method @RequiresPermission(android.Manifest.permission.MANAGE_UI_TRANSLATION) public void resumeTranslation(@NonNull android.app.assist.ActivityId);
-    method @RequiresPermission(android.Manifest.permission.MANAGE_UI_TRANSLATION) public void startTranslation(@NonNull android.view.translation.TranslationSpec, @NonNull android.view.translation.TranslationSpec, @NonNull java.util.List<android.view.autofill.AutofillId>, int);
     method @RequiresPermission(android.Manifest.permission.MANAGE_UI_TRANSLATION) public void startTranslation(@NonNull android.view.translation.TranslationSpec, @NonNull android.view.translation.TranslationSpec, @NonNull java.util.List<android.view.autofill.AutofillId>, @NonNull android.app.assist.ActivityId);
   }
 
@@ -14634,6 +14747,7 @@
     method public default boolean onCheckIsTextEditor();
     method public void onConfigurationChanged(android.content.res.Configuration);
     method public android.view.inputmethod.InputConnection onCreateInputConnection(android.view.inputmethod.EditorInfo);
+    method @Nullable public default void onCreateTranslationRequests(@NonNull long[], @NonNull int[], @NonNull java.util.function.Consumer<android.view.translation.ViewTranslationRequest>);
     method public void onDetachedFromWindow();
     method public boolean onDragEvent(android.view.DragEvent);
     method public void onDraw(android.graphics.Canvas);
@@ -14658,6 +14772,7 @@
     method public void onStartTemporaryDetach();
     method public boolean onTouchEvent(android.view.MotionEvent);
     method public boolean onTrackballEvent(android.view.MotionEvent);
+    method public default void onTranslationResponse(@NonNull android.util.LongSparseArray<android.view.translation.ViewTranslationResponse>);
     method public void onVisibilityChanged(android.view.View, int);
     method public void onWindowFocusChanged(boolean);
     method public void onWindowVisibilityChanged(int);
diff --git a/core/api/system-removed.txt b/core/api/system-removed.txt
index 0c02c43..b50b8dd 100644
--- a/core/api/system-removed.txt
+++ b/core/api/system-removed.txt
@@ -48,6 +48,14 @@
 
 }
 
+package android.bluetooth {
+
+  public final class BluetoothHeadset implements android.bluetooth.BluetoothProfile {
+    method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean setPriority(android.bluetooth.BluetoothDevice, int);
+  }
+
+}
+
 package android.content {
 
   public class Intent implements java.lang.Cloneable android.os.Parcelable {
@@ -181,3 +189,14 @@
 
 }
 
+package android.view.translation {
+
+  public final class UiTranslationManager {
+    method @Deprecated @RequiresPermission(android.Manifest.permission.MANAGE_UI_TRANSLATION) public void finishTranslation(int);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.MANAGE_UI_TRANSLATION) public void pauseTranslation(int);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.MANAGE_UI_TRANSLATION) public void resumeTranslation(int);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.MANAGE_UI_TRANSLATION) public void startTranslation(@NonNull android.view.translation.TranslationSpec, @NonNull android.view.translation.TranslationSpec, @NonNull java.util.List<android.view.autofill.AutofillId>, int);
+  }
+
+}
+
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 4be6206..56b0a9d 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -29,12 +29,12 @@
     field public static final String NETWORK_STACK = "android.permission.NETWORK_STACK";
     field public static final String OVERRIDE_DISPLAY_MODE_REQUESTS = "android.permission.OVERRIDE_DISPLAY_MODE_REQUESTS";
     field public static final String QUERY_AUDIO_STATE = "android.permission.QUERY_AUDIO_STATE";
-    field public static final String QUERY_USERS = "android.permission.QUERY_USERS";
     field public static final String READ_CELL_BROADCASTS = "android.permission.READ_CELL_BROADCASTS";
     field public static final String READ_PRIVILEGED_PHONE_STATE = "android.permission.READ_PRIVILEGED_PHONE_STATE";
     field public static final String RECORD_BACKGROUND_AUDIO = "android.permission.RECORD_BACKGROUND_AUDIO";
     field public static final String REMOVE_TASKS = "android.permission.REMOVE_TASKS";
     field public static final String RESET_APP_ERRORS = "android.permission.RESET_APP_ERRORS";
+    field public static final String SET_AND_VERIFY_LOCKSCREEN_CREDENTIALS = "android.permission.SET_AND_VERIFY_LOCKSCREEN_CREDENTIALS";
     field public static final String START_TASKS_FROM_RECENTS = "android.permission.START_TASKS_FROM_RECENTS";
     field public static final String SUSPEND_APPS = "android.permission.SUSPEND_APPS";
     field public static final String TEST_BIOMETRIC = "android.permission.TEST_BIOMETRIC";
@@ -107,7 +107,6 @@
     method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public boolean stopUser(int, boolean);
     method @RequiresPermission(android.Manifest.permission.CHANGE_CONFIGURATION) public boolean updateMccMncConfiguration(@NonNull String, @NonNull String);
     method @RequiresPermission(android.Manifest.permission.DUMP) public void waitForBroadcastIdle();
-    field public static final long DROP_CLOSE_SYSTEM_DIALOGS = 174664120L; // 0xa6929b8L
     field public static final long LOCK_DOWN_CLOSE_SYSTEM_DIALOGS = 174664365L; // 0xa692aadL
     field public static final int PROCESS_CAPABILITY_ALL = 15; // 0xf
     field public static final int PROCESS_CAPABILITY_ALL_EXPLICIT = 1; // 0x1
@@ -221,6 +220,7 @@
     method @RequiresPermission("android.permission.MANAGE_APPOPS") public void rebootHistory(long);
     method @RequiresPermission("android.permission.MANAGE_APPOPS") public void reloadNonHistoricalState();
     method @RequiresPermission("android.permission.MANAGE_APPOPS") public void resetHistoryParameters();
+    method @RequiresPermission("android.permission.MANAGE_APPOPS") public void resetPackageOpsNoHistory(@NonNull String);
     method @RequiresPermission("android.permission.MANAGE_APPOPS") public void setHistoryParameters(int, long, int);
     method @RequiresPermission("android.permission.MANAGE_APP_OPS_MODES") public void setMode(int, int, String, int);
     method public static int strOpToOp(@NonNull String);
@@ -234,6 +234,8 @@
     field public static final String KEY_FG_SERVICE_STATE_SETTLE_TIME = "fg_service_state_settle_time";
     field public static final String KEY_TOP_STATE_SETTLE_TIME = "top_state_settle_time";
     field public static final String OPSTR_MANAGE_ONGOING_CALLS = "android:manage_ongoing_calls";
+    field public static final String OPSTR_PHONE_CALL_CAMERA = "android:phone_call_camera";
+    field public static final String OPSTR_PHONE_CALL_MICROPHONE = "android:phone_call_microphone";
     field public static final String OPSTR_USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER = "android:use_icc_auth_with_device_identifier";
     field public static final int OP_COARSE_LOCATION = 0; // 0x0
     field public static final int OP_RECORD_AUDIO = 27; // 0x1b
@@ -251,6 +253,14 @@
     method public void offsetBeginAndEndTime(long);
   }
 
+  public class BroadcastOptions {
+    ctor public BroadcastOptions(@NonNull android.os.Bundle);
+    method public long getTemporaryAppAllowlistDuration();
+    method @Nullable public String getTemporaryAppAllowlistReason();
+    method public int getTemporaryAppAllowlistReasonCode();
+    method public int getTemporaryAppAllowlistType();
+  }
+
   public class DownloadManager {
     field public static final String COLUMN_MEDIASTORE_URI = "mediastore_uri";
   }
@@ -271,6 +281,10 @@
     method public abstract void onHomeVisibilityChanged(boolean);
   }
 
+  public class Notification implements android.os.Parcelable {
+    method public boolean shouldShowForegroundImmediately();
+  }
+
   public final class NotificationChannel implements android.os.Parcelable {
     method public int getOriginalImportance();
     method public boolean isBlockable();
@@ -649,6 +663,11 @@
 
 package android.content {
 
+  public final class AttributionSource implements android.os.Parcelable {
+    ctor public AttributionSource(int, @Nullable String, @Nullable String);
+    ctor public AttributionSource(int, @Nullable String, @Nullable String, @Nullable android.content.AttributionSource);
+  }
+
   public final class AutofillOptions implements android.os.Parcelable {
     ctor public AutofillOptions(int, boolean);
     method public int describeContents();
@@ -819,6 +838,7 @@
     method public int describeContents();
     method public android.os.UserHandle getUserHandle();
     method public boolean isAdmin();
+    method public boolean isCloneProfile();
     method public boolean isDemo();
     method public boolean isEnabled();
     method public boolean isEphemeral();
@@ -1134,10 +1154,13 @@
   }
 
   public final class DisplayManager {
-    method @RequiresPermission(android.Manifest.permission.MODIFY_REFRESH_RATE_SWITCHING_TYPE) public int getRefreshRateSwitchingType();
+    method public boolean areUserDisabledHdrTypesAllowed();
+    method @NonNull public int[] getUserDisabledHdrTypes();
     method public boolean isMinimalPostProcessingRequested(int);
+    method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setAreUserDisabledHdrTypesAllowed(boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_REFRESH_RATE_SWITCHING_TYPE) public void setRefreshRateSwitchingType(int);
     method @RequiresPermission(android.Manifest.permission.OVERRIDE_DISPLAY_MODE_REQUESTS) public void setShouldAlwaysRespectAppRequestedMode(boolean);
+    method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setUserDisabledHdrTypes(@NonNull int[]);
     method @RequiresPermission(android.Manifest.permission.OVERRIDE_DISPLAY_MODE_REQUESTS) public boolean shouldAlwaysRespectAppRequestedMode();
     field public static final int SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS = 2; // 0x2
     field public static final int SWITCHING_TYPE_NONE = 0; // 0x0
@@ -1353,9 +1376,12 @@
   }
 
   public class AudioManager {
+    method @RequiresPermission("android.permission.QUERY_AUDIO_STATE") public int abandonAudioFocusForTest(@NonNull android.media.AudioFocusRequest, @NonNull String);
     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 public boolean hasRegisteredDynamicPolicy();
     method @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_ROUTING, android.Manifest.permission.QUERY_AUDIO_STATE}) public boolean isFullVolumeDevice();
+    method @RequiresPermission("android.permission.QUERY_AUDIO_STATE") public int requestAudioFocusForTest(@NonNull android.media.AudioFocusRequest, @NonNull String, int, int);
   }
 
   public static final class AudioRecord.MetricsConstants {
@@ -1475,6 +1501,14 @@
 
 }
 
+package android.media.metrics {
+
+  public final class LogSessionId {
+    ctor public LogSessionId(@NonNull String);
+  }
+
+}
+
 package android.media.tv {
 
   public final class TvInputManager {
@@ -1622,6 +1656,7 @@
     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
   }
 
@@ -1696,6 +1731,7 @@
     method public static android.os.VibrationEffect get(int, boolean);
     method @Nullable public static android.os.VibrationEffect get(android.net.Uri, android.content.Context);
     method public abstract long getDuration();
+    method @NonNull public static android.os.VibrationEffect.WaveformBuilder startWaveform();
     field public static final int EFFECT_POP = 4; // 0x4
     field public static final int EFFECT_STRENGTH_LIGHT = 0; // 0x0
     field public static final int EFFECT_STRENGTH_MEDIUM = 1; // 0x1
@@ -1705,35 +1741,30 @@
     field public static final int[] RINGTONES;
   }
 
-  public static class VibrationEffect.OneShot extends android.os.VibrationEffect implements android.os.Parcelable {
-    ctor public VibrationEffect.OneShot(android.os.Parcel);
-    ctor public VibrationEffect.OneShot(long, int);
-    method public int getAmplitude();
-    method public long getDuration();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.os.VibrationEffect.OneShot> CREATOR;
-  }
-
-  public static class VibrationEffect.Prebaked extends android.os.VibrationEffect implements android.os.Parcelable {
-    ctor public VibrationEffect.Prebaked(android.os.Parcel);
-    ctor public VibrationEffect.Prebaked(int, boolean, int);
-    method public long getDuration();
-    method public int getEffectStrength();
-    method public int getId();
-    method public boolean shouldFallback();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.os.VibrationEffect.Prebaked> CREATOR;
-  }
-
-  public static class VibrationEffect.Waveform extends android.os.VibrationEffect implements android.os.Parcelable {
-    ctor public VibrationEffect.Waveform(android.os.Parcel);
-    ctor public VibrationEffect.Waveform(long[], int[], int);
-    method public int[] getAmplitudes();
+  public static final class VibrationEffect.Composed extends android.os.VibrationEffect {
+    method @NonNull public android.os.VibrationEffect.Composed applyEffectStrength(int);
     method public long getDuration();
     method public int getRepeatIndex();
-    method public long[] getTimings();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.os.VibrationEffect.Waveform> CREATOR;
+    method @NonNull public java.util.List<android.os.vibrator.VibrationEffectSegment> getSegments();
+    method @NonNull public android.os.VibrationEffect.Composed resolve(int);
+    method @NonNull public android.os.VibrationEffect.Composed scale(float);
+    method public void validate();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.os.VibrationEffect.Composed> CREATOR;
+  }
+
+  public static final class VibrationEffect.Composition {
+    method @NonNull public android.os.VibrationEffect.Composition addEffect(@NonNull android.os.VibrationEffect);
+    method @NonNull public android.os.VibrationEffect.Composition addEffect(@NonNull android.os.VibrationEffect, @IntRange(from=0) int);
+  }
+
+  public static final class VibrationEffect.WaveformBuilder {
+    method @NonNull public android.os.VibrationEffect.WaveformBuilder addRamp(@FloatRange(from=0.0f, to=1.0f) float, @IntRange(from=0) int);
+    method @NonNull public android.os.VibrationEffect.WaveformBuilder addRamp(@FloatRange(from=0.0f, to=1.0f) float, @FloatRange(from=-1.0F, to=1.0f) float, @IntRange(from=0) int);
+    method @NonNull public android.os.VibrationEffect.WaveformBuilder addStep(@FloatRange(from=0.0f, to=1.0f) float, @IntRange(from=0) int);
+    method @NonNull public android.os.VibrationEffect.WaveformBuilder addStep(@FloatRange(from=0.0f, to=1.0f) float, @FloatRange(from=-1.0F, to=1.0f) float, @IntRange(from=0) int);
+    method @NonNull public android.os.VibrationEffect build();
+    method @NonNull public android.os.VibrationEffect build(int);
   }
 
   public class VintfObject {
@@ -1834,6 +1865,7 @@
   public class StorageManager {
     method @NonNull public static java.util.UUID convert(@NonNull String);
     method @NonNull public static String convert(@NonNull java.util.UUID);
+    method public boolean isAppIoBlocked(@NonNull java.util.UUID, int, int, int);
     method public static boolean isUserKeyUnlocked(int);
   }
 
@@ -1850,8 +1882,93 @@
 
 }
 
+package android.os.vibrator {
+
+  public final class PrebakedSegment extends android.os.vibrator.VibrationEffectSegment {
+    method @NonNull public android.os.vibrator.PrebakedSegment applyEffectStrength(int);
+    method public int describeContents();
+    method public long getDuration();
+    method public int getEffectId();
+    method public int getEffectStrength();
+    method public boolean hasNonZeroAmplitude();
+    method @NonNull public android.os.vibrator.PrebakedSegment resolve(int);
+    method @NonNull public android.os.vibrator.PrebakedSegment scale(float);
+    method public boolean shouldFallback();
+    method public void validate();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.os.vibrator.PrebakedSegment> CREATOR;
+  }
+
+  public final class PrimitiveSegment extends android.os.vibrator.VibrationEffectSegment {
+    method @NonNull public android.os.vibrator.PrimitiveSegment applyEffectStrength(int);
+    method public int describeContents();
+    method public int getDelay();
+    method public long getDuration();
+    method public int getPrimitiveId();
+    method public float getScale();
+    method public boolean hasNonZeroAmplitude();
+    method @NonNull public android.os.vibrator.PrimitiveSegment resolve(int);
+    method @NonNull public android.os.vibrator.PrimitiveSegment scale(float);
+    method public void validate();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.os.vibrator.PrimitiveSegment> CREATOR;
+  }
+
+  public final class RampSegment extends android.os.vibrator.VibrationEffectSegment {
+    method @NonNull public android.os.vibrator.RampSegment applyEffectStrength(int);
+    method public int describeContents();
+    method public long getDuration();
+    method public float getEndAmplitude();
+    method public float getEndFrequency();
+    method public float getStartAmplitude();
+    method public float getStartFrequency();
+    method public boolean hasNonZeroAmplitude();
+    method @NonNull public android.os.vibrator.RampSegment resolve(int);
+    method @NonNull public android.os.vibrator.RampSegment scale(float);
+    method public void validate();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.os.vibrator.RampSegment> CREATOR;
+  }
+
+  public final class StepSegment extends android.os.vibrator.VibrationEffectSegment {
+    method @NonNull public android.os.vibrator.StepSegment applyEffectStrength(int);
+    method public int describeContents();
+    method public float getAmplitude();
+    method public long getDuration();
+    method public float getFrequency();
+    method public boolean hasNonZeroAmplitude();
+    method @NonNull public android.os.vibrator.StepSegment resolve(int);
+    method @NonNull public android.os.vibrator.StepSegment scale(float);
+    method public void validate();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.os.vibrator.StepSegment> CREATOR;
+  }
+
+  public abstract class VibrationEffectSegment implements android.os.Parcelable {
+    method @NonNull public abstract <T extends android.os.vibrator.VibrationEffectSegment> T applyEffectStrength(int);
+    method public abstract long getDuration();
+    method public abstract boolean hasNonZeroAmplitude();
+    method @NonNull public abstract <T extends android.os.vibrator.VibrationEffectSegment> T resolve(int);
+    method @NonNull public abstract <T extends android.os.vibrator.VibrationEffectSegment> T scale(float);
+    method public abstract void validate();
+    field @NonNull public static final android.os.Parcelable.Creator<android.os.vibrator.VibrationEffectSegment> CREATOR;
+  }
+
+}
+
 package android.permission {
 
+  public final class PermGroupUsage {
+    ctor public PermGroupUsage(@NonNull String, int, @NonNull String, long, boolean, boolean, @Nullable CharSequence);
+    method @Nullable public CharSequence getAttribution();
+    method public long getLastAccess();
+    method @NonNull public String getPackageName();
+    method @NonNull public String getPermGroupName();
+    method public int getUid();
+    method public boolean isActive();
+    method public boolean isPhoneCall();
+  }
+
   public final class PermissionControllerManager {
     method @RequiresPermission(android.Manifest.permission.GET_RUNTIME_PERMISSIONS) public void countPermissionApps(@NonNull java.util.List<java.lang.String>, int, @NonNull android.permission.PermissionControllerManager.OnCountPermissionAppsResultCallback, @Nullable android.os.Handler);
     method @RequiresPermission(android.Manifest.permission.GET_RUNTIME_PERMISSIONS) public void getAppPermissions(@NonNull String, @NonNull android.permission.PermissionControllerManager.OnGetAppPermissionResultCallback, @Nullable android.os.Handler);
@@ -1866,6 +1983,10 @@
     method public void onGetAppPermissions(@NonNull java.util.List<android.permission.RuntimePermissionPresentationInfo>);
   }
 
+  public final class PermissionManager {
+    method @NonNull @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public java.util.List<android.permission.PermGroupUsage> getIndicatorAppOpUsageData();
+  }
+
 }
 
 package android.print {
@@ -1925,6 +2046,7 @@
 
   public static final class Settings.Global extends android.provider.Settings.NameValueTable {
     field public static final String APP_OPS_CONSTANTS = "app_ops_constants";
+    field public static final String ARE_USER_DISABLED_HDR_FORMATS_ALLOWED = "are_user_disabled_hdr_formats_allowed";
     field public static final String AUTOMATIC_POWER_SAVE_MODE = "automatic_power_save_mode";
     field public static final String BATTERY_SAVER_CONSTANTS = "battery_saver_constants";
     field public static final String DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW = "enable_non_resizable_multi_window";
@@ -1939,6 +2061,7 @@
     field 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 USER_DISABLED_HDR_FORMATS = "user_disabled_hdr_formats";
     field public static final String USE_OPEN_WIFI_PACKAGE = "use_open_wifi_package";
   }
 
@@ -2254,6 +2377,7 @@
   public class ServiceState implements android.os.Parcelable {
     method public void addNetworkRegistrationInfo(android.telephony.NetworkRegistrationInfo);
     method public int getDataNetworkType();
+    method public int getDataRegState();
     method public void setCdmaSystemAndNetworkId(int, int);
     method public void setCellBandwidths(int[]);
     method public void setChannelNumber(int);
@@ -2488,6 +2612,7 @@
   }
 
   public final class Display {
+    method @NonNull public int[] getReportedHdrTypes();
     method @NonNull public android.graphics.ColorSpace[] getSupportedWideColorGamut();
     method public int getType();
     method public boolean hasAccess(int);
@@ -2538,7 +2663,9 @@
   public final class SurfaceControl implements android.os.Parcelable {
     ctor public SurfaceControl(@NonNull android.view.SurfaceControl, @NonNull String);
     method public static long acquireFrameRateFlexibilityToken();
+    method @NonNull public static android.os.IBinder getInternalDisplayToken();
     method public boolean isSameSurface(@NonNull android.view.SurfaceControl);
+    method public static void overrideHdrTypes(@NonNull android.os.IBinder, @NonNull int[]);
     method public static void releaseFrameRateFlexibilityToken(long);
   }
 
@@ -2750,6 +2877,14 @@
 
 }
 
+package android.view.displayhash {
+
+  public final class DisplayHashManager {
+    method @RequiresPermission("android.permission.READ_FRAME_BUFFER") public void setDisplayHashThrottlingEnabled(boolean);
+  }
+
+}
+
 package android.view.inputmethod {
 
   public final class InlineSuggestion implements android.os.Parcelable {
diff --git a/core/api/test-lint-baseline.txt b/core/api/test-lint-baseline.txt
index a536efb..1833ed5 100644
--- a/core/api/test-lint-baseline.txt
+++ b/core/api/test-lint-baseline.txt
@@ -1515,30 +1515,6 @@
     
 MissingNullability: android.os.VibrationEffect#get(int, boolean):
     
-MissingNullability: android.os.VibrationEffect.OneShot#OneShot(android.os.Parcel) parameter #0:
-    
-MissingNullability: android.os.VibrationEffect.OneShot#scale(float, int):
-    
-MissingNullability: android.os.VibrationEffect.OneShot#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.os.VibrationEffect.Prebaked#Prebaked(android.os.Parcel) parameter #0:
-    
-MissingNullability: android.os.VibrationEffect.Prebaked#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.os.VibrationEffect.Waveform#Waveform(android.os.Parcel) parameter #0:
-    
-MissingNullability: android.os.VibrationEffect.Waveform#Waveform(long[], int[], int) parameter #0:
-    
-MissingNullability: android.os.VibrationEffect.Waveform#Waveform(long[], int[], int) parameter #1:
-    
-MissingNullability: android.os.VibrationEffect.Waveform#getAmplitudes():
-    
-MissingNullability: android.os.VibrationEffect.Waveform#getTimings():
-    
-MissingNullability: android.os.VibrationEffect.Waveform#scale(float, int):
-    
-MissingNullability: android.os.VibrationEffect.Waveform#writeToParcel(android.os.Parcel, int) parameter #0:
-    
 MissingNullability: android.os.VintfObject#getHalNamesAndVersions():
     
 MissingNullability: android.os.VintfObject#getSepolicyVersion():
@@ -2739,12 +2715,6 @@
     
 ParcelConstructor: android.os.StrictMode.ViolationInfo#ViolationInfo(android.os.Parcel):
     
-ParcelConstructor: android.os.VibrationEffect.OneShot#OneShot(android.os.Parcel):
-    
-ParcelConstructor: android.os.VibrationEffect.Prebaked#Prebaked(android.os.Parcel):
-    
-ParcelConstructor: android.os.VibrationEffect.Waveform#Waveform(android.os.Parcel):
-    
 ParcelConstructor: android.os.health.HealthStatsParceler#HealthStatsParceler(android.os.Parcel):
     
 ParcelConstructor: android.service.notification.SnoozeCriterion#SnoozeCriterion(android.os.Parcel):
@@ -2773,12 +2743,6 @@
     
 ParcelCreator: android.net.metrics.ValidationProbeEvent:
     
-ParcelCreator: android.os.VibrationEffect.OneShot:
-    
-ParcelCreator: android.os.VibrationEffect.Prebaked:
-    
-ParcelCreator: android.os.VibrationEffect.Waveform:
-    
 ParcelCreator: android.service.autofill.InternalOnClickAction:
     
 ParcelCreator: android.service.autofill.InternalSanitizer:
@@ -2797,12 +2761,6 @@
     
 ParcelNotFinal: android.os.IncidentManager.IncidentReport:
     
-ParcelNotFinal: android.os.VibrationEffect.OneShot:
-    
-ParcelNotFinal: android.os.VibrationEffect.Prebaked:
-    
-ParcelNotFinal: android.os.VibrationEffect.Waveform:
-    
 ParcelNotFinal: android.os.health.HealthStatsParceler:
     
 ParcelNotFinal: android.service.autofill.InternalOnClickAction:
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 86e2723..0f38b5f 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -642,7 +642,7 @@
  *     protected void onCreate(Bundle savedInstanceState) {
  *         super.onCreate(savedInstanceState);
  *
- *         SharedPreferences mPrefs = getSharedPreferences();
+ *         mPrefs = getSharedPreferences(getLocalClassName(), MODE_PRIVATE);
  *         mCurViewMode = mPrefs.getInt("view_mode", DAY_VIEW_MODE);
  *     }
  *
@@ -5246,13 +5246,40 @@
         if (requestCode < 0) {
             throw new IllegalArgumentException("requestCode should be >= 0");
         }
+
         if (mHasCurrentPermissionsRequest) {
             Log.w(TAG, "Can request only one set of permissions at a time");
             // Dispatch the callback with empty arrays which means a cancellation.
             onRequestPermissionsResult(requestCode, new String[0], new int[0]);
             return;
         }
-        Intent intent = getPackageManager().buildRequestPermissionsIntent(permissions);
+
+        List<String> filteredPermissions = null;
+
+        if (!getAttributionSource().getRenouncedPermissions().isEmpty()) {
+            final int permissionCount = permissions.length;
+            for (int i = 0; i < permissionCount; i++) {
+                if (getAttributionSource().getRenouncedPermissions().contains(permissions[i])) {
+                    if (filteredPermissions == null) {
+                        filteredPermissions = new ArrayList<>(i);
+                        for (int j = 0; j < i; j++) {
+                            filteredPermissions.add(permissions[i]);
+                        }
+                    }
+                } else if (filteredPermissions != null) {
+                    filteredPermissions.add(permissions[i]);
+                }
+            }
+        }
+
+        final Intent intent;
+        if (filteredPermissions == null) {
+            intent = getPackageManager().buildRequestPermissionsIntent(permissions);
+        } else {
+            intent = getPackageManager().buildRequestPermissionsIntent(
+                    filteredPermissions.toArray(new String[0]));
+        }
+
         startActivityForResult(REQUEST_PERMISSIONS_WHO_PREFIX, intent, requestCode, null);
         mHasCurrentPermissionsRequest = true;
     }
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 3fedda3..36c66e5 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -901,7 +901,6 @@
      *
      * @hide
      */
-    @TestApi
     @ChangeId
     public static final long DROP_CLOSE_SYSTEM_DIALOGS = 174664120L;
 
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index f7a3514..a7d5b05 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -30,8 +30,8 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.IBinder;
-import android.os.PowerWhitelistManager.ReasonCode;
-import android.os.PowerWhitelistManager.TempAllowListType;
+import android.os.PowerExemptionManager.ReasonCode;
+import android.os.PowerExemptionManager.TempAllowListType;
 import android.os.TransactionTooLargeException;
 import android.os.WorkSource;
 import android.util.ArraySet;
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index a1dce77..006b2b5 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -1606,7 +1606,8 @@
 
     /**
      * Sets a launch cookie that can be used to track the activity and task that are launch as a
-     * result of this option.
+     * result of this option. If the launched activity is a trampoline that starts another activity
+     * immediately, the cookie will be transferred to the next activity.
      *
      * @hide
      */
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index c1d8541..7298d87 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -2328,7 +2328,7 @@
     }
 
     @UnsupportedAppUsage
-    final Handler getHandler() {
+    public Handler getHandler() {
         return mH;
     }
 
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 27b19bc..f76e1c0 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -50,6 +50,7 @@
 import android.os.Looper;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.content.AttributionSource;
 import android.os.Process;
 import android.os.RemoteCallback;
 import android.os.RemoteException;
@@ -1073,6 +1074,8 @@
     /** @hide */
     @UnsupportedAppUsage
     public static final int OP_BLUETOOTH_SCAN = AppProtoEnums.APP_OP_BLUETOOTH_SCAN;
+    /** @hide */
+    public static final int OP_BLUETOOTH_CONNECT = AppProtoEnums.APP_OP_BLUETOOTH_CONNECT;
     /** @hide Use the BiometricPrompt/BiometricManager APIs. */
     public static final int OP_USE_BIOMETRIC = AppProtoEnums.APP_OP_USE_BIOMETRIC;
     /** @hide Physical activity recognition. */
@@ -1221,7 +1224,7 @@
 
     /** @hide */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    public static final int _NUM_OP = 111;
+    public static final int _NUM_OP = 112;
 
     /** Access to coarse location information. */
     public static final String OPSTR_COARSE_LOCATION = "android:coarse_location";
@@ -1465,6 +1468,8 @@
     public static final String OPSTR_START_FOREGROUND = "android:start_foreground";
     /** @hide */
     public static final String OPSTR_BLUETOOTH_SCAN = "android:bluetooth_scan";
+    /** @hide */
+    public static final String OPSTR_BLUETOOTH_CONNECT = "android:bluetooth_connect";
 
     /** @hide Use the BiometricPrompt/BiometricManager APIs. */
     public static final String OPSTR_USE_BIOMETRIC = "android:use_biometric";
@@ -1557,12 +1562,14 @@
      *
      * @hide
      */
+    @TestApi
     public static final String OPSTR_PHONE_CALL_MICROPHONE = "android:phone_call_microphone";
     /**
      * Phone call is using camera
      *
      * @hide
      */
+    @TestApi
     public static final String OPSTR_PHONE_CALL_CAMERA = "android:phone_call_camera";
 
     /**
@@ -1696,6 +1703,9 @@
             OP_WRITE_MEDIA_VIDEO,
             OP_READ_MEDIA_IMAGES,
             OP_WRITE_MEDIA_IMAGES,
+            // Nearby devices
+            OP_BLUETOOTH_SCAN,
+            OP_BLUETOOTH_CONNECT,
 
             // APPOP PERMISSIONS
             OP_ACCESS_NOTIFICATIONS,
@@ -1801,7 +1811,7 @@
             OP_ACCEPT_HANDOVER,                 // ACCEPT_HANDOVER
             OP_MANAGE_IPSEC_TUNNELS,            // MANAGE_IPSEC_HANDOVERS
             OP_START_FOREGROUND,                // START_FOREGROUND
-            OP_COARSE_LOCATION,                 // BLUETOOTH_SCAN
+            OP_BLUETOOTH_SCAN,                  // BLUETOOTH_SCAN
             OP_USE_BIOMETRIC,                   // BIOMETRIC
             OP_ACTIVITY_RECOGNITION,            // ACTIVITY_RECOGNITION
             OP_SMS_FINANCIAL_TRANSACTIONS,      // SMS_FINANCIAL_TRANSACTIONS
@@ -1835,6 +1845,7 @@
             OP_FINE_LOCATION,                   // OP_FINE_LOCATION_SOURCE
             OP_COARSE_LOCATION,                 // OP_COARSE_LOCATION_SOURCE
             OP_MANAGE_MEDIA,                    // MANAGE_MEDIA
+            OP_BLUETOOTH_CONNECT,               // OP_BLUETOOTH_CONNECT
     };
 
     /**
@@ -1952,6 +1963,7 @@
             OPSTR_FINE_LOCATION_SOURCE,
             OPSTR_COARSE_LOCATION_SOURCE,
             OPSTR_MANAGE_MEDIA,
+            OPSTR_BLUETOOTH_CONNECT,
     };
 
     /**
@@ -2070,6 +2082,7 @@
             "FINE_LOCATION_SOURCE",
             "COARSE_LOCATION_SOURCE",
             "MANAGE_MEDIA",
+            "BLUETOOTH_CONNECT",
     };
 
     /**
@@ -2155,7 +2168,7 @@
             Manifest.permission.ACCEPT_HANDOVER,
             Manifest.permission.MANAGE_IPSEC_TUNNELS,
             Manifest.permission.FOREGROUND_SERVICE,
-            null, // no permission for OP_BLUETOOTH_SCAN
+            Manifest.permission.BLUETOOTH_SCAN,
             Manifest.permission.USE_BIOMETRIC,
             Manifest.permission.ACTIVITY_RECOGNITION,
             Manifest.permission.SMS_FINANCIAL_TRANSACTIONS,
@@ -2189,6 +2202,7 @@
             null, // no permission for OP_ACCESS_FINE_LOCATION_SOURCE,
             null, // no permission for OP_ACCESS_COARSE_LOCATION_SOURCE,
             Manifest.permission.MANAGE_MEDIA,
+            Manifest.permission.BLUETOOTH_CONNECT,
     };
 
     /**
@@ -2308,6 +2322,7 @@
             null, // ACCESS_FINE_LOCATION_SOURCE
             null, // ACCESS_COARSE_LOCATION_SOURCE
             null, // MANAGE_MEDIA
+            null, // BLUETOOTH_CONNECT
     };
 
     /**
@@ -2426,6 +2441,7 @@
             null, // ACCESS_FINE_LOCATION_SOURCE
             null, // ACCESS_COARSE_LOCATION_SOURCE
             null, // MANAGE_MEDIA
+            null, // BLUETOOTH_CONNECT
     };
 
     /**
@@ -2543,6 +2559,7 @@
             AppOpsManager.MODE_ALLOWED, // ACCESS_FINE_LOCATION_SOURCE
             AppOpsManager.MODE_ALLOWED, // ACCESS_COARSE_LOCATION_SOURCE
             AppOpsManager.MODE_DEFAULT, // MANAGE_MEDIA
+            AppOpsManager.MODE_ALLOWED, // BLUETOOTH_CONNECT
     };
 
     /**
@@ -2664,6 +2681,7 @@
             false, // ACCESS_FINE_LOCATION_SOURCE
             false, // ACCESS_COARSE_LOCATION_SOURCE
             false, // MANAGE_MEDIA
+            false, // BLUETOOTH_CONNECT
     };
 
     /**
@@ -5938,7 +5956,7 @@
          *
          * @return The historical ops for the attribution.
          */
-        public @Nullable AttributedHistoricalOps getAttributedOps(@NonNull String attributionTag) {
+        public @Nullable AttributedHistoricalOps getAttributedOps(@Nullable String attributionTag) {
             if (mAttributedHistoricalOps == null) {
                 return null;
             }
@@ -6463,7 +6481,7 @@
          * Gets number of discrete historical app ops.
          *
          * @return The number historical app ops.
-         * @see #getOpAt(int)
+         * @see #getDiscreteAccessAt(int)
          */
         public @IntRange(from = 0) int getDiscreteAccessCount() {
             if (mDiscreteAccesses == null) {
@@ -6477,7 +6495,7 @@
          *
          * @param index The index to lookup.
          * @return The op at the given index.
-         * @see #getOpCount()
+         * @see #getDiscreteAccessCount()
          */
         public @NonNull AttributedOpEntry getDiscreteAccessAt(@IntRange(from = 0) int index) {
             if (mDiscreteAccesses == null) {
@@ -7962,7 +7980,7 @@
         try {
             collectNoteOpCallsForValidation(op);
             int collectionMode = getNotedOpCollectionMode(uid, packageName, op);
-            boolean shouldCollectMessage = Process.myUid() == Process.SYSTEM_UID ? true : false;
+            boolean shouldCollectMessage = Process.myUid() == Process.SYSTEM_UID;
             if (collectionMode == COLLECT_ASYNC) {
                 if (message == null) {
                     // Set stack trace as default message
@@ -8016,14 +8034,9 @@
      */
     public int noteProxyOp(int op, @Nullable String proxiedPackageName, int proxiedUid,
             @Nullable String proxiedAttributionTag, @Nullable String message) {
-        int mode = noteProxyOpNoThrow(op, proxiedPackageName, proxiedUid, proxiedAttributionTag,
-                message);
-        if (mode == MODE_ERRORED) {
-            throw new SecurityException("Proxy package " + mContext.getOpPackageName()
-                    + " from uid " + Process.myUid() + " or calling package " + proxiedPackageName
-                    + " from uid " + proxiedUid + " not allowed to perform " + sOpNames[op]);
-        }
-        return mode;
+        return noteProxyOp(op, new AttributionSource(mContext.getAttributionSource(),
+                new AttributionSource(proxiedUid, proxiedPackageName, proxiedAttributionTag)),
+                message, /*skipProxyOperation*/ false);
     }
 
     /**
@@ -8052,6 +8065,36 @@
     }
 
     /**
+     * Make note of an application performing an operation on behalf of another application(s).
+     *
+     * @param op The operation to note. One of the OPSTR_* constants.
+     * @param attributionSource The permission identity for which to note.
+     * @param message A message describing the reason the op was noted
+     * @param skipProxyOperation Whether to skip the proxy note.
+     *
+     * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or {@link #MODE_IGNORED}
+     * if it is not allowed and should be silently ignored (without causing the app to crash).
+     *
+     * @throws SecurityException If the any proxying operations in the permission identityf
+     *     chain fails.
+     *
+     * @hide
+     */
+    public int noteProxyOp(@NonNull int op, @NonNull AttributionSource attributionSource,
+            @Nullable String message, boolean skipProxyOperation) {
+        final int mode = noteProxyOpNoThrow(op, attributionSource, message, skipProxyOperation);
+        if (mode == MODE_ERRORED) {
+            throw new SecurityException("Proxy package "
+                    + attributionSource.getPackageName()  + " from uid "
+                    + attributionSource.getUid() + " or calling package "
+                    + attributionSource.getNextPackageName() + " from uid "
+                    + attributionSource.getNextUid() + " not allowed to perform "
+                    + sOpNames[op]);
+        }
+        return mode;
+    }
+
+    /**
      * @deprecated Use {@link #noteProxyOpNoThrow(String, String, int, String, String)} instead
      */
     @Deprecated
@@ -8076,24 +8119,36 @@
      */
     public int noteProxyOpNoThrow(@NonNull String op, @Nullable String proxiedPackageName,
             int proxiedUid, @Nullable String proxiedAttributionTag, @Nullable String message) {
-        return noteProxyOpNoThrow(strOpToOp(op), proxiedPackageName, proxiedUid,
-                proxiedAttributionTag, message);
+        return noteProxyOpNoThrow(strOpToOp(op), new AttributionSource(
+                mContext.getAttributionSource(), new AttributionSource(proxiedUid,
+                        proxiedPackageName, proxiedAttributionTag)), message,
+                        /*skipProxyOperation*/ false);
     }
 
     /**
-     * @see #noteProxyOpNoThrow(String, String, int, String, String)
+     * Make note of an application performing an operation on behalf of another application(s).
+     *
+     * @param op The operation to note. One of the OPSTR_* constants.
+     * @param attributionSource The permission identity for which to note.
+     * @param message A message describing the reason the op was noted
+     * @param skipProxyOperation Whether to note op for the proxy
+     *
+     * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or {@link #MODE_IGNORED}
+     * if it is not allowed and should be silently ignored (without causing the app to crash).
      *
      * @hide
      */
     @SuppressWarnings("AndroidFrameworkClientSidePermissionCheck")
-    public int noteProxyOpNoThrow(int op, @Nullable String proxiedPackageName, int proxiedUid,
-            @Nullable String proxiedAttributionTag, @Nullable String message) {
+    public int noteProxyOpNoThrow(int op, @NonNull AttributionSource attributionSource,
+            @Nullable String message, boolean skipProxyOperation) {
         int myUid = Process.myUid();
 
         try {
             collectNoteOpCallsForValidation(op);
-            int collectionMode = getNotedOpCollectionMode(proxiedUid, proxiedPackageName, op);
-            boolean shouldCollectMessage = myUid == Process.SYSTEM_UID ? true : false;
+            int collectionMode = getNotedOpCollectionMode(
+                    attributionSource.getNextUid(),
+                    attributionSource.getNextAttributionTag(), op);
+            boolean shouldCollectMessage = (myUid == Process.SYSTEM_UID);
             if (collectionMode == COLLECT_ASYNC) {
                 if (message == null) {
                     // Set stack trace as default message
@@ -8102,20 +8157,19 @@
                 }
             }
 
-            int mode = mService.noteProxyOperation(op, proxiedUid, proxiedPackageName,
-                    proxiedAttributionTag, myUid, mContext.getOpPackageName(),
-                    mContext.getAttributionTag(), collectionMode == COLLECT_ASYNC, message,
-                    shouldCollectMessage);
+            int mode = mService.noteProxyOperation(op, attributionSource,
+                    collectionMode == COLLECT_ASYNC, message,
+                    shouldCollectMessage, skipProxyOperation);
 
             if (mode == MODE_ALLOWED) {
                 if (collectionMode == COLLECT_SELF) {
-                    collectNotedOpForSelf(op, proxiedAttributionTag);
+                    collectNotedOpForSelf(op, attributionSource.getNextAttributionTag());
                 } else if (collectionMode == COLLECT_SYNC
                         // Only collect app-ops when the proxy is trusted
                         && (mContext.checkPermission(Manifest.permission.UPDATE_APP_OPS_STATS, -1,
                         myUid) == PackageManager.PERMISSION_GRANTED ||
-                        Binder.getCallingUid() == proxiedUid)) {
-                    collectNotedOpSync(op, proxiedAttributionTag);
+                            Binder.getCallingUid() == attributionSource.getNextUid())) {
+                    collectNotedOpSync(op, attributionSource.getNextAttributionTag());
                 }
             }
 
@@ -8407,7 +8461,7 @@
         try {
             collectNoteOpCallsForValidation(op);
             int collectionMode = getNotedOpCollectionMode(uid, packageName, op);
-            boolean shouldCollectMessage = Process.myUid() == Process.SYSTEM_UID ? true : false;
+            boolean shouldCollectMessage = Process.myUid() == Process.SYSTEM_UID;
             if (collectionMode == COLLECT_ASYNC) {
                 if (message == null) {
                     // Set stack trace as default message
@@ -8433,6 +8487,7 @@
             throw e.rethrowFromSystemServer();
         }
     }
+
     /**
      * Report that an application has started executing a long-running operation on behalf of
      * another application when handling an IPC. This function will verify that the calling uid and
@@ -8453,19 +8508,45 @@
      */
     public int startProxyOp(@NonNull String op, int proxiedUid, @NonNull String proxiedPackageName,
             @Nullable String proxiedAttributionTag, @Nullable String message) {
-        final int mode = startProxyOpNoThrow(op, proxiedUid, proxiedPackageName,
-                proxiedAttributionTag, message);
+        return startProxyOp(op, new AttributionSource(mContext.getAttributionSource(),
+                new AttributionSource(proxiedUid, proxiedPackageName, proxiedAttributionTag)),
+                message, /*skipProxyOperation*/ false);
+    }
+
+    /**
+     * Report that an application has started executing a long-running operation on behalf of
+     * another application for the attribution chain specified by the {@link AttributionSource}}.
+     *
+     * @param op The op to note
+     * @param attributionSource The permission identity for which to check
+     * @param message A message describing the reason the op was noted
+     * @param skipProxyOperation Whether to skip the proxy start.
+     *
+     * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or {@link #MODE_IGNORED}
+     * if it is not allowed and should be silently ignored (without causing the app to crash).
+     *
+     * @throws SecurityException If the any proxying operations in the permission identity
+     *     chain fails.
+     *
+     * @hide
+     */
+    public int startProxyOp(@NonNull String op, @NonNull AttributionSource attributionSource,
+            @Nullable String message, boolean skipProxyOperation) {
+        final int mode = startProxyOpNoThrow(AppOpsManager.strOpToOp(op), attributionSource,
+                message, skipProxyOperation);
         if (mode == MODE_ERRORED) {
-            throw new SecurityException("Proxy package " + mContext.getOpPackageName()
-                    + " from uid " + Process.myUid() + " or calling package " + proxiedPackageName
-                    + " from uid " + proxiedUid + " not allowed to perform "
-                    + sOpNames[strOpToOp(op)]);
+            throw new SecurityException("Proxy package "
+                    + attributionSource.getPackageName()  + " from uid "
+                    + attributionSource.getUid() + " or calling package "
+                    + attributionSource.getNextPackageName() + " from uid "
+                    + attributionSource.getNextUid() + " not allowed to perform "
+                    + op);
         }
         return mode;
     }
 
     /**
-     *Like {@link #startProxyOp(String, int, String, String, String)} but instead
+     * Like {@link #startProxyOp(String, int, String, String, String)} but instead
      * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
      *
      * @see #startProxyOp(String, int, String, String, String)
@@ -8473,11 +8554,28 @@
     public int startProxyOpNoThrow(@NonNull String op, int proxiedUid,
             @NonNull String proxiedPackageName, @Nullable String proxiedAttributionTag,
             @Nullable String message) {
-        try {
-            int opInt = strOpToOp(op);
+        return startProxyOpNoThrow(AppOpsManager.strOpToOp(op), new AttributionSource(
+                mContext.getAttributionSource(), new AttributionSource(proxiedUid,
+                        proxiedPackageName, proxiedAttributionTag)), message,
+                /*skipProxyOperation*/ false);
+    }
 
-            collectNoteOpCallsForValidation(opInt);
-            int collectionMode = getNotedOpCollectionMode(proxiedUid, proxiedPackageName, opInt);
+    /**
+     * Like {@link #startProxyOp(String, AttributionSource, String)} but instead
+     * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED} and
+     * the checks is for the attribution chain specified by the {@link AttributionSource}.
+     *
+     * @see #startProxyOp(String, AttributionSource, String)
+     *
+     * @hide
+     */
+    public int startProxyOpNoThrow(int op, @NonNull AttributionSource attributionSource,
+            @Nullable String message, boolean skipProxyOperation) {
+        try {
+            collectNoteOpCallsForValidation(op);
+            int collectionMode = getNotedOpCollectionMode(
+                    attributionSource.getNextUid(),
+                    attributionSource.getNextPackageName(), op);
             boolean shouldCollectMessage = Process.myUid() == Process.SYSTEM_UID;
             if (collectionMode == COLLECT_ASYNC) {
                 if (message == null) {
@@ -8487,24 +8585,23 @@
                 }
             }
 
-            int mode = mService.startProxyOperation(getClientId(), opInt, proxiedUid,
-                    proxiedPackageName, proxiedAttributionTag, Process.myUid(),
-                    mContext.getOpPackageName(), mContext.getAttributionTag(), false,
-                    collectionMode == COLLECT_ASYNC, message, shouldCollectMessage);
+            int mode = mService.startProxyOperation(getClientId(), op,
+                    attributionSource, false, collectionMode == COLLECT_ASYNC, message,
+                    shouldCollectMessage, skipProxyOperation);
 
             if (mode == MODE_ALLOWED) {
                 if (collectionMode == COLLECT_SELF) {
-                    collectNotedOpForSelf(opInt, proxiedAttributionTag);
+                    collectNotedOpForSelf(op,
+                            attributionSource.getNextAttributionTag());
                 } else if (collectionMode == COLLECT_SYNC
                         // Only collect app-ops when the proxy is trusted
                         && (mContext.checkPermission(Manifest.permission.UPDATE_APP_OPS_STATS, -1,
                         Process.myUid()) == PackageManager.PERMISSION_GRANTED
-                        || Binder.getCallingUid() == proxiedUid)) {
-                    collectNotedOpSync(opInt, proxiedAttributionTag);
+                        || Binder.getCallingUid() == attributionSource.getNextUid())) {
+                    collectNotedOpSync(op, attributionSource.getNextAttributionTag());
                 }
             }
 
-
             return mode;
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -8563,22 +8660,37 @@
     }
 
     /**
-     *  Report that an application is no longer performing an operation that had previously
+     * Report that an application is no longer performing an operation that had previously
      * been started with {@link #startProxyOp(String, int, String, String, String)}. There is no
      * validation of input or result; the parameters supplied here must be the exact same ones
      * previously passed in when starting the operation.
+     *
      * @param op The operation which was started
-     * @param proxiedUid The uid the op was started on behalf of
-     * @param proxiedPackageName The package the op was started on behalf of
-     * @param proxiedAttributionTag The proxied {@link Context#createAttributionContext
-     * attribution tag} or {@code null} for default attribution
+     * @param proxiedUid The proxied appp's UID
+     * @param proxiedPackageName The proxied appp's package name
+     * @param proxiedAttributionTag The proxied appp's attribution tag or
+     *     {@code null} for default attribution
      */
     public void finishProxyOp(@NonNull String op, int proxiedUid,
             @NonNull String proxiedPackageName, @Nullable String proxiedAttributionTag) {
+        finishProxyOp(op, new AttributionSource(mContext.getAttributionSource(),
+                new AttributionSource(proxiedUid, proxiedPackageName, proxiedAttributionTag)));
+    }
+
+    /**
+     * Report that an application is no longer performing an operation that had previously
+     * been started with {@link #startProxyOp(String, AttributionSource, String)}. There is no
+     * validation of input or result; the parameters supplied here must be the exact same ones
+     * previously passed in when starting the operation.
+     *
+     * @param op The operation which was started
+     * @param attributionSource The permission identity for which to finish
+     *
+     * @hide
+     */
+    public void finishProxyOp(@NonNull String op, @NonNull AttributionSource attributionSource) {
         try {
-            mService.finishProxyOperation(getClientId(), strOpToOp(op), proxiedUid,
-                    proxiedPackageName, proxiedAttributionTag, Process.myUid(),
-                    mContext.getOpPackageName(), mContext.getAttributionTag());
+            mService.finishProxyOperation(getClientId(), strOpToOp(op), attributionSource);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -8599,6 +8711,46 @@
     }
 
     /**
+     * Get whether you are currently proxying to another package. That applies only
+     * for long running operations like {@link #OP_RECORD_AUDIO}.
+     *
+     * @param op The op.
+     * @param proxyAttributionTag Your attribution tag to query for.
+     * @param proxiedUid The proxied UID to query for.
+     * @param proxiedPackageName The proxied package to query for.
+     * @return Whether you are currently proxying to this target.
+     *
+     * @hide
+     */
+    public boolean isProxying(int op, @NonNull String proxyAttributionTag, int proxiedUid,
+            @NonNull String proxiedPackageName) {
+        try {
+            return mService.isProxying(op, mContext.getOpPackageName(),
+                    mContext.getAttributionTag(), proxiedUid, proxiedPackageName);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Clears the op state (last accesses + op modes) for a package but not
+     * the historical state.
+     *
+     * @param packageName The package to reset.
+     *
+     * @hide
+     */
+    @TestApi
+    @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
+    public void resetPackageOpsNoHistory(@NonNull String packageName) {
+        try {
+            mService.resetPackageOpsNoHistory(packageName);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Start collection of noted appops on this thread.
      *
      * <p>Called at the beginning of a two way binder transaction.
@@ -8754,7 +8906,7 @@
             packageName = "android";
         }
 
-        // check it the appops needs to be collected and cache result
+        // check if the appops needs to be collected and cache result
         if (sAppOpsToNote[op] == SHOULD_COLLECT_NOTE_OP_NOT_INITIALIZED) {
             boolean shouldCollectNotes;
             try {
diff --git a/core/java/android/app/AppOpsManagerInternal.java b/core/java/android/app/AppOpsManagerInternal.java
index 5e032f0..a3d0cf2 100644
--- a/core/java/android/app/AppOpsManagerInternal.java
+++ b/core/java/android/app/AppOpsManagerInternal.java
@@ -18,12 +18,17 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.content.AttributionSource;
+import android.os.IBinder;
 import android.util.SparseArray;
 import android.util.SparseIntArray;
 
 import com.android.internal.app.IAppOpsCallback;
 import com.android.internal.util.function.HeptFunction;
+import com.android.internal.util.function.HexFunction;
+import com.android.internal.util.function.OctFunction;
 import com.android.internal.util.function.QuadFunction;
+import com.android.internal.util.function.TriFunction;
 
 /**
  * App ops service local interface.
@@ -76,6 +81,55 @@
                 @Nullable String message, boolean shouldCollectMessage,
                 @NonNull HeptFunction<Integer, Integer, String, String, Boolean, String, Boolean,
                         Integer> superImpl);
+
+        /**
+         * Allows overriding note proxy operation behavior.
+         *
+         * @param code The op code to note.
+         * @param attributionSource The permission identity of the caller.
+         * @param shouldCollectAsyncNotedOp If an {@link AsyncNotedAppOp} should be collected
+         * @param message The message in the async noted op
+         * @param shouldCollectMessage whether to collect messages
+         * @param skipProxyOperation Whether to skip the proxy portion of the operation
+         * @param superImpl The super implementation.
+         * @return The app op note result.
+         */
+        int noteProxyOperation(int code, @NonNull AttributionSource attributionSource,
+                boolean shouldCollectAsyncNotedOp, @Nullable String message,
+                boolean shouldCollectMessage, boolean skipProxyOperation,
+                @NonNull HexFunction<Integer, AttributionSource, Boolean, String, Boolean,
+                        Boolean, Integer> superImpl);
+
+        /**
+         * Allows overriding start proxy operation behavior.
+         *
+         * @param code The op code to start.
+         * @param attributionSource The permission identity of the caller.
+         * @param startIfModeDefault Whether to start the op of the mode is default.
+         * @param shouldCollectAsyncNotedOp If an {@link AsyncNotedAppOp} should be collected
+         * @param message The message in the async noted op
+         * @param shouldCollectMessage whether to collect messages
+         * @param skipProxyOperation Whether to skip the proxy portion of the operation
+         * @param superImpl The super implementation.
+         * @return The app op note result.
+         */
+        int startProxyOperation(IBinder token, int code,
+                @NonNull AttributionSource attributionSource, boolean startIfModeDefault,
+                boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage,
+                boolean skipProxyOperation, @NonNull OctFunction<IBinder, Integer,
+                        AttributionSource, Boolean, Boolean, String, Boolean, Boolean,
+                        Integer> superImpl);
+
+        /**
+         * Allows overriding finish proxy op.
+         *
+         * @param clientId Client state token.
+         * @param code The op code to finish.
+         * @param attributionSource The permission identity of the caller.
+         */
+        void finishProxyOperation(IBinder clientId, int code,
+                @NonNull AttributionSource attributionSource,
+                @NonNull TriFunction<IBinder, Integer, AttributionSource, Void> superImpl);
     }
 
     /**
diff --git a/core/java/android/app/Application.java b/core/java/android/app/Application.java
index 146d648..618eda8 100644
--- a/core/java/android/app/Application.java
+++ b/core/java/android/app/Application.java
@@ -22,6 +22,7 @@
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.ComponentCallbacks;
 import android.content.ComponentCallbacks2;
+import android.content.ComponentCallbacksController;
 import android.content.Context;
 import android.content.ContextWrapper;
 import android.content.Intent;
@@ -53,14 +54,14 @@
 public class Application extends ContextWrapper implements ComponentCallbacks2 {
     private static final String TAG = "Application";
     @UnsupportedAppUsage
-    private ArrayList<ComponentCallbacks> mComponentCallbacks =
-            new ArrayList<ComponentCallbacks>();
-    @UnsupportedAppUsage
     private ArrayList<ActivityLifecycleCallbacks> mActivityLifecycleCallbacks =
             new ArrayList<ActivityLifecycleCallbacks>();
     @UnsupportedAppUsage
     private ArrayList<OnProvideAssistDataListener> mAssistCallbacks = null;
 
+    private final ComponentCallbacksController mCallbacksController =
+            new ComponentCallbacksController();
+
     /** @hide */
     @UnsupportedAppUsage
     public LoadedApk mLoadedApk;
@@ -260,47 +261,25 @@
 
     @CallSuper
     public void onConfigurationChanged(@NonNull Configuration newConfig) {
-        Object[] callbacks = collectComponentCallbacks();
-        if (callbacks != null) {
-            for (int i=0; i<callbacks.length; i++) {
-                ((ComponentCallbacks)callbacks[i]).onConfigurationChanged(newConfig);
-            }
-        }
+        mCallbacksController.dispatchConfigurationChanged(newConfig);
     }
 
     @CallSuper
     public void onLowMemory() {
-        Object[] callbacks = collectComponentCallbacks();
-        if (callbacks != null) {
-            for (int i=0; i<callbacks.length; i++) {
-                ((ComponentCallbacks)callbacks[i]).onLowMemory();
-            }
-        }
+        mCallbacksController.dispatchLowMemory();
     }
 
     @CallSuper
     public void onTrimMemory(int level) {
-        Object[] callbacks = collectComponentCallbacks();
-        if (callbacks != null) {
-            for (int i=0; i<callbacks.length; i++) {
-                Object c = callbacks[i];
-                if (c instanceof ComponentCallbacks2) {
-                    ((ComponentCallbacks2)c).onTrimMemory(level);
-                }
-            }
-        }
+        mCallbacksController.dispatchTrimMemory(level);
     }
 
     public void registerComponentCallbacks(ComponentCallbacks callback) {
-        synchronized (mComponentCallbacks) {
-            mComponentCallbacks.add(callback);
-        }
+        mCallbacksController.registerCallbacks(callback);
     }
 
     public void unregisterComponentCallbacks(ComponentCallbacks callback) {
-        synchronized (mComponentCallbacks) {
-            mComponentCallbacks.remove(callback);
-        }
+        mCallbacksController.unregisterCallbacks(callback);
     }
 
     public void registerActivityLifecycleCallbacks(ActivityLifecycleCallbacks callback) {
@@ -575,16 +554,6 @@
         }
     }
 
-    private Object[] collectComponentCallbacks() {
-        Object[] callbacks = null;
-        synchronized (mComponentCallbacks) {
-            if (mComponentCallbacks.size() > 0) {
-                callbacks = mComponentCallbacks.toArray();
-            }
-        }
-        return callbacks;
-    }
-
     @UnsupportedAppUsage
     private Object[] collectActivityLifecycleCallbacks() {
         Object[] callbacks = null;
diff --git a/core/java/android/app/BroadcastOptions.java b/core/java/android/app/BroadcastOptions.java
index 477e96b..9da2581 100644
--- a/core/java/android/app/BroadcastOptions.java
+++ b/core/java/android/app/BroadcastOptions.java
@@ -16,14 +16,16 @@
 
 package android.app;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.os.Build;
 import android.os.Bundle;
-import android.os.PowerWhitelistManager;
-import android.os.PowerWhitelistManager.ReasonCode;
-import android.os.PowerWhitelistManager.TempAllowListType;
+import android.os.PowerExemptionManager;
+import android.os.PowerExemptionManager.ReasonCode;
+import android.os.PowerExemptionManager.TempAllowListType;
 
 /**
  * Helper class for building an options Bundle that can be used with
@@ -35,8 +37,7 @@
 public class BroadcastOptions {
     private long mTemporaryAppAllowlistDuration;
     private @TempAllowListType int mTemporaryAppAllowlistType;
-    private @ReasonCode int mTemporaryAppAllowlistReasonCode =
-            PowerWhitelistManager.REASON_UNKNOWN;
+    private @ReasonCode int mTemporaryAppAllowlistReasonCode;
     private @Nullable String mTemporaryAppAllowlistReason;
     private int mMinManifestReceiverApiLevel = 0;
     private int mMaxManifestReceiverApiLevel = Build.VERSION_CODES.CUR_DEVELOPMENT;
@@ -47,59 +48,59 @@
      * How long to temporarily put an app on the power allowlist when executing this broadcast
      * to it.
      */
-    static final String KEY_TEMPORARY_APP_ALLOWLIST_DURATION
+    private static final String KEY_TEMPORARY_APP_ALLOWLIST_DURATION
             = "android:broadcast.temporaryAppAllowlistDuration";
 
-    static final String KEY_TEMPORARY_APP_ALLOWLIST_TYPE
+    private static final String KEY_TEMPORARY_APP_ALLOWLIST_TYPE
             = "android:broadcast.temporaryAppAllowlistType";
 
-    static final String KEY_TEMPORARY_APP_ALLOWLIST_REASON_CODE =
+    private static final String KEY_TEMPORARY_APP_ALLOWLIST_REASON_CODE =
             "android:broadcast.temporaryAppAllowlistReasonCode";
 
-    static final String KEY_TEMPORARY_APP_ALLOWLIST_REASON =
+    private static final String KEY_TEMPORARY_APP_ALLOWLIST_REASON =
             "android:broadcast.temporaryAppAllowlistReason";
 
     /**
      * Corresponds to {@link #setMinManifestReceiverApiLevel}.
      */
-    static final String KEY_MIN_MANIFEST_RECEIVER_API_LEVEL
+    private static final String KEY_MIN_MANIFEST_RECEIVER_API_LEVEL
             = "android:broadcast.minManifestReceiverApiLevel";
 
     /**
      * Corresponds to {@link #setMaxManifestReceiverApiLevel}.
      */
-    static final String KEY_MAX_MANIFEST_RECEIVER_API_LEVEL
+    private static final String KEY_MAX_MANIFEST_RECEIVER_API_LEVEL
             = "android:broadcast.maxManifestReceiverApiLevel";
 
     /**
      * Corresponds to {@link #setDontSendToRestrictedApps}.
      */
-    static final String KEY_DONT_SEND_TO_RESTRICTED_APPS =
+    private static final String KEY_DONT_SEND_TO_RESTRICTED_APPS =
             "android:broadcast.dontSendToRestrictedApps";
 
     /**
      * Corresponds to {@link #setBackgroundActivityStartsAllowed}.
      */
-    static final String KEY_ALLOW_BACKGROUND_ACTIVITY_STARTS =
+    private static final String KEY_ALLOW_BACKGROUND_ACTIVITY_STARTS =
             "android:broadcast.allowBackgroundActivityStarts";
 
     /**
      * @hide
-     * @deprecated Use {@link android.os.PowerWhitelistManager#
-     * TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED} instead.
+     * @deprecated Use {@link android.os.PowerExemptionManager#
+     * TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED} instead.
      */
     @Deprecated
     public static final int TEMPORARY_WHITELIST_TYPE_FOREGROUND_SERVICE_ALLOWED =
-            PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED;
+            PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED;
 
     /**
      * @hide
-     * @deprecated Use {@link android.os.PowerWhitelistManager#
-     * TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED} instead.
+     * @deprecated Use {@link android.os.PowerExemptionManager#
+     * TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED} instead.
      */
     @Deprecated
     public static final int TEMPORARY_WHITELIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED =
-            PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED;
+            PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED;
 
     public static BroadcastOptions makeBasic() {
         BroadcastOptions opts = new BroadcastOptions();
@@ -107,15 +108,22 @@
     }
 
     private BroadcastOptions() {
+        resetTemporaryAppAllowlist();
     }
 
     /** @hide */
-    public BroadcastOptions(Bundle opts) {
-        mTemporaryAppAllowlistDuration = opts.getLong(KEY_TEMPORARY_APP_ALLOWLIST_DURATION);
-        mTemporaryAppAllowlistType = opts.getInt(KEY_TEMPORARY_APP_ALLOWLIST_TYPE);
-        mTemporaryAppAllowlistReasonCode = opts.getInt(KEY_TEMPORARY_APP_ALLOWLIST_REASON_CODE,
-                PowerWhitelistManager.REASON_UNKNOWN);
-        mTemporaryAppAllowlistReason = opts.getString(KEY_TEMPORARY_APP_ALLOWLIST_REASON);
+    @TestApi
+    public BroadcastOptions(@NonNull Bundle opts) {
+        // Match the logic in toBundle().
+        if (opts.containsKey(KEY_TEMPORARY_APP_ALLOWLIST_DURATION)) {
+            mTemporaryAppAllowlistDuration = opts.getLong(KEY_TEMPORARY_APP_ALLOWLIST_DURATION);
+            mTemporaryAppAllowlistType = opts.getInt(KEY_TEMPORARY_APP_ALLOWLIST_TYPE);
+            mTemporaryAppAllowlistReasonCode = opts.getInt(KEY_TEMPORARY_APP_ALLOWLIST_REASON_CODE,
+                    PowerExemptionManager.REASON_UNKNOWN);
+            mTemporaryAppAllowlistReason = opts.getString(KEY_TEMPORARY_APP_ALLOWLIST_REASON);
+        } else {
+            resetTemporaryAppAllowlist();
+        }
         mMinManifestReceiverApiLevel = opts.getInt(KEY_MIN_MANIFEST_RECEIVER_API_LEVEL, 0);
         mMaxManifestReceiverApiLevel = opts.getInt(KEY_MAX_MANIFEST_RECEIVER_API_LEVEL,
                 Build.VERSION_CODES.CUR_DEVELOPMENT);
@@ -136,18 +144,21 @@
             android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND})
     public void setTemporaryAppWhitelistDuration(long duration) {
         setTemporaryAppAllowlist(duration,
-                PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
-                PowerWhitelistManager.REASON_UNKNOWN, null);
+                PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
+                PowerExemptionManager.REASON_UNKNOWN, null);
     }
 
     /**
      * Set a duration for which the system should temporary place an application on the
      * power allowlist when this broadcast is being delivered to it, specify the temp allowlist
      * type.
-     * @param duration the duration in milliseconds; 0 means to not place on allowlist.
-     * @param type one of {@link TempAllowListType}
+     * @param duration the duration in milliseconds.
+     *                 0 means to not place on allowlist, and clears previous call to this method.
+     * @param type one of {@link TempAllowListType}.
+     *             {@link PowerExemptionManager#TEMPORARY_ALLOW_LIST_TYPE_NONE} means
+     *             to not place on allowlist, and clears previous call to this method.
      * @param reasonCode one of {@link ReasonCode}, use
-     *                  {@link PowerWhitelistManager#REASON_UNKNOWN} if not sure.
+     *                  {@link PowerExemptionManager#REASON_UNKNOWN} if not sure.
      * @param reason A human-readable reason explaining why the app is temp allowlisted. Only
      *               used for logging purposes. Could be null or empty string.
      */
@@ -160,12 +171,30 @@
         mTemporaryAppAllowlistType = type;
         mTemporaryAppAllowlistReasonCode = reasonCode;
         mTemporaryAppAllowlistReason = reason;
+
+        if (!isTemporaryAppAllowlistSet()) {
+            resetTemporaryAppAllowlist();
+        }
+    }
+
+    private boolean isTemporaryAppAllowlistSet() {
+        return mTemporaryAppAllowlistDuration > 0
+                && mTemporaryAppAllowlistType
+                    != PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_NONE;
+    }
+
+    private void resetTemporaryAppAllowlist() {
+        mTemporaryAppAllowlistDuration = 0;
+        mTemporaryAppAllowlistType = PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_NONE;
+        mTemporaryAppAllowlistReasonCode = PowerExemptionManager.REASON_UNKNOWN;
+        mTemporaryAppAllowlistReason = null;
     }
 
     /**
      * Return {@link #setTemporaryAppAllowlist}.
      * @hide
      */
+    @TestApi
     public long getTemporaryAppAllowlistDuration() {
         return mTemporaryAppAllowlistDuration;
     }
@@ -174,6 +203,7 @@
      * Return {@link #mTemporaryAppAllowlistType}.
      * @hide
      */
+    @TestApi
     public @TempAllowListType int getTemporaryAppAllowlistType() {
         return mTemporaryAppAllowlistType;
     }
@@ -182,6 +212,7 @@
      * Return {@link #mTemporaryAppAllowlistReasonCode}.
      * @hide
      */
+    @TestApi
     public @ReasonCode int getTemporaryAppAllowlistReasonCode() {
         return mTemporaryAppAllowlistReasonCode;
     }
@@ -190,6 +221,7 @@
      * Return {@link #mTemporaryAppAllowlistReason}.
      * @hide
      */
+    @TestApi
     public @Nullable String getTemporaryAppAllowlistReason() {
         return mTemporaryAppAllowlistReason;
     }
@@ -276,16 +308,10 @@
      */
     public Bundle toBundle() {
         Bundle b = new Bundle();
-        if (mTemporaryAppAllowlistDuration > 0) {
+        if (isTemporaryAppAllowlistSet()) {
             b.putLong(KEY_TEMPORARY_APP_ALLOWLIST_DURATION, mTemporaryAppAllowlistDuration);
-        }
-        if (mTemporaryAppAllowlistType != 0) {
             b.putInt(KEY_TEMPORARY_APP_ALLOWLIST_TYPE, mTemporaryAppAllowlistType);
-        }
-        if (mTemporaryAppAllowlistReasonCode != PowerWhitelistManager.REASON_UNKNOWN) {
             b.putInt(KEY_TEMPORARY_APP_ALLOWLIST_REASON_CODE, mTemporaryAppAllowlistReasonCode);
-        }
-        if (mTemporaryAppAllowlistReason != null) {
             b.putString(KEY_TEMPORARY_APP_ALLOWLIST_REASON, mTemporaryAppAllowlistReason);
         }
         if (mMinManifestReceiverApiLevel != 0) {
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 0358fe5..f8165e9 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -19,10 +19,12 @@
 import static android.content.pm.PackageManager.PERMISSION_DENIED;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.os.StrictMode.vmIncorrectContextUseEnabled;
+import static android.view.WindowManager.LayoutParams.WindowType;
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.UiContext;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.AutofillOptions;
 import android.content.BroadcastReceiver;
@@ -58,6 +60,7 @@
 import android.graphics.Bitmap;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
+import android.content.AttributionSource;
 import android.os.Binder;
 import android.os.Build;
 import android.os.Bundle;
@@ -87,6 +90,8 @@
 import android.view.Display;
 import android.view.DisplayAdjustments;
 import android.view.autofill.AutofillManager.AutofillClient;
+import android.window.WindowContext;
+import android.window.WindowTokenClient;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.Preconditions;
@@ -220,8 +225,8 @@
     private final String mBasePackageName;
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
     private final String mOpPackageName;
-
     private final @NonNull ContextParams mParams;
+    private @NonNull AttributionSource mAttributionSource;
 
     private final @NonNull ResourcesManager mResourcesManager;
     @UnsupportedAppUsage
@@ -463,13 +468,13 @@
     /** @hide */
     @Override
     public String getOpPackageName() {
-        return mOpPackageName != null ? mOpPackageName : getBasePackageName();
+        return mAttributionSource.getPackageName();
     }
 
     /** @hide */
     @Override
     public @Nullable String getAttributionTag() {
-        return mParams.getAttributionTag();
+        return mAttributionSource.getAttributionTag();
     }
 
     @Override
@@ -478,6 +483,11 @@
     }
 
     @Override
+    public @NonNull AttributionSource getAttributionSource() {
+        return mAttributionSource;
+    }
+
+    @Override
     public ApplicationInfo getApplicationInfo() {
         if (mPackageInfo != null) {
             return mPackageInfo.getApplicationInfo();
@@ -1995,8 +2005,8 @@
                 final String errorMessage = "Tried to access visual service "
                         + SystemServiceRegistry.getSystemServiceClassName(name)
                         + " from a non-visual Context:" + getOuterContext();
-                final String message = "Visual services, such as WindowManager"
-                        + "or LayoutInflater should be accessed from Activity or other visual "
+                final String message = "Visual services, such as WindowManager "
+                        + "or LayoutInflater should be accessed from Activity or another visual "
                         + "Context. Use an Activity or a Context created with "
                         + "Context#createWindowContext(int, Bundle), which are adjusted to "
                         + "the configuration and visual bounds of an area on screen.";
@@ -2070,13 +2080,7 @@
             Log.v(TAG, "Treating renounced permission " + permission + " as denied");
             return PERMISSION_DENIED;
         }
-
-        try {
-            return ActivityManager.getService().checkPermissionWithToken(
-                    permission, pid, uid, callerToken);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
+        return checkPermission(permission, pid, uid);
     }
 
     @Override
@@ -2411,8 +2415,10 @@
         LoadedApk pi = mMainThread.getPackageInfo(application, mResources.getCompatibilityInfo(),
                 flags | CONTEXT_REGISTER_PACKAGE);
         if (pi != null) {
-            ContextImpl c = new ContextImpl(this, mMainThread, pi, ContextParams.EMPTY, null,
-                    mToken, new UserHandle(UserHandle.getUserId(application.uid)),
+            ContextImpl c = new ContextImpl(this, mMainThread, pi, ContextParams.EMPTY,
+                    mAttributionSource.getAttributionTag(),
+                    mAttributionSource.getNext(),
+                    null, mToken, new UserHandle(UserHandle.getUserId(application.uid)),
                     flags, null, null);
 
             final int displayId = getDisplayId();
@@ -2442,15 +2448,19 @@
         if (packageName.equals("system") || packageName.equals("android")) {
             // The system resources are loaded in every application, so we can safely copy
             // the context without reloading Resources.
-            return new ContextImpl(this, mMainThread, mPackageInfo, mParams, null,
-                    mToken, user, flags, null, null);
+            return new ContextImpl(this, mMainThread, mPackageInfo, mParams,
+                    mAttributionSource.getAttributionTag(),
+                    mAttributionSource.getNext(),
+                    null, mToken, user, flags, null, null);
         }
 
         LoadedApk pi = mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(),
                 flags | CONTEXT_REGISTER_PACKAGE, user.getIdentifier());
         if (pi != null) {
-            ContextImpl c = new ContextImpl(this, mMainThread, pi, mParams, null,
-                    mToken, user, flags, null, null);
+            ContextImpl c = new ContextImpl(this, mMainThread, pi, mParams,
+                    mAttributionSource.getAttributionTag(),
+                    mAttributionSource.getNext(),
+                    null, mToken, user, flags, null, null);
 
             final int displayId = getDisplayId();
             final Integer overrideDisplayId = mForceDisplayOverrideInResources
@@ -2487,8 +2497,10 @@
         final ClassLoader classLoader = mPackageInfo.getSplitClassLoader(splitName);
         final String[] paths = mPackageInfo.getSplitPaths(splitName);
 
-        final ContextImpl context = new ContextImpl(this, mMainThread, mPackageInfo,
-                mParams, splitName, mToken, mUser, mFlags, classLoader, null);
+        final ContextImpl context = new ContextImpl(this, mMainThread, mPackageInfo, mParams,
+                mAttributionSource.getAttributionTag(),
+                mAttributionSource.getNext(),
+                splitName, mToken, mUser, mFlags, classLoader, null);
 
         context.setResources(ResourcesManager.getInstance().getResources(
                 mToken,
@@ -2522,6 +2534,8 @@
         }
 
         ContextImpl context = new ContextImpl(this, mMainThread, mPackageInfo, mParams,
+                mAttributionSource.getAttributionTag(),
+                mAttributionSource.getNext(),
                 mSplitName, mToken, mUser, mFlags, mClassLoader, null);
 
         final int displayId = getDisplayId();
@@ -2540,6 +2554,8 @@
         }
 
         ContextImpl context = new ContextImpl(this, mMainThread, mPackageInfo, mParams,
+                mAttributionSource.getAttributionTag(),
+                mAttributionSource.getNext(),
                 mSplitName, mToken, mUser, mFlags, mClassLoader, null);
 
         final int displayId = display.getDisplayId();
@@ -2563,23 +2579,63 @@
 
     @NonNull
     @Override
-    public WindowContext createWindowContext(int type, @NonNull Bundle options) {
+    public WindowContext createWindowContext(@WindowType int type,
+            @Nullable Bundle options) {
         if (getDisplay() == null) {
-            throw new UnsupportedOperationException("WindowContext can only be created from "
-                    + "other visual contexts, such as Activity or one created with "
-                    + "Context#createDisplayContext(Display)");
+            throw new UnsupportedOperationException("Please call this API with context associated"
+                    + " with a display instance, such as Activity or context created via"
+                    + " Context#createDisplayContext(Display), or try to invoke"
+                    + " Context#createWindowContext(Display, int, Bundle)");
         }
-        return new WindowContext(this, type, options);
+        return createWindowContextInternal(getDisplay(), type, options);
     }
 
     @NonNull
     @Override
-    public WindowContext createWindowContext(@NonNull Display display, int type,
-            @NonNull Bundle options) {
+    public WindowContext createWindowContext(@NonNull Display display, @WindowType int type,
+            @Nullable Bundle options) {
         if (display == null) {
             throw new IllegalArgumentException("Display must not be null");
         }
-        return new WindowContext(this, display, type, options);
+        return createWindowContextInternal(display, type, options);
+    }
+
+    /**
+     * The internal implementation of {@link Context#createWindowContext(int, Bundle)} and
+     * {@link Context#createWindowContext(Display, int, Bundle)}.
+     *
+     * @param display The {@link Display} instance to be associated with.
+     *
+     * @see Context#createWindowContext(Display, int, Bundle)
+     * @see Context#createWindowContext(int, Bundle)
+     */
+    private WindowContext createWindowContextInternal(@NonNull Display display,
+            @WindowType int type, @Nullable Bundle options) {
+        // Step 1. Create a WindowTokenClient to associate with the WindowContext's Resources
+        //         instance and it will be later used to receive configuration updates from the
+        //         server side.
+        final WindowTokenClient windowTokenClient = new WindowTokenClient();
+
+        // Step 2. Create the base context of the window context, it will also create a Resources
+        //         associated with the WindowTokenClient and set the token to the base context.
+        final ContextImpl windowContextBase = createWindowContextBase(windowTokenClient, display);
+
+        // Step 3. Create a WindowContext instance and set it as the outer context of the base
+        //         context to make the service obtained by #getSystemService(String) able to query
+        //         the WindowContext's WindowManager instead of the default one.
+        final WindowContext windowContext = new WindowContext(windowContextBase, type, options);
+        windowContextBase.setOuterContext(windowContext);
+
+        // Step 4. Attach the WindowContext to the WindowTokenClient. In this way, when there's a
+        //         configuration update from the server side, the update will then apply to
+        //         WindowContext's resources.
+        windowTokenClient.attachContext(windowContext);
+
+        // Step 5. Register the window context's token to the server side to associate with a
+        //         window manager node.
+        windowContext.registerWithServer();
+
+        return windowContext;
     }
 
     @NonNull
@@ -2588,47 +2644,75 @@
         if (display == null) {
             throw new IllegalArgumentException("Display must not be null");
         }
-        final ContextImpl tokenContext = createBaseWindowContext(token, display);
-        tokenContext.setResources(createWindowContextResources());
+        final ContextImpl tokenContext = createWindowContextBase(token, display);
+        tokenContext.setResources(createWindowContextResources(tokenContext));
         return tokenContext;
     }
 
-
-    ContextImpl createBaseWindowContext(IBinder token, Display display) {
-        ContextImpl context = new ContextImpl(this, mMainThread, mPackageInfo, mParams,
+    /**
+     * Creates the base {@link Context} for UI context to associate with a non-{@link Activity}
+     * window.
+     *
+     * @param token The token to associate with {@link Resources}
+     * @param display The {@link Display} to associate with.
+     *
+     * @see #createWindowContext(Display, int, Bundle)
+     * @see #createTokenContext(IBinder, Display)
+     */
+    @UiContext
+    ContextImpl createWindowContextBase(@NonNull IBinder token, @NonNull Display display) {
+        ContextImpl baseContext = new ContextImpl(this, mMainThread, mPackageInfo, mParams,
+                mAttributionSource.getAttributionTag(),
+                mAttributionSource.getNext(),
                 mSplitName, token, mUser, mFlags, mClassLoader, null);
         // Window contexts receive configurations directly from the server and as such do not
         // need to override their display in ResourcesManager.
-        context.mForceDisplayOverrideInResources = false;
-        context.mContextType = CONTEXT_TYPE_WINDOW_CONTEXT;
-        if (display != null) {
-            context.mDisplay = display;
-        }
-        return context;
+        baseContext.mForceDisplayOverrideInResources = false;
+        baseContext.mContextType = CONTEXT_TYPE_WINDOW_CONTEXT;
+        baseContext.mDisplay = display;
+
+        final Resources windowContextResources = createWindowContextResources(baseContext);
+        baseContext.setResources(windowContextResources);
+
+        return baseContext;
     }
 
-    Resources createWindowContextResources() {
-        final String resDir = mPackageInfo.getResDir();
-        final String[] splitResDirs = mPackageInfo.getSplitResDirs();
-        final String[] legacyOverlayDirs = mPackageInfo.getOverlayDirs();
-        final String[] overlayPaths = mPackageInfo.getOverlayPaths();
-        final String[] libDirs = mPackageInfo.getApplicationInfo().sharedLibraryFiles;
-        final int displayId = getDisplayId();
-        final CompatibilityInfo compatInfo = (displayId == Display.DEFAULT_DISPLAY)
-                ? mPackageInfo.getCompatibilityInfo()
-                : CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
-        final List<ResourcesLoader> loaders = mResources.getLoaders();
+    /**
+     * Creates the {@link Resources} to associate with the {@link WindowContext}'s token.
+     *
+     * When there's a {@link Configuration} update, this Resources instance will be updated to match
+     * the new configuration.
+     *
+     * @see WindowTokenClient
+     * @see #getWindowContextToken()
+     */
+    private static Resources createWindowContextResources(@NonNull ContextImpl windowContextBase) {
+        final LoadedApk packageInfo = windowContextBase.mPackageInfo;
+        final ClassLoader classLoader = windowContextBase.mClassLoader;
+        final IBinder token = windowContextBase.getWindowContextToken();
 
-        return mResourcesManager.createBaseTokenResources(mToken, resDir, splitResDirs,
-                legacyOverlayDirs, overlayPaths, libDirs, displayId, null /* overrideConfig */,
-                compatInfo, mClassLoader, loaders);
+        final String resDir = packageInfo.getResDir();
+        final String[] splitResDirs = packageInfo.getSplitResDirs();
+        final String[] legacyOverlayDirs = packageInfo.getOverlayDirs();
+        final String[] overlayPaths = packageInfo.getOverlayPaths();
+        final String[] libDirs = packageInfo.getApplicationInfo().sharedLibraryFiles;
+        final int displayId = windowContextBase.getDisplayId();
+        final CompatibilityInfo compatInfo = (displayId == Display.DEFAULT_DISPLAY)
+                ? packageInfo.getCompatibilityInfo()
+                : CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
+        final List<ResourcesLoader> loaders = windowContextBase.mResources.getLoaders();
+
+        return windowContextBase.mResourcesManager.createBaseTokenResources(token, resDir,
+                splitResDirs, legacyOverlayDirs, overlayPaths, libDirs, displayId,
+                null /* overrideConfig */, compatInfo, classLoader, loaders);
     }
 
     @NonNull
     @Override
-    public Context createContext(@NonNull ContextParams params) {
-        return new ContextImpl(this, mMainThread, mPackageInfo, params, mSplitName,
-                mToken, mUser, mFlags, mClassLoader, null);
+    public Context createContext(@NonNull ContextParams contextParams) {
+        return new ContextImpl(this, mMainThread, mPackageInfo, contextParams,
+                contextParams.getAttributionTag(), contextParams.getNextAttributionSource(),
+                mSplitName, mToken, mUser, mFlags, mClassLoader, null);
     }
 
     @Override
@@ -2641,16 +2725,20 @@
     public Context createDeviceProtectedStorageContext() {
         final int flags = (mFlags & ~Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE)
                 | Context.CONTEXT_DEVICE_PROTECTED_STORAGE;
-        return new ContextImpl(this, mMainThread, mPackageInfo, mParams, mSplitName,
-                mToken, mUser, flags, mClassLoader, null);
+        return new ContextImpl(this, mMainThread, mPackageInfo, mParams,
+                mAttributionSource.getAttributionTag(),
+                mAttributionSource.getNext(),
+                mSplitName, mToken, mUser, flags, mClassLoader, null);
     }
 
     @Override
     public Context createCredentialProtectedStorageContext() {
         final int flags = (mFlags & ~Context.CONTEXT_DEVICE_PROTECTED_STORAGE)
                 | Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE;
-        return new ContextImpl(this, mMainThread, mPackageInfo, mParams, mSplitName,
-                mToken, mUser, flags, mClassLoader, null);
+        return new ContextImpl(this, mMainThread, mPackageInfo, mParams,
+                mAttributionSource.getAttributionTag(),
+                mAttributionSource.getNext(),
+                mSplitName, mToken, mUser, flags, mClassLoader, null);
     }
 
     @Override
@@ -2824,7 +2912,7 @@
     static ContextImpl createSystemContext(ActivityThread mainThread) {
         LoadedApk packageInfo = new LoadedApk(mainThread);
         ContextImpl context = new ContextImpl(null, mainThread, packageInfo,
-                ContextParams.EMPTY, null, null, null, 0, null, null);
+                ContextParams.EMPTY, null, null, null, null, null, 0, null, null);
         context.setResources(packageInfo.getResources());
         context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(),
                 context.mResourcesManager.getDisplayMetrics());
@@ -2842,7 +2930,7 @@
     static ContextImpl createSystemUiContext(ContextImpl systemContext, int displayId) {
         final LoadedApk packageInfo = systemContext.mPackageInfo;
         ContextImpl context = new ContextImpl(null, systemContext.mMainThread, packageInfo,
-                ContextParams.EMPTY, null, null, null, 0, null, null);
+                ContextParams.EMPTY, null, null, null, null, null, 0, null, null);
         context.setResources(createResources(null, packageInfo, null, displayId, null,
                 packageInfo.getCompatibilityInfo(), null));
         context.updateDisplay(displayId);
@@ -2867,7 +2955,7 @@
             String opPackageName) {
         if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
         ContextImpl context = new ContextImpl(null, mainThread, packageInfo,
-                ContextParams.EMPTY, null, null, null, 0, null, opPackageName);
+            ContextParams.EMPTY, null, null, null, null, null, 0, null, opPackageName);
         context.setResources(packageInfo.getResources());
         context.mContextType = isSystemOrSystemUI(context) ? CONTEXT_TYPE_SYSTEM_OR_SYSTEM_UI
                 : CONTEXT_TYPE_NON_UI;
@@ -2897,7 +2985,7 @@
         }
 
         ContextImpl context = new ContextImpl(null, mainThread, packageInfo, ContextParams.EMPTY,
-                activityInfo.splitName, activityToken, null, 0, classLoader, null);
+                null, null, activityInfo.splitName, activityToken, null, 0, classLoader, null);
         context.mContextType = CONTEXT_TYPE_ACTIVITY;
 
         // Clamp display ID to DEFAULT_DISPLAY if it is INVALID_DISPLAY.
@@ -2930,6 +3018,7 @@
 
     private ContextImpl(@Nullable ContextImpl container, @NonNull ActivityThread mainThread,
             @NonNull LoadedApk packageInfo, @NonNull ContextParams params,
+            @Nullable String attributionTag, @Nullable AttributionSource nextAttributionSource,
             @Nullable String splitName, @Nullable IBinder token, @Nullable UserHandle user,
             int flags, @Nullable ClassLoader classLoader, @Nullable String overrideOpPackageName) {
         mOuterContext = this;
@@ -2985,9 +3074,27 @@
 
         mOpPackageName = overrideOpPackageName != null ? overrideOpPackageName : opPackageName;
         mParams = Objects.requireNonNull(params);
+        initializeAttributionSource(attributionTag, nextAttributionSource);
         mContentResolver = new ApplicationContentResolver(this, mainThread);
     }
 
+    private void initializeAttributionSource(@Nullable String attributionTag,
+            @Nullable AttributionSource nextAttributionSource) {
+        mAttributionSource = new AttributionSource(Process.myUid(), mOpPackageName,
+                attributionTag, nextAttributionSource);
+        // If we want to access protected data on behalf of another app we need to
+        // tell the OS that we opt in to participate in the attribution chain.
+        if (nextAttributionSource != null) {
+            // If an app happened to stub the internal OS for testing the registration method
+            // can return null. In this case we keep the current untrusted attribution source.
+            final AttributionSource attributionSource = getSystemService(PermissionManager.class)
+                    .registerAttributionSource(mAttributionSource);
+            if (attributionSource != null) {
+                mAttributionSource = attributionSource;
+            }
+        }
+    }
+
     void setResources(Resources r) {
         if (r instanceof CompatResources) {
             ((CompatResources) r).setContext(this);
@@ -3114,6 +3221,14 @@
         return result;
     }
 
+    @Override
+    public void destroy() {
+        // The final clean-up is to release BroadcastReceiver registrations. It is called in
+        // ActivityThread for Activity and Service. For the context, such as WindowContext,
+        // without lifecycle concept, it should be called once the context is released.
+        scheduleFinalCleanup(getClass().getName(), getOuterContext().getClass().getSimpleName());
+    }
+
     // ----------------------------------------------------------------------
     // ----------------------------------------------------------------------
     // ----------------------------------------------------------------------
diff --git a/core/java/android/app/GameManager.java b/core/java/android/app/GameManager.java
index 47de040..5964f71 100644
--- a/core/java/android/app/GameManager.java
+++ b/core/java/android/app/GameManager.java
@@ -135,4 +135,20 @@
             throw e.rethrowFromSystemServer();
         }
     }
+    /**
+     * Returns a list of supported game modes for a given package.
+     * <p>
+     * The caller must have {@link android.Manifest.permission#MANAGE_GAME_MODE}.
+     *
+     * @hide
+     */
+    @RequiresPermission(Manifest.permission.MANAGE_GAME_MODE)
+    public @GameMode int[] getAvailableGameModes(@NonNull String packageName) {
+        try {
+            return mService.getAvailableGameModes(packageName);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
 }
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 4c2433c..81e5e1d 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -475,8 +475,6 @@
     @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     boolean isTopOfTask(in IBinder token);
     void bootAnimationComplete();
-    int checkPermissionWithToken(in String permission, int pid, int uid,
-            in IBinder callerToken);
     @UnsupportedAppUsage
     void registerTaskStackListener(in ITaskStackListener listener);
     void unregisterTaskStackListener(in ITaskStackListener listener);
diff --git a/core/java/android/app/IActivityTaskManager.aidl b/core/java/android/app/IActivityTaskManager.aidl
index 3bfddf7..e5a969a 100644
--- a/core/java/android/app/IActivityTaskManager.aidl
+++ b/core/java/android/app/IActivityTaskManager.aidl
@@ -244,6 +244,8 @@
     boolean requestAutofillData(in IAssistDataReceiver receiver, in Bundle receiverExtras,
             in IBinder activityToken, int flags);
     boolean isAssistDataAllowedOnCurrentActivity();
+    boolean requestAssistDataForTask(in IAssistDataReceiver receiver, int taskId,
+            in String callingPackageName);
 
     /**
      * Notify the system that the keyguard is going away.
diff --git a/core/java/android/app/IGameManagerService.aidl b/core/java/android/app/IGameManagerService.aidl
index c8e1478..4bf8a3f 100644
--- a/core/java/android/app/IGameManagerService.aidl
+++ b/core/java/android/app/IGameManagerService.aidl
@@ -22,4 +22,5 @@
 interface IGameManagerService {
     int getGameMode(String packageName, int userId);
     void setGameMode(String packageName, int gameMode, int userId);
+    int[] getAvailableGameModes(String packageName);
 }
\ No newline at end of file
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index bda2fa9..a5f8f10 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -104,7 +104,6 @@
     void createConversationNotificationChannelForPackage(String pkg, int uid, in NotificationChannel parentChannel, String conversationId);
     NotificationChannel getNotificationChannelForPackage(String pkg, int uid, String channelId, String conversationId, boolean includeDeleted);
     void deleteNotificationChannel(String pkg, String channelId);
-    void deleteConversationNotificationChannels(String pkg, int uid, String conversationId);
     ParceledListSlice getNotificationChannels(String callingPkg, String targetPkg, int userId);
     ParceledListSlice getNotificationChannelsForPackage(String pkg, int uid, boolean includeDeleted);
     int getNumNotificationChannelsForPackage(String pkg, int uid, boolean includeDeleted);
diff --git a/core/java/android/app/KeyguardManager.java b/core/java/android/app/KeyguardManager.java
index b6d25cf..4326c2d 100644
--- a/core/java/android/app/KeyguardManager.java
+++ b/core/java/android/app/KeyguardManager.java
@@ -133,6 +133,42 @@
      */
     public static final String EXTRA_DISALLOW_BIOMETRICS_IF_POLICY_EXISTS = "check_dpm";
 
+    /**
+     *
+     * Password lock type, see {@link #setLock}
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final int PASSWORD = 0;
+
+    /**
+     *
+     * Pin lock type, see {@link #setLock}
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final int PIN = 1;
+
+    /**
+     *
+     * Pattern lock type, see {@link #setLock}
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final int PATTERN = 2;
+
+    /**
+     * Available lock types
+     */
+    @IntDef({
+            PASSWORD,
+            PIN,
+            PATTERN
+    })
+    @interface LockTypes {}
 
     /**
      * Get an intent to prompt the user to confirm credentials (pin, pattern, password or biometrics
@@ -695,7 +731,7 @@
         PasswordMetrics adminMetrics =
                 devicePolicyManager.getPasswordMinimumMetrics(mContext.getUserId());
         // Check if the password fits the mold of a pin or pattern.
-        boolean isPinOrPattern = lockType != LockTypes.PASSWORD;
+        boolean isPinOrPattern = lockType != PASSWORD;
 
         return PasswordMetrics.validatePassword(
                 adminMetrics, complexity, isPinOrPattern, password).size() == 0;
@@ -759,7 +795,7 @@
         boolean success = false;
         try {
             switch (lockType) {
-                case LockTypes.PASSWORD:
+                case PASSWORD:
                     CharSequence passwordStr = new String(password, Charset.forName("UTF-8"));
                     lockPatternUtils.setLockCredential(
                             LockscreenCredential.createPassword(passwordStr),
@@ -767,7 +803,7 @@
                             userId);
                     success = true;
                     break;
-                case LockTypes.PIN:
+                case PIN:
                     CharSequence pinStr = new String(password);
                     lockPatternUtils.setLockCredential(
                             LockscreenCredential.createPin(pinStr),
@@ -775,7 +811,7 @@
                             userId);
                     success = true;
                     break;
-                case LockTypes.PATTERN:
+                case PATTERN:
                     List<LockPatternView.Cell> pattern =
                             LockPatternUtils.byteArrayToPattern(password);
                     lockPatternUtils.setLockCredential(
@@ -796,18 +832,4 @@
         }
         return success;
     }
-
-    /**
-    * Available lock types
-    */
-    @IntDef({
-            LockTypes.PASSWORD,
-            LockTypes.PIN,
-            LockTypes.PATTERN
-    })
-    @interface LockTypes {
-        int PASSWORD = 0;
-        int PIN = 1;
-        int PATTERN = 2;
-    }
 }
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 60506b5..2fbea28 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -20,8 +20,6 @@
 import static android.graphics.drawable.Icon.TYPE_URI;
 import static android.graphics.drawable.Icon.TYPE_URI_ADAPTIVE_BITMAP;
 
-import static com.android.internal.util.ContrastColorUtil.satisfiesTextContrast;
-
 import static java.util.Objects.requireNonNull;
 
 import android.annotation.AttrRes;
@@ -40,8 +38,8 @@
 import android.annotation.StringRes;
 import android.annotation.SuppressLint;
 import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.compat.annotation.UnsupportedAppUsage;
-import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.LocusId;
@@ -133,6 +131,52 @@
     private static final String TAG = "Notification";
 
     /**
+     * @hide
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({
+            FOREGROUND_SERVICE_DEFAULT,
+            FOREGROUND_SERVICE_IMMEDIATE,
+            FOREGROUND_SERVICE_DEFERRED
+    })
+    public @interface ServiceNotificationPolicy {};
+
+    /**
+     * If the Notification associated with starting a foreground service has been
+     * built using setForegroundServiceBehavior() with this behavior, display of
+     * the notification will usually be suppressed for a short time to avoid visual
+     * disturbances to the user.
+     * @see Notification.Builder#setForegroundServiceBehavior(int)
+     * @see #FOREGROUND_SERVICE_IMMEDIATE
+     * @see #FOREGROUND_SERVICE_DEFERRED
+     */
+    public static final @ServiceNotificationPolicy int FOREGROUND_SERVICE_DEFAULT = 0;
+
+    /**
+     * If the Notification associated with starting a foreground service has been
+     * built using setForegroundServiceBehavior() with this behavior, display of
+     * the notification will be immediate even if the default behavior would be
+     * to defer visibility for a short time.
+     * @see Notification.Builder#setForegroundServiceBehavior(int)
+     * @see #FOREGROUND_SERVICE_DEFAULT
+     * @see #FOREGROUND_SERVICE_DEFERRED
+     */
+    public static final @ServiceNotificationPolicy int FOREGROUND_SERVICE_IMMEDIATE = 1;
+
+    /**
+     * If the Notification associated with starting a foreground service has been
+     * built using setForegroundServiceBehavior() with this behavior, display of
+     * the notification will usually be suppressed for a short time to avoid visual
+     * disturbances to the user.
+     * @see Notification.Builder#setForegroundServiceBehavior(int)
+     * @see #FOREGROUND_SERVICE_DEFAULT
+     * @see #FOREGROUND_SERVICE_IMMEDIATE
+     */
+    public static final @ServiceNotificationPolicy int FOREGROUND_SERVICE_DEFERRED = 2;
+
+    private int mFgsDeferBehavior;
+
+    /**
      * An activity that provides a user interface for adjusting notification preferences for its
      * containing application.
      */
@@ -647,11 +691,6 @@
      */
     public static final int FLAG_BUBBLE = 0x00001000;
 
-    /**
-     * @hide
-     */
-    public static final int FLAG_IMMEDIATE_FGS_DISPLAY = 0x00002000;
-
     private static final List<Class<? extends Style>> PLATFORM_STYLE_CLASSES = Arrays.asList(
             BigTextStyle.class, BigPictureStyle.class, InboxStyle.class, MediaStyle.class,
             DecoratedCustomViewStyle.class, DecoratedMediaCustomViewStyle.class,
@@ -661,8 +700,7 @@
     @IntDef(flag = true, prefix = { "FLAG_" }, value = {FLAG_SHOW_LIGHTS, FLAG_ONGOING_EVENT,
             FLAG_INSISTENT, FLAG_ONLY_ALERT_ONCE,
             FLAG_AUTO_CANCEL, FLAG_NO_CLEAR, FLAG_FOREGROUND_SERVICE, FLAG_HIGH_PRIORITY,
-            FLAG_LOCAL_ONLY, FLAG_GROUP_SUMMARY, FLAG_AUTOGROUP_SUMMARY, FLAG_BUBBLE,
-            FLAG_IMMEDIATE_FGS_DISPLAY})
+            FLAG_LOCAL_ONLY, FLAG_GROUP_SUMMARY, FLAG_AUTOGROUP_SUMMARY, FLAG_BUBBLE})
     @Retention(RetentionPolicy.SOURCE)
     public @interface NotificationFlags{};
 
@@ -1207,9 +1245,16 @@
     public static final String EXTRA_PICTURE = "android.picture";
 
     /**
+     * {@link #extras} key: this is an {@link Icon} of an image to be
+     * shown in {@link BigPictureStyle} expanded notifications, supplied to
+     * {@link BigPictureStyle#bigPicture(Icon)}.
+     */
+    public static final String EXTRA_PICTURE_ICON = "android.pictureIcon";
+
+    /**
      * {@link #extras} key: this is a content description of the big picture supplied from
      * {@link BigPictureStyle#bigPicture(Bitmap)}, supplied to
-     * {@link BigPictureStyle#bigPictureContentDescription(CharSequence)}.
+     * {@link BigPictureStyle#setContentDescription(CharSequence)}.
      */
     public static final String EXTRA_PICTURE_CONTENT_DESCRIPTION =
             "android.pictureContentDescription";
@@ -2545,6 +2590,8 @@
         }
 
         mAllowSystemGeneratedContextualActions = parcel.readBoolean();
+
+        mFgsDeferBehavior = parcel.readInt();
     }
 
     @Override
@@ -2660,6 +2707,7 @@
         that.mBadgeIcon = this.mBadgeIcon;
         that.mSettingsText = this.mSettingsText;
         that.mGroupAlertBehavior = this.mGroupAlertBehavior;
+        that.mFgsDeferBehavior = this.mFgsDeferBehavior;
         that.mBubbleMetadata = this.mBubbleMetadata;
         that.mAllowSystemGeneratedContextualActions = this.mAllowSystemGeneratedContextualActions;
 
@@ -2668,6 +2716,14 @@
         }
     }
 
+    private static void visitIconUri(@NonNull Consumer<Uri> visitor, @Nullable Icon icon) {
+        if (icon == null) return;
+        final int iconType = icon.getType();
+        if (iconType == TYPE_URI || iconType == TYPE_URI_ADAPTIVE_BITMAP) {
+            visitor.accept(icon.getUri());
+        }
+    }
+
     /**
      * Note all {@link Uri} that are referenced internally, with the expectation
      * that Uri permission grants will need to be issued to ensure the recipient
@@ -2683,7 +2739,19 @@
         if (bigContentView != null) bigContentView.visitUris(visitor);
         if (headsUpContentView != null) headsUpContentView.visitUris(visitor);
 
+        visitIconUri(visitor, mSmallIcon);
+        visitIconUri(visitor, mLargeIcon);
+
+        if (actions != null) {
+            for (Action action : actions) {
+                visitIconUri(visitor, action.getIcon());
+            }
+        }
+
         if (extras != null) {
+            visitIconUri(visitor, extras.getParcelable(EXTRA_LARGE_ICON_BIG));
+            visitIconUri(visitor, extras.getParcelable(EXTRA_PICTURE_ICON));
+
             // NOTE: The documentation of EXTRA_AUDIO_CONTENTS_URI explicitly says that it is a
             // String representation of a Uri, but the previous implementation (and unit test) of
             // this method has always treated it as a Uri object. Given the inconsistency,
@@ -2702,14 +2770,12 @@
             ArrayList<Person> people = extras.getParcelableArrayList(EXTRA_PEOPLE_LIST);
             if (people != null && !people.isEmpty()) {
                 for (Person p : people) {
-                    if (p.getIconUri() != null) {
-                        visitor.accept(p.getIconUri());
-                    }
+                    visitor.accept(p.getIconUri());
                 }
             }
 
             final Person person = extras.getParcelable(EXTRA_MESSAGING_PERSON);
-            if (person != null && person.getIconUri() != null) {
+            if (person != null) {
                 visitor.accept(person.getIconUri());
             }
         }
@@ -2722,7 +2788,7 @@
                     visitor.accept(message.getDataUri());
 
                     Person senderPerson = message.getSenderPerson();
-                    if (senderPerson != null && senderPerson.getIconUri() != null) {
+                    if (senderPerson != null) {
                         visitor.accept(senderPerson.getIconUri());
                     }
                 }
@@ -2735,19 +2801,15 @@
                     visitor.accept(message.getDataUri());
 
                     Person senderPerson = message.getSenderPerson();
-                    if (senderPerson != null && senderPerson.getIconUri() != null) {
+                    if (senderPerson != null) {
                         visitor.accept(senderPerson.getIconUri());
                     }
                 }
             }
         }
 
-        if (mBubbleMetadata != null && mBubbleMetadata.getIcon() != null) {
-            final Icon icon = mBubbleMetadata.getIcon();
-            final int iconType = icon.getType();
-            if (iconType == TYPE_URI_ADAPTIVE_BITMAP || iconType == TYPE_URI) {
-                visitor.accept(icon.getUri());
-            }
+        if (mBubbleMetadata != null) {
+            visitIconUri(visitor, mBubbleMetadata.getIcon());
         }
     }
 
@@ -3045,6 +3107,8 @@
 
         parcel.writeBoolean(mAllowSystemGeneratedContextualActions);
 
+        parcel.writeInt(mFgsDeferBehavior);
+
         // mUsesStandardHeader is not written because it should be recomputed in listeners
     }
 
@@ -3680,8 +3744,6 @@
         private int mTextColorsAreForBackground = COLOR_INVALID;
         private int mPrimaryTextColor = COLOR_INVALID;
         private int mSecondaryTextColor = COLOR_INVALID;
-        private int mBackgroundColor = COLOR_INVALID;
-        private int mForegroundColor = COLOR_INVALID;
         private boolean mRebuildStyledRemoteViews;
 
         private boolean mTintActionButtons;
@@ -4515,10 +4577,40 @@
          * foreground service is shown as soon as the service's {@code startForeground()}
          * method is called, even if the system's UI policy might otherwise defer
          * its visibility to a later time.
+         * @deprecated Use setForegroundServiceBehavior(int) instead
          */
+        @Deprecated
         @NonNull
         public Builder setShowForegroundImmediately(boolean showImmediately) {
-            setFlag(FLAG_IMMEDIATE_FGS_DISPLAY, showImmediately);
+            setForegroundServiceBehavior(showImmediately
+                    ? FOREGROUND_SERVICE_IMMEDIATE
+                    : FOREGROUND_SERVICE_DEFAULT);
+            return this;
+        }
+
+        /**
+         * Specify a desired visibility policy for a Notification associated with a
+         * foreground service.  By default, the system can choose to defer
+         * visibility of the notification for a short time after the service is
+         * started.  Pass
+         * {@link Notification#FOREGROUND_SERVICE_IMMEDIATE BEHAVIOR_IMMEDIATE_DISPLAY}
+         * to this method in order to guarantee that visibility is never deferred.  Pass
+         * {@link Notification#FOREGROUND_SERVICE_DEFERRED BEHAVIOR_DEFERRED_DISPLAY}
+         * to request that visibility is deferred whenever possible.
+         *
+         * <p class="note">Note that deferred visibility is not guaranteed.  There
+         * may be some circumstances under which the system will show the foreground
+         * service's associated Notification immediately even when the app has used
+         * this method to explicitly request deferred display.</p>
+         * @param behavior One of
+         * {@link Notification#FOREGROUND_SERVICE_DEFAULT BEHAVIOR_DEFAULT},
+         * {@link Notification#FOREGROUND_SERVICE_IMMEDIATE BEHAVIOR_IMMEDIATE_DISPLAY},
+         * or {@link Notification#FOREGROUND_SERVICE_DEFERRED BEHAVIOR_DEFERRED_DISPLAY}
+         * @return
+         */
+        @NonNull
+        public Builder setForegroundServiceBehavior(int behavior) {
+            mN.mFgsDeferBehavior = behavior;
             return this;
         }
 
@@ -5020,7 +5112,8 @@
         private RemoteViews applyStandardTemplate(int resId, StandardTemplateParams p,
                 TemplateBindResult result) {
             p.headerless(resId == getBaseLayoutResource()
-                    || resId == getHeadsUpBaseLayoutResource());
+                    || resId == getHeadsUpBaseLayoutResource()
+                    || resId == R.layout.notification_template_material_media);
             RemoteViews contentView = new BuilderRemoteViews(mContext.getApplicationInfo(), resId);
 
             resetStandardTemplate(contentView);
@@ -5071,7 +5164,7 @@
         }
 
         private CharSequence processTextSpans(CharSequence text) {
-            if (hasForegroundColor() || mInNightMode) {
+            if (mInNightMode) {
                 return ContrastColorUtil.clearColorSpans(text);
             }
             return text;
@@ -5082,10 +5175,6 @@
             contentView.setTextColor(id, getPrimaryTextColor(p));
         }
 
-        private boolean hasForegroundColor() {
-            return mForegroundColor != COLOR_INVALID;
-        }
-
         /**
          * @param p the template params to inflate this with
          * @return the primary text color
@@ -5119,75 +5208,15 @@
                     || mSecondaryTextColor == COLOR_INVALID
                     || mTextColorsAreForBackground != backgroundColor) {
                 mTextColorsAreForBackground = backgroundColor;
-                if (!hasForegroundColor() || !isColorized(p)) {
-                    mPrimaryTextColor = ContrastColorUtil.resolvePrimaryColor(mContext,
-                            backgroundColor, mInNightMode);
-                    mSecondaryTextColor = ContrastColorUtil.resolveSecondaryColor(mContext,
-                            backgroundColor, mInNightMode);
-                    if (backgroundColor != COLOR_DEFAULT && isColorized(p)) {
-                        mPrimaryTextColor = ContrastColorUtil.findAlphaToMeetContrast(
-                                mPrimaryTextColor, backgroundColor, 4.5);
-                        mSecondaryTextColor = ContrastColorUtil.findAlphaToMeetContrast(
-                                mSecondaryTextColor, backgroundColor, 4.5);
-                    }
-                } else {
-                    double backLum = ContrastColorUtil.calculateLuminance(backgroundColor);
-                    double textLum = ContrastColorUtil.calculateLuminance(mForegroundColor);
-                    double contrast = ContrastColorUtil.calculateContrast(mForegroundColor,
-                            backgroundColor);
-                    // We only respect the given colors if worst case Black or White still has
-                    // contrast
-                    boolean backgroundLight = backLum > textLum
-                                    && satisfiesTextContrast(backgroundColor, Color.BLACK)
-                            || backLum <= textLum
-                                    && !satisfiesTextContrast(backgroundColor, Color.WHITE);
-                    if (contrast < 4.5f) {
-                        if (backgroundLight) {
-                            mSecondaryTextColor = ContrastColorUtil.findContrastColor(
-                                    mForegroundColor,
-                                    backgroundColor,
-                                    true /* findFG */,
-                                    4.5f);
-                            mPrimaryTextColor = ContrastColorUtil.changeColorLightness(
-                                    mSecondaryTextColor, -LIGHTNESS_TEXT_DIFFERENCE_LIGHT);
-                        } else {
-                            mSecondaryTextColor =
-                                    ContrastColorUtil.findContrastColorAgainstDark(
-                                    mForegroundColor,
-                                    backgroundColor,
-                                    true /* findFG */,
-                                    4.5f);
-                            mPrimaryTextColor = ContrastColorUtil.changeColorLightness(
-                                    mSecondaryTextColor, -LIGHTNESS_TEXT_DIFFERENCE_DARK);
-                        }
-                    } else {
-                        mPrimaryTextColor = mForegroundColor;
-                        mSecondaryTextColor = ContrastColorUtil.changeColorLightness(
-                                mPrimaryTextColor, backgroundLight ? LIGHTNESS_TEXT_DIFFERENCE_LIGHT
-                                        : LIGHTNESS_TEXT_DIFFERENCE_DARK);
-                        if (ContrastColorUtil.calculateContrast(mSecondaryTextColor,
-                                backgroundColor) < 4.5f) {
-                            // oh well the secondary is not good enough
-                            if (backgroundLight) {
-                                mSecondaryTextColor = ContrastColorUtil.findContrastColor(
-                                        mSecondaryTextColor,
-                                        backgroundColor,
-                                        true /* findFG */,
-                                        4.5f);
-                            } else {
-                                mSecondaryTextColor
-                                        = ContrastColorUtil.findContrastColorAgainstDark(
-                                        mSecondaryTextColor,
-                                        backgroundColor,
-                                        true /* findFG */,
-                                        4.5f);
-                            }
-                            mPrimaryTextColor = ContrastColorUtil.changeColorLightness(
-                                    mSecondaryTextColor, backgroundLight
-                                            ? -LIGHTNESS_TEXT_DIFFERENCE_LIGHT
-                                            : -LIGHTNESS_TEXT_DIFFERENCE_DARK);
-                        }
-                    }
+                mPrimaryTextColor = ContrastColorUtil.resolvePrimaryColor(mContext,
+                        backgroundColor, mInNightMode);
+                mSecondaryTextColor = ContrastColorUtil.resolveSecondaryColor(mContext,
+                        backgroundColor, mInNightMode);
+                if (backgroundColor != COLOR_DEFAULT && isColorized(p)) {
+                    mPrimaryTextColor = ContrastColorUtil.findAlphaToMeetContrast(
+                            mPrimaryTextColor, backgroundColor, 4.5);
+                    mSecondaryTextColor = ContrastColorUtil.findAlphaToMeetContrast(
+                            mSecondaryTextColor, backgroundColor, 4.5);
                 }
             }
         }
@@ -5233,11 +5262,7 @@
                 result = new TemplateBindResult();
             }
             bindLargeIcon(contentView, p, result);
-            if (p.mHeaderless) {
-                // views in the headerless (collapsed) state
-                result.mHeadingExtraMarginSet.applyToView(contentView,
-                        R.id.notification_headerless_view_column);
-            } else {
+            if (!p.mHeaderless) {
                 // views in states with a header (big states)
                 result.mHeadingExtraMarginSet.applyToView(contentView, R.id.notification_header);
                 result.mTitleMarginSet.applyToView(contentView, R.id.title);
@@ -5257,6 +5282,8 @@
                 @NonNull TemplateBindResult result) {
             final Resources resources = mContext.getResources();
             final float density = resources.getDisplayMetrics().density;
+            final float iconMarginDp = resources.getDimension(
+                    R.dimen.notification_right_icon_content_margin) / density;
             final float contentMarginDp = resources.getDimension(
                     R.dimen.notification_content_margin_end) / density;
             final float expanderSizeDp = resources.getDimension(
@@ -5265,8 +5292,7 @@
                     R.dimen.notification_right_icon_size) / density;
             float viewWidthDp = viewHeightDp;  // icons are 1:1 by default
             if (largeIconShown && (p.mPromotePicture
-                    || mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.S
-                    || DevFlags.shouldBackportSNotifRules(mContext.getContentResolver()))) {
+                    || mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.S)) {
                 Drawable drawable = mN.mLargeIcon.loadDrawable(mContext);
                 if (drawable != null) {
                     int iconWidth = drawable.getIntrinsicWidth();
@@ -5278,7 +5304,7 @@
                     }
                 }
             }
-            final float extraMarginEndDpIfVisible = viewWidthDp + contentMarginDp;
+            final float extraMarginEndDpIfVisible = viewWidthDp + iconMarginDp;
             result.setRightIconState(largeIconShown, viewWidthDp,
                     extraMarginEndDpIfVisible, expanderSizeDp);
         }
@@ -5333,8 +5359,12 @@
             contentView.setInt(R.id.expand_button, "setDefaultPillColor", pillColor);
             // Use different highlighted colors except when low-priority mode prevents that
             if (!p.mReduceHighlights) {
-                textColor = getBackgroundColor(p);
-                pillColor = getAccentColor(p);
+                pillColor = getAccentTertiaryColor(p);
+                // TODO(b/183710694): The accent tertiary is currently too bright in dark mode, so
+                //  we need to pick a contrasting color.
+                textColor = ColorUtils.setAlphaComponent(
+                        ContrastColorUtil.resolvePrimaryColor(mContext, pillColor, mInNightMode),
+                        0xFF);
             }
             contentView.setInt(R.id.expand_button, "setHighlightTextColor", textColor);
             contentView.setInt(R.id.expand_button, "setHighlightPillColor", pillColor);
@@ -5342,7 +5372,7 @@
 
         private void bindHeaderChronometerAndTime(RemoteViews contentView,
                 StandardTemplateParams p, boolean hasTextToLeft) {
-            if (showsTimeOrChronometer()) {
+            if (!p.mHideTime && showsTimeOrChronometer()) {
                 if (hasTextToLeft) {
                     contentView.setViewVisibility(R.id.time_divider, View.VISIBLE);
                     setTextViewColorSecondary(contentView, R.id.time_divider, p);
@@ -5373,6 +5403,9 @@
          */
         private boolean bindHeaderText(RemoteViews contentView, StandardTemplateParams p,
                 boolean hasTextToLeft) {
+            if (p.mHideSubText) {
+                return false;
+            }
             CharSequence summaryText = p.summaryText;
             if (summaryText == null && mStyle != null && mStyle.mSummaryTextSet
                     && mStyle.hasSummaryInHeader()) {
@@ -5403,6 +5436,9 @@
          */
         private boolean bindHeaderTextSecondary(RemoteViews contentView, StandardTemplateParams p,
                 boolean hasTextToLeft) {
+            if (p.mHideSubText) {
+                return false;
+            }
             if (!TextUtils.isEmpty(p.headerTextSecondary)) {
                 contentView.setTextViewText(R.id.header_text_secondary, processTextSpans(
                         processLegacyText(p.headerTextSecondary)));
@@ -5704,55 +5740,45 @@
             if (fromStyle && PLATFORM_STYLE_CLASSES.contains(mStyle.getClass())) {
                 return false;
             }
-            final ContentResolver contentResolver = mContext.getContentResolver();
-            final int decorationType = DevFlags.getFullyCustomViewNotifDecoration(contentResolver);
-            return decorationType != DevFlags.DECORATION_NONE
-                    && (DevFlags.shouldBackportSNotifRules(contentResolver)
-                    || mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.S);
+            return mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.S;
         }
 
         private RemoteViews minimallyDecoratedContentView(@NonNull RemoteViews customContent) {
-            int decorationType =
-                    DevFlags.getFullyCustomViewNotifDecoration(mContext.getContentResolver());
             StandardTemplateParams p = mParams.reset()
                     .viewType(StandardTemplateParams.VIEW_TYPE_NORMAL)
-                    .decorationType(decorationType)
+                    .decorationType(StandardTemplateParams.DECORATION_MINIMAL)
                     .fillTextsFrom(this);
             TemplateBindResult result = new TemplateBindResult();
             RemoteViews standard = applyStandardTemplate(getBaseLayoutResource(), p, result);
             buildCustomContentIntoTemplate(mContext, standard, customContent,
-                    p, result, decorationType);
+                    p, result);
             return standard;
         }
 
         private RemoteViews minimallyDecoratedBigContentView(@NonNull RemoteViews customContent) {
-            int decorationType =
-                    DevFlags.getFullyCustomViewNotifDecoration(mContext.getContentResolver());
             StandardTemplateParams p = mParams.reset()
                     .viewType(StandardTemplateParams.VIEW_TYPE_BIG)
-                    .decorationType(decorationType)
+                    .decorationType(StandardTemplateParams.DECORATION_MINIMAL)
                     .fillTextsFrom(this);
             TemplateBindResult result = new TemplateBindResult();
             RemoteViews standard = applyStandardTemplateWithActions(getBigBaseLayoutResource(),
                     p, result);
             buildCustomContentIntoTemplate(mContext, standard, customContent,
-                    p, result, decorationType);
+                    p, result);
             return standard;
         }
 
         private RemoteViews minimallyDecoratedHeadsUpContentView(
                 @NonNull RemoteViews customContent) {
-            int decorationType =
-                    DevFlags.getFullyCustomViewNotifDecoration(mContext.getContentResolver());
             StandardTemplateParams p = mParams.reset()
                     .viewType(StandardTemplateParams.VIEW_TYPE_HEADS_UP)
-                    .decorationType(decorationType)
+                    .decorationType(StandardTemplateParams.DECORATION_MINIMAL)
                     .fillTextsFrom(this);
             TemplateBindResult result = new TemplateBindResult();
             RemoteViews standard = applyStandardTemplateWithActions(getHeadsUpBaseLayoutResource(),
                     p, result);
             buildCustomContentIntoTemplate(mContext, standard, customContent,
-                    p, result, decorationType);
+                    p, result);
             return standard;
         }
 
@@ -5811,12 +5837,6 @@
                             .fillTextsFrom(this);
                     result = applyStandardTemplateWithActions(getBigBaseLayoutResource(), p,
                             null /* result */);
-                } else if (DevFlags.shouldBackportSNotifRules(mContext.getContentResolver())
-                        && useExistingRemoteView()
-                        && fullyCustomViewRequiresDecoration(false /* fromStyle */)) {
-                    // This "backport" logic is a special case to handle the UNDO style of notif
-                    // so that we can see what that will look like when the app targets S.
-                    result = minimallyDecoratedBigContentView(mN.contentView);
                 }
             }
             makeHeaderExpanded(result);
@@ -6279,6 +6299,25 @@
         }
 
         /**
+         * Gets the tertiary accent color for colored UI elements. If we're tinting with the theme
+         * accent, this comes from the tertiary system accent palette, otherwise this would be
+         * identical to {@link #getSmallIconColor(StandardTemplateParams)}.
+         */
+        private @ColorInt int getAccentTertiaryColor(StandardTemplateParams p) {
+            if (isColorized(p)) {
+                return getPrimaryTextColor(p);
+            }
+            if (mTintWithThemeAccent) {
+                int color = obtainThemeColor(com.android.internal.R.attr.colorAccentTertiary,
+                        COLOR_INVALID);
+                if (color != COLOR_INVALID) {
+                    return color;
+                }
+            }
+            return getContrastColor(p);
+        }
+
+        /**
          * Gets the theme's error color, or the primary text color for colorized notifications.
          */
         private @ColorInt int getErrorColor(StandardTemplateParams p) {
@@ -6633,7 +6672,7 @@
          */
         private @ColorInt int getUnresolvedBackgroundColor(StandardTemplateParams p) {
             if (isColorized(p)) {
-                return mBackgroundColor != COLOR_INVALID ? mBackgroundColor : getRawColor(p);
+                return getRawColor(p);
             } else {
                 return COLOR_DEFAULT;
             }
@@ -6661,21 +6700,6 @@
         }
 
         /**
-         * Set a color palette to be used as the background and textColors
-         *
-         * @param backgroundColor the color to be used as the background
-         * @param foregroundColor the color to be used as the foreground
-         *
-         * @hide
-         */
-        public void setColorPalette(@ColorInt int backgroundColor, @ColorInt int foregroundColor) {
-            mBackgroundColor = backgroundColor;
-            mForegroundColor = foregroundColor;
-            mTextColorsAreForBackground = COLOR_INVALID;
-            ensureColors(mParams.reset().fillTextsFrom(this));
-        }
-
-        /**
          * Forces all styled remoteViews to be built from scratch and not use any cached
          * RemoteViews.
          * This is needed for legacy apps that are baking in their remoteviews into the
@@ -6731,24 +6755,14 @@
         if (mLargeIcon != null || largeIcon != null) {
             Resources resources = context.getResources();
             Class<? extends Style> style = getNotificationStyle();
-            int maxWidth = resources.getDimensionPixelSize(isLowRam
+            int maxSize = resources.getDimensionPixelSize(isLowRam
                     ? R.dimen.notification_right_icon_size_low_ram
                     : R.dimen.notification_right_icon_size);
-            int maxHeight = maxWidth;
-            if (MediaStyle.class.equals(style)
-                    || DecoratedMediaCustomViewStyle.class.equals(style)) {
-                maxHeight = resources.getDimensionPixelSize(isLowRam
-                        ? R.dimen.notification_media_image_max_height_low_ram
-                        : R.dimen.notification_media_image_max_height);
-                maxWidth = resources.getDimensionPixelSize(isLowRam
-                        ? R.dimen.notification_media_image_max_width_low_ram
-                        : R.dimen.notification_media_image_max_width);
-            }
             if (mLargeIcon != null) {
-                mLargeIcon.scaleDownIfNecessary(maxWidth, maxHeight);
+                mLargeIcon.scaleDownIfNecessary(maxSize, maxSize);
             }
             if (largeIcon != null) {
-                largeIcon = Icon.scaleDownIfNecessary(largeIcon, maxWidth, maxHeight);
+                largeIcon = Icon.scaleDownIfNecessary(largeIcon, maxSize, maxSize);
             }
         }
         reduceImageSizesForRemoteView(contentView, context, isLowRam);
@@ -6784,31 +6798,60 @@
      * immediately when tied to a foreground service, even if the system might generally
      * avoid showing the notifications for short-lived foreground service lifetimes.
      *
-     * Immediate visibility of the Notification is recommended when:
+     * Immediate visibility of the Notification is indicated when:
      * <ul>
      *     <li>The app specifically indicated it with
-     *         {@link Notification.Builder#setShowForegroundImmediately(boolean)
-     *         setShowForegroundImmediately(true)}</li>
+     *         {@link Notification.Builder#setForegroundServiceBehavior(int)
+     *         setForegroundServiceBehavior(BEHAVIOR_IMMEDIATE_DISPLAY)}</li>
      *     <li>It is a media notification or has an associated media session</li>
      *     <li>It is a call or navigation notification</li>
      *     <li>It provides additional action affordances</li>
      * </ul>
-     * @return whether this notification should always be displayed immediately when
+     *
+     * If the app has specified
+     * {@code NotificationBuilder.setForegroundServiceBehavior(BEHAVIOR_DEFERRED_DISPLAY)}
+     * then this method will return {@code false} and notification visibility will be
+     * deferred following the service's transition to the foreground state even in the
+     * circumstances described above.
+     *
+     * @return whether this notification should be displayed immediately when
      * its associated service transitions to the foreground state
      * @hide
      */
+    @TestApi
     public boolean shouldShowForegroundImmediately() {
-        if ((flags & Notification.FLAG_IMMEDIATE_FGS_DISPLAY) != 0
-                || isMediaNotification() || hasMediaSession()
-                || CATEGORY_CALL.equals(category)
-                || CATEGORY_NAVIGATION.equals(category)
-                || (actions != null && actions.length > 0)) {
+        // Has the app demanded immediate display?
+        if (mFgsDeferBehavior == FOREGROUND_SERVICE_IMMEDIATE) {
             return true;
         }
+
+        // Has the app demanded deferred display?
+        if (mFgsDeferBehavior == FOREGROUND_SERVICE_DEFERRED) {
+            return false;
+        }
+
+        // We show these sorts of notifications immediately in the absence of
+        // any explicit app declaration
+        if (isMediaNotification() || hasMediaSession()
+                    || CATEGORY_CALL.equals(category)
+                    || CATEGORY_NAVIGATION.equals(category)
+                    || (actions != null && actions.length > 0)) {
+            return true;
+        }
+
+        // No extenuating circumstances: defer visibility
         return false;
     }
 
     /**
+     * Has forced deferral for FGS purposes been specified?
+     * @hide
+     */
+    public boolean isForegroundDisplayForceDeferred() {
+        return FOREGROUND_SERVICE_DEFERRED == mFgsDeferBehavior;
+    }
+
+    /**
      * @return whether this notification has a media session attached
      * @hide
      */
@@ -6835,9 +6878,6 @@
      * @hide
      */
     public boolean isColorized() {
-        if (isColorizedMedia()) {
-            return true;
-        }
         return extras.getBoolean(EXTRA_COLORIZED)
                 && (hasColorizedPermission() || isForegroundService());
     }
@@ -6851,27 +6891,6 @@
     }
 
     /**
-     * @return true if this notification is colorized and it is a media notification
-     *
-     * @hide
-     */
-    public boolean isColorizedMedia() {
-        Class<? extends Style> style = getNotificationStyle();
-        if (MediaStyle.class.equals(style)) {
-            Boolean colorized = (Boolean) extras.get(EXTRA_COLORIZED);
-            if ((colorized == null || colorized) && hasMediaSession()) {
-                return true;
-            }
-        } else if (DecoratedMediaCustomViewStyle.class.equals(style)) {
-            if (extras.getBoolean(EXTRA_COLORIZED) && hasMediaSession()) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-
-    /**
      * @return true if this is a media notification
      *
      * @hide
@@ -6955,24 +6974,18 @@
 
     private static void buildCustomContentIntoTemplate(@NonNull Context context,
             @NonNull RemoteViews template, @Nullable RemoteViews customContent,
-            @NonNull StandardTemplateParams p, @NonNull TemplateBindResult result,
-            int decorationType) {
+            @NonNull StandardTemplateParams p, @NonNull TemplateBindResult result) {
         int childIndex = -1;
         if (customContent != null) {
             // Need to clone customContent before adding, because otherwise it can no longer be
             // parceled independently of remoteViews.
             customContent = customContent.clone();
             if (p.mHeaderless) {
-                if (decorationType <= DevFlags.DECORATION_PARTIAL) {
-                    template.removeFromParent(R.id.notification_top_line);
-                }
-                // The vertical margins are bigger in the "two-line" scenario than the "one-line"
-                //  scenario, but the 'compatible' decoration state is intended to have 3 lines,
-                //  (1 for the top line views and 2 for the custom views), so in that one case we
-                //  use the smaller 1-line margins. This gives the compatible case 88-16*2=56 dp of
-                //  height, 24dp of which goes to the top line, leaving 32dp for the custom view.
-                boolean hasSecondLine = decorationType != DevFlags.DECORATION_FULL_COMPATIBLE;
-                Builder.setHeaderlessVerticalMargins(template, p, hasSecondLine);
+                template.removeFromParent(R.id.notification_top_line);
+                // We do not know how many lines ar emote view has, so we presume it has 2;  this
+                // ensures that we don't under-pad the content, which could lead to abuse, at the
+                // cost of making single-line custom content over-padded.
+                Builder.setHeaderlessVerticalMargins(template, p, true /* hasSecondLine */);
             } else {
                 // also update the end margin to account for the large icon or expander
                 Resources resources = context.getResources();
@@ -7159,15 +7172,6 @@
 
         /**
          * @hide
-         * @return true if the style positions the progress bar on the second line; false if the
-         *         style hides the progress bar
-         */
-        protected boolean hasProgress() {
-            return true;
-        }
-
-        /**
-         * @hide
          * @return Whether we should put the summary be put into the notification header
          */
         public boolean hasSummaryInHeader() {
@@ -7231,7 +7235,7 @@
      * @see Notification#bigContentView
      */
     public static class BigPictureStyle extends Style {
-        private Bitmap mPicture;
+        private Icon mPictureIcon;
         private Icon mBigLargeIcon;
         private boolean mBigLargeIconSet = false;
         private CharSequence mPictureContentDescription;
@@ -7271,7 +7275,7 @@
          * Set the content description of the big picture.
          */
         @NonNull
-        public BigPictureStyle bigPictureContentDescription(
+        public BigPictureStyle setContentDescription(
                 @Nullable CharSequence contentDescription) {
             mPictureContentDescription = contentDescription;
             return this;
@@ -7280,8 +7284,12 @@
         /**
          * @hide
          */
-        public Bitmap getBigPicture() {
-            return mPicture;
+        @Nullable
+        public Icon getBigPicture() {
+            if (mPictureIcon != null) {
+                return mPictureIcon;
+            }
+            return null;
         }
 
         /**
@@ -7289,7 +7297,16 @@
          */
         @NonNull
         public BigPictureStyle bigPicture(@Nullable Bitmap b) {
-            mPicture = b;
+            mPictureIcon = b == null ? null : Icon.createWithBitmap(b);
+            return this;
+        }
+
+        /**
+         * Provide the content Uri to be used as the payload for the BigPicture notification.
+         */
+        @NonNull
+        public BigPictureStyle bigPicture(@Nullable Icon icon) {
+            mPictureIcon = icon;
             return this;
         }
 
@@ -7331,10 +7348,8 @@
         @Override
         public void purgeResources() {
             super.purgeResources();
-            if (mPicture != null &&
-                mPicture.isMutable() &&
-                mPicture.getAllocationByteCount() >= MIN_ASHMEM_BITMAP_SIZE) {
-                mPicture = mPicture.asShared();
+            if (mPictureIcon != null) {
+                mPictureIcon.convertToAshmem();
             }
             if (mBigLargeIcon != null) {
                 mBigLargeIcon.convertToAshmem();
@@ -7349,14 +7364,14 @@
             super.reduceImageSizes(context);
             Resources resources = context.getResources();
             boolean isLowRam = ActivityManager.isLowRamDeviceStatic();
-            if (mPicture != null) {
+            if (mPictureIcon != null) {
                 int maxPictureWidth = resources.getDimensionPixelSize(isLowRam
                         ? R.dimen.notification_big_picture_max_height_low_ram
                         : R.dimen.notification_big_picture_max_height);
                 int maxPictureHeight = resources.getDimensionPixelSize(isLowRam
                         ? R.dimen.notification_big_picture_max_width_low_ram
                         : R.dimen.notification_big_picture_max_width);
-                mPicture = Icon.scaleDownIfNecessary(mPicture, maxPictureWidth, maxPictureHeight);
+                mPictureIcon.scaleDownIfNecessary(maxPictureWidth, maxPictureHeight);
             }
             if (mBigLargeIcon != null) {
                 int rightIconSize = resources.getDimensionPixelSize(isLowRam
@@ -7371,12 +7386,12 @@
          */
         @Override
         public RemoteViews makeContentView(boolean increasedHeight) {
-            if (mPicture == null || !mShowBigPictureWhenCollapsed) {
+            if (mPictureIcon == null || !mShowBigPictureWhenCollapsed) {
                 return super.makeContentView(increasedHeight);
             }
 
             Icon oldLargeIcon = mBuilder.mN.mLargeIcon;
-            mBuilder.mN.mLargeIcon = Icon.createWithBitmap(mPicture);
+            mBuilder.mN.mLargeIcon = mPictureIcon;
             // The legacy largeIcon might not allow us to clear the image, as it's taken in
             // replacement if the other one is null. Because we're restoring these legacy icons
             // for old listeners, this is in general non-null.
@@ -7401,12 +7416,12 @@
          */
         @Override
         public RemoteViews makeHeadsUpContentView(boolean increasedHeight) {
-            if (mPicture == null || !mShowBigPictureWhenCollapsed) {
+            if (mPictureIcon == null || !mShowBigPictureWhenCollapsed) {
                 return super.makeHeadsUpContentView(increasedHeight);
             }
 
             Icon oldLargeIcon = mBuilder.mN.mLargeIcon;
-            mBuilder.mN.mLargeIcon = Icon.createWithBitmap(mPicture);
+            mBuilder.mN.mLargeIcon = mPictureIcon;
             // The legacy largeIcon might not allow us to clear the image, as it's taken in
             // replacement if the other one is null. Because we're restoring these legacy icons
             // for old listeners, this is in general non-null.
@@ -7463,7 +7478,7 @@
                 mBuilder.mN.largeIcon = largeIconLegacy;
             }
 
-            contentView.setImageViewBitmap(R.id.big_picture, mPicture);
+            contentView.setImageViewIcon(R.id.big_picture, mPictureIcon);
 
             if (mPictureContentDescription != null) {
                 contentView.setContentDescription(R.id.big_picture, mPictureContentDescription);
@@ -7486,7 +7501,17 @@
                         mPictureContentDescription);
             }
             extras.putBoolean(EXTRA_SHOW_BIG_PICTURE_WHEN_COLLAPSED, mShowBigPictureWhenCollapsed);
-            extras.putParcelable(EXTRA_PICTURE, mPicture);
+
+            // If the icon contains a bitmap, use the old extra so that listeners which look for
+            // that extra can still find the picture.  Don't include the new extra in that case,
+            // to avoid duplicating data.
+            if (mPictureIcon != null && mPictureIcon.getType() == Icon.TYPE_BITMAP) {
+                extras.putParcelable(EXTRA_PICTURE, mPictureIcon.getBitmap());
+                extras.putParcelable(EXTRA_PICTURE_ICON, null);
+            } else {
+                extras.putParcelable(EXTRA_PICTURE, null);
+                extras.putParcelable(EXTRA_PICTURE_ICON, mPictureIcon);
+            }
         }
 
         /**
@@ -7507,7 +7532,16 @@
             }
 
             mShowBigPictureWhenCollapsed = extras.getBoolean(EXTRA_SHOW_BIG_PICTURE_WHEN_COLLAPSED);
-            mPicture = extras.getParcelable(EXTRA_PICTURE);
+
+            // When this style adds a picture, we only add one of the keys.  If both were added,
+            // it would most likely be a legacy app trying to override the picture in some way.
+            // Because of that case it's better to give precedence to the legacy field.
+            Bitmap bitmapPicture = extras.getParcelable(EXTRA_PICTURE);
+            if (bitmapPicture != null) {
+                mPictureIcon = Icon.createWithBitmap(bitmapPicture);
+            } else {
+                mPictureIcon = extras.getParcelable(EXTRA_PICTURE_ICON);
+            }
         }
 
         /**
@@ -7529,20 +7563,32 @@
                 return true;
             }
             BigPictureStyle otherS = (BigPictureStyle) other;
-            return areBitmapsObviouslyDifferent(getBigPicture(), otherS.getBigPicture());
+            return areIconsObviouslyDifferent(getBigPicture(), otherS.getBigPicture());
         }
 
-        private static boolean areBitmapsObviouslyDifferent(Bitmap a, Bitmap b) {
+        private static boolean areIconsObviouslyDifferent(Icon a, Icon b) {
             if (a == b) {
                 return false;
             }
             if (a == null || b == null) {
                 return true;
             }
-            return a.getWidth() != b.getWidth()
-                    || a.getHeight() != b.getHeight()
-                    || a.getConfig() != b.getConfig()
-                    || a.getGenerationId() != b.getGenerationId();
+            if (a.sameAs(b)) {
+                return false;
+            }
+            final int aType = a.getType();
+            if (aType != b.getType()) {
+                return true;
+            }
+            if (aType == Icon.TYPE_BITMAP || aType == Icon.TYPE_ADAPTIVE_BITMAP) {
+                final Bitmap aBitmap = a.getBitmap();
+                final Bitmap bBitmap = b.getBitmap();
+                return aBitmap.getWidth() != bBitmap.getWidth()
+                        || aBitmap.getHeight() != bBitmap.getHeight()
+                        || aBitmap.getConfig() != bBitmap.getConfig()
+                        || aBitmap.getGenerationId() != bBitmap.getGenerationId();
+            }
+            return true;
         }
     }
 
@@ -8978,7 +9024,7 @@
          */
         @Override
         public RemoteViews makeContentView(boolean increasedHeight) {
-            return makeMediaContentView();
+            return makeMediaContentView(null /* customContent */);
         }
 
         /**
@@ -8986,7 +9032,7 @@
          */
         @Override
         public RemoteViews makeBigContentView() {
-            return makeMediaBigContentView();
+            return makeMediaBigContentView(null /* customContent */);
         }
 
         /**
@@ -8994,7 +9040,7 @@
          */
         @Override
         public RemoteViews makeHeadsUpContentView(boolean increasedHeight) {
-            return makeMediaContentView();
+            return makeMediaContentView(null /* customContent */);
         }
 
         /** @hide */
@@ -9064,88 +9110,70 @@
             container.setContentDescription(buttonId, action.title);
         }
 
-        private RemoteViews makeMediaContentView() {
-            StandardTemplateParams p = mBuilder.mParams.reset()
-                    .viewType(StandardTemplateParams.VIEW_TYPE_NORMAL)
-                    .hideProgress(true)
-                    .fillTextsFrom(mBuilder);
-            RemoteViews view = mBuilder.applyStandardTemplate(
-                    R.layout.notification_template_material_media, p,
-                    null /* result */);
-
+        /** @hide */
+        protected RemoteViews makeMediaContentView(@Nullable RemoteViews customContent) {
             final int numActions = mBuilder.mActions.size();
-            final int numActionsToShow = mActionsToShowInCompact == null
-                    ? 0
-                    : Math.min(mActionsToShowInCompact.length, MAX_MEDIA_BUTTONS_IN_COMPACT);
+            final int numActionsToShow = Math.min(mActionsToShowInCompact == null
+                    ? 0 : mActionsToShowInCompact.length, MAX_MEDIA_BUTTONS_IN_COMPACT);
             if (numActionsToShow > numActions) {
                 throw new IllegalArgumentException(String.format(
                         "setShowActionsInCompactView: action %d out of bounds (max %d)",
                         numActions, numActions - 1));
             }
+
+            StandardTemplateParams p = mBuilder.mParams.reset()
+                    .viewType(StandardTemplateParams.VIEW_TYPE_NORMAL)
+                    .hideTime(numActionsToShow > 1)    // hide if actions wider than a large icon
+                    .hideSubText(numActionsToShow > 1) // hide if actions wider than a large icon
+                    .hideLargeIcon(numActionsToShow > 0)  // large icon or actions; not both
+                    .hideProgress(true)
+                    .fillTextsFrom(mBuilder);
+            TemplateBindResult result = new TemplateBindResult();
+            RemoteViews template = mBuilder.applyStandardTemplate(
+                    R.layout.notification_template_material_media, p,
+                    null /* result */);
+
             for (int i = 0; i < MAX_MEDIA_BUTTONS_IN_COMPACT; i++) {
                 if (i < numActionsToShow) {
                     final Action action = mBuilder.mActions.get(mActionsToShowInCompact[i]);
-                    bindMediaActionButton(view, MEDIA_BUTTON_IDS[i], action, p);
+                    bindMediaActionButton(template, MEDIA_BUTTON_IDS[i], action, p);
                 } else {
-                    view.setViewVisibility(MEDIA_BUTTON_IDS[i], View.GONE);
+                    template.setViewVisibility(MEDIA_BUTTON_IDS[i], View.GONE);
                 }
             }
-            handleImage(view);
-            // handle the content margin
-            int endMargin = R.dimen.notification_content_margin_end;
-            if (mBuilder.mN.hasLargeIcon()) {
-                endMargin = R.dimen.notification_media_image_margin_end;
-            }
-            view.setViewLayoutMarginDimen(R.id.notification_main_column,
-                            RemoteViews.MARGIN_END, endMargin);
-            return view;
+            // Prevent a swooping expand animation when there are no actions
+            boolean hasActions = numActionsToShow != 0;
+            template.setViewVisibility(R.id.media_actions, hasActions ? View.VISIBLE : View.GONE);
+
+            // Add custom view if provided by subclass.
+            buildCustomContentIntoTemplate(mBuilder.mContext, template, customContent, p, result);
+            return template;
         }
 
-        private RemoteViews makeMediaBigContentView() {
+        /** @hide */
+        protected RemoteViews makeMediaBigContentView(@Nullable RemoteViews customContent) {
             final int actionCount = Math.min(mBuilder.mActions.size(), MAX_MEDIA_BUTTONS);
-            // Dont add an expanded view if there is no more content to be revealed
-            int actionsInCompact = mActionsToShowInCompact == null
-                    ? 0
-                    : Math.min(mActionsToShowInCompact.length, MAX_MEDIA_BUTTONS_IN_COMPACT);
-            if (!mBuilder.mN.hasLargeIcon() && actionCount <= actionsInCompact) {
-                return null;
-            }
             StandardTemplateParams p = mBuilder.mParams.reset()
                     .viewType(StandardTemplateParams.VIEW_TYPE_BIG)
                     .hideProgress(true)
                     .fillTextsFrom(mBuilder);
-            RemoteViews big = mBuilder.applyStandardTemplate(
-                    R.layout.notification_template_material_big_media, p , null /* result */);
+            TemplateBindResult result = new TemplateBindResult();
+            RemoteViews template = mBuilder.applyStandardTemplate(
+                    R.layout.notification_template_material_big_media, p , result);
 
             for (int i = 0; i < MAX_MEDIA_BUTTONS; i++) {
                 if (i < actionCount) {
-                    bindMediaActionButton(big, MEDIA_BUTTON_IDS[i], mBuilder.mActions.get(i), p);
+                    bindMediaActionButton(template,
+                            MEDIA_BUTTON_IDS[i], mBuilder.mActions.get(i), p);
                 } else {
-                    big.setViewVisibility(MEDIA_BUTTON_IDS[i], View.GONE);
+                    template.setViewVisibility(MEDIA_BUTTON_IDS[i], View.GONE);
                 }
             }
-            handleImage(big);
-            return big;
-        }
-
-        private void handleImage(RemoteViews contentView) {
-            if (mBuilder.mN.hasLargeIcon()) {
-                contentView.setViewLayoutMarginDimen(R.id.title, RemoteViews.MARGIN_END, 0);
-                contentView.setViewLayoutMarginDimen(R.id.text, RemoteViews.MARGIN_END, 0);
-            }
-        }
-
-        /**
-         * @hide
-         */
-        @Override
-        protected boolean hasProgress() {
-            return false;
+            buildCustomContentIntoTemplate(mBuilder.mContext, template, customContent, p, result);
+            return template;
         }
     }
 
-
-
     /**
      * Helper class for generating large-format notifications that include a large image attachment.
      *
@@ -9718,16 +9746,15 @@
             if (mBuilder.mActions.size() == 0) {
                return makeStandardTemplateWithCustomContent(headsUpContentView);
             }
-            int decorationType = getDecorationType();
             TemplateBindResult result = new TemplateBindResult();
             StandardTemplateParams p = mBuilder.mParams.reset()
                     .viewType(StandardTemplateParams.VIEW_TYPE_HEADS_UP)
-                    .decorationType(decorationType)
+                    .decorationType(StandardTemplateParams.DECORATION_PARTIAL)
                     .fillTextsFrom(mBuilder);
             RemoteViews remoteViews = mBuilder.applyStandardTemplateWithActions(
                     mBuilder.getHeadsUpBaseLayoutResource(), p, result);
             buildCustomContentIntoTemplate(mBuilder.mContext, remoteViews, headsUpContentView,
-                    p, result, decorationType);
+                    p, result);
             return remoteViews;
         }
 
@@ -9735,16 +9762,15 @@
             if (customContent == null) {
                 return null;  // no custom view; use the default behavior
             }
-            int decorationType = getDecorationType();
             TemplateBindResult result = new TemplateBindResult();
             StandardTemplateParams p = mBuilder.mParams.reset()
                     .viewType(StandardTemplateParams.VIEW_TYPE_NORMAL)
-                    .decorationType(decorationType)
+                    .decorationType(StandardTemplateParams.DECORATION_PARTIAL)
                     .fillTextsFrom(mBuilder);
             RemoteViews remoteViews = mBuilder.applyStandardTemplate(
                     mBuilder.getBaseLayoutResource(), p, result);
             buildCustomContentIntoTemplate(mBuilder.mContext, remoteViews, customContent,
-                    p, result, decorationType);
+                    p, result);
             return remoteViews;
         }
 
@@ -9755,24 +9781,18 @@
             if (bigContentView == null) {
                 return null;  // no custom view; use the default behavior
             }
-            int decorationType = getDecorationType();
             TemplateBindResult result = new TemplateBindResult();
             StandardTemplateParams p = mBuilder.mParams.reset()
                     .viewType(StandardTemplateParams.VIEW_TYPE_BIG)
-                    .decorationType(decorationType)
+                    .decorationType(StandardTemplateParams.DECORATION_PARTIAL)
                     .fillTextsFrom(mBuilder);
             RemoteViews remoteViews = mBuilder.applyStandardTemplateWithActions(
                     mBuilder.getBigBaseLayoutResource(), p, result);
             buildCustomContentIntoTemplate(mBuilder.mContext, remoteViews, bigContentView,
-                    p, result, decorationType);
+                    p, result);
             return remoteViews;
         }
 
-        private int getDecorationType() {
-            ContentResolver contentResolver = mBuilder.mContext.getContentResolver();
-            return DevFlags.getDecoratedCustomViewNotifDecoration(contentResolver);
-        }
-
         /**
          * @hide
          */
@@ -9833,9 +9853,7 @@
          */
         @Override
         public RemoteViews makeContentView(boolean increasedHeight) {
-            RemoteViews remoteViews = super.makeContentView(false /* increasedHeight */);
-            return buildIntoRemoteView(remoteViews, R.id.notification_content_container,
-                    mBuilder.mN.contentView);
+            return makeMediaContentView(mBuilder.mN.contentView);
         }
 
         /**
@@ -9843,24 +9861,10 @@
          */
         @Override
         public RemoteViews makeBigContentView() {
-            RemoteViews customRemoteView = mBuilder.mN.bigContentView != null
+            RemoteViews customContent = mBuilder.mN.bigContentView != null
                     ? mBuilder.mN.bigContentView
                     : mBuilder.mN.contentView;
-            return makeBigContentViewWithCustomContent(customRemoteView);
-        }
-
-        private RemoteViews makeBigContentViewWithCustomContent(RemoteViews customRemoteView) {
-            RemoteViews remoteViews = super.makeBigContentView();
-            if (remoteViews != null) {
-                return buildIntoRemoteView(remoteViews, R.id.notification_main_column,
-                        customRemoteView);
-            } else if (customRemoteView != mBuilder.mN.contentView){
-                remoteViews = super.makeContentView(false /* increasedHeight */);
-                return buildIntoRemoteView(remoteViews, R.id.notification_content_container,
-                        customRemoteView);
-            } else {
-                return null;
-            }
+            return makeMediaBigContentView(customContent);
         }
 
         /**
@@ -9868,10 +9872,10 @@
          */
         @Override
         public RemoteViews makeHeadsUpContentView(boolean increasedHeight) {
-            RemoteViews customRemoteView = mBuilder.mN.headsUpContentView != null
+            RemoteViews customContent = mBuilder.mN.headsUpContentView != null
                     ? mBuilder.mN.headsUpContentView
                     : mBuilder.mN.contentView;
-            return makeBigContentViewWithCustomContent(customRemoteView);
+            return makeMediaBigContentView(customContent);
         }
 
         /**
@@ -9886,18 +9890,21 @@
             return false;
         }
 
-        private RemoteViews buildIntoRemoteView(RemoteViews remoteViews, int id,
-                RemoteViews customContent) {
+        private RemoteViews buildIntoRemoteView(RemoteViews template, RemoteViews customContent,
+                boolean headerless) {
             if (customContent != null) {
                 // Need to clone customContent before adding, because otherwise it can no longer be
                 // parceled independently of remoteViews.
                 customContent = customContent.clone();
                 customContent.overrideTextColors(mBuilder.getPrimaryTextColor(mBuilder.mParams));
-                remoteViews.removeAllViews(id);
-                remoteViews.addView(id, customContent);
-                remoteViews.addFlags(RemoteViews.FLAG_REAPPLY_DISALLOWED);
+                if (headerless) {
+                    template.removeFromParent(R.id.notification_top_line);
+                }
+                template.removeAllViews(R.id.notification_main_column);
+                template.addView(R.id.notification_main_column, customContent);
+                template.addFlags(RemoteViews.FLAG_REAPPLY_DISALLOWED);
             }
-            return remoteViews;
+            return template;
         }
     }
 
@@ -12178,6 +12185,22 @@
     }
 
     private static class StandardTemplateParams {
+        /**
+         * Notifications will be minimally decorated with ONLY an icon and expander:
+         * <li>A large icon is never shown.
+         * <li>A progress bar is never shown.
+         * <li>The expanded and heads up states do not show actions, even if provided.
+         */
+        public static final int DECORATION_MINIMAL = 1;
+
+        /**
+         * Notifications will be partially decorated with AT LEAST an icon and expander:
+         * <li>A large icon is shown if provided.
+         * <li>A progress bar is shown if provided and enough space remains below the content.
+         * <li>Actions are shown in the expanded and heads up states.
+         */
+        public static final int DECORATION_PARTIAL = 2;
+
         public static int VIEW_TYPE_UNSPECIFIED = 0;
         public static int VIEW_TYPE_NORMAL = 1;
         public static int VIEW_TYPE_BIG = 2;
@@ -12190,6 +12213,8 @@
         boolean mHeaderless;
         boolean mHideAppName;
         boolean mHideTitle;
+        boolean mHideSubText;
+        boolean mHideTime;
         boolean mHideActions;
         boolean mHideProgress;
         boolean mHideSnoozeButton;
@@ -12212,6 +12237,8 @@
             mHeaderless = false;
             mHideAppName = false;
             mHideTitle = false;
+            mHideSubText = false;
+            mHideTime = false;
             mHideActions = false;
             mHideProgress = false;
             mHideSnoozeButton = false;
@@ -12225,6 +12252,7 @@
             summaryText = null;
             headerTextSecondary = null;
             maxRemoteInputHistory = Style.MAX_REMOTE_INPUT_HISTORY_LINES;
+            hideLargeIcon = false;
             allowColorization = true;
             mReduceHighlights = false;
             return this;
@@ -12249,6 +12277,16 @@
             return this;
         }
 
+        public StandardTemplateParams hideSubText(boolean hideSubText) {
+            mHideSubText = hideSubText;
+            return this;
+        }
+
+        public StandardTemplateParams hideTime(boolean hideTime) {
+            mHideTime = hideTime;
+            return this;
+        }
+
         final StandardTemplateParams hideActions(boolean hideActions) {
             this.mHideActions = hideActions;
             return this;
@@ -12348,134 +12386,14 @@
         }
 
         public StandardTemplateParams decorationType(int decorationType) {
-            boolean hideTitle = decorationType <= DevFlags.DECORATION_FULL_COMPATIBLE;
-            boolean hideOtherFields = decorationType <= DevFlags.DECORATION_MINIMAL;
-            hideTitle(hideTitle);
+            hideTitle(true);
+            // Minimally decorated custom views do not show certain pieces of chrome that have
+            // always been shown when using DecoratedCustomViewStyle.
+            boolean hideOtherFields = decorationType <= DECORATION_MINIMAL;
             hideLargeIcon(hideOtherFields);
             hideProgress(hideOtherFields);
             hideActions(hideOtherFields);
             return this;
         }
     }
-
-    /**
-     * A class to centrally access various developer flags related to notifications.
-     * This class is a non-final wrapper around Settings.Global which allows mocking for unit tests.
-     * TODO(b/176239013): Try to remove this before shipping S
-     * @hide
-     */
-    public static class DevFlags {
-
-        /**
-         * Notifications will not be decorated.  The custom content will be shown as-is.
-         *
-         * <p>NOTE: This option is not available for notifications with DecoratedCustomViewStyle,
-         * as that API contract includes decorations that this does not provide.
-         */
-        public static final int DECORATION_NONE = 0;
-
-        /**
-         * Notifications will be minimally decorated with ONLY an icon and expander as follows:
-         * <li>A large icon is never shown.
-         * <li>A progress bar is never shown.
-         * <li>The expanded and heads up states do not show actions, even if provided.
-         * <li>The collapsed state gives the app's custom content 48dp of vertical space.
-         * <li>The collapsed state does NOT include the top line of views,
-         * like the alerted icon or work profile badge.
-         *
-         * <p>NOTE: This option is not available for notifications with DecoratedCustomViewStyle,
-         * as that API contract includes decorations that this does not provide.
-         */
-        public static final int DECORATION_MINIMAL = 1;
-
-        /**
-         * Notifications will be partially decorated with AT LEAST an icon and expander as follows:
-         * <li>A large icon is shown if provided.
-         * <li>A progress bar is shown if provided and enough space remains below the content.
-         * <li>Actions are shown in the expanded and heads up states.
-         * <li>The collapsed state gives the app's custom content 48dp of vertical space.
-         * <li>The collapsed state does NOT include the top line of views,
-         * like the alerted icon or work profile badge.
-         */
-        public static final int DECORATION_PARTIAL = 2;
-
-        /**
-         * Notifications will be fully decorated as follows:
-         * <li>A large icon is shown if provided.
-         * <li>A progress bar is shown if provided and enough space remains below the content.
-         * <li>Actions are shown in the expanded and heads up states.
-         * <li>The collapsed state gives the app's custom content 40dp of vertical space.
-         * <li>The collapsed state DOES include the top line of views,
-         * like the alerted icon or work profile badge.
-         * <li>The collapsed state's top line views will never show the title text.
-         */
-        public static final int DECORATION_FULL_COMPATIBLE = 3;
-
-        /**
-         * Notifications will be fully decorated as follows:
-         * <li>A large icon is shown if provided.
-         * <li>A progress bar is shown if provided and enough space remains below the content.
-         * <li>Actions are shown in the expanded and heads up states.
-         * <li>The collapsed state gives the app's custom content 20dp of vertical space.
-         * <li>The collapsed state DOES include the top line of views
-         * like the alerted icon or work profile badge.
-         * <li>The collapsed state's top line views will contain the title text if provided.
-         */
-        public static final int DECORATION_FULL_CONSTRAINED = 4;
-
-        private static final boolean DEFAULT_BACKPORT_S_NOTIF_RULES = false;
-        private static final int DEFAULT_FULLY_CUSTOM_DECORATION = DECORATION_MINIMAL;
-        private static final int DEFAULT_DECORATED_DECORATION = DECORATION_PARTIAL;
-
-        /**
-         * Used by unit tests to force that this class returns its default values, which is required
-         * in cases where the ContentResolver instance is a mock.
-         * @hide
-         */
-        public static boolean sForceDefaults;
-
-        /**
-         * @return if the S notification rules should be backported to apps not yet targeting S
-         * @hide
-         */
-        public static boolean shouldBackportSNotifRules(@NonNull ContentResolver contentResolver) {
-            if (sForceDefaults) {
-                return DEFAULT_BACKPORT_S_NOTIF_RULES;
-            }
-            return Settings.Global.getInt(contentResolver, Settings.Global.BACKPORT_S_NOTIF_RULES,
-                        DEFAULT_BACKPORT_S_NOTIF_RULES ? 1 : 0) == 1;
-        }
-
-        /**
-         * @return the decoration type to be applied to notifications with fully custom view.
-         * @hide
-         */
-        public static int getFullyCustomViewNotifDecoration(
-                @NonNull ContentResolver contentResolver) {
-            if (sForceDefaults) {
-                return DEFAULT_FULLY_CUSTOM_DECORATION;
-            }
-            final int decoration = Settings.Global.getInt(contentResolver,
-                    Settings.Global.FULLY_CUSTOM_VIEW_NOTIF_DECORATION,
-                    DEFAULT_FULLY_CUSTOM_DECORATION);
-            // clamp to a valid decoration value
-            return Math.max(DECORATION_NONE, Math.min(decoration, DECORATION_FULL_CONSTRAINED));
-        }
-
-        /**
-         * @return the decoration type to be applied to notifications with DecoratedCustomViewStyle.
-         * @hide
-         */
-        public static int getDecoratedCustomViewNotifDecoration(
-                @NonNull ContentResolver contentResolver) {
-            if (sForceDefaults) {
-                return DEFAULT_DECORATED_DECORATION;
-            }
-            final int decoration = Settings.Global.getInt(contentResolver,
-                    Settings.Global.DECORATED_CUSTOM_VIEW_NOTIF_DECORATION,
-                    DEFAULT_DECORATED_DECORATION);
-            // clamp to a valid decoration value (and don't allow decoration to be NONE or MINIMAL)
-            return Math.max(DECORATION_PARTIAL, Math.min(decoration, DECORATION_FULL_CONSTRAINED));
-        }
-    }
 }
diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java
index 11adc5a..f4b9542 100644
--- a/core/java/android/app/PendingIntent.java
+++ b/core/java/android/app/PendingIntent.java
@@ -1010,7 +1010,7 @@
      * @deprecated Renamed to {@link #getCreatorPackage()}.
      */
     @Deprecated
-    @NonNull
+    @Nullable
     public String getTargetPackage() {
         return getCreatorPackage();
     }
@@ -1032,7 +1032,7 @@
      *
      * @return The package name of the PendingIntent.
      */
-    @NonNull
+    @Nullable
     public String getCreatorPackage() {
         return getCachedInfo().getCreatorPackage();
     }
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index ac8d3a2..74134e1 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -39,13 +39,13 @@
 import android.os.Process;
 import android.os.Trace;
 import android.util.ArrayMap;
-import android.util.ArraySet;
 import android.util.DisplayMetrics;
 import android.util.Log;
 import android.util.Pair;
 import android.util.Slog;
 import android.view.Display;
 import android.view.DisplayAdjustments;
+import android.window.WindowContext;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.ArrayUtils;
@@ -61,7 +61,6 @@
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashSet;
-import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Objects;
 import java.util.WeakHashMap;
@@ -168,7 +167,7 @@
 
     /**
      * Class containing the base configuration override and set of resources associated with an
-     * Activity or {@link WindowContext}.
+     * {@link Activity} or a {@link WindowContext}.
      */
     private static class ActivityResources {
         /**
diff --git a/core/java/android/app/WallpaperColors.java b/core/java/android/app/WallpaperColors.java
index 6b2e649..d640a6f 100644
--- a/core/java/android/app/WallpaperColors.java
+++ b/core/java/android/app/WallpaperColors.java
@@ -189,7 +189,7 @@
         } else {
             palette = Palette
                     .from(bitmap, new CelebiQuantizer())
-                    .maximumColorCount(256)
+                    .maximumColorCount(5)
                     .resizeBitmapArea(MAX_WALLPAPER_EXTRACTION_AREA)
                     .generate();
         }
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index 3ef6757..6a71c92 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -1962,14 +1962,20 @@
     }
 
     /**
-     * Set the current zoom out level of the wallpaper
+     * Set the current zoom out level of the wallpaper.
+     *
+     * @param windowToken window requesting wallpaper zoom. Zoom level will only be applier while
+     *                    such window is visible.
      * @param zoom from 0 to 1 (inclusive) where 1 means fully zoomed out, 0 means fully zoomed in
      *
      * @hide
      */
-    public void setWallpaperZoomOut(IBinder windowToken, float zoom) {
+    public void setWallpaperZoomOut(@NonNull IBinder windowToken, float zoom) {
         if (zoom < 0 || zoom > 1f) {
-            throw new IllegalArgumentException("zoom must be between 0 and one: " + zoom);
+            throw new IllegalArgumentException("zoom must be between 0 and 1: " + zoom);
+        }
+        if (windowToken == null) {
+            throw new IllegalArgumentException("windowToken must not be null");
         }
         try {
             WindowManagerGlobal.getWindowSession().setWallpaperZoomOut(windowToken, zoom);
diff --git a/core/java/android/app/WindowContext.java b/core/java/android/app/WindowContext.java
deleted file mode 100644
index cbe2995..0000000
--- a/core/java/android/app/WindowContext.java
+++ /dev/null
@@ -1,138 +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 android.app;
-
-import static android.view.WindowManagerImpl.createWindowContextWindowManager;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.UiContext;
-import android.content.Context;
-import android.content.ContextWrapper;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.view.Display;
-import android.view.IWindowManager;
-import android.view.WindowManager;
-import android.view.WindowManagerGlobal;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.lang.ref.Reference;
-
-/**
- * {@link WindowContext} is a context for non-activity windows such as
- * {@link android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY} windows or system
- * windows. Its resources and configuration are adjusted to the area of the display that will be
- * used when a new window is added via {@link android.view.WindowManager#addView}.
- *
- * @see Context#createWindowContext(int, Bundle)
- * @hide
- */
-@UiContext
-public class WindowContext extends ContextWrapper {
-    private final WindowManager mWindowManager;
-    private final IWindowManager mWms;
-    private final WindowTokenClient mToken;
-    private boolean mListenerRegistered;
-
-    /**
-     * Default constructor. Will generate a {@link WindowTokenClient} and attach this context to
-     * the token.
-     *
-     * @param base Base {@link Context} for this new instance.
-     * @param type Window type to be used with this context.
-     * @hide
-     */
-    public WindowContext(@NonNull Context base, int type, @Nullable Bundle options) {
-        this(base, null /* display */, type, options);
-    }
-
-    /**
-     * Default constructor. Will generate a {@link WindowTokenClient} and attach this context to
-     * the token.
-     *
-     * @param base Base {@link Context} for this new instance.
-     * @param display the {@link Display} to override.
-     * @param type Window type to be used with this context.
-     * @hide
-     */
-    public WindowContext(@NonNull Context base, @Nullable Display display, int type,
-            @Nullable Bundle options) {
-        // Correct base context will be built once the token is resolved, so passing 'null' here.
-        super(null /* base */);
-
-        mWms = WindowManagerGlobal.getWindowManagerService();
-        mToken = new WindowTokenClient();
-
-        final ContextImpl contextImpl = createBaseWindowContext(base, mToken, display);
-        attachBaseContext(contextImpl);
-        contextImpl.setOuterContext(this);
-
-        mToken.attachContext(this);
-
-        mWindowManager = createWindowContextWindowManager(this);
-
-        try {
-            mListenerRegistered = mWms.registerWindowContextListener(mToken, type, getDisplayId(),
-                    options);
-        }  catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-        Reference.reachabilityFence(this);
-    }
-
-    private static ContextImpl createBaseWindowContext(Context outer, IBinder token,
-            Display display) {
-        final ContextImpl contextImpl = ContextImpl.getImpl(outer);
-        return contextImpl.createBaseWindowContext(token, display);
-    }
-
-    @Override
-    public Object getSystemService(String name) {
-        if (WINDOW_SERVICE.equals(name)) {
-            return mWindowManager;
-        }
-        return super.getSystemService(name);
-    }
-
-    @Override
-    protected void finalize() throws Throwable {
-        release();
-        super.finalize();
-    }
-
-    /** Used for test to invoke because we can't invoke finalize directly. */
-    @VisibleForTesting
-    public void release() {
-        if (mListenerRegistered) {
-            mListenerRegistered = false;
-            try {
-                mWms.unregisterWindowContextListener(mToken);
-            } catch (RemoteException e) {
-                throw e.rethrowFromSystemServer();
-            }
-        }
-        destroy();
-    }
-
-    void destroy() {
-        final ContextImpl impl = (ContextImpl) getBaseContext();
-        impl.scheduleFinalCleanup(getClass().getName(), "WindowContext");
-        Reference.reachabilityFence(this);
-    }
-}
diff --git a/core/java/android/app/admin/DeviceAdminReceiver.java b/core/java/android/app/admin/DeviceAdminReceiver.java
index 747a2de..da64dcd 100644
--- a/core/java/android/app/admin/DeviceAdminReceiver.java
+++ b/core/java/android/app/admin/DeviceAdminReceiver.java
@@ -524,6 +524,16 @@
             "android.app.action.OPERATION_SAFETY_STATE_CHANGED";
 
     /**
+     * Broadcast action: notify the profile owner on an organization-owned device that it needs to
+     * acknowledge device compliance.
+     *
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_COMPLIANCE_ACKNOWLEDGEMENT_REQUIRED =
+            "android.app.action.COMPLIANCE_ACKNOWLEDGEMENT_REQUIRED";
+
+    /**
      * An {@code int} extra specifying an {@link OperationSafetyReason}.
      *
      * @hide
@@ -1116,6 +1126,29 @@
         onOperationSafetyStateChanged(context, reason, isSafe);
     }
 
+    /**
+     * Called to notify a profile owner of an organization-owned device that it needs to acknowledge
+     * device compliance to allow the user to turn the profile off if needed according to the
+     * maximum profile time off policy.
+     *
+     * Default implementation acknowledges compliance immediately. DPC may prefer to override this
+     * implementation to delay acknowledgement until a successful policy sync. Until compliance is
+     * acknowledged the user is still free to turn the profile off, but the timer won't be reset,
+     * so personal apps will be suspended sooner. This callback is delivered using a foreground
+     * broadcast and should be handled quickly.
+     *
+     * @param context the running context as per {@link #onReceive}
+     * @param intent The received intent as per {@link #onReceive}.
+     *
+     * @see DevicePolicyManager#acknowledgeDeviceCompliant()
+     * @see DevicePolicyManager#isComplianceAcknowledgementRequired()
+     * @see DevicePolicyManager#setManagedProfileMaximumTimeOff(ComponentName, long)
+     */
+    public void onComplianceAcknowledgementRequired(
+            @NonNull Context context, @NonNull Intent intent) {
+        getManager(context).acknowledgeDeviceCompliant();
+    }
+
     private boolean hasRequiredExtra(Intent intent, String extra) {
         if (intent.hasExtra(extra)) return true;
 
@@ -1204,6 +1237,8 @@
                     intent.getParcelableExtra(Intent.EXTRA_USER));
         } else if (ACTION_OPERATION_SAFETY_STATE_CHANGED.equals(action)) {
             onOperationSafetyStateChanged(context, intent);
+        } else if (ACTION_COMPLIANCE_ACKNOWLEDGEMENT_REQUIRED.equals(action)) {
+            onComplianceAcknowledgementRequired(context, intent);
         }
     }
 }
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 426159f..89d08cc 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -872,8 +872,7 @@
      *
      * The name is displayed only during provisioning.
      *
-     * <p>Use in an intent with action {@link #ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE}
-     * or {@link #ACTION_PROVISION_FINANCED_DEVICE}
+     * <p>Use in an intent with action {@link #ACTION_PROVISION_FINANCED_DEVICE}
      *
      * @hide
      */
@@ -1676,6 +1675,29 @@
     })
     public @interface PasswordComplexity {}
 
+    /** Indicates that nearby streaming is disabled. */
+    public static final int NEARBY_STREAMING_DISABLED = 0;
+
+    /** Indicates that nearby streaming is enabled. */
+    public static final int NEARBY_STREAMING_ENABLED = 1;
+
+    /**
+     * Indicates that nearby streaming is enabled only to devices offering a comparable level of
+     * security, with the same authenticated managed account.
+     */
+    public static final int NEARBY_STREAMING_SAME_MANAGED_ACCOUNT_ONLY = 2;
+
+    /**
+     * @hide
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = {"NEARBY_STREAMING_"}, value = {
+        NEARBY_STREAMING_DISABLED,
+        NEARBY_STREAMING_ENABLED,
+        NEARBY_STREAMING_SAME_MANAGED_ACCOUNT_ONLY,
+    })
+    public @interface NearbyStreamingPolicy {}
+
     /**
      * Activity action: have the user enter a new password for the parent profile.
      * If the intent is launched from within a managed profile, this will trigger
@@ -3307,6 +3329,41 @@
             "android.account.DEVICE_OR_PROFILE_OWNER_DISALLOWED";
 
     /**
+     * A {@code boolean} metadata to be included in a mainline module's {@code <application>}
+     * manifest element, which declares that the module should be considered a required app for
+     * managed users.
+     * <p>Being declared as a required app prevents removal of this package during the
+     * provisioning process.
+     * @hide
+     */
+    @SystemApi
+    public static final String REQUIRED_APP_MANAGED_USER = "android.app.REQUIRED_APP_MANAGED_USER";
+
+    /**
+     * A {@code boolean} metadata to be included in a mainline module's {@code <application>}
+     * manifest element, which declares that the module should be considered a required app for
+     * managed devices.
+     * <p>Being declared as a required app prevents removal of this package during the
+     * provisioning process.
+     * @hide
+     */
+    @SystemApi
+    public static final String REQUIRED_APP_MANAGED_DEVICE =
+            "android.app.REQUIRED_APP_MANAGED_DEVICE";
+
+    /**
+     * A {@code boolean} metadata to be included in a mainline module's {@code <application>}
+     * manifest element, which declares that the module should be considered a required app for
+     * managed profiles.
+     * <p>Being declared as a required app prevents removal of this package during the
+     * provisioning process.
+     * @hide
+     */
+    @SystemApi
+    public static final String REQUIRED_APP_MANAGED_PROFILE =
+            "android.app.REQUIRED_APP_MANAGED_PROFILE";
+
+    /**
      * Called by an application that is administering the device to set the password restrictions it
      * is imposing. After setting this, the user will not be able to enter a new password that is
      * not at least as restrictive as what has been set. Note that the current password will remain
@@ -7129,6 +7186,77 @@
     }
 
     /**
+     * Called by a device/profile owner to set nearby notification streaming policy. Notification
+     * streaming is sending notification data from pre-installed apps to nearby devices.
+     *
+     * @param policy One of the {@code NearbyStreamingPolicy} constants.
+     * @throws SecurityException if caller is not a device or profile owner
+     */
+    public void setNearbyNotificationStreamingPolicy(@NearbyStreamingPolicy int policy) {
+        throwIfParentInstance("setNearbyNotificationStreamingPolicy");
+        if (mService == null) {
+            return;
+        }
+        try {
+            mService.setNearbyNotificationStreamingPolicy(policy);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns the current runtime nearby notification streaming policy set by the device or profile
+     * owner. The default is {@link #NEARBY_STREAMING_DISABLED}.
+     */
+    public @NearbyStreamingPolicy int getNearbyNotificationStreamingPolicy() {
+        throwIfParentInstance("getNearbyNotificationStreamingPolicy");
+        if (mService == null) {
+            return NEARBY_STREAMING_DISABLED;
+        }
+        try {
+            return mService.getNearbyNotificationStreamingPolicy();
+        } catch (RemoteException re) {
+            throw re.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Called by a device/profile owner to set nearby app streaming policy. App streaming is when
+     * the device starts an app on a virtual display and sends a video stream of the app to nearby
+     * devices.
+     *
+     * @param policy One of the {@code NearbyStreamingPolicy} constants.
+     * @throws SecurityException if caller is not a device or profile owner.
+     */
+    public void setNearbyAppStreamingPolicy(@NearbyStreamingPolicy int policy) {
+        throwIfParentInstance("setNearbyAppStreamingPolicy");
+        if (mService == null) {
+            return;
+        }
+        try {
+            mService.setNearbyAppStreamingPolicy(policy);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns the current runtime nearby app streaming policy set by the device or profile owner.
+     * The default is {@link #NEARBY_STREAMING_DISABLED}.
+     */
+    public @NearbyStreamingPolicy int getNearbyAppStreamingPolicy() {
+        throwIfParentInstance("getNearbyAppStreamingPolicy");
+        if (mService == null) {
+            return NEARBY_STREAMING_DISABLED;
+        }
+        try {
+            return mService.getNearbyAppStreamingPolicy();
+        } catch (RemoteException re) {
+            throw re.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Called by a device owner, or alternatively a profile owner from Android 8.0 (API level 26) or
      * higher, to set whether auto time is required. If auto time is required, no user will be able
      * set the date and time and network date and time will be used.
@@ -9990,26 +10118,24 @@
     }
 
     /**
-     * Sets whether 5g slicing is enabled on the work profile.
+     * Sets whether enterprise network preference is enabled on the work profile.
      *
-     * Slicing allows operators to virtually divide their networks in portions and use different
-     * portions for specific use cases; for example, a corporation can have a deal/agreement with
-     * a carrier that all of its employees’ devices use data on a slice dedicated for enterprise
-     * use.
+     * For example, a corporation can have a deal/agreement with a carrier that all of its
+     * employees’ devices use data on a network preference dedicated for enterprise use.
      *
-     * By default, 5g slicing is enabled on the work profile on supported carriers and devices.
-     * Admins can explicitly disable it with this API.
+     * By default, enterprise network preference is enabled on the work profile on supported
+     * carriers and devices. Admins can explicitly disable it with this API.
      *
      * <p>This method can only be called by the profile owner of a managed profile.
      *
-     * @param enabled whether 5g Slice should be enabled.
+     * @param enabled whether enterprise network preference should be enabled.
      * @throws SecurityException if the caller is not the profile owner.
      **/
-    public void setNetworkSlicingEnabled(boolean enabled) {
-        throwIfParentInstance("setNetworkSlicingEnabled");
+    public void setEnterpriseNetworkPreferenceEnabled(boolean enabled) {
+        throwIfParentInstance("setEnterpriseNetworkPreferenceEnabled");
         if (mService != null) {
             try {
-                mService.setNetworkSlicingEnabled(enabled);
+                mService.setEnterpriseNetworkPreferenceEnabled(enabled);
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -10017,20 +10143,20 @@
     }
 
     /**
-     * Indicates whether 5g slicing is enabled.
+     * Indicates whether whether enterprise network preference is enabled.
      *
      * <p>This method can be called by the profile owner of a managed profile.
      *
-     * @return whether 5g Slice is enabled.
+     * @return whether whether enterprise network preference is enabled.
      * @throws SecurityException if the caller is not the profile owner.
      */
-    public boolean isNetworkSlicingEnabled() {
-        throwIfParentInstance("isNetworkSlicingEnabled");
+    public boolean isEnterpriseNetworkPreferenceEnabled() {
+        throwIfParentInstance("isEnterpriseNetworkPreferenceEnabled");
         if (mService == null) {
             return false;
         }
         try {
-            return mService.isNetworkSlicingEnabled(myUserId());
+            return mService.isEnterpriseNetworkPreferenceEnabled(myUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -13377,6 +13503,63 @@
     }
 
     /**
+     * Called by a profile owner of an organization-owned managed profile to acknowledge that the
+     * device is compliant and the user can turn the profile off if needed according to the maximum
+     * time off policy.
+     *
+     * This method should be called when the device is deemed compliant after getting
+     * {@link DeviceAdminReceiver#onComplianceAcknowledgementRequired(Context, Intent)} callback in
+     * case it is overridden. Before this method is called the user is still free to turn the
+     * profile off, but the timer won't be reset, so personal apps will be suspended sooner.
+     *
+     * DPCs only need acknowledging device compliance if they override
+     * {@link DeviceAdminReceiver#onComplianceAcknowledgementRequired(Context, Intent)}, otherwise
+     * compliance is acknowledged automatically.
+     *
+     * @throws IllegalStateException if the user isn't unlocked
+     * @see #isComplianceAcknowledgementRequired()
+     * @see #setManagedProfileMaximumTimeOff(ComponentName, long)
+     * @see DeviceAdminReceiver#onComplianceAcknowledgementRequired(Context, Intent)
+     */
+    public void acknowledgeDeviceCompliant() {
+        throwIfParentInstance("acknowledgeDeviceCompliant");
+        if (mService != null) {
+            try {
+                mService.acknowledgeDeviceCompliant();
+            } catch (RemoteException re) {
+                throw re.rethrowFromSystemServer();
+            }
+        }
+    }
+
+    /**
+     * Called by a profile owner of an organization-owned managed profile to query whether it needs
+     * to acknowledge device compliance to allow the user to turn the profile off if needed
+     * according to the maximum profile time off policy.
+     *
+     * Normally when acknowledgement is needed the DPC gets a
+     * {@link DeviceAdminReceiver#onComplianceAcknowledgementRequired(Context, Intent)} callback.
+     * But if the callback was not delivered or handled for some reason, this method can be used to
+     * verify if acknowledgement is needed.
+     *
+     * @throws IllegalStateException if the user isn't unlocked
+     * @see #acknowledgeDeviceCompliant()
+     * @see #setManagedProfileMaximumTimeOff(ComponentName, long)
+     * @see DeviceAdminReceiver#onComplianceAcknowledgementRequired(Context, Intent)
+     */
+    public boolean isComplianceAcknowledgementRequired() {
+        throwIfParentInstance("isComplianceAcknowledgementRequired");
+        if (mService != null) {
+            try {
+                return mService.isComplianceAcknowledgementRequired();
+            } catch (RemoteException re) {
+                throw re.rethrowFromSystemServer();
+            }
+        }
+        return false;
+    }
+
+    /**
      * Returns {@code true} when {@code userId} has a profile owner that is capable of resetting
      * password in RUNNING_LOCKED state. For that it should have at least one direct boot aware
      * component and have an active password reset token. Can only be called by the system.
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 7901791..8a8c69c 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -132,6 +132,12 @@
     void setScreenCaptureDisabled(in ComponentName who, boolean disabled, boolean parent);
     boolean getScreenCaptureDisabled(in ComponentName who, int userHandle, boolean parent);
 
+    void setNearbyNotificationStreamingPolicy(int policy);
+    int getNearbyNotificationStreamingPolicy();
+
+    void setNearbyAppStreamingPolicy(int policy);
+    int getNearbyAppStreamingPolicy();
+
     void setKeyguardDisabledFeatures(in ComponentName who, int which, boolean parent);
     int getKeyguardDisabledFeatures(in ComponentName who, int userHandle, boolean parent);
 
@@ -268,8 +274,8 @@
     void setSecondaryLockscreenEnabled(in ComponentName who, boolean enabled);
     boolean isSecondaryLockscreenEnabled(in UserHandle userHandle);
 
-    void setNetworkSlicingEnabled(in boolean enabled);
-    boolean isNetworkSlicingEnabled(int userHandle);
+    void setEnterpriseNetworkPreferenceEnabled(in boolean enabled);
+    boolean isEnterpriseNetworkPreferenceEnabled(int userHandle);
 
     void setLockTaskPackages(in ComponentName who, in String[] packages);
     String[] getLockTaskPackages(in ComponentName who);
@@ -495,6 +501,10 @@
 
     long getManagedProfileMaximumTimeOff(in ComponentName admin);
     void setManagedProfileMaximumTimeOff(in ComponentName admin, long timeoutMs);
+
+    void acknowledgeDeviceCompliant();
+    boolean isComplianceAcknowledgementRequired();
+
     boolean canProfileOwnerResetPasswordWhenLocked(int userId);
 
     void setNextOperationSafety(int operation, int reason);
diff --git a/core/java/android/app/backup/RestoreSet.java b/core/java/android/app/backup/RestoreSet.java
index 6759346..51430c0 100644
--- a/core/java/android/app/backup/RestoreSet.java
+++ b/core/java/android/app/backup/RestoreSet.java
@@ -16,6 +16,7 @@
 
 package android.app.backup;
 
+import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -32,12 +33,14 @@
      * Name of this restore set.  May be user generated, may simply be the name
      * of the handset model, e.g. "T-Mobile G1".
      */
+    @Nullable
     public String name;
 
     /**
      * Identifier of the device whose data this is.  This will be as unique as
      * is practically possible; for example, it might be an IMEI.
      */
+    @Nullable
     public String device;
 
     /**
@@ -47,15 +50,48 @@
      */
     public long token;
 
+    /**
+     * Properties of the {@link BackupTransport} transport that was used to obtain the data in
+     * this restore set.
+     */
+    public final int backupTransportFlags;
 
+    /**
+     * Constructs a RestoreSet object that identifies a set of data that can be restored.
+     */
     public RestoreSet() {
         // Leave everything zero / null
+        backupTransportFlags = 0;
     }
 
-    public RestoreSet(String _name, String _dev, long _token) {
-        name = _name;
-        device = _dev;
-        token = _token;
+    /**
+     * Constructs a RestoreSet object that identifies a set of data that can be restored.
+     *
+     * @param name The name of the restore set.
+     * @param device The name of the device where the restore data is coming from.
+     * @param token The unique identifier for the current restore set.
+     */
+    public RestoreSet(@Nullable String name, @Nullable String device, long token) {
+        this(name, device, token, /* backupTransportFlags */ 0);
+    }
+
+    /**
+     * Constructs a RestoreSet object that identifies a set of data that can be restored.
+     *
+     * @param name The name of the restore set.
+     * @param device The name of the device where the restore data is coming from.
+     * @param token The unique identifier for the current restore set.
+     * @param backupTransportFlags Flags returned by {@link BackupTransport#getTransportFlags()}
+     *                             implementation of the backup transport used by the source device
+     *                             to create this restore set. See {@link BackupAgent} for possible
+     *                             flag values.
+     */
+    public RestoreSet(@Nullable String name, @Nullable String device, long token,
+            int backupTransportFlags) {
+        this.name = name;
+        this.device = device;
+        this.token = token;
+        this.backupTransportFlags = backupTransportFlags;
     }
 
     // Parcelable implementation
@@ -67,6 +103,7 @@
         out.writeString(name);
         out.writeString(device);
         out.writeLong(token);
+        out.writeInt(backupTransportFlags);
     }
 
     public static final @android.annotation.NonNull Parcelable.Creator<RestoreSet> CREATOR
@@ -84,5 +121,6 @@
         name = in.readString();
         device = in.readString();
         token = in.readLong();
+        backupTransportFlags = in.readInt();
     }
 }
diff --git a/core/java/android/app/compat/CompatChanges.java b/core/java/android/app/compat/CompatChanges.java
index ab38832..74e1ece 100644
--- a/core/java/android/app/compat/CompatChanges.java
+++ b/core/java/android/app/compat/CompatChanges.java
@@ -104,16 +104,15 @@
      *
      * @param packageName The package name of the app in question.
      * @param overrides A map from changeId to the override applied for this change id.
-     * @hide
      */
-    @RequiresPermission(android.Manifest.permission.OVERRIDE_COMPAT_CHANGE_CONFIG)
-    public static void setPackageOverride(String packageName,
-            Map<Long, PackageOverride> overrides) {
+    @RequiresPermission(android.Manifest.permission.OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD)
+    public static void setPackageOverride(@NonNull String packageName,
+            @NonNull Map<Long, PackageOverride> overrides) {
         IPlatformCompat platformCompat = IPlatformCompat.Stub.asInterface(
                 ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
         CompatibilityOverrideConfig config = new CompatibilityOverrideConfig(overrides);
         try {
-            platformCompat.setOverridesFromInstaller(config, packageName);
+            platformCompat.setOverridesOnReleaseBuilds(config, packageName);
         } catch (RemoteException e) {
             e.rethrowFromSystemServer();
         }
diff --git a/core/java/android/app/compat/PackageOverride.java b/core/java/android/app/compat/PackageOverride.java
index 9f97cd4..59b3555 100644
--- a/core/java/android/app/compat/PackageOverride.java
+++ b/core/java/android/app/compat/PackageOverride.java
@@ -17,8 +17,9 @@
 package android.app.compat;
 
 import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
 import android.os.Parcel;
-import android.os.Parcelable;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -32,15 +33,16 @@
  *
  * @hide
  */
-public class PackageOverride implements Parcelable {
+@SystemApi
+public final class PackageOverride {
 
+    /** @hide */
     @IntDef({
             VALUE_UNDEFINED,
             VALUE_ENABLED,
             VALUE_DISABLED
     })
     @Retention(RetentionPolicy.SOURCE)
-    /** @hide */
     public @interface EvaluatedOverride {
     }
 
@@ -75,10 +77,6 @@
         this.mEnabled = enabled;
     }
 
-    private PackageOverride(Parcel in) {
-        this(in.readLong(), in.readLong(), in.readBoolean());
-    }
-
     /**
      * Evaluate the override for the given {@code versionCode}. If no override is defined for
      * the specified version code, {@link #VALUE_UNDEFINED} is returned.
@@ -114,25 +112,23 @@
     }
 
     /** Returns the enabled value for the override. */
-    public boolean getEnabled() {
+    public boolean isEnabled() {
         return mEnabled;
     }
 
     /** @hide */
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    /** @hide */
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
+    public void writeToParcel(Parcel dest) {
         dest.writeLong(mMinVersionCode);
         dest.writeLong(mMaxVersionCode);
         dest.writeBoolean(mEnabled);
     }
 
     /** @hide */
+    public static PackageOverride createFromParcel(Parcel in) {
+        return new PackageOverride(in.readLong(), in.readLong(), in.readBoolean());
+    }
+
+    /** @hide */
     @Override
     public String toString() {
         if (mMinVersionCode == Long.MIN_VALUE && mMaxVersionCode == Long.MAX_VALUE) {
@@ -141,25 +137,10 @@
         return String.format("[%d,%d,%b]", mMinVersionCode, mMaxVersionCode, mEnabled);
     }
 
-    /** @hide */
-    public static final Creator<PackageOverride> CREATOR =
-            new Creator<PackageOverride>() {
-
-                @Override
-                public PackageOverride createFromParcel(Parcel in) {
-                    return new PackageOverride(in);
-                }
-
-                @Override
-                public PackageOverride[] newArray(int size) {
-                    return new PackageOverride[size];
-                }
-            };
-
     /**
      * Builder to construct a PackageOverride.
      */
-    public static class Builder {
+    public static final class Builder {
         private long mMinVersionCode = Long.MIN_VALUE;
         private long mMaxVersionCode = Long.MAX_VALUE;
         private boolean mEnabled;
@@ -169,6 +150,7 @@
          *
          * default value: {@code Long.MIN_VALUE}.
          */
+        @NonNull
         public Builder setMinVersionCode(long minVersionCode) {
             mMinVersionCode = minVersionCode;
             return this;
@@ -179,6 +161,7 @@
          *
          * default value: {@code Long.MAX_VALUE}.
          */
+        @NonNull
         public Builder setMaxVersionCode(long maxVersionCode) {
             mMaxVersionCode = maxVersionCode;
             return this;
@@ -189,6 +172,7 @@
          *
          * default value: {@code false}.
          */
+        @NonNull
         public Builder setEnabled(boolean enabled) {
             mEnabled = enabled;
             return this;
@@ -200,6 +184,7 @@
          * @throws IllegalArgumentException if {@code minVersionCode} is larger than
          *                                  {@code maxVersionCode}.
          */
+        @NonNull
         public PackageOverride build() {
             if (mMinVersionCode > mMaxVersionCode) {
                 throw new IllegalArgumentException("minVersionCode must not be larger than "
diff --git a/core/java/android/app/people/PeopleSpaceTile.java b/core/java/android/app/people/PeopleSpaceTile.java
index dd2ba7d..e645831 100644
--- a/core/java/android/app/people/PeopleSpaceTile.java
+++ b/core/java/android/app/people/PeopleSpaceTile.java
@@ -56,6 +56,7 @@
     private CharSequence mNotificationContent;
     private String mNotificationCategory;
     private Uri mNotificationDataUri;
+    private int mMessagesCount;
     private Intent mIntent;
     private long mNotificationTimestamp;
     private List<ConversationStatus> mStatuses;
@@ -74,6 +75,7 @@
         mNotificationContent = b.mNotificationContent;
         mNotificationCategory = b.mNotificationCategory;
         mNotificationDataUri = b.mNotificationDataUri;
+        mMessagesCount = b.mMessagesCount;
         mIntent = b.mIntent;
         mNotificationTimestamp = b.mNotificationTimestamp;
         mStatuses = b.mStatuses;
@@ -140,6 +142,10 @@
         return mNotificationDataUri;
     }
 
+    public int getMessagesCount() {
+        return mMessagesCount;
+    }
+
     /**
      * Provides an intent to launch. If present, we should manually launch the intent on tile
      * click, rather than calling {@link android.content.pm.LauncherApps} to launch the shortcut ID.
@@ -175,6 +181,7 @@
         builder.setNotificationContent(mNotificationContent);
         builder.setNotificationCategory(mNotificationCategory);
         builder.setNotificationDataUri(mNotificationDataUri);
+        builder.setMessagesCount(mMessagesCount);
         builder.setIntent(mIntent);
         builder.setNotificationTimestamp(mNotificationTimestamp);
         builder.setStatuses(mStatuses);
@@ -196,6 +203,7 @@
         private CharSequence mNotificationContent;
         private String mNotificationCategory;
         private Uri mNotificationDataUri;
+        private int mMessagesCount;
         private Intent mIntent;
         private long mNotificationTimestamp;
         private List<ConversationStatus> mStatuses;
@@ -320,6 +328,12 @@
             return this;
         }
 
+        /** Sets the number of messages associated with the Tile. */
+        public Builder setMessagesCount(int messagesCount) {
+            mMessagesCount = messagesCount;
+            return this;
+        }
+
         /** Sets an intent to launch on click. */
         public Builder setIntent(Intent intent) {
             mIntent = intent;
@@ -359,6 +373,7 @@
         mNotificationContent = in.readCharSequence();
         mNotificationCategory = in.readString();
         mNotificationDataUri = in.readParcelable(Uri.class.getClassLoader());
+        mMessagesCount = in.readInt();
         mIntent = in.readParcelable(Intent.class.getClassLoader());
         mNotificationTimestamp = in.readLong();
         mStatuses = new ArrayList<>();
@@ -385,6 +400,7 @@
         dest.writeCharSequence(mNotificationContent);
         dest.writeString(mNotificationCategory);
         dest.writeParcelable(mNotificationDataUri, flags);
+        dest.writeInt(mMessagesCount);
         dest.writeParcelable(mIntent, flags);
         dest.writeLong(mNotificationTimestamp);
         dest.writeParcelableList(mStatuses, flags);
diff --git a/core/java/android/app/time/ExternalTimeSuggestion.java b/core/java/android/app/time/ExternalTimeSuggestion.java
index 61defb5..8e281c0 100644
--- a/core/java/android/app/time/ExternalTimeSuggestion.java
+++ b/core/java/android/app/time/ExternalTimeSuggestion.java
@@ -20,6 +20,7 @@
 import android.annotation.ElapsedRealtimeLong;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.SystemApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.TimestampedValue;
@@ -67,6 +68,7 @@
  *
  * @hide
  */
+@SystemApi
 public final class ExternalTimeSuggestion implements Parcelable {
 
     public static final @NonNull Creator<ExternalTimeSuggestion> CREATOR =
@@ -129,7 +131,6 @@
 
     /**
      * Returns information that can be useful for debugging / logging. See {@link #addDebugInfo}.
-     * {@hide}
      */
     @NonNull
     public List<String> getDebugInfo() {
diff --git a/core/java/android/app/time/TimeManager.java b/core/java/android/app/time/TimeManager.java
index c8fa5c8..d6acb8c 100644
--- a/core/java/android/app/time/TimeManager.java
+++ b/core/java/android/app/time/TimeManager.java
@@ -262,9 +262,8 @@
      * HAL. This time <em>may</em> be used to set the device system clock, depending on the device
      * configuration and user settings. This method call is processed asynchronously.
      * See {@link ExternalTimeSuggestion} for more details.
-     * {@hide}
      */
-    @RequiresPermission(android.Manifest.permission.SET_TIME)
+    @RequiresPermission(android.Manifest.permission.SUGGEST_EXTERNAL_TIME)
     public void suggestExternalTime(@NonNull ExternalTimeSuggestion timeSuggestion) {
         if (DEBUG) {
             Log.d(TAG, "suggestExternalTime called: " + timeSuggestion);
diff --git a/core/java/android/app/usage/UsageStats.java b/core/java/android/app/usage/UsageStats.java
index 5d50c5d7..ef92172 100644
--- a/core/java/android/app/usage/UsageStats.java
+++ b/core/java/android/app/usage/UsageStats.java
@@ -110,7 +110,9 @@
     public long mTotalTimeForegroundServiceUsed;
 
     /**
-     * Last time this package's component is used, measured in milliseconds since the epoch.
+     * Last time this package's component is used by a client package, measured in milliseconds
+     * since the epoch. Note that component usage is only reported in certain cases (e.g. broadcast
+     * receiver, service, content provider).
      * See {@link UsageEvents.Event#APP_COMPONENT_USED}
      * @hide
      */
@@ -274,8 +276,10 @@
     }
 
     /**
-     * Get the last time this package's component was used, measured in milliseconds since the
-     * epoch.
+     * Get the last time this package's component was used by a client package, measured in
+     * milliseconds since the epoch. Note that component usage is only reported in certain cases
+     * (e.g. broadcast receiver, service, content provider).
+     * See {@link UsageEvents.Event#APP_COMPONENT_USED}
      * @hide
      */
     @SystemApi
diff --git a/core/java/android/apphibernation/AppHibernationManager.java b/core/java/android/apphibernation/AppHibernationManager.java
index 132cc40..a36da88 100644
--- a/core/java/android/apphibernation/AppHibernationManager.java
+++ b/core/java/android/apphibernation/AppHibernationManager.java
@@ -24,6 +24,8 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 
+import java.util.List;
+
 /**
  * This class provides an API surface for system apps to manipulate the app hibernation
  * state of a package for the user provided in the context.
@@ -31,7 +33,7 @@
  */
 @SystemApi
 @SystemService(Context.APP_HIBERNATION_SERVICE)
-public final class AppHibernationManager {
+public class AppHibernationManager {
     private static final String TAG = "AppHibernationManager";
     private final Context mContext;
     private final IAppHibernationService mIAppHibernationService;
@@ -111,4 +113,20 @@
             throw e.rethrowFromSystemServer();
         }
     }
+
+    /**
+     * Get the hibernating packages for the user. This is equivalent to the list of packages for
+     * the user that return true for {@link #isHibernatingForUser}.
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(value = android.Manifest.permission.MANAGE_APP_HIBERNATION)
+    public @NonNull List<String> getHibernatingPackagesForUser() {
+        try {
+            return mIAppHibernationService.getHibernatingPackagesForUser(mContext.getUserId());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
 }
diff --git a/core/java/android/apphibernation/IAppHibernationService.aidl b/core/java/android/apphibernation/IAppHibernationService.aidl
index 6a068ee..afdb3fe 100644
--- a/core/java/android/apphibernation/IAppHibernationService.aidl
+++ b/core/java/android/apphibernation/IAppHibernationService.aidl
@@ -25,4 +25,5 @@
     void setHibernatingForUser(String packageName, int userId, boolean isHibernating);
     boolean isHibernatingGlobally(String packageName);
     void setHibernatingGlobally(String packageName, boolean isHibernating);
+    List<String> getHibernatingPackagesForUser(int userId);
 }
\ No newline at end of file
diff --git a/core/java/android/appwidget/AppWidgetHostView.java b/core/java/android/appwidget/AppWidgetHostView.java
index a6b4b47..82da4fb 100644
--- a/core/java/android/appwidget/AppWidgetHostView.java
+++ b/core/java/android/appwidget/AppWidgetHostView.java
@@ -841,8 +841,8 @@
      * Calling this method will trigger a full re-inflation of the App Widget.
      *
      * The color resources that can be overloaded are the ones whose name is prefixed with
-     * {@code system_primary_}, {@code system_secondary_} or {@code system_neutral_}, for example
-     * {@link android.R.color#system_primary_500}.
+     * {@code system_neutral} or {@code system_accent}, for example
+     * {@link android.R.color#system_neutral1_500}.
      */
     public void setColorResources(@NonNull SparseIntArray colorMapping) {
         mColorResources = RemoteViews.ColorResources.create(mContext, colorMapping);
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 8d41572..0be7b73 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -52,6 +52,8 @@
 import android.util.Log;
 import android.util.Pair;
 
+import com.android.internal.util.Preconditions;
+
 import java.io.IOException;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -743,7 +745,6 @@
      * Use {@link #getDefaultAdapter} to get the BluetoothAdapter instance.
      */
     BluetoothAdapter(IBluetoothManager managerService) {
-
         if (managerService == null) {
             throw new IllegalArgumentException("bluetooth manager service is null");
         }
@@ -3152,6 +3153,25 @@
         return true;
     }
 
+    /**
+     * Determines whether a String Bluetooth address, such as "00:43:A8:23:10:F0"
+     * is a RANDOM STATIC address.
+     *
+     * RANDOM STATIC: (addr & 0b11) == 0b11
+     * RANDOM RESOLVABLE: (addr & 0b11) == 0b10
+     * RANDOM non-RESOLVABLE: (addr & 0b11) == 0b00
+     *
+     * @param address Bluetooth address as string
+     * @return true if the 2 Least Significant Bits of the address equals 0b11.
+     *
+     * @hide
+     */
+    public static boolean isAddressRandomStatic(@NonNull String address) {
+        Preconditions.checkNotNull(address);
+        return checkBluetoothAddress(address)
+                && (Integer.parseInt(address.split(":")[5], 16) & 0b11) == 0b11;
+    }
+
     @UnsupportedAppUsage
     /*package*/ IBluetoothManager getBluetoothManager() {
         return mManagerService;
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index 07dbdce..a96c14f 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -26,6 +26,7 @@
 import android.annotation.SuppressLint;
 import android.annotation.SystemApi;
 import android.app.PropertyInvalidatedCache;
+import android.companion.AssociationRequest;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.os.Build;
@@ -1022,6 +1023,24 @@
     public static final String EXTRA_MAS_INSTANCE =
             "android.bluetooth.device.extra.MAS_INSTANCE";
 
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(
+        prefix = { "ADDRESS_TYPE_" },
+        value = {
+            /** Hardware MAC Address */
+            ADDRESS_TYPE_PUBLIC,
+            /** Address is either resolvable, non-resolvable or static.*/
+            ADDRESS_TYPE_RANDOM,
+        }
+    )
+    public @interface AddressType {}
+
+    /** Hardware MAC Address of the device */
+    public static final int ADDRESS_TYPE_PUBLIC = 0;
+    /** Address is either resolvable, non-resolvable or static. */
+    public static final int ADDRESS_TYPE_RANDOM = 1;
+
     /**
      * Lazy initialization. Guaranteed final after first object constructed, or
      * getService() called.
@@ -1030,6 +1049,7 @@
     private static volatile IBluetooth sService;
 
     private final String mAddress;
+    @AddressType private final int mAddressType;
 
     /*package*/
     @UnsupportedAppUsage
@@ -1084,6 +1104,7 @@
         }
 
         mAddress = address;
+        mAddressType = ADDRESS_TYPE_PUBLIC;
     }
 
     @Override
@@ -1211,8 +1232,7 @@
     }
 
     /**
-     * Get the Bluetooth alias of the remote device.
-     * <p>Alias is the locally modified name of a remote device.
+     * Get the locally modifiable name (alias) of the remote Bluetooth device.
      *
      * @return the Bluetooth alias, the friendly device name if no alias, or
      * null if there was a problem
@@ -1238,25 +1258,35 @@
     }
 
     /**
-     * Set the Bluetooth alias of the remote device.
-     * <p>Alias is the locally modified name of a remote device.
-     * <p>This methoid overwrites the alias. The changed
-     * alias is saved in the local storage so that the change
-     * is preserved over power cycle.
+     * Sets the locally modifiable name (alias) of the remote Bluetooth device. This method
+     * overwrites the previously stored alias. The new alias is saved in local
+     * storage so that the change is preserved over power cycles.
      *
-     * @return true on success, false on error
-     * @hide
+     * <p>This method requires the calling app to be associated with Companion Device Manager (see
+     * {@link android.companion.CompanionDeviceManager#associate(AssociationRequest,
+     * android.companion.CompanionDeviceManager.Callback, Handler)}) and have the {@link
+     * android.Manifest.permission#BLUETOOTH} permission. Alternatively, if the caller has the
+     * {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED} permission, they can bypass the
+     * Companion Device Manager association requirement.
+     *
+     * @param alias is the new locally modifiable name for the remote Bluetooth device which must be
+     *              non-null and not the empty string.
+     * @return {@code true} if the alias is successfully set, {@code false} on error
+     * @throws IllegalArgumentException if the alias is {@code null} or the empty string
      */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     @RequiresPermission(Manifest.permission.BLUETOOTH)
     public boolean setAlias(@NonNull String alias) {
+        if (alias == null || alias.isEmpty()) {
+            throw new IllegalArgumentException("Cannot set the alias to null or the empty string");
+        }
         final IBluetooth service = sService;
         if (service == null) {
             Log.e(TAG, "BT not enabled. Cannot set Remote Device name");
             return false;
         }
         try {
-            return service.setRemoteAlias(this, alias);
+            BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+            return service.setRemoteAlias(this, alias, adapter.getOpPackageName());
         } catch (RemoteException e) {
             Log.e(TAG, "", e);
         }
diff --git a/core/java/android/bluetooth/BluetoothHeadset.java b/core/java/android/bluetooth/BluetoothHeadset.java
index 4fb5577..632572d 100644
--- a/core/java/android/bluetooth/BluetoothHeadset.java
+++ b/core/java/android/bluetooth/BluetoothHeadset.java
@@ -567,6 +567,7 @@
      * @return true if priority is set, false on error
      * @hide
      * @deprecated Replaced with {@link #setConnectionPolicy(BluetoothDevice, int)}
+     * @removed
      */
     @Deprecated
     @SystemApi
diff --git a/core/java/android/bluetooth/le/ScanFilter.java b/core/java/android/bluetooth/le/ScanFilter.java
index 51f63f7..27c579b 100644
--- a/core/java/android/bluetooth/le/ScanFilter.java
+++ b/core/java/android/bluetooth/le/ScanFilter.java
@@ -16,15 +16,19 @@
 
 package android.bluetooth.le;
 
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.SystemApi;
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothDevice.AddressType;
 import android.os.Parcel;
 import android.os.ParcelUuid;
 import android.os.Parcelable;
 
 import com.android.internal.util.BitUtils;
+import com.android.internal.util.Preconditions;
 
 import java.util.Arrays;
 import java.util.List;
@@ -53,6 +57,11 @@
     @Nullable
     private final String mDeviceAddress;
 
+    private final @AddressType int mAddressType;
+
+    @Nullable
+    private final byte[] mIrk;
+
     @Nullable
     private final ParcelUuid mServiceUuid;
     @Nullable
@@ -79,12 +88,12 @@
     /** @hide */
     public static final ScanFilter EMPTY = new ScanFilter.Builder().build();
 
-
     private ScanFilter(String name, String deviceAddress, ParcelUuid uuid,
             ParcelUuid uuidMask, ParcelUuid solicitationUuid,
             ParcelUuid solicitationUuidMask, ParcelUuid serviceDataUuid,
             byte[] serviceData, byte[] serviceDataMask,
-            int manufacturerId, byte[] manufacturerData, byte[] manufacturerDataMask) {
+            int manufacturerId, byte[] manufacturerData, byte[] manufacturerDataMask,
+            @AddressType int addressType, @Nullable byte[] irk) {
         mDeviceName = name;
         mServiceUuid = uuid;
         mServiceUuidMask = uuidMask;
@@ -97,6 +106,8 @@
         mManufacturerId = manufacturerId;
         mManufacturerData = manufacturerData;
         mManufacturerDataMask = manufacturerDataMask;
+        mAddressType = addressType;
+        mIrk = irk;
     }
 
     @Override
@@ -280,6 +291,23 @@
         return mDeviceAddress;
     }
 
+    /**
+     * @hide
+     */
+    @SystemApi
+    public @AddressType int getAddressType() {
+        return mAddressType;
+    }
+
+    /**
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public byte[] getIrk() {
+        return mIrk;
+    }
+
     @Nullable
     public byte[] getServiceData() {
         return mServiceData;
@@ -516,8 +544,16 @@
      */
     public static final class Builder {
 
+        /**
+         * @hide
+         */
+        @SystemApi
+        public static final int LEN_IRK_OCTETS = 16;
+
         private String mDeviceName;
         private String mDeviceAddress;
+        private @AddressType int mAddressType = BluetoothDevice.ADDRESS_TYPE_PUBLIC;
+        private byte[] mIrk;
 
         private ParcelUuid mServiceUuid;
         private ParcelUuid mUuidMask;
@@ -546,14 +582,130 @@
          *
          * @param deviceAddress The device Bluetooth address for the filter. It needs to be in the
          * format of "01:02:03:AB:CD:EF". The device address can be validated using {@link
-         * BluetoothAdapter#checkBluetoothAddress}.
+         * BluetoothAdapter#checkBluetoothAddress}.  The @AddressType is defaulted to {@link
+         * BluetoothDevice#ADDRESS_TYPE_PUBLIC}
          * @throws IllegalArgumentException If the {@code deviceAddress} is invalid.
          */
         public Builder setDeviceAddress(String deviceAddress) {
-            if (deviceAddress != null && !BluetoothAdapter.checkBluetoothAddress(deviceAddress)) {
+            return setDeviceAddress(deviceAddress, BluetoothDevice.ADDRESS_TYPE_PUBLIC);
+        }
+
+        /**
+         * Set filter on Address with AddressType
+         *
+         * <p>This key is used to resolve a private address from a public address.
+         *
+         * @param deviceAddress The device Bluetooth address for the filter. It needs to be in the
+         * format of "01:02:03:AB:CD:EF". The device address can be validated using {@link
+         * BluetoothAdapter#checkBluetoothAddress}. May be any type of address.
+         * @param addressType indication of the type of address
+         * e.g. {@link BluetoothDevice#ADDRESS_TYPE_PUBLIC}
+         * or {@link BluetoothDevice#ADDRESS_TYPE_RANDOM}
+         *
+         * @throws IllegalArgumentException If the {@code deviceAddress} is invalid.
+         * @throws IllegalArgumentException If the {@code addressType} is invalid length
+         * @throws NullPointerException if {@code deviceAddress} is null.
+         *
+         * @hide
+         */
+        @NonNull
+        @SystemApi
+        public Builder setDeviceAddress(@NonNull String deviceAddress,
+                                        @AddressType int addressType) {
+            return setDeviceAddressInternal(deviceAddress, addressType, null);
+        }
+
+        /**
+         * Set filter on Address with AddressType and the Identity Resolving Key (IRK).
+         *
+         * <p>The IRK is used to resolve a {@link BluetoothDevice#ADDRESS_TYPE_PUBLIC} from
+         * a PRIVATE_ADDRESS type.
+         *
+         * @param deviceAddress The device Bluetooth address for the filter. It needs to be in the
+         * format of "01:02:03:AB:CD:EF". The device address can be validated using {@link
+         * BluetoothAdapter#checkBluetoothAddress}.  This Address type must only be PUBLIC OR RANDOM
+         * STATIC.
+         * @param addressType indication of the type of address
+         * e.g. {@link BluetoothDevice#ADDRESS_TYPE_PUBLIC}
+         * or {@link BluetoothDevice#ADDRESS_TYPE_RANDOM}
+         * @param irk non-null byte array representing the Identity Resolving Key
+         *
+         * @throws IllegalArgumentException If the {@code deviceAddress} is invalid.
+         * @throws IllegalArgumentException if the {@code irk} is invalid length.
+         * @throws IllegalArgumentException If the {@code addressType} is invalid length or is not
+         * PUBLIC or RANDOM STATIC when an IRK is present.
+         * @throws NullPointerException if {@code deviceAddress} or {@code irk} is null.
+         *
+         * @hide
+         */
+        @NonNull
+        @SystemApi
+        public Builder setDeviceAddress(@NonNull String deviceAddress,
+                                        @AddressType int addressType,
+                                        @NonNull byte[] irk) {
+            Preconditions.checkNotNull(irk);
+            if (irk.length != LEN_IRK_OCTETS) {
+                throw new IllegalArgumentException("'irk' is invalid length!");
+            }
+            return setDeviceAddressInternal(deviceAddress, addressType, irk);
+        }
+
+        /**
+         * Set filter on Address with AddressType and the Identity Resolving Key (IRK).
+         *
+         * <p>Internal setter for the device address
+         *
+         * @param deviceAddress The device Bluetooth address for the filter. It needs to be in the
+         * format of "01:02:03:AB:CD:EF". The device address can be validated using {@link
+         * BluetoothAdapter#checkBluetoothAddress}.
+         * @param addressType indication of the type of address
+         * e.g. {@link BluetoothDevice#ADDRESS_TYPE_PUBLIC}
+         * @param irk non-null byte array representing the Identity Resolving Address; nullable
+         * internally.
+         *
+         * @throws IllegalArgumentException If the {@code deviceAddress} is invalid.
+         * @throws IllegalArgumentException If the {@code addressType} is invalid length.
+         * @throws NullPointerException if {@code deviceAddress} is null.
+         *
+         * @hide
+         */
+        @NonNull
+        private Builder setDeviceAddressInternal(@NonNull String deviceAddress,
+                                                 @AddressType int addressType,
+                                                 @Nullable byte[] irk) {
+
+            // Make sure our deviceAddress is valid!
+            Preconditions.checkNotNull(deviceAddress);
+            if (!BluetoothAdapter.checkBluetoothAddress(deviceAddress)) {
                 throw new IllegalArgumentException("invalid device address " + deviceAddress);
             }
+
+            // Verify type range
+            if (addressType < BluetoothDevice.ADDRESS_TYPE_PUBLIC
+                || addressType > BluetoothDevice.ADDRESS_TYPE_RANDOM) {
+                throw new IllegalArgumentException("'addressType' is invalid!");
+            }
+
+            // IRK can only be used for a PUBLIC or RANDOM (STATIC) Address.
+            if (addressType == BluetoothDevice.ADDRESS_TYPE_RANDOM) {
+                // Don't want a bad combination of address and irk!
+                if (irk != null) {
+                    // Since there are 3 possible RANDOM subtypes we must check to make sure
+                    // the correct type of address is used.
+                    if (!BluetoothAdapter.isAddressRandomStatic(deviceAddress)) {
+                        throw new IllegalArgumentException(
+                                "Invalid combination: IRK requires either a PUBLIC or "
+                                + "RANDOM (STATIC) Address");
+                    }
+                }
+            }
+
+            // PUBLIC doesn't require extra work
+            // Without an IRK any address may be accepted
+
             mDeviceAddress = deviceAddress;
+            mAddressType = addressType;
+            mIrk = irk;
             return this;
         }
 
@@ -727,7 +879,8 @@
                     mServiceUuid, mUuidMask, mServiceSolicitationUuid,
                     mServiceSolicitationUuidMask,
                     mServiceDataUuid, mServiceData, mServiceDataMask,
-                    mManufacturerId, mManufacturerData, mManufacturerDataMask);
+                    mManufacturerId, mManufacturerData, mManufacturerDataMask,
+                    mAddressType, mIrk);
         }
     }
 }
diff --git a/core/java/android/bluetooth/le/ScanSettings.java b/core/java/android/bluetooth/le/ScanSettings.java
index 504118e..368d1ee 100644
--- a/core/java/android/bluetooth/le/ScanSettings.java
+++ b/core/java/android/bluetooth/le/ScanSettings.java
@@ -52,6 +52,16 @@
     public static final int SCAN_MODE_LOW_LATENCY = 2;
 
     /**
+     * Perform Bluetooth LE scan in ambient discovery mode. This mode has lower duty cycle and more
+     * aggressive scan interval than balanced mode that provides a good trade-off between scan
+     * latency and power consumption.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final int SCAN_MODE_AMBIENT_DISCOVERY = 3;
+
+    /**
      * Trigger a callback for every Bluetooth advertisement found that matches the filter criteria.
      * If no filter is active, all advertisement packets are reported.
      */
@@ -276,10 +286,17 @@
          * @throws IllegalArgumentException If the {@code scanMode} is invalid.
          */
         public Builder setScanMode(int scanMode) {
-            if (scanMode < SCAN_MODE_OPPORTUNISTIC || scanMode > SCAN_MODE_LOW_LATENCY) {
-                throw new IllegalArgumentException("invalid scan mode " + scanMode);
+            switch (scanMode) {
+                case SCAN_MODE_OPPORTUNISTIC:
+                case SCAN_MODE_LOW_POWER:
+                case SCAN_MODE_BALANCED:
+                case SCAN_MODE_LOW_LATENCY:
+                case SCAN_MODE_AMBIENT_DISCOVERY:
+                    mScanMode = scanMode;
+                    break;
+                default:
+                    throw new IllegalArgumentException("invalid scan mode " + scanMode);
             }
-            mScanMode = scanMode;
             return this;
         }
 
diff --git a/core/java/android/companion/CompanionDeviceManager.java b/core/java/android/companion/CompanionDeviceManager.java
index b441b36..2ce7156 100644
--- a/core/java/android/companion/CompanionDeviceManager.java
+++ b/core/java/android/companion/CompanionDeviceManager.java
@@ -25,6 +25,7 @@
 import android.app.Activity;
 import android.app.Application;
 import android.app.PendingIntent;
+import android.bluetooth.BluetoothDevice;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.IntentSender;
@@ -331,6 +332,33 @@
     }
 
     /**
+     * Checks whether the bluetooth device represented by the mac address was recently associated
+     * with the companion app. This allows these devices to skip the Bluetooth pairing dialog if
+     * their pairing variant is {@link BluetoothDevice#PAIRING_VARIANT_CONSENT}.
+     *
+     * @param packageName the package name of the calling app
+     * @param deviceMacAddress the bluetooth device's mac address
+     * @param userId the calling user's identifier
+     * @return true if it was recently associated and we can bypass the dialog, false otherwise
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MANAGE_COMPANION_DEVICES)
+    public boolean canPairWithoutPrompt(@NonNull String packageName,
+            @NonNull String deviceMacAddress, int userId) {
+        if (!checkFeaturePresent()) {
+            return false;
+        }
+        Objects.requireNonNull(packageName, "package name cannot be null");
+        Objects.requireNonNull(deviceMacAddress, "device mac address cannot be null");
+        try {
+            return mService.canPairWithoutPrompt(packageName, deviceMacAddress, userId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Register to receive callbacks whenever the associated device comes in and out of range.
      *
      * The provided device must be {@link #associate associated} with the calling app before
@@ -397,6 +425,32 @@
                     mContext.getPackageName(), deviceAddress);
         } catch (RemoteException e) {
             ExceptionUtils.propagateIfInstanceOf(e.getCause(), DeviceNotAssociatedException.class);
+        }
+    }
+
+    /**
+     * Associates given device with given app for the given user directly, without UI prompt.
+     *
+     * @return whether successful
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.ASSOCIATE_COMPANION_DEVICES)
+    public boolean associate(
+            @NonNull String packageName,
+            @NonNull MacAddress macAddress) {
+        if (!checkFeaturePresent()) {
+            return false;
+        }
+        Objects.requireNonNull(packageName, "package name cannot be null");
+        Objects.requireNonNull(macAddress, "mac address cannot be null");
+
+        UserHandle user = android.os.Process.myUserHandle();
+        try {
+            return mService.createAssociation(
+                    packageName, macAddress.toString(), user.getIdentifier());
+        } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
     }
diff --git a/core/java/android/companion/ICompanionDeviceManager.aidl b/core/java/android/companion/ICompanionDeviceManager.aidl
index 95d3515..83db358 100644
--- a/core/java/android/companion/ICompanionDeviceManager.aidl
+++ b/core/java/android/companion/ICompanionDeviceManager.aidl
@@ -51,4 +51,6 @@
     void unregisterDevicePresenceListenerService(in String packageName, in String deviceAddress);
 
     boolean canPairWithoutPrompt(in String packageName, in String deviceMacAddress, int userId);
+
+    boolean createAssociation(in String packageName, in String macAddress, int userId);
 }
diff --git a/services/core/java/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneIdValidator.java b/core/java/android/content/AttributionSource.aidl
similarity index 61%
copy from services/core/java/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneIdValidator.java
copy to core/java/android/content/AttributionSource.aidl
index cab5ad2..10d5c27 100644
--- a/services/core/java/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneIdValidator.java
+++ b/core/java/android/content/AttributionSource.aidl
@@ -14,17 +14,6 @@
  * limitations under the License.
  */
 
-package com.android.server.timezonedetector.location;
+package android.content;
 
-import android.annotation.NonNull;
-
-import com.android.i18n.timezone.ZoneInfoDb;
-
-class ZoneInfoDbTimeZoneIdValidator implements
-        LocationTimeZoneProvider.TimeZoneIdValidator {
-
-    @Override
-    public boolean isValid(@NonNull String timeZoneId) {
-        return ZoneInfoDb.getInstance().hasTimeZone(timeZoneId);
-    }
-}
+parcelable AttributionSource;
diff --git a/core/java/android/content/AttributionSource.java b/core/java/android/content/AttributionSource.java
new file mode 100644
index 0000000..053bfc1
--- /dev/null
+++ b/core/java/android/content/AttributionSource.java
@@ -0,0 +1,612 @@
+/*
+ * 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 android.content;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
+import android.app.AppGlobals;
+import android.os.Binder;
+import android.os.Build;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.permission.PermissionManager;
+import android.util.ArraySet;
+
+import com.android.internal.annotations.Immutable;
+import com.android.internal.util.CollectionUtils;
+import com.android.internal.util.DataClass;
+import com.android.internal.util.Parcelling;
+
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * This class represents a source to which access to permission protected data should be
+ * attributed. Attribution sources can be chained to represent cases where the protected
+ * data would flow through several applications. For example, app A may ask app B for
+ * contacts and in turn app B may ask app C for contacts. In this case, the attribution
+ * chain would be A -> B -> C and the data flow would be C -> B -> A. There are two
+ * main benefits of using the attribution source mechanism: avoid doing explicit permission
+ * checks on behalf of the calling app if you are accessing private data on their behalf
+ * to send back; avoid double data access blaming which happens as you check the calling
+ * app's permissions and when you access the data behind these permissions (for runtime
+ * permissions). Also if not explicitly blaming the caller the data access would be
+ * counted towards your app vs to the previous app where yours was just a proxy.
+ * <p>
+ * Every {@link Context} has an attribution source and you can get it via {@link
+ * Context#getAttributionSource()} representing itself, which is a chain of one. You
+ * can attribute work to another app, or more precisely to a chain of apps, through
+ * which the data you would be accessing would flow, via {@link Context#createContext(
+ * ContextParams)} plus specifying an attribution source for the next app to receive
+ * the protected data you are accessing via {@link AttributionSource.Builder#setNext(
+ * AttributionSource)}. Creating this attribution chain ensures that the datasource would
+ * check whether every app in the attribution chain has permission to access the data
+ * before releasing it. The datasource will also record appropriately that this data was
+ * accessed by the apps in the sequence if the data is behind a sensitive permission
+ * (e.g. dangerous). Again, this is useful if you are accessing the data on behalf of another
+ * app, for example a speech recognizer using the mic so it can provide recognition to
+ * a calling app.
+ * <p>
+ * You can create an attribution chain of you and any other app without any verification
+ * as this is something already available via the {@link android.app.AppOpsManager} APIs.
+ * This is supported to handle cases where you don't have access to the caller's attribution
+ * source and you can directly use the {@link AttributionSource.Builder} APIs. However,
+ * if the data flows through more than two apps (more than you access the data for the
+ * caller - which you cannot know ahead of time) you need to have a handle to the {@link
+ * AttributionSource} for the calling app's context in order to create an attribution context.
+ * This means you either need to have an API for the other app to send you its attribution
+ * source or use a platform API that pipes the callers attribution source.
+ * <p>
+ * You cannot forge an attribution chain without the participation of every app in the
+ * attribution chain (aside of the special case mentioned above). To create an attribution
+ * source that is trusted you need to create an attribution context that points to an
+ * attribution source that was explicitly created by the app that it refers to, recursively.
+ * <p>
+ * Since creating an attribution context leads to all permissions for apps in the attribution
+ * chain being checked, you need to expect getting a security exception when accessing
+ * permission protected APIs since some app in the chain may not have the permission.
+ */
+@Immutable
+// TODO: Codegen doesn't properly verify the class if the parcelling is inner class
+// TODO: Codegen doesn't allow overriding the constructor to change its visibility
+// TODO: Codegen applies method level annotations to argument vs the generated member (@SystemApi)
+// TODO: Codegen doesn't properly read/write IBinder members
+// TODO: Codegen doesn't properly handle Set arguments
+// @DataClass(genEqualsHashCode = true, genConstructor = false, genBuilder = true)
+public final class AttributionSource implements Parcelable {
+    /**
+     * @hide
+     */
+    static class RenouncedPermissionsParcelling implements Parcelling<Set<String>> {
+
+        @Override
+        public void parcel(Set<String> item, Parcel dest, int parcelFlags) {
+            if (item == null) {
+                dest.writeInt(-1);
+            } else {
+                dest.writeInt(item.size());
+                for (String permission : item) {
+                    dest.writeString8(permission);
+                }
+            }
+        }
+
+        @Override
+        public Set<String> unparcel(Parcel source) {
+            final int size = source.readInt();
+            if (size < 0) {
+                return null;
+            }
+            final ArraySet<String> result = new ArraySet<>(size);
+            for (int i = 0; i < size; i++) {
+                result.add(source.readString8());
+            }
+            return result;
+        }
+    }
+
+    /**
+     * The UID that is accessing the permission protected data.
+     */
+    private final int mUid;
+
+    /**
+     * The package that is accessing the permission protected data.
+     */
+    private @Nullable String mPackageName = null;
+
+    /**
+     * The attribution tag of the app accessing the permission protected data.
+     */
+    private @Nullable String mAttributionTag = null;
+
+    /**
+     * Unique token for that source.
+     *
+     * @hide
+     */
+    private @Nullable IBinder mToken = null;
+
+    /**
+     * Permissions that should be considered revoked regardless if granted.
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.RENOUNCE_PERMISSIONS)
+    @DataClass.ParcelWith(RenouncedPermissionsParcelling.class)
+    private @Nullable Set<String> mRenouncedPermissions = null;
+
+    /**
+     * The next app to receive the permission protected data.
+     */
+    private @Nullable AttributionSource mNext = null;
+
+    /** @hide */
+    @TestApi
+    public AttributionSource(int uid, @Nullable String packageName,
+            @Nullable String attributionTag) {
+        this(uid, packageName, attributionTag, /*next*/ null);
+    }
+
+    /** @hide */
+    @TestApi
+    public AttributionSource(int uid, @Nullable String packageName,
+            @Nullable String attributionTag, @Nullable AttributionSource next) {
+        this(uid, packageName, attributionTag, /*token*/ null,
+                /*renouncedPermissions*/ null, next);
+    }
+
+    /** @hide */
+    public AttributionSource(@NonNull AttributionSource current,
+            @Nullable AttributionSource next) {
+        this(current.getUid(), current.getPackageName(), current.getAttributionTag(),
+                /*token*/ null, /*renouncedPermissions*/ null, next);
+    }
+
+    /** @hide */
+    public AttributionSource withNextAttributionSource(@Nullable AttributionSource next) {
+        return new AttributionSource(mUid, mPackageName, mAttributionTag,  mToken,
+                mRenouncedPermissions, next);
+    }
+
+    /** @hide */
+    public AttributionSource withToken(@Nullable IBinder token) {
+        return new AttributionSource(mUid, mPackageName, mAttributionTag, token,
+                mRenouncedPermissions, mNext);
+    }
+
+    /**
+     * If you are handling an IPC and you don't trust the caller you need to validate
+     * whether the attribution source is one for the calling app to prevent the caller
+     * to pass you a source from another app without including themselves in the
+     * attribution chain.
+     *
+     * @throws SecurityException if the attribution source cannot be trusted to be
+     * from the caller.
+     */
+    public void enforceCallingUid() {
+        final int callingUid = Binder.getCallingUid();
+        if (callingUid != Process.SYSTEM_UID && callingUid != mUid) {
+            throw new SecurityException("Calling uid: " + callingUid
+                    + " doesn't match source uid: " + mUid);
+        }
+        // No need to check package as app ops manager does it already.
+    }
+
+    /**
+     * If you are handling an IPC and you don't trust the caller you need to validate
+     * whether the attribution source is one for the calling app to prevent the caller
+     * to pass you a source from another app without including themselves in the
+     * attribution chain.
+     *f
+     * @return if the attribution source cannot be trusted to be from the caller.
+     */
+    public boolean checkCallingUid() {
+        final int callingUid = Binder.getCallingUid();
+        if (callingUid != Process.SYSTEM_UID && callingUid != mUid) {
+            return false;
+        }
+        // No need to check package as app ops manager does it already.
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        if (Build.IS_DEBUGGABLE) {
+            return "AttributionSource { " +
+                    "uid = " + mUid + ", " +
+                    "packageName = " + mPackageName + ", " +
+                    "attributionTag = " + mAttributionTag + ", " +
+                    "token = " + mToken + ", " +
+                    "next = " + mNext +
+                    " }";
+        }
+        return super.toString();
+    }
+
+    /**
+     * @return The next UID that would receive the permission protected data.
+     *
+     * @hide
+     */
+    public int getNextUid() {
+        if (mNext != null) {
+            return mNext.getUid();
+        }
+        return Process.INVALID_UID;
+    }
+
+    /**
+     * @return The next package that would receive the permission protected data.
+     *
+     * @hide
+     */
+    public @Nullable String getNextPackageName() {
+        if (mNext != null) {
+            return mNext.getPackageName();
+        }
+        return null;
+    }
+
+    /**
+     * @return The nexxt package's attribution tag that would receive
+     * the permission protected data.
+     *
+     * @hide
+     */
+    public @Nullable String getNextAttributionTag() {
+        if (mNext != null) {
+            return mNext.getAttributionTag();
+        }
+        return null;
+    }
+
+    /**
+     * Checks whether this attribution source can be trusted. That is whether
+     * the app it refers to created it and provided to the attribution chain.
+     *
+     * @param context Context handle.
+     * @return Whether this is a trusted source.
+     */
+    public boolean isTrusted(@NonNull Context context) {
+        return mToken != null && context.getSystemService(PermissionManager.class)
+                .isRegisteredAttributionSource(this);
+    }
+
+    /**
+     * Permissions that should be considered revoked regardless if granted.
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.RENOUNCE_PERMISSIONS)
+    @NonNull
+    public Set<String> getRenouncedPermissions() {
+        return CollectionUtils.emptyIfNull(mRenouncedPermissions);
+    }
+
+    @DataClass.Suppress({"setUid", "setToken"})
+    static class BaseBuilder {}
+
+
+
+
+
+
+    // Code below generated by codegen v1.0.22.
+    //
+    // DO NOT MODIFY!
+    // CHECKSTYLE:OFF Generated code
+    //
+    // To regenerate run:
+    // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/content/AttributionSource.java
+    //
+    // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
+    //   Settings > Editor > Code Style > Formatter Control
+    //@formatter:off
+
+
+    /* package-private */ AttributionSource(
+            int uid,
+            @Nullable String packageName,
+            @Nullable String attributionTag,
+            @Nullable IBinder token,
+            @RequiresPermission(android.Manifest.permission.RENOUNCE_PERMISSIONS) @Nullable Set<String> renouncedPermissions,
+            @Nullable AttributionSource next) {
+        this.mUid = uid;
+        this.mPackageName = packageName;
+        this.mAttributionTag = attributionTag;
+        this.mToken = token;
+        this.mRenouncedPermissions = renouncedPermissions;
+        com.android.internal.util.AnnotationValidations.validate(
+                SystemApi.class, null, mRenouncedPermissions);
+        com.android.internal.util.AnnotationValidations.validate(
+                RequiresPermission.class, null, mRenouncedPermissions,
+                "value", android.Manifest.permission.RENOUNCE_PERMISSIONS);
+        this.mNext = next;
+
+        // onConstructed(); // You can define this method to get a callback
+    }
+
+    /**
+     * The UID that is accessing the permission protected data.
+     */
+    public int getUid() {
+        return mUid;
+    }
+
+    /**
+     * The package that is accessing the permission protected data.
+     */
+    public @Nullable String getPackageName() {
+        return mPackageName;
+    }
+
+    /**
+     * The attribution tag of the app accessing the permission protected data.
+     */
+    public @Nullable String getAttributionTag() {
+        return mAttributionTag;
+    }
+
+    /**
+     * Unique token for that source.
+     *
+     * @hide
+     */
+    public @Nullable IBinder getToken() {
+        return mToken;
+    }
+
+    /**
+     * The next app to receive the permission protected data.
+     */
+    public @Nullable AttributionSource getNext() {
+        return mNext;
+    }
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        // You can override field equality logic by defining either of the methods like:
+        // boolean fieldNameEquals(AttributionSource other) { ... }
+        // boolean fieldNameEquals(FieldType otherValue) { ... }
+
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        @SuppressWarnings("unchecked")
+        AttributionSource that = (AttributionSource) o;
+        //noinspection PointlessBooleanExpression
+        return true
+                && mUid == that.mUid
+                && Objects.equals(mPackageName, that.mPackageName)
+                && Objects.equals(mAttributionTag, that.mAttributionTag)
+                && Objects.equals(mToken, that.mToken)
+                && Objects.equals(mRenouncedPermissions, that.mRenouncedPermissions)
+                && Objects.equals(mNext, that.mNext);
+    }
+
+    @Override
+    public int hashCode() {
+        // You can override field hashCode logic by defining methods like:
+        // int fieldNameHashCode() { ... }
+
+        int _hash = 1;
+        _hash = 31 * _hash + mUid;
+        _hash = 31 * _hash + Objects.hashCode(mPackageName);
+        _hash = 31 * _hash + Objects.hashCode(mAttributionTag);
+        _hash = 31 * _hash + Objects.hashCode(mToken);
+        _hash = 31 * _hash + Objects.hashCode(mRenouncedPermissions);
+        _hash = 31 * _hash + Objects.hashCode(mNext);
+        return _hash;
+    }
+
+    static Parcelling<Set<String>> sParcellingForRenouncedPermissions =
+            Parcelling.Cache.get(
+                    RenouncedPermissionsParcelling.class);
+    static {
+        if (sParcellingForRenouncedPermissions == null) {
+            sParcellingForRenouncedPermissions = Parcelling.Cache.put(
+                    new RenouncedPermissionsParcelling());
+        }
+    }
+
+    @Override
+    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 (mPackageName != null) flg |= 0x2;
+        if (mAttributionTag != null) flg |= 0x4;
+        if (mToken != null) flg |= 0x8;
+        if (mRenouncedPermissions != null) flg |= 0x10;
+        if (mNext != null) flg |= 0x20;
+        dest.writeByte(flg);
+        dest.writeInt(mUid);
+        if (mPackageName != null) dest.writeString(mPackageName);
+        if (mAttributionTag != null) dest.writeString(mAttributionTag);
+        if (mToken != null) dest.writeStrongBinder(mToken);
+        sParcellingForRenouncedPermissions.parcel(mRenouncedPermissions, dest, flags);
+        if (mNext != null) dest.writeTypedObject(mNext, flags);
+    }
+
+    @Override
+    public int describeContents() { return 0; }
+
+    /** @hide */
+    @SuppressWarnings({"unchecked", "RedundantCast"})
+    /* package-private */ AttributionSource(@NonNull Parcel in) {
+        // You can override field unparcelling by defining methods like:
+        // static FieldType unparcelFieldName(Parcel in) { ... }
+
+        byte flg = in.readByte();
+        int uid = in.readInt();
+        String packageName = (flg & 0x2) == 0 ? null : in.readString();
+        String attributionTag = (flg & 0x4) == 0 ? null : in.readString();
+        IBinder token = (flg & 0x8) == 0 ? null : in.readStrongBinder();
+        Set<String> renouncedPermissions = sParcellingForRenouncedPermissions.unparcel(in);
+        AttributionSource next = (flg & 0x20) == 0 ? null : (AttributionSource) in.readTypedObject(AttributionSource.CREATOR);
+
+        this.mUid = uid;
+        this.mPackageName = packageName;
+        this.mAttributionTag = attributionTag;
+        this.mToken = token;
+        this.mRenouncedPermissions = renouncedPermissions;
+        com.android.internal.util.AnnotationValidations.validate(
+                SystemApi.class, null, mRenouncedPermissions);
+        com.android.internal.util.AnnotationValidations.validate(
+                RequiresPermission.class, null, mRenouncedPermissions,
+                "value", android.Manifest.permission.RENOUNCE_PERMISSIONS);
+        this.mNext = next;
+
+        // onConstructed(); // You can define this method to get a callback
+    }
+
+    public static final @NonNull Parcelable.Creator<AttributionSource> CREATOR
+            = new Parcelable.Creator<AttributionSource>() {
+        @Override
+        public AttributionSource[] newArray(int size) {
+            return new AttributionSource[size];
+        }
+
+        @Override
+        public AttributionSource createFromParcel(@NonNull Parcel in) {
+            return new AttributionSource(in);
+        }
+    };
+
+    /**
+     * A builder for {@link AttributionSource}
+     */
+    @SuppressWarnings("WeakerAccess")
+    public static final class Builder extends BaseBuilder {
+
+        private int mUid;
+        private @Nullable String mPackageName;
+        private @Nullable String mAttributionTag;
+        private @Nullable IBinder mToken;
+        private @SystemApi @RequiresPermission(android.Manifest.permission.RENOUNCE_PERMISSIONS) @Nullable Set<String> mRenouncedPermissions;
+        private @Nullable AttributionSource mNext;
+
+        private long mBuilderFieldsSet = 0L;
+
+        /**
+         * Creates a new Builder.
+         *
+         * @param uid
+         *   The UID that is accessing the permission protected data.
+         */
+        public Builder(
+                int uid) {
+            mUid = uid;
+        }
+
+        /**
+         * The package that is accessing the permission protected data.
+         */
+        public @NonNull Builder setPackageName(@NonNull String value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x2;
+            mPackageName = value;
+            return this;
+        }
+
+        /**
+         * The attribution tag of the app accessing the permission protected data.
+         */
+        public @NonNull Builder setAttributionTag(@NonNull String value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x4;
+            mAttributionTag = value;
+            return this;
+        }
+
+        /**
+         * Permissions that should be considered revoked regardless if granted.
+         *
+         * @hide
+         */
+        @SystemApi
+        @RequiresPermission(android.Manifest.permission.RENOUNCE_PERMISSIONS)
+        public @NonNull Builder setRenouncedPermissions(@NonNull Set<String> value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x10;
+            mRenouncedPermissions = value;
+            return this;
+        }
+
+        /**
+         * The next app to receive the permission protected data.
+         */
+        public @NonNull Builder setNext(@NonNull AttributionSource value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x20;
+            mNext = value;
+            return this;
+        }
+
+        /** Builds the instance. This builder should not be touched after calling this! */
+        public @NonNull AttributionSource build() {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x40; // Mark builder used
+
+            if ((mBuilderFieldsSet & 0x2) == 0) {
+                mPackageName = null;
+            }
+            if ((mBuilderFieldsSet & 0x4) == 0) {
+                mAttributionTag = null;
+            }
+            if ((mBuilderFieldsSet & 0x8) == 0) {
+                mToken = null;
+            }
+            if ((mBuilderFieldsSet & 0x10) == 0) {
+                mRenouncedPermissions = null;
+            }
+            if ((mBuilderFieldsSet & 0x20) == 0) {
+                mNext = null;
+            }
+            AttributionSource o = new AttributionSource(
+                    mUid,
+                    mPackageName,
+                    mAttributionTag,
+                    mToken,
+                    mRenouncedPermissions,
+                    mNext);
+            return o;
+        }
+
+        private void checkNotUsed() {
+            if ((mBuilderFieldsSet & 0x40) != 0) {
+                throw new IllegalStateException(
+                        "This Builder should not be reused. Use a new Builder instance instead");
+            }
+        }
+    }
+
+
+    //@formatter:on
+    // End of generated code
+
+}
diff --git a/core/java/android/content/ComponentCallbacksController.java b/core/java/android/content/ComponentCallbacksController.java
new file mode 100644
index 0000000..a81aaf7
--- /dev/null
+++ b/core/java/android/content/ComponentCallbacksController.java
@@ -0,0 +1,127 @@
+/*
+ * 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 android.content;
+
+import android.annotation.NonNull;
+import android.content.res.Configuration;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Consumer;
+
+/**
+ * A helper class to manage {@link ComponentCallbacks} and {@link ComponentCallbacks2}, such as
+ * registering ,unregistering {@link ComponentCallbacks} and sending callbacks to all registered
+ * {@link ComponentCallbacks}.
+ *
+ * @see Context#registerComponentCallbacks(ComponentCallbacks)
+ * @see Context#unregisterComponentCallbacks(ComponentCallbacks)
+ * @see ComponentCallbacks
+ * @see ComponentCallbacks2
+ *
+ * @hide
+ */
+public class ComponentCallbacksController {
+    @GuardedBy("mLock")
+    private List<ComponentCallbacks> mComponentCallbacks;
+
+    private final Object mLock = new Object();
+
+    /**
+     * Register the {@link ComponentCallbacks}.
+     *
+     * @see Context#registerComponentCallbacks(ComponentCallbacks)
+     */
+    public void registerCallbacks(@NonNull ComponentCallbacks callbacks) {
+        synchronized (mLock) {
+            if (mComponentCallbacks == null) {
+                mComponentCallbacks = new ArrayList<>();
+            }
+            mComponentCallbacks.add(callbacks);
+        }
+    }
+
+    /**
+     * Unregister the {@link ComponentCallbacks}.
+     *
+     * @see Context#unregisterComponentCallbacks(ComponentCallbacks)
+     */
+    public void unregisterCallbacks(@NonNull ComponentCallbacks callbacks) {
+        synchronized (mLock) {
+            if (mComponentCallbacks == null || mComponentCallbacks.isEmpty()) {
+                return;
+            }
+            mComponentCallbacks.remove(callbacks);
+        }
+    }
+
+    /**
+     * Clear all registered {@link ComponentCallbacks}.
+     * It is useful when the associated {@link Context} is going to be released.
+     */
+    public void clearCallbacks() {
+        synchronized (mLock) {
+            if (mComponentCallbacks != null) {
+                mComponentCallbacks.clear();
+            }
+        }
+    }
+
+    /**
+     * Sending {@link ComponentCallbacks#onConfigurationChanged(Configuration)} to all registered
+     * {@link ComponentCallbacks}.
+     */
+    public void dispatchConfigurationChanged(@NonNull Configuration newConfig) {
+        forAllComponentCallbacks(callbacks -> callbacks.onConfigurationChanged(newConfig));
+    }
+
+    /**
+     * Sending {@link ComponentCallbacks#onLowMemory()} to all registered
+     * {@link ComponentCallbacks}.
+     */
+    public void dispatchLowMemory() {
+        forAllComponentCallbacks(ComponentCallbacks::onLowMemory);
+    }
+
+    /**
+     * Sending {@link ComponentCallbacks2#onTrimMemory(int)} to all registered
+     * {@link ComponentCallbacks2}.
+     */
+    public void dispatchTrimMemory(int level) {
+        forAllComponentCallbacks(callbacks -> {
+            if (callbacks instanceof ComponentCallbacks2) {
+                ((ComponentCallbacks2) callbacks).onTrimMemory(level);
+            }
+        });
+    }
+
+    private void forAllComponentCallbacks(Consumer<ComponentCallbacks> callbacksConsumer) {
+        final ComponentCallbacks[] callbacksArray;
+        synchronized (mLock) {
+            if (mComponentCallbacks == null || mComponentCallbacks.isEmpty()) {
+                return;
+            }
+            callbacksArray = new ComponentCallbacks[mComponentCallbacks.size()];
+            mComponentCallbacks.toArray(callbacksArray);
+        }
+        for (ComponentCallbacks callbacks : callbacksArray) {
+            callbacksConsumer.accept(callbacks);
+        }
+    }
+}
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index 73b4f62..8284203 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -18,11 +18,6 @@
 
 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
-import static android.app.AppOpsManager.MODE_ALLOWED;
-import static android.app.AppOpsManager.MODE_DEFAULT;
-import static android.app.AppOpsManager.MODE_ERRORED;
-import static android.app.AppOpsManager.MODE_IGNORED;
-import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.os.Trace.TRACE_TAG_DATABASE;
 
 import android.annotation.NonNull;
@@ -45,7 +40,6 @@
 import android.os.Build;
 import android.os.Bundle;
 import android.os.CancellationSignal;
-import android.os.IBinder;
 import android.os.ICancellationSignal;
 import android.os.ParcelFileDescriptor;
 import android.os.ParcelableException;
@@ -57,7 +51,6 @@
 import android.os.storage.StorageManager;
 import android.text.TextUtils;
 import android.util.Log;
-import android.util.Pair;
 
 import com.android.internal.annotations.VisibleForTesting;
 
@@ -141,7 +134,7 @@
     private boolean mNoPerms;
     private boolean mSingleUser;
 
-    private ThreadLocal<Pair<String, String>> mCallingPackage;
+    private ThreadLocal<AttributionSource> mCallingAttributionSource;
 
     private Transport mTransport = new Transport();
 
@@ -231,13 +224,13 @@
         }
 
         @Override
-        public Cursor query(String callingPkg, @Nullable String attributionTag, Uri uri,
+        public Cursor query(@NonNull AttributionSource attributionSource, Uri uri,
                 @Nullable String[] projection, @Nullable Bundle queryArgs,
                 @Nullable ICancellationSignal cancellationSignal) {
             uri = validateIncomingUri(uri);
             uri = maybeGetUriWithoutUserId(uri);
-            if (enforceReadPermission(callingPkg, attributionTag, uri, null)
-                    != AppOpsManager.MODE_ALLOWED) {
+            if (enforceReadPermission(attributionSource, uri)
+                    != PermissionChecker.PERMISSION_GRANTED) {
                 // The caller has no access to the data, so return an empty cursor with
                 // the columns in the requested order. The caller may ask for an invalid
                 // column and we would not catch that but this is not a problem in practice.
@@ -253,8 +246,8 @@
                 // we have to execute the query as if allowed to get a cursor with the
                 // columns. We then use the column names to return an empty cursor.
                 Cursor cursor;
-                final Pair<String, String> original = setCallingPackage(
-                        new Pair<>(callingPkg, attributionTag));
+                final AttributionSource original = setCallingAttributionSource(
+                        attributionSource);
                 try {
                     cursor = mInterface.query(
                             uri, projection, queryArgs,
@@ -262,7 +255,7 @@
                 } catch (RemoteException e) {
                     throw e.rethrowAsRuntimeException();
                 } finally {
-                    setCallingPackage(original);
+                    setCallingAttributionSource(original);
                 }
                 if (cursor == null) {
                     return null;
@@ -272,8 +265,8 @@
                 return new MatrixCursor(cursor.getColumnNames(), 0);
             }
             Trace.traceBegin(TRACE_TAG_DATABASE, "query");
-            final Pair<String, String> original = setCallingPackage(
-                    new Pair<>(callingPkg, attributionTag));
+            final AttributionSource original = setCallingAttributionSource(
+                    attributionSource);
             try {
                 return mInterface.query(
                         uri, projection, queryArgs,
@@ -281,7 +274,7 @@
             } catch (RemoteException e) {
                 throw e.rethrowAsRuntimeException();
             } finally {
-                setCallingPackage(original);
+                setCallingAttributionSource(original);
                 Trace.traceEnd(TRACE_TAG_DATABASE);
             }
         }
@@ -314,60 +307,59 @@
         }
 
         @Override
-        public Uri insert(String callingPkg, @Nullable String attributionTag, Uri uri,
+        public Uri insert(@NonNull AttributionSource attributionSource, Uri uri,
                 ContentValues initialValues, Bundle extras) {
             uri = validateIncomingUri(uri);
             int userId = getUserIdFromUri(uri);
             uri = maybeGetUriWithoutUserId(uri);
-            if (enforceWritePermission(callingPkg, attributionTag, uri, null)
-                    != AppOpsManager.MODE_ALLOWED) {
-                final Pair<String, String> original = setCallingPackage(
-                        new Pair<>(callingPkg, attributionTag));
+            if (enforceWritePermission(attributionSource, uri)
+                    != PermissionChecker.PERMISSION_GRANTED) {
+                final AttributionSource original = setCallingAttributionSource(
+                        attributionSource);
                 try {
                     return rejectInsert(uri, initialValues);
                 } finally {
-                    setCallingPackage(original);
+                    setCallingAttributionSource(original);
                 }
             }
             Trace.traceBegin(TRACE_TAG_DATABASE, "insert");
-            final Pair<String, String> original = setCallingPackage(
-                    new Pair<>(callingPkg, attributionTag));
+            final AttributionSource original = setCallingAttributionSource(
+                    attributionSource);
             try {
                 return maybeAddUserId(mInterface.insert(uri, initialValues, extras), userId);
             } catch (RemoteException e) {
                 throw e.rethrowAsRuntimeException();
             } finally {
-                setCallingPackage(original);
+                setCallingAttributionSource(original);
                 Trace.traceEnd(TRACE_TAG_DATABASE);
             }
         }
 
         @Override
-        public int bulkInsert(String callingPkg, @Nullable String attributionTag, Uri uri,
+        public int bulkInsert(@NonNull AttributionSource attributionSource, Uri uri,
                 ContentValues[] initialValues) {
             uri = validateIncomingUri(uri);
             uri = maybeGetUriWithoutUserId(uri);
-            if (enforceWritePermission(callingPkg, attributionTag, uri, null)
-                    != AppOpsManager.MODE_ALLOWED) {
+            if (enforceWritePermission(attributionSource, uri)
+                    != PermissionChecker.PERMISSION_GRANTED) {
                 return 0;
             }
             Trace.traceBegin(TRACE_TAG_DATABASE, "bulkInsert");
-            final Pair<String, String> original = setCallingPackage(
-                    new Pair<>(callingPkg, attributionTag));
+            final AttributionSource original = setCallingAttributionSource(
+                    attributionSource);
             try {
                 return mInterface.bulkInsert(uri, initialValues);
             } catch (RemoteException e) {
                 throw e.rethrowAsRuntimeException();
             } finally {
-                setCallingPackage(original);
+                setCallingAttributionSource(original);
                 Trace.traceEnd(TRACE_TAG_DATABASE);
             }
         }
 
         @Override
-        public ContentProviderResult[] applyBatch(String callingPkg,
-                @Nullable String attributionTag, String authority,
-                ArrayList<ContentProviderOperation> operations)
+        public ContentProviderResult[] applyBatch(@NonNull AttributionSource attributionSource,
+                String authority, ArrayList<ContentProviderOperation> operations)
                 throws OperationApplicationException {
             validateIncomingAuthority(authority);
             int numOperations = operations.size();
@@ -383,22 +375,24 @@
                     operation = new ContentProviderOperation(operation, uri);
                     operations.set(i, operation);
                 }
+                final AttributionSource accessAttributionSource =
+                        attributionSource;
                 if (operation.isReadOperation()) {
-                    if (enforceReadPermission(callingPkg, attributionTag, uri, null)
-                            != AppOpsManager.MODE_ALLOWED) {
+                    if (enforceReadPermission(accessAttributionSource, uri)
+                            != PermissionChecker.PERMISSION_GRANTED) {
                         throw new OperationApplicationException("App op not allowed", 0);
                     }
                 }
                 if (operation.isWriteOperation()) {
-                    if (enforceWritePermission(callingPkg, attributionTag, uri, null)
-                            != AppOpsManager.MODE_ALLOWED) {
+                    if (enforceWritePermission(accessAttributionSource, uri)
+                            != PermissionChecker.PERMISSION_GRANTED) {
                         throw new OperationApplicationException("App op not allowed", 0);
                     }
                 }
             }
             Trace.traceBegin(TRACE_TAG_DATABASE, "applyBatch");
-            final Pair<String, String> original = setCallingPackage(
-                    new Pair<>(callingPkg, attributionTag));
+            final AttributionSource original = setCallingAttributionSource(
+                    attributionSource);
             try {
                 ContentProviderResult[] results = mInterface.applyBatch(authority,
                         operations);
@@ -414,111 +408,111 @@
             } catch (RemoteException e) {
                 throw e.rethrowAsRuntimeException();
             } finally {
-                setCallingPackage(original);
+                setCallingAttributionSource(original);
                 Trace.traceEnd(TRACE_TAG_DATABASE);
             }
         }
 
         @Override
-        public int delete(String callingPkg, @Nullable String attributionTag, Uri uri,
+        public int delete(@NonNull AttributionSource attributionSource, Uri uri,
                 Bundle extras) {
             uri = validateIncomingUri(uri);
             uri = maybeGetUriWithoutUserId(uri);
-            if (enforceWritePermission(callingPkg, attributionTag, uri, null)
-                    != AppOpsManager.MODE_ALLOWED) {
+            if (enforceWritePermission(attributionSource, uri)
+                    != PermissionChecker.PERMISSION_GRANTED) {
                 return 0;
             }
             Trace.traceBegin(TRACE_TAG_DATABASE, "delete");
-            final Pair<String, String> original = setCallingPackage(
-                    new Pair<>(callingPkg, attributionTag));
+            final AttributionSource original = setCallingAttributionSource(
+                    attributionSource);
             try {
                 return mInterface.delete(uri, extras);
             } catch (RemoteException e) {
                 throw e.rethrowAsRuntimeException();
             } finally {
-                setCallingPackage(original);
+                setCallingAttributionSource(original);
                 Trace.traceEnd(TRACE_TAG_DATABASE);
             }
         }
 
         @Override
-        public int update(String callingPkg, @Nullable String attributionTag, Uri uri,
+        public int update(@NonNull AttributionSource attributionSource, Uri uri,
                 ContentValues values, Bundle extras) {
             uri = validateIncomingUri(uri);
             uri = maybeGetUriWithoutUserId(uri);
-            if (enforceWritePermission(callingPkg, attributionTag, uri, null)
-                    != AppOpsManager.MODE_ALLOWED) {
+            if (enforceWritePermission(attributionSource, uri)
+                    != PermissionChecker.PERMISSION_GRANTED) {
                 return 0;
             }
             Trace.traceBegin(TRACE_TAG_DATABASE, "update");
-            final Pair<String, String> original = setCallingPackage(
-                    new Pair<>(callingPkg, attributionTag));
+            final AttributionSource original = setCallingAttributionSource(
+                    attributionSource);
             try {
                 return mInterface.update(uri, values, extras);
             } catch (RemoteException e) {
                 throw e.rethrowAsRuntimeException();
             } finally {
-                setCallingPackage(original);
+                setCallingAttributionSource(original);
                 Trace.traceEnd(TRACE_TAG_DATABASE);
             }
         }
 
         @Override
-        public ParcelFileDescriptor openFile(String callingPkg, @Nullable String attributionTag,
-                Uri uri, String mode, ICancellationSignal cancellationSignal, IBinder callerToken)
+        public ParcelFileDescriptor openFile(@NonNull AttributionSource attributionSource,
+                Uri uri, String mode, ICancellationSignal cancellationSignal)
                 throws FileNotFoundException {
             uri = validateIncomingUri(uri);
             uri = maybeGetUriWithoutUserId(uri);
-            enforceFilePermission(callingPkg, attributionTag, uri, mode, callerToken);
+            enforceFilePermission(attributionSource, uri, mode);
             Trace.traceBegin(TRACE_TAG_DATABASE, "openFile");
-            final Pair<String, String> original = setCallingPackage(
-                    new Pair<>(callingPkg, attributionTag));
+            final AttributionSource original = setCallingAttributionSource(
+                    attributionSource);
             try {
                 return mInterface.openFile(
                         uri, mode, CancellationSignal.fromTransport(cancellationSignal));
             } catch (RemoteException e) {
                 throw e.rethrowAsRuntimeException();
             } finally {
-                setCallingPackage(original);
+                setCallingAttributionSource(original);
                 Trace.traceEnd(TRACE_TAG_DATABASE);
             }
         }
 
         @Override
-        public AssetFileDescriptor openAssetFile(String callingPkg, @Nullable String attributionTag,
+        public AssetFileDescriptor openAssetFile(@NonNull AttributionSource attributionSource,
                 Uri uri, String mode, ICancellationSignal cancellationSignal)
                 throws FileNotFoundException {
             uri = validateIncomingUri(uri);
             uri = maybeGetUriWithoutUserId(uri);
-            enforceFilePermission(callingPkg, attributionTag, uri, mode, null);
+            enforceFilePermission(attributionSource, uri, mode);
             Trace.traceBegin(TRACE_TAG_DATABASE, "openAssetFile");
-            final Pair<String, String> original = setCallingPackage(
-                    new Pair<>(callingPkg, attributionTag));
+            final AttributionSource original = setCallingAttributionSource(
+                    attributionSource);
             try {
                 return mInterface.openAssetFile(
                         uri, mode, CancellationSignal.fromTransport(cancellationSignal));
             } catch (RemoteException e) {
                 throw e.rethrowAsRuntimeException();
             } finally {
-                setCallingPackage(original);
+                setCallingAttributionSource(original);
                 Trace.traceEnd(TRACE_TAG_DATABASE);
             }
         }
 
         @Override
-        public Bundle call(String callingPkg, @Nullable String attributionTag, String authority,
+        public Bundle call(@NonNull AttributionSource attributionSource, String authority,
                 String method, @Nullable String arg, @Nullable Bundle extras) {
             validateIncomingAuthority(authority);
             Bundle.setDefusable(extras, true);
             Trace.traceBegin(TRACE_TAG_DATABASE, "call");
-            final Pair<String, String> original = setCallingPackage(
-                    new Pair<>(callingPkg, attributionTag));
+            final AttributionSource original = setCallingAttributionSource(
+                    attributionSource);
             try {
                 return mInterface.call(authority, method, arg, extras);
             } catch (RemoteException e) {
                 throw e.rethrowAsRuntimeException();
             } finally {
-                setCallingPackage(original);
+                setCallingAttributionSource(original);
                 Trace.traceEnd(TRACE_TAG_DATABASE);
             }
         }
@@ -539,23 +533,23 @@
         }
 
         @Override
-        public AssetFileDescriptor openTypedAssetFile(String callingPkg,
-                @Nullable String attributionTag, Uri uri, String mimeType, Bundle opts,
-                ICancellationSignal cancellationSignal) throws FileNotFoundException {
+        public AssetFileDescriptor openTypedAssetFile(
+                @NonNull AttributionSource attributionSource, Uri uri, String mimeType,
+                Bundle opts, ICancellationSignal cancellationSignal) throws FileNotFoundException {
             Bundle.setDefusable(opts, true);
             uri = validateIncomingUri(uri);
             uri = maybeGetUriWithoutUserId(uri);
-            enforceFilePermission(callingPkg, attributionTag, uri, "r", null);
+            enforceFilePermission(attributionSource, uri, "r");
             Trace.traceBegin(TRACE_TAG_DATABASE, "openTypedAssetFile");
-            final Pair<String, String> original = setCallingPackage(
-                    new Pair<>(callingPkg, attributionTag));
+            final AttributionSource original = setCallingAttributionSource(
+                    attributionSource);
             try {
                 return mInterface.openTypedAssetFile(
                         uri, mimeType, opts, CancellationSignal.fromTransport(cancellationSignal));
             } catch (RemoteException e) {
                 throw e.rethrowAsRuntimeException();
             } finally {
-                setCallingPackage(original);
+                setCallingAttributionSource(original);
                 Trace.traceEnd(TRACE_TAG_DATABASE);
             }
         }
@@ -566,34 +560,34 @@
         }
 
         @Override
-        public Uri canonicalize(String callingPkg, @Nullable String attributionTag, Uri uri) {
+        public Uri canonicalize(@NonNull AttributionSource attributionSource, Uri uri) {
             uri = validateIncomingUri(uri);
             int userId = getUserIdFromUri(uri);
             uri = getUriWithoutUserId(uri);
-            if (enforceReadPermission(callingPkg, attributionTag, uri, null)
-                    != AppOpsManager.MODE_ALLOWED) {
+            if (enforceReadPermission(attributionSource, uri)
+                    != PermissionChecker.PERMISSION_GRANTED) {
                 return null;
             }
             Trace.traceBegin(TRACE_TAG_DATABASE, "canonicalize");
-            final Pair<String, String> original = setCallingPackage(
-                    new Pair<>(callingPkg, attributionTag));
+            final AttributionSource original = setCallingAttributionSource(
+                    attributionSource);
             try {
                 return maybeAddUserId(mInterface.canonicalize(uri), userId);
             } catch (RemoteException e) {
                 throw e.rethrowAsRuntimeException();
             } finally {
-                setCallingPackage(original);
+                setCallingAttributionSource(original);
                 Trace.traceEnd(TRACE_TAG_DATABASE);
             }
         }
 
         @Override
-        public void canonicalizeAsync(String callingPkg, @Nullable String attributionTag, Uri uri,
+        public void canonicalizeAsync(@NonNull AttributionSource attributionSource, Uri uri,
                 RemoteCallback callback) {
             final Bundle result = new Bundle();
             try {
                 result.putParcelable(ContentResolver.REMOTE_CALLBACK_RESULT,
-                        canonicalize(callingPkg, attributionTag, uri));
+                        canonicalize(attributionSource, uri));
             } catch (Exception e) {
                 result.putParcelable(ContentResolver.REMOTE_CALLBACK_ERROR,
                         new ParcelableException(e));
@@ -602,34 +596,34 @@
         }
 
         @Override
-        public Uri uncanonicalize(String callingPkg, String attributionTag,  Uri uri) {
+        public Uri uncanonicalize(@NonNull AttributionSource attributionSource, Uri uri) {
             uri = validateIncomingUri(uri);
             int userId = getUserIdFromUri(uri);
             uri = getUriWithoutUserId(uri);
-            if (enforceReadPermission(callingPkg, attributionTag, uri, null)
-                    != AppOpsManager.MODE_ALLOWED) {
+            if (enforceReadPermission(attributionSource, uri)
+                    != PermissionChecker.PERMISSION_GRANTED) {
                 return null;
             }
             Trace.traceBegin(TRACE_TAG_DATABASE, "uncanonicalize");
-            final Pair<String, String> original = setCallingPackage(
-                    new Pair<>(callingPkg, attributionTag));
+            final AttributionSource original = setCallingAttributionSource(
+                    attributionSource);
             try {
                 return maybeAddUserId(mInterface.uncanonicalize(uri), userId);
             } catch (RemoteException e) {
                 throw e.rethrowAsRuntimeException();
             } finally {
-                setCallingPackage(original);
+                setCallingAttributionSource(original);
                 Trace.traceEnd(TRACE_TAG_DATABASE);
             }
         }
 
         @Override
-        public void uncanonicalizeAsync(String callingPkg, @Nullable String attributionTag, Uri uri,
+        public void uncanonicalizeAsync(@NonNull AttributionSource attributionSource, Uri uri,
                 RemoteCallback callback) {
             final Bundle result = new Bundle();
             try {
                 result.putParcelable(ContentResolver.REMOTE_CALLBACK_RESULT,
-                        uncanonicalize(callingPkg, attributionTag, uri));
+                        uncanonicalize(attributionSource, uri));
             } catch (Exception e) {
                 result.putParcelable(ContentResolver.REMOTE_CALLBACK_ERROR,
                         new ParcelableException(e));
@@ -638,92 +632,95 @@
         }
 
         @Override
-        public boolean refresh(String callingPkg, String attributionTag, Uri uri, Bundle extras,
-                ICancellationSignal cancellationSignal) throws RemoteException {
+        public boolean refresh(@NonNull AttributionSource attributionSource, Uri uri,
+                Bundle extras, ICancellationSignal cancellationSignal) throws RemoteException {
             uri = validateIncomingUri(uri);
             uri = getUriWithoutUserId(uri);
-            if (enforceReadPermission(callingPkg, attributionTag, uri, null)
-                    != AppOpsManager.MODE_ALLOWED) {
+            if (enforceReadPermission(attributionSource, uri)
+                    != PermissionChecker.PERMISSION_GRANTED) {
                 return false;
             }
             Trace.traceBegin(TRACE_TAG_DATABASE, "refresh");
-            final Pair<String, String> original = setCallingPackage(
-                    new Pair<>(callingPkg, attributionTag));
+            final AttributionSource original = setCallingAttributionSource(
+                    attributionSource);
             try {
                 return mInterface.refresh(uri, extras,
                         CancellationSignal.fromTransport(cancellationSignal));
             } finally {
-                setCallingPackage(original);
+                setCallingAttributionSource(original);
                 Trace.traceEnd(TRACE_TAG_DATABASE);
             }
         }
 
         @Override
-        public int checkUriPermission(String callingPkg, @Nullable String attributionTag, Uri uri,
+        public int checkUriPermission(@NonNull AttributionSource attributionSource, Uri uri,
                 int uid, int modeFlags) {
             uri = validateIncomingUri(uri);
             uri = maybeGetUriWithoutUserId(uri);
             Trace.traceBegin(TRACE_TAG_DATABASE, "checkUriPermission");
-            final Pair<String, String> original = setCallingPackage(
-                    new Pair<>(callingPkg, attributionTag));
+            final AttributionSource original = setCallingAttributionSource(
+                    attributionSource);
             try {
                 return mInterface.checkUriPermission(uri, uid, modeFlags);
             } catch (RemoteException e) {
                 throw e.rethrowAsRuntimeException();
             } finally {
-                setCallingPackage(original);
+                setCallingAttributionSource(original);
                 Trace.traceEnd(TRACE_TAG_DATABASE);
             }
         }
 
-        private void enforceFilePermission(String callingPkg, @Nullable String attributionTag,
-                Uri uri, String mode, IBinder callerToken)
+        @PermissionChecker.PermissionResult
+        private void enforceFilePermission(@NonNull AttributionSource attributionSource,
+                Uri uri, String mode)
                 throws FileNotFoundException, SecurityException {
             if (mode != null && mode.indexOf('w') != -1) {
-                if (enforceWritePermission(callingPkg, attributionTag, uri, callerToken)
-                        != AppOpsManager.MODE_ALLOWED) {
+                if (enforceWritePermission(attributionSource, uri)
+                        != PermissionChecker.PERMISSION_GRANTED) {
                     throw new FileNotFoundException("App op not allowed");
                 }
             } else {
-                if (enforceReadPermission(callingPkg, attributionTag, uri, callerToken)
-                        != AppOpsManager.MODE_ALLOWED) {
+                if (enforceReadPermission(attributionSource, uri)
+                        != PermissionChecker.PERMISSION_GRANTED) {
                     throw new FileNotFoundException("App op not allowed");
                 }
             }
         }
 
-        private int enforceReadPermission(String callingPkg, @Nullable String attributionTag,
-                Uri uri, IBinder callerToken)
+        @PermissionChecker.PermissionResult
+        private int enforceReadPermission(@NonNull AttributionSource attributionSource, Uri uri)
                 throws SecurityException {
-            final int mode = enforceReadPermissionInner(uri, callingPkg, attributionTag,
-                    callerToken);
-            if (mode != MODE_ALLOWED) {
-                return mode;
+            final int result = enforceReadPermissionInner(uri, attributionSource);
+            if (result != PermissionChecker.PERMISSION_GRANTED) {
+                return result;
             }
-
-            return noteProxyOp(callingPkg, attributionTag, mReadOp);
+            // Only check the read op if it differs from the one for the permission
+            // we already checked above to avoid double attribution for every access.
+            if (mTransport.mReadOp != AppOpsManager.OP_NONE
+                    && mTransport.mReadOp != AppOpsManager.permissionToOpCode(mReadPermission)) {
+                return PermissionChecker.checkOpForDataDelivery(getContext(),
+                        AppOpsManager.opToPublicName(mTransport.mReadOp),
+                        attributionSource, /*message*/ null);
+            }
+            return PermissionChecker.PERMISSION_GRANTED;
         }
 
-        private int enforceWritePermission(String callingPkg, String attributionTag, Uri uri,
-                IBinder callerToken)
+        @PermissionChecker.PermissionResult
+        private int enforceWritePermission(@NonNull AttributionSource attributionSource, Uri uri)
                 throws SecurityException {
-            final int mode = enforceWritePermissionInner(uri, callingPkg, attributionTag,
-                    callerToken);
-            if (mode != MODE_ALLOWED) {
-                return mode;
+            final int result = enforceWritePermissionInner(uri, attributionSource);
+            if (result != PermissionChecker.PERMISSION_GRANTED) {
+                return result;
             }
-
-            return noteProxyOp(callingPkg, attributionTag, mWriteOp);
-        }
-
-        private int noteProxyOp(String callingPkg, String attributionTag, int op) {
-            if (op != AppOpsManager.OP_NONE) {
-                int mode = mAppOpsManager.noteProxyOp(op, callingPkg, Binder.getCallingUid(),
-                        attributionTag, null);
-                return mode == MODE_DEFAULT ? MODE_IGNORED : mode;
+            // Only check the write op if it differs from the one for the permission
+            // we already checked above to avoid double attribution for every access.
+            if (mTransport.mWriteOp != AppOpsManager.OP_NONE
+                    && mTransport.mWriteOp != AppOpsManager.permissionToOpCode(mWritePermission)) {
+                return PermissionChecker.checkOpForDataDelivery(getContext(),
+                        AppOpsManager.opToPublicName(mTransport.mWriteOp),
+                        attributionSource, /*message*/ null);
             }
-
-            return AppOpsManager.MODE_ALLOWED;
+            return PermissionChecker.PERMISSION_GRANTED;
         }
     }
 
@@ -731,49 +728,53 @@
         if (UserHandle.getUserId(uid) == context.getUserId() || mSingleUser) {
             return true;
         }
-        return context.checkPermission(INTERACT_ACROSS_USERS, pid, uid) == PERMISSION_GRANTED
+        return context.checkPermission(INTERACT_ACROSS_USERS, pid, uid)
+                    == PackageManager.PERMISSION_GRANTED
                 || context.checkPermission(INTERACT_ACROSS_USERS_FULL, pid, uid)
-                == PERMISSION_GRANTED;
+                    == PackageManager.PERMISSION_GRANTED;
     }
 
     /**
      * Verify that calling app holds both the given permission and any app-op
      * associated with that permission.
      */
-    private int checkPermissionAndAppOp(String permission, String callingPkg,
-            @Nullable String attributionTag, IBinder callerToken) {
-        if (getContext().checkPermission(permission, Binder.getCallingPid(), Binder.getCallingUid(),
-                callerToken) != PERMISSION_GRANTED) {
-            return MODE_ERRORED;
+    @PermissionChecker.PermissionResult
+    private int checkPermission(String permission,
+            @NonNull AttributionSource attributionSource) {
+        if (Binder.getCallingPid() == Process.myPid()) {
+            return PermissionChecker.PERMISSION_GRANTED;
         }
-
-        return mTransport.noteProxyOp(callingPkg, attributionTag,
-                AppOpsManager.permissionToOpCode(permission));
+        if (!attributionSource.checkCallingUid()) {
+            return PermissionChecker.PERMISSION_HARD_DENIED;
+        }
+        return PermissionChecker.checkPermissionForDataDeliveryFromDataSource(getContext(),
+                permission, -1, new AttributionSource(getContext().getAttributionSource(),
+                        attributionSource), /*message*/ null);
     }
 
     /** {@hide} */
-    protected int enforceReadPermissionInner(Uri uri, String callingPkg,
-            @Nullable String attributionTag, IBinder callerToken) throws SecurityException {
+    @PermissionChecker.PermissionResult
+    protected int enforceReadPermissionInner(Uri uri,
+            @NonNull AttributionSource attributionSource) throws SecurityException {
         final Context context = getContext();
         final int pid = Binder.getCallingPid();
         final int uid = Binder.getCallingUid();
         String missingPerm = null;
-        int strongestMode = MODE_ALLOWED;
+        int strongestResult = PermissionChecker.PERMISSION_GRANTED;
 
         if (UserHandle.isSameApp(uid, mMyUid)) {
-            return MODE_ALLOWED;
+            return PermissionChecker.PERMISSION_GRANTED;
         }
 
         if (mExported && checkUser(pid, uid, context)) {
             final String componentPerm = getReadPermission();
             if (componentPerm != null) {
-                final int mode = checkPermissionAndAppOp(componentPerm, callingPkg, attributionTag,
-                        callerToken);
-                if (mode == MODE_ALLOWED) {
-                    return MODE_ALLOWED;
+                final int result = checkPermission(componentPerm, attributionSource);
+                if (result == PermissionChecker.PERMISSION_GRANTED) {
+                    return PermissionChecker.PERMISSION_GRANTED;
                 } else {
                     missingPerm = componentPerm;
-                    strongestMode = Math.max(strongestMode, mode);
+                    strongestResult = Math.max(strongestResult, result);
                 }
             }
 
@@ -787,16 +788,15 @@
                 for (PathPermission pp : pps) {
                     final String pathPerm = pp.getReadPermission();
                     if (pathPerm != null && pp.match(path)) {
-                        final int mode = checkPermissionAndAppOp(pathPerm, callingPkg,
-                                attributionTag, callerToken);
-                        if (mode == MODE_ALLOWED) {
-                            return MODE_ALLOWED;
+                        final int result = checkPermission(pathPerm, attributionSource);
+                        if (result == PermissionChecker.PERMISSION_GRANTED) {
+                            return PermissionChecker.PERMISSION_GRANTED;
                         } else {
                             // any denied <path-permission> means we lose
                             // default <provider> access.
                             allowDefaultRead = false;
                             missingPerm = pathPerm;
-                            strongestMode = Math.max(strongestMode, mode);
+                            strongestResult = Math.max(strongestResult, result);
                         }
                     }
                 }
@@ -804,22 +804,22 @@
 
             // if we passed <path-permission> checks above, and no default
             // <provider> permission, then allow access.
-            if (allowDefaultRead) return MODE_ALLOWED;
+            if (allowDefaultRead) return PermissionChecker.PERMISSION_GRANTED;
         }
 
         // last chance, check against any uri grants
         final int callingUserId = UserHandle.getUserId(uid);
         final Uri userUri = (mSingleUser && !UserHandle.isSameUser(mMyUid, uid))
                 ? maybeAddUserId(uri, callingUserId) : uri;
-        if (context.checkUriPermission(userUri, pid, uid, Intent.FLAG_GRANT_READ_URI_PERMISSION,
-                callerToken) == PERMISSION_GRANTED) {
-            return MODE_ALLOWED;
+        if (context.checkUriPermission(userUri, pid, uid, Intent.FLAG_GRANT_READ_URI_PERMISSION)
+                == PackageManager.PERMISSION_GRANTED) {
+            return PermissionChecker.PERMISSION_GRANTED;
         }
 
         // If the worst denial we found above was ignored, then pass that
         // ignored through; otherwise we assume it should be a real error below.
-        if (strongestMode == MODE_IGNORED) {
-            return MODE_IGNORED;
+        if (strongestResult == PermissionChecker.PERMISSION_SOFT_DENIED) {
+            return PermissionChecker.PERMISSION_SOFT_DENIED;
         }
 
         final String suffix;
@@ -836,28 +836,28 @@
     }
 
     /** {@hide} */
-    protected int enforceWritePermissionInner(Uri uri, String callingPkg,
-            @Nullable String attributionTag, IBinder callerToken) throws SecurityException {
+    @PermissionChecker.PermissionResult
+    protected int enforceWritePermissionInner(Uri uri,
+            @NonNull AttributionSource attributionSource) throws SecurityException {
         final Context context = getContext();
         final int pid = Binder.getCallingPid();
         final int uid = Binder.getCallingUid();
         String missingPerm = null;
-        int strongestMode = MODE_ALLOWED;
+        int strongestResult = PermissionChecker.PERMISSION_GRANTED;
 
         if (UserHandle.isSameApp(uid, mMyUid)) {
-            return MODE_ALLOWED;
+            return PermissionChecker.PERMISSION_GRANTED;
         }
 
         if (mExported && checkUser(pid, uid, context)) {
             final String componentPerm = getWritePermission();
             if (componentPerm != null) {
-                final int mode = checkPermissionAndAppOp(componentPerm, callingPkg,
-                        attributionTag, callerToken);
-                if (mode == MODE_ALLOWED) {
-                    return MODE_ALLOWED;
+                final int mode = checkPermission(componentPerm, attributionSource);
+                if (mode == PermissionChecker.PERMISSION_GRANTED) {
+                    return PermissionChecker.PERMISSION_GRANTED;
                 } else {
                     missingPerm = componentPerm;
-                    strongestMode = Math.max(strongestMode, mode);
+                    strongestResult = Math.max(strongestResult, mode);
                 }
             }
 
@@ -871,16 +871,15 @@
                 for (PathPermission pp : pps) {
                     final String pathPerm = pp.getWritePermission();
                     if (pathPerm != null && pp.match(path)) {
-                        final int mode = checkPermissionAndAppOp(pathPerm, callingPkg,
-                                attributionTag, callerToken);
-                        if (mode == MODE_ALLOWED) {
-                            return MODE_ALLOWED;
+                        final int mode = checkPermission(pathPerm, attributionSource);
+                        if (mode == PermissionChecker.PERMISSION_GRANTED) {
+                            return PermissionChecker.PERMISSION_GRANTED;
                         } else {
                             // any denied <path-permission> means we lose
                             // default <provider> access.
                             allowDefaultWrite = false;
                             missingPerm = pathPerm;
-                            strongestMode = Math.max(strongestMode, mode);
+                            strongestResult = Math.max(strongestResult, mode);
                         }
                     }
                 }
@@ -888,19 +887,19 @@
 
             // if we passed <path-permission> checks above, and no default
             // <provider> permission, then allow access.
-            if (allowDefaultWrite) return MODE_ALLOWED;
+            if (allowDefaultWrite) return PermissionChecker.PERMISSION_GRANTED;
         }
 
         // last chance, check against any uri grants
-        if (context.checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
-                callerToken) == PERMISSION_GRANTED) {
-            return MODE_ALLOWED;
+        if (context.checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
+                == PackageManager.PERMISSION_GRANTED) {
+            return PermissionChecker.PERMISSION_GRANTED;
         }
 
         // If the worst denial we found above was ignored, then pass that
         // ignored through; otherwise we assume it should be a real error below.
-        if (strongestMode == MODE_IGNORED) {
-            return MODE_IGNORED;
+        if (strongestResult == PermissionChecker.PERMISSION_SOFT_DENIED) {
+            return PermissionChecker.PERMISSION_SOFT_DENIED;
         }
 
         final String failReason = mExported
@@ -941,9 +940,10 @@
      * Set the calling package/feature, returning the current value (or {@code null})
      * which can be used later to restore the previous state.
      */
-    private Pair<String, String> setCallingPackage(Pair<String, String> callingPackage) {
-        final Pair<String, String> original = mCallingPackage.get();
-        mCallingPackage.set(callingPackage);
+    private @Nullable AttributionSource setCallingAttributionSource(
+            @Nullable AttributionSource attributionSource) {
+        final AttributionSource original = mCallingAttributionSource.get();
+        mCallingAttributionSource.set(attributionSource);
         onCallingPackageChanged();
         return original;
     }
@@ -963,13 +963,30 @@
      *             calling UID.
      */
     public final @Nullable String getCallingPackage() {
-        final Pair<String, String> pkg = mCallingPackage.get();
-        if (pkg != null) {
-            mTransport.mAppOpsManager.checkPackage(Binder.getCallingUid(), pkg.first);
-            return pkg.first;
-        }
+        final AttributionSource callingAttributionSource = getCallingAttributionSource();
+        return (callingAttributionSource != null)
+                ? callingAttributionSource.getPackageName() : null;
+    }
 
-        return null;
+    /**
+     * Gets the attribution source of the calling app. If you want to attribute
+     * the data access to the calling app you can create an attribution context
+     * via {@link android.content.Context#createContext(ContextParams)} and passing
+     * this identity to {@link ContextParams.Builder#setNextAttributionSource(
+     * AttributionSource)}.
+     *
+     * @return The identity of the caller for permission purposes.
+     *
+     * @see ContextParams.Builder#setNextAttributionSource(AttributionSource)
+     * @see AttributionSource
+     */
+    public final @Nullable AttributionSource getCallingAttributionSource() {
+        final AttributionSource attributionSource = mCallingAttributionSource.get();
+        if (attributionSource != null) {
+            mTransport.mAppOpsManager.checkPackage(Binder.getCallingUid(),
+                    attributionSource.getPackageName());
+        }
+        return attributionSource;
     }
 
     /**
@@ -983,11 +1000,10 @@
      * @see #getCallingPackage
      */
     public final @Nullable String getCallingAttributionTag() {
-        final Pair<String, String> pkg = mCallingPackage.get();
-        if (pkg != null) {
-            return pkg.second;
+        final AttributionSource attributionSource = mCallingAttributionSource.get();
+        if (attributionSource != null) {
+            return attributionSource.getAttributionTag();
         }
-
         return null;
     }
 
@@ -1012,11 +1028,10 @@
      * @see Context#grantUriPermission(String, Uri, int)
      */
     public final @Nullable String getCallingPackageUnchecked() {
-        final Pair<String, String> pkg = mCallingPackage.get();
-        if (pkg != null) {
-            return pkg.first;
+        final AttributionSource attributionSource = mCallingAttributionSource.get();
+        if (attributionSource != null) {
+            return attributionSource.getPackageName();
         }
-
         return null;
     }
 
@@ -1038,12 +1053,12 @@
         /** {@hide} */
         public final long binderToken;
         /** {@hide} */
-        public final Pair<String, String> callingPackage;
+        public final @Nullable AttributionSource callingAttributionSource;
 
         /** {@hide} */
-        public CallingIdentity(long binderToken, Pair<String, String> callingPackage) {
+        public CallingIdentity(long binderToken, @Nullable AttributionSource attributionSource) {
             this.binderToken = binderToken;
-            this.callingPackage = callingPackage;
+            this.callingAttributionSource = attributionSource;
         }
     }
 
@@ -1059,7 +1074,8 @@
      */
     @SuppressWarnings("AndroidFrameworkBinderIdentity")
     public final @NonNull CallingIdentity clearCallingIdentity() {
-        return new CallingIdentity(Binder.clearCallingIdentity(), setCallingPackage(null));
+        return new CallingIdentity(Binder.clearCallingIdentity(),
+                setCallingAttributionSource(null));
     }
 
     /**
@@ -1071,7 +1087,7 @@
      */
     public final void restoreCallingIdentity(@NonNull CallingIdentity identity) {
         Binder.restoreCallingIdentity(identity.binderToken);
-        mCallingPackage.set(identity.callingPackage);
+        mCallingAttributionSource.set(identity.callingAttributionSource);
     }
 
     /**
@@ -2374,7 +2390,7 @@
 
     private void attachInfo(Context context, ProviderInfo info, boolean testing) {
         mNoPerms = testing;
-        mCallingPackage = new ThreadLocal<>();
+        mCallingAttributionSource = new ThreadLocal<>();
 
         /*
          * Only allow it to be set once, so after the content service gives
diff --git a/core/java/android/content/ContentProviderClient.java b/core/java/android/content/ContentProviderClient.java
index 5af7861..518e753 100644
--- a/core/java/android/content/ContentProviderClient.java
+++ b/core/java/android/content/ContentProviderClient.java
@@ -79,7 +79,8 @@
     private final IContentProvider mContentProvider;
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
     private final String mPackageName;
-    private final @Nullable String mAttributionTag;
+    private final @NonNull AttributionSource mAttributionSource;
+
     private final String mAuthority;
     private final boolean mStable;
 
@@ -103,7 +104,7 @@
         mContentResolver = contentResolver;
         mContentProvider = contentProvider;
         mPackageName = contentResolver.mPackageName;
-        mAttributionTag = contentResolver.mAttributionTag;
+        mAttributionSource = contentResolver.getAttributionSource();
 
         mAuthority = authority;
         mStable = stable;
@@ -193,7 +194,7 @@
                 cancellationSignal.setRemote(remoteCancellationSignal);
             }
             final Cursor cursor = mContentProvider.query(
-                    mPackageName, mAttributionTag, uri, projection, queryArgs,
+                    mAttributionSource, uri, projection, queryArgs,
                     remoteCancellationSignal);
             if (cursor == null) {
                 return null;
@@ -254,7 +255,7 @@
 
         beforeRemote();
         try {
-            return mContentProvider.canonicalize(mPackageName, mAttributionTag, url);
+            return mContentProvider.canonicalize(mAttributionSource, url);
         } catch (DeadObjectException e) {
             if (!mStable) {
                 mContentResolver.unstableProviderDied(mContentProvider);
@@ -272,7 +273,7 @@
 
         beforeRemote();
         try {
-            return mContentProvider.uncanonicalize(mPackageName, mAttributionTag, url);
+            return mContentProvider.uncanonicalize(mAttributionSource, url);
         } catch (DeadObjectException e) {
             if (!mStable) {
                 mContentResolver.unstableProviderDied(mContentProvider);
@@ -297,7 +298,7 @@
                 remoteCancellationSignal = mContentProvider.createCancellationSignal();
                 cancellationSignal.setRemote(remoteCancellationSignal);
             }
-            return mContentProvider.refresh(mPackageName, mAttributionTag, url, extras,
+            return mContentProvider.refresh(mAttributionSource, url, extras,
                     remoteCancellationSignal);
         } catch (DeadObjectException e) {
             if (!mStable) {
@@ -317,7 +318,7 @@
 
         beforeRemote();
         try {
-            return mContentProvider.checkUriPermission(mPackageName, mAttributionTag, uri, uid,
+            return mContentProvider.checkUriPermission(mAttributionSource, uri, uid,
                     modeFlags);
         } catch (DeadObjectException e) {
             if (!mStable) {
@@ -343,7 +344,7 @@
 
         beforeRemote();
         try {
-            return mContentProvider.insert(mPackageName, mAttributionTag, url, initialValues,
+            return mContentProvider.insert(mAttributionSource, url, initialValues,
                     extras);
         } catch (DeadObjectException e) {
             if (!mStable) {
@@ -364,7 +365,7 @@
 
         beforeRemote();
         try {
-            return mContentProvider.bulkInsert(mPackageName, mAttributionTag, url, initialValues);
+            return mContentProvider.bulkInsert(mAttributionSource, url, initialValues);
         } catch (DeadObjectException e) {
             if (!mStable) {
                 mContentResolver.unstableProviderDied(mContentProvider);
@@ -388,7 +389,7 @@
 
         beforeRemote();
         try {
-            return mContentProvider.delete(mPackageName, mAttributionTag, url, extras);
+            return mContentProvider.delete(mAttributionSource, url, extras);
         } catch (DeadObjectException e) {
             if (!mStable) {
                 mContentResolver.unstableProviderDied(mContentProvider);
@@ -413,7 +414,7 @@
 
         beforeRemote();
         try {
-            return mContentProvider.update(mPackageName, mAttributionTag, url, values, extras);
+            return mContentProvider.update(mAttributionSource, url, values, extras);
         } catch (DeadObjectException e) {
             if (!mStable) {
                 mContentResolver.unstableProviderDied(mContentProvider);
@@ -457,8 +458,7 @@
                 remoteSignal = mContentProvider.createCancellationSignal();
                 signal.setRemote(remoteSignal);
             }
-            return mContentProvider.openFile(mPackageName, mAttributionTag, url, mode,
-                    remoteSignal, null);
+            return mContentProvider.openFile(mAttributionSource, url, mode, remoteSignal);
         } catch (DeadObjectException e) {
             if (!mStable) {
                 mContentResolver.unstableProviderDied(mContentProvider);
@@ -502,7 +502,7 @@
                 remoteSignal = mContentProvider.createCancellationSignal();
                 signal.setRemote(remoteSignal);
             }
-            return mContentProvider.openAssetFile(mPackageName, mAttributionTag, url, mode,
+            return mContentProvider.openAssetFile(mAttributionSource, url, mode,
                     remoteSignal);
         } catch (DeadObjectException e) {
             if (!mStable) {
@@ -544,7 +544,7 @@
                 signal.setRemote(remoteSignal);
             }
             return mContentProvider.openTypedAssetFile(
-                    mPackageName, mAttributionTag, uri, mimeTypeFilter, opts, remoteSignal);
+                    mAttributionSource, uri, mimeTypeFilter, opts, remoteSignal);
         } catch (DeadObjectException e) {
             if (!mStable) {
                 mContentResolver.unstableProviderDied(mContentProvider);
@@ -571,7 +571,7 @@
 
         beforeRemote();
         try {
-            return mContentProvider.applyBatch(mPackageName, mAttributionTag, authority,
+            return mContentProvider.applyBatch(mAttributionSource, authority,
                     operations);
         } catch (DeadObjectException e) {
             if (!mStable) {
@@ -598,7 +598,7 @@
 
         beforeRemote();
         try {
-            return mContentProvider.call(mPackageName, mAttributionTag, authority, method, arg,
+            return mContentProvider.call(mAttributionSource, authority, method, arg,
                     extras);
         } catch (DeadObjectException e) {
             if (!mStable) {
diff --git a/core/java/android/content/ContentProviderNative.java b/core/java/android/content/ContentProviderNative.java
index 7d121d5..47c96699 100644
--- a/core/java/android/content/ContentProviderNative.java
+++ b/core/java/android/content/ContentProviderNative.java
@@ -16,6 +16,7 @@
 
 package android.content;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.res.AssetFileDescriptor;
@@ -83,8 +84,8 @@
                 {
                     data.enforceInterface(IContentProvider.descriptor);
 
-                    String callingPkg = data.readString();
-                    String callingFeatureId = data.readString();
+                    AttributionSource attributionSource = AttributionSource.CREATOR
+                            .createFromParcel(data);
                     Uri url = Uri.CREATOR.createFromParcel(data);
 
                     // String[] projection
@@ -103,7 +104,7 @@
                     ICancellationSignal cancellationSignal = ICancellationSignal.Stub.asInterface(
                             data.readStrongBinder());
 
-                    Cursor cursor = query(callingPkg, callingFeatureId, url, projection, queryArgs,
+                    Cursor cursor = query(attributionSource, url, projection, queryArgs,
                             cancellationSignal);
                     if (cursor != null) {
                         CursorToBulkCursorAdaptor adaptor = null;
@@ -158,13 +159,13 @@
                 case INSERT_TRANSACTION:
                 {
                     data.enforceInterface(IContentProvider.descriptor);
-                    String callingPkg = data.readString();
-                    String featureId = data.readString();
+                    AttributionSource attributionSource = AttributionSource.CREATOR
+                            .createFromParcel(data);
                     Uri url = Uri.CREATOR.createFromParcel(data);
                     ContentValues values = ContentValues.CREATOR.createFromParcel(data);
                     Bundle extras = data.readBundle();
 
-                    Uri out = insert(callingPkg, featureId, url, values, extras);
+                    Uri out = insert(attributionSource, url, values, extras);
                     reply.writeNoException();
                     Uri.writeToParcel(reply, out);
                     return true;
@@ -173,12 +174,12 @@
                 case BULK_INSERT_TRANSACTION:
                 {
                     data.enforceInterface(IContentProvider.descriptor);
-                    String callingPkg = data.readString();
-                    String featureId = data.readString();
+                    AttributionSource attributionSource = AttributionSource.CREATOR
+                            .createFromParcel(data);
                     Uri url = Uri.CREATOR.createFromParcel(data);
                     ContentValues[] values = data.createTypedArray(ContentValues.CREATOR);
 
-                    int count = bulkInsert(callingPkg, featureId, url, values);
+                    int count = bulkInsert(attributionSource, url, values);
                     reply.writeNoException();
                     reply.writeInt(count);
                     return true;
@@ -187,8 +188,8 @@
                 case APPLY_BATCH_TRANSACTION:
                 {
                     data.enforceInterface(IContentProvider.descriptor);
-                    String callingPkg = data.readString();
-                    String featureId = data.readString();
+                    AttributionSource attributionSource = AttributionSource.CREATOR
+                            .createFromParcel(data);
                     String authority = data.readString();
                     final int numOperations = data.readInt();
                     final ArrayList<ContentProviderOperation> operations =
@@ -196,7 +197,7 @@
                     for (int i = 0; i < numOperations; i++) {
                         operations.add(i, ContentProviderOperation.CREATOR.createFromParcel(data));
                     }
-                    final ContentProviderResult[] results = applyBatch(callingPkg, featureId,
+                    final ContentProviderResult[] results = applyBatch(attributionSource,
                             authority, operations);
                     reply.writeNoException();
                     reply.writeTypedArray(results, 0);
@@ -206,12 +207,12 @@
                 case DELETE_TRANSACTION:
                 {
                     data.enforceInterface(IContentProvider.descriptor);
-                    String callingPkg = data.readString();
-                    String featureId = data.readString();
+                    AttributionSource attributionSource = AttributionSource.CREATOR
+                            .createFromParcel(data);
                     Uri url = Uri.CREATOR.createFromParcel(data);
                     Bundle extras = data.readBundle();
 
-                    int count = delete(callingPkg, featureId, url, extras);
+                    int count = delete(attributionSource, url, extras);
 
                     reply.writeNoException();
                     reply.writeInt(count);
@@ -221,13 +222,13 @@
                 case UPDATE_TRANSACTION:
                 {
                     data.enforceInterface(IContentProvider.descriptor);
-                    String callingPkg = data.readString();
-                    String featureId = data.readString();
+                    AttributionSource attributionSource = AttributionSource.CREATOR
+                            .createFromParcel(data);
                     Uri url = Uri.CREATOR.createFromParcel(data);
                     ContentValues values = ContentValues.CREATOR.createFromParcel(data);
                     Bundle extras = data.readBundle();
 
-                    int count = update(callingPkg, featureId, url, values, extras);
+                    int count = update(attributionSource, url, values, extras);
 
                     reply.writeNoException();
                     reply.writeInt(count);
@@ -237,16 +238,15 @@
                 case OPEN_FILE_TRANSACTION:
                 {
                     data.enforceInterface(IContentProvider.descriptor);
-                    String callingPkg = data.readString();
-                    String featureId = data.readString();
+                    AttributionSource attributionSource = AttributionSource.CREATOR
+                            .createFromParcel(data);
                     Uri url = Uri.CREATOR.createFromParcel(data);
                     String mode = data.readString();
                     ICancellationSignal signal = ICancellationSignal.Stub.asInterface(
                             data.readStrongBinder());
-                    IBinder callerToken = data.readStrongBinder();
 
                     ParcelFileDescriptor fd;
-                    fd = openFile(callingPkg, featureId, url, mode, signal, callerToken);
+                    fd = openFile(attributionSource, url, mode, signal);
                     reply.writeNoException();
                     if (fd != null) {
                         reply.writeInt(1);
@@ -261,15 +261,15 @@
                 case OPEN_ASSET_FILE_TRANSACTION:
                 {
                     data.enforceInterface(IContentProvider.descriptor);
-                    String callingPkg = data.readString();
-                    String featureId = data.readString();
+                    AttributionSource attributionSource = AttributionSource.CREATOR
+                            .createFromParcel(data);
                     Uri url = Uri.CREATOR.createFromParcel(data);
                     String mode = data.readString();
                     ICancellationSignal signal = ICancellationSignal.Stub.asInterface(
                             data.readStrongBinder());
 
                     AssetFileDescriptor fd;
-                    fd = openAssetFile(callingPkg, featureId, url, mode, signal);
+                    fd = openAssetFile(attributionSource, url, mode, signal);
                     reply.writeNoException();
                     if (fd != null) {
                         reply.writeInt(1);
@@ -285,14 +285,14 @@
                 {
                     data.enforceInterface(IContentProvider.descriptor);
 
-                    String callingPkg = data.readString();
-                    String featureId = data.readString();
+                    AttributionSource attributionSource = AttributionSource.CREATOR
+                            .createFromParcel(data);
                     String authority = data.readString();
                     String method = data.readString();
                     String stringArg = data.readString();
                     Bundle extras = data.readBundle();
 
-                    Bundle responseBundle = call(callingPkg, featureId, authority, method,
+                    Bundle responseBundle = call(attributionSource, authority, method,
                             stringArg, extras);
 
                     reply.writeNoException();
@@ -315,8 +315,8 @@
                 case OPEN_TYPED_ASSET_FILE_TRANSACTION:
                 {
                     data.enforceInterface(IContentProvider.descriptor);
-                    String callingPkg = data.readString();
-                    String featureId = data.readString();
+                    AttributionSource attributionSource = AttributionSource.CREATOR
+                            .createFromParcel(data);
                     Uri url = Uri.CREATOR.createFromParcel(data);
                     String mimeType = data.readString();
                     Bundle opts = data.readBundle();
@@ -324,7 +324,7 @@
                             data.readStrongBinder());
 
                     AssetFileDescriptor fd;
-                    fd = openTypedAssetFile(callingPkg, featureId, url, mimeType, opts, signal);
+                    fd = openTypedAssetFile(attributionSource, url, mimeType, opts, signal);
                     reply.writeNoException();
                     if (fd != null) {
                         reply.writeInt(1);
@@ -349,11 +349,11 @@
                 case CANONICALIZE_TRANSACTION:
                 {
                     data.enforceInterface(IContentProvider.descriptor);
-                    String callingPkg = data.readString();
-                    String featureId = data.readString();
+                    AttributionSource attributionSource = AttributionSource.CREATOR
+                            .createFromParcel(data);
                     Uri url = Uri.CREATOR.createFromParcel(data);
 
-                    Uri out = canonicalize(callingPkg, featureId, url);
+                    Uri out = canonicalize(attributionSource, url);
                     reply.writeNoException();
                     Uri.writeToParcel(reply, out);
                     return true;
@@ -361,22 +361,22 @@
 
                 case CANONICALIZE_ASYNC_TRANSACTION: {
                     data.enforceInterface(IContentProvider.descriptor);
-                    String callingPkg = data.readString();
-                    String featureId = data.readString();
+                    AttributionSource attributionSource = AttributionSource.CREATOR
+                            .createFromParcel(data);
                     Uri uri = Uri.CREATOR.createFromParcel(data);
                     RemoteCallback callback = RemoteCallback.CREATOR.createFromParcel(data);
-                    canonicalizeAsync(callingPkg, featureId, uri, callback);
+                    canonicalizeAsync(attributionSource, uri, callback);
                     return true;
                 }
 
                 case UNCANONICALIZE_TRANSACTION:
                 {
                     data.enforceInterface(IContentProvider.descriptor);
-                    String callingPkg = data.readString();
-                    String featureId = data.readString();
+                    AttributionSource attributionSource = AttributionSource.CREATOR
+                            .createFromParcel(data);
                     Uri url = Uri.CREATOR.createFromParcel(data);
 
-                    Uri out = uncanonicalize(callingPkg, featureId, url);
+                    Uri out = uncanonicalize(attributionSource, url);
                     reply.writeNoException();
                     Uri.writeToParcel(reply, out);
                     return true;
@@ -384,24 +384,24 @@
 
                 case UNCANONICALIZE_ASYNC_TRANSACTION: {
                     data.enforceInterface(IContentProvider.descriptor);
-                    String callingPkg = data.readString();
-                    String featureId = data.readString();
+                    AttributionSource attributionSource = AttributionSource.CREATOR
+                            .createFromParcel(data);
                     Uri uri = Uri.CREATOR.createFromParcel(data);
                     RemoteCallback callback = RemoteCallback.CREATOR.createFromParcel(data);
-                    uncanonicalizeAsync(callingPkg, featureId, uri, callback);
+                    uncanonicalizeAsync(attributionSource, uri, callback);
                     return true;
                 }
 
                 case REFRESH_TRANSACTION: {
                     data.enforceInterface(IContentProvider.descriptor);
-                    String callingPkg = data.readString();
-                    String featureId = data.readString();
+                    AttributionSource attributionSource = AttributionSource.CREATOR
+                            .createFromParcel(data);
                     Uri url = Uri.CREATOR.createFromParcel(data);
                     Bundle extras = data.readBundle();
                     ICancellationSignal signal = ICancellationSignal.Stub.asInterface(
                             data.readStrongBinder());
 
-                    boolean out = refresh(callingPkg, featureId, url, extras, signal);
+                    boolean out = refresh(attributionSource, url, extras, signal);
                     reply.writeNoException();
                     reply.writeInt(out ? 0 : -1);
                     return true;
@@ -409,13 +409,13 @@
 
                 case CHECK_URI_PERMISSION_TRANSACTION: {
                     data.enforceInterface(IContentProvider.descriptor);
-                    String callingPkg = data.readString();
-                    String featureId = data.readString();
+                    AttributionSource attributionSource = AttributionSource.CREATOR
+                            .createFromParcel(data);
                     Uri uri = Uri.CREATOR.createFromParcel(data);
                     int uid = data.readInt();
                     int modeFlags = data.readInt();
 
-                    int out = checkUriPermission(callingPkg, featureId, uri, uid, modeFlags);
+                    int out = checkUriPermission(attributionSource, uri, uid, modeFlags);
                     reply.writeNoException();
                     reply.writeInt(out);
                     return true;
@@ -451,7 +451,7 @@
     }
 
     @Override
-    public Cursor query(String callingPkg, @Nullable String featureId, Uri url,
+    public Cursor query(@NonNull AttributionSource attributionSource, Uri url,
             @Nullable String[] projection, @Nullable Bundle queryArgs,
             @Nullable ICancellationSignal cancellationSignal)
             throws RemoteException {
@@ -461,8 +461,7 @@
         try {
             data.writeInterfaceToken(IContentProvider.descriptor);
 
-            data.writeString(callingPkg);
-            data.writeString(featureId);
+            attributionSource.writeToParcel(data, 0);
             url.writeToParcel(data, 0);
             int length = 0;
             if (projection != null) {
@@ -540,7 +539,7 @@
     }
 
     @Override
-    public Uri insert(String callingPkg, @Nullable String featureId, Uri url,
+    public Uri insert(@NonNull AttributionSource attributionSource, Uri url,
             ContentValues values, Bundle extras) throws RemoteException
     {
         Parcel data = Parcel.obtain();
@@ -548,8 +547,7 @@
         try {
             data.writeInterfaceToken(IContentProvider.descriptor);
 
-            data.writeString(callingPkg);
-            data.writeString(featureId);
+            attributionSource.writeToParcel(data, 0);
             url.writeToParcel(data, 0);
             values.writeToParcel(data, 0);
             data.writeBundle(extras);
@@ -566,15 +564,14 @@
     }
 
     @Override
-    public int bulkInsert(String callingPkg, @Nullable String featureId, Uri url,
+    public int bulkInsert(@NonNull AttributionSource attributionSource, Uri url,
             ContentValues[] values) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         try {
             data.writeInterfaceToken(IContentProvider.descriptor);
 
-            data.writeString(callingPkg);
-            data.writeString(featureId);
+            attributionSource.writeToParcel(data, 0);
             url.writeToParcel(data, 0);
             data.writeTypedArray(values, 0);
 
@@ -590,15 +587,14 @@
     }
 
     @Override
-    public ContentProviderResult[] applyBatch(String callingPkg, @Nullable String featureId,
+    public ContentProviderResult[] applyBatch(@NonNull AttributionSource attributionSource,
             String authority, ArrayList<ContentProviderOperation> operations)
             throws RemoteException, OperationApplicationException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         try {
             data.writeInterfaceToken(IContentProvider.descriptor);
-            data.writeString(callingPkg);
-            data.writeString(featureId);
+            attributionSource.writeToParcel(data, 0);
             data.writeString(authority);
             data.writeInt(operations.size());
             for (ContentProviderOperation operation : operations) {
@@ -617,15 +613,14 @@
     }
 
     @Override
-    public int delete(String callingPkg, @Nullable String featureId, Uri url, Bundle extras)
+    public int delete(@NonNull AttributionSource attributionSource, Uri url, Bundle extras)
             throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         try {
             data.writeInterfaceToken(IContentProvider.descriptor);
 
-            data.writeString(callingPkg);
-            data.writeString(featureId);
+            attributionSource.writeToParcel(data, 0);
             url.writeToParcel(data, 0);
             data.writeBundle(extras);
 
@@ -641,15 +636,14 @@
     }
 
     @Override
-    public int update(String callingPkg, @Nullable String featureId, Uri url,
+    public int update(@NonNull AttributionSource attributionSource, Uri url,
             ContentValues values, Bundle extras) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         try {
             data.writeInterfaceToken(IContentProvider.descriptor);
 
-            data.writeString(callingPkg);
-            data.writeString(featureId);
+            attributionSource.writeToParcel(data, 0);
             url.writeToParcel(data, 0);
             values.writeToParcel(data, 0);
             data.writeBundle(extras);
@@ -666,20 +660,18 @@
     }
 
     @Override
-    public ParcelFileDescriptor openFile(String callingPkg, @Nullable String featureId, Uri url,
-            String mode, ICancellationSignal signal, IBinder token)
+    public ParcelFileDescriptor openFile(@NonNull AttributionSource attributionSource, Uri url,
+            String mode, ICancellationSignal signal)
             throws RemoteException, FileNotFoundException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         try {
             data.writeInterfaceToken(IContentProvider.descriptor);
 
-            data.writeString(callingPkg);
-            data.writeString(featureId);
+            attributionSource.writeToParcel(data, 0);
             url.writeToParcel(data, 0);
             data.writeString(mode);
             data.writeStrongBinder(signal != null ? signal.asBinder() : null);
-            data.writeStrongBinder(token);
 
             mRemote.transact(IContentProvider.OPEN_FILE_TRANSACTION, data, reply, 0);
 
@@ -695,7 +687,7 @@
     }
 
     @Override
-    public AssetFileDescriptor openAssetFile(String callingPkg, @Nullable String featureId,
+    public AssetFileDescriptor openAssetFile(@NonNull AttributionSource attributionSource,
             Uri url, String mode, ICancellationSignal signal)
             throws RemoteException, FileNotFoundException {
         Parcel data = Parcel.obtain();
@@ -703,8 +695,7 @@
         try {
             data.writeInterfaceToken(IContentProvider.descriptor);
 
-            data.writeString(callingPkg);
-            data.writeString(featureId);
+            attributionSource.writeToParcel(data, 0);
             url.writeToParcel(data, 0);
             data.writeString(mode);
             data.writeStrongBinder(signal != null ? signal.asBinder() : null);
@@ -723,15 +714,14 @@
     }
 
     @Override
-    public Bundle call(String callingPkg, @Nullable String featureId, String authority,
+    public Bundle call(@NonNull AttributionSource attributionSource, String authority,
             String method, String request, Bundle extras) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         try {
             data.writeInterfaceToken(IContentProvider.descriptor);
 
-            data.writeString(callingPkg);
-            data.writeString(featureId);
+            attributionSource.writeToParcel(data, 0);
             data.writeString(authority);
             data.writeString(method);
             data.writeString(request);
@@ -771,7 +761,7 @@
     }
 
     @Override
-    public AssetFileDescriptor openTypedAssetFile(String callingPkg, @Nullable String featureId,
+    public AssetFileDescriptor openTypedAssetFile(@NonNull AttributionSource attributionSource,
             Uri url, String mimeType, Bundle opts, ICancellationSignal signal)
             throws RemoteException, FileNotFoundException {
         Parcel data = Parcel.obtain();
@@ -779,8 +769,7 @@
         try {
             data.writeInterfaceToken(IContentProvider.descriptor);
 
-            data.writeString(callingPkg);
-            data.writeString(featureId);
+            attributionSource.writeToParcel(data, 0);
             url.writeToParcel(data, 0);
             data.writeString(mimeType);
             data.writeBundle(opts);
@@ -820,15 +809,14 @@
     }
 
     @Override
-    public Uri canonicalize(String callingPkg, @Nullable String featureId, Uri url)
+    public Uri canonicalize(@NonNull AttributionSource attributionSource, Uri url)
             throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         try {
             data.writeInterfaceToken(IContentProvider.descriptor);
 
-            data.writeString(callingPkg);
-            data.writeString(featureId);
+            attributionSource.writeToParcel(data, 0);
             url.writeToParcel(data, 0);
 
             mRemote.transact(IContentProvider.CANONICALIZE_TRANSACTION, data, reply, 0);
@@ -843,14 +831,13 @@
     }
 
     @Override
-    /* oneway */ public void canonicalizeAsync(String callingPkg, @Nullable String featureId,
+    /* oneway */ public void canonicalizeAsync(@NonNull AttributionSource attributionSource,
             Uri uri, RemoteCallback callback) throws RemoteException {
         Parcel data = Parcel.obtain();
         try {
             data.writeInterfaceToken(IContentProvider.descriptor);
 
-            data.writeString(callingPkg);
-            data.writeString(featureId);
+            attributionSource.writeToParcel(data, 0);
             uri.writeToParcel(data, 0);
             callback.writeToParcel(data, 0);
 
@@ -862,15 +849,14 @@
     }
 
     @Override
-    public Uri uncanonicalize(String callingPkg, @Nullable String featureId, Uri url)
+    public Uri uncanonicalize(@NonNull AttributionSource attributionSource, Uri url)
             throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         try {
             data.writeInterfaceToken(IContentProvider.descriptor);
 
-            data.writeString(callingPkg);
-            data.writeString(featureId);
+            attributionSource.writeToParcel(data, 0);
             url.writeToParcel(data, 0);
 
             mRemote.transact(IContentProvider.UNCANONICALIZE_TRANSACTION, data, reply, 0);
@@ -885,14 +871,13 @@
     }
 
     @Override
-    /* oneway */ public void uncanonicalizeAsync(String callingPkg, @Nullable String featureId,
+    /* oneway */ public void uncanonicalizeAsync(@NonNull AttributionSource attributionSource,
             Uri uri, RemoteCallback callback) throws RemoteException {
         Parcel data = Parcel.obtain();
         try {
             data.writeInterfaceToken(IContentProvider.descriptor);
 
-            data.writeString(callingPkg);
-            data.writeString(featureId);
+            attributionSource.writeToParcel(data, 0);
             uri.writeToParcel(data, 0);
             callback.writeToParcel(data, 0);
 
@@ -904,15 +889,14 @@
     }
 
     @Override
-    public boolean refresh(String callingPkg, @Nullable String featureId, Uri url, Bundle extras,
+    public boolean refresh(@NonNull AttributionSource attributionSource, Uri url, Bundle extras,
             ICancellationSignal signal) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         try {
             data.writeInterfaceToken(IContentProvider.descriptor);
 
-            data.writeString(callingPkg);
-            data.writeString(featureId);
+            attributionSource.writeToParcel(data, 0);
             url.writeToParcel(data, 0);
             data.writeBundle(extras);
             data.writeStrongBinder(signal != null ? signal.asBinder() : null);
@@ -929,15 +913,14 @@
     }
 
     @Override
-    public int checkUriPermission(String callingPkg, @Nullable String featureId, Uri url, int uid,
+    public int checkUriPermission(@NonNull AttributionSource attributionSource, Uri url, int uid,
             int modeFlags) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         try {
             data.writeInterfaceToken(IContentProvider.descriptor);
 
-            data.writeString(callingPkg);
-            data.writeString(featureId);
+            attributionSource.writeToParcel(data, 0);
             url.writeToParcel(data, 0);
             data.writeInt(uid);
             data.writeInt(modeFlags);
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 8ea417f..14b2a65 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -816,7 +816,6 @@
     public ContentResolver(@Nullable Context context, @Nullable ContentInterface wrapped) {
         mContext = context != null ? context : ActivityThread.currentApplication();
         mPackageName = mContext.getOpPackageName();
-        mAttributionTag = mContext.getAttributionTag();
         mTargetSdkVersion = mContext.getApplicationInfo().targetSdkVersion;
         mWrapped = wrapped;
     }
@@ -1217,7 +1216,7 @@
                 cancellationSignal.setRemote(remoteCancellationSignal);
             }
             try {
-                qCursor = unstableProvider.query(mPackageName, mAttributionTag, uri, projection,
+                qCursor = unstableProvider.query(mContext.getAttributionSource(), uri, projection,
                         queryArgs, remoteCancellationSignal);
             } catch (DeadObjectException e) {
                 // The remote process has died...  but we only hold an unstable
@@ -1228,7 +1227,7 @@
                 if (stableProvider == null) {
                     return null;
                 }
-                qCursor = stableProvider.query(mPackageName, mAttributionTag, uri, projection,
+                qCursor = stableProvider.query(mContext.getAttributionSource(), uri, projection,
                         queryArgs, remoteCancellationSignal);
             }
             if (qCursor == null) {
@@ -1320,7 +1319,7 @@
 
         try {
             final UriResultListener resultListener = new UriResultListener();
-            provider.canonicalizeAsync(mPackageName, mAttributionTag, url,
+            provider.canonicalizeAsync(mContext.getAttributionSource(), url,
                     new RemoteCallback(resultListener));
             resultListener.waitForResult(CONTENT_PROVIDER_TIMEOUT_MILLIS);
             if (resultListener.exception != null) {
@@ -1371,7 +1370,7 @@
 
         try {
             final UriResultListener resultListener = new UriResultListener();
-            provider.uncanonicalizeAsync(mPackageName, mAttributionTag, url,
+            provider.uncanonicalizeAsync(mContext.getAttributionSource(), url,
                     new RemoteCallback(resultListener));
             resultListener.waitForResult(CONTENT_PROVIDER_TIMEOUT_MILLIS);
             if (resultListener.exception != null) {
@@ -1429,7 +1428,7 @@
                 remoteCancellationSignal = provider.createCancellationSignal();
                 cancellationSignal.setRemote(remoteCancellationSignal);
             }
-            return provider.refresh(mPackageName, mAttributionTag, url, extras,
+            return provider.refresh(mContext.getAttributionSource(), url, extras,
                     remoteCancellationSignal);
         } catch (RemoteException e) {
             // Arbitrary and not worth documenting, as Activity
@@ -1858,7 +1857,7 @@
 
                     try {
                         fd = unstableProvider.openAssetFile(
-                                mPackageName, mAttributionTag, uri, mode,
+                                mContext.getAttributionSource(), uri, mode,
                                 remoteCancellationSignal);
                         if (fd == null) {
                             // The provider will be released by the finally{} clause
@@ -1873,8 +1872,8 @@
                         if (stableProvider == null) {
                             throw new FileNotFoundException("No content provider: " + uri);
                         }
-                        fd = stableProvider.openAssetFile(
-                                mPackageName, mAttributionTag, uri, mode, remoteCancellationSignal);
+                        fd = stableProvider.openAssetFile(mContext.getAttributionSource(),
+                                uri, mode, remoteCancellationSignal);
                         if (fd == null) {
                             // The provider will be released by the finally{} clause
                             return null;
@@ -2025,7 +2024,7 @@
 
             try {
                 fd = unstableProvider.openTypedAssetFile(
-                        mPackageName, mAttributionTag, uri, mimeType, opts,
+                        mContext.getAttributionSource(), uri, mimeType, opts,
                         remoteCancellationSignal);
                 if (fd == null) {
                     // The provider will be released by the finally{} clause
@@ -2041,7 +2040,7 @@
                     throw new FileNotFoundException("No content provider: " + uri);
                 }
                 fd = stableProvider.openTypedAssetFile(
-                        mPackageName, mAttributionTag, uri, mimeType, opts,
+                        mContext.getAttributionSource(), uri, mimeType, opts,
                         remoteCancellationSignal);
                 if (fd == null) {
                     // The provider will be released by the finally{} clause
@@ -2190,7 +2189,7 @@
         }
         try {
             long startTime = SystemClock.uptimeMillis();
-            Uri createdRow = provider.insert(mPackageName, mAttributionTag, url, values, extras);
+            Uri createdRow = provider.insert(mContext.getAttributionSource(), url, values, extras);
             long durationMillis = SystemClock.uptimeMillis() - startTime;
             maybeLogUpdateToEventLog(durationMillis, url, "insert", null /* where */);
             return createdRow;
@@ -2271,7 +2270,7 @@
         }
         try {
             long startTime = SystemClock.uptimeMillis();
-            int rowsCreated = provider.bulkInsert(mPackageName, mAttributionTag, url, values);
+            int rowsCreated = provider.bulkInsert(mContext.getAttributionSource(), url, values);
             long durationMillis = SystemClock.uptimeMillis() - startTime;
             maybeLogUpdateToEventLog(durationMillis, url, "bulkinsert", null /* where */);
             return rowsCreated;
@@ -2330,7 +2329,7 @@
         }
         try {
             long startTime = SystemClock.uptimeMillis();
-            int rowsDeleted = provider.delete(mPackageName, mAttributionTag, url, extras);
+            int rowsDeleted = provider.delete(mContext.getAttributionSource(), url, extras);
             long durationMillis = SystemClock.uptimeMillis() - startTime;
             maybeLogUpdateToEventLog(durationMillis, url, "delete", null);
             return rowsDeleted;
@@ -2397,7 +2396,8 @@
         }
         try {
             long startTime = SystemClock.uptimeMillis();
-            int rowsUpdated = provider.update(mPackageName, mAttributionTag, uri, values, extras);
+            int rowsUpdated = provider.update(mContext.getAttributionSource(),
+                    uri, values, extras);
             long durationMillis = SystemClock.uptimeMillis() - startTime;
             maybeLogUpdateToEventLog(durationMillis, uri, "update", null);
             return rowsUpdated;
@@ -2446,8 +2446,8 @@
             throw new IllegalArgumentException("Unknown authority " + authority);
         }
         try {
-            final Bundle res = provider.call(mPackageName, mAttributionTag, authority, method, arg,
-                    extras);
+            final Bundle res = provider.call(mContext.getAttributionSource(),
+                    authority, method, arg, extras);
             Bundle.setDefusable(res, true);
             return res;
         } catch (RemoteException e) {
@@ -3866,12 +3866,17 @@
     /** @hide */
     @UnsupportedAppUsage
     public String getPackageName() {
-        return mPackageName;
+        return mContext.getOpPackageName();
     }
 
     /** @hide */
     public @Nullable String getAttributionTag() {
-        return mAttributionTag;
+        return mContext.getAttributionTag();
+    }
+
+    /** @hide */
+    public @NonNull AttributionSource getAttributionSource() {
+        return mContext.getAttributionSource();
     }
 
     @UnsupportedAppUsage
@@ -3881,7 +3886,6 @@
 
     @UnsupportedAppUsage
     final String mPackageName;
-    final @Nullable String mAttributionTag;
     final int mTargetSdkVersion;
     final ContentInterface mWrapped;
 
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 64ca92f..8531d34 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -81,6 +81,7 @@
 import android.view.autofill.AutofillManager.AutofillClient;
 import android.view.contentcapture.ContentCaptureManager.ContentCaptureClient;
 import android.view.textclassifier.TextClassificationManager;
+import android.window.WindowContext;
 
 import com.android.internal.compat.IPlatformCompat;
 import com.android.internal.compat.IPlatformCompatNative;
@@ -395,7 +396,7 @@
      *
      * @hide
      */
-    public static final int BIND_ALLOW_NETWORK_ACCESS = 0x00020000;
+    public static final int BIND_BYPASS_POWER_NETWORK_RESTRICTIONS = 0x00020000;
 
     /**
      * Flag for {@link #bindService}: allow background foreground service starts from the bound
@@ -655,12 +656,21 @@
     /**
      * Add a new {@link ComponentCallbacks} to the base application of the
      * Context, which will be called at the same times as the ComponentCallbacks
-     * methods of activities and other components are called.  Note that you
+     * methods of activities and other components are called. Note that you
      * <em>must</em> be sure to use {@link #unregisterComponentCallbacks} when
      * appropriate in the future; this will not be removed for you.
+     * <p>
+     * After {@link Build.VERSION_CODES#S}, Registering the ComponentCallbacks to Context created
+     * via {@link #createWindowContext(int, Bundle)} or
+     * {@link #createWindowContext(Display, int, Bundle)} will receive
+     * {@link ComponentCallbacks#onConfigurationChanged(Configuration)} from Window Context rather
+     * than its base application. It is helpful if you want to handle UI components that
+     * associated with the Window Context when the Window Context has configuration changes.</p>
      *
      * @param callback The interface to call.  This can be either a
      * {@link ComponentCallbacks} or {@link ComponentCallbacks2} interface.
+     *
+     * @see Context#createWindowContext(int, Bundle)
      */
     public void registerComponentCallbacks(ComponentCallbacks callback) {
         getApplicationContext().registerComponentCallbacks(callback);
@@ -879,6 +889,15 @@
         return null;
     }
 
+    /**
+     * @return The identity of this context for permission purposes.
+     *
+     * @see AttributionSource
+     */
+    public @NonNull AttributionSource getAttributionSource() {
+        return null;
+    }
+
     // TODO moltmann: Remove
     /**
      * @removed
@@ -6358,6 +6377,16 @@
      * windowContext.getSystemService(WindowManager.class).addView(overlayView, mParams);
      * </pre>
      * <p>
+     * After {@link Build.VERSION_CODES#S}, window context provides the capability to listen to its
+     * {@link Configuration} changes by calling
+     * {@link #registerComponentCallbacks(ComponentCallbacks)}, while other kinds of {@link Context}
+     * will register the {@link ComponentCallbacks} to {@link #getApplicationContext() its
+     * Application context}. Note that window context only propagate
+     * {@link ComponentCallbacks#onConfigurationChanged(Configuration)} callback.
+     * {@link ComponentCallbacks#onLowMemory()} or other callbacks in {@link ComponentCallbacks2}
+     * won't be invoked.
+     * </p>
+     * <p>
      * Note that using {@link android.app.Application} or {@link android.app.Service} context for
      * UI-related queries may result in layout or continuity issues on devices with variable screen
      * sizes (e.g. foldables) or in multi-window modes, since these non-UI contexts may not reflect
@@ -6445,8 +6474,10 @@
      * @removed
      */
     @Deprecated
-    public @NonNull Context createFeatureContext(@Nullable String featureId) {
-        return createAttributionContext(featureId);
+    public @NonNull Context createFeatureContext(@Nullable String attributionTag) {
+        return createContext(new ContextParams.Builder()
+                .setAttributionTag(attributionTag)
+                .build());
     }
 
     /**
@@ -6774,4 +6805,15 @@
     public boolean isUiContext() {
         throw new RuntimeException("Not implemented. Must override in a subclass.");
     }
+
+    /**
+     * Called when a {@link Context} is going to be released.
+     * This method can be overridden to perform the final cleanups, such as release
+     * {@link BroadcastReceiver} registrations.
+     *
+     * @see WindowContext#destroy()
+     *
+     * @hide
+     */
+    public void destroy() { }
 }
diff --git a/core/java/android/content/ContextParams.java b/core/java/android/content/ContextParams.java
index fad905b..2b2db8f 100644
--- a/core/java/android/content/ContextParams.java
+++ b/core/java/android/content/ContextParams.java
@@ -19,7 +19,6 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
-import android.annotation.SuppressLint;
 import android.annotation.SystemApi;
 
 import java.util.Collections;
@@ -38,36 +37,26 @@
  * is an arbitrary string your app specifies for the purposes of tracking permission
  * accesses from a given portion of your app; against another package and optionally
  * its attribution tag if you are accessing the data on behalf of another app and
- * you will be passing that data to this app. Both attributions are not mutually
- * exclusive.
- *
- * <p>For example if you have a feature "foo" in your app which accesses
- * permissions on behalf of app "foo.bar.baz" with feature "bar" you need to
- * create a context like this:
- *
- * <pre class="prettyprint">
- * context.createContext(new ContextParams.Builder()
- *     .setAttributionTag("foo")
- *     .setReceiverPackage("foo.bar.baz", "bar")
- *     .build())
- * </pre>
+ * you will be passing that data to this app, recursively. Both attributions are
+ * not mutually exclusive.
  *
  * @see Context#createContext(ContextParams)
+ * @see AttributionSource
  */
 public final class ContextParams {
-    private final String mAttributionTag;
-    private final String mReceiverPackage;
-    private final String mReceiverAttributionTag;
-    private final Set<String> mRenouncedPermissions;
+    private final @Nullable String mAttributionTag;
+    private final @Nullable AttributionSource mNext;
+    private final @NonNull Set<String> mRenouncedPermissions;
 
     /** {@hide} */
     public static final ContextParams EMPTY = new ContextParams.Builder().build();
 
-    private ContextParams(@NonNull ContextParams.Builder builder) {
-        mAttributionTag = builder.mAttributionTag;
-        mReceiverPackage = builder.mReceiverPackage;
-        mReceiverAttributionTag = builder.mReceiverAttributionTag;
-        mRenouncedPermissions = builder.mRenouncedPermissions;
+    private ContextParams(@Nullable String attributionTag,
+            @Nullable AttributionSource next,
+            @NonNull Set<String> renouncedPermissions) {
+        mAttributionTag = attributionTag;
+        mNext = next;
+        mRenouncedPermissions = renouncedPermissions;
     }
 
     /**
@@ -79,45 +68,35 @@
     }
 
     /**
-     * @return The receiving package.
-     */
-    @Nullable
-    public String getReceiverPackage() {
-        return mReceiverPackage;
-    }
-
-    /**
-     * @return The receiving package's attribution tag.
-     */
-    @Nullable
-    public String getReceiverAttributionTag() {
-        return mReceiverAttributionTag;
-    }
-
-    /**
      * @return The set of permissions to treat as renounced.
      * @hide
      */
     @SystemApi
-    @SuppressLint("NullableCollection")
     @RequiresPermission(android.Manifest.permission.RENOUNCE_PERMISSIONS)
-    public @Nullable Set<String> getRenouncedPermissions() {
+    public @NonNull Set<String> getRenouncedPermissions() {
         return mRenouncedPermissions;
     }
 
     /** @hide */
     public boolean isRenouncedPermission(@NonNull String permission) {
-        return mRenouncedPermissions != null && mRenouncedPermissions.contains(permission);
+        return mRenouncedPermissions.contains(permission);
+    }
+
+    /**
+     * @return The receiving attribution source.
+     */
+    @Nullable
+    public AttributionSource getNextAttributionSource() {
+        return mNext;
     }
 
     /**
      * Builder for creating a {@link ContextParams}.
      */
     public static final class Builder {
-        private String mAttributionTag;
-        private String mReceiverPackage;
-        private String mReceiverAttributionTag;
-        private Set<String> mRenouncedPermissions;
+        private @Nullable String mAttributionTag;
+        private @NonNull Set<String> mRenouncedPermissions = Collections.emptySet();
+        private @Nullable AttributionSource mNext;
 
         /**
          * Create a new builder.
@@ -145,9 +124,8 @@
         public Builder(@NonNull ContextParams params) {
             Objects.requireNonNull(params);
             mAttributionTag = params.mAttributionTag;
-            mReceiverPackage = params.mReceiverPackage;
-            mReceiverAttributionTag = params.mReceiverAttributionTag;
             mRenouncedPermissions = params.mRenouncedPermissions;
+            mNext = params.mNext;
         }
 
         /**
@@ -163,18 +141,16 @@
         }
 
         /**
-         * Sets the package and its optional attribution tag that would be receiving
-         * the permission protected data.
+         * Sets the attribution source for the app on whose behalf you are doing the work.
          *
-         * @param packageName The package name receiving the permission protected data.
-         * @param attributionTag An attribution tag of the receiving package.
+         * @param next The permission identity of the receiving app.
          * @return This builder.
+         *
+         * @see AttributionSource
          */
         @NonNull
-        public Builder setReceiverPackage(@Nullable String packageName,
-                @Nullable String attributionTag) {
-            mReceiverPackage = packageName;
-            mReceiverAttributionTag = attributionTag;
+        public Builder setNextAttributionSource(@NonNull AttributionSource next) {
+            mNext = Objects.requireNonNull(next);
             return this;
         }
 
@@ -194,19 +170,16 @@
          * permissions are supported by this mechanism.
          *
          * @param renouncedPermissions The set of permissions to treat as
-         *            renounced.
+         *            renounced, which is as if not granted.
          * @return This builder.
          * @hide
          */
         @SystemApi
         @RequiresPermission(android.Manifest.permission.RENOUNCE_PERMISSIONS)
         public @NonNull Builder setRenouncedPermissions(
-                @Nullable Set<String> renouncedPermissions) {
-            if (renouncedPermissions != null) {
-                mRenouncedPermissions = Collections.unmodifiableSet(renouncedPermissions);
-            } else {
-                mRenouncedPermissions = null;
-            }
+                @NonNull Set<String> renouncedPermissions) {
+            mRenouncedPermissions = Collections.unmodifiableSet(
+                    Objects.requireNonNull(renouncedPermissions));
             return this;
         }
 
@@ -217,7 +190,8 @@
          */
         @NonNull
         public ContextParams build() {
-            return new ContextParams(this);
+            return new ContextParams(mAttributionTag, mNext,
+                    mRenouncedPermissions);
         }
     }
 }
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index 609f417..de0d65f 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -1060,6 +1060,12 @@
         return mBase.createAttributionContext(attributionTag);
     }
 
+    @NonNull
+    @Override
+    public AttributionSource getAttributionSource() {
+        return mBase.getAttributionSource();
+    }
+
     @Override
     public boolean isRestricted() {
         return mBase.isRestricted();
diff --git a/core/java/android/content/IContentProvider.java b/core/java/android/content/IContentProvider.java
index 9210b13..e0315a3 100644
--- a/core/java/android/content/IContentProvider.java
+++ b/core/java/android/content/IContentProvider.java
@@ -16,11 +16,13 @@
 
 package android.content;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.res.AssetFileDescriptor;
 import android.database.Cursor;
 import android.net.Uri;
+import android.os.Binder;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.IBinder;
@@ -38,11 +40,11 @@
  * @hide
  */
 public interface IContentProvider extends IInterface {
-    public Cursor query(String callingPkg, @Nullable String attributionTag, Uri url,
+    Cursor query(@NonNull AttributionSource attributionSource, Uri url,
             @Nullable String[] projection,
             @Nullable Bundle queryArgs, @Nullable ICancellationSignal cancellationSignal)
             throws RemoteException;
-    public String getType(Uri url) throws RemoteException;
+    String getType(Uri url) throws RemoteException;
 
     /**
      * A oneway version of getType. The functionality is exactly the same, except that the
@@ -55,54 +57,56 @@
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "Use {@link "
             + "ContentProviderClient#insert(android.net.Uri, android.content.ContentValues)} "
             + "instead")
-    public default Uri insert(String callingPkg, Uri url, ContentValues initialValues)
+    default Uri insert(String callingPkg, Uri url, ContentValues initialValues)
             throws RemoteException {
-        return insert(callingPkg, null, url, initialValues, null);
+        return insert(new AttributionSource(Binder.getCallingUid(), callingPkg, null),
+                url, initialValues, null);
     }
-    public Uri insert(String callingPkg, String attributionTag, Uri url,
+    Uri insert(@NonNull AttributionSource attributionSource, Uri url,
             ContentValues initialValues, Bundle extras) throws RemoteException;
     @Deprecated
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "Use {@link "
             + "ContentProviderClient#bulkInsert(android.net.Uri, android.content.ContentValues[])"
             + "} instead")
-    public default int bulkInsert(String callingPkg, Uri url, ContentValues[] initialValues)
+    default int bulkInsert(String callingPkg, Uri url, ContentValues[] initialValues)
             throws RemoteException {
-        return bulkInsert(callingPkg, null, url, initialValues);
+        return bulkInsert(new AttributionSource(Binder.getCallingUid(), callingPkg, null),
+                url, initialValues);
     }
-    public int bulkInsert(String callingPkg, String attributionTag, Uri url,
+    int bulkInsert(@NonNull AttributionSource attributionSource, Uri url,
             ContentValues[] initialValues) throws RemoteException;
     @Deprecated
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "Use {@link "
             + "ContentProviderClient#delete(android.net.Uri, java.lang.String, java.lang"
             + ".String[])} instead")
-    public default int delete(String callingPkg, Uri url, String selection, String[] selectionArgs)
+    default int delete(String callingPkg, Uri url, String selection, String[] selectionArgs)
             throws RemoteException {
-        return delete(callingPkg, null, url,
-                ContentResolver.createSqlQueryBundle(selection, selectionArgs));
+        return delete(new AttributionSource(Binder.getCallingUid(), callingPkg, null),
+                url, ContentResolver.createSqlQueryBundle(selection, selectionArgs));
     }
-    public int delete(String callingPkg, String attributionTag, Uri url, Bundle extras)
+    int delete(@NonNull AttributionSource attributionSource, Uri url, Bundle extras)
             throws RemoteException;
     @Deprecated
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "Use {@link "
             + "ContentProviderClient#update(android.net.Uri, android.content.ContentValues, java"
             + ".lang.String, java.lang.String[])} instead")
-    public default int update(String callingPkg, Uri url, ContentValues values, String selection,
+    default int update(String callingPkg, Uri url, ContentValues values, String selection,
             String[] selectionArgs) throws RemoteException {
-        return update(callingPkg, null, url, values,
-                ContentResolver.createSqlQueryBundle(selection, selectionArgs));
+        return update(new AttributionSource(Binder.getCallingUid(), callingPkg, null),
+                url, values, ContentResolver.createSqlQueryBundle(selection, selectionArgs));
     }
-    public int update(String callingPkg, String attributionTag, Uri url, ContentValues values,
+    int update(@NonNull AttributionSource attributionSource, Uri url, ContentValues values,
             Bundle extras) throws RemoteException;
 
-    public ParcelFileDescriptor openFile(String callingPkg, @Nullable String attributionTag,
-            Uri url, String mode, ICancellationSignal signal, IBinder callerToken)
-            throws RemoteException, FileNotFoundException;
-
-    public AssetFileDescriptor openAssetFile(String callingPkg, @Nullable String attributionTag,
+    ParcelFileDescriptor openFile(@NonNull AttributionSource attributionSource,
             Uri url, String mode, ICancellationSignal signal)
             throws RemoteException, FileNotFoundException;
 
-    public ContentProviderResult[] applyBatch(String callingPkg, @Nullable String attributionTag,
+    AssetFileDescriptor openAssetFile(@NonNull AttributionSource attributionSource,
+            Uri url, String mode, ICancellationSignal signal)
+            throws RemoteException, FileNotFoundException;
+
+    ContentProviderResult[] applyBatch(@NonNull AttributionSource attributionSource,
             String authority, ArrayList<ContentProviderOperation> operations)
             throws RemoteException, OperationApplicationException;
 
@@ -112,18 +116,19 @@
             + "instead")
     public default Bundle call(String callingPkg, String method,
             @Nullable String arg, @Nullable Bundle extras) throws RemoteException {
-        return call(callingPkg, null, "unknown", method, arg, extras);
+        return call(new AttributionSource(Binder.getCallingUid(), callingPkg, null),
+                "unknown", method, arg, extras);
     }
 
-    public Bundle call(String callingPkg, @Nullable String attributionTag, String authority,
+    Bundle call(@NonNull AttributionSource attributionSource, String authority,
             String method, @Nullable String arg, @Nullable Bundle extras) throws RemoteException;
 
-    public int checkUriPermission(String callingPkg, @Nullable String attributionTag, Uri uri,
+    int checkUriPermission(@NonNull AttributionSource attributionSource, Uri uri,
             int uid, int modeFlags) throws RemoteException;
 
-    public ICancellationSignal createCancellationSignal() throws RemoteException;
+    ICancellationSignal createCancellationSignal() throws RemoteException;
 
-    public Uri canonicalize(String callingPkg, @Nullable String attributionTag, Uri uri)
+    Uri canonicalize(@NonNull AttributionSource attributionSource, Uri uri)
             throws RemoteException;
 
     /**
@@ -131,10 +136,10 @@
      * call returns immediately, and the resulting type is returned when available via
      * a binder callback.
      */
-    void canonicalizeAsync(String callingPkg, @Nullable String attributionTag, Uri uri,
+    void canonicalizeAsync(@NonNull AttributionSource attributionSource, Uri uri,
             RemoteCallback callback) throws RemoteException;
 
-    public Uri uncanonicalize(String callingPkg, @Nullable String attributionTag, Uri uri)
+    Uri uncanonicalize(@NonNull AttributionSource attributionSource, Uri uri)
             throws RemoteException;
 
     /**
@@ -142,18 +147,17 @@
      * call returns immediately, and the resulting type is returned when available via
      * a binder callback.
      */
-    void uncanonicalizeAsync(String callingPkg, @Nullable String attributionTag, Uri uri,
+    void uncanonicalizeAsync(@NonNull AttributionSource attributionSource, Uri uri,
             RemoteCallback callback) throws RemoteException;
 
-    public boolean refresh(String callingPkg, @Nullable String attributionTag, Uri url,
+    public boolean refresh(@NonNull AttributionSource attributionSource, Uri url,
             @Nullable Bundle extras, ICancellationSignal cancellationSignal) throws RemoteException;
 
     // Data interchange.
     public String[] getStreamTypes(Uri url, String mimeTypeFilter) throws RemoteException;
 
-    public AssetFileDescriptor openTypedAssetFile(String callingPkg,
-            @Nullable String attributionTag, Uri url, String mimeType, Bundle opts,
-            ICancellationSignal signal)
+    public AssetFileDescriptor openTypedAssetFile(@NonNull AttributionSource attributionSource,
+            Uri url, String mimeType, Bundle opts, ICancellationSignal signal)
             throws RemoteException, FileNotFoundException;
 
     /* IPC constants */
diff --git a/core/java/android/content/OWNERS b/core/java/android/content/OWNERS
index d0d406a..01b554a 100644
--- a/core/java/android/content/OWNERS
+++ b/core/java/android/content/OWNERS
@@ -8,3 +8,5 @@
 per-file AutofillOptions* = file:/core/java/android/service/autofill/OWNERS
 per-file ContentCaptureOptions* = file:/core/java/android/service/contentcapture/OWNERS
 per-file LocusId* = file:/core/java/android/service/contentcapture/OWNERS
+per-file ComponentCallbacksController = file:/services/core/java/com/android/server/wm/OWNERS
+per-file ComponentCallbacksController = charlesccchen@google.com
diff --git a/core/java/android/content/PermissionChecker.java b/core/java/android/content/PermissionChecker.java
index 159db92..08eac5a 100644
--- a/core/java/android/content/PermissionChecker.java
+++ b/core/java/android/content/PermissionChecker.java
@@ -27,6 +27,8 @@
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
 
 /**
  * This class provides permission check APIs that verify both the
@@ -68,8 +70,14 @@
  * @hide
  */
 public final class PermissionChecker {
+    private static final String PLATFORM_PACKAGE_NAME = "android";
+
     /** The permission is granted. */
-    public static final int PERMISSION_GRANTED =  PackageManager.PERMISSION_GRANTED;
+    public static final int PERMISSION_GRANTED = AppOpsManager.MODE_ALLOWED;
+
+    /** Only for runtime permissions, its returned when the runtime permission
+     * is granted, but the corresponding app op is denied. */
+    public static final int PERMISSION_SOFT_DENIED = AppOpsManager.MODE_IGNORED;
 
     /** Returned when:
      * <ul>
@@ -79,15 +87,14 @@
      * </ul>
      *
      */
-    public static final int PERMISSION_HARD_DENIED =  PackageManager.PERMISSION_DENIED;
-
-    /** Only for runtime permissions, its returned when the runtime permission
-     * is granted, but the corresponding app op is denied. */
-    public static final int PERMISSION_SOFT_DENIED =  PackageManager.PERMISSION_DENIED - 1;
+    public static final int PERMISSION_HARD_DENIED = AppOpsManager.MODE_ERRORED;
 
     /** Constant when the PID for which we check permissions is unknown. */
     public static final int PID_UNKNOWN = -1;
 
+    private static final ConcurrentHashMap<String, PermissionInfo> sPlatformPermissions
+            = new ConcurrentHashMap<>();
+
     /** @hide */
     @IntDef({PERMISSION_GRANTED,
             PERMISSION_SOFT_DENIED,
@@ -131,6 +138,50 @@
      * @return The permission check result which is either {@link #PERMISSION_GRANTED}
      *     or {@link #PERMISSION_SOFT_DENIED} or {@link #PERMISSION_HARD_DENIED}.
      * @param message A message describing the reason the permission was checked
+     * @param startDataDelivery Whether this is the start of data delivery.
+     *
+     * @see #checkPermissionForPreflight(Context, String, int, int, String)
+     */
+    @PermissionResult
+    public static int checkPermissionForDataDelivery(@NonNull Context context,
+            @NonNull String permission, int pid, int uid, @Nullable String packageName,
+            @Nullable String attributionTag, @Nullable String message, boolean startDataDelivery) {
+        return checkPermissionForDataDelivery(context, permission, pid, new AttributionSource(uid,
+                packageName, attributionTag), message, startDataDelivery);
+    }
+
+    /**
+     * Checks whether a given package in a UID and PID has a given permission
+     * and whether the app op that corresponds to this permission is allowed.
+     *
+     * <strong>NOTE:</strong> Use this method only for permission checks at the
+     * point where you will deliver the permission protected data to clients.
+     *
+     * <p>For example, if an app registers a location listener it should have the location
+     * permission but no data is actually sent to the app at the moment of registration
+     * and you should use {@link #checkPermissionForPreflight(Context, String, int, int, String)}
+     * to determine if the app has or may have location permission (if app has only foreground
+     * location the grant state depends on the app's fg/gb state) and this check will not
+     * leave a trace that permission protected data was delivered. When you are about to
+     * deliver the location data to a registered listener you should use this method which
+     * will evaluate the permission access based on the current fg/bg state of the app and
+     * leave a record that the data was accessed.
+     *
+     * <p>For more details how to determine the {@code packageName}, {@code attributionTag}, and
+     * {@code message}, please check the description in
+     * {@link AppOpsManager#noteOp(String, int, String, String, String)}
+     *
+     * @param context Context for accessing resources.
+     * @param permission The permission to check.
+     * @param pid The process id for which to check. Use {@link #PID_UNKNOWN} if the PID
+     *    is not known.
+     * @param uid The uid for which to check.
+     * @param packageName The package name for which to check. If null the
+     *     the first package for the calling UID will be used.
+     * @param attributionTag attribution tag
+     * @return The permission check result which is either {@link #PERMISSION_GRANTED}
+     *     or {@link #PERMISSION_SOFT_DENIED} or {@link #PERMISSION_HARD_DENIED}.
+     * @param message A message describing the reason the permission was checked
      *
      * @see #checkPermissionForPreflight(Context, String, int, int, String)
      */
@@ -138,8 +189,303 @@
     public static int checkPermissionForDataDelivery(@NonNull Context context,
             @NonNull String permission, int pid, int uid, @Nullable String packageName,
             @Nullable String attributionTag, @Nullable String message) {
-        return checkPermissionCommon(context, permission, pid, uid, packageName, attributionTag,
-                message, true /*forDataDelivery*/);
+        return checkPermissionForDataDelivery(context, permission, pid, uid,
+                packageName, attributionTag, message, false /*startDataDelivery*/);
+    }
+
+    /**
+     * Checks whether a given data access chain described by the given {@link AttributionSource}
+     * has a given permission and whether the app op that corresponds to this permission
+     * is allowed. Call this method if you are the datasource which would not blame you for
+     * access to the data since you are the data.
+     *
+     * <strong>NOTE:</strong> Use this method only for permission checks at the
+     * point where you will deliver the permission protected data to clients.
+     *
+     * <p>For example, if an app registers a location listener it should have the location
+     * permission but no data is actually sent to the app at the moment of registration
+     * and you should use {@link #checkPermissionForPreflight(Context, String, int, int, String)}
+     * to determine if the app has or may have location permission (if app has only foreground
+     * location the grant state depends on the app's fg/gb state) and this check will not
+     * leave a trace that permission protected data was delivered. When you are about to
+     * deliver the location data to a registered listener you should use this method which
+     * will evaluate the permission access based on the current fg/bg state of the app and
+     * leave a record that the data was accessed.
+     *
+     * @param context Context for accessing resources.
+     * @param permission The permission to check.
+     * @param pid The process id for which to check. Use {@link #PID_UNKNOWN} if the PID
+     *    is not known.
+     * @param attributionSource the permission identity
+     * @return The permission check result which is either {@link #PERMISSION_GRANTED}
+     *     or {@link #PERMISSION_SOFT_DENIED} or {@link #PERMISSION_HARD_DENIED}.
+     * @param message A message describing the reason the permission was checked
+     *
+     * @see #checkPermissionForPreflight(Context, String, AttributionSource)
+     */
+    @PermissionResult
+    public static int checkPermissionForDataDeliveryFromDataSource(@NonNull Context context,
+            @NonNull String permission, int pid, @NonNull AttributionSource attributionSource,
+            @Nullable String message) {
+        return checkPermissionForDataDeliveryCommon(context, permission, pid, attributionSource,
+                message, false /*startDataDelivery*/, /*fromDatasource*/ true);
+    }
+
+    /**
+     * Checks whether a given data access chain described by the given {@link AttributionSource}
+     * has a given permission and whether the app op that corresponds to this permission
+     * is allowed.
+     *
+     * <strong>NOTE:</strong> Use this method only for permission checks at the
+     * point where you will deliver the permission protected data to clients.
+     *
+     * <p>For example, if an app registers a location listener it should have the location
+     * permission but no data is actually sent to the app at the moment of registration
+     * and you should use {@link #checkPermissionForPreflight(Context, String, AttributionSource)}
+     * to determine if the app has or may have location permission (if app has only foreground
+     * location the grant state depends on the app's fg/gb state) and this check will not
+     * leave a trace that permission protected data was delivered. When you are about to
+     * deliver the location data to a registered listener you should use this method which
+     * will evaluate the permission access based on the current fg/bg state of the app and
+     * leave a record that the data was accessed.
+     *
+     * @param context Context for accessing resources.
+     * @param permission The permission to check.
+     * @param pid The process id for which to check. Use {@link #PID_UNKNOWN} if the PID
+     *    is not known.
+     * @param attributionSource the permission identity
+     * @param message A message describing the reason the permission was checked
+     * @return The permission check result which is either {@link #PERMISSION_GRANTED}
+     *     or {@link #PERMISSION_SOFT_DENIED} or {@link #PERMISSION_HARD_DENIED}.
+     *
+     * @see #checkPermissionForPreflight(Context, String, AttributionSource)
+     */
+    @PermissionResult
+    public static int checkPermissionForDataDelivery(@NonNull Context context,
+            @NonNull String permission, int pid, @NonNull AttributionSource attributionSource,
+            @Nullable String message) {
+        return checkPermissionForDataDelivery(context, permission, pid, attributionSource,
+                message, false /*startDataDelivery*/);
+    }
+
+    /**
+     * Checks whether a given data access chain described by the given {@link AttributionSource}
+     * has a given permission and whether the app op that corresponds to this permission
+     * is allowed.
+     *
+     * <strong>NOTE:</strong> Use this method only for permission checks at the
+     * point where you will deliver the permission protected data to clients.
+     *
+     * <p>For example, if an app registers a data listener it should have the required
+     * permission but no data is actually sent to the app at the moment of registration
+     * and you should use {@link #checkPermissionForPreflight(Context, String,
+     * AttributionSource)}
+     * to determine if the app has or may have permission and this check will not
+     * leave a trace that permission protected data was delivered. When you are about to
+     * deliver the data to a registered listener you should use this method which
+     * will evaluate the permission access based on the current fg/bg state of the app and
+     * leave a record that the data was accessed.
+     *
+     * @param context Context for accessing resources.
+     * @param permission The permission to check.
+     * @param pid The process id for which to check. Use {@link #PID_UNKNOWN} if the PID
+     *    is not known.
+     * @param attributionSource The identity for which to check the permission.
+     * @param message A message describing the reason the permission was checked
+     * @param startDataDelivery Whether this is the start of data delivery.
+     * @return The permission check result which is either {@link #PERMISSION_GRANTED}
+     *     or {@link #PERMISSION_SOFT_DENIED} or {@link #PERMISSION_HARD_DENIED}.
+     *
+     * @see #checkPermissionForPreflight(Context, String, AttributionSource)
+     */
+    @PermissionResult
+    public static int checkPermissionForDataDelivery(@NonNull Context context,
+            @NonNull String permission, int pid, @NonNull AttributionSource attributionSource,
+            @Nullable String message, boolean startDataDelivery) {
+        return checkPermissionForDataDeliveryCommon(context, permission, pid, attributionSource,
+                message, startDataDelivery, /*fromDatasource*/ false);
+    }
+
+    private static int checkPermissionForDataDeliveryCommon(@NonNull Context context,
+            @NonNull String permission, int pid, @NonNull AttributionSource attributionSource,
+            @Nullable String message, boolean startDataDelivery, boolean fromDatasource) {
+        // If the check failed in the middle of the chain, finish any started op.
+        final int result = checkPermissionCommon(context, permission, attributionSource,
+                message, true /*forDataDelivery*/, startDataDelivery, fromDatasource);
+        if (startDataDelivery && result != PERMISSION_GRANTED) {
+            finishDataDelivery(context, AppOpsManager.permissionToOp(permission),
+                    attributionSource);
+        }
+        return result;
+    }
+
+    /**
+     * Checks whether a given data access chain described by the given {@link AttributionSource}
+     * has a given permission and whether the app op that corresponds to this permission
+     * is allowed. The app ops area also marked as started. This is useful for long running
+     * permissions like camera.
+     *
+     * <strong>NOTE:</strong> Use this method only for permission checks at the
+     * point where you will deliver the permission protected data to clients.
+     *
+     * <p>For example, if an app registers a data listener it should have the required
+     * permission but no data is actually sent to the app at the moment of registration
+     * and you should use {@link #checkPermissionForPreflight(Context, String,
+     * AttributionSource)}
+     * to determine if the app has or may have permission and this check will not
+     * leave a trace that permission protected data was delivered. When you are about to
+     * deliver the data to a registered listener you should use this method which
+     * will evaluate the permission access based on the current fg/bg state of the app and
+     * leave a record that the data was accessed.
+     *
+     * @param context Context for accessing resources.
+     * @param permission The permission to check.
+     * @param attributionSource The identity for which to check the permission.
+     * @param message A message describing the reason the permission was checked
+     * @return The permission check result which is either {@link #PERMISSION_GRANTED}
+     *     or {@link #PERMISSION_SOFT_DENIED} or {@link #PERMISSION_HARD_DENIED}.
+     *
+     * @see #checkPermissionForPreflight(Context, String, AttributionSource)
+     */
+    @PermissionResult
+    public static int checkPermissionAndStartDataDelivery(@NonNull Context context,
+            @NonNull String permission, @NonNull AttributionSource attributionSource,
+            @Nullable String message) {
+        return checkPermissionCommon(context, permission, attributionSource,
+                message, true /*forDataDelivery*/, /*startDataDelivery*/ true,
+                /*fromDatasource*/ false);
+    }
+
+    /**
+     * Checks whether a given data access chain described by the given {@link
+     * AttributionSource} has a given app op allowed and marks the op as started.
+     *
+     * <strong>NOTE:</strong> Use this method only for app op checks at the
+     * point where you will deliver the protected data to clients.
+     *
+     * <p>For example, if an app registers a data listener it should have the data
+     * op but no data is actually sent to the app at the moment of registration
+     * and you should use {@link #checkOpForPreflight(Context, String, AttributionSource, String)}
+     * to determine if the app has or may have op access and this check will not
+     * leave a trace that op protected data was delivered. When you are about to
+     * deliver the data to a registered listener you should use this method which
+     * will evaluate the op access based on the current fg/bg state of the app and
+     * leave a record that the data was accessed.
+     *
+     * @param context Context for accessing resources.
+     * @param opName THe op to start.
+     * @param attributionSource The identity for which to check the permission.
+     * @param message A message describing the reason the permission was checked
+     * @return The permission check result which is either {@link #PERMISSION_GRANTED}
+     *     or {@link #PERMISSION_SOFT_DENIED} or {@link #PERMISSION_HARD_DENIED}.
+     *
+     * @see #finishDataDelivery(Context, String, AttributionSource)
+     */
+    @PermissionResult
+    public static int startOpForDataDelivery(@NonNull Context context,
+            @NonNull String opName, @NonNull AttributionSource attributionSource,
+            @Nullable String message) {
+        final int result = checkOp(context, AppOpsManager.strOpToOp(opName), attributionSource,
+                message, true /*forDataDelivery*/, true /*startDataDelivery*/);
+        // It is important to finish any started op if some step in the attribution chain failed.
+        if (result != PERMISSION_GRANTED) {
+            finishDataDelivery(context, opName, attributionSource);
+        }
+        return result;
+    }
+
+    /**
+     * Finishes an ongoing op for data access chain described by the given {@link
+     * AttributionSource}.
+     *
+     * @param context Context for accessing resources.
+     * @param op The op to finish.
+     * @param attributionSource The identity for which finish op.
+     *
+     * @see #startOpForDataDelivery(Context, String, AttributionSource, String)
+     * @see #checkPermissionAndStartDataDelivery(Context, String, AttributionSource, String)
+     */
+    public static void finishDataDelivery(@NonNull Context context, @NonNull String op,
+            @NonNull AttributionSource attributionSource) {
+        if (op == null || attributionSource.getPackageName() == null) {
+            return;
+        }
+
+        final AppOpsManager appOpsManager = context.getSystemService(AppOpsManager.class);
+        appOpsManager.finishProxyOp(op, attributionSource);
+
+        if (attributionSource.getNext() != null) {
+            finishDataDelivery(context, op, attributionSource.getNext());
+        }
+    }
+
+    /**
+     * Checks whether a given data access chain described by the given {@link
+     * AttributionSource} has a given app op allowed.
+     *
+     * <strong>NOTE:</strong> Use this method only for op checks at the
+     * preflight point where you will not deliver the protected data
+     * to clients but schedule a data delivery, apps register listeners,
+     * etc.
+     *
+     * <p>For example, if an app registers a data listener it should have the op
+     * but no data is actually sent to the app at the moment of registration
+     * and you should use this method to determine if the app has or may have data
+     * access and this check will not leave a trace that protected data
+     * was delivered. When you are about to deliver the data to a registered
+     * listener you should use {@link #checkOpForDataDelivery(Context, String,
+     * AttributionSource, String)} which will evaluate the op access based
+     * on the current fg/bg state of the app and leave a record that the data was
+     * accessed.
+     *
+     * @param context Context for accessing resources.
+     * @param opName The op to check.
+     * @param attributionSource The identity for which to check the permission.
+     * @param message A message describing the reason the permission was checked
+     * @return The permission check result which is either {@link #PERMISSION_GRANTED}
+     *     or {@link #PERMISSION_SOFT_DENIED} or {@link #PERMISSION_HARD_DENIED}.
+     *
+     * @see #checkOpForDataDelivery(Context, String, AttributionSource, String)
+     */
+    @PermissionResult
+    public static int checkOpForPreflight(@NonNull Context context,
+            @NonNull String opName, @NonNull AttributionSource attributionSource,
+            @Nullable String message) {
+        return checkOp(context, AppOpsManager.strOpToOp(opName), attributionSource,
+                message,  false /*forDataDelivery*/, false /*startDataDelivery*/);
+    }
+
+    /**
+     * Checks whether a given data access chain described by the given {@link AttributionSource}
+     * has an allowed app op.
+     *
+     * <strong>NOTE:</strong> Use this method only for op checks at the
+     * point where you will deliver the permission protected data to clients.
+     *
+     * <p>For example, if an app registers a data listener it should have the data
+     * permission but no data is actually sent to the app at the moment of registration
+     * and you should use {@link #checkOpForPreflight(Context, String, AttributionSource, String)}
+     * to determine if the app has or may have data access and this check will not
+     * leave a trace that op protected data was delivered. When you are about to
+     * deliver the  data to a registered listener you should use this method which
+     * will evaluate the op access based on the current fg/bg state of the app and
+     * leave a record that the data was accessed.
+     *
+     * @param context Context for accessing resources.
+     * @param opName The op to check.
+     * @param attributionSource The identity for which to check the op.
+     * @return The permission check result which is either {@link #PERMISSION_GRANTED}
+     *     or {@link #PERMISSION_SOFT_DENIED} or {@link #PERMISSION_HARD_DENIED}.
+     * @param message A message describing the reason the permission was checked
+     *
+     * @see #checkOpForPreflight(Context, String, AttributionSource, String)
+     */
+    @PermissionResult
+    public static int checkOpForDataDelivery(@NonNull Context context,
+            @NonNull String opName, @NonNull AttributionSource attributionSource,
+            @Nullable String message) {
+        return checkOp(context, AppOpsManager.strOpToOp(opName), attributionSource,
+                message,  true /*forDataDelivery*/, false /*startDataDelivery*/);
     }
 
     /**
@@ -158,8 +504,8 @@
      * fg/gb state) and this check will not leave a trace that permission protected data
      * was delivered. When you are about to deliver the location data to a registered
      * listener you should use {@link #checkPermissionForDataDelivery(Context, String,
-     * int, int, String, String)} which will evaluate the permission access based on the current
-     * fg/bg state of the app and leave a record that the data was accessed.
+     * int, int, String, String, String)} which will evaluate the permission access based
+     * on the currentfg/bg state of the app and leave a record that the data was accessed.
      *
      * @param context Context for accessing resources.
      * @param permission The permission to check.
@@ -170,13 +516,49 @@
      * @return The permission check result which is either {@link #PERMISSION_GRANTED}
      *     or {@link #PERMISSION_SOFT_DENIED} or {@link #PERMISSION_HARD_DENIED}.
      *
-     * @see #checkPermissionForDataDelivery(Context, String, int, int, String, String)
+     * @see #checkPermissionForDataDelivery(Context, String, int, int, String, String, String)
      */
     @PermissionResult
     public static int checkPermissionForPreflight(@NonNull Context context,
             @NonNull String permission, int pid, int uid, @Nullable String packageName) {
-        return checkPermissionCommon(context, permission, pid, uid, packageName,
-                null /*attributionTag*/, null /*message*/, false /*forDataDelivery*/);
+        return checkPermissionForPreflight(context, permission, new AttributionSource(
+                uid, packageName, null /*attributionTag*/));
+    }
+
+    /**
+     * Checks whether a given data access chain described by the given {@link AttributionSource}
+     * has a given permission and whether the app op that corresponds to this permission
+     * is allowed.
+     *
+     * <strong>NOTE:</strong> Use this method only for permission checks at the
+     * preflight point where you will not deliver the permission protected data
+     * to clients but schedule permission data delivery, apps register listeners,
+     * etc.
+     *
+     * <p>For example, if an app registers a data listener it should have the required
+     * permission but no data is actually sent to the app at the moment of registration
+     * and you should use this method to determine if the app has or may have the
+     * permission and this check will not leave a trace that permission protected data
+     * was delivered. When you are about to deliver the protected data to a registered
+     * listener you should use {@link #checkPermissionForDataDelivery(Context, String,
+     * int, AttributionSource, String, boolean)} which will evaluate the permission access based
+     * on the current fg/bg state of the app and leave a record that the data was accessed.
+     *
+     * @param context Context for accessing resources.
+     * @param permission The permission to check.
+     * @param attributionSource The identity for which to check the permission.
+     * @return The permission check result which is either {@link #PERMISSION_GRANTED}
+     *     or {@link #PERMISSION_SOFT_DENIED} or {@link #PERMISSION_HARD_DENIED}.
+     *
+     * @see #checkPermissionForDataDelivery(Context, String, int, AttributionSource,
+     *     String, boolean)
+     */
+    @PermissionResult
+    public static int checkPermissionForPreflight(@NonNull Context context,
+            @NonNull String permission, @NonNull AttributionSource attributionSource) {
+        return checkPermissionCommon(context, permission, attributionSource,
+                null /*message*/, false /*forDataDelivery*/, /*startDataDelivery*/ false,
+                /*fromDatasource*/ false);
     }
 
     /**
@@ -211,7 +593,8 @@
     public static int checkSelfPermissionForDataDelivery(@NonNull Context context,
             @NonNull String permission, @Nullable String message) {
         return checkPermissionForDataDelivery(context, permission, Process.myPid(),
-                Process.myUid(), context.getPackageName(), context.getAttributionTag(), message);
+                Process.myUid(), context.getPackageName(), context.getAttributionTag(), message,
+                /*startDataDelivery*/ false);
     }
 
     /**
@@ -289,7 +672,8 @@
             return PERMISSION_HARD_DENIED;
         }
         return checkPermissionForDataDelivery(context, permission, Binder.getCallingPid(),
-                Binder.getCallingUid(), callingPackageName, callingAttributionTag, message);
+                Binder.getCallingUid(), callingPackageName, callingAttributionTag, message,
+                /*startDataDelivery*/ false);
     }
 
     /**
@@ -308,8 +692,8 @@
      * fg/gb state) and this check will not leave a trace that permission protected data
      * was delivered. When you are about to deliver the location data to a registered
      * listener you should use {@link #checkCallingOrSelfPermissionForDataDelivery(Context,
-     * String, String)} which will evaluate the permission access based on the current fg/bg state
-     * of the app and leave a record that the data was accessed.
+     * String, String, String, String)} which will evaluate the permission access based on the
+     * current fg/bg stateof the app and leave a record that the data was accessed.
      *
      * @param context Context for accessing resources.
      * @param permission The permission to check.
@@ -318,7 +702,7 @@
      * @return The permission check result which is either {@link #PERMISSION_GRANTED}
      *     or {@link #PERMISSION_SOFT_DENIED} or {@link #PERMISSION_HARD_DENIED}.
      *
-     * @see #checkCallingPermissionForDataDelivery(Context, String, String, String)
+     * @see #checkCallingPermissionForDataDelivery(Context, String, String, String, String)
      */
     @PermissionResult
     public static int checkCallingPermissionForPreflight(@NonNull Context context,
@@ -370,7 +754,8 @@
         callingAttributionTag = (Binder.getCallingPid() == Process.myPid())
                 ? context.getAttributionTag() : callingAttributionTag;
         return checkPermissionForDataDelivery(context, permission, Binder.getCallingPid(),
-                Binder.getCallingUid(), callingPackageName, callingAttributionTag, message);
+                Binder.getCallingUid(), callingPackageName, callingAttributionTag, message,
+                /*startDataDelivery*/ false);
     }
 
     /**
@@ -408,88 +793,325 @@
                 Binder.getCallingUid(), packageName);
     }
 
-    static int checkPermissionCommon(@NonNull Context context, @NonNull String permission,
-            int pid, int uid, @Nullable String packageName, @Nullable String attributionTag,
-            @Nullable String message, boolean forDataDelivery) {
-        final PermissionInfo permissionInfo;
-        try {
-            // TODO(b/147869157): Cache platform defined app op and runtime permissions to avoid
-            // calling into the package manager every time.
-            permissionInfo = context.getPackageManager().getPermissionInfo(permission, 0);
-        } catch (PackageManager.NameNotFoundException ignored) {
-            return PERMISSION_HARD_DENIED;
-        }
+    @PermissionResult
+    private static int checkPermissionCommon(@NonNull Context context, @NonNull String permission,
+            @NonNull AttributionSource attributionSource,
+            @Nullable String message, boolean forDataDelivery, boolean startDataDelivery,
+            boolean fromDatasource) {
+        PermissionInfo permissionInfo = sPlatformPermissions.get(permission);
 
-        if (packageName == null) {
-            String[] packageNames = context.getPackageManager().getPackagesForUid(uid);
-            if (packageNames != null && packageNames.length > 0) {
-                packageName = packageNames[0];
+        if (permissionInfo == null) {
+            try {
+                permissionInfo = context.getPackageManager().getPermissionInfo(permission, 0);
+                if (PLATFORM_PACKAGE_NAME.equals(permissionInfo.packageName)) {
+                    // Double addition due to concurrency is fine - the backing store is concurrent.
+                    sPlatformPermissions.put(permission, permissionInfo);
+                }
+            } catch (PackageManager.NameNotFoundException ignored) {
+                return PERMISSION_HARD_DENIED;
             }
         }
 
         if (permissionInfo.isAppOp()) {
-            return checkAppOpPermission(context, permission, pid, uid, packageName, attributionTag,
-                    message, forDataDelivery);
+            return checkAppOpPermission(context, permission, attributionSource, message,
+                    forDataDelivery, fromDatasource);
         }
         if (permissionInfo.isRuntime()) {
-            return checkRuntimePermission(context, permission, pid, uid, packageName,
-                    attributionTag, message, forDataDelivery);
+            return checkRuntimePermission(context, permission, attributionSource, message,
+                    forDataDelivery, startDataDelivery, fromDatasource);
         }
-        return context.checkPermission(permission, pid, uid);
+
+        if (!fromDatasource && !checkPermission(context, permission, attributionSource.getUid(),
+                attributionSource.getRenouncedPermissions())) {
+            return PERMISSION_HARD_DENIED;
+        }
+
+        if (attributionSource.getNext() != null) {
+            return checkPermissionCommon(context, permission,
+                    attributionSource.getNext(), message, forDataDelivery,
+                    startDataDelivery, /*fromDatasource*/ false);
+        }
+
+        return PERMISSION_GRANTED;
     }
 
+    @PermissionResult
     private static int checkAppOpPermission(@NonNull Context context, @NonNull String permission,
-            int pid, int uid, @Nullable String packageName, @Nullable String attributionTag,
-            @Nullable String message, boolean forDataDelivery) {
-        final String op = AppOpsManager.permissionToOp(permission);
-        if (op == null || packageName == null) {
+            @NonNull AttributionSource attributionSource, @Nullable String message,
+            boolean forDataDelivery, boolean fromDatasource) {
+        final int op = AppOpsManager.permissionToOpCode(permission);
+        if (op < 0 || attributionSource.getPackageName() == null) {
             return PERMISSION_HARD_DENIED;
         }
 
         final AppOpsManager appOpsManager = context.getSystemService(AppOpsManager.class);
-        final int opMode = (forDataDelivery)
-                ? appOpsManager.noteProxyOpNoThrow(op, packageName, uid, attributionTag, message)
-                : appOpsManager.unsafeCheckOpRawNoThrow(op, uid, packageName);
 
-        switch (opMode) {
-            case AppOpsManager.MODE_ALLOWED:
-            case AppOpsManager.MODE_FOREGROUND: {
-                return PERMISSION_GRANTED;
-            }
-            case AppOpsManager.MODE_DEFAULT: {
-                return context.checkPermission(permission, pid, uid)
-                            == PackageManager.PERMISSION_GRANTED
-                        ? PERMISSION_GRANTED : PERMISSION_HARD_DENIED;
-            }
-            default: {
+        AttributionSource current = attributionSource;
+        AttributionSource next = null;
+
+        while (true) {
+            final boolean skipCurrentChecks = (fromDatasource || next != null);
+
+            next = current.getNext();
+
+            // If the call is from a datasource we need to vet only the chain before it. This
+            // way we can avoid the datasource creating an attribution context for every call.
+            if ((!fromDatasource || current != attributionSource)
+                    && next != null && !current.isTrusted(context)) {
                 return PERMISSION_HARD_DENIED;
             }
+
+            int opMode;
+            if (forDataDelivery) {
+                if (next == null) {
+                    opMode = appOpsManager.noteOpNoThrow(op, current.getUid(),
+                            current.getPackageName(), current.getAttributionTag(), message);
+                } else {
+                    opMode = appOpsManager.noteProxyOpNoThrow(op, current, message,
+                            skipCurrentChecks);
+                }
+            } else {
+                opMode = appOpsManager.unsafeCheckOpRawNoThrow(op, current.getUid(),
+                        current.getPackageName());
+                if (next != null && opMode == AppOpsManager.MODE_ALLOWED) {
+                    opMode = appOpsManager.unsafeCheckOpRawNoThrow(op, next.getUid(),
+                            next.getPackageName());
+                }
+            }
+
+            switch (opMode) {
+                case AppOpsManager.MODE_IGNORED:
+                case AppOpsManager.MODE_ERRORED: {
+                    return PERMISSION_HARD_DENIED;
+                }
+                case AppOpsManager.MODE_DEFAULT: {
+                    if (!skipCurrentChecks && !checkPermission(context, permission,
+                            attributionSource.getUid(), attributionSource
+                                    .getRenouncedPermissions())) {
+                        return PERMISSION_HARD_DENIED;
+                    }
+                    if (next != null && !checkPermission(context, permission,
+                            next.getUid(), next.getRenouncedPermissions())) {
+                        return PERMISSION_HARD_DENIED;
+                    }
+                }
+            }
+
+            if (next == null || next.getNext() == null) {
+                return PERMISSION_GRANTED;
+            }
+
+            current = next;
         }
     }
 
     private static int checkRuntimePermission(@NonNull Context context, @NonNull String permission,
-            int pid, int uid, @Nullable String packageName, @Nullable String attributionTag,
-            @Nullable String message, boolean forDataDelivery) {
-        if (context.checkPermission(permission, pid, uid) == PackageManager.PERMISSION_DENIED) {
+            @NonNull AttributionSource attributionSource, @Nullable String message,
+            boolean forDataDelivery, boolean startDataDelivery, boolean fromDatasource) {
+        // Now let's check the identity chain...
+        final int op = AppOpsManager.permissionToOpCode(permission);
+
+        AttributionSource current = attributionSource;
+        AttributionSource next = null;
+
+        while (true) {
+            final boolean skipCurrentChecks = (fromDatasource || next != null);
+            next = current.getNext();
+
+            // If the call is from a datasource we need to vet only the chain before it. This
+            // way we can avoid the datasource creating an attribution context for every call.
+            if ((!fromDatasource || current != attributionSource)
+                    && next != null && !current.isTrusted(context)) {
+                return PERMISSION_HARD_DENIED;
+            }
+
+            // If we already checked the permission for this one, skip the work
+            if (!skipCurrentChecks && !checkPermission(context, permission,
+                    current.getUid(), current.getRenouncedPermissions())) {
+                return PERMISSION_HARD_DENIED;
+            }
+
+            if (next != null && !checkPermission(context, permission,
+                    next.getUid(), next.getRenouncedPermissions())) {
+                return PERMISSION_HARD_DENIED;
+            }
+
+            if (op < 0) {
+                continue;
+            }
+
+            // The access is for oneself if this is the single receiver of data
+            // after the data source or if this is the single attribution source
+            // in the chain if not from a datasource.
+            final boolean singleReceiverFromDatasource = (fromDatasource
+                    && current == attributionSource && next != null && next.getNext() == null);
+            final boolean selfAccess = singleReceiverFromDatasource || next == null;
+
+            final int opMode = performOpTransaction(context, op, current, message,
+                    forDataDelivery, startDataDelivery, skipCurrentChecks, selfAccess,
+                    singleReceiverFromDatasource);
+
+            switch (opMode) {
+                case AppOpsManager.MODE_ERRORED: {
+                    return PERMISSION_HARD_DENIED;
+                }
+                case AppOpsManager.MODE_IGNORED: {
+                    return PERMISSION_SOFT_DENIED;
+                }
+            }
+
+            if (next == null || next.getNext() == null) {
+                return PERMISSION_GRANTED;
+            }
+
+            current = next;
+        }
+    }
+
+    private static boolean checkPermission(@NonNull Context context, @NonNull String permission,
+            int uid, @NonNull Set<String> renouncedPermissions) {
+        final boolean permissionGranted = context.checkPermission(permission, /*pid*/ -1,
+                uid) == PackageManager.PERMISSION_GRANTED;
+        if (permissionGranted && renouncedPermissions.contains(permission)) {
+            return false;
+        }
+        return permissionGranted;
+    }
+
+    private static int checkOp(@NonNull Context context, @NonNull int op,
+            @NonNull AttributionSource attributionSource, @Nullable String message,
+            boolean forDataDelivery, boolean startDataDelivery) {
+        if (op < 0 || attributionSource.getPackageName() == null) {
             return PERMISSION_HARD_DENIED;
         }
 
-        final String op = AppOpsManager.permissionToOp(permission);
-        if (op == null || packageName == null) {
-            return PERMISSION_GRANTED;
-        }
+        AttributionSource current = attributionSource;
+        AttributionSource next = null;
 
-        final AppOpsManager appOpsManager = context.getSystemService(AppOpsManager.class);
-        final int opMode = (forDataDelivery)
-                ? appOpsManager.noteProxyOpNoThrow(op, packageName, uid, attributionTag, message)
-                : appOpsManager.unsafeCheckOpRawNoThrow(op, uid, packageName);
+        while (true) {
+            final boolean skipCurrentChecks = (next != null);
+            next = current.getNext();
 
-        switch (opMode) {
-            case AppOpsManager.MODE_ALLOWED:
-            case AppOpsManager.MODE_FOREGROUND:
+            // If the call is from a datasource we need to vet only the chain before it. This
+            // way we can avoid the datasource creating an attribution context for every call.
+            if (next != null && !current.isTrusted(context)) {
+                return PERMISSION_HARD_DENIED;
+            }
+
+            // The access is for oneself if this is the single attribution source in the chain.
+            final boolean selfAccess = (next == null);
+
+            final int opMode = performOpTransaction(context, op, current, message,
+                    forDataDelivery, startDataDelivery, skipCurrentChecks, selfAccess,
+                    /*fromDatasource*/ false);
+
+            switch (opMode) {
+                case AppOpsManager.MODE_ERRORED: {
+                    return PERMISSION_HARD_DENIED;
+                }
+                case AppOpsManager.MODE_IGNORED: {
+                    return PERMISSION_SOFT_DENIED;
+                }
+            }
+
+            if (next == null || next.getNext() == null) {
                 return PERMISSION_GRANTED;
-            default:
-                return PERMISSION_SOFT_DENIED;
+            }
+
+            current = next;
         }
     }
+    // If from data source and there is next app after that we need to note SELF of (noteOp) for the app vs proxy
+    private static int performOpTransaction(@NonNull Context context, int op,
+            @NonNull AttributionSource attributionSource, @Nullable String message,
+            boolean forDataDelivery, boolean startDataDelivery, boolean skipProxyOperation,
+            boolean selfAccess, boolean singleReceiverFromDatasource) {
+        // We cannot perform app ops transactions without a package name. In all relevant
+        // places we pass the package name but just in case there is a bug somewhere we
+        // do a best effort to resolve the package from the UID (pick first without a loss
+        // of generality - they are in the same security sandbox).
+        final AppOpsManager appOpsManager = context.getSystemService(AppOpsManager.class);
+        if (!forDataDelivery) {
+            final String resolvedPackageName = resolvePackageName(context, attributionSource);
+            if (resolvedPackageName == null) {
+                return AppOpsManager.MODE_ERRORED;
+            }
+            final int opMode = appOpsManager.unsafeCheckOpRawNoThrow(op,
+                    attributionSource.getUid(), resolvedPackageName);
+            final AttributionSource previous = attributionSource.getNext();
+            if (opMode == AppOpsManager.MODE_ALLOWED && previous != null) {
+                final String resolvedPreviousPackageName = resolvePackageName(context,
+                        previous);
+                if (resolvedPreviousPackageName == null) {
+                    return AppOpsManager.MODE_ERRORED;
+                }
+                return appOpsManager.unsafeCheckOpRawNoThrow(op, previous.getUid(),
+                        resolvedPreviousPackageName);
+            }
+            return opMode;
+        } else if (startDataDelivery) {
+            final AttributionSource accessorSource = (!singleReceiverFromDatasource)
+                    ? attributionSource : attributionSource.getNext();
+            final AttributionSource resolvedAttributionSource = resolveAttributionSource(
+                    context, accessorSource);
+            if (resolvedAttributionSource.getPackageName() == null) {
+                return AppOpsManager.MODE_ERRORED;
+            }
+            if (selfAccess) {
+                return appOpsManager.startOpNoThrow(op, resolvedAttributionSource.getUid(),
+                        resolvedAttributionSource.getPackageName(),
+                        /*startIfModeDefault*/ false,
+                        resolvedAttributionSource.getAttributionTag(),
+                        message);
+            } else {
+                return appOpsManager.startProxyOpNoThrow(op, resolvedAttributionSource, message,
+                        skipProxyOperation);
+            }
+        } else {
+            final AttributionSource accessorSource = (!singleReceiverFromDatasource)
+                    ? attributionSource : attributionSource.getNext();
+            final AttributionSource resolvedAttributionSource = resolveAttributionSource(
+                    context, accessorSource);
+            if (resolvedAttributionSource.getPackageName() == null) {
+                return AppOpsManager.MODE_ERRORED;
+            }
+            if (selfAccess) {
+                return appOpsManager.noteOpNoThrow(op, resolvedAttributionSource.getUid(),
+                        resolvedAttributionSource.getPackageName(),
+                        resolvedAttributionSource.getAttributionTag(),
+                        message);
+            } else {
+                return appOpsManager.noteProxyOpNoThrow(op, resolvedAttributionSource, message,
+                        skipProxyOperation);
+            }
+        }
+    }
+
+    private static @Nullable String resolvePackageName(@NonNull Context context,
+            @NonNull AttributionSource attributionSource) {
+        if (attributionSource.getPackageName() != null) {
+            return attributionSource.getPackageName();
+        }
+        final String[] packageNames = context.getPackageManager().getPackagesForUid(
+                attributionSource.getUid());
+        if (packageNames != null) {
+            // This is best effort if the caller doesn't pass a package. The security
+            // sandbox is UID, therefore we pick an arbitrary package.
+            return packageNames[0];
+        }
+        return null;
+    }
+
+    private static @NonNull AttributionSource resolveAttributionSource(
+            @NonNull Context context, @NonNull AttributionSource attributionSource) {
+        if (attributionSource.getPackageName() != null) {
+            return attributionSource;
+        }
+        return new AttributionSource(attributionSource.getUid(),
+                resolvePackageName(context, attributionSource),
+                attributionSource.getAttributionTag(),
+                attributionSource.getToken(),
+                attributionSource.getRenouncedPermissions(),
+                attributionSource.getNext());
+    }
 }
diff --git a/core/java/android/content/TEST_MAPPING b/core/java/android/content/TEST_MAPPING
index a2880df..614143e 100644
--- a/core/java/android/content/TEST_MAPPING
+++ b/core/java/android/content/TEST_MAPPING
@@ -44,9 +44,12 @@
         },
         {
           "include-filter": "android.content.ContextTest"
+        },
+        {
+          "include-filter": "android.content.ComponentCallbacksControllerTest"
         }
       ],
-      "file_patterns": ["(/|^)Context.java", "(/|^)ContextWrapper.java"]
+      "file_patterns": ["(/|^)Context.java", "(/|^)ContextWrapper.java", "(/|^)ComponentCallbacksController.java"]
     }
   ]
 }
\ No newline at end of file
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index feb58a30..0952b3e 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -550,9 +550,18 @@
     public static final int FLAG_INHERIT_SHOW_WHEN_LOCKED = 0x1;
 
     /**
+     * Bit in {@link #privateFlags} indicating whether a home sound effect should be played if the
+     * home app moves to front after the activity with this flag set.
+     * Set from the {@link android.R.attr#playHomeTransitionSound} attribute.
+     * @hide
+     */
+    public static final int PRIVATE_FLAG_HOME_TRANSITION_SOUND = 0x2;
+
+    /**
      * Options that have been set in the activity declaration in the manifest.
      * These include:
-     * {@link #FLAG_INHERIT_SHOW_WHEN_LOCKED}.
+     * {@link #FLAG_INHERIT_SHOW_WHEN_LOCKED},
+     * {@link #PRIVATE_FLAG_HOME_TRANSITION_SOUND}.
      * @hide
      */
     public int privateFlags;
diff --git a/core/java/android/content/pm/AppSearchPerson.java b/core/java/android/content/pm/AppSearchPerson.java
index 66295eb..9283e5f 100644
--- a/core/java/android/content/pm/AppSearchPerson.java
+++ b/core/java/android/content/pm/AppSearchPerson.java
@@ -107,7 +107,7 @@
     public static class Builder extends GenericDocument.Builder<Builder> {
 
         public Builder(@NonNull final String id) {
-            super(id, SCHEMA_TYPE);
+            super(/*namespace=*/ "", id, SCHEMA_TYPE);
         }
 
         /** @hide */
diff --git a/core/java/android/content/pm/AppSearchShortcutInfo.java b/core/java/android/content/pm/AppSearchShortcutInfo.java
index 5af3b5a..b2478ca 100644
--- a/core/java/android/content/pm/AppSearchShortcutInfo.java
+++ b/core/java/android/content/pm/AppSearchShortcutInfo.java
@@ -40,6 +40,7 @@
 import java.net.URISyntaxException;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.List;
 import java.util.Objects;
 import java.util.Set;
@@ -216,9 +217,8 @@
     @NonNull
     public static AppSearchShortcutInfo instance(@NonNull final ShortcutInfo shortcutInfo) {
         Objects.requireNonNull(shortcutInfo);
-        return new Builder(shortcutInfo.getId())
+        return new Builder(shortcutInfo.getPackage(), shortcutInfo.getId())
                 .setActivity(shortcutInfo.getActivity())
-                .setNamespace(shortcutInfo.getPackage())
                 .setShortLabel(shortcutInfo.getShortLabel())
                 .setShortLabelResId(shortcutInfo.getShortLabelResourceId())
                 .setShortLabelResName(shortcutInfo.getTitleResName())
@@ -327,12 +327,25 @@
         return si;
     }
 
+    /**
+     * @hide
+     */
+    @NonNull
+    public static List<GenericDocument> toGenericDocuments(
+            @NonNull final Collection<ShortcutInfo> shortcuts) {
+        final List<GenericDocument> docs = new ArrayList<>(shortcuts.size());
+        for (ShortcutInfo si : shortcuts) {
+            docs.add(AppSearchShortcutInfo.instance(si));
+        }
+        return docs;
+    }
+
     /** @hide */
     @VisibleForTesting
     public static class Builder extends GenericDocument.Builder<Builder> {
 
-        public Builder(String id) {
-            super(id, SCHEMA_TYPE);
+        public Builder(String packageName, String id) {
+            super(/*namespace=*/ packageName, id, SCHEMA_TYPE);
         }
 
         /**
@@ -560,16 +573,6 @@
         /**
          * @hide
          */
-        public Builder setPackageName(@Nullable final String packageName) {
-            if (!TextUtils.isEmpty(packageName)) {
-                setNamespace(packageName);
-            }
-            return this;
-        }
-
-        /**
-         * @hide
-         */
         public Builder setFlags(@ShortcutInfo.ShortcutFlags final int flags) {
             setPropertyLong(KEY_FLAGS, flattenFlags(flags));
             return this;
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 1a5dad5..5f3ec36 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -1363,7 +1363,7 @@
      * Indicates if the application has requested GWP-ASan to be enabled, disabled, or left
      * unspecified. Processes can override this setting.
      */
-    private @GwpAsanMode int gwpAsanMode;
+    private @GwpAsanMode int gwpAsanMode = GWP_ASAN_DEFAULT;
 
     /**
      * Default (unspecified) setting of Memtag.
@@ -1402,13 +1402,45 @@
      * Indicates if the application has requested Memtag to be enabled, disabled, or left
      * unspecified. Processes can override this setting.
      */
-    private @MemtagMode int memtagMode;
+    private @MemtagMode int memtagMode = MEMTAG_DEFAULT;
+
+    /**
+     * Default (unspecified) setting of nativeHeapZeroInitialized.
+     */
+    public static final int ZEROINIT_DEFAULT = -1;
+
+    /**
+     * Disable zero-initialization of the native heap in this application or process.
+     */
+    public static final int ZEROINIT_DISABLED = 0;
+
+    /**
+     * Enable zero-initialization of the native heap in this application or process.
+     */
+    public static final int ZEROINIT_ENABLED = 1;
+
+    /**
+     * @hide
+     */
+    @IntDef(prefix = {"ZEROINIT_"}, value = {
+            ZEROINIT_DEFAULT,
+            ZEROINIT_DISABLED,
+            ZEROINIT_ENABLED,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface NativeHeapZeroInitialized {}
 
     /**
      * Enable automatic zero-initialization of native heap memory allocations.
      */
+    private @NativeHeapZeroInitialized int nativeHeapZeroInitialized = ZEROINIT_DEFAULT;
+
+    /**
+     * If {@code true} this app requests optimized external storage access.
+     * The request may not be honored due to policy or other reasons.
+     */
     @Nullable
-    private Boolean nativeHeapZeroInit;
+    private Boolean requestOptimizedExternalStorageAccess;
 
     /**
      * Represents the default policy. The actual policy used will depend on other properties of
@@ -1563,8 +1595,12 @@
             if (memtagMode != MEMTAG_DEFAULT) {
                 pw.println(prefix + "memtagMode=" + memtagMode);
             }
-            if (nativeHeapZeroInit != null) {
-                pw.println(prefix + "nativeHeapZeroInit=" + nativeHeapZeroInit);
+            if (nativeHeapZeroInitialized != ZEROINIT_DEFAULT) {
+                pw.println(prefix + "nativeHeapZeroInitialized=" + nativeHeapZeroInitialized);
+            }
+            if (requestOptimizedExternalStorageAccess != null) {
+                pw.println(prefix + "requestOptimizedExternalStorageAccess="
+                        + requestOptimizedExternalStorageAccess);
             }
         }
         super.dumpBack(pw, prefix);
@@ -1675,8 +1711,9 @@
             if (memtagMode != MEMTAG_DEFAULT) {
                 proto.write(ApplicationInfoProto.Detail.ENABLE_MEMTAG, memtagMode);
             }
-            if (nativeHeapZeroInit != null) {
-                proto.write(ApplicationInfoProto.Detail.NATIVE_HEAP_ZERO_INIT, nativeHeapZeroInit);
+            if (nativeHeapZeroInitialized != ZEROINIT_DEFAULT) {
+                proto.write(ApplicationInfoProto.Detail.NATIVE_HEAP_ZERO_INIT,
+                        nativeHeapZeroInitialized);
             }
             proto.end(detailToken);
         }
@@ -1791,7 +1828,8 @@
         zygotePreloadName = orig.zygotePreloadName;
         gwpAsanMode = orig.gwpAsanMode;
         memtagMode = orig.memtagMode;
-        nativeHeapZeroInit = orig.nativeHeapZeroInit;
+        nativeHeapZeroInitialized = orig.nativeHeapZeroInitialized;
+        requestOptimizedExternalStorageAccess = orig.requestOptimizedExternalStorageAccess;
     }
 
     public String toString() {
@@ -1879,7 +1917,8 @@
         dest.writeString8(zygotePreloadName);
         dest.writeInt(gwpAsanMode);
         dest.writeInt(memtagMode);
-        sForBoolean.parcel(nativeHeapZeroInit, dest, parcelableFlags);
+        dest.writeInt(nativeHeapZeroInitialized);
+        sForBoolean.parcel(requestOptimizedExternalStorageAccess, dest, parcelableFlags);
     }
 
     public static final @android.annotation.NonNull Parcelable.Creator<ApplicationInfo> CREATOR
@@ -1964,7 +2003,8 @@
         zygotePreloadName = source.readString8();
         gwpAsanMode = source.readInt();
         memtagMode = source.readInt();
-        nativeHeapZeroInit = sForBoolean.unparcel(source);
+        nativeHeapZeroInitialized = source.readInt();
+        requestOptimizedExternalStorageAccess = sForBoolean.unparcel(source);
     }
 
     /**
@@ -2079,6 +2119,24 @@
     }
 
     /**
+     * @return
+     * <ul>
+     * <li>{@code true} if this app requested optimized external storage access
+     * <li>{@code false} if this app requests to disable optimized external storage access.
+     * <li>{@code null} if the app didn't specify
+     * {@link android.R.styleable#AndroidManifestApplication_requestOptimizedExternalStorageAccess}
+     * in its manifest file.
+     * </ul>
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public Boolean hasRequestOptimizedExternalStorageAccess() {
+        return requestOptimizedExternalStorageAccess;
+    }
+
+    /**
      * If {@code true} this app allows heap pointer tagging.
      *
      * @hide
@@ -2350,7 +2408,13 @@
     /** {@hide} */ public void setSplitResourcePaths(String[] splitResourcePaths) { splitPublicSourceDirs = splitResourcePaths; }
     /** {@hide} */ public void setGwpAsanMode(@GwpAsanMode int value) { gwpAsanMode = value; }
     /** {@hide} */ public void setMemtagMode(@MemtagMode int value) { memtagMode = value; }
-    /** {@hide} */ public void setNativeHeapZeroInit(@Nullable Boolean value) { nativeHeapZeroInit = value; }
+    /** {@hide} */ public void setNativeHeapZeroInitialized(@NativeHeapZeroInitialized int value) {
+        nativeHeapZeroInitialized = value;
+    }
+    /** {@hide} */
+    public void setRequestOptimizedExternalStorageAccess(@Nullable Boolean value) {
+        requestOptimizedExternalStorageAccess = value;
+    }
 
     /** {@hide} */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
@@ -2364,8 +2428,22 @@
     /** {@hide} */ public String[] getSplitResourcePaths() { return splitPublicSourceDirs; }
     @GwpAsanMode
     public int getGwpAsanMode() { return gwpAsanMode; }
+
+    /**
+     * Returns whether the application has requested Memtag to be enabled, disabled, or left
+     * unspecified. Processes can override this setting.
+     */
     @MemtagMode
-    public int getMemtagMode() { return memtagMode; }
-    @Nullable
-    public Boolean isNativeHeapZeroInit() { return nativeHeapZeroInit; }
+    public int getMemtagMode() {
+        return memtagMode;
+    }
+
+    /**
+     * Returns whether the application has requested automatic zero-initialization of native heap
+     * memory allocations to be enabled or disabled.
+     */
+    @NativeHeapZeroInitialized
+    public int getNativeHeapZeroInitialized() {
+        return nativeHeapZeroInitialized;
+    }
 }
diff --git a/core/java/android/content/pm/ILauncherApps.aidl b/core/java/android/content/pm/ILauncherApps.aidl
index d688614..37fd3ff 100644
--- a/core/java/android/content/pm/ILauncherApps.aidl
+++ b/core/java/android/content/pm/ILauncherApps.aidl
@@ -90,6 +90,8 @@
             String callingPackage, String packageName, in UserHandle user);
     IntentSender getShortcutConfigActivityIntent(String callingPackage, in ComponentName component,
             in UserHandle user);
+    PendingIntent getShortcutIntent(String callingPackage, String packageName, String shortcutId,
+            in Bundle opts, in UserHandle user);
 
     // Unregister is performed using package installer
     void registerPackageInstallerCallback(String callingPackage,
diff --git a/core/java/android/content/pm/InstallationFile.java b/core/java/android/content/pm/InstallationFile.java
index de761ad..e764020 100644
--- a/core/java/android/content/pm/InstallationFile.java
+++ b/core/java/android/content/pm/InstallationFile.java
@@ -18,21 +18,16 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.annotation.SystemApi;
 
 /**
  * Definition of a file in a streaming installation session.
  * You can use this class to retrieve the information of such a file, such as its name, size and
  * metadata. These file attributes will be consistent with those used in:
- * {@code PackageInstaller.Session#addFile}, when the file was first added into the session.
- *
- * WARNING: This is a system API to aid internal development.
- * Use at your own risk. It will change or be removed without warning.
+ * {@code android.content.pm.PackageInstaller.Session#addFile}, when the file was first added
+ * into the session.
  *
  * @see android.content.pm.PackageInstaller.Session#addFile
- * @hide
  */
-@SystemApi
 public final class InstallationFile {
     private final @NonNull InstallationFileParcel mParcel;
 
diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java
index 80fecc1..8b9b736 100644
--- a/core/java/android/content/pm/LauncherApps.java
+++ b/core/java/android/content/pm/LauncherApps.java
@@ -843,6 +843,30 @@
     }
 
     /**
+     * Returns PendingIntent associated with specified shortcut.
+     *
+     * @param packageName The packageName of the shortcut
+     * @param shortcutId The id of the shortcut
+     * @param opts Options to pass to the PendingIntent
+     * @param user The UserHandle of the profile
+     */
+    @Nullable
+    public PendingIntent getShortcutIntent(@NonNull final String packageName,
+            @NonNull final String shortcutId, @Nullable final Bundle opts,
+            @NonNull final UserHandle user) {
+        logErrorForInvalidProfileAccess(user);
+        if (DEBUG) {
+            Log.i(TAG, "GetShortcutIntent " + packageName + "/" + shortcutId + " " + user);
+        }
+        try {
+            return mService.getShortcutIntent(
+                    mContext.getPackageName(), packageName, shortcutId, opts, user);
+        } catch (RemoteException re) {
+            throw re.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Retrieves a list of config activities for creating {@link ShortcutInfo}.
      *
      * @param packageName The specific package to query. If null, it checks all installed packages
diff --git a/core/java/android/content/pm/PackageInfo.java b/core/java/android/content/pm/PackageInfo.java
index e8ef077..0462a4b 100644
--- a/core/java/android/content/pm/PackageInfo.java
+++ b/core/java/android/content/pm/PackageInfo.java
@@ -232,13 +232,23 @@
      *
      * @removed We do not support required permissions.
      */
-    public static final int REQUESTED_PERMISSION_REQUIRED = 1<<0;
+    public static final int REQUESTED_PERMISSION_REQUIRED = 0x00000001;
 
     /**
      * Flag for {@link #requestedPermissionsFlags}: the requested permission
      * is currently granted to the application.
      */
-    public static final int REQUESTED_PERMISSION_GRANTED = 1<<1;
+    public static final int REQUESTED_PERMISSION_GRANTED = 0x00000002;
+
+    /**
+     * Flag for {@link #requestedPermissionsFlags}: the requested permission has
+     * declared {@code neverForLocation} in their manifest as a strong assertion
+     * by a developer that they will never use this permission to derive the
+     * physical location of the device, regardless of
+     * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} and/or
+     * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION} being granted.
+     */
+    public static final int REQUESTED_PERMISSION_NEVER_FOR_LOCATION = 0x00010000;
 
     /**
      * Array of all signatures read from the package file. This is only filled
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 5afec06..0d218c2 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -1165,7 +1165,8 @@
         }
 
         /**
-         * Adds a file to session. On commit this file will be pulled from dataLoader.
+         * Adds a file to session. On commit this file will be pulled from dataLoader {@code
+         * android.service.dataloader.DataLoaderService.DataLoader}.
          *
          * @param location target location for the file. Possible values:
          *            {@link #LOCATION_DATA_APP},
@@ -1184,7 +1185,9 @@
          *                  <a href="https://source.android.com/security/apksigning/v4.html">APK Signature Scheme v4</a>
          * @throws SecurityException if called after the session has been
          *             sealed or abandoned
-         * @throws IllegalStateException if called for non-callback session
+         * @throws IllegalStateException if called for non-streaming session
+         *
+         * @see android.content.pm.InstallationFile
          */
         public void addFile(@FileLocation int location, @NonNull String name, long lengthBytes,
                 @NonNull byte[] metadata, @Nullable byte[] signature) {
@@ -1205,10 +1208,8 @@
          * @param name name of a file, e.g. split.
          * @throws SecurityException if called after the session has been
          *             sealed or abandoned
-         * @throws IllegalStateException if called for non-callback session
-         * {@hide}
+         * @throws IllegalStateException if called for non-streaming session
          */
-        @SystemApi
         public void removeFile(@FileLocation int location, @NonNull String name) {
             try {
                 mSession.removeFile(location, name);
@@ -1565,6 +1566,8 @@
         public int rollbackDataPolicy = PackageManager.RollbackDataPolicy.RESTORE;
         /** {@hide} */
         public boolean forceQueryableOverride;
+        /** {@hide} */
+        public Boolean requireUserAction;
 
         /**
          * Construct parameters for a new package install session.
@@ -1607,6 +1610,12 @@
                 dataLoaderParams = new DataLoaderParams(dataLoaderParamsParcel);
             }
             rollbackDataPolicy = source.readInt();
+            int requireUserActionInt = source.readInt();
+            requireUserAction = requireUserActionInt == 0
+                    ? Boolean.FALSE
+                    : requireUserActionInt == 1
+                            ? Boolean.TRUE : null;
+
         }
 
         /** {@hide} */
@@ -1635,6 +1644,7 @@
             ret.requiredInstalledVersionCode = requiredInstalledVersionCode;
             ret.dataLoaderParams = dataLoaderParams;
             ret.rollbackDataPolicy = rollbackDataPolicy;
+            ret.requireUserAction = requireUserAction;
             return ret;
         }
 
@@ -2015,6 +2025,8 @@
          * Set the data loader params for the session.
          * This also switches installation into data provider mode and disallow direct writes into
          * staging folder.
+         *
+         * @see android.service.dataloader.DataLoaderService.DataLoader
          */
         public void setDataLoaderParams(@NonNull DataLoaderParams dataLoaderParams) {
             this.dataLoaderParams = dataLoaderParams;
@@ -2029,6 +2041,41 @@
         }
 
         /**
+         * Optionally indicate whether user action should be required when the session is
+         * committed.
+         * <p>
+         * Defaults to {@code true} for installers using the
+         * {@link android.Manifest.permission#REQUEST_INSTALL_PACKAGES android.permission
+         * #REQUEST_INSTALL_PACKAGES} permission, and {@code false} otherwise. When {@code true},
+         * installers will receive a {@link #STATUS_PENDING_USER_ACTION} callback once the
+         * session is committed, indicating that the user is required for the install to proceed.
+         * <p>
+         * For installers using the {@link android.Manifest.permission#REQUEST_INSTALL_PACKAGES
+         * android.permission.REQUEST_INSTALL_PACKAGES} permission, user action will not be
+         * required when the following conditions are met:
+         *
+         * <ul>
+         *     <li>{@code requireUserAction} is set to {@code false}.</li>
+         *     <li>The being installed targets {@link android.os.Build.VERSION_CODES#Q API 29} or
+         *     higher.</li>
+         *     <li>The installer is the {@link InstallSourceInfo#getInstallingPackageName()
+         *     installer of record} of an existing version of the app (i.e.: this install session
+         *     is an app update or the installer is updating itself).</li>
+         *     <li>The installer declares the
+         *     {@link android.Manifest.permission#UPDATE_PACKAGES_WITHOUT_USER_ACTION android
+         *     .permission.UPDATE_PACKAGES_WITHOUT_USER_ACTION} permission.</li>
+         * </ul>
+         * <p>
+         * Note: The target API level requirement will advance in future Android versions.
+         * Session owners should always be prepared to handle {@link #STATUS_PENDING_USER_ACTION}
+         *
+         * @param requireUserAction whether user action should be required.
+         */
+        public void setRequireUserAction(boolean requireUserAction) {
+            this.requireUserAction = requireUserAction;
+        }
+
+        /**
          * Sets the install scenario for this session, which describes the expected user journey.
          */
         public void setInstallScenario(@InstallScenario int installScenario) {
@@ -2058,6 +2105,7 @@
             pw.printPair("isMultiPackage", isMultiPackage);
             pw.printPair("isStaged", isStaged);
             pw.printPair("forceQueryable", forceQueryableOverride);
+            pw.printPair("requireUserAction", requireUserAction);
             pw.printPair("requiredInstalledVersionCode", requiredInstalledVersionCode);
             pw.printPair("dataLoaderParams", dataLoaderParams);
             pw.printPair("rollbackDataPolicy", rollbackDataPolicy);
@@ -2099,6 +2147,10 @@
                 dest.writeParcelable(null, flags);
             }
             dest.writeInt(rollbackDataPolicy);
+            dest.writeInt(requireUserAction == Boolean.TRUE
+                    ? 1
+                    : requireUserAction == Boolean.FALSE
+                            ? 0 : 2);
         }
 
         public static final Parcelable.Creator<SessionParams>
@@ -2165,6 +2217,31 @@
          */
         public static final int STAGED_SESSION_CONFLICT = 4;
 
+        /** @hide */
+        @IntDef(prefix = {"USER_ACTION"}, value = {
+                USER_ACTION_UNSPECIFIED,
+                USER_ACTION_REQUIRED,
+                USER_ACTION_NOT_REQUIRED
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface UserActionRequirement {}
+
+        /**
+         * The installer did not calling {@link SessionParams#setRequireUserAction(boolean)} to
+         * specify whether user action should be required for the install.
+         */
+        public static final int USER_ACTION_UNSPECIFIED = 0;
+        /**
+         * The installer called {@link SessionParams#setRequireUserAction(boolean)} with
+         * {@code true} to require user action for the install to complete.
+         */
+        public static final int USER_ACTION_REQUIRED = 1;
+        /**
+         * The installer called {@link SessionParams#setRequireUserAction(boolean)} with
+         * {@code false} to request that user action not be required for this install.
+         */
+        public static final int USER_ACTION_NOT_REQUIRED = 2;
+
         /** {@hide} */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
         public int sessionId;
@@ -2257,6 +2334,9 @@
         public int rollbackDataPolicy;
 
         /** {@hide} */
+        public Boolean requireUserAction;
+
+        /** {@hide} */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
         public SessionInfo() {
         }
@@ -2305,6 +2385,11 @@
             isCommitted = source.readBoolean();
             rollbackDataPolicy = source.readInt();
             createdMillis = source.readLong();
+            int requireUserActionInt = source.readInt();
+            requireUserAction = requireUserActionInt == 0
+                    ? Boolean.FALSE
+                    : requireUserActionInt == 1
+                            ? Boolean.TRUE : null;
         }
 
         /**
@@ -2804,6 +2889,25 @@
             return updatedMillis;
         }
 
+        /**
+         * Whether user action was required by the installer.
+         *
+         * <p>
+         * Note: a return value of {@code USER_ACTION_NOT_REQUIRED} does not guarantee that the
+         * install will not result in user action.
+         *
+         * @return {@link #USER_ACTION_NOT_REQUIRED}, {@link #USER_ACTION_REQUIRED} or
+         *         {@link #USER_ACTION_UNSPECIFIED}
+         */
+        @UserActionRequirement
+        public int getRequireUserAction() {
+            return requireUserAction == null
+                    ? USER_ACTION_UNSPECIFIED
+                    : requireUserAction == Boolean.TRUE
+                            ? USER_ACTION_REQUIRED
+                            : USER_ACTION_NOT_REQUIRED;
+        }
+
         @Override
         public int describeContents() {
             return 0;
@@ -2849,6 +2953,10 @@
             dest.writeBoolean(isCommitted);
             dest.writeInt(rollbackDataPolicy);
             dest.writeLong(createdMillis);
+            dest.writeInt(requireUserAction == Boolean.TRUE
+                    ? 1
+                    : requireUserAction == Boolean.FALSE
+                            ? 0 : 2);
         }
 
         public static final Parcelable.Creator<SessionInfo>
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index d79b66c..21de365 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -3511,8 +3511,57 @@
     public static final String FEATURE_VR_HEADTRACKING = "android.hardware.vr.headtracking";
 
     /**
-     * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}:
-     * The device has a StrongBox hardware-backed Keystore.
+     * Feature for {@link #getSystemAvailableFeatures} and
+     * {@link #hasSystemFeature(String, int)}: If this feature is supported, the device implements
+     * the Android Keystore backed by an isolated execution environment. The version indicates
+     * which features are implemented in the isolated execution environment:
+     * <ul>
+     * <li>100: Hardware support for ECDH (see {@link javax.crypto.KeyAgreement}) and support
+     * for app-generated attestation keys (see {@link
+     * android.security.keystore.KeyGenParameterSpec.Builder#setAttestKeyAlias(String)}).
+     * <li>41: Hardware enforcement of device-unlocked keys (see {@link
+     * android.security.keystore.KeyGenParameterSpec.Builder#setUnlockedDeviceRequired(boolean)}).
+     * <li>40: Support for wrapped key import (see {@link
+     * android.security.keystore.WrappedKeyEntry}), optional support for ID attestation (see {@link
+     * android.security.keystore.KeyGenParameterSpec.Builder#setDevicePropertiesAttestationIncluded(boolean)}),
+     * attestation (see {@link
+     * android.security.keystore.KeyGenParameterSpec.Builder#setAttestationChallenge(byte[])}),
+     * AES, HMAC, ECDSA and RSA support where the secret or private key never leaves secure
+     * hardware, and support for requiring user authentication before a key can be used.
+     * </ul>
+     * This feature version is guaranteed to be set for all devices launching with Android 12 and
+     * may be set on devices launching with an earlier version. If the feature version is set, it
+     * will at least have the value 40. If it's not set the device may have a version of
+     * hardware-backed keystore but it may not support all features listed above.
+     */
+    @SdkConstant(SdkConstantType.FEATURE)
+    public static final String FEATURE_HARDWARE_KEYSTORE = "android.hardware.hardware_keystore";
+
+    /**
+     * Feature for {@link #getSystemAvailableFeatures}, {@link #hasSystemFeature(String)}, and
+     * {@link #hasSystemFeature(String, int)}: If this feature is supported, the device implements
+     * the Android Keystore backed by a dedicated secure processor referred to as
+     * <a href="https://source.android.com/security/best-practices/hardware#strongbox-keymaster">
+     * StrongBox</a>. If this feature has a version, the version number indicates which features are
+     * implemented in StrongBox:
+     * <ul>
+     * <li>100: Hardware support for ECDH (see {@link javax.crypto.KeyAgreement}) and support
+     * for app-generated attestation keys (see {@link
+     * android.security.keystore.KeyGenParameterSpec.Builder#setAttestKeyAlias(String)}).
+     * <li>41: Hardware enforcement of device-unlocked keys (see {@link
+     * android.security.keystore.KeyGenParameterSpec.Builder#setUnlockedDeviceRequired(boolean)}).
+     * <li>40: Support for wrapped key import (see {@link
+     * android.security.keystore.WrappedKeyEntry}), optional support for ID attestation (see {@link
+     * android.security.keystore.KeyGenParameterSpec.Builder#setDevicePropertiesAttestationIncluded(boolean)}),
+     * attestation (see {@link
+     * android.security.keystore.KeyGenParameterSpec.Builder#setAttestationChallenge(byte[])}),
+     * AES, HMAC, ECDSA and RSA support where the secret or private key never leaves secure
+     * hardware, and support for requiring user authentication before a key can be used.
+     * </ul>
+     * If a device has StrongBox, this feature version number is guaranteed to be set for all
+     * devices launching with Android 12 and may be set on devices launching with an earlier
+     * version. If the feature version is set, it will at least have the value 40. If it's not
+     * set the device may have StrongBox but it may not support all features listed above.
      */
     @SdkConstant(SdkConstantType.FEATURE)
     public static final String FEATURE_STRONGBOX_KEYSTORE =
diff --git a/core/java/android/content/pm/ProcessInfo.java b/core/java/android/content/pm/ProcessInfo.java
index 3dd5ee1..632c0f5 100644
--- a/core/java/android/content/pm/ProcessInfo.java
+++ b/core/java/android/content/pm/ProcessInfo.java
@@ -62,8 +62,7 @@
     /**
      * Enable automatic zero-initialization of native heap memory allocations.
      */
-    @Nullable
-    public Boolean nativeHeapZeroInit;
+    public @ApplicationInfo.NativeHeapZeroInitialized int nativeHeapZeroInitialized;
 
     @Deprecated
     public ProcessInfo(@NonNull ProcessInfo orig) {
@@ -71,7 +70,7 @@
         this.deniedPermissions = orig.deniedPermissions;
         this.gwpAsanMode = orig.gwpAsanMode;
         this.memtagMode = orig.memtagMode;
-        this.nativeHeapZeroInit = orig.nativeHeapZeroInit;
+        this.nativeHeapZeroInitialized = orig.nativeHeapZeroInitialized;
     }
 
 
@@ -101,7 +100,7 @@
      * @param memtagMode
      *   Indicates if the process has requested Memtag to be enabled (in sync or async mode),
      *   disabled, or left unspecified.
-     * @param nativeHeapZeroInit
+     * @param nativeHeapZeroInitialized
      *   Enable automatic zero-initialization of native heap memory allocations.
      */
     @DataClass.Generated.Member
@@ -110,7 +109,7 @@
             @Nullable ArraySet<String> deniedPermissions,
             @ApplicationInfo.GwpAsanMode int gwpAsanMode,
             @ApplicationInfo.MemtagMode int memtagMode,
-            @Nullable Boolean nativeHeapZeroInit) {
+            @ApplicationInfo.NativeHeapZeroInitialized int nativeHeapZeroInitialized) {
         this.name = name;
         com.android.internal.util.AnnotationValidations.validate(
                 NonNull.class, null, name);
@@ -121,7 +120,9 @@
         this.memtagMode = memtagMode;
         com.android.internal.util.AnnotationValidations.validate(
                 ApplicationInfo.MemtagMode.class, null, memtagMode);
-        this.nativeHeapZeroInit = nativeHeapZeroInit;
+        this.nativeHeapZeroInitialized = nativeHeapZeroInitialized;
+        com.android.internal.util.AnnotationValidations.validate(
+                ApplicationInfo.NativeHeapZeroInitialized.class, null, nativeHeapZeroInitialized);
 
         // onConstructed(); // You can define this method to get a callback
     }
@@ -145,13 +146,12 @@
 
         byte flg = 0;
         if (deniedPermissions != null) flg |= 0x2;
-        if (nativeHeapZeroInit != null) flg |= 0x10;
         dest.writeByte(flg);
         dest.writeString(name);
         sParcellingForDeniedPermissions.parcel(deniedPermissions, dest, flags);
         dest.writeInt(gwpAsanMode);
         dest.writeInt(memtagMode);
-        if (nativeHeapZeroInit != null) dest.writeBoolean(nativeHeapZeroInit);
+        dest.writeInt(nativeHeapZeroInitialized);
     }
 
     @Override
@@ -170,7 +170,7 @@
         ArraySet<String> _deniedPermissions = sParcellingForDeniedPermissions.unparcel(in);
         int _gwpAsanMode = in.readInt();
         int _memtagMode = in.readInt();
-        Boolean _nativeHeapZeroInit = (flg & 0x10) == 0 ? null : (Boolean) in.readBoolean();
+        int _nativeHeapZeroInitialized = in.readInt();
 
         this.name = _name;
         com.android.internal.util.AnnotationValidations.validate(
@@ -182,7 +182,9 @@
         this.memtagMode = _memtagMode;
         com.android.internal.util.AnnotationValidations.validate(
                 ApplicationInfo.MemtagMode.class, null, memtagMode);
-        this.nativeHeapZeroInit = _nativeHeapZeroInit;
+        this.nativeHeapZeroInitialized = _nativeHeapZeroInitialized;
+        com.android.internal.util.AnnotationValidations.validate(
+                ApplicationInfo.NativeHeapZeroInitialized.class, null, nativeHeapZeroInitialized);
 
         // onConstructed(); // You can define this method to get a callback
     }
@@ -202,10 +204,10 @@
     };
 
     @DataClass.Generated(
-            time = 1611614699049L,
+            time = 1615850184524L,
             codegenVersion = "1.0.22",
             sourceFile = "frameworks/base/core/java/android/content/pm/ProcessInfo.java",
-            inputSignatures = "public @android.annotation.NonNull java.lang.String name\npublic @android.annotation.Nullable @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInternedStringArraySet.class) android.util.ArraySet<java.lang.String> deniedPermissions\npublic @android.content.pm.ApplicationInfo.GwpAsanMode int gwpAsanMode\npublic @android.content.pm.ApplicationInfo.MemtagMode int memtagMode\npublic @android.annotation.Nullable java.lang.Boolean nativeHeapZeroInit\nclass ProcessInfo extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genGetters=true, genSetters=false, genParcelable=true, genAidl=false, genBuilder=false)")
+            inputSignatures = "public @android.annotation.NonNull java.lang.String name\npublic @android.annotation.Nullable @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInternedStringArraySet.class) android.util.ArraySet<java.lang.String> deniedPermissions\npublic @android.content.pm.ApplicationInfo.GwpAsanMode int gwpAsanMode\npublic @android.content.pm.ApplicationInfo.MemtagMode int memtagMode\npublic @android.content.pm.ApplicationInfo.NativeHeapZeroInitialized int nativeHeapZeroInitialized\nclass ProcessInfo extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genGetters=true, genSetters=false, genParcelable=true, genAidl=false, genBuilder=false)")
     @Deprecated
     private void __metadata() {}
 
diff --git a/core/java/android/content/pm/SuspendDialogInfo.java b/core/java/android/content/pm/SuspendDialogInfo.java
index 60f3218..23945ee 100644
--- a/core/java/android/content/pm/SuspendDialogInfo.java
+++ b/core/java/android/content/pm/SuspendDialogInfo.java
@@ -65,16 +65,20 @@
     private static final String TAG = SuspendDialogInfo.class.getSimpleName();
     private static final String XML_ATTR_ICON_RES_ID = "iconResId";
     private static final String XML_ATTR_TITLE_RES_ID = "titleResId";
+    private static final String XML_ATTR_TITLE = "title";
     private static final String XML_ATTR_DIALOG_MESSAGE_RES_ID = "dialogMessageResId";
     private static final String XML_ATTR_DIALOG_MESSAGE = "dialogMessage";
     private static final String XML_ATTR_BUTTON_TEXT_RES_ID = "buttonTextResId";
+    private static final String XML_ATTR_BUTTON_TEXT = "buttonText";
     private static final String XML_ATTR_BUTTON_ACTION = "buttonAction";
 
     private final int mIconResId;
     private final int mTitleResId;
+    private final String mTitle;
     private final int mDialogMessageResId;
     private final String mDialogMessage;
     private final int mNeutralButtonTextResId;
+    private final String mNeutralButtonText;
     private final int mNeutralButtonAction;
 
     /**
@@ -129,6 +133,16 @@
     }
 
     /**
+     * @return the title to be shown on the dialog. Returns {@code null} if {@link #getTitleResId()}
+     * returns a valid resource id
+     * @hide
+     */
+    @Nullable
+    public String getTitle() {
+        return mTitle;
+    }
+
+    /**
      * @return the resource id of the text to be shown in the dialog's body
      * @hide
      */
@@ -148,7 +162,7 @@
     }
 
     /**
-     * @return the text to be shown
+     * @return the text to be shown on the neutral button
      * @hide
      */
     @StringRes
@@ -157,6 +171,16 @@
     }
 
     /**
+     * @return the text to be shown on the neutral button. Returns {@code null} if
+     * {@link #getNeutralButtonTextResId()} returns a valid resource id
+     * @hide
+     */
+    @Nullable
+    public String getNeutralButtonText() {
+        return mNeutralButtonText;
+    }
+
+    /**
      * @return The {@link ButtonAction} that happens on tapping this button
      * @hide
      */
@@ -174,6 +198,8 @@
         }
         if (mTitleResId != ID_NULL) {
             out.attributeInt(null, XML_ATTR_TITLE_RES_ID, mTitleResId);
+        } else {
+            XmlUtils.writeStringAttribute(out, XML_ATTR_TITLE, mTitle);
         }
         if (mDialogMessageResId != ID_NULL) {
             out.attributeInt(null, XML_ATTR_DIALOG_MESSAGE_RES_ID, mDialogMessageResId);
@@ -182,6 +208,8 @@
         }
         if (mNeutralButtonTextResId != ID_NULL) {
             out.attributeInt(null, XML_ATTR_BUTTON_TEXT_RES_ID, mNeutralButtonTextResId);
+        } else {
+            XmlUtils.writeStringAttribute(out, XML_ATTR_BUTTON_TEXT, mNeutralButtonText);
         }
         out.attributeInt(null, XML_ATTR_BUTTON_ACTION, mNeutralButtonAction);
     }
@@ -194,8 +222,10 @@
         try {
             final int iconId = in.getAttributeInt(null, XML_ATTR_ICON_RES_ID, ID_NULL);
             final int titleId = in.getAttributeInt(null, XML_ATTR_TITLE_RES_ID, ID_NULL);
+            final String title = XmlUtils.readStringAttribute(in, XML_ATTR_TITLE);
             final int buttonTextId =
                     in.getAttributeInt(null, XML_ATTR_BUTTON_TEXT_RES_ID, ID_NULL);
+            final String buttonText = XmlUtils.readStringAttribute(in, XML_ATTR_BUTTON_TEXT);
             final int buttonAction =
                     in.getAttributeInt(null, XML_ATTR_BUTTON_ACTION, BUTTON_ACTION_MORE_DETAILS);
             final int dialogMessageResId =
@@ -207,9 +237,13 @@
             }
             if (titleId != ID_NULL) {
                 dialogInfoBuilder.setTitle(titleId);
+            } else if (title != null) {
+                dialogInfoBuilder.setTitle(title);
             }
             if (buttonTextId != ID_NULL) {
                 dialogInfoBuilder.setNeutralButtonText(buttonTextId);
+            } else if (buttonText != null) {
+                dialogInfoBuilder.setNeutralButtonText(buttonText);
             }
             if (dialogMessageResId != ID_NULL) {
                 dialogInfoBuilder.setMessage(dialogMessageResId);
@@ -227,7 +261,9 @@
     public int hashCode() {
         int hashCode = mIconResId;
         hashCode = 31 * hashCode + mTitleResId;
+        hashCode = 31 * hashCode + Objects.hashCode(mTitle);
         hashCode = 31 * hashCode + mNeutralButtonTextResId;
+        hashCode = 31 * hashCode + Objects.hashCode(mNeutralButtonText);
         hashCode = 31 * hashCode + mDialogMessageResId;
         hashCode = 31 * hashCode + Objects.hashCode(mDialogMessage);
         hashCode = 31 * hashCode + mNeutralButtonAction;
@@ -245,10 +281,12 @@
         final SuspendDialogInfo otherDialogInfo = (SuspendDialogInfo) obj;
         return mIconResId == otherDialogInfo.mIconResId
                 && mTitleResId == otherDialogInfo.mTitleResId
+                && Objects.equals(mTitle, otherDialogInfo.mTitle)
                 && mDialogMessageResId == otherDialogInfo.mDialogMessageResId
+                && Objects.equals(mDialogMessage, otherDialogInfo.mDialogMessage)
                 && mNeutralButtonTextResId == otherDialogInfo.mNeutralButtonTextResId
-                && mNeutralButtonAction == otherDialogInfo.mNeutralButtonAction
-                && Objects.equals(mDialogMessage, otherDialogInfo.mDialogMessage);
+                && Objects.equals(mNeutralButtonText, otherDialogInfo.mNeutralButtonText)
+                && mNeutralButtonAction == otherDialogInfo.mNeutralButtonAction;
     }
 
     @NonNull
@@ -264,11 +302,19 @@
             builder.append("mTitleResId = 0x");
             builder.append(Integer.toHexString(mTitleResId));
             builder.append(" ");
+        } else if (mTitle != null) {
+            builder.append("mTitle = \"");
+            builder.append(mTitle);
+            builder.append("\"");
         }
         if (mNeutralButtonTextResId != ID_NULL) {
             builder.append("mNeutralButtonTextResId = 0x");
             builder.append(Integer.toHexString(mNeutralButtonTextResId));
             builder.append(" ");
+        } else if (mNeutralButtonText != null) {
+            builder.append("mNeutralButtonText = \"");
+            builder.append(mNeutralButtonText);
+            builder.append("\"");
         }
         if (mDialogMessageResId != ID_NULL) {
             builder.append("mDialogMessageResId = 0x");
@@ -294,27 +340,33 @@
     public void writeToParcel(Parcel dest, int parcelableFlags) {
         dest.writeInt(mIconResId);
         dest.writeInt(mTitleResId);
+        dest.writeString(mTitle);
         dest.writeInt(mDialogMessageResId);
         dest.writeString(mDialogMessage);
         dest.writeInt(mNeutralButtonTextResId);
+        dest.writeString(mNeutralButtonText);
         dest.writeInt(mNeutralButtonAction);
     }
 
     private SuspendDialogInfo(Parcel source) {
         mIconResId = source.readInt();
         mTitleResId = source.readInt();
+        mTitle = source.readString();
         mDialogMessageResId = source.readInt();
         mDialogMessage = source.readString();
         mNeutralButtonTextResId = source.readInt();
+        mNeutralButtonText = source.readString();
         mNeutralButtonAction = source.readInt();
     }
 
     SuspendDialogInfo(Builder b) {
         mIconResId = b.mIconResId;
         mTitleResId = b.mTitleResId;
+        mTitle = (mTitleResId == ID_NULL) ? b.mTitle : null;
         mDialogMessageResId = b.mDialogMessageResId;
         mDialogMessage = (mDialogMessageResId == ID_NULL) ? b.mDialogMessage : null;
         mNeutralButtonTextResId = b.mNeutralButtonTextResId;
+        mNeutralButtonText = (mNeutralButtonTextResId == ID_NULL) ? b.mNeutralButtonText : null;
         mNeutralButtonAction = b.mNeutralButtonAction;
     }
 
@@ -338,8 +390,10 @@
         private int mDialogMessageResId = ID_NULL;
         private String mDialogMessage;
         private int mTitleResId = ID_NULL;
+        private String mTitle;
         private int mIconResId = ID_NULL;
         private int mNeutralButtonTextResId = ID_NULL;
+        private String mNeutralButtonText;
         private int mNeutralButtonAction = BUTTON_ACTION_MORE_DETAILS;
 
         /**
@@ -370,6 +424,21 @@
         }
 
         /**
+         * Set the title text of the dialog. Ignored if a resource id is set via
+         * {@link #setTitle(int)}
+         *
+         * @param title The title of the dialog.
+         * @return this builder object.
+         * @see #setTitle(int)
+         */
+        @NonNull
+        public Builder setTitle(@NonNull String title) {
+            Preconditions.checkStringNotEmpty(title, "Title cannot be null or empty");
+            mTitle = title;
+            return this;
+        }
+
+        /**
          * Set the text to show in the body of the dialog. Ignored if a resource id is set via
          * {@link #setMessage(int)}.
          * <p>
@@ -427,6 +496,22 @@
         }
 
         /**
+         * Set the text to be shown on the neutral button. Ignored if a resource id is set via
+         * {@link #setNeutralButtonText(int)}
+         *
+         * @param neutralButtonText The title of the dialog.
+         * @return this builder object.
+         * @see #setNeutralButtonText(int)
+         */
+        @NonNull
+        public Builder setNeutralButtonText(@NonNull String neutralButtonText) {
+            Preconditions.checkStringNotEmpty(neutralButtonText,
+                    "Button text cannot be null or empty");
+            mNeutralButtonText = neutralButtonText;
+            return this;
+        }
+
+        /**
          * Set the action expected to happen on neutral button tap. Defaults to
          * {@link #BUTTON_ACTION_MORE_DETAILS} if this is not provided.
          *
diff --git a/core/java/android/content/pm/UserInfo.java b/core/java/android/content/pm/UserInfo.java
index cfb6e1b..5a89708 100644
--- a/core/java/android/content/pm/UserInfo.java
+++ b/core/java/android/content/pm/UserInfo.java
@@ -321,6 +321,10 @@
         return UserManager.isUserTypeManagedProfile(userType);
     }
 
+    public boolean isCloneProfile() {
+        return UserManager.isUserTypeCloneProfile(userType);
+    }
+
     @UnsupportedAppUsage
     public boolean isEnabled() {
         return (flags & FLAG_DISABLED) != FLAG_DISABLED;
diff --git a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
index a3c2cbc..5887047 100644
--- a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
+++ b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
@@ -106,7 +106,7 @@
             final String packagePath = packageFile.getAbsolutePath();
             return input.success(
                     new PackageLite(packagePath, baseApk.getPath(), baseApk, null,
-                            null, null, null, null, null));
+                            null, null, null, null, null, baseApk.getTargetSdkVersion()));
         } finally {
             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
         }
@@ -242,7 +242,8 @@
                 splitNameToFileName(baseApk)).getAbsolutePath() : baseApk.getPath();
         return input.success(
                 new PackageLite(codePath, baseCodePath, baseApk, splitNames, isFeatureSplits,
-                        usesSplitNames, configForSplits, splitCodePaths, splitRevisionCodes));
+                        usesSplitNames, configForSplits, splitCodePaths, splitRevisionCodes,
+                        baseApk.getTargetSdkVersion()));
     }
 
     /**
diff --git a/core/java/android/content/pm/parsing/PackageInfoWithoutStateUtils.java b/core/java/android/content/pm/parsing/PackageInfoWithoutStateUtils.java
index fdd2c2a..e0052da 100644
--- a/core/java/android/content/pm/parsing/PackageInfoWithoutStateUtils.java
+++ b/core/java/android/content/pm/parsing/PackageInfoWithoutStateUtils.java
@@ -52,6 +52,7 @@
 import android.content.pm.parsing.component.ParsedPermissionGroup;
 import android.content.pm.parsing.component.ParsedProvider;
 import android.content.pm.parsing.component.ParsedService;
+import android.content.pm.parsing.component.ParsedUsesPermission;
 import android.os.Environment;
 import android.os.UserHandle;
 
@@ -61,6 +62,7 @@
 
 import java.io.File;
 import java.util.Collections;
+import java.util.List;
 import java.util.Set;
 
 /** @hide **/
@@ -264,17 +266,26 @@
                             flags);
                 }
             }
-            size = pkg.getRequestedPermissions().size();
+            final List<ParsedUsesPermission> usesPermissions = pkg.getUsesPermissions();
+            size = usesPermissions.size();
             if (size > 0) {
                 pi.requestedPermissions = new String[size];
                 pi.requestedPermissionsFlags = new int[size];
                 for (int i = 0; i < size; i++) {
-                    final String perm = pkg.getRequestedPermissions().get(i);
-                    pi.requestedPermissions[i] = perm;
+                    final ParsedUsesPermission usesPermission = usesPermissions.get(i);
+                    pi.requestedPermissions[i] = usesPermission.name;
                     // The notion of required permissions is deprecated but for compatibility.
-                    pi.requestedPermissionsFlags[i] |= PackageInfo.REQUESTED_PERMISSION_REQUIRED;
-                    if (grantedPermissions != null && grantedPermissions.contains(perm)) {
-                        pi.requestedPermissionsFlags[i] |= PackageInfo.REQUESTED_PERMISSION_GRANTED;
+                    pi.requestedPermissionsFlags[i] |=
+                            PackageInfo.REQUESTED_PERMISSION_REQUIRED;
+                    if (grantedPermissions != null
+                            && grantedPermissions.contains(usesPermission.name)) {
+                        pi.requestedPermissionsFlags[i] |=
+                                PackageInfo.REQUESTED_PERMISSION_GRANTED;
+                    }
+                    if ((usesPermission.usesPermissionFlags
+                            & ParsedUsesPermission.FLAG_NEVER_FOR_LOCATION) != 0) {
+                        pi.requestedPermissionsFlags[i] |=
+                                PackageInfo.REQUESTED_PERMISSION_NEVER_FOR_LOCATION;
                     }
                 }
             }
diff --git a/core/java/android/content/pm/parsing/PackageLite.java b/core/java/android/content/pm/parsing/PackageLite.java
index 803d643..9172555 100644
--- a/core/java/android/content/pm/parsing/PackageLite.java
+++ b/core/java/android/content/pm/parsing/PackageLite.java
@@ -55,6 +55,7 @@
     /** Major and minor version number of this package */
     private final int mVersionCodeMajor;
     private final int mVersionCode;
+    private final int mTargetSdk;
     /** Revision code of base APK */
     private final int mBaseRevisionCode;
     /** Revision codes of any split APKs, ordered by parsed splitName */
@@ -99,7 +100,8 @@
 
     public PackageLite(String path, String baseApkPath, ApkLite baseApk,
             String[] splitNames, boolean[] isFeatureSplits, String[] usesSplitNames,
-            String[] configForSplit, String[] splitApkPaths, int[] splitRevisionCodes) {
+            String[] configForSplit, String[] splitApkPaths, int[] splitRevisionCodes,
+            int targetSdk) {
         // The following paths may be different from the path in ApkLite because we
         // move or rename the APK files. Use parameters to indicate the correct paths.
         mPath = path;
@@ -125,6 +127,7 @@
         mConfigForSplit = configForSplit;
         mSplitApkPaths = splitApkPaths;
         mSplitRevisionCodes = splitRevisionCodes;
+        mTargetSdk = targetSdk;
     }
 
     /**
@@ -230,6 +233,11 @@
         return mVersionCode;
     }
 
+    @DataClass.Generated.Member
+    public int getTargetSdk() {
+        return mTargetSdk;
+    }
+
     /**
      * Revision code of base APK
      */
@@ -349,10 +357,10 @@
     }
 
     @DataClass.Generated(
-            time = 1610596639255L,
+            time = 1615914120261L,
             codegenVersion = "1.0.22",
             sourceFile = "frameworks/base/core/java/android/content/pm/parsing/PackageLite.java",
-            inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.NonNull java.lang.String mBaseApkPath\nprivate final @android.annotation.Nullable java.lang.String[] mSplitApkPaths\nprivate final @android.annotation.Nullable java.lang.String[] mSplitNames\nprivate final @android.annotation.Nullable java.lang.String[] mUsesSplitNames\nprivate final @android.annotation.Nullable java.lang.String[] mConfigForSplit\nprivate final  int mVersionCodeMajor\nprivate final  int mVersionCode\nprivate final  int mBaseRevisionCode\nprivate final @android.annotation.Nullable int[] mSplitRevisionCodes\nprivate final  int mInstallLocation\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.Nullable boolean[] mIsFeatureSplits\nprivate final  boolean mIsolatedSplits\nprivate final  boolean mSplitRequired\nprivate final  boolean mCoreApp\nprivate final  boolean mDebuggable\nprivate final  boolean mMultiArch\nprivate final  boolean mUse32bitAbi\nprivate final  boolean mExtractNativeLibs\nprivate final  boolean mProfileableByShell\nprivate final  boolean mUseEmbeddedDex\npublic  java.util.List<java.lang.String> getAllApkPaths()\npublic  long getLongVersionCode()\nclass PackageLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)")
+            inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.NonNull java.lang.String mBaseApkPath\nprivate final @android.annotation.Nullable java.lang.String[] mSplitApkPaths\nprivate final @android.annotation.Nullable java.lang.String[] mSplitNames\nprivate final @android.annotation.Nullable java.lang.String[] mUsesSplitNames\nprivate final @android.annotation.Nullable java.lang.String[] mConfigForSplit\nprivate final  int mVersionCodeMajor\nprivate final  int mVersionCode\nprivate final  int mTargetSdk\nprivate final  int mBaseRevisionCode\nprivate final @android.annotation.Nullable int[] mSplitRevisionCodes\nprivate final  int mInstallLocation\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.Nullable boolean[] mIsFeatureSplits\nprivate final  boolean mIsolatedSplits\nprivate final  boolean mSplitRequired\nprivate final  boolean mCoreApp\nprivate final  boolean mDebuggable\nprivate final  boolean mMultiArch\nprivate final  boolean mUse32bitAbi\nprivate final  boolean mExtractNativeLibs\nprivate final  boolean mProfileableByShell\nprivate final  boolean mUseEmbeddedDex\npublic  java.util.List<java.lang.String> getAllApkPaths()\npublic  long getLongVersionCode()\nclass PackageLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)")
     @Deprecated
     private void __metadata() {}
 
diff --git a/core/java/android/content/pm/parsing/ParsingPackage.java b/core/java/android/content/pm/parsing/ParsingPackage.java
index ba6416d..1c65e00 100644
--- a/core/java/android/content/pm/parsing/ParsingPackage.java
+++ b/core/java/android/content/pm/parsing/ParsingPackage.java
@@ -20,6 +20,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Intent;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.ConfigurationInfo;
 import android.content.pm.FeatureGroupInfo;
 import android.content.pm.FeatureInfo;
@@ -251,11 +252,15 @@
 
     ParsingPackage setEnabled(boolean enabled);
 
-    ParsingPackage setGwpAsanMode(int gwpAsanMode);
+    ParsingPackage setGwpAsanMode(@ApplicationInfo.GwpAsanMode int gwpAsanMode);
 
-    ParsingPackage setMemtagMode(int memtagMode);
+    ParsingPackage setMemtagMode(@ApplicationInfo.MemtagMode int memtagMode);
 
-    ParsingPackage setNativeHeapZeroInit(@Nullable Boolean nativeHeapZeroInit);
+    ParsingPackage setNativeHeapZeroInitialized(
+            @ApplicationInfo.NativeHeapZeroInitialized int nativeHeapZeroInitialized);
+
+    ParsingPackage setRequestOptimizedExternalStorageAccess(
+            @Nullable Boolean requestOptimizedExternalStorageAccess);
 
     ParsingPackage setCrossProfile(boolean crossProfile);
 
diff --git a/core/java/android/content/pm/parsing/ParsingPackageImpl.java b/core/java/android/content/pm/parsing/ParsingPackageImpl.java
index b3c26ab..60aac76 100644
--- a/core/java/android/content/pm/parsing/ParsingPackageImpl.java
+++ b/core/java/android/content/pm/parsing/ParsingPackageImpl.java
@@ -382,12 +382,18 @@
 
     private int autoRevokePermissions;
 
-    protected int gwpAsanMode;
-    protected int memtagMode;
+    @ApplicationInfo.GwpAsanMode
+    private int gwpAsanMode;
+
+    @ApplicationInfo.MemtagMode
+    private int memtagMode;
+
+    @ApplicationInfo.NativeHeapZeroInitialized
+    private int nativeHeapZeroInitialized;
 
     @Nullable
     @DataClass.ParcelWith(ForBoolean.class)
-    private Boolean nativeHeapZeroInit;
+    private Boolean requestOptimizedExternalStorageAccess;
 
     // TODO(chiuwinson): Non-null
     @Nullable
@@ -1067,7 +1073,8 @@
         appInfo.zygotePreloadName = zygotePreloadName;
         appInfo.setGwpAsanMode(gwpAsanMode);
         appInfo.setMemtagMode(memtagMode);
-        appInfo.setNativeHeapZeroInit(nativeHeapZeroInit);
+        appInfo.setNativeHeapZeroInitialized(nativeHeapZeroInitialized);
+        appInfo.setRequestOptimizedExternalStorageAccess(requestOptimizedExternalStorageAccess);
         appInfo.setBaseCodePath(mBaseApkPath);
         appInfo.setBaseResourcePath(mBaseApkPath);
         appInfo.setCodePath(mPath);
@@ -1202,7 +1209,8 @@
         dest.writeLong(this.mBooleans);
         dest.writeMap(this.mProperties);
         dest.writeInt(this.memtagMode);
-        sForBoolean.parcel(this.nativeHeapZeroInit, dest, flags);
+        dest.writeInt(this.nativeHeapZeroInitialized);
+        sForBoolean.parcel(this.requestOptimizedExternalStorageAccess, dest, flags);
     }
 
     public ParsingPackageImpl(Parcel in) {
@@ -1325,7 +1333,8 @@
         this.mBooleans = in.readLong();
         this.mProperties = in.createTypedArrayMap(Property.CREATOR);
         this.memtagMode = in.readInt();
-        this.nativeHeapZeroInit = sForBoolean.unparcel(in);
+        this.nativeHeapZeroInitialized = in.readInt();
+        this.requestOptimizedExternalStorageAccess = sForBoolean.unparcel(in);
         assignDerivedFields();
     }
 
@@ -2089,20 +2098,28 @@
         return getBoolean(Booleans.DIRECT_BOOT_AWARE);
     }
 
+    @ApplicationInfo.GwpAsanMode
     @Override
     public int getGwpAsanMode() {
         return gwpAsanMode;
     }
 
+    @ApplicationInfo.MemtagMode
     @Override
     public int getMemtagMode() {
         return memtagMode;
     }
 
+    @ApplicationInfo.NativeHeapZeroInitialized
+    @Override
+    public int getNativeHeapZeroInitialized() {
+        return nativeHeapZeroInitialized;
+    }
+
     @Nullable
     @Override
-    public Boolean isNativeHeapZeroInit() {
-        return nativeHeapZeroInit;
+    public Boolean hasRequestOptimizedExternalStorageAccess() {
+        return requestOptimizedExternalStorageAccess;
     }
 
     @Override
@@ -2537,24 +2554,30 @@
     }
 
     @Override
-    public ParsingPackageImpl setGwpAsanMode(int value) {
+    public ParsingPackageImpl setGwpAsanMode(@ApplicationInfo.GwpAsanMode int value) {
         gwpAsanMode = value;
         return this;
     }
 
     @Override
-    public ParsingPackageImpl setMemtagMode(int value) {
+    public ParsingPackageImpl setMemtagMode(@ApplicationInfo.MemtagMode int value) {
         memtagMode = value;
         return this;
     }
 
     @Override
-    public ParsingPackageImpl setNativeHeapZeroInit(@Nullable Boolean value) {
-        nativeHeapZeroInit = value;
+    public ParsingPackageImpl setNativeHeapZeroInitialized(
+            @ApplicationInfo.NativeHeapZeroInitialized int value) {
+        nativeHeapZeroInitialized = value;
         return this;
     }
 
     @Override
+    public ParsingPackageImpl setRequestOptimizedExternalStorageAccess(@Nullable Boolean value) {
+        requestOptimizedExternalStorageAccess = value;
+        return this;
+    }
+    @Override
     public ParsingPackageImpl setPartiallyDirectBootAware(boolean value) {
         return setBoolean(Booleans.PARTIALLY_DIRECT_BOOT_AWARE, value);
     }
diff --git a/core/java/android/content/pm/parsing/ParsingPackageRead.java b/core/java/android/content/pm/parsing/ParsingPackageRead.java
index 9f52183..cfd828e 100644
--- a/core/java/android/content/pm/parsing/ParsingPackageRead.java
+++ b/core/java/android/content/pm/parsing/ParsingPackageRead.java
@@ -887,20 +887,25 @@
      * @see ApplicationInfo#gwpAsanMode
      * @see R.styleable#AndroidManifest_gwpAsanMode
      */
+    @ApplicationInfo.GwpAsanMode
     int getGwpAsanMode();
 
     /**
      * @see ApplicationInfo#memtagMode
      * @see R.styleable#AndroidManifest_memtagMode
      */
+    @ApplicationInfo.MemtagMode
     int getMemtagMode();
 
-      /**
-     * @see ApplicationInfo#nativeHeapZeroInit
-     * @see R.styleable#AndroidManifest_nativeHeapZeroInit
+    /**
+     * @see ApplicationInfo#nativeHeapZeroInitialized
+     * @see R.styleable#AndroidManifest_nativeHeapZeroInitialized
      */
+    @ApplicationInfo.NativeHeapZeroInitialized
+    int getNativeHeapZeroInitialized();
+
     @Nullable
-    Boolean isNativeHeapZeroInit();
+    Boolean hasRequestOptimizedExternalStorageAccess();
 
     // TODO(b/135203078): Hide and enforce going through PackageInfoUtils
     ApplicationInfo toAppInfoWithoutState();
diff --git a/core/java/android/content/pm/parsing/ParsingPackageUtils.java b/core/java/android/content/pm/parsing/ParsingPackageUtils.java
index 2be0157..4e7bd70 100644
--- a/core/java/android/content/pm/parsing/ParsingPackageUtils.java
+++ b/core/java/android/content/pm/parsing/ParsingPackageUtils.java
@@ -34,6 +34,8 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.StyleableRes;
+import android.app.ActivityThread;
+import android.app.ResourcesManager;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.ApplicationInfo;
@@ -85,7 +87,9 @@
 import android.os.Build;
 import android.os.Bundle;
 import android.os.FileUtils;
+import android.os.RemoteException;
 import android.os.Trace;
+import android.os.UserHandle;
 import android.os.ext.SdkExtensions;
 import android.permission.PermissionManager;
 import android.text.TextUtils;
@@ -2008,9 +2012,17 @@
 
             pkg.setGwpAsanMode(sa.getInt(R.styleable.AndroidManifestApplication_gwpAsanMode, -1));
             pkg.setMemtagMode(sa.getInt(R.styleable.AndroidManifestApplication_memtagMode, -1));
-            if (sa.hasValue(R.styleable.AndroidManifestApplication_nativeHeapZeroInit)) {
-                pkg.setNativeHeapZeroInit(sa.getBoolean(
-                        R.styleable.AndroidManifestApplication_nativeHeapZeroInit, false));
+            if (sa.hasValue(R.styleable.AndroidManifestApplication_nativeHeapZeroInitialized)) {
+                Boolean v = sa.getBoolean(
+                        R.styleable.AndroidManifestApplication_nativeHeapZeroInitialized, false);
+                pkg.setNativeHeapZeroInitialized(
+                        v ? ApplicationInfo.ZEROINIT_ENABLED : ApplicationInfo.ZEROINIT_DISABLED);
+            }
+            if (sa.hasValue(
+                    R.styleable.AndroidManifestApplication_requestOptimizedExternalStorageAccess)) {
+                pkg.setRequestOptimizedExternalStorageAccess(sa.getBoolean(R.styleable
+                                .AndroidManifestApplication_requestOptimizedExternalStorageAccess,
+                        false));
             }
         } finally {
             sa.recycle();
@@ -3035,6 +3047,42 @@
         }
     }
 
+    /**
+     * @hide
+     */
+    public static void readConfigUseRoundIcon(Resources r) {
+        if (r != null) {
+            sUseRoundIcon = r.getBoolean(com.android.internal.R.bool.config_useRoundIcon);
+            return;
+        }
+
+        final ApplicationInfo androidAppInfo;
+        try {
+            androidAppInfo = ActivityThread.getPackageManager().getApplicationInfo(
+                    "android", 0 /* flags */,
+                    UserHandle.myUserId());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+        final Resources systemResources = Resources.getSystem();
+
+        // Create in-flight as this overlayable resource is only used when config changes
+        final Resources overlayableRes = ResourcesManager.getInstance().getResources(
+                null /* activityToken */,
+                null /* resDir */,
+                null /* splitResDirs */,
+                androidAppInfo.resourceDirs,
+                androidAppInfo.overlayPaths,
+                androidAppInfo.sharedLibraryFiles,
+                null /* overrideDisplayId */,
+                null /* overrideConfig */,
+                systemResources.getCompatibilityInfo(),
+                systemResources.getClassLoader(),
+                null /* loaders */);
+
+        sUseRoundIcon = overlayableRes.getBoolean(com.android.internal.R.bool.config_useRoundIcon);
+    }
+
     /*
      The following set of methods makes code easier to read by re-ordering the TypedArray methods.
 
diff --git a/core/java/android/content/pm/parsing/component/ParsedActivityUtils.java b/core/java/android/content/pm/parsing/component/ParsedActivityUtils.java
index d99c410..ff6aaad 100644
--- a/core/java/android/content/pm/parsing/component/ParsedActivityUtils.java
+++ b/core/java/android/content/pm/parsing/component/ParsedActivityUtils.java
@@ -149,7 +149,10 @@
                         | flag(ActivityInfo.FLAG_TURN_SCREEN_ON, R.styleable.AndroidManifestActivity_turnScreenOn, sa)
                         | flag(ActivityInfo.FLAG_PREFER_MINIMAL_POST_PROCESSING, R.styleable.AndroidManifestActivity_preferMinimalPostProcessing, sa);
 
-                activity.privateFlags |= flag(ActivityInfo.FLAG_INHERIT_SHOW_WHEN_LOCKED, R.styleable.AndroidManifestActivity_inheritShowWhenLocked, sa);
+                activity.privateFlags |= flag(ActivityInfo.FLAG_INHERIT_SHOW_WHEN_LOCKED,
+                        R.styleable.AndroidManifestActivity_inheritShowWhenLocked, sa)
+                        | flag(ActivityInfo.PRIVATE_FLAG_HOME_TRANSITION_SOUND,
+                        R.styleable.AndroidManifestActivity_playHomeTransitionSound, true, sa);
 
                 activity.colorMode = sa.getInt(R.styleable.AndroidManifestActivity_colorMode, ActivityInfo.COLOR_MODE_DEFAULT);
                 activity.documentLaunchMode = sa.getInt(R.styleable.AndroidManifestActivity_documentLaunchMode, ActivityInfo.DOCUMENT_LAUNCH_NONE);
diff --git a/core/java/android/content/pm/parsing/component/ParsedProcess.java b/core/java/android/content/pm/parsing/component/ParsedProcess.java
index 89fef9d..54a60d3 100644
--- a/core/java/android/content/pm/parsing/component/ParsedProcess.java
+++ b/core/java/android/content/pm/parsing/component/ParsedProcess.java
@@ -42,10 +42,12 @@
     @DataClass.ParcelWith(Parcelling.BuiltIn.ForInternedStringSet.class)
     protected Set<String> deniedPermissions = emptySet();
 
+    @ApplicationInfo.GwpAsanMode
     protected int gwpAsanMode = ApplicationInfo.GWP_ASAN_DEFAULT;
+    @ApplicationInfo.MemtagMode
     protected int memtagMode = ApplicationInfo.MEMTAG_DEFAULT;
-    @Nullable
-    protected Boolean nativeHeapZeroInit = null;
+    @ApplicationInfo.NativeHeapZeroInitialized
+    protected int nativeHeapZeroInitialized = ApplicationInfo.ZEROINIT_DEFAULT;
 
     public ParsedProcess() {
     }
@@ -78,9 +80,9 @@
     public ParsedProcess(
             @NonNull String name,
             @NonNull Set<String> deniedPermissions,
-            int gwpAsanMode,
-            int memtagMode,
-            @Nullable Boolean nativeHeapZeroInit) {
+            @ApplicationInfo.GwpAsanMode int gwpAsanMode,
+            @ApplicationInfo.MemtagMode int memtagMode,
+            @ApplicationInfo.NativeHeapZeroInitialized int nativeHeapZeroInitialized) {
         this.name = name;
         com.android.internal.util.AnnotationValidations.validate(
                 NonNull.class, null, name);
@@ -88,8 +90,14 @@
         com.android.internal.util.AnnotationValidations.validate(
                 NonNull.class, null, deniedPermissions);
         this.gwpAsanMode = gwpAsanMode;
+        com.android.internal.util.AnnotationValidations.validate(
+                ApplicationInfo.GwpAsanMode.class, null, gwpAsanMode);
         this.memtagMode = memtagMode;
-        this.nativeHeapZeroInit = nativeHeapZeroInit;
+        com.android.internal.util.AnnotationValidations.validate(
+                ApplicationInfo.MemtagMode.class, null, memtagMode);
+        this.nativeHeapZeroInitialized = nativeHeapZeroInitialized;
+        com.android.internal.util.AnnotationValidations.validate(
+                ApplicationInfo.NativeHeapZeroInitialized.class, null, nativeHeapZeroInitialized);
 
         // onConstructed(); // You can define this method to get a callback
     }
@@ -105,18 +113,18 @@
     }
 
     @DataClass.Generated.Member
-    public int getGwpAsanMode() {
+    public @ApplicationInfo.GwpAsanMode int getGwpAsanMode() {
         return gwpAsanMode;
     }
 
     @DataClass.Generated.Member
-    public int getMemtagMode() {
+    public @ApplicationInfo.MemtagMode int getMemtagMode() {
         return memtagMode;
     }
 
     @DataClass.Generated.Member
-    public @Nullable Boolean getNativeHeapZeroInit() {
-        return nativeHeapZeroInit;
+    public @ApplicationInfo.NativeHeapZeroInitialized int getNativeHeapZeroInitialized() {
+        return nativeHeapZeroInitialized;
     }
 
     @DataClass.Generated.Member
@@ -136,14 +144,11 @@
         // You can override field parcelling by defining methods like:
         // void parcelFieldName(Parcel dest, int flags) { ... }
 
-        byte flg = 0;
-        if (nativeHeapZeroInit != null) flg |= 0x10;
-        dest.writeByte(flg);
         dest.writeString(name);
         sParcellingForDeniedPermissions.parcel(deniedPermissions, dest, flags);
         dest.writeInt(gwpAsanMode);
         dest.writeInt(memtagMode);
-        if (nativeHeapZeroInit != null) dest.writeBoolean(nativeHeapZeroInit);
+        dest.writeInt(nativeHeapZeroInitialized);
     }
 
     @Override
@@ -157,12 +162,11 @@
         // You can override field unparcelling by defining methods like:
         // static FieldType unparcelFieldName(Parcel in) { ... }
 
-        byte flg = in.readByte();
         String _name = in.readString();
         Set<String> _deniedPermissions = sParcellingForDeniedPermissions.unparcel(in);
         int _gwpAsanMode = in.readInt();
         int _memtagMode = in.readInt();
-        Boolean _nativeHeapZeroInit = (flg & 0x10) == 0 ? null : (Boolean) in.readBoolean();
+        int _nativeHeapZeroInitialized = in.readInt();
 
         this.name = _name;
         com.android.internal.util.AnnotationValidations.validate(
@@ -171,8 +175,14 @@
         com.android.internal.util.AnnotationValidations.validate(
                 NonNull.class, null, deniedPermissions);
         this.gwpAsanMode = _gwpAsanMode;
+        com.android.internal.util.AnnotationValidations.validate(
+                ApplicationInfo.GwpAsanMode.class, null, gwpAsanMode);
         this.memtagMode = _memtagMode;
-        this.nativeHeapZeroInit = _nativeHeapZeroInit;
+        com.android.internal.util.AnnotationValidations.validate(
+                ApplicationInfo.MemtagMode.class, null, memtagMode);
+        this.nativeHeapZeroInitialized = _nativeHeapZeroInitialized;
+        com.android.internal.util.AnnotationValidations.validate(
+                ApplicationInfo.NativeHeapZeroInitialized.class, null, nativeHeapZeroInitialized);
 
         // onConstructed(); // You can define this method to get a callback
     }
@@ -192,10 +202,10 @@
     };
 
     @DataClass.Generated(
-            time = 1611615591258L,
+            time = 1615850515058L,
             codegenVersion = "1.0.22",
             sourceFile = "frameworks/base/core/java/android/content/pm/parsing/component/ParsedProcess.java",
-            inputSignatures = "protected @android.annotation.NonNull java.lang.String name\nprotected @android.annotation.NonNull @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInternedStringSet.class) java.util.Set<java.lang.String> deniedPermissions\nprotected  int gwpAsanMode\nprotected  int memtagMode\nprotected @android.annotation.Nullable java.lang.Boolean nativeHeapZeroInit\npublic  void addStateFrom(android.content.pm.parsing.component.ParsedProcess)\nclass ParsedProcess extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genGetters=true, genSetters=false, genParcelable=true, genAidl=false, genBuilder=false)")
+            inputSignatures = "protected @android.annotation.NonNull java.lang.String name\nprotected @android.annotation.NonNull @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInternedStringSet.class) java.util.Set<java.lang.String> deniedPermissions\nprotected @android.content.pm.ApplicationInfo.GwpAsanMode int gwpAsanMode\nprotected @android.content.pm.ApplicationInfo.MemtagMode int memtagMode\nprotected @android.content.pm.ApplicationInfo.NativeHeapZeroInitialized int nativeHeapZeroInitialized\npublic  void addStateFrom(android.content.pm.parsing.component.ParsedProcess)\nclass ParsedProcess extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genGetters=true, genSetters=false, genParcelable=true, genAidl=false, genBuilder=false)")
     @Deprecated
     private void __metadata() {}
 
diff --git a/core/java/android/content/pm/parsing/component/ParsedProcessUtils.java b/core/java/android/content/pm/parsing/component/ParsedProcessUtils.java
index 2579774..e417e74 100644
--- a/core/java/android/content/pm/parsing/component/ParsedProcessUtils.java
+++ b/core/java/android/content/pm/parsing/component/ParsedProcessUtils.java
@@ -17,6 +17,7 @@
 package android.content.pm.parsing.component;
 
 import android.annotation.NonNull;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.parsing.ParsingPackage;
 import android.content.pm.parsing.ParsingUtils;
 import android.content.pm.parsing.result.ParseInput;
@@ -104,9 +105,11 @@
 
             proc.gwpAsanMode = sa.getInt(R.styleable.AndroidManifestProcess_gwpAsanMode, -1);
             proc.memtagMode = sa.getInt(R.styleable.AndroidManifestProcess_memtagMode, -1);
-            if (sa.hasValue(R.styleable.AndroidManifestProcess_nativeHeapZeroInit)) {
-                proc.nativeHeapZeroInit =
-                        sa.getBoolean(R.styleable.AndroidManifestProcess_nativeHeapZeroInit, false);
+            if (sa.hasValue(R.styleable.AndroidManifestProcess_nativeHeapZeroInitialized)) {
+                Boolean v = sa.getBoolean(
+                        R.styleable.AndroidManifestProcess_nativeHeapZeroInitialized, false);
+                proc.nativeHeapZeroInitialized =
+                        v ? ApplicationInfo.ZEROINIT_ENABLED : ApplicationInfo.ZEROINIT_DISABLED;
             }
         } finally {
             sa.recycle();
diff --git a/core/java/android/content/pm/parsing/component/ParsedUsesPermission.java b/core/java/android/content/pm/parsing/component/ParsedUsesPermission.java
index b9c2e36..adf8da0 100644
--- a/core/java/android/content/pm/parsing/component/ParsedUsesPermission.java
+++ b/core/java/android/content/pm/parsing/component/ParsedUsesPermission.java
@@ -20,6 +20,7 @@
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
+import android.content.pm.PackageInfo;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -44,7 +45,8 @@
      * to derive the physical location of the device, regardless of
      * ACCESS_FINE_LOCATION and/or ACCESS_COARSE_LOCATION being granted.
      */
-    public static final int FLAG_NEVER_FOR_LOCATION = 0x1;
+    public static final int FLAG_NEVER_FOR_LOCATION =
+            PackageInfo.REQUESTED_PERMISSION_NEVER_FOR_LOCATION;
 
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
diff --git a/core/java/android/content/pm/verify/domain/DomainVerificationManager.java b/core/java/android/content/pm/verify/domain/DomainVerificationManager.java
index 55e19f2..33920c6 100644
--- a/core/java/android/content/pm/verify/domain/DomainVerificationManager.java
+++ b/core/java/android/content/pm/verify/domain/DomainVerificationManager.java
@@ -16,6 +16,7 @@
 
 package android.content.pm.verify.domain;
 
+import android.annotation.CheckResult;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -29,6 +30,8 @@
 import android.os.ServiceSpecificException;
 import android.os.UserHandle;
 
+import com.android.internal.util.CollectionUtils;
+
 import java.util.List;
 import java.util.Set;
 import java.util.UUID;
@@ -80,22 +83,6 @@
     public static final int ERROR_DOMAIN_SET_ID_INVALID = 1;
 
     /**
-     * The provided domain set ID was null. This is a developer error.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int ERROR_DOMAIN_SET_ID_NULL = 2;
-
-    /**
-     * The provided set of domains was null or empty. This is a developer error.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int ERROR_DOMAIN_SET_NULL_OR_EMPTY = 3;
-
-    /**
      * The provided set of domains contains a domain not declared by the target package. This
      * usually means the work being processed by the verification agent is outdated and a new
      * request should be scheduled, which should already be in progress as part of the
@@ -104,7 +91,7 @@
      * @hide
      */
     @SystemApi
-    public static final int ERROR_UNKNOWN_DOMAIN = 4;
+    public static final int ERROR_UNKNOWN_DOMAIN = 2;
 
     /**
      * The system was unable to select the domain for approval. This indicates another application
@@ -114,17 +101,7 @@
      * @hide
      */
     @SystemApi
-    public static final int ERROR_UNABLE_TO_APPROVE = 5;
-
-    /**
-     * The provided state code is incorrect. The domain verification agent is only allowed to
-     * assign {@link DomainVerificationInfo#STATE_SUCCESS} or error codes equal to or greater than
-     * {@link DomainVerificationInfo#STATE_FIRST_VERIFIER_DEFINED}.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int ERROR_INVALID_STATE_CODE = 6;
+    public static final int ERROR_UNABLE_TO_APPROVE = 3;
 
     /**
      * Used to communicate through {@link ServiceSpecificException}. Should not be exposed as API.
@@ -138,11 +115,8 @@
      */
     @IntDef(prefix = {"ERROR_"}, value = {
             ERROR_DOMAIN_SET_ID_INVALID,
-            ERROR_DOMAIN_SET_ID_NULL,
-            ERROR_DOMAIN_SET_NULL_OR_EMPTY,
             ERROR_UNKNOWN_DOMAIN,
             ERROR_UNABLE_TO_APPROVE,
-            ERROR_INVALID_STATE_CODE
     })
     public @interface Error {
     }
@@ -205,10 +179,7 @@
      */
     @SystemApi
     @Nullable
-    @RequiresPermission(anyOf = {
-            android.Manifest.permission.DOMAIN_VERIFICATION_AGENT,
-            android.Manifest.permission.UPDATE_DOMAIN_VERIFICATION_USER_SELECTION
-    })
+    @RequiresPermission(android.Manifest.permission.DOMAIN_VERIFICATION_AGENT)
     public DomainVerificationInfo getDomainVerificationInfo(@NonNull String packageName)
             throws NameNotFoundException {
         try {
@@ -232,19 +203,21 @@
      * @param domainSetId See {@link DomainVerificationInfo#getIdentifier()}.
      * @param domains     List of host names to change the state of.
      * @param state       See {@link DomainVerificationInfo#getHostToStateMap()}.
-     * @throws NameNotFoundException    If the ID is known to be good, but the package is
-     *                                  unavailable. This may be because the package is installed on
-     *                                  a volume that is no longer mounted. This error is
-     *                                  unrecoverable until the package is available again, and
-     *                                  should not be re-tried except on a time scheduled basis.
      * @return error code or {@link #STATUS_OK} if successful
-     *
+     * @throws NameNotFoundException If the ID is known to be good, but the package is
+     *                               unavailable. This may be because the package is installed on
+     *                               a volume that is no longer mounted. This error is
+     *                               unrecoverable until the package is available again, and
+     *                               should not be re-tried except on a time scheduled basis.
      * @hide
      */
+    @CheckResult
     @SystemApi
     @RequiresPermission(android.Manifest.permission.DOMAIN_VERIFICATION_AGENT)
     public int setDomainVerificationStatus(@NonNull UUID domainSetId, @NonNull Set<String> domains,
             int state) throws NameNotFoundException {
+        validateInput(domainSetId, domains);
+
         try {
             return mDomainVerificationManager.setDomainVerificationStatus(domainSetId.toString(),
                     new DomainSet(domains), state);
@@ -312,19 +285,21 @@
      * @param domainSetId See {@link DomainVerificationInfo#getIdentifier()}.
      * @param domains     The domains to toggle the state of.
      * @param enabled     Whether or not the app should automatically open the domains specified.
-     * @throws NameNotFoundException    If the ID is known to be good, but the package is
-     *                                  unavailable. This may be because the package is installed on
-     *                                  a volume that is no longer mounted. This error is
-     *                                  unrecoverable until the package is available again, and
-     *                                  should not be re-tried except on a time scheduled basis.
      * @return error code or {@link #STATUS_OK} if successful
-     *
+     * @throws NameNotFoundException If the ID is known to be good, but the package is
+     *                               unavailable. This may be because the package is installed on
+     *                               a volume that is no longer mounted. This error is
+     *                               unrecoverable until the package is available again, and
+     *                               should not be re-tried except on a time scheduled basis.
      * @hide
      */
+    @CheckResult
     @SystemApi
     @RequiresPermission(android.Manifest.permission.UPDATE_DOMAIN_VERIFICATION_USER_SELECTION)
     public int setDomainVerificationUserSelection(@NonNull UUID domainSetId,
             @NonNull Set<String> domains, boolean enabled) throws NameNotFoundException {
+        validateInput(domainSetId, domains);
+
         try {
             return mDomainVerificationManager.setDomainVerificationUserSelection(
                     domainSetId.toString(), new DomainSet(domains), enabled, mContext.getUserId());
@@ -341,11 +316,11 @@
     }
 
     /**
-     * Retrieve the user selection data for the given {@param packageName} and the current user.
+     * Retrieve the user state for the given package and the {@link Context}'s user.
      *
      * @param packageName The app to query state for.
-     * @return the user selection verification data for the given package for the current user, or
-     * null if the package does not declare any HTTP/HTTPS domains.
+     * @return The user selection verification data for the given package for the user, or null if
+     * the package does not declare any HTTP/HTTPS domains.
      */
     @Nullable
     public DomainVerificationUserState getDomainVerificationUserState(
@@ -405,4 +380,12 @@
             return exception;
         }
     }
+
+    private void validateInput(@Nullable UUID domainSetId, @Nullable Set<String> domains) {
+        if (domainSetId == null) {
+            throw new IllegalArgumentException("domainSetId cannot be null");
+        } else if (CollectionUtils.isEmpty(domains)) {
+            throw new IllegalArgumentException("Provided domain set cannot be empty");
+        }
+    }
 }
diff --git a/core/java/android/content/res/ColorStateList.java b/core/java/android/content/res/ColorStateList.java
index 921c630..cdd8265 100644
--- a/core/java/android/content/res/ColorStateList.java
+++ b/core/java/android/content/res/ColorStateList.java
@@ -34,6 +34,7 @@
 import android.util.Xml;
 
 import com.android.internal.R;
+import com.android.internal.graphics.ColorUtils;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.GrowingArrayUtils;
 
@@ -112,6 +113,18 @@
  *         android:color="?android:attr/colorAccent"
  *         android:alpha="0.5" /&gt;
  * </pre>
+ * <p>
+ * Starting with API 31, items may optionally define an {@link android.R.attr#lStar android:lStar}
+ * attribute to modify the base color's perceptual luminance. This attribute takes a either
+ * floating-point value between 0 and 100 or a theme attribute that resolves as such. The item's
+ * overall color is calculated by converting the base color to an accessibility friendly color space
+ * and setting its L* to the value specified on the {@code lStar} attribute. For
+ * example, the following item represents the theme's accent color at 50% perpectual luminosity:
+ * <pre>
+ * &lt;item android:state_enabled="false"
+ *         android:color="?android:attr/colorAccent"
+ *         android:lStar="50" /&gt;
+ * </pre>
  *
  * <a name="DeveloperGuide"></a>
  * <h3>Developer guide</h3>
@@ -122,6 +135,7 @@
  *
  * @attr ref android.R.styleable#ColorStateListItem_alpha
  * @attr ref android.R.styleable#ColorStateListItem_color
+ * @attr ref android.R.styleable#ColorStateListItem_lStar
  */
 public class ColorStateList extends ComplexColor implements Parcelable {
     private static final String TAG = "ColorStateList";
@@ -301,6 +315,24 @@
     }
 
     /**
+     * Creates a new ColorStateList that has the same states and colors as this
+     * one but where each color has the specified perceived luminosity value (0-100).
+     *
+     * @param lStar Target perceptual luminance (0-100).
+     * @return A new color state list.
+     */
+    @NonNull
+    public ColorStateList withLStar(float lStar) {
+        final int[] colors = new int[mColors.length];
+        final int len = colors.length;
+        for (int i = 0; i < len; i++) {
+            colors[i] = modulateColor(mColors[i], 1.0f /* alphaMod */, lStar);
+        }
+
+        return new ColorStateList(mStateSpecs, colors);
+    }
+
+    /**
      * Fill in this object based on the contents of an XML "selector" element.
      */
     private void inflate(@NonNull Resources r, @NonNull XmlPullParser parser,
@@ -332,6 +364,7 @@
             final int[] themeAttrs = a.extractThemeAttrs();
             final int baseColor = a.getColor(R.styleable.ColorStateListItem_color, Color.MAGENTA);
             final float alphaMod = a.getFloat(R.styleable.ColorStateListItem_alpha, 1.0f);
+            final float lStar = a.getFloat(R.styleable.ColorStateListItem_lStar, -1.0f);
 
             changingConfigurations |= a.getChangingConfigurations();
 
@@ -346,6 +379,7 @@
                 switch (stateResId) {
                     case R.attr.color:
                     case R.attr.alpha:
+                    case R.attr.lStar:
                         // Recognized attribute, ignore.
                         break;
                     default:
@@ -355,10 +389,11 @@
             }
             stateSpec = StateSet.trimStateSet(stateSpec, j);
 
-            // Apply alpha modulation. If we couldn't resolve the color or
+            // Apply alpha and luma modulation. If we couldn't resolve the color or
             // alpha yet, the default values leave us enough information to
             // modulate again during applyTheme().
-            final int color = modulateColorAlpha(baseColor, alphaMod);
+            final int color = modulateColor(baseColor, alphaMod, lStar);
+
             if (listSize == 0 || stateSpec.length == 0) {
                 defaultColor = color;
             }
@@ -455,7 +490,9 @@
                         R.styleable.ColorStateListItem_color, mColors[i]);
                 final float alphaMod = a.getFloat(
                         R.styleable.ColorStateListItem_alpha, defaultAlphaMod);
-                mColors[i] = modulateColorAlpha(baseColor, alphaMod);
+                final float lStar = a.getFloat(
+                        R.styleable.ColorStateListItem_lStar, -1.0f);
+                mColors[i] = modulateColor(baseColor, alphaMod, lStar);
 
                 // Account for any configuration changes.
                 mChangingConfigurations |= a.getChangingConfigurations();
@@ -505,13 +542,21 @@
         return super.getChangingConfigurations() | mChangingConfigurations;
     }
 
-    private int modulateColorAlpha(int baseColor, float alphaMod) {
-        if (alphaMod == 1.0f) {
+    private int modulateColor(int baseColor, float alphaMod, float lStar) {
+        final boolean validLStar = lStar >= 0.0f && lStar <= 100.0f;
+        if (alphaMod == 1.0f && !validLStar) {
             return baseColor;
         }
 
         final int baseAlpha = Color.alpha(baseColor);
         final int alpha = MathUtils.constrain((int) (baseAlpha * alphaMod + 0.5f), 0, 255);
+
+        if (validLStar) {
+            final double[] labColor = new double[3];
+            ColorUtils.colorToLAB(baseColor, labColor);
+            baseColor = ColorUtils.LABToColor(lStar, labColor[1], labColor[2]);
+        }
+
         return (baseColor & 0xFFFFFF) | (alpha << 24);
     }
 
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index aed0823..ac4b7b7 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -360,7 +360,7 @@
                 WeakReference<Theme> weakThemeRef = mThemeRefs.get(i);
                 Theme theme = weakThemeRef != null ? weakThemeRef.get() : null;
                 if (theme != null) {
-                    theme.setImpl(mResourcesImpl.newThemeImpl(theme.getKey()));
+                    theme.setNewResourcesImpl(mResourcesImpl);
                 }
             }
         }
@@ -1500,6 +1500,9 @@
      * retrieve XML attributes with style and theme information applied.
      */
     public final class Theme {
+        private final Object mLock = new Object();
+
+        @GuardedBy("mLock")
         @UnsupportedAppUsage
         private ResourcesImpl.ThemeImpl mThemeImpl;
 
@@ -1507,7 +1510,15 @@
         }
 
         void setImpl(ResourcesImpl.ThemeImpl impl) {
-            mThemeImpl = impl;
+            synchronized (mLock) {
+                mThemeImpl = impl;
+            }
+        }
+
+        void setNewResourcesImpl(ResourcesImpl resImpl) {
+            synchronized (mLock) {
+                mThemeImpl = resImpl.newThemeImpl(mThemeImpl.getKey());
+            }
         }
 
         /**
@@ -1528,7 +1539,9 @@
          *              if not already defined in the theme.
          */
         public void applyStyle(int resId, boolean force) {
-            mThemeImpl.applyStyle(resId, force);
+            synchronized (mLock) {
+                mThemeImpl.applyStyle(resId, force);
+            }
         }
 
         /**
@@ -1541,7 +1554,11 @@
          * @param other The existing Theme to copy from.
          */
         public void setTo(Theme other) {
-            mThemeImpl.setTo(other.mThemeImpl);
+            synchronized (mLock) {
+                synchronized (other.mLock) {
+                    mThemeImpl.setTo(other.mThemeImpl);
+                }
+            }
         }
 
         /**
@@ -1566,7 +1583,9 @@
          */
         @NonNull
         public TypedArray obtainStyledAttributes(@NonNull @StyleableRes int[] attrs) {
-            return mThemeImpl.obtainStyledAttributes(this, null, attrs, 0, 0);
+            synchronized (mLock) {
+                return mThemeImpl.obtainStyledAttributes(this, null, attrs, 0, 0);
+            }
         }
 
         /**
@@ -1594,7 +1613,9 @@
         public TypedArray obtainStyledAttributes(@StyleRes int resId,
                 @NonNull @StyleableRes int[] attrs)
                 throws NotFoundException {
-            return mThemeImpl.obtainStyledAttributes(this, null, attrs, 0, resId);
+            synchronized (mLock) {
+                return mThemeImpl.obtainStyledAttributes(this, null, attrs, 0, resId);
+            }
         }
 
         /**
@@ -1650,7 +1671,10 @@
         public TypedArray obtainStyledAttributes(@Nullable AttributeSet set,
                 @NonNull @StyleableRes int[] attrs, @AttrRes int defStyleAttr,
                 @StyleRes int defStyleRes) {
-            return mThemeImpl.obtainStyledAttributes(this, set, attrs, defStyleAttr, defStyleRes);
+            synchronized (mLock) {
+                return mThemeImpl.obtainStyledAttributes(this, set, attrs, defStyleAttr,
+                        defStyleRes);
+            }
         }
 
         /**
@@ -1671,7 +1695,9 @@
         @NonNull
         @UnsupportedAppUsage
         public TypedArray resolveAttributes(@NonNull int[] values, @NonNull int[] attrs) {
-            return mThemeImpl.resolveAttributes(this, values, attrs);
+            synchronized (mLock) {
+                return mThemeImpl.resolveAttributes(this, values, attrs);
+            }
         }
 
         /**
@@ -1692,7 +1718,9 @@
          *         <var>outValue</var> is valid, else false.
          */
         public boolean resolveAttribute(int resid, TypedValue outValue, boolean resolveRefs) {
-            return mThemeImpl.resolveAttribute(resid, outValue, resolveRefs);
+            synchronized (mLock) {
+                return mThemeImpl.resolveAttribute(resid, outValue, resolveRefs);
+            }
         }
 
         /**
@@ -1702,7 +1730,9 @@
          * @hide
          */
         public int[] getAllAttributes() {
-            return mThemeImpl.getAllAttributes();
+            synchronized (mLock) {
+                return mThemeImpl.getAllAttributes();
+            }
         }
 
         /**
@@ -1738,7 +1768,9 @@
          * @see ActivityInfo
          */
         public @Config int getChangingConfigurations() {
-            return mThemeImpl.getChangingConfigurations();
+            synchronized (mLock) {
+                return mThemeImpl.getChangingConfigurations();
+            }
         }
 
         /**
@@ -1749,23 +1781,31 @@
          * @param prefix Text to prefix each line printed.
          */
         public void dump(int priority, String tag, String prefix) {
-            mThemeImpl.dump(priority, tag, prefix);
+            synchronized (mLock) {
+                mThemeImpl.dump(priority, tag, prefix);
+            }
         }
 
         // Needed by layoutlib.
         /*package*/ long getNativeTheme() {
-            return mThemeImpl.getNativeTheme();
+            synchronized (mLock) {
+                return mThemeImpl.getNativeTheme();
+            }
         }
 
         /*package*/ int getAppliedStyleResId() {
-            return mThemeImpl.getAppliedStyleResId();
+            synchronized (mLock) {
+                return mThemeImpl.getAppliedStyleResId();
+            }
         }
 
         /**
          * @hide
          */
         public ThemeKey getKey() {
-            return mThemeImpl.getKey();
+            synchronized (mLock) {
+                return mThemeImpl.getKey();
+            }
         }
 
         private String getResourceNameFromHexString(String hexString) {
@@ -1781,7 +1821,9 @@
          */
         @ViewDebug.ExportedProperty(category = "theme", hasAdjacentMapping = true)
         public String[] getTheme() {
-            return mThemeImpl.getTheme();
+            synchronized (mLock) {
+                return mThemeImpl.getTheme();
+            }
         }
 
         /** @hide */
@@ -1800,7 +1842,9 @@
          * {@link #applyStyle(int, boolean)}.
          */
         public void rebase() {
-            mThemeImpl.rebase();
+            synchronized (mLock) {
+                mThemeImpl.rebase();
+            }
         }
 
         /**
@@ -1862,12 +1906,14 @@
         @NonNull
         public int[] getAttributeResolutionStack(@AttrRes int defStyleAttr,
                 @StyleRes int defStyleRes, @StyleRes int explicitStyleRes) {
-            int[] stack = mThemeImpl.getAttributeResolutionStack(
-                    defStyleAttr, defStyleRes, explicitStyleRes);
-            if (stack == null) {
-                return new int[0];
-            } else {
-                return stack;
+            synchronized (mLock) {
+                int[] stack = mThemeImpl.getAttributeResolutionStack(
+                        defStyleAttr, defStyleRes, explicitStyleRes);
+                if (stack == null) {
+                    return new int[0];
+                } else {
+                    return stack;
+                }
             }
         }
     }
diff --git a/core/java/android/content/res/ResourcesImpl.java b/core/java/android/content/res/ResourcesImpl.java
index cbcdb37..553e11b 100644
--- a/core/java/android/content/res/ResourcesImpl.java
+++ b/core/java/android/content/res/ResourcesImpl.java
@@ -1314,22 +1314,16 @@
         }
 
         void applyStyle(int resId, boolean force) {
-            synchronized (mKey) {
-                mAssets.applyStyleToTheme(mTheme, resId, force);
-                mThemeResId = resId;
-                mKey.append(resId, force);
-            }
+            mAssets.applyStyleToTheme(mTheme, resId, force);
+            mThemeResId = resId;
+            mKey.append(resId, force);
         }
 
         void setTo(ThemeImpl other) {
-            synchronized (mKey) {
-                synchronized (other.mKey) {
-                    mAssets.setThemeTo(mTheme, other.mAssets, other.mTheme);
+            mAssets.setThemeTo(mTheme, other.mAssets, other.mTheme);
 
-                    mThemeResId = other.mThemeResId;
-                    mKey.setTo(other.getKey());
-                }
-            }
+            mThemeResId = other.mThemeResId;
+            mKey.setTo(other.getKey());
         }
 
         @NonNull
@@ -1338,46 +1332,40 @@
                 @StyleableRes int[] attrs,
                 @AttrRes int defStyleAttr,
                 @StyleRes int defStyleRes) {
-            synchronized (mKey) {
-                final int len = attrs.length;
-                final TypedArray array = TypedArray.obtain(wrapper.getResources(), len);
+            final int len = attrs.length;
+            final TypedArray array = TypedArray.obtain(wrapper.getResources(), len);
 
-                // XXX note that for now we only work with compiled XML files.
-                // To support generic XML files we will need to manually parse
-                // out the attributes from the XML file (applying type information
-                // contained in the resources and such).
-                final XmlBlock.Parser parser = (XmlBlock.Parser) set;
-                mAssets.applyStyle(mTheme, defStyleAttr, defStyleRes, parser, attrs,
-                        array.mDataAddress, array.mIndicesAddress);
-                array.mTheme = wrapper;
-                array.mXml = parser;
-                return array;
-            }
+            // XXX note that for now we only work with compiled XML files.
+            // To support generic XML files we will need to manually parse
+            // out the attributes from the XML file (applying type information
+            // contained in the resources and such).
+            final XmlBlock.Parser parser = (XmlBlock.Parser) set;
+            mAssets.applyStyle(mTheme, defStyleAttr, defStyleRes, parser, attrs,
+                    array.mDataAddress, array.mIndicesAddress);
+            array.mTheme = wrapper;
+            array.mXml = parser;
+            return array;
         }
 
         @NonNull
         TypedArray resolveAttributes(@NonNull Resources.Theme wrapper,
                 @NonNull int[] values,
                 @NonNull int[] attrs) {
-            synchronized (mKey) {
-                final int len = attrs.length;
-                if (values == null || len != values.length) {
-                    throw new IllegalArgumentException(
-                            "Base attribute values must the same length as attrs");
-                }
-
-                final TypedArray array = TypedArray.obtain(wrapper.getResources(), len);
-                mAssets.resolveAttrs(mTheme, 0, 0, values, attrs, array.mData, array.mIndices);
-                array.mTheme = wrapper;
-                array.mXml = null;
-                return array;
+            final int len = attrs.length;
+            if (values == null || len != values.length) {
+                throw new IllegalArgumentException(
+                        "Base attribute values must the same length as attrs");
             }
+
+            final TypedArray array = TypedArray.obtain(wrapper.getResources(), len);
+            mAssets.resolveAttrs(mTheme, 0, 0, values, attrs, array.mData, array.mIndices);
+            array.mTheme = wrapper;
+            array.mXml = null;
+            return array;
         }
 
         boolean resolveAttribute(int resid, TypedValue outValue, boolean resolveRefs) {
-            synchronized (mKey) {
-                return mAssets.getThemeValue(mTheme, resid, outValue, resolveRefs);
-            }
+            return mAssets.getThemeValue(mTheme, resid, outValue, resolveRefs);
         }
 
         int[] getAllAttributes() {
@@ -1385,35 +1373,29 @@
         }
 
         @Config int getChangingConfigurations() {
-            synchronized (mKey) {
-                final @NativeConfig int nativeChangingConfig =
-                        AssetManager.nativeThemeGetChangingConfigurations(mTheme);
-                return ActivityInfo.activityInfoConfigNativeToJava(nativeChangingConfig);
-            }
+            final @NativeConfig int nativeChangingConfig =
+                    AssetManager.nativeThemeGetChangingConfigurations(mTheme);
+            return ActivityInfo.activityInfoConfigNativeToJava(nativeChangingConfig);
         }
 
         public void dump(int priority, String tag, String prefix) {
-            synchronized (mKey) {
-                mAssets.dumpTheme(mTheme, priority, tag, prefix);
-            }
+            mAssets.dumpTheme(mTheme, priority, tag, prefix);
         }
 
         String[] getTheme() {
-            synchronized (mKey) {
-                final int N = mKey.mCount;
-                final String[] themes = new String[N * 2];
-                for (int i = 0, j = N - 1; i < themes.length; i += 2, --j) {
-                    final int resId = mKey.mResId[j];
-                    final boolean forced = mKey.mForce[j];
-                    try {
-                        themes[i] = getResourceName(resId);
-                    } catch (NotFoundException e) {
-                        themes[i] = Integer.toHexString(i);
-                    }
-                    themes[i + 1] = forced ? "forced" : "not forced";
+            final int n = mKey.mCount;
+            final String[] themes = new String[n * 2];
+            for (int i = 0, j = n - 1; i < themes.length; i += 2, --j) {
+                final int resId = mKey.mResId[j];
+                final boolean forced = mKey.mForce[j];
+                try {
+                    themes[i] = getResourceName(resId);
+                } catch (NotFoundException e) {
+                    themes[i] = Integer.toHexString(i);
                 }
-                return themes;
+                themes[i + 1] = forced ? "forced" : "not forced";
             }
+            return themes;
         }
 
         /**
@@ -1422,15 +1404,13 @@
          * {@link #applyStyle(int, boolean)}.
          */
         void rebase() {
-            synchronized (mKey) {
-                AssetManager.nativeThemeClear(mTheme);
+            AssetManager.nativeThemeClear(mTheme);
 
-                // Reapply the same styles in the same order.
-                for (int i = 0; i < mKey.mCount; i++) {
-                    final int resId = mKey.mResId[i];
-                    final boolean force = mKey.mForce[i];
-                    mAssets.applyStyleToTheme(mTheme, resId, force);
-                }
+            // Reapply the same styles in the same order.
+            for (int i = 0; i < mKey.mCount; i++) {
+                final int resId = mKey.mResId[i];
+                final boolean force = mKey.mForce[i];
+                mAssets.applyStyleToTheme(mTheme, resId, force);
             }
         }
 
@@ -1455,10 +1435,8 @@
         @Nullable
         public int[] getAttributeResolutionStack(@AttrRes int defStyleAttr,
                 @StyleRes int defStyleRes, @StyleRes int explicitStyleRes) {
-            synchronized (mKey) {
-                return mAssets.getAttributeResolutionStack(
-                        mTheme, defStyleAttr, defStyleRes, explicitStyleRes);
-            }
+            return mAssets.getAttributeResolutionStack(
+                    mTheme, defStyleAttr, defStyleRes, explicitStyleRes);
         }
     }
 
diff --git a/core/java/android/content/res/TypedArray.java b/core/java/android/content/res/TypedArray.java
index 5eaa766..2a349e9 100644
--- a/core/java/android/content/res/TypedArray.java
+++ b/core/java/android/content/res/TypedArray.java
@@ -46,7 +46,7 @@
  * The indices used to retrieve values from this structure correspond to
  * the positions of the attributes given to obtainStyledAttributes.
  */
-public class TypedArray {
+public class TypedArray implements AutoCloseable {
 
     static TypedArray obtain(Resources res, int len) {
         TypedArray attrs = res.mTypedArrayPool.acquire();
@@ -1253,6 +1253,17 @@
     }
 
     /**
+     * Recycles the TypedArray, to be re-used by a later caller. After calling
+     * this function you must not ever touch the typed array again.
+     *
+     * @see #recycle()
+     * @throws RuntimeException if the TypedArray has already been recycled.
+     */
+    public void close() {
+        recycle();
+    }
+
+    /**
      * Extracts theme attributes from a typed array for later resolution using
      * {@link android.content.res.Resources.Theme#resolveAttributes(int[], int[])}.
      * Removes the entries from the typed array so that subsequent calls to typed
diff --git a/core/java/android/hardware/SensorPrivacyManager.java b/core/java/android/hardware/SensorPrivacyManager.java
index e03c1f4..d30848f 100644
--- a/core/java/android/hardware/SensorPrivacyManager.java
+++ b/core/java/android/hardware/SensorPrivacyManager.java
@@ -22,6 +22,7 @@
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
 import android.annotation.TestApi;
+import android.annotation.UserIdInt;
 import android.content.Context;
 import android.os.Binder;
 import android.os.IBinder;
@@ -229,7 +230,25 @@
     @RequiresPermission(android.Manifest.permission.OBSERVE_SENSOR_PRIVACY)
     public void addSensorPrivacyListener(@Sensors.Sensor int sensor,
             @NonNull OnSensorPrivacyChangedListener listener) {
-        addSensorPrivacyListener(sensor, mContext.getMainExecutor(), listener);
+        addSensorPrivacyListener(sensor, mContext.getUserId(), mContext.getMainExecutor(),
+                listener);
+    }
+
+    /**
+     * Registers a new listener to receive notification when the state of sensor privacy
+     * changes.
+     *
+     * @param sensor the sensor to listen to changes to
+     * @param userId the user's id
+     * @param listener the OnSensorPrivacyChangedListener to be notified when the state of sensor
+     *                 privacy changes.
+     *
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.OBSERVE_SENSOR_PRIVACY)
+    public void addSensorPrivacyListener(@Sensors.Sensor int sensor, @UserIdInt int userId,
+            @NonNull OnSensorPrivacyChangedListener listener) {
+        addSensorPrivacyListener(sensor, userId, mContext.getMainExecutor(), listener);
     }
 
     /**
@@ -248,6 +267,24 @@
     @RequiresPermission(android.Manifest.permission.OBSERVE_SENSOR_PRIVACY)
     public void addSensorPrivacyListener(@Sensors.Sensor int sensor, @NonNull Executor executor,
             @NonNull OnSensorPrivacyChangedListener listener) {
+        addSensorPrivacyListener(sensor, mContext.getUserId(), executor, listener);
+    }
+
+    /**
+     * Registers a new listener to receive notification when the state of sensor privacy
+     * changes.
+     *
+     * @param sensor the sensor to listen to changes to
+     * @param executor the executor to dispatch the callback on
+     * @param userId the user's id
+     * @param listener the OnSensorPrivacyChangedListener to be notified when the state of sensor
+     *                 privacy changes.
+     *
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.OBSERVE_SENSOR_PRIVACY)
+    public void addSensorPrivacyListener(@Sensors.Sensor int sensor, @UserIdInt int userId,
+            @NonNull Executor executor, @NonNull OnSensorPrivacyChangedListener listener) {
         synchronized (mListeners) {
             ISensorPrivacyListener iListener = mListeners.get(listener);
             if (iListener == null) {
@@ -261,7 +298,7 @@
             }
 
             try {
-                mService.addIndividualSensorPrivacyListener(mContext.getUserId(), sensor,
+                mService.addIndividualSensorPrivacyListener(userId, sensor,
                         iListener);
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
@@ -322,8 +359,20 @@
     @TestApi
     @RequiresPermission(android.Manifest.permission.OBSERVE_SENSOR_PRIVACY)
     public boolean isSensorPrivacyEnabled(@Sensors.Sensor int sensor) {
+        return isSensorPrivacyEnabled(sensor, mContext.getUserId());
+    }
+
+    /**
+     * Returns whether sensor privacy is currently enabled for a specific sensor.
+     *
+     * @return true if sensor privacy is currently enabled, false otherwise.
+     *
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.OBSERVE_SENSOR_PRIVACY)
+    public boolean isSensorPrivacyEnabled(@Sensors.Sensor int sensor, @UserIdInt int userId) {
         try {
-            return mService.isIndividualSensorPrivacyEnabled(mContext.getUserId(), sensor);
+            return mService.isIndividualSensorPrivacyEnabled(userId, sensor);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -340,8 +389,23 @@
     @TestApi
     @RequiresPermission(android.Manifest.permission.MANAGE_SENSOR_PRIVACY)
     public void setSensorPrivacy(@Sensors.Sensor int sensor, boolean enable) {
+        setSensorPrivacy(sensor, enable, mContext.getUserId());
+    }
+
+    /**
+     * Sets sensor privacy to the specified state for an individual sensor.
+     *
+     * @param sensor the sensor which to change the state for
+     * @param enable the state to which sensor privacy should be set.
+     * @param userId the user's id
+     *
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.MANAGE_SENSOR_PRIVACY)
+    public void setSensorPrivacy(@Sensors.Sensor int sensor, boolean enable,
+            @UserIdInt int userId) {
         try {
-            mService.setIndividualSensorPrivacy(mContext.getUserId(), sensor, enable);
+            mService.setIndividualSensorPrivacy(userId, sensor, enable);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -360,8 +424,24 @@
     @RequiresPermission(android.Manifest.permission.MANAGE_SENSOR_PRIVACY)
     public void setSensorPrivacyForProfileGroup(@Sensors.Sensor int sensor,
             boolean enable) {
+        setSensorPrivacyForProfileGroup(sensor, enable, mContext.getUserId());
+    }
+
+    /**
+     * Sets sensor privacy to the specified state for an individual sensor for the profile group of
+     * context's user.
+     *
+     * @param sensor the sensor which to change the state for
+     * @param enable the state to which sensor privacy should be set.
+     * @param userId the user's id
+     *
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.MANAGE_SENSOR_PRIVACY)
+    public void setSensorPrivacyForProfileGroup(@Sensors.Sensor int sensor,
+            boolean enable, @UserIdInt int userId) {
         try {
-            mService.setIndividualSensorPrivacyForProfileGroup(mContext.getUserId(), sensor,
+            mService.setIndividualSensorPrivacyForProfileGroup(userId, sensor,
                     enable);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -379,8 +459,23 @@
     @RequiresPermission(android.Manifest.permission.MANAGE_SENSOR_PRIVACY)
     public void suppressSensorPrivacyReminders(@NonNull String packageName,
             boolean suppress) {
+        suppressSensorPrivacyReminders(packageName, suppress, mContext.getUserId());
+    }
+
+    /**
+     * Don't show dialogs to turn off sensor privacy for this package.
+     *
+     * @param packageName Package name not to show dialogs for
+     * @param suppress Whether to suppress or re-enable.
+     * @param userId the user's id
+     *
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.MANAGE_SENSOR_PRIVACY)
+    public void suppressSensorPrivacyReminders(@NonNull String packageName,
+            boolean suppress, @UserIdInt int userId) {
         try {
-            mService.suppressIndividualSensorPrivacyReminders(mContext.getUserId(), packageName,
+            mService.suppressIndividualSensorPrivacyReminders(userId, packageName,
                     token, suppress);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 07ebbaf..6654c2c 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -1210,6 +1210,25 @@
             new Key<android.util.Range<Float>>("android.control.zoomRatioRange", new TypeReference<android.util.Range<Float>>() {{ }});
 
     /**
+     * <p>List of available high speed video size, fps range and max batch size configurations
+     * supported by the camera device, in the format of
+     * (width, height, fps_min, fps_max, batch_size_max),
+     * when {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} is set to
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }.</p>
+     * <p>Analogous to android.control.availableHighSpeedVideoConfigurations, for configurations
+     * which are applicable when {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} is set to
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }.</p>
+     * <p><b>Range of valid values:</b><br></p>
+     * <p>For each configuration, the fps_max &gt;= 120fps.</p>
+     * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
+     *
+     * @see CaptureRequest#SENSOR_PIXEL_MODE
+     * @hide
+     */
+    public static final Key<android.hardware.camera2.params.HighSpeedVideoConfiguration[]> CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS_MAXIMUM_RESOLUTION =
+            new Key<android.hardware.camera2.params.HighSpeedVideoConfiguration[]>("android.control.availableHighSpeedVideoConfigurationsMaximumResolution", android.hardware.camera2.params.HighSpeedVideoConfiguration[].class);
+
+    /**
      * <p>List of edge enhancement modes for {@link CaptureRequest#EDGE_MODE android.edge.mode} that are supported by this camera
      * device.</p>
      * <p>Full-capability camera devices must always support OFF; camera devices that support
@@ -1770,6 +1789,48 @@
             new Key<float[]>("android.lens.distortion", float[].class);
 
     /**
+     * <p>The correction coefficients to correct for this camera device's
+     * radial and tangential lens distortion for a
+     * CaptureRequest with {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} set to
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }.</p>
+     * <p>Analogous to {@link CameraCharacteristics#LENS_DISTORTION android.lens.distortion}, when {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} is set to
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }.</p>
+     * <p><b>Units</b>:
+     * Unitless coefficients.</p>
+     * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
+     * <p><b>Permission {@link android.Manifest.permission#CAMERA } is needed to access this property</b></p>
+     *
+     * @see CameraCharacteristics#LENS_DISTORTION
+     * @see CaptureRequest#SENSOR_PIXEL_MODE
+     */
+    @PublicKey
+    @NonNull
+    public static final Key<float[]> LENS_DISTORTION_MAXIMUM_RESOLUTION =
+            new Key<float[]>("android.lens.distortionMaximumResolution", float[].class);
+
+    /**
+     * <p>The parameters for this camera device's intrinsic
+     * calibration when {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} is set to
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }.</p>
+     * <p>Analogous to {@link CameraCharacteristics#LENS_INTRINSIC_CALIBRATION android.lens.intrinsicCalibration}, when {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} is set to
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }.</p>
+     * <p><b>Units</b>:
+     * Pixels in the
+     * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION android.sensor.info.preCorrectionActiveArraySizeMaximumResolution}
+     * coordinate system.</p>
+     * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
+     * <p><b>Permission {@link android.Manifest.permission#CAMERA } is needed to access this property</b></p>
+     *
+     * @see CameraCharacteristics#LENS_INTRINSIC_CALIBRATION
+     * @see CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION
+     * @see CaptureRequest#SENSOR_PIXEL_MODE
+     */
+    @PublicKey
+    @NonNull
+    public static final Key<float[]> LENS_INTRINSIC_CALIBRATION_MAXIMUM_RESOLUTION =
+            new Key<float[]>("android.lens.intrinsicCalibrationMaximumResolution", float[].class);
+
+    /**
      * <p>List of noise reduction modes for {@link CaptureRequest#NOISE_REDUCTION_MODE android.noiseReduction.mode} that are supported
      * by this camera device.</p>
      * <p>Full-capability camera devices will always support OFF and FAST.</p>
@@ -2056,6 +2117,8 @@
      *   <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_SECURE_IMAGE_DATA SECURE_IMAGE_DATA}</li>
      *   <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_SYSTEM_CAMERA SYSTEM_CAMERA}</li>
      *   <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_OFFLINE_PROCESSING OFFLINE_PROCESSING}</li>
+     *   <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR ULTRA_HIGH_RESOLUTION_SENSOR}</li>
+     *   <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_REMOSAIC_REPROCESSING REMOSAIC_REPROCESSING}</li>
      * </ul>
      *
      * <p>This key is available on all devices.</p>
@@ -2077,6 +2140,8 @@
      * @see #REQUEST_AVAILABLE_CAPABILITIES_SECURE_IMAGE_DATA
      * @see #REQUEST_AVAILABLE_CAPABILITIES_SYSTEM_CAMERA
      * @see #REQUEST_AVAILABLE_CAPABILITIES_OFFLINE_PROCESSING
+     * @see #REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR
+     * @see #REQUEST_AVAILABLE_CAPABILITIES_REMOSAIC_REPROCESSING
      */
     @PublicKey
     @NonNull
@@ -2535,8 +2600,6 @@
      * set to either OFF or FAST.</p>
      * <p>When multiple streams are used in a request, the minimum frame
      * duration will be max(individual stream min durations).</p>
-     * <p>The minimum frame duration of a stream (of a particular format, size)
-     * is the same regardless of whether the stream is input or output.</p>
      * <p>See {@link CaptureRequest#SENSOR_FRAME_DURATION android.sensor.frameDuration} and
      * android.scaler.availableStallDurations for more details about
      * calculating the max frame rate.</p>
@@ -2916,10 +2979,10 @@
      * configurations which belong to this physical camera, and it will advertise and will only
      * advertise the maximum supported resolutions for a particular format.</p>
      * <p>If this camera device isn't a physical camera device constituting a logical camera,
-     * but a standalone ULTRA_HIGH_RESOLUTION_SENSOR camera, this field represents the
-     * multi-resolution input/output stream configurations of default mode and max resolution
-     * modes. The sizes will be the maximum resolution of a particular format for default mode
-     * and max resolution mode.</p>
+     * but a standalone {@link android.hardware.camera2.CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR }
+     * camera, this field represents the multi-resolution input/output stream configurations of
+     * default mode and max resolution modes. The sizes will be the maximum resolution of a
+     * particular format for default mode and max resolution mode.</p>
      * <p>This field will only be advertised if the device is a physical camera of a
      * logical multi-camera device or an ultra high resolution sensor camera. For a logical
      * multi-camera, the camera API will derive the logical camera’s multi-resolution stream
@@ -2977,6 +3040,132 @@
             new Key<android.hardware.camera2.params.MultiResolutionStreamConfigurationMap>("android.scaler.multiResolutionStreamConfigurationMap", android.hardware.camera2.params.MultiResolutionStreamConfigurationMap.class);
 
     /**
+     * <p>The available stream configurations that this
+     * camera device supports (i.e. format, width, height, output/input stream) for a
+     * CaptureRequest with {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} set to
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }.</p>
+     * <p>Analogous to android.scaler.availableStreamConfigurations, for configurations
+     * which are applicable when {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} is set to
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }.</p>
+     * <p>Not all output formats may be supported in a configuration with
+     * an input stream of a particular format. For more details, see
+     * android.scaler.availableInputOutputFormatsMapMaximumResolution.</p>
+     * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
+     *
+     * @see CaptureRequest#SENSOR_PIXEL_MODE
+     * @hide
+     */
+    public static final Key<android.hardware.camera2.params.StreamConfiguration[]> SCALER_AVAILABLE_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION =
+            new Key<android.hardware.camera2.params.StreamConfiguration[]>("android.scaler.availableStreamConfigurationsMaximumResolution", android.hardware.camera2.params.StreamConfiguration[].class);
+
+    /**
+     * <p>This lists the minimum frame duration for each
+     * format/size combination when the camera device is sent a CaptureRequest with
+     * {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} set to
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }.</p>
+     * <p>Analogous to android.scaler.availableMinFrameDurations, for configurations
+     * which are applicable when {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} is set to
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }.</p>
+     * <p>When multiple streams are used in a request (if supported, when {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode}
+     * is set to
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }), the
+     * minimum frame duration will be max(individual stream min durations).</p>
+     * <p>See {@link CaptureRequest#SENSOR_FRAME_DURATION android.sensor.frameDuration} and
+     * android.scaler.availableStallDurationsMaximumResolution for more details about
+     * calculating the max frame rate.</p>
+     * <p><b>Units</b>: (format, width, height, ns) x n</p>
+     * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
+     *
+     * @see CaptureRequest#SENSOR_FRAME_DURATION
+     * @see CaptureRequest#SENSOR_PIXEL_MODE
+     * @hide
+     */
+    public static final Key<android.hardware.camera2.params.StreamConfigurationDuration[]> SCALER_AVAILABLE_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION =
+            new Key<android.hardware.camera2.params.StreamConfigurationDuration[]>("android.scaler.availableMinFrameDurationsMaximumResolution", android.hardware.camera2.params.StreamConfigurationDuration[].class);
+
+    /**
+     * <p>This lists the maximum stall duration for each
+     * output format/size combination when CaptureRequests are submitted with
+     * {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} set to
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }</p>
+     * <p>Analogous to android.scaler.availableMinFrameDurations, for configurations
+     * which are applicable when {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} is set to
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }.</p>
+     * <p><b>Units</b>: (format, width, height, ns) x n</p>
+     * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
+     *
+     * @see CaptureRequest#SENSOR_PIXEL_MODE
+     * @hide
+     */
+    public static final Key<android.hardware.camera2.params.StreamConfigurationDuration[]> SCALER_AVAILABLE_STALL_DURATIONS_MAXIMUM_RESOLUTION =
+            new Key<android.hardware.camera2.params.StreamConfigurationDuration[]>("android.scaler.availableStallDurationsMaximumResolution", android.hardware.camera2.params.StreamConfigurationDuration[].class);
+
+    /**
+     * <p>The available stream configurations that this
+     * camera device supports when given a CaptureRequest with {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode}
+     * set to
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION };
+     * also includes the minimum frame durations
+     * and the stall durations for each format/size combination.</p>
+     * <p>Analogous to {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP android.scaler.streamConfigurationMap} for CaptureRequests where
+     * {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} is
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }.</p>
+     * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
+     *
+     * @see CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP
+     * @see CaptureRequest#SENSOR_PIXEL_MODE
+     */
+    @PublicKey
+    @NonNull
+    @SyntheticKey
+    public static final Key<android.hardware.camera2.params.StreamConfigurationMap> SCALER_STREAM_CONFIGURATION_MAP_MAXIMUM_RESOLUTION =
+            new Key<android.hardware.camera2.params.StreamConfigurationMap>("android.scaler.streamConfigurationMapMaximumResolution", android.hardware.camera2.params.StreamConfigurationMap.class);
+
+    /**
+     * <p>The mapping of image formats that are supported by this
+     * camera device for input streams, to their corresponding output formats, when
+     * {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} is set to
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }.</p>
+     * <p>Analogous to android.scaler.availableInputOutputFormatsMap for CaptureRequests where
+     * {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} is
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }.</p>
+     * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
+     *
+     * @see CaptureRequest#SENSOR_PIXEL_MODE
+     * @hide
+     */
+    public static final Key<android.hardware.camera2.params.ReprocessFormatsMap> SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP_MAXIMUM_RESOLUTION =
+            new Key<android.hardware.camera2.params.ReprocessFormatsMap>("android.scaler.availableInputOutputFormatsMapMaximumResolution", android.hardware.camera2.params.ReprocessFormatsMap.class);
+
+    /**
+     * <p>An array of mandatory stream combinations which are applicable when
+     * {@link android.hardware.camera2.CaptureRequest } has {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} set
+     * to {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }.
+     * This is an app-readable conversion of the maximum resolution mandatory stream combination
+     * {@link android.hardware.camera2.CameraDevice#createCaptureSession tables}.</p>
+     * <p>The array of
+     * {@link android.hardware.camera2.params.MandatoryStreamCombination combinations} is
+     * generated according to the documented
+     * {@link android.hardware.camera2.CameraDevice#createCaptureSession guideline} for each
+     * device which has the
+     * {@link android.hardware.camera2.CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR }
+     * capability.
+     * Clients can use the array as a quick reference to find an appropriate camera stream
+     * combination.
+     * The mandatory stream combination array will be {@code null} in case the device is not an
+     * {@link android.hardware.camera2.CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR }
+     * device.</p>
+     * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
+     *
+     * @see CaptureRequest#SENSOR_PIXEL_MODE
+     */
+    @PublicKey
+    @NonNull
+    @SyntheticKey
+    public static final Key<android.hardware.camera2.params.MandatoryStreamCombination[]> SCALER_MANDATORY_MAXIMUM_RESOLUTION_STREAM_COMBINATIONS =
+            new Key<android.hardware.camera2.params.MandatoryStreamCombination[]>("android.scaler.mandatoryMaximumResolutionStreamCombinations", android.hardware.camera2.params.MandatoryStreamCombination[].class);
+
+    /**
      * <p>The area of the image sensor which corresponds to active pixels after any geometric
      * distortion correction has been applied.</p>
      * <p>This is the rectangle representing the size of the active region of the sensor (i.e.
@@ -3292,6 +3481,101 @@
             new Key<android.graphics.Rect>("android.sensor.info.preCorrectionActiveArraySize", android.graphics.Rect.class);
 
     /**
+     * <p>The area of the image sensor which corresponds to active pixels after any geometric
+     * distortion correction has been applied, when the sensor runs in maximum resolution mode.</p>
+     * <p>Analogous to {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}, when {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode}
+     * is set to
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }.
+     * Refer to {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} for details, with sensor array related keys
+     * replaced with their
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }
+     * counterparts.
+     * This key will only be present for devices which advertise the
+     * {@link android.hardware.camera2.CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR }
+     * capability.</p>
+     * <p><b>Units</b>: Pixel coordinates on the image sensor</p>
+     * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
+     *
+     * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
+     * @see CaptureRequest#SENSOR_PIXEL_MODE
+     */
+    @PublicKey
+    @NonNull
+    public static final Key<android.graphics.Rect> SENSOR_INFO_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION =
+            new Key<android.graphics.Rect>("android.sensor.info.activeArraySizeMaximumResolution", android.graphics.Rect.class);
+
+    /**
+     * <p>Dimensions of the full pixel array, possibly
+     * including black calibration pixels, when the sensor runs in maximum resolution mode.
+     * Analogous to {@link CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE android.sensor.info.pixelArraySize}, when {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} is
+     * set to
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }.</p>
+     * <p>The pixel count of the full pixel array of the image sensor, which covers
+     * {@link CameraCharacteristics#SENSOR_INFO_PHYSICAL_SIZE android.sensor.info.physicalSize} area. This represents the full pixel dimensions of
+     * the raw buffers produced by this sensor, when it runs in maximum resolution mode. That
+     * is, when {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} is set to
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }.
+     * This key will only be present for devices which advertise the
+     * {@link android.hardware.camera2.CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR }
+     * capability.</p>
+     * <p><b>Units</b>: Pixels</p>
+     * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
+     *
+     * @see CameraCharacteristics#SENSOR_INFO_PHYSICAL_SIZE
+     * @see CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE
+     * @see CaptureRequest#SENSOR_PIXEL_MODE
+     */
+    @PublicKey
+    @NonNull
+    public static final Key<android.util.Size> SENSOR_INFO_PIXEL_ARRAY_SIZE_MAXIMUM_RESOLUTION =
+            new Key<android.util.Size>("android.sensor.info.pixelArraySizeMaximumResolution", android.util.Size.class);
+
+    /**
+     * <p>The area of the image sensor which corresponds to active pixels prior to the
+     * application of any geometric distortion correction, when the sensor runs in maximum
+     * resolution mode. This key must be used for crop / metering regions, only when
+     * {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} is set to
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }.</p>
+     * <p>Analogous to {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize},
+     * when {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} is set to
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }.
+     * This key will only be present for devices which advertise the
+     * {@link android.hardware.camera2.CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR }
+     * capability.</p>
+     * <p><b>Units</b>: Pixel coordinates on the image sensor</p>
+     * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
+     *
+     * @see CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE
+     * @see CaptureRequest#SENSOR_PIXEL_MODE
+     */
+    @PublicKey
+    @NonNull
+    public static final Key<android.graphics.Rect> SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION =
+            new Key<android.graphics.Rect>("android.sensor.info.preCorrectionActiveArraySizeMaximumResolution", android.graphics.Rect.class);
+
+    /**
+     * <p>Dimensions of the group of pixels which are under the same color filter.
+     * This specifies the width and height (pair of integers) of the group of pixels which fall
+     * under the same color filter for ULTRA_HIGH_RESOLUTION sensors.</p>
+     * <p>Sensors can have pixels grouped together under the same color filter in order
+     * to improve various aspects of imaging such as noise reduction, low light
+     * performance etc. These groups can be of various sizes such as 2X2 (quad bayer),
+     * 3X3 (nona-bayer). This key specifies the length and width of the pixels grouped under
+     * the same color filter.</p>
+     * <p>This key will not be present if REMOSAIC_REPROCESSING is not supported, since RAW images
+     * will have a regular bayer pattern.</p>
+     * <p>This key will not be present for sensors which don't have the
+     * {@link android.hardware.camera2.CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR }
+     * capability.</p>
+     * <p><b>Units</b>: Pixels</p>
+     * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
+     */
+    @PublicKey
+    @NonNull
+    public static final Key<android.util.Size> SENSOR_INFO_BINNING_FACTOR =
+            new Key<android.util.Size>("android.sensor.info.binningFactor", android.util.Size.class);
+
+    /**
      * <p>The standard reference illuminant used as the scene light source when
      * calculating the {@link CameraCharacteristics#SENSOR_COLOR_TRANSFORM1 android.sensor.colorTransform1},
      * {@link CameraCharacteristics#SENSOR_CALIBRATION_TRANSFORM1 android.sensor.calibrationTransform1}, and
@@ -4150,6 +4434,111 @@
             new Key<android.hardware.camera2.params.StreamConfigurationDuration[]>("android.depth.availableDynamicDepthStallDurations", android.hardware.camera2.params.StreamConfigurationDuration[].class);
 
     /**
+     * <p>The available depth dataspace stream
+     * configurations that this camera device supports
+     * (i.e. format, width, height, output/input stream) when a CaptureRequest is submitted with
+     * {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} set to
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }.</p>
+     * <p>Analogous to android.depth.availableDepthStreamConfigurations, for configurations which
+     * are applicable when {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} is set to
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }.</p>
+     * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
+     *
+     * @see CaptureRequest#SENSOR_PIXEL_MODE
+     * @hide
+     */
+    public static final Key<android.hardware.camera2.params.StreamConfiguration[]> DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION =
+            new Key<android.hardware.camera2.params.StreamConfiguration[]>("android.depth.availableDepthStreamConfigurationsMaximumResolution", android.hardware.camera2.params.StreamConfiguration[].class);
+
+    /**
+     * <p>This lists the minimum frame duration for each
+     * format/size combination for depth output formats when a CaptureRequest is submitted with
+     * {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} set to
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }.</p>
+     * <p>Analogous to android.depth.availableDepthMinFrameDurations, for configurations which
+     * are applicable when {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} is set to
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }.</p>
+     * <p>See {@link CaptureRequest#SENSOR_FRAME_DURATION android.sensor.frameDuration} and
+     * android.scaler.availableStallDurationsMaximumResolution for more details about
+     * calculating the max frame rate.</p>
+     * <p><b>Units</b>: (format, width, height, ns) x n</p>
+     * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
+     *
+     * @see CaptureRequest#SENSOR_FRAME_DURATION
+     * @see CaptureRequest#SENSOR_PIXEL_MODE
+     * @hide
+     */
+    public static final Key<android.hardware.camera2.params.StreamConfigurationDuration[]> DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION =
+            new Key<android.hardware.camera2.params.StreamConfigurationDuration[]>("android.depth.availableDepthMinFrameDurationsMaximumResolution", android.hardware.camera2.params.StreamConfigurationDuration[].class);
+
+    /**
+     * <p>This lists the maximum stall duration for each
+     * output format/size combination for depth streams for CaptureRequests where
+     * {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} is set to
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }.</p>
+     * <p>Analogous to android.depth.availableDepthStallDurations, for configurations which
+     * are applicable when {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} is set to
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }.</p>
+     * <p><b>Units</b>: (format, width, height, ns) x n</p>
+     * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
+     *
+     * @see CaptureRequest#SENSOR_PIXEL_MODE
+     * @hide
+     */
+    public static final Key<android.hardware.camera2.params.StreamConfigurationDuration[]> DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS_MAXIMUM_RESOLUTION =
+            new Key<android.hardware.camera2.params.StreamConfigurationDuration[]>("android.depth.availableDepthStallDurationsMaximumResolution", android.hardware.camera2.params.StreamConfigurationDuration[].class);
+
+    /**
+     * <p>The available dynamic depth dataspace stream
+     * configurations that this camera device supports (i.e. format, width, height,
+     * output/input stream) for CaptureRequests where {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} is set to
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }.</p>
+     * <p>Analogous to android.depth.availableDynamicDepthStreamConfigurations, for configurations
+     * which are applicable when {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} is set to
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }.</p>
+     * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
+     *
+     * @see CaptureRequest#SENSOR_PIXEL_MODE
+     * @hide
+     */
+    public static final Key<android.hardware.camera2.params.StreamConfiguration[]> DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION =
+            new Key<android.hardware.camera2.params.StreamConfiguration[]>("android.depth.availableDynamicDepthStreamConfigurationsMaximumResolution", android.hardware.camera2.params.StreamConfiguration[].class);
+
+    /**
+     * <p>This lists the minimum frame duration for each
+     * format/size combination for dynamic depth output streams  for CaptureRequests where
+     * {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} is set to
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }.</p>
+     * <p>Analogous to android.depth.availableDynamicDepthMinFrameDurations, for configurations
+     * which are applicable when {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} is set to
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }.</p>
+     * <p><b>Units</b>: (format, width, height, ns) x n</p>
+     * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
+     *
+     * @see CaptureRequest#SENSOR_PIXEL_MODE
+     * @hide
+     */
+    public static final Key<android.hardware.camera2.params.StreamConfigurationDuration[]> DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION =
+            new Key<android.hardware.camera2.params.StreamConfigurationDuration[]>("android.depth.availableDynamicDepthMinFrameDurationsMaximumResolution", android.hardware.camera2.params.StreamConfigurationDuration[].class);
+
+    /**
+     * <p>This lists the maximum stall duration for each
+     * output format/size combination for dynamic depth streams for CaptureRequests where
+     * {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} is set to
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }.</p>
+     * <p>Analogous to android.depth.availableDynamicDepthStallDurations, for configurations
+     * which are applicable when {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} is set to
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }.</p>
+     * <p><b>Units</b>: (format, width, height, ns) x n</p>
+     * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
+     *
+     * @see CaptureRequest#SENSOR_PIXEL_MODE
+     * @hide
+     */
+    public static final Key<android.hardware.camera2.params.StreamConfigurationDuration[]> DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS_MAXIMUM_RESOLUTION =
+            new Key<android.hardware.camera2.params.StreamConfigurationDuration[]>("android.depth.availableDynamicDepthStallDurationsMaximumResolution", android.hardware.camera2.params.StreamConfigurationDuration[].class);
+
+    /**
      * <p>String containing the ids of the underlying physical cameras.</p>
      * <p>For a logical camera, this is concatenation of all underlying physical camera IDs.
      * The null terminator for physical camera ID must be preserved so that the whole string
@@ -4286,6 +4675,47 @@
     public static final Key<android.hardware.camera2.params.StreamConfigurationDuration[]> HEIC_AVAILABLE_HEIC_STALL_DURATIONS =
             new Key<android.hardware.camera2.params.StreamConfigurationDuration[]>("android.heic.availableHeicStallDurations", android.hardware.camera2.params.StreamConfigurationDuration[].class);
 
+    /**
+     * <p>The available HEIC (ISO/IEC 23008-12) stream
+     * configurations that this camera device supports
+     * (i.e. format, width, height, output/input stream).</p>
+     * <p>Refer to android.heic.availableHeicStreamConfigurations for details.</p>
+     * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
+     * @hide
+     */
+    public static final Key<android.hardware.camera2.params.StreamConfiguration[]> HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION =
+            new Key<android.hardware.camera2.params.StreamConfiguration[]>("android.heic.availableHeicStreamConfigurationsMaximumResolution", android.hardware.camera2.params.StreamConfiguration[].class);
+
+    /**
+     * <p>This lists the minimum frame duration for each
+     * format/size combination for HEIC output formats for CaptureRequests where
+     * {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} is set to
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }.</p>
+     * <p>Refer to android.heic.availableHeicMinFrameDurations for details.</p>
+     * <p><b>Units</b>: (format, width, height, ns) x n</p>
+     * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
+     *
+     * @see CaptureRequest#SENSOR_PIXEL_MODE
+     * @hide
+     */
+    public static final Key<android.hardware.camera2.params.StreamConfigurationDuration[]> HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION =
+            new Key<android.hardware.camera2.params.StreamConfigurationDuration[]>("android.heic.availableHeicMinFrameDurationsMaximumResolution", android.hardware.camera2.params.StreamConfigurationDuration[].class);
+
+    /**
+     * <p>This lists the maximum stall duration for each
+     * output format/size combination for HEIC streams for CaptureRequests where
+     * {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} is set to
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }.</p>
+     * <p>Refer to android.heic.availableHeicStallDurations for details.</p>
+     * <p><b>Units</b>: (format, width, height, ns) x n</p>
+     * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
+     *
+     * @see CaptureRequest#SENSOR_PIXEL_MODE
+     * @hide
+     */
+    public static final Key<android.hardware.camera2.params.StreamConfigurationDuration[]> HEIC_AVAILABLE_HEIC_STALL_DURATIONS_MAXIMUM_RESOLUTION =
+            new Key<android.hardware.camera2.params.StreamConfigurationDuration[]>("android.heic.availableHeicStallDurationsMaximumResolution", android.hardware.camera2.params.StreamConfigurationDuration[].class);
+
     /*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
      * End generated code
      *~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~O@*/
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index b7b1a14..726bca4 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -507,6 +507,18 @@
         return new CameraExtensionCharacteristics(mContext, cameraId, chars);
     }
 
+    private Map<String, CameraCharacteristics> getPhysicalIdToCharsMap(
+            CameraCharacteristics chars) throws CameraAccessException {
+        HashMap<String, CameraCharacteristics> physicalIdsToChars =
+                new HashMap<String, CameraCharacteristics>();
+        Set<String> physicalCameraIds = chars.getPhysicalCameraIds();
+        for (String physicalCameraId : physicalCameraIds) {
+            CameraCharacteristics physicalChars = getCameraCharacteristics(physicalCameraId);
+            physicalIdsToChars.put(physicalCameraId, physicalChars);
+        }
+        return physicalIdsToChars;
+    }
+
     /**
      * Helper for opening a connection to a camera with the given ID.
      *
@@ -535,17 +547,18 @@
             throws CameraAccessException {
         CameraCharacteristics characteristics = getCameraCharacteristics(cameraId);
         CameraDevice device = null;
-
+        Map<String, CameraCharacteristics> physicalIdsToChars =
+                getPhysicalIdToCharsMap(characteristics);
         synchronized (mLock) {
 
             ICameraDeviceUser cameraUser = null;
-
             android.hardware.camera2.impl.CameraDeviceImpl deviceImpl =
                     new android.hardware.camera2.impl.CameraDeviceImpl(
                         cameraId,
                         callback,
                         executor,
                         characteristics,
+                        physicalIdsToChars,
                         mContext.getApplicationInfo().targetSdkVersion,
                         mContext);
 
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index 924dcee..d4da3b9 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -586,7 +586,7 @@
      *   that is, {@link android.graphics.ImageFormat#PRIVATE } is included in the lists of
      *   formats returned by {@link android.hardware.camera2.params.StreamConfigurationMap#getInputFormats } and {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputFormats }.</li>
      * <li>{@link android.hardware.camera2.params.StreamConfigurationMap#getValidOutputFormatsForInput }
-     *   returns non empty int[] for each supported input format returned by {@link android.hardware.camera2.params.StreamConfigurationMap#getInputFormats }.</li>
+     *   returns non-empty int[] for each supported input format returned by {@link android.hardware.camera2.params.StreamConfigurationMap#getInputFormats }.</li>
      * <li>Each size returned by {@link android.hardware.camera2.params.StreamConfigurationMap#getInputSizes getInputSizes(ImageFormat.PRIVATE)} is also included in {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputSizes getOutputSizes(ImageFormat.PRIVATE)}</li>
      * <li>Using {@link android.graphics.ImageFormat#PRIVATE } does not cause a frame rate drop
      *   relative to the sensor's maximum capture rate (at that resolution).</li>
@@ -1114,6 +1114,63 @@
      */
     public static final int REQUEST_AVAILABLE_CAPABILITIES_OFFLINE_PROCESSING = 15;
 
+    /**
+     * <p>This camera device is capable of producing ultra high resolution images in
+     * addition to the image sizes described in the
+     * {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP android.scaler.streamConfigurationMap}.
+     * It can operate in 'default' mode and 'max resolution' mode. It generally does this
+     * by binning pixels in 'default' mode and not binning them in 'max resolution' mode.
+     * <code>{@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP android.scaler.streamConfigurationMap}</code> describes the streams supported in 'default'
+     * mode.
+     * The stream configurations supported in 'max resolution' mode are described by
+     * <code>{@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP_MAXIMUM_RESOLUTION android.scaler.streamConfigurationMapMaximumResolution}</code>.</p>
+     *
+     * @see CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP
+     * @see CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP_MAXIMUM_RESOLUTION
+     * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
+     */
+    public static final int REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR = 16;
+
+    /**
+     * <p>The device supports reprocessing from the <code>RAW_SENSOR</code> format with a bayer pattern
+     * given by {@link CameraCharacteristics#SENSOR_INFO_BINNING_FACTOR android.sensor.info.binningFactor} (m x n group of pixels with the same
+     * color filter) to a remosaiced regular bayer pattern.</p>
+     * <p>This capability will only be present for devices with
+     * {@link android.hardware.camera2.CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR }
+     * capability. When
+     * {@link android.hardware.camera2.CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR }
+     * devices do not advertise this capability,
+     * {@link android.graphics.ImageFormat#RAW_SENSOR } images will already have a
+     * regular bayer pattern.</p>
+     * <p>If a <code>RAW_SENSOR</code> stream is requested along with another non-RAW stream in a
+     * {@link android.hardware.camera2.CaptureRequest } (if multiple streams are supported
+     * when {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} is set to
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }),
+     * the <code>RAW_SENSOR</code> stream will have a regular bayer pattern.</p>
+     * <p>This capability requires the camera device to support the following :
+     * * The {@link android.hardware.camera2.params.StreamConfigurationMap } mentioned below
+     *   refers to the one, described by
+     *   <code>{@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP_MAXIMUM_RESOLUTION android.scaler.streamConfigurationMapMaximumResolution}</code>.
+     * * One input stream is supported, that is, <code>{@link CameraCharacteristics#REQUEST_MAX_NUM_INPUT_STREAMS android.request.maxNumInputStreams} == 1</code>.
+     * * {@link android.graphics.ImageFormat#RAW_SENSOR } is supported as an output/input
+     *   format, that is, {@link android.graphics.ImageFormat#RAW_SENSOR } is included in the
+     *   lists of formats returned by {@link android.hardware.camera2.params.StreamConfigurationMap#getInputFormats } and {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputFormats }.
+     * * {@link android.hardware.camera2.params.StreamConfigurationMap#getValidOutputFormatsForInput }
+     *   returns non-empty int[] for each supported input format returned by {@link android.hardware.camera2.params.StreamConfigurationMap#getInputFormats }.
+     * * Each size returned by {@link android.hardware.camera2.params.StreamConfigurationMap#getInputSizes getInputSizes(ImageFormat.RAW_SENSOR)} is also included in {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputSizes getOutputSizes(ImageFormat.RAW_SENSOR)}
+     * * Using {@link android.graphics.ImageFormat#RAW_SENSOR } does not cause a frame rate
+     *   drop relative to the sensor's maximum capture rate (at that resolution).
+     * * No CaptureRequest controls will be applicable when a request has an input target
+     *   with {@link android.graphics.ImageFormat#RAW_SENSOR } format.</p>
+     *
+     * @see CameraCharacteristics#REQUEST_MAX_NUM_INPUT_STREAMS
+     * @see CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP_MAXIMUM_RESOLUTION
+     * @see CameraCharacteristics#SENSOR_INFO_BINNING_FACTOR
+     * @see CaptureRequest#SENSOR_PIXEL_MODE
+     * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
+     */
+    public static final int REQUEST_AVAILABLE_CAPABILITIES_REMOSAIC_REPROCESSING = 17;
+
     //
     // Enumeration values for CameraCharacteristics#SCALER_CROPPING_TYPE
     //
@@ -2955,6 +3012,27 @@
     public static final int SENSOR_TEST_PATTERN_MODE_CUSTOM1 = 256;
 
     //
+    // Enumeration values for CaptureRequest#SENSOR_PIXEL_MODE
+    //
+
+    /**
+     * <p>This is the default sensor pixel mode. This is the only sensor pixel mode
+     * supported unless a camera device advertises
+     * {@link android.hardware.camera2.CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR }.</p>
+     * @see CaptureRequest#SENSOR_PIXEL_MODE
+     */
+    public static final int SENSOR_PIXEL_MODE_DEFAULT = 0;
+
+    /**
+     * <p>This sensor pixel mode is offered by devices with capability
+     * {@link android.hardware.camera2.CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR }.
+     * In this mode, sensors typically do not bin pixels, as a result can offer larger
+     * image sizes.</p>
+     * @see CaptureRequest#SENSOR_PIXEL_MODE
+     */
+    public static final int SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION = 1;
+
+    //
     // Enumeration values for CaptureRequest#SHADING_MODE
     //
 
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 9ac2ff5..906256d 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -1391,6 +1391,13 @@
      * scene as they do before. See {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio} for details. Whether to use
      * activeArraySize or preCorrectionActiveArraySize still depends on distortion correction
      * mode.</p>
+     * <p>For camera devices with the
+     * {@link android.hardware.camera2.CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR }
+     * capability,
+     * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION android.sensor.info.activeArraySizeMaximumResolution} /
+     * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION android.sensor.info.preCorrectionActiveArraySizeMaximumResolution} must be used as the
+     * coordinate system for requests where {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} is set to
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }.</p>
      * <p><b>Units</b>: Pixel coordinates within {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} or
      * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize} depending on
      * distortion correction capability and mode</p>
@@ -1405,7 +1412,10 @@
      * @see CaptureRequest#DISTORTION_CORRECTION_MODE
      * @see CaptureRequest#SCALER_CROP_REGION
      * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
+     * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION
      * @see CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE
+     * @see CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION
+     * @see CaptureRequest#SENSOR_PIXEL_MODE
      */
     @PublicKey
     @NonNull
@@ -1603,6 +1613,12 @@
      * scene as they do before. See {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio} for details. Whether to use
      * activeArraySize or preCorrectionActiveArraySize still depends on distortion correction
      * mode.</p>
+     * <p>For camera devices with the
+     * {@link android.hardware.camera2.CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR }
+     * capability, {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION android.sensor.info.activeArraySizeMaximumResolution} /
+     * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION android.sensor.info.preCorrectionActiveArraySizeMaximumResolution} must be used as the
+     * coordinate system for requests where {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} is set to
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }.</p>
      * <p><b>Units</b>: Pixel coordinates within {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} or
      * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize} depending on
      * distortion correction capability and mode</p>
@@ -1617,7 +1633,10 @@
      * @see CaptureRequest#DISTORTION_CORRECTION_MODE
      * @see CaptureRequest#SCALER_CROP_REGION
      * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
+     * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION
      * @see CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE
+     * @see CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION
+     * @see CaptureRequest#SENSOR_PIXEL_MODE
      */
     @PublicKey
     @NonNull
@@ -1808,6 +1827,12 @@
      * the scene as they do before. See {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio} for details. Whether to use
      * activeArraySize or preCorrectionActiveArraySize still depends on distortion correction
      * mode.</p>
+     * <p>For camera devices with the
+     * {@link android.hardware.camera2.CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR }
+     * capability, {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION android.sensor.info.activeArraySizeMaximumResolution} /
+     * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION android.sensor.info.preCorrectionActiveArraySizeMaximumResolution} must be used as the
+     * coordinate system for requests where {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} is set to
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }.</p>
      * <p><b>Units</b>: Pixel coordinates within {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} or
      * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize} depending on
      * distortion correction capability and mode</p>
@@ -1822,7 +1847,10 @@
      * @see CaptureRequest#DISTORTION_CORRECTION_MODE
      * @see CaptureRequest#SCALER_CROP_REGION
      * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
+     * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION
      * @see CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE
+     * @see CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION
+     * @see CaptureRequest#SENSOR_PIXEL_MODE
      */
     @PublicKey
     @NonNull
@@ -2896,6 +2924,12 @@
      * coordinate system is post-zoom, meaning that the activeArraySize or
      * preCorrectionActiveArraySize covers the camera device's field of view "after" zoom.  See
      * {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio} for details.</p>
+     * <p>For camera devices with the
+     * {@link android.hardware.camera2.CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR }
+     * capability, {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION android.sensor.info.activeArraySizeMaximumResolution} /
+     * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION android.sensor.info.preCorrectionActiveArraySizeMaximumResolution} must be used as the
+     * coordinate system for requests where {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} is set to
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }.</p>
      * <p><b>Units</b>: Pixel coordinates relative to
      * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} or
      * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize} depending on distortion correction
@@ -2908,7 +2942,10 @@
      * @see CameraCharacteristics#SCALER_AVAILABLE_MAX_DIGITAL_ZOOM
      * @see CameraCharacteristics#SCALER_CROPPING_TYPE
      * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
+     * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION
      * @see CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE
+     * @see CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION
+     * @see CaptureRequest#SENSOR_PIXEL_MODE
      */
     @PublicKey
     @NonNull
@@ -3214,6 +3251,53 @@
             new Key<Integer>("android.sensor.testPatternMode", int.class);
 
     /**
+     * <p>Switches sensor pixel mode between maximum resolution mode and default mode.</p>
+     * <p>This key controls whether the camera sensor operates in
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }
+     * mode or not. By default, all camera devices operate in
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_DEFAULT } mode.
+     * When operating in
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_DEFAULT } mode, sensors
+     * with {@link android.hardware.camera2.CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR }
+     * capability would typically perform pixel binning in order to improve low light
+     * performance, noise reduction etc. However, in
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }
+     * mode (supported only
+     * by {@link android.hardware.camera2.CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR }
+     * sensors), sensors typically operate in unbinned mode allowing for a larger image size.
+     * The stream configurations supported in
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }
+     * mode are also different from those of
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_DEFAULT } mode.
+     * They can be queried through
+     * {@link android.hardware.camera2.CameraCharacteristics#get } with
+     * {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP_MAXIMUM_RESOLUTION) }.
+     * Unless reported by both
+     * {@link android.hardware.camera2.params.StreamConfigurationMap }s, the outputs from
+     * <code>{@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP_MAXIMUM_RESOLUTION android.scaler.streamConfigurationMapMaximumResolution}</code> and
+     * <code>{@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP android.scaler.streamConfigurationMap}</code>
+     * must not be mixed in the same CaptureRequest. In other words, these outputs are
+     * exclusive to each other.
+     * This key does not need to be set for reprocess requests.</p>
+     * <p><b>Possible values:</b></p>
+     * <ul>
+     *   <li>{@link #SENSOR_PIXEL_MODE_DEFAULT DEFAULT}</li>
+     *   <li>{@link #SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION MAXIMUM_RESOLUTION}</li>
+     * </ul>
+     *
+     * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
+     *
+     * @see CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP
+     * @see CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP_MAXIMUM_RESOLUTION
+     * @see #SENSOR_PIXEL_MODE_DEFAULT
+     * @see #SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION
+     */
+    @PublicKey
+    @NonNull
+    public static final Key<Integer> SENSOR_PIXEL_MODE =
+            new Key<Integer>("android.sensor.pixelMode", int.class);
+
+    /**
      * <p>Quality of lens shading correction applied
      * to the image data.</p>
      * <p>When set to OFF mode, no lens shading correction will be applied by the
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index e7457e7..6ff68c1 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -812,6 +812,13 @@
      * scene as they do before. See {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio} for details. Whether to use
      * activeArraySize or preCorrectionActiveArraySize still depends on distortion correction
      * mode.</p>
+     * <p>For camera devices with the
+     * {@link android.hardware.camera2.CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR }
+     * capability,
+     * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION android.sensor.info.activeArraySizeMaximumResolution} /
+     * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION android.sensor.info.preCorrectionActiveArraySizeMaximumResolution} must be used as the
+     * coordinate system for requests where {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} is set to
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }.</p>
      * <p><b>Units</b>: Pixel coordinates within {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} or
      * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize} depending on
      * distortion correction capability and mode</p>
@@ -826,7 +833,10 @@
      * @see CaptureRequest#DISTORTION_CORRECTION_MODE
      * @see CaptureRequest#SCALER_CROP_REGION
      * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
+     * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION
      * @see CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE
+     * @see CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION
+     * @see CaptureRequest#SENSOR_PIXEL_MODE
      */
     @PublicKey
     @NonNull
@@ -1274,6 +1284,12 @@
      * scene as they do before. See {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio} for details. Whether to use
      * activeArraySize or preCorrectionActiveArraySize still depends on distortion correction
      * mode.</p>
+     * <p>For camera devices with the
+     * {@link android.hardware.camera2.CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR }
+     * capability, {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION android.sensor.info.activeArraySizeMaximumResolution} /
+     * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION android.sensor.info.preCorrectionActiveArraySizeMaximumResolution} must be used as the
+     * coordinate system for requests where {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} is set to
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }.</p>
      * <p><b>Units</b>: Pixel coordinates within {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} or
      * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize} depending on
      * distortion correction capability and mode</p>
@@ -1288,7 +1304,10 @@
      * @see CaptureRequest#DISTORTION_CORRECTION_MODE
      * @see CaptureRequest#SCALER_CROP_REGION
      * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
+     * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION
      * @see CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE
+     * @see CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION
+     * @see CaptureRequest#SENSOR_PIXEL_MODE
      */
     @PublicKey
     @NonNull
@@ -1890,6 +1909,12 @@
      * the scene as they do before. See {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio} for details. Whether to use
      * activeArraySize or preCorrectionActiveArraySize still depends on distortion correction
      * mode.</p>
+     * <p>For camera devices with the
+     * {@link android.hardware.camera2.CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR }
+     * capability, {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION android.sensor.info.activeArraySizeMaximumResolution} /
+     * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION android.sensor.info.preCorrectionActiveArraySizeMaximumResolution} must be used as the
+     * coordinate system for requests where {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} is set to
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }.</p>
      * <p><b>Units</b>: Pixel coordinates within {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} or
      * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize} depending on
      * distortion correction capability and mode</p>
@@ -1904,7 +1929,10 @@
      * @see CaptureRequest#DISTORTION_CORRECTION_MODE
      * @see CaptureRequest#SCALER_CROP_REGION
      * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
+     * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION
      * @see CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE
+     * @see CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION
+     * @see CaptureRequest#SENSOR_PIXEL_MODE
      */
     @PublicKey
     @NonNull
@@ -3565,6 +3593,12 @@
      * coordinate system is post-zoom, meaning that the activeArraySize or
      * preCorrectionActiveArraySize covers the camera device's field of view "after" zoom.  See
      * {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio} for details.</p>
+     * <p>For camera devices with the
+     * {@link android.hardware.camera2.CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR }
+     * capability, {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION android.sensor.info.activeArraySizeMaximumResolution} /
+     * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION android.sensor.info.preCorrectionActiveArraySizeMaximumResolution} must be used as the
+     * coordinate system for requests where {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} is set to
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }.</p>
      * <p><b>Units</b>: Pixel coordinates relative to
      * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} or
      * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize} depending on distortion correction
@@ -3577,7 +3611,10 @@
      * @see CameraCharacteristics#SCALER_AVAILABLE_MAX_DIGITAL_ZOOM
      * @see CameraCharacteristics#SCALER_CROPPING_TYPE
      * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
+     * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION
      * @see CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE
+     * @see CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION
+     * @see CaptureRequest#SENSOR_PIXEL_MODE
      */
     @PublicKey
     @NonNull
@@ -4107,6 +4144,69 @@
             new Key<Integer>("android.sensor.dynamicWhiteLevel", int.class);
 
     /**
+     * <p>Switches sensor pixel mode between maximum resolution mode and default mode.</p>
+     * <p>This key controls whether the camera sensor operates in
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }
+     * mode or not. By default, all camera devices operate in
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_DEFAULT } mode.
+     * When operating in
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_DEFAULT } mode, sensors
+     * with {@link android.hardware.camera2.CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR }
+     * capability would typically perform pixel binning in order to improve low light
+     * performance, noise reduction etc. However, in
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }
+     * mode (supported only
+     * by {@link android.hardware.camera2.CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR }
+     * sensors), sensors typically operate in unbinned mode allowing for a larger image size.
+     * The stream configurations supported in
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }
+     * mode are also different from those of
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_DEFAULT } mode.
+     * They can be queried through
+     * {@link android.hardware.camera2.CameraCharacteristics#get } with
+     * {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP_MAXIMUM_RESOLUTION) }.
+     * Unless reported by both
+     * {@link android.hardware.camera2.params.StreamConfigurationMap }s, the outputs from
+     * <code>{@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP_MAXIMUM_RESOLUTION android.scaler.streamConfigurationMapMaximumResolution}</code> and
+     * <code>{@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP android.scaler.streamConfigurationMap}</code>
+     * must not be mixed in the same CaptureRequest. In other words, these outputs are
+     * exclusive to each other.
+     * This key does not need to be set for reprocess requests.</p>
+     * <p><b>Possible values:</b></p>
+     * <ul>
+     *   <li>{@link #SENSOR_PIXEL_MODE_DEFAULT DEFAULT}</li>
+     *   <li>{@link #SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION MAXIMUM_RESOLUTION}</li>
+     * </ul>
+     *
+     * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
+     *
+     * @see CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP
+     * @see CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP_MAXIMUM_RESOLUTION
+     * @see #SENSOR_PIXEL_MODE_DEFAULT
+     * @see #SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION
+     */
+    @PublicKey
+    @NonNull
+    public static final Key<Integer> SENSOR_PIXEL_MODE =
+            new Key<Integer>("android.sensor.pixelMode", int.class);
+
+    /**
+     * <p>Whether <code>RAW</code> images requested have their bayer pattern as described by
+     * {@link CameraCharacteristics#SENSOR_INFO_BINNING_FACTOR android.sensor.info.binningFactor}.</p>
+     * <p>This key will only be present in devices advertisting the
+     * {@link android.hardware.camera2.CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR }
+     * capability which also advertise <code>REMOSAIC_REPROCESSING</code> capability. On all other devices
+     * RAW targets will have a regular bayer pattern.</p>
+     * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
+     *
+     * @see CameraCharacteristics#SENSOR_INFO_BINNING_FACTOR
+     */
+    @PublicKey
+    @NonNull
+    public static final Key<Boolean> SENSOR_RAW_BINNING_FACTOR_USED =
+            new Key<Boolean>("android.sensor.rawBinningFactorUsed", boolean.class);
+
+    /**
      * <p>Quality of lens shading correction applied
      * to the image data.</p>
      * <p>When set to OFF mode, no lens shading correction will be applied by the
diff --git a/core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java
index 0a42981..2920e67 100644
--- a/core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java
@@ -20,6 +20,7 @@
 import android.hardware.camera2.CameraCharacteristics;
 import android.hardware.camera2.CameraConstrainedHighSpeedCaptureSession;
 import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CameraMetadata;
 import android.hardware.camera2.CameraOfflineSession;
 import android.hardware.camera2.CameraOfflineSession.CameraOfflineSessionCallback;
 import android.hardware.camera2.CaptureRequest;
@@ -81,11 +82,17 @@
         if (request == null) {
             throw new IllegalArgumentException("Input capture request must not be null");
         }
+        CameraCharacteristics.Key<StreamConfigurationMap> ck =
+                CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP;
+        Integer sensorPixelMode = request.get(CaptureRequest.SENSOR_PIXEL_MODE);
+        if (sensorPixelMode != null && sensorPixelMode ==
+                CameraMetadata.SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION) {
+            ck = CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP_MAXIMUM_RESOLUTION;
+        }
         Collection<Surface> outputSurfaces = request.getTargets();
         Range<Integer> fpsRange = request.get(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE);
 
-        StreamConfigurationMap config =
-                mCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
+        StreamConfigurationMap config = mCharacteristics.get(ck);
         SurfaceUtils.checkConstrainedHighSpeedSurfaces(outputSurfaces, fpsRange, config);
 
         // Request list size: to limit the preview to 30fps, need use maxFps/30; to maximize
diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
index 4defd23..b578bf8 100644
--- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
@@ -20,6 +20,7 @@
 
 import android.annotation.NonNull;
 import android.content.Context;
+import android.graphics.ImageFormat;
 import android.hardware.ICameraService;
 import android.hardware.camera2.CameraAccessException;
 import android.hardware.camera2.CameraCaptureSession;
@@ -62,6 +63,8 @@
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashSet;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Objects;
@@ -114,6 +117,7 @@
 
     private final String mCameraId;
     private final CameraCharacteristics mCharacteristics;
+    private final Map<String, CameraCharacteristics> mPhysicalIdsToChars;
     private final int mTotalPartialCount;
     private final Context mContext;
 
@@ -257,7 +261,9 @@
     };
 
     public CameraDeviceImpl(String cameraId, StateCallback callback, Executor executor,
-                        CameraCharacteristics characteristics, int appTargetSdkVersion,
+                        CameraCharacteristics characteristics,
+                        Map<String, CameraCharacteristics> physicalIdsToChars,
+                        int appTargetSdkVersion,
                         Context ctx) {
         if (cameraId == null || callback == null || executor == null || characteristics == null) {
             throw new IllegalArgumentException("Null argument given");
@@ -266,6 +272,7 @@
         mDeviceCallback = callback;
         mDeviceExecutor = executor;
         mCharacteristics = characteristics;
+        mPhysicalIdsToChars = physicalIdsToChars;
         mAppTargetSdkVersion = appTargetSdkVersion;
         mContext = ctx;
 
@@ -1357,11 +1364,71 @@
         }
     }
 
+    private boolean checkInputConfigurationWithStreamConfigurationsAs(
+            InputConfiguration inputConfig, StreamConfigurationMap configMap) {
+        int[] inputFormats = configMap.getInputFormats();
+        boolean validFormat = false;
+        int inputFormat = inputConfig.getFormat();
+        for (int format : inputFormats) {
+            if (format == inputFormat) {
+                validFormat = true;
+            }
+        }
+
+        if (validFormat == false) {
+            return false;
+        }
+
+        boolean validSize = false;
+        Size[] inputSizes = configMap.getInputSizes(inputFormat);
+        for (Size s : inputSizes) {
+            if (inputConfig.getWidth() == s.getWidth() &&
+                    inputConfig.getHeight() == s.getHeight()) {
+                validSize = true;
+            }
+        }
+
+        if (validSize == false) {
+            return false;
+        }
+        return true;
+    }
+
+    private boolean checkInputConfigurationWithStreamConfigurations(
+            InputConfiguration inputConfig, boolean maxResolution) {
+        // Check if either this logical camera or any of its physical cameras support the
+        // input config. If they do, the input config is valid.
+        CameraCharacteristics.Key<StreamConfigurationMap> ck =
+                CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP;
+
+        if (maxResolution) {
+            ck = CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP_MAXIMUM_RESOLUTION;
+        }
+
+        StreamConfigurationMap configMap = mCharacteristics.get(ck);
+
+        if (configMap != null &&
+                checkInputConfigurationWithStreamConfigurationsAs(inputConfig, configMap)) {
+            return true;
+        }
+
+        for (Map.Entry<String, CameraCharacteristics> entry : mPhysicalIdsToChars.entrySet()) {
+            configMap = entry.getValue().get(ck);
+
+            if (configMap != null &&
+                    checkInputConfigurationWithStreamConfigurationsAs(inputConfig, configMap)) {
+                // Input config supported.
+                return true;
+            }
+        }
+        return false;
+    }
+
     private void checkInputConfiguration(InputConfiguration inputConfig) {
         if (inputConfig == null) {
             return;
         }
-
+        int inputFormat = inputConfig.getFormat();
         if (inputConfig.isMultiResolution()) {
             MultiResolutionStreamConfigurationMap configMap = mCharacteristics.get(
                     CameraCharacteristics.SCALER_MULTI_RESOLUTION_STREAM_CONFIGURATION_MAP);
@@ -1369,19 +1436,19 @@
             int[] inputFormats = configMap.getInputFormats();
             boolean validFormat = false;
             for (int format : inputFormats) {
-                if (format == inputConfig.getFormat()) {
+                if (format == inputFormat) {
                     validFormat = true;
                 }
             }
 
             if (validFormat == false) {
                 throw new IllegalArgumentException("multi-resolution input format " +
-                        inputConfig.getFormat() + " is not valid");
+                        inputFormat + " is not valid");
             }
 
             boolean validSize = false;
             Collection<MultiResolutionStreamInfo> inputStreamInfo =
-                    configMap.getInputInfo(inputConfig.getFormat());
+                    configMap.getInputInfo(inputFormat);
             for (MultiResolutionStreamInfo info : inputStreamInfo) {
                 if (inputConfig.getWidth() == info.getWidth() &&
                         inputConfig.getHeight() == info.getHeight()) {
@@ -1394,34 +1461,11 @@
                         inputConfig.getWidth() + "x" + inputConfig.getHeight() + " is not valid");
             }
         } else {
-            StreamConfigurationMap configMap = mCharacteristics.get(
-                    CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
-
-            int[] inputFormats = configMap.getInputFormats();
-            boolean validFormat = false;
-            for (int format : inputFormats) {
-                if (format == inputConfig.getFormat()) {
-                    validFormat = true;
-                }
-            }
-
-            if (validFormat == false) {
-                throw new IllegalArgumentException("input format " + inputConfig.getFormat() +
-                        " is not valid");
-            }
-
-            boolean validSize = false;
-            Size[] inputSizes = configMap.getInputSizes(inputConfig.getFormat());
-            for (Size s : inputSizes) {
-                if (inputConfig.getWidth() == s.getWidth() &&
-                        inputConfig.getHeight() == s.getHeight()) {
-                    validSize = true;
-                }
-            }
-
-            if (validSize == false) {
-                throw new IllegalArgumentException("input size " + inputConfig.getWidth() + "x" +
-                        inputConfig.getHeight() + " is not valid");
+            if (!checkInputConfigurationWithStreamConfigurations(inputConfig, /*maxRes*/false) &&
+                    !checkInputConfigurationWithStreamConfigurations(inputConfig, /*maxRes*/true)) {
+                throw new IllegalArgumentException("Input config with format " +
+                        inputFormat + " and size " + inputConfig.getWidth() + "x" +
+                        inputConfig.getHeight() + " not supported by camera id " + mCameraId);
             }
         }
     }
diff --git a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
index 0cdf744..aa84b02 100644
--- a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
+++ b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
@@ -327,6 +327,10 @@
     private static final String GPS_PROCESS = "GPS";
     private static final int FACE_LANDMARK_SIZE = 6;
 
+    private static final int MANDATORY_STREAM_CONFIGURATIONS_DEFAULT = 0;
+    private static final int MANDATORY_STREAM_CONFIGURATIONS_MAX_RESOLUTION = 1;
+    private static final int MANDATORY_STREAM_CONFIGURATIONS_CONCURRENT = 2;
+
     private static String translateLocationProviderToProcess(final String provider) {
         if (provider == null) {
             return null;
@@ -644,6 +648,15 @@
                         return (T) metadata.getStreamConfigurationMap();
                     }
                 });
+         sGetCommandMap.put(
+                CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP_MAXIMUM_RESOLUTION.getNativeKey(),
+                        new GetCommand() {
+                    @Override
+                    @SuppressWarnings("unchecked")
+                    public <T> T getValue(CameraMetadataNative metadata, Key<T> key) {
+                        return (T) metadata.getStreamConfigurationMapMaximumResolution();
+                    }
+                });
         sGetCommandMap.put(
                 CameraCharacteristics.SCALER_MANDATORY_STREAM_COMBINATIONS.getNativeKey(),
                         new GetCommand() {
@@ -664,6 +677,16 @@
                 });
 
         sGetCommandMap.put(
+                CameraCharacteristics.SCALER_MANDATORY_MAXIMUM_RESOLUTION_STREAM_COMBINATIONS.getNativeKey(),
+                        new GetCommand() {
+                    @Override
+                    @SuppressWarnings("unchecked")
+                    public <T> T getValue(CameraMetadataNative metadata, Key<T> key) {
+                        return (T) metadata.getMandatoryMaximumResolutionStreamCombinations();
+                    }
+                });
+
+        sGetCommandMap.put(
                 CameraCharacteristics.CONTROL_MAX_REGIONS_AE.getNativeKey(), new GetCommand() {
                     @Override
                     @SuppressWarnings("unchecked")
@@ -1285,12 +1308,12 @@
         return recommendedConfigurations;
     }
 
-    private boolean isBurstSupported() {
+    private boolean isCapabilitySupported(int capabilityRequested) {
         boolean ret = false;
 
         int[] capabilities = getBase(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES);
         for (int capability : capabilities) {
-            if (capability == CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE) {
+            if (capabilityRequested == capability) {
                 ret = true;
                 break;
             }
@@ -1299,8 +1322,18 @@
         return ret;
     }
 
+    private boolean isUltraHighResolutionSensor() {
+        return isCapabilitySupported(
+                CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR);
+
+    }
+    private boolean isBurstSupported() {
+        return isCapabilitySupported(
+                CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE);
+    }
+
     private MandatoryStreamCombination[] getMandatoryStreamCombinationsHelper(
-            boolean getConcurrent) {
+            int mandatoryStreamsType) {
         int[] capabilities = getBase(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES);
         ArrayList<Integer> caps = new ArrayList<Integer>();
         caps.ensureCapacity(capabilities.length);
@@ -1309,20 +1342,25 @@
         }
         int hwLevel = getBase(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
         MandatoryStreamCombination.Builder build = new MandatoryStreamCombination.Builder(
-                mCameraId, hwLevel, mDisplaySize, caps, getStreamConfigurationMap());
+                mCameraId, hwLevel, mDisplaySize, caps, getStreamConfigurationMap(),
+                getStreamConfigurationMapMaximumResolution());
 
         List<MandatoryStreamCombination> combs = null;
-        if (getConcurrent) {
-            combs = build.getAvailableMandatoryConcurrentStreamCombinations();
-        } else {
-            combs = build.getAvailableMandatoryStreamCombinations();
+        switch (mandatoryStreamsType) {
+            case MANDATORY_STREAM_CONFIGURATIONS_CONCURRENT:
+                combs = build.getAvailableMandatoryConcurrentStreamCombinations();
+                break;
+            case MANDATORY_STREAM_CONFIGURATIONS_MAX_RESOLUTION:
+                combs = build.getAvailableMandatoryMaximumResolutionStreamCombinations();
+                break;
+            default:
+                combs = build.getAvailableMandatoryStreamCombinations();
         }
         if ((combs != null) && (!combs.isEmpty())) {
             MandatoryStreamCombination[] combArray = new MandatoryStreamCombination[combs.size()];
             combArray = combs.toArray(combArray);
             return combArray;
         }
-
         return null;
     }
 
@@ -1330,11 +1368,18 @@
         if (!mHasMandatoryConcurrentStreams) {
             return null;
         }
-        return getMandatoryStreamCombinationsHelper(true);
+        return getMandatoryStreamCombinationsHelper(MANDATORY_STREAM_CONFIGURATIONS_CONCURRENT);
+    }
+
+    private MandatoryStreamCombination[] getMandatoryMaximumResolutionStreamCombinations() {
+        if (!isUltraHighResolutionSensor()) {
+            return null;
+        }
+        return getMandatoryStreamCombinationsHelper(MANDATORY_STREAM_CONFIGURATIONS_MAX_RESOLUTION);
     }
 
     private MandatoryStreamCombination[] getMandatoryStreamCombinations() {
-        return getMandatoryStreamCombinationsHelper(false);
+        return getMandatoryStreamCombinationsHelper(MANDATORY_STREAM_CONFIGURATIONS_DEFAULT);
     }
 
     private StreamConfigurationMap getStreamConfigurationMap() {
@@ -1377,6 +1422,50 @@
                 listHighResolution);
     }
 
+    private StreamConfigurationMap getStreamConfigurationMapMaximumResolution() {
+        if (!isUltraHighResolutionSensor()) {
+            return null;
+        }
+        StreamConfiguration[] configurations = getBase(
+                CameraCharacteristics.SCALER_AVAILABLE_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION);
+        StreamConfigurationDuration[] minFrameDurations = getBase(
+                CameraCharacteristics.SCALER_AVAILABLE_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION);
+        StreamConfigurationDuration[] stallDurations = getBase(
+                CameraCharacteristics.SCALER_AVAILABLE_STALL_DURATIONS_MAXIMUM_RESOLUTION);
+        StreamConfiguration[] depthConfigurations = getBase(
+                CameraCharacteristics.DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION);
+        StreamConfigurationDuration[] depthMinFrameDurations = getBase(
+                CameraCharacteristics.DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION);
+        StreamConfigurationDuration[] depthStallDurations = getBase(
+                CameraCharacteristics.DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS_MAXIMUM_RESOLUTION);
+        StreamConfiguration[] dynamicDepthConfigurations = getBase(
+                CameraCharacteristics.DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION);
+        StreamConfigurationDuration[] dynamicDepthMinFrameDurations = getBase(
+                CameraCharacteristics.DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION);
+        StreamConfigurationDuration[] dynamicDepthStallDurations = getBase(
+                CameraCharacteristics.DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS_MAXIMUM_RESOLUTION);
+        StreamConfiguration[] heicConfigurations = getBase(
+                CameraCharacteristics.HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION);
+        StreamConfigurationDuration[] heicMinFrameDurations = getBase(
+                CameraCharacteristics.HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION);
+        StreamConfigurationDuration[] heicStallDurations = getBase(
+                CameraCharacteristics.HEIC_AVAILABLE_HEIC_STALL_DURATIONS_MAXIMUM_RESOLUTION);
+        HighSpeedVideoConfiguration[] highSpeedVideoConfigurations = getBase(
+                CameraCharacteristics.CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS_MAXIMUM_RESOLUTION);
+        ReprocessFormatsMap inputOutputFormatsMap = getBase(
+                CameraCharacteristics.SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP_MAXIMUM_RESOLUTION);
+        // TODO: Is this correct, burst capability shouldn't necessarily correspond to max res mode
+        boolean listHighResolution = isBurstSupported();
+        return new StreamConfigurationMap(
+                configurations, minFrameDurations, stallDurations,
+                depthConfigurations, depthMinFrameDurations, depthStallDurations,
+                dynamicDepthConfigurations, dynamicDepthMinFrameDurations,
+                dynamicDepthStallDurations, heicConfigurations,
+                heicMinFrameDurations, heicStallDurations,
+                highSpeedVideoConfigurations, inputOutputFormatsMap,
+                listHighResolution, false);
+    }
+
     private <T> Integer getMaxRegions(Key<T> key) {
         final int AE = 0;
         final int AWB = 1;
diff --git a/core/java/android/hardware/camera2/params/MandatoryStreamCombination.java b/core/java/android/hardware/camera2/params/MandatoryStreamCombination.java
index 8a0172e..29bdee3 100644
--- a/core/java/android/hardware/camera2/params/MandatoryStreamCombination.java
+++ b/core/java/android/hardware/camera2/params/MandatoryStreamCombination.java
@@ -62,6 +62,7 @@
         private final int mFormat;
         private final ArrayList<Size> mAvailableSizes = new ArrayList<Size> ();
         private final boolean mIsInput;
+        private final boolean mIsUltraHighResolution;
 
         /**
          * Create a new {@link MandatoryStreamInformation}.
@@ -74,8 +75,8 @@
          *              ImageFormat/PixelFormat.
          * @hide
          */
-        public MandatoryStreamInformation(@NonNull List<Size> availableSizes, int format) {
-            this(availableSizes, format, /*isInput*/false);
+        public MandatoryStreamInformation(@NonNull List<Size> availableSizes, @Format int format) {
+            this(availableSizes, format, /*isInput*/false, /*maximumResolution*/false);
         }
 
         /**
@@ -92,12 +93,31 @@
          */
         public MandatoryStreamInformation(@NonNull List<Size> availableSizes, @Format int format,
                 boolean isInput) {
+            this(availableSizes, format, isInput, /*maximumResolution*/ false);
+        }
+
+        /**
+         * Create a new {@link MandatoryStreamInformation}.
+         *
+           @param availableSizes List of possible stream sizes.
+         * @param format Image format.
+         * @param isInput Flag indicating whether this stream is input.
+         * @param isMaxResolution Flag indicating whether this is a maximum resolution stream.
+         *
+         * @throws IllegalArgumentException
+         *              if sizes is empty or if the format was not user-defined in
+         *              ImageFormat/PixelFormat.
+         * @hide
+         */
+        public MandatoryStreamInformation(@NonNull List<Size> availableSizes, @Format int format,
+                boolean isInput, boolean isUltraHighResolution) {
             if (availableSizes.isEmpty()) {
                 throw new IllegalArgumentException("No available sizes");
             }
             mAvailableSizes.addAll(availableSizes);
             mFormat = checkArgumentFormat(format);
             mIsInput = isInput;
+            mIsUltraHighResolution = isUltraHighResolution;
         }
 
         /**
@@ -109,6 +129,18 @@
         }
 
         /**
+         * Confirms whether or not this is an ultra high resolution stream.
+         * An 'ultra high resolution' stream is one which has a configuration which appears in
+         * {@link android.hardware.camera2.CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP_MAXIMUM_RESOLUTION},
+         * Streams which are ultra high resolution must not be included with streams which are not
+         * ultra high resolution in the same {@link android.hardware.camera2.CaptureRequest}.
+         * @return true in case the stream is ultra high resolution, false otherwise.
+        */
+        public boolean isUltraHighResolution() {
+            return mIsUltraHighResolution;
+        }
+
+        /**
          * Return the list of available sizes for this mandatory stream.
          *
          * <p>Per documented {@link CameraDevice#createCaptureSession guideline} the largest
@@ -153,6 +185,7 @@
             if (obj instanceof MandatoryStreamInformation) {
                 final MandatoryStreamInformation other = (MandatoryStreamInformation) obj;
                 if ((mFormat != other.mFormat) || (mIsInput != other.mIsInput) ||
+                        (mIsUltraHighResolution != other.mIsUltraHighResolution) ||
                         (mAvailableSizes.size() != other.mAvailableSizes.size())) {
                     return false;
                 }
@@ -169,7 +202,7 @@
         @Override
         public int hashCode() {
             return HashCodeHelpers.hashCode(mFormat, Boolean.hashCode(mIsInput),
-                    mAvailableSizes.hashCode());
+                    Boolean.hashCode(mIsUltraHighResolution), mAvailableSizes.hashCode());
         }
     }
 
@@ -267,21 +300,26 @@
                 mStreamsInformation.hashCode());
     }
 
-    private static enum SizeThreshold { VGA, PREVIEW, RECORD, MAXIMUM, s720p, s1440p }
-    private static enum ReprocessType { NONE, PRIVATE, YUV }
+    private static enum SizeThreshold { VGA, PREVIEW, RECORD, MAXIMUM, s720p, s1440p, FULL_RES }
+    private static enum ReprocessType { NONE, PRIVATE, YUV, REMOSAIC }
     private static final class StreamTemplate {
         public int mFormat;
         public SizeThreshold mSizeThreshold;
         public boolean mIsInput;
+        public boolean mIsUltraHighResolution;
         public StreamTemplate(int format, SizeThreshold sizeThreshold) {
-            this(format, sizeThreshold, /*isInput*/false);
+            this(format, sizeThreshold, /*isInput*/false, /*ultraHighResolution*/false);
         }
-
         public StreamTemplate(@Format int format, @NonNull SizeThreshold sizeThreshold,
                 boolean isInput) {
+            this(format, sizeThreshold, isInput, /*ultraHighResolution*/ false);
+        }
+        public StreamTemplate(@Format int format, @NonNull SizeThreshold sizeThreshold,
+                boolean isInput, boolean isUltraHighResolution) {
             mFormat = format;
             mSizeThreshold = sizeThreshold;
             mIsInput = isInput;
+            mIsUltraHighResolution = isUltraHighResolution;
         }
     }
 
@@ -691,6 +729,18 @@
                 "Depth capture for mesh based object rendering"),
     };
 
+    private static StreamCombinationTemplate sUltraHighResolutionStreamCombinations[] = {
+        new StreamCombinationTemplate(new StreamTemplate [] {
+                new StreamTemplate(ImageFormat.YUV_420_888, SizeThreshold.FULL_RES) },
+                "Full res YUV image capture"),
+        new StreamCombinationTemplate(new StreamTemplate [] {
+                new StreamTemplate(ImageFormat.RAW_SENSOR, SizeThreshold.FULL_RES) },
+                "Full res RAW capture"),
+        new StreamCombinationTemplate(new StreamTemplate [] {
+                new StreamTemplate(ImageFormat.JPEG, SizeThreshold.FULL_RES) },
+                "Full res JPEG still image capture"),
+    };
+
     /**
      * Helper builder class to generate a list of available mandatory stream combinations.
      * @hide
@@ -700,6 +750,7 @@
         private List<Integer> mCapabilities;
         private int mHwLevel, mCameraId;
         private StreamConfigurationMap mStreamConfigMap;
+        private StreamConfigurationMap mStreamConfigMapMaximumResolution;
         private boolean mIsHiddenPhysicalCamera;
 
         private final Size kPreviewSizeBound = new Size(1920, 1088);
@@ -712,13 +763,17 @@
          * @param displaySize The device display size.
          * @param capabilities The camera device capabilities.
          * @param sm The camera device stream configuration map.
+         * @param smMaxResolution The camera device stream configuration map when it runs in max
+         *                        resolution mode.
          */
         public Builder(int cameraId, int hwLevel, @NonNull Size displaySize,
-                @NonNull List<Integer> capabilities, @NonNull StreamConfigurationMap sm) {
+                @NonNull List<Integer> capabilities, @NonNull StreamConfigurationMap sm,
+                StreamConfigurationMap smMaxResolution) {
             mCameraId = cameraId;
             mDisplaySize = displaySize;
             mCapabilities = capabilities;
             mStreamConfigMap = sm;
+            mStreamConfigMapMaximumResolution = smMaxResolution;
             mHwLevel = hwLevel;
             mIsHiddenPhysicalCamera =
                     CameraManager.isHiddenPhysicalCamera(Integer.toString(mCameraId));
@@ -797,6 +852,98 @@
         }
 
         /**
+         * Retrieve a list of all available mandatory stream combinations supported when
+         * {@link CaptureRequest#ANDROID_SENSOR_PIXEL_MODE} is set to
+         * {@link CameraMetadata#ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION}.
+         *
+         * @return a non-modifiable list of supported mandatory stream combinations or
+         *         null in case device is not backward compatible or the method encounters
+         *         an error.
+         */
+        public @NonNull List<MandatoryStreamCombination>
+                getAvailableMandatoryMaximumResolutionStreamCombinations() {
+
+            ArrayList<StreamCombinationTemplate> chosenStreamCombinations =
+                    new ArrayList<StreamCombinationTemplate>();
+
+            chosenStreamCombinations.addAll(Arrays.asList(sUltraHighResolutionStreamCombinations));
+
+            ArrayList<MandatoryStreamCombination> availableStreamCombinations =
+                    new ArrayList<MandatoryStreamCombination>();
+            boolean addRemosaicReprocessing = isRemosaicReprocessingSupported();
+            int remosaicSize = 0;
+            if (addRemosaicReprocessing) {
+                remosaicSize = 1;
+            }
+            availableStreamCombinations.ensureCapacity(
+                    chosenStreamCombinations.size() + remosaicSize);
+            fillMandatoryOutputStreamCombinations(availableStreamCombinations,
+                    chosenStreamCombinations, mStreamConfigMapMaximumResolution);
+            if (isRemosaicReprocessingSupported()) {
+                // Add reprocess mandatory streams
+                ArrayList<MandatoryStreamInformation> streamsInfo =
+                        new ArrayList<MandatoryStreamInformation>();
+
+                ArrayList<Size> inputSize = new ArrayList<Size>();
+                Size maxRawInputSize = getMaxSize(mStreamConfigMapMaximumResolution.getInputSizes(
+                        ImageFormat.RAW_SENSOR));
+                inputSize.add(maxRawInputSize);
+
+                streamsInfo.add(new MandatoryStreamInformation(inputSize,
+                        ImageFormat.RAW_SENSOR, /*isInput*/true, /*ultraHighResolution*/true));
+                streamsInfo.add(new MandatoryStreamInformation(inputSize,
+                        ImageFormat.RAW_SENSOR, /*isInput*/ false, /*ultraHighResolution*/true));
+                MandatoryStreamCombination streamCombination;
+                streamCombination = new MandatoryStreamCombination(streamsInfo,
+                        "Remosaic reprocessing", /*isReprocess*/true);
+                availableStreamCombinations.add(streamCombination);
+            }
+            return Collections.unmodifiableList(availableStreamCombinations);
+        }
+
+        private void fillMandatoryOutputStreamCombinations(
+                ArrayList<MandatoryStreamCombination> availableStreamCombinations,
+                ArrayList<StreamCombinationTemplate> chosenStreamCombinations,
+                StreamConfigurationMap streamConfigMap) {
+
+            for (StreamCombinationTemplate combTemplate : chosenStreamCombinations) {
+                ArrayList<MandatoryStreamInformation> streamsInfo =
+                        new ArrayList<MandatoryStreamInformation>();
+                streamsInfo.ensureCapacity(combTemplate.mStreamTemplates.length);
+
+                for (StreamTemplate template : combTemplate.mStreamTemplates) {
+                    MandatoryStreamInformation streamInfo;
+                    List<Size> sizes = new ArrayList<Size>();
+                    Size sizeChosen =
+                            getMaxSize(streamConfigMap.getOutputSizes(
+                                    template.mFormat));
+                    sizes.add(sizeChosen);
+                    try {
+                        streamInfo = new MandatoryStreamInformation(sizes, template.mFormat,
+                                /*isInput*/ false, /*ultraHighResolution*/ true);
+                    } catch (IllegalArgumentException e) {
+                        String cause = "No available sizes found for format: " + template.mFormat
+                                + " size threshold: " + template.mSizeThreshold + " combination: "
+                                + combTemplate.mDescription;
+                        throw new RuntimeException(cause, e);
+                    }
+                    streamsInfo.add(streamInfo);
+                }
+
+                MandatoryStreamCombination streamCombination;
+                try {
+                    streamCombination = new MandatoryStreamCombination(streamsInfo,
+                            combTemplate.mDescription, /*isReprocess*/false);
+                } catch (IllegalArgumentException e) {
+                    String cause =  "No stream information for mandatory combination: "
+                            + combTemplate.mDescription;
+                    throw new RuntimeException(cause, e);
+                }
+                availableStreamCombinations.add(streamCombination);
+            }
+        }
+
+        /**
          * Retrieve a list of all available mandatory stream combinations.
          *
          * @return a non-modifiable list of supported mandatory stream combinations or
@@ -948,7 +1095,6 @@
                         inputSize.add(maxYUVInputSize);
                         format = ImageFormat.YUV_420_888;
                     }
-
                     streamsInfo.add(new MandatoryStreamInformation(inputSize, format,
                                 /*isInput*/true));
                     streamsInfo.add(new MandatoryStreamInformation(inputSize, format));
@@ -974,7 +1120,6 @@
                                 combTemplate.mDescription);
                         return null;
                     }
-
                     streamsInfo.add(streamInfo);
                 }
 
@@ -1220,6 +1365,14 @@
         }
 
         /**
+         * Check whether the current device supports YUV reprocessing.
+         */
+        private boolean isRemosaicReprocessingSupported() {
+            return isCapabilitySupported(
+                    CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_REMOSAIC_REPROCESSING);
+        }
+
+        /**
          * Return the maximum supported video size using the camcorder profile information.
          *
          * @return Maximum supported video size.
diff --git a/core/java/android/hardware/camera2/params/OutputConfiguration.java b/core/java/android/hardware/camera2/params/OutputConfiguration.java
index e31bd60..84736dc 100644
--- a/core/java/android/hardware/camera2/params/OutputConfiguration.java
+++ b/core/java/android/hardware/camera2/params/OutputConfiguration.java
@@ -19,6 +19,7 @@
 
 import static com.android.internal.util.Preconditions.*;
 
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
@@ -26,6 +27,7 @@
 import android.hardware.camera2.CameraCaptureSession;
 import android.hardware.camera2.CameraCharacteristics;
 import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CameraMetadata;
 import android.hardware.camera2.MultiResolutionImageReader;
 import android.hardware.camera2.params.MultiResolutionStreamInfo;
 import android.hardware.camera2.utils.HashCodeHelpers;
@@ -33,10 +35,13 @@
 import android.media.ImageReader;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.util.ArraySet;
 import android.util.Log;
 import android.util.Size;
 import android.view.Surface;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -145,6 +150,13 @@
      */
     public static final int SURFACE_GROUP_ID_NONE = -1;
 
+    /** @hide */
+     @Retention(RetentionPolicy.SOURCE)
+     @IntDef(prefix = {"SENSOR_PIXEL_MODE_"}, value =
+         {CameraMetadata.SENSOR_PIXEL_MODE_DEFAULT,
+          CameraMetadata.SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION})
+     public @interface SensorPixelMode {};
+
     /**
      * Create a new {@link OutputConfiguration} instance with a {@link Surface}.
      *
@@ -306,6 +318,7 @@
         mIsShared = false;
         mPhysicalCameraId = null;
         mIsMultiResolution = false;
+        mSensorPixelModesUsed = new ArrayList<Integer>();
     }
 
     /**
@@ -399,6 +412,7 @@
         mIsShared = false;
         mPhysicalCameraId = null;
         mIsMultiResolution = false;
+        mSensorPixelModesUsed = new ArrayList<Integer>();
     }
 
     /**
@@ -485,6 +499,81 @@
     }
 
     /**
+     * Add a sensor pixel mode that this OutputConfiguration will be used in.
+     *
+     * <p> In the case that this output stream configuration (format, width, height) is
+     * available through {@link android.hardware.camera2.CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP}
+     * configurations and
+     * {@link android.hardware.camera2.CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP_MAXIMUM_RESOLUTION},
+     * configurations, the camera sub-system will assume that this {@link OutputConfiguration} will
+     * be used only with {@link android.hardware.camera2.CaptureRequest}s which has
+     * {@link android.hardware.camera2.CaptureRequest#SENSOR_PIXEL_MODE} set to
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_DEFAULT}.
+     * In such cases, if clients intend to use the
+     * {@link OutputConfiguration}(s) in a {@link android.hardware.camera2.CaptureRequest} with
+     * other sensor pixel modes, they must specify which
+     * {@link android.hardware.camera2.CaptureRequest#SENSOR_PIXEL_MODE}(s) they will use this
+     * {@link OutputConfiguration} with, by calling this method.
+     *
+     * In case this output stream configuration (format, width, height) is only in
+     * {@link android.hardware.camera2.CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP_MAXIMUM_RESOLUTION},
+     * configurations, this output target must only be used with
+     * {@link android.hardware.camera2.CaptureRequest}s which has
+     * {@link android.hardware.camera2.CaptureRequest#SENSOR_PIXEL_MODE} set to
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION} and that
+     * is what the camera sub-system will assume. If clients add
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_DEFAULT} in this
+     * case, session configuration will fail, if this {@link OutputConfiguration} is included.
+     *
+     * In case this output stream configuration (format, width, height) is only in
+     * {@link android.hardware.camera2.CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP},
+     * configurations, this output target must only be used with
+     * {@link android.hardware.camera2.CaptureRequest}s which has
+     * {@link android.hardware.camera2.CaptureRequest#SENSOR_PIXEL_MODE} set to
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_DEFAULT} and that is what
+     * the camera sub-system will assume. If clients add
+     * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION} in this
+     * case, session configuration will fail, if this {@link OutputConfiguration} is included.
+     *
+     * @param sensorPixelModeUsed The sensor pixel mode this OutputConfiguration will be used with
+     * </p>
+     *
+     */
+    public void addSensorPixelModeUsed(@SensorPixelMode int sensorPixelModeUsed) {
+        // Verify that the values are in range.
+        if (sensorPixelModeUsed != CameraMetadata.SENSOR_PIXEL_MODE_DEFAULT &&
+                sensorPixelModeUsed != CameraMetadata.SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION) {
+            throw new IllegalArgumentException("Not a valid sensor pixel mode " +
+                    sensorPixelModeUsed);
+        }
+
+        if (mSensorPixelModesUsed.contains(sensorPixelModeUsed)) {
+            // Already added, ignore;
+            return;
+        }
+        mSensorPixelModesUsed.add(sensorPixelModeUsed);
+    }
+
+    /**
+     * Remove a sensor pixel mode, previously added through addSensorPixelModeUsed, from this
+     * OutputConfiguration.
+     *
+     * <p> Sensor pixel modes added via calls to {@link #addSensorPixelModeUsed} can also be removed
+     * from the OutputConfiguration.</p>
+     *
+     * @param sensorPixelModeUsed The sensor pixel mode to be removed.
+     *
+     * @throws IllegalArgumentException If the sensor pixel mode wasn't previously added
+     *                                  through {@link #addSensorPixelModeUsed}.
+     */
+    public void removeSensorPixelModeUsed(@SensorPixelMode int sensorPixelModeUsed) {
+      if (!mSensorPixelModesUsed.remove(Integer.valueOf(sensorPixelModeUsed))) {
+            throw new IllegalArgumentException("sensorPixelMode " + sensorPixelModeUsed +
+                    "is not part of this output configuration");
+      }
+    }
+
+    /**
      * Check if this configuration is for a physical camera.
      *
      * <p>This returns true if the output configuration was for a physical camera making up a
@@ -625,6 +714,7 @@
         this.mIsShared = other.mIsShared;
         this.mPhysicalCameraId = other.mPhysicalCameraId;
         this.mIsMultiResolution = other.mIsMultiResolution;
+        this.mSensorPixelModesUsed = other.mSensorPixelModesUsed;
     }
 
     /**
@@ -642,7 +732,8 @@
         source.readTypedList(surfaces, Surface.CREATOR);
         String physicalCameraId = source.readString();
         boolean isMultiResolutionOutput = source.readInt() == 1;
-
+        ArrayList<Integer> sensorPixelModesUsed = new ArrayList<Integer>();
+        source.readList(sensorPixelModesUsed, Integer.class.getClassLoader());
         checkArgumentInRange(rotation, ROTATION_0, ROTATION_270, "Rotation constant");
 
         mSurfaceGroupId = surfaceSetId;
@@ -666,6 +757,7 @@
         }
         mPhysicalCameraId = physicalCameraId;
         mIsMultiResolution = isMultiResolutionOutput;
+        mSensorPixelModesUsed = sensorPixelModesUsed;
     }
 
     /**
@@ -766,6 +858,7 @@
         dest.writeTypedList(mSurfaces);
         dest.writeString(mPhysicalCameraId);
         dest.writeInt(mIsMultiResolution ? 1 : 0);
+        dest.writeList(mSensorPixelModesUsed);
     }
 
     /**
@@ -798,7 +891,14 @@
                     !Objects.equals(mPhysicalCameraId, other.mPhysicalCameraId) ||
                     mIsMultiResolution != other.mIsMultiResolution)
                 return false;
-
+            if (mSensorPixelModesUsed.size() != other.mSensorPixelModesUsed.size()) {
+                return false;
+            }
+            for (int j = 0; j < mSensorPixelModesUsed.size(); j++) {
+                if (mSensorPixelModesUsed.get(j) != other.mSensorPixelModesUsed.get(j)) {
+                    return false;
+                }
+            }
             int minLen = Math.min(mSurfaces.size(), other.mSurfaces.size());
             for (int i = 0;  i < minLen; i++) {
                 if (mSurfaces.get(i) != other.mSurfaces.get(i))
@@ -823,7 +923,7 @@
                     mRotation, mConfiguredSize.hashCode(), mConfiguredFormat, mConfiguredDataspace,
                     mSurfaceGroupId, mSurfaceType, mIsShared ? 1 : 0,
                     mPhysicalCameraId == null ? 0 : mPhysicalCameraId.hashCode(),
-                    mIsMultiResolution ? 1 : 0);
+                    mIsMultiResolution ? 1 : 0, mSensorPixelModesUsed.hashCode());
         }
 
         return HashCodeHelpers.hashCode(
@@ -831,7 +931,7 @@
                 mConfiguredSize.hashCode(), mConfiguredFormat,
                 mConfiguredDataspace, mSurfaceGroupId, mIsShared ? 1 : 0,
                 mPhysicalCameraId == null ? 0 : mPhysicalCameraId.hashCode(),
-                mIsMultiResolution ? 1 : 0);
+                mIsMultiResolution ? 1 : 0, mSensorPixelModesUsed.hashCode());
     }
 
     private static final String TAG = "OutputConfiguration";
@@ -861,4 +961,6 @@
     // Flag indicating if this config is for a multi-resolution output with a
     // MultiResolutionImageReader
     private boolean mIsMultiResolution;
+    // The sensor pixel modes that this OutputConfiguration will use
+    private ArrayList<Integer> mSensorPixelModesUsed;
 }
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java
index 6dd6744..6c2d140 100644
--- a/core/java/android/hardware/display/DisplayManager.java
+++ b/core/java/android/hardware/display/DisplayManager.java
@@ -17,8 +17,10 @@
 package android.hardware.display;
 
 import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.Display.HdrCapabilities.HdrType;
 
 import android.Manifest;
+import android.annotation.FloatRange;
 import android.annotation.IntDef;
 import android.annotation.LongDef;
 import android.annotation.NonNull;
@@ -36,6 +38,7 @@
 import android.os.Build;
 import android.os.Handler;
 import android.util.Pair;
+import android.util.Slog;
 import android.util.SparseArray;
 import android.view.Display;
 import android.view.Surface;
@@ -346,6 +349,37 @@
 
 
     /** @hide */
+    @IntDef(prefix = {"MATCH_CONTENT_FRAMERATE_"}, value = {
+            MATCH_CONTENT_FRAMERATE_UNKNOWN,
+            MATCH_CONTENT_FRAMERATE_NEVER,
+            MATCH_CONTENT_FRAMERATE_SEAMLESSS_ONLY,
+            MATCH_CONTENT_FRAMERATE_ALWAYS,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface MatchContentFrameRateType {}
+
+    /**
+     * Match content frame rate user preference is unknown.
+     */
+    public static final int MATCH_CONTENT_FRAMERATE_UNKNOWN = -1;
+
+    /**
+     * No mode switching is allowed.
+     */
+    public static final int MATCH_CONTENT_FRAMERATE_NEVER = 0;
+
+    /**
+     * Only refresh rate switches without visual interruptions are allowed.
+     */
+    public static final int MATCH_CONTENT_FRAMERATE_SEAMLESSS_ONLY = 1;
+
+    /**
+     * Refresh rate switches between all refresh rates are allowed even if they have visual
+     * interruptions for the user.
+     */
+    public static final int MATCH_CONTENT_FRAMERATE_ALWAYS = 2;
+
+    /** @hide */
     @IntDef(prefix = {"SWITCHING_TYPE_"}, value = {
             SWITCHING_TYPE_NONE,
             SWITCHING_TYPE_WITHIN_GROUPS,
@@ -709,6 +743,55 @@
     }
 
     /**
+     * Sets the HDR types that have been disabled by user.
+     * @param userDisabledTypes the HDR types to disable.
+     * @hide
+     */
+    @TestApi
+    @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
+    public void setUserDisabledHdrTypes(@NonNull @HdrType int[] userDisabledTypes) {
+        mGlobal.setUserDisabledHdrTypes(userDisabledTypes);
+    }
+
+    /**
+     * Sets whether or not the user disabled HDR types are returned from
+     * {@link Display#getHdrCapabilities}.
+     *
+     * @param areUserDisabledHdrTypesAllowed If true, the user-disabled types
+     * are ignored and returned, if the display supports them. If false, the
+     * user-disabled types are taken into consideration and are never returned,
+     * even if the display supports them.
+     * @hide
+     */
+    @TestApi
+    @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
+    public void setAreUserDisabledHdrTypesAllowed(boolean areUserDisabledHdrTypesAllowed) {
+        mGlobal.setAreUserDisabledHdrTypesAllowed(areUserDisabledHdrTypesAllowed);
+    }
+
+    /**
+     * Returns whether or not the user-disabled HDR types are returned from
+     * {@link Display#getHdrCapabilities}.
+     *
+     * @hide
+     */
+    @TestApi
+    public boolean areUserDisabledHdrTypesAllowed() {
+        return mGlobal.areUserDisabledHdrTypesAllowed();
+    }
+
+    /**
+     * Returns the HDR formats disabled by the user.
+     *
+     * @hide
+     */
+    @TestApi
+    public @NonNull int[] getUserDisabledHdrTypes() {
+        return mGlobal.getUserDisabledHdrTypes();
+    }
+
+
+    /**
      * Creates a virtual display.
      *
      * @see #createVirtualDisplay(String, int, int, int, Surface, int,
@@ -921,6 +1004,43 @@
         mGlobal.setTemporaryBrightness(displayId, brightness);
     }
 
+
+    /**
+     * Sets the brightness of the specified display.
+     * <p>
+     * Requires the {@link android.Manifest.permission#CONTROL_DISPLAY_BRIGHTNESS}
+     * permission.
+     * </p>
+     *
+     * @param displayId the logical display id
+     * @param brightness The brightness value from 0.0f to 1.0f.
+     *
+     * @hide
+     */
+    @RequiresPermission(Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS)
+    public void setBrightness(int displayId, @FloatRange(from = 0f, to = 1f) float brightness) {
+        mGlobal.setBrightness(displayId, brightness);
+    }
+
+
+    /**
+     * Gets the brightness of the specified display.
+     * <p>
+     * Requires the {@link android.Manifest.permission#CONTROL_DISPLAY_BRIGHTNESS}
+     * permission.
+     * </p>
+     *
+     * @param displayId The display of which brightness value to get from.
+     *
+     * @hide
+     */
+    @RequiresPermission(Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS)
+    @FloatRange(from = 0f, to = 1f)
+    public float getBrightness(int displayId) {
+        return mGlobal.getBrightness(displayId);
+    }
+
+
     /**
      * Temporarily sets the auto brightness adjustment factor.
      * <p>
@@ -988,14 +1108,36 @@
     }
 
     /**
-     * Returns the refresh rate switching type.
-     *
-     * @hide
+     * Returns the user preference for "Match content frame rate".
+     * <p>
+     * Never: Even if the app requests it, the device will never try to match its output to the
+     * original frame rate of the content.
+     * </p><p>
+     * Seamless: If the app requests it, the device will match its output to the original frame
+     * rate of the content, ONLY if the display can transition seamlessly.
+     * </p><p>
+     * Always: If the app requests it, the device will match its output to the original
+     * frame rate of the content. This may cause the screen to go blank for a
+     * second when exiting or entering a video playback.
+     * </p>
      */
-    @TestApi
-    @RequiresPermission(Manifest.permission.MODIFY_REFRESH_RATE_SWITCHING_TYPE)
-    @SwitchingType public int getRefreshRateSwitchingType() {
-        return mGlobal.getRefreshRateSwitchingType();
+    @MatchContentFrameRateType public int getMatchContentFrameRateUserPreference() {
+        return toMatchContentFrameRateSetting(mGlobal.getRefreshRateSwitchingType());
+    }
+
+    @MatchContentFrameRateType
+    private int toMatchContentFrameRateSetting(@SwitchingType int switchingType) {
+        switch (switchingType) {
+            case SWITCHING_TYPE_NONE:
+                return MATCH_CONTENT_FRAMERATE_NEVER;
+            case SWITCHING_TYPE_WITHIN_GROUPS:
+                return MATCH_CONTENT_FRAMERATE_SEAMLESSS_ONLY;
+            case SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS:
+                return MATCH_CONTENT_FRAMERATE_ALWAYS;
+            default:
+                Slog.e(TAG, switchingType + " is not a valid value of switching type.");
+                return MATCH_CONTENT_FRAMERATE_UNKNOWN;
+        }
     }
 
     /**
diff --git a/core/java/android/hardware/display/DisplayManagerGlobal.java b/core/java/android/hardware/display/DisplayManagerGlobal.java
index fd0431c5..cdc219a 100644
--- a/core/java/android/hardware/display/DisplayManagerGlobal.java
+++ b/core/java/android/hardware/display/DisplayManagerGlobal.java
@@ -16,7 +16,9 @@
 
 package android.hardware.display;
 
+
 import static android.hardware.display.DisplayManager.EventsMask;
+import static android.view.Display.HdrCapabilities.HdrType;
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
@@ -508,6 +510,59 @@
         }
     }
 
+    /**
+     * Sets the HDR types that have been disabled by user.
+     * @param userDisabledHdrTypes the HDR types to disable. The HDR types are any of
+     */
+    public void setUserDisabledHdrTypes(@HdrType int[] userDisabledHdrTypes) {
+        try {
+            mDm.setUserDisabledHdrTypes(userDisabledHdrTypes);
+        } catch (RemoteException ex) {
+            throw ex.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Sets whether or not the user disabled HDR types are returned from
+     * {@link Display#getHdrCapabilities}.
+     *
+     * @param areUserDisabledHdrTypesAllowed If true, the user-disabled
+     * types are ignored and returned, if the display supports them. If
+     * false, the user-disabled types are taken into consideration and
+     * are never returned, even if the display supports them.
+     */
+    public void setAreUserDisabledHdrTypesAllowed(boolean areUserDisabledHdrTypesAllowed) {
+        try {
+            mDm.setAreUserDisabledHdrTypesAllowed(areUserDisabledHdrTypesAllowed);
+        } catch (RemoteException ex) {
+            throw ex.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns whether or not the user-disabled HDR types are returned from
+     * {@link Display#getHdrCapabilities}.
+     */
+    public boolean areUserDisabledHdrTypesAllowed() {
+        try {
+            return mDm.areUserDisabledHdrTypesAllowed();
+        } catch (RemoteException ex) {
+            throw ex.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns the HDR formats disabled by the user.
+     *
+     */
+    public int[] getUserDisabledHdrTypes() {
+        try {
+            return mDm.getUserDisabledHdrTypes();
+        } catch (RemoteException ex) {
+            throw ex.rethrowFromSystemServer();
+        }
+    }
+
     public void requestColorMode(int displayId, int colorMode) {
         try {
             mDm.requestColorMode(displayId, colorMode);
@@ -690,6 +745,37 @@
         }
     }
 
+
+    /**
+     * Sets the brightness of the display.
+     *
+     * @param brightness The brightness value from 0.0f to 1.0f.
+     *
+     * @hide
+     */
+    public void setBrightness(int displayId, float brightness) {
+        try {
+            mDm.setBrightness(displayId, brightness);
+        } catch (RemoteException ex) {
+            throw ex.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Gets the brightness of the display.
+     *
+     * @param displayId The display from which to get the brightness
+     *
+     * @hide
+     */
+    public float getBrightness(int displayId) {
+        try {
+            return mDm.getBrightness(displayId);
+        } catch (RemoteException ex) {
+            throw ex.rethrowFromSystemServer();
+        }
+    }
+
     /**
      * Temporarily sets the auto brightness adjustment factor.
      * <p>
diff --git a/core/java/android/hardware/display/IDisplayManager.aidl b/core/java/android/hardware/display/IDisplayManager.aidl
index dee9144..5ca4e0c 100644
--- a/core/java/android/hardware/display/IDisplayManager.aidl
+++ b/core/java/android/hardware/display/IDisplayManager.aidl
@@ -68,6 +68,18 @@
     // No permissions required.
     WifiDisplayStatus getWifiDisplayStatus();
 
+    // Requires WRITE_SECURE_SETTINGS permission.
+    void setUserDisabledHdrTypes(in int[] userDisabledTypes);
+
+    // Requires WRITE_SECURE_SETTINGS permission.
+    void setAreUserDisabledHdrTypesAllowed(boolean areUserDisabledHdrTypesAllowed);
+
+    // No permissions required.
+    boolean areUserDisabledHdrTypesAllowed();
+
+    // No permissions required.
+    int[] getUserDisabledHdrTypes();
+
     // Requires CONFIGURE_DISPLAY_COLOR_MODE
     void requestColorMode(int displayId, int colorMode);
 
@@ -119,6 +131,12 @@
     // Temporarily sets the display brightness.
     void setTemporaryBrightness(int displayId, float brightness);
 
+    // Saves the display brightness.
+    void setBrightness(int displayId, float brightness);
+
+    // Retrieves the display brightness.
+    float getBrightness(int displayId);
+
     // Temporarily sets the auto brightness adjustment factor.
     void setTemporaryAutoBrightnessAdjustment(float adjustment);
 
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index 01fd396..c83ccfa 100644
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -223,6 +223,14 @@
     public static final long BLOCK_FLAG_SLIPPERY = android.os.IInputConstants.BLOCK_FLAG_SLIPPERY;
 
     /**
+     * Check whether apps are using MotionEvent.getRawX/Y. This is implementation-specific, and
+     * thus undefined for most 3p app usages.
+     * @hide
+     */
+    @ChangeId
+    public static final long APP_USES_RAW_INPUT_COORDS = 179274888L;
+
+    /**
      * Input Event Injection Synchronization Mode: None.
      * Never blocks.  Injection is asynchronous and is assumed always to be successful.
      * @hide
diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java
index 3da1227..9a8cd79 100644
--- a/core/java/android/net/NetworkPolicyManager.java
+++ b/core/java/android/net/NetworkPolicyManager.java
@@ -204,81 +204,6 @@
     public @interface SubscriptionOverrideMask {}
 
     /**
-     * Flag to indicate that an app is not subject to any restrictions that could result in its
-     * network access blocked.
-     *
-     * @hide
-     */
-    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
-    public static final int BLOCKED_REASON_NONE = 0;
-
-    /**
-     * Flag to indicate that an app is subject to Battery saver restrictions that would
-     * result in its network access being blocked.
-     *
-     * @hide
-     */
-    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
-    public static final int BLOCKED_REASON_BATTERY_SAVER = 1 << 0;
-
-    /**
-     * Flag to indicate that an app is subject to Doze restrictions that would
-     * result in its network access being blocked.
-     *
-     * @hide
-     */
-    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
-    public static final int BLOCKED_REASON_DOZE = 1 << 1;
-
-    /**
-     * Flag to indicate that an app is subject to App Standby restrictions that would
-     * result in its network access being blocked.
-     *
-     * @hide
-     */
-    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
-    public static final int BLOCKED_REASON_APP_STANDBY = 1 << 2;
-
-    /**
-     * Flag to indicate that an app is subject to Restricted mode restrictions that would
-     * result in its network access being blocked.
-     *
-     * @hide
-     */
-    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
-    public static final int BLOCKED_REASON_RESTRICTED_MODE = 1 << 3;
-
-    /**
-     * Flag to indicate that an app is subject to Data saver restrictions that would
-     * result in its metered network access being blocked.
-     *
-     * @hide
-     */
-    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
-    public static final int BLOCKED_METERED_REASON_DATA_SAVER = 1 << 16;
-
-    /**
-     * Flag to indicate that an app is subject to user restrictions that would
-     * result in its metered network access being blocked.
-     *
-     * @hide
-     */
-    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
-    public static final int BLOCKED_METERED_REASON_USER_RESTRICTED = 1 << 17;
-
-    /**
-     * Flag to indicate that an app is subject to Device admin restrictions that would
-     * result in its metered network access being blocked.
-     *
-     * @hide
-     */
-    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
-    public static final int BLOCKED_METERED_REASON_ADMIN_DISABLED = 1 << 18;
-
-    /** @hide */
-    public static final int BLOCKED_METERED_REASON_MASK = 0xffff0000;
-
-    /**
      * Flag to indicate that app is not exempt from any network restrictions.
      *
      * @hide
@@ -326,26 +251,24 @@
      * @hide
      */
     public static final int ALLOWED_METERED_REASON_USER_EXEMPTED = 1 << 16;
+    /**
+     * Flag to indicate that app is exempt from certain metered network restrictions because of it
+     * being a system component.
+     *
+     * @hide
+     */
+    public static final int ALLOWED_METERED_REASON_SYSTEM = 1 << 17;
+    /**
+     * Flag to indicate that app is exempt from certain metered network restrictions because of it
+     * being in the foreground.
+     *
+     * @hide
+     */
+    public static final int ALLOWED_METERED_REASON_FOREGROUND = 1 << 18;
 
     /** @hide */
     public static final int ALLOWED_METERED_REASON_MASK = 0xffff0000;
 
-    /**
-     * @hide
-     */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(flag = true, prefix = {"BLOCKED_"}, value = {
-            BLOCKED_REASON_NONE,
-            BLOCKED_REASON_BATTERY_SAVER,
-            BLOCKED_REASON_DOZE,
-            BLOCKED_REASON_APP_STANDBY,
-            BLOCKED_REASON_RESTRICTED_MODE,
-            BLOCKED_METERED_REASON_DATA_SAVER,
-            BLOCKED_METERED_REASON_USER_RESTRICTED,
-            BLOCKED_METERED_REASON_ADMIN_DISABLED,
-    })
-    public @interface BlockedReason {}
-
     private final Context mContext;
     @UnsupportedAppUsage
     private INetworkPolicyManager mService;
@@ -862,35 +785,6 @@
     }
 
     /**
-     * Returns whether network access of an UID is blocked or not based on {@code blockedReasons}
-     * corresponding to it.
-     *
-     * {@code blockedReasons} would be a bitwise {@code OR} combination of the
-     * {@code BLOCKED_REASON_*} and/or {@code BLOCKED_METERED_REASON_*} constants.
-     *
-     * @param blockedReasons Value indicating the reasons for why the network access of an UID is
-     *                       blocked. If the value is equal to {@link #BLOCKED_REASON_NONE}, then
-     *                       it indicates that an app's network access is not blocked.
-     * @param meteredNetwork Value indicating whether the network is metered or not.
-     * @return Whether network access is blocked or not.
-     * @hide
-     */
-    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
-    public static boolean isUidBlocked(@BlockedReason int blockedReasons, boolean meteredNetwork) {
-        if (blockedReasons == BLOCKED_REASON_NONE) {
-            return false;
-        }
-        final int blockedOnAllNetworksReason = (blockedReasons & ~BLOCKED_METERED_REASON_MASK);
-        if (blockedOnAllNetworksReason != BLOCKED_REASON_NONE) {
-            return true;
-        }
-        if (meteredNetwork) {
-            return blockedReasons != BLOCKED_REASON_NONE;
-        }
-        return false;
-    }
-
-    /**
      * Returns the {@code string} representation of {@code blockedReasons} argument.
      *
      * @param blockedReasons Value indicating the reasons for why the network access of an UID is
@@ -899,7 +793,7 @@
      */
     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     @NonNull
-    public static String blockedReasonsToString(@BlockedReason int blockedReasons) {
+    public static String blockedReasonsToString(int blockedReasons) {
         return DebugUtils.flagsToString(NetworkPolicyManager.class, "BLOCKED_", blockedReasons);
     }
 
@@ -963,7 +857,7 @@
          * @hide
          */
         @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
-        default void onUidBlockedReasonChanged(int uid, @BlockedReason int blockedReasons) {}
+        default void onUidBlockedReasonChanged(int uid, int blockedReasons) {}
     }
 
     /** @hide */
@@ -978,8 +872,7 @@
         }
 
         @Override
-        public void onBlockedReasonChanged(int uid, @BlockedReason int oldBlockedReasons,
-                @BlockedReason int newBlockedReasons) {
+        public void onBlockedReasonChanged(int uid, int oldBlockedReasons, int newBlockedReasons) {
             if (oldBlockedReasons != newBlockedReasons) {
                 dispatchOnUidBlockedReasonChanged(mExecutor, mCallback, uid, newBlockedReasons);
             }
@@ -987,7 +880,7 @@
     }
 
     private static void dispatchOnUidBlockedReasonChanged(@Nullable Executor executor,
-            @NonNull NetworkPolicyCallback callback, int uid, @BlockedReason int blockedReasons) {
+            @NonNull NetworkPolicyCallback callback, int uid, int blockedReasons) {
         if (executor == null) {
             callback.onUidBlockedReasonChanged(uid, blockedReasons);
         } else {
diff --git a/core/java/android/net/netstats/provider/INetworkStatsProvider.aidl b/core/java/android/net/netstats/provider/INetworkStatsProvider.aidl
index 4078b24..74c3ba4 100644
--- a/core/java/android/net/netstats/provider/INetworkStatsProvider.aidl
+++ b/core/java/android/net/netstats/provider/INetworkStatsProvider.aidl
@@ -23,6 +23,6 @@
  */
 oneway interface INetworkStatsProvider {
     void onRequestStatsUpdate(int token);
-    void onSetLimit(String iface, long quotaBytes);
     void onSetAlert(long quotaBytes);
+    void onSetWarningAndLimit(String iface, long warningBytes, long limitBytes);
 }
diff --git a/core/java/android/net/netstats/provider/INetworkStatsProviderCallback.aidl b/core/java/android/net/netstats/provider/INetworkStatsProviderCallback.aidl
index bd336dd..7eaa01e 100644
--- a/core/java/android/net/netstats/provider/INetworkStatsProviderCallback.aidl
+++ b/core/java/android/net/netstats/provider/INetworkStatsProviderCallback.aidl
@@ -26,6 +26,6 @@
 oneway interface INetworkStatsProviderCallback {
     void notifyStatsUpdated(int token, in NetworkStats ifaceStats, in NetworkStats uidStats);
     void notifyAlertReached();
-    void notifyLimitReached();
+    void notifyWarningOrLimitReached();
     void unregister();
 }
diff --git a/core/java/android/net/netstats/provider/NetworkStatsProvider.java b/core/java/android/net/netstats/provider/NetworkStatsProvider.java
index 7639d22..23fc069 100644
--- a/core/java/android/net/netstats/provider/NetworkStatsProvider.java
+++ b/core/java/android/net/netstats/provider/NetworkStatsProvider.java
@@ -29,7 +29,8 @@
 @SystemApi
 public abstract class NetworkStatsProvider {
     /**
-     * A value used by {@link #onSetLimit} and {@link #onSetAlert} indicates there is no limit.
+     * A value used by {@link #onSetLimit}, {@link #onSetAlert} and {@link #onSetWarningAndLimit}
+     * indicates there is no limit.
      */
     public static final int QUOTA_UNLIMITED = -1;
 
@@ -42,13 +43,13 @@
         }
 
         @Override
-        public void onSetLimit(String iface, long quotaBytes) {
-            NetworkStatsProvider.this.onSetLimit(iface, quotaBytes);
+        public void onSetAlert(long quotaBytes) {
+            NetworkStatsProvider.this.onSetAlert(quotaBytes);
         }
 
         @Override
-        public void onSetAlert(long quotaBytes) {
-            NetworkStatsProvider.this.onSetAlert(quotaBytes);
+        public void onSetWarningAndLimit(String iface, long warningBytes, long limitBytes) {
+            NetworkStatsProvider.this.onSetWarningAndLimit(iface, warningBytes, limitBytes);
         }
     };
 
@@ -145,11 +146,25 @@
     }
 
     /**
-     * Notify system that the quota set by {@code onSetLimit} has been reached.
+     * Notify system that the warning set by {@link #onSetWarningAndLimit} has been reached.
+     */
+    public void notifyWarningReached() {
+        try {
+            // Reuse the code path to notify warning reached with limit reached
+            // since framework handles them in the same way.
+            getProviderCallbackBinderOrThrow().notifyWarningOrLimitReached();
+        } catch (RemoteException e) {
+            e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * Notify system that the quota set by {@link #onSetLimit} or limit set by
+     * {@link #onSetWarningAndLimit} has been reached.
      */
     public void notifyLimitReached() {
         try {
-            getProviderCallbackBinderOrThrow().notifyLimitReached();
+            getProviderCallbackBinderOrThrow().notifyWarningOrLimitReached();
         } catch (RemoteException e) {
             e.rethrowAsRuntimeException();
         }
@@ -183,6 +198,28 @@
     public abstract void onSetLimit(@NonNull String iface, long quotaBytes);
 
     /**
+     * Called by {@code NetworkStatsService} when setting the interface quotas for the specified
+     * upstream interface. If a provider implements {@link #onSetWarningAndLimit}, the system
+     * will not call {@link #onSetLimit}. When this method is called, the implementation
+     * should behave as follows:
+     *   1. If {@code warningBytes} is reached on {@code iface}, block all further traffic on
+     *      {@code iface} and call {@link NetworkStatsProvider@notifyWarningReached()}.
+     *   2. If {@code limitBytes} is reached on {@code iface}, block all further traffic on
+     *   {@code iface} and call {@link NetworkStatsProvider#notifyLimitReached()}.
+     *
+     * @param iface the interface requiring the operation.
+     * @param warningBytes the warning defined as the number of bytes, starting from zero and
+     *                     counting from now. A value of {@link #QUOTA_UNLIMITED} indicates
+     *                     there is no warning.
+     * @param limitBytes the limit defined as the number of bytes, starting from zero and counting
+     *                   from now. A value of {@link #QUOTA_UNLIMITED} indicates there is no limit.
+     */
+    public void onSetWarningAndLimit(@NonNull String iface, long warningBytes, long limitBytes) {
+        // Backward compatibility for those who didn't override this function.
+        onSetLimit(iface, limitBytes);
+    }
+
+    /**
      * Called by {@code NetworkStatsService} when setting the alert bytes. Custom implementations
      * MUST call {@link NetworkStatsProvider#notifyAlertReached()} when {@code quotaBytes} bytes
      * have been reached. Unlike {@link #onSetLimit(String, long)}, the custom implementation should
diff --git a/core/java/android/net/vcn/IVcnManagementService.aidl b/core/java/android/net/vcn/IVcnManagementService.aidl
index 6a3cb42..5b79f73 100644
--- a/core/java/android/net/vcn/IVcnManagementService.aidl
+++ b/core/java/android/net/vcn/IVcnManagementService.aidl
@@ -29,7 +29,7 @@
  */
 interface IVcnManagementService {
     void setVcnConfig(in ParcelUuid subscriptionGroup, in VcnConfig config, in String opPkgName);
-    void clearVcnConfig(in ParcelUuid subscriptionGroup);
+    void clearVcnConfig(in ParcelUuid subscriptionGroup, in String opPkgName);
 
     void addVcnUnderlyingNetworkPolicyListener(in IVcnUnderlyingNetworkPolicyListener listener);
     void removeVcnUnderlyingNetworkPolicyListener(in IVcnUnderlyingNetworkPolicyListener listener);
diff --git a/core/java/android/net/vcn/VcnManager.java b/core/java/android/net/vcn/VcnManager.java
index b73fdbf..abd41da 100644
--- a/core/java/android/net/vcn/VcnManager.java
+++ b/core/java/android/net/vcn/VcnManager.java
@@ -154,7 +154,7 @@
         requireNonNull(subscriptionGroup, "subscriptionGroup was null");
 
         try {
-            mService.clearVcnConfig(subscriptionGroup);
+            mService.clearVcnConfig(subscriptionGroup, mContext.getOpPackageName());
         } catch (ServiceSpecificException e) {
             throw new IOException(e);
         } catch (RemoteException e) {
@@ -439,7 +439,7 @@
          * @param statusCode the code for the status change encountered by this {@link
          *     VcnStatusCallback}'s subscription group.
          */
-        public abstract void onVcnStatusChanged(@VcnStatusCode int statusCode);
+        public abstract void onStatusChanged(@VcnStatusCode int statusCode);
 
         /**
          * Invoked when a VCN Gateway Connection corresponding to this callback's subscription group
@@ -476,7 +476,7 @@
      * and there is a VCN active for its specified subscription group (this may happen after the
      * callback is registered).
      *
-     * <p>{@link VcnStatusCallback#onVcnStatusChanged(int)} will be invoked on registration with the
+     * <p>{@link VcnStatusCallback#onStatusChanged(int)} will be invoked on registration with the
      * current status for the specified subscription group's VCN. If the registrant is not
      * privileged for this subscription group, {@link #VCN_STATUS_CODE_NOT_CONFIGURED} will be
      * returned.
@@ -580,7 +580,7 @@
         @Override
         public void onVcnStatusChanged(@VcnStatusCode int statusCode) {
             Binder.withCleanCallingIdentity(
-                    () -> mExecutor.execute(() -> mCallback.onVcnStatusChanged(statusCode)));
+                    () -> mExecutor.execute(() -> mCallback.onStatusChanged(statusCode)));
         }
 
         // TODO(b/180521637): use ServiceSpecificException for safer Exception 'parceling'
diff --git a/core/java/android/nfc/INfcAdapter.aidl b/core/java/android/nfc/INfcAdapter.aidl
index bc3d5c4..11445e9 100644
--- a/core/java/android/nfc/INfcAdapter.aidl
+++ b/core/java/android/nfc/INfcAdapter.aidl
@@ -72,7 +72,7 @@
     boolean deviceSupportsNfcSecure();
     boolean setNfcSecure(boolean enable);
 
-    boolean setAlwaysOn(boolean value);
-    boolean isAlwaysOnEnabled();
-    boolean isAlwaysOnSupported();
+    boolean setControllerAlwaysOn(boolean value);
+    boolean isControllerAlwaysOn();
+    boolean isControllerAlwaysOnSupported();
 }
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index e85eb93..eed2c77 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -2254,13 +2254,13 @@
      * @hide
      */
     @SystemApi
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public boolean setAlwaysOn(boolean value) {
+    @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON)
+    public boolean setControllerAlwaysOn(boolean value) {
         if (!sHasNfcFeature) {
             throw new UnsupportedOperationException();
         }
         try {
-            return sService.setAlwaysOn(value);
+            return sService.setControllerAlwaysOn(value);
         } catch (RemoteException e) {
             attemptDeadServiceRecovery(e);
             // Try one more time
@@ -2269,7 +2269,7 @@
                 return false;
             }
             try {
-                return sService.setAlwaysOn(value);
+                return sService.setControllerAlwaysOn(value);
             } catch (RemoteException ee) {
                 Log.e(TAG, "Failed to recover NFC Service.");
             }
@@ -2286,10 +2286,10 @@
      */
 
     @SystemApi
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public boolean isAlwaysOnEnabled() {
+    @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON)
+    public boolean isControllerAlwaysOn() {
         try {
-            return sService.isAlwaysOnEnabled();
+            return sService.isControllerAlwaysOn();
         } catch (RemoteException e) {
             attemptDeadServiceRecovery(e);
             // Try one more time
@@ -2298,7 +2298,7 @@
                 return false;
             }
             try {
-                return sService.isAlwaysOnEnabled();
+                return sService.isControllerAlwaysOn();
             } catch (RemoteException ee) {
                 Log.e(TAG, "Failed to recover NFC Service.");
             }
@@ -2315,13 +2315,13 @@
      */
 
     @SystemApi
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public boolean isAlwaysOnSupported() {
+    @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON)
+    public boolean isControllerAlwaysOnSupported() {
         if (!sHasNfcFeature) {
             throw new UnsupportedOperationException();
         }
         try {
-            return sService.isAlwaysOnSupported();
+            return sService.isControllerAlwaysOnSupported();
         } catch (RemoteException e) {
             attemptDeadServiceRecovery(e);
             // Try one more time
@@ -2330,7 +2330,7 @@
                 return false;
             }
             try {
-                return sService.isAlwaysOnSupported();
+                return sService.isControllerAlwaysOnSupported();
             } catch (RemoteException ee) {
                 Log.e(TAG, "Failed to recover NFC Service.");
             }
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index fa6472e..c47fc57 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -1004,6 +1004,24 @@
         public abstract long getCpuMeasuredBatteryConsumptionUC();
 
         /**
+         * Returns the battery consumption (in microcoulombs) of the uid's GNSS usage, derived from
+         * on device power measurement data.
+         * Will return {@link #POWER_DATA_UNAVAILABLE} if data is unavailable.
+         *
+         * {@hide}
+         */
+        public abstract long getGnssMeasuredBatteryConsumptionUC();
+
+        /**
+         * Returns the battery consumption (in microcoulombs) of the uid's radio usage, derived from
+         * on device power measurement data.
+         * Will return {@link #POWER_DATA_UNAVAILABLE} if data is unavailable.
+         *
+         * {@hide}
+         */
+        public abstract long getMobileRadioMeasuredBatteryConsumptionUC();
+
+        /**
          * Returns the battery consumption (in microcoulombs) of the screen while on and uid active,
          * derived from on device power measurement data.
          * Will return {@link #POWER_DATA_UNAVAILABLE} if data is unavailable.
@@ -2548,6 +2566,24 @@
     public abstract long getCpuMeasuredBatteryConsumptionUC();
 
     /**
+     * Returns the battery consumption (in microcoulombs) of the GNSS, derived from on device power
+     * measurement data.
+     * Will return {@link #POWER_DATA_UNAVAILABLE} if data is unavailable.
+     *
+     * {@hide}
+     */
+    public abstract long getGnssMeasuredBatteryConsumptionUC();
+
+    /**
+     * Returns the battery consumption (in microcoulombs) of the radio, derived from on device power
+     * measurement data.
+     * Will return {@link #POWER_DATA_UNAVAILABLE} if data is unavailable.
+     *
+     * {@hide}
+     */
+    public abstract long getMobileRadioMeasuredBatteryConsumptionUC();
+
+    /**
      * Returns the battery consumption (in microcoulombs) of the screen while on, derived from on
      * device power measurement data.
      * Will return {@link #POWER_DATA_UNAVAILABLE} if data is unavailable.
@@ -6030,7 +6066,7 @@
                     pw.print(":");
                     for (int it=0; it<types.size(); it++) {
                         pw.print(" ");
-                        pw.print(JobParameters.getReasonCodeDescription(types.keyAt(it)));
+                        pw.print(JobParameters.getLegacyReasonCodeDescription(types.keyAt(it)));
                         pw.print("(");
                         pw.print(types.valueAt(it));
                         pw.print("x)");
diff --git a/core/java/android/os/BatteryUsageStats.java b/core/java/android/os/BatteryUsageStats.java
index f12eb88..a0721c3 100644
--- a/core/java/android/os/BatteryUsageStats.java
+++ b/core/java/android/os/BatteryUsageStats.java
@@ -34,7 +34,7 @@
 public final class BatteryUsageStats implements Parcelable {
     private final double mConsumedPower;
     private final int mDischargePercentage;
-    private final long mStatsStartRealtimeMs;
+    private final long mStatsStartTimestampMs;
     private final double mDischargedPowerLowerBound;
     private final double mDischargedPowerUpperBound;
     private final long mBatteryTimeRemainingMs;
@@ -46,7 +46,7 @@
     private final List<BatteryStats.HistoryTag> mHistoryTagPool;
 
     private BatteryUsageStats(@NonNull Builder builder) {
-        mStatsStartRealtimeMs = builder.mStatsStartRealtimeMs;
+        mStatsStartTimestampMs = builder.mStatsStartTimestampMs;
         mDischargePercentage = builder.mDischargePercentage;
         mDischargedPowerLowerBound = builder.mDischargedPowerLowerBoundMah;
         mDischargedPowerUpperBound = builder.mDischargedPowerUpperBoundMah;
@@ -91,10 +91,11 @@
     }
 
     /**
-     * Timestamp of the latest battery stats reset, in milliseconds.
+     * Timestamp (as returned by System.currentTimeMillis()) of the latest battery stats reset, in
+     * milliseconds.
      */
-    public long getStatsStartRealtime() {
-        return mStatsStartRealtimeMs;
+    public long getStatsStartTimestamp() {
+        return mStatsStartTimestampMs;
     }
 
     /**
@@ -174,7 +175,7 @@
     }
 
     private BatteryUsageStats(@NonNull Parcel source) {
-        mStatsStartRealtimeMs = source.readLong();
+        mStatsStartTimestampMs = source.readLong();
         mConsumedPower = source.readDouble();
         mDischargePercentage = source.readInt();
         mDischargedPowerLowerBound = source.readDouble();
@@ -214,7 +215,7 @@
 
     @Override
     public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeLong(mStatsStartRealtimeMs);
+        dest.writeLong(mStatsStartTimestampMs);
         dest.writeDouble(mConsumedPower);
         dest.writeInt(mDischargePercentage);
         dest.writeDouble(mDischargedPowerLowerBound);
@@ -260,7 +261,7 @@
     public static final class Builder {
         private final int mCustomPowerComponentCount;
         private final int mCustomTimeComponentCount;
-        private long mStatsStartRealtimeMs;
+        private long mStatsStartTimestampMs;
         private int mDischargePercentage;
         private double mDischargedPowerLowerBoundMah;
         private double mDischargedPowerUpperBoundMah;
@@ -291,8 +292,8 @@
         /**
          * Sets the timestamp of the latest battery stats reset, in milliseconds.
          */
-        public Builder setStatsStartRealtime(long statsStartRealtimeMs) {
-            mStatsStartRealtimeMs = statsStartRealtimeMs;
+        public Builder setStatsStartTimestamp(long statsStartTimestampMs) {
+            mStatsStartTimestampMs = statsStartTimestampMs;
             return this;
         }
 
diff --git a/core/java/android/os/BatteryUsageStatsQuery.java b/core/java/android/os/BatteryUsageStatsQuery.java
index 9518bf1..85861bc 100644
--- a/core/java/android/os/BatteryUsageStatsQuery.java
+++ b/core/java/android/os/BatteryUsageStatsQuery.java
@@ -60,14 +60,18 @@
      */
     public static final int FLAG_BATTERY_USAGE_STATS_INCLUDE_HISTORY = 2;
 
+    private static final long DEFAULT_MAX_STATS_AGE_MS = 5 * 60 * 1000;
+
     private final int mFlags;
     @NonNull
     private final int[] mUserIds;
+    private final long mMaxStatsAgeMs;
 
     private BatteryUsageStatsQuery(@NonNull Builder builder) {
         mFlags = builder.mFlags;
         mUserIds = builder.mUserIds != null ? builder.mUserIds.toArray()
                 : new int[]{UserHandle.USER_ALL};
+        mMaxStatsAgeMs = builder.mMaxStatsAgeMs;
     }
 
     @BatteryUsageStatsFlags
@@ -94,10 +98,19 @@
         return (mFlags & FLAG_BATTERY_USAGE_STATS_POWER_PROFILE_MODEL) != 0;
     }
 
+    /**
+     * Returns the client's tolerance for stale battery stats. The data is allowed to be up to
+     * this many milliseconds out-of-date.
+     */
+    public long getMaxStatsAge() {
+        return mMaxStatsAgeMs;
+    }
+
     private BatteryUsageStatsQuery(Parcel in) {
         mFlags = in.readInt();
         mUserIds = new int[in.readInt()];
         in.readIntArray(mUserIds);
+        mMaxStatsAgeMs = in.readLong();
     }
 
     @Override
@@ -105,6 +118,7 @@
         dest.writeInt(mFlags);
         dest.writeInt(mUserIds.length);
         dest.writeIntArray(mUserIds);
+        dest.writeLong(mMaxStatsAgeMs);
     }
 
     @Override
@@ -132,6 +146,7 @@
     public static final class Builder {
         private int mFlags;
         private IntArray mUserIds;
+        private long mMaxStatsAgeMs = DEFAULT_MAX_STATS_AGE_MS;
 
         /**
          * Builds a read-only BatteryUsageStatsQuery object.
@@ -170,5 +185,14 @@
             mFlags |= BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_POWER_PROFILE_MODEL;
             return this;
         }
+
+        /**
+         * Set the client's tolerance for stale battery stats. The data may be up to
+         * this many milliseconds out-of-date.
+         */
+        public Builder setMaxStatsAgeMs(long maxStatsAgeMs) {
+            mMaxStatsAgeMs = maxStatsAgeMs;
+            return this;
+        }
     }
 }
diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java
index 8dcd937..635f581 100644
--- a/core/java/android/os/Binder.java
+++ b/core/java/android/os/Binder.java
@@ -550,6 +550,16 @@
     public final native void markVintfStability();
 
     /**
+     * Use a VINTF-stability binder w/o VINTF requirements. Should be called
+     * on a binder before it is sent out of process.
+     *
+     * This must be called before the object is sent to another process.
+     *
+     * @hide
+     */
+    public final native void forceDowngradeToSystemStability();
+
+    /**
      * Flush any Binder commands pending in the current thread to the kernel
      * driver.  This can be
      * useful to call before performing an operation that may block for a long
diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl
index ae7d94c..425e797 100644
--- a/core/java/android/os/IPowerManager.aidl
+++ b/core/java/android/os/IPowerManager.aidl
@@ -27,9 +27,9 @@
 interface IPowerManager
 {
     void acquireWakeLock(IBinder lock, int flags, String tag, String packageName, in WorkSource ws,
-            String historyTag);
+            String historyTag, int displayId);
     void acquireWakeLockWithUid(IBinder lock, int flags, String tag, String packageName,
-            int uidtoblame);
+            int uidtoblame, int displayId);
     @UnsupportedAppUsage
     void releaseWakeLock(IBinder lock, int flags);
     void updateWakeLockUids(IBinder lock, in int[] uids);
diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl
index 087568d..34f2c103f 100644
--- a/core/java/android/os/IUserManager.aidl
+++ b/core/java/android/os/IUserManager.aidl
@@ -99,6 +99,8 @@
     boolean someUserHasSeedAccount(in String accountName, in String accountType);
     boolean isProfile(int userId);
     boolean isManagedProfile(int userId);
+    boolean isCloneProfile(int userId);
+    boolean sharesMediaWithParent(int userId);
     boolean isDemoUser(int userId);
     boolean isPreCreated(int userId);
     UserInfo createProfileForUserEvenWhenDisallowedWithThrow(in String name, in String userType, int flags,
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 2c4d130..9d1fd50 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -36,6 +36,7 @@
 import android.util.ArrayMap;
 import android.util.Log;
 import android.util.proto.ProtoOutputStream;
+import android.view.Display;
 
 import com.android.internal.util.Preconditions;
 
@@ -1143,8 +1144,7 @@
      * wake lock, and {@link WakeLock#release release()} when you are done.
      * </p><p>
      * {@samplecode
-     * PowerManager pm = (PowerManager)mContext.getSystemService(
-     *                                          Context.POWER_SERVICE);
+     * PowerManager pm = mContext.getSystemService(PowerManager.class);
      * PowerManager.WakeLock wl = pm.newWakeLock(
      *                                      PowerManager.SCREEN_DIM_WAKE_LOCK
      *                                      | PowerManager.ON_AFTER_RELEASE,
@@ -1162,6 +1162,8 @@
      * {@link android.view.WindowManager.LayoutParams#FLAG_KEEP_SCREEN_ON} instead.
      * This window flag will be correctly managed by the platform
      * as the user moves between applications and doesn't require a special permission.
+     * Additionally using the flag will keep only the appropriate screen on in a
+     * multi-display scenario while using a wake lock will keep every screen powered on.
      * </p>
      *
      * <p>
@@ -1179,7 +1181,7 @@
      * can be transformed by java optimizer and obfuscator tools.
      * <li>avoid wrapping the tag or a prefix to avoid collision with wake lock
      * tags from the platform (e.g. *alarm*).
-     * <li>never include personnally identifiable information for privacy
+     * <li>never include personally identifiable information for privacy
      * reasons.
      * </ul>
      * </p>
@@ -1200,7 +1202,27 @@
      */
     public WakeLock newWakeLock(int levelAndFlags, String tag) {
         validateWakeLockParameters(levelAndFlags, tag);
-        return new WakeLock(levelAndFlags, tag, mContext.getOpPackageName());
+        return new WakeLock(levelAndFlags, tag, mContext.getOpPackageName(),
+                Display.INVALID_DISPLAY);
+    }
+
+    /**
+     * Creates a new wake lock with the specified level and flags.
+     * <p>
+     * The wakelock will only apply to the {@link com.android.server.display.DisplayGroup} of the
+     * provided {@code displayId}. If {@code displayId} is {@link Display#INVALID_DISPLAY} then it
+     * will apply to all {@link com.android.server.display.DisplayGroup DisplayGroups}.
+     *
+     * @param levelAndFlags Combination of wake lock level and flag values defining
+     * the requested behavior of the WakeLock.
+     * @param tag Your class name (or other tag) for debugging purposes.
+     * @param displayId The display id to which this wake lock is tied.
+     *
+     * @hide
+     */
+    public WakeLock newWakeLock(int levelAndFlags, String tag, int displayId) {
+        validateWakeLockParameters(levelAndFlags, tag);
+        return new WakeLock(levelAndFlags, tag, mContext.getOpPackageName(), displayId);
     }
 
     /** @hide */
@@ -2603,19 +2625,17 @@
         private WorkSource mWorkSource;
         private String mHistoryTag;
         private final String mTraceName;
+        private final int mDisplayId;
 
-        private final Runnable mReleaser = new Runnable() {
-            public void run() {
-                release(RELEASE_FLAG_TIMEOUT);
-            }
-        };
+        private final Runnable mReleaser = () -> release(RELEASE_FLAG_TIMEOUT);
 
-        WakeLock(int flags, String tag, String packageName) {
+        WakeLock(int flags, String tag, String packageName, int displayId) {
             mFlags = flags;
             mTag = tag;
             mPackageName = packageName;
             mToken = new Binder();
             mTraceName = "WakeLock (" + mTag + ")";
+            mDisplayId = displayId;
         }
 
         @Override
@@ -2696,7 +2716,7 @@
                 Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, mTraceName, 0);
                 try {
                     mService.acquireWakeLock(mToken, mFlags, mTag, mPackageName, mWorkSource,
-                            mHistoryTag);
+                            mHistoryTag, mDisplayId);
                 } catch (RemoteException e) {
                     throw e.rethrowFromSystemServer();
                 }
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index bf859d4..f9e4f73 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -131,6 +131,7 @@
      * @hide
      */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    @TestApi
     public static final int NFC_UID = 1027;
 
     /**
diff --git a/core/java/android/os/SystemBatteryConsumer.java b/core/java/android/os/SystemBatteryConsumer.java
index 06cff90..5f35332 100644
--- a/core/java/android/os/SystemBatteryConsumer.java
+++ b/core/java/android/os/SystemBatteryConsumer.java
@@ -18,6 +18,7 @@
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
+import android.util.Slog;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -31,6 +32,7 @@
  * {@hide}
  */
 public class SystemBatteryConsumer extends BatteryConsumer implements Parcelable {
+    private static final String TAG = "SystemBatteryConsumer";
 
     //                           ****************
     // This list must be kept current with atoms.proto (frameworks/base/cmds/statsd/src/atoms.proto)
@@ -72,6 +74,8 @@
     @DrainType
     private final int mDrainType;
 
+    private final double mPowerConsumedByAppsMah;
+
     @DrainType
     public int getDrainType() {
         return mDrainType;
@@ -80,11 +84,23 @@
     private SystemBatteryConsumer(@NonNull SystemBatteryConsumer.Builder builder) {
         super(builder.mPowerComponentsBuilder.build());
         mDrainType = builder.mDrainType;
+        mPowerConsumedByAppsMah = builder.mPowerConsumedByAppsMah;
+        if (mPowerConsumedByAppsMah > getConsumedPower()) {
+            Slog.wtf(TAG,
+                    "Power attributed to apps exceeds total: drain type = " + mDrainType
+                            + " total consumed power = " + getConsumedPower()
+                            + " power consumed by apps = " + mPowerConsumedByAppsMah);
+        }
     }
 
     private SystemBatteryConsumer(Parcel in) {
         super(new PowerComponents(in));
         mDrainType = in.readInt();
+        mPowerConsumedByAppsMah = in.readDouble();
+    }
+
+    public double getPowerConsumedByApps() {
+        return mPowerConsumedByAppsMah;
     }
 
     /**
@@ -94,6 +110,7 @@
     public void writeToParcel(@NonNull Parcel dest, int flags) {
         super.writeToParcel(dest, flags);
         dest.writeInt(mDrainType);
+        dest.writeDouble(mPowerConsumedByAppsMah);
     }
 
     public static final Creator<SystemBatteryConsumer> CREATOR =
@@ -120,6 +137,7 @@
     public static final class Builder extends BaseBuilder<Builder> {
         @DrainType
         private final int mDrainType;
+        private double mPowerConsumedByAppsMah;
         private List<UidBatteryConsumer.Builder> mUidBatteryConsumers;
 
         Builder(int customPowerComponentCount, int customTimeComponentCount,
@@ -129,6 +147,15 @@
         }
 
         /**
+         * Sets the amount of power used by this system component that is attributed to apps.
+         * It should not exceed the total consumed power.
+         */
+        public Builder setPowerConsumedByApps(double powerConsumedByAppsMah) {
+            mPowerConsumedByAppsMah = powerConsumedByAppsMah;
+            return this;
+        }
+
+        /**
          * Add a UidBatteryConsumer to this SystemBatteryConsumer. For example,
          * the UidBatteryConsumer with the UID == {@link Process#BLUETOOTH_UID} should
          * be added to the SystemBatteryConsumer with the drain type == {@link
diff --git a/core/java/android/os/SystemVibrator.java b/core/java/android/os/SystemVibrator.java
index b42a495..219912c 100644
--- a/core/java/android/os/SystemVibrator.java
+++ b/core/java/android/os/SystemVibrator.java
@@ -218,7 +218,7 @@
 
     @Override
     public boolean[] arePrimitivesSupported(
-            @NonNull @VibrationEffect.Composition.Primitive int... primitiveIds) {
+            @NonNull @VibrationEffect.Composition.PrimitiveType int... primitiveIds) {
         boolean[] supported = new boolean[primitiveIds.length];
         if (mVibratorManager == null) {
             Log.w(TAG, "Failed to check supported primitives; no vibrator manager.");
diff --git a/core/java/android/os/SystemVibratorManager.java b/core/java/android/os/SystemVibratorManager.java
index b528eb1..841aad5 100644
--- a/core/java/android/os/SystemVibratorManager.java
+++ b/core/java/android/os/SystemVibratorManager.java
@@ -211,7 +211,7 @@
 
         @Override
         public boolean[] arePrimitivesSupported(
-                @NonNull @VibrationEffect.Composition.Primitive int... primitiveIds) {
+                @NonNull @VibrationEffect.Composition.PrimitiveType int... primitiveIds) {
             boolean[] supported = new boolean[primitiveIds.length];
             for (int i = 0; i < primitiveIds.length; i++) {
                 supported[i] = mVibratorInfo.isPrimitiveSupported(primitiveIds[i]);
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 5069e031..d4de4fa 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -25,6 +25,7 @@
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
 import android.annotation.StringDef;
+import android.annotation.SuppressAutoDoc;
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
 import android.annotation.TestApi;
@@ -136,6 +137,16 @@
     public static final String USER_TYPE_PROFILE_MANAGED = "android.os.usertype.profile.MANAGED";
 
     /**
+     * User type representing a clone profile. Clone profile is a user profile type used to run
+     * second instance of an otherwise single user App (eg, messengers). Only the primary user
+     * is allowed to have a clone profile.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String USER_TYPE_PROFILE_CLONE = "android.os.usertype.profile.CLONE";
+
+    /**
      * User type representing a generic profile for testing purposes. Only on debuggable builds.
      * @hide
      */
@@ -1984,6 +1995,14 @@
     }
 
     /**
+     * Returns whether the user type is a {@link UserManager#USER_TYPE_PROFILE_CLONE clone user}.
+     * @hide
+     */
+    public static boolean isUserTypeCloneProfile(String userType) {
+        return USER_TYPE_PROFILE_CLONE.equals(userType);
+    }
+
+    /**
      * Returns the enum defined in the statsd UserLifecycleJourneyReported atom corresponding to the
      * user type.
      * @hide
@@ -2233,6 +2252,31 @@
     }
 
     /**
+     * Checks if the context user is a clone profile.
+     *
+     * <p>Requires {@link android.Manifest.permission#MANAGE_USERS} or
+     * {@link android.Manifest.permission#INTERACT_ACROSS_USERS} permission, otherwise the caller
+     * must be in the same profile group of the user.
+     *
+     * @return whether the context user is a clone profile.
+     *
+     * @see android.os.UserManager#USER_TYPE_PROFILE_CLONE
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(anyOf = {android.Manifest.permission.MANAGE_USERS,
+            Manifest.permission.INTERACT_ACROSS_USERS}, conditional = true)
+    @UserHandleAware
+    @SuppressAutoDoc
+    public boolean isCloneProfile() {
+        try {
+            return mService.isCloneProfile(mUserId);
+        } catch (RemoteException re) {
+            throw re.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Checks if the calling app is running as an ephemeral user.
      *
      * @return whether the caller is an ephemeral user.
@@ -4064,6 +4108,31 @@
     }
 
     /**
+     * If the user is a {@link UserManager#isProfile profile}, checks if the user
+     * shares media with its parent user (the user that created this profile).
+     * Returns false for any other type of user.
+     *
+     * <p>Requires {@link android.Manifest.permission#MANAGE_USERS} or
+     * {@link android.Manifest.permission#INTERACT_ACROSS_USERS} permission, otherwise the
+     * caller must be in the same profile group as the user.
+     *
+     * @return true if the user shares media with its parent user, false otherwise.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(anyOf = {android.Manifest.permission.MANAGE_USERS,
+            Manifest.permission.INTERACT_ACROSS_USERS}, conditional = true)
+    @UserHandleAware
+    @SuppressAutoDoc
+    public boolean sharesMediaWithParent() {
+        try {
+            return mService.sharesMediaWithParent(mUserId);
+        } catch (RemoteException re) {
+            throw re.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Removes a user and all associated data.
      * @param userId the integer handle of the user.
      * @hide
diff --git a/core/java/android/os/VibrationAttributes.java b/core/java/android/os/VibrationAttributes.java
index 217f178..cec323f 100644
--- a/core/java/android/os/VibrationAttributes.java
+++ b/core/java/android/os/VibrationAttributes.java
@@ -21,6 +21,8 @@
 import android.annotation.Nullable;
 import android.annotation.TestApi;
 import android.media.AudioAttributes;
+import android.os.vibrator.PrebakedSegment;
+import android.os.vibrator.VibrationEffectSegment;
 import android.util.Slog;
 
 import java.lang.annotation.Retention;
@@ -330,9 +332,9 @@
 
         private void applyHapticFeedbackHeuristics(@Nullable VibrationEffect effect) {
             if (effect != null) {
-                if (mUsage == USAGE_UNKNOWN && effect instanceof VibrationEffect.Prebaked) {
-                    VibrationEffect.Prebaked prebaked = (VibrationEffect.Prebaked) effect;
-                    switch (prebaked.getId()) {
+                PrebakedSegment prebaked = extractPrebakedSegment(effect);
+                if (mUsage == USAGE_UNKNOWN && prebaked != null) {
+                    switch (prebaked.getEffectId()) {
                         case VibrationEffect.EFFECT_CLICK:
                         case VibrationEffect.EFFECT_DOUBLE_CLICK:
                         case VibrationEffect.EFFECT_HEAVY_CLICK:
@@ -355,6 +357,20 @@
             }
         }
 
+        @Nullable
+        private PrebakedSegment extractPrebakedSegment(VibrationEffect effect) {
+            if (effect instanceof VibrationEffect.Composed) {
+                VibrationEffect.Composed composed = (VibrationEffect.Composed) effect;
+                if (composed.getSegments().size() == 1) {
+                    VibrationEffectSegment segment = composed.getSegments().get(0);
+                    if (segment instanceof PrebakedSegment) {
+                        return (PrebakedSegment) segment;
+                    }
+                }
+            }
+            return null;
+        }
+
         private void setUsage(@NonNull AudioAttributes audio) {
             mOriginalAudioUsage = audio.getUsage();
             switch (audio.getUsage()) {
diff --git a/core/java/android/os/VibrationEffect.aidl b/core/java/android/os/VibrationEffect.aidl
index 89478fa..6311760 100644
--- a/core/java/android/os/VibrationEffect.aidl
+++ b/core/java/android/os/VibrationEffect.aidl
@@ -17,4 +17,3 @@
 package android.os;
 
 parcelable VibrationEffect;
-parcelable VibrationEffect.Composition.PrimitiveEffect;
\ No newline at end of file
diff --git a/core/java/android/os/VibrationEffect.java b/core/java/android/os/VibrationEffect.java
index 0199fad..c78bf8c 100644
--- a/core/java/android/os/VibrationEffect.java
+++ b/core/java/android/os/VibrationEffect.java
@@ -21,6 +21,7 @@
 import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.SuppressLint;
 import android.annotation.TestApi;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.ContentResolver;
@@ -28,6 +29,11 @@
 import android.hardware.vibrator.V1_0.EffectStrength;
 import android.hardware.vibrator.V1_3.Effect;
 import android.net.Uri;
+import android.os.vibrator.PrebakedSegment;
+import android.os.vibrator.PrimitiveSegment;
+import android.os.vibrator.RampSegment;
+import android.os.vibrator.StepSegment;
+import android.os.vibrator.VibrationEffectSegment;
 import android.util.MathUtils;
 
 import com.android.internal.util.Preconditions;
@@ -45,11 +51,6 @@
  * These effects may be any number of things, from single shot vibrations to complex waveforms.
  */
 public abstract class VibrationEffect implements Parcelable {
-    private static final int PARCEL_TOKEN_ONE_SHOT = 1;
-    private static final int PARCEL_TOKEN_WAVEFORM = 2;
-    private static final int PARCEL_TOKEN_EFFECT = 3;
-    private static final int PARCEL_TOKEN_COMPOSITION = 4;
-
     // Stevens' coefficient to scale the perceived vibration intensity.
     private static final float SCALE_GAMMA = 0.65f;
 
@@ -181,9 +182,7 @@
      * @return The desired effect.
      */
     public static VibrationEffect createOneShot(long milliseconds, int amplitude) {
-        VibrationEffect effect = new OneShot(milliseconds, amplitude);
-        effect.validate();
-        return effect;
+        return createWaveform(new long[]{milliseconds}, new int[]{amplitude}, -1 /* repeat */);
     }
 
     /**
@@ -243,7 +242,19 @@
      * @return The desired effect.
      */
     public static VibrationEffect createWaveform(long[] timings, int[] amplitudes, int repeat) {
-        VibrationEffect effect = new Waveform(timings, amplitudes, repeat);
+        if (timings.length != amplitudes.length) {
+            throw new IllegalArgumentException(
+                    "timing and amplitude arrays must be of equal length"
+                            + " (timings.length=" + timings.length
+                            + ", amplitudes.length=" + amplitudes.length + ")");
+        }
+        List<StepSegment> segments = new ArrayList<>();
+        for (int i = 0; i < timings.length; i++) {
+            float parsedAmplitude = amplitudes[i] == DEFAULT_AMPLITUDE
+                    ? DEFAULT_AMPLITUDE : (float) amplitudes[i] / MAX_AMPLITUDE;
+            segments.add(new StepSegment(parsedAmplitude, /* frequency= */ 0, (int) timings[i]));
+        }
+        VibrationEffect effect = new Composed(segments, repeat);
         effect.validate();
         return effect;
     }
@@ -317,7 +328,8 @@
      */
     @TestApi
     public static VibrationEffect get(int effectId, boolean fallback) {
-        VibrationEffect effect = new Prebaked(effectId, fallback, EffectStrength.MEDIUM);
+        VibrationEffect effect = new Composed(
+                new PrebakedSegment(effectId, fallback, EffectStrength.MEDIUM));
         effect.validate();
         return effect;
     }
@@ -379,8 +391,26 @@
      * @see VibrationEffect.Composition
      */
     @NonNull
-    public static VibrationEffect.Composition startComposition() {
-        return new VibrationEffect.Composition();
+    public static Composition startComposition() {
+        return new Composition();
+    }
+
+    /**
+     * Start building a waveform vibration.
+     *
+     * <p>The waveform builder offers more flexibility for creating waveform vibrations, allowing
+     * control over vibration frequency and ramping up or down the vibration amplitude, frequency or
+     * both.
+     *
+     * <p>For simpler waveform patterns see {@link #createWaveform} methods.
+     *
+     * @hide
+     * @see VibrationEffect.WaveformBuilder
+     */
+    @TestApi
+    @NonNull
+    public static WaveformBuilder startWaveform() {
+        return new WaveformBuilder();
     }
 
     @Override
@@ -428,32 +458,28 @@
     public abstract <T extends VibrationEffect> T scale(float scaleFactor);
 
     /**
-     * Scale given vibration intensity by the given factor.
+     * Applies given effect strength to prebaked effects represented by one of
+     * VibrationEffect.EFFECT_*.
      *
-     * @param amplitude amplitude of the effect, must be between 0 and MAX_AMPLITUDE
-     * @param scaleFactor scale factor to be applied to the intensity. Values within [0,1) will
-     *                    scale down the intensity, values larger than 1 will scale up
-     *
+     * @param effectStrength new effect strength to be applied, one of
+     *                       VibrationEffect.EFFECT_STRENGTH_*.
+     * @return this if there is no change to this effect, or a copy of this effect with applied
+     * effect strength otherwise.
      * @hide
      */
-    protected static int scale(int amplitude, float scaleFactor) {
-        if (amplitude == 0) {
-            return 0;
-        }
-        int scaled = (int) (scale((float) amplitude / MAX_AMPLITUDE, scaleFactor) * MAX_AMPLITUDE);
-        return MathUtils.constrain(scaled, 1, MAX_AMPLITUDE);
+    public <T extends VibrationEffect> T applyEffectStrength(int effectStrength) {
+        return (T) this;
     }
 
     /**
      * Scale given vibration intensity by the given factor.
      *
-     * @param intensity relative intensity of the effect, must be between 0 and 1
+     * @param intensity   relative intensity of the effect, must be between 0 and 1
      * @param scaleFactor scale factor to be applied to the intensity. Values within [0,1) will
      *                    scale down the intensity, values larger than 1 will scale up
-     *
      * @hide
      */
-    protected static float scale(float intensity, float scaleFactor) {
+    public static float scale(float intensity, float scaleFactor) {
         // Applying gamma correction to the scale factor, which is the same as encoding the input
         // value, scaling it, then decoding the scaled value.
         float scale = MathUtils.pow(scaleFactor, 1f / SCALE_GAMMA);
@@ -516,545 +542,152 @@
         }
     }
 
-    /** @hide */
+    /**
+     * Implementation of {@link VibrationEffect} described by a composition of one or more
+     * {@link VibrationEffectSegment}, with an optional index to represent repeating effects.
+     *
+     * @hide
+     */
     @TestApi
-    public static class OneShot extends VibrationEffect implements Parcelable {
-        private final long mDuration;
-        private final int mAmplitude;
+    public static final class Composed extends VibrationEffect {
+        private final ArrayList<VibrationEffectSegment> mSegments;
+        private final int mRepeatIndex;
 
-        public OneShot(Parcel in) {
-            mDuration = in.readLong();
-            mAmplitude = in.readInt();
+        Composed(@NonNull Parcel in) {
+            this(in.readArrayList(VibrationEffectSegment.class.getClassLoader()), in.readInt());
         }
 
-        public OneShot(long milliseconds, int amplitude) {
-            mDuration = milliseconds;
-            mAmplitude = amplitude;
-        }
-
-        @Override
-        public long getDuration() {
-            return mDuration;
-        }
-
-        public int getAmplitude() {
-            return mAmplitude;
+        Composed(@NonNull VibrationEffectSegment segment) {
+            this(Arrays.asList(segment), /* repeatIndex= */ -1);
         }
 
         /** @hide */
-        @Override
-        public OneShot scale(float scaleFactor) {
-            if (scaleFactor == 1f || mAmplitude == DEFAULT_AMPLITUDE) {
-                // Just return this if there's no scaling to be done or if amplitude is not yet set.
-                return this;
-            }
-            return new OneShot(mDuration, scale(mAmplitude, scaleFactor));
+        public Composed(@NonNull List<? extends VibrationEffectSegment> segments, int repeatIndex) {
+            super();
+            mSegments = new ArrayList<>(segments);
+            mRepeatIndex = repeatIndex;
         }
 
-        /** @hide */
-        @Override
-        public OneShot resolve(int defaultAmplitude) {
-            if (defaultAmplitude > MAX_AMPLITUDE || defaultAmplitude <= 0) {
-                throw new IllegalArgumentException(
-                        "amplitude must be between 1 and 255 inclusive (amplitude="
-                        + defaultAmplitude + ")");
-            }
-            if (mAmplitude == DEFAULT_AMPLITUDE) {
-                return new OneShot(mDuration, defaultAmplitude);
-            }
-            return this;
-        }
-
-        /** @hide */
-        @Override
-        public void validate() {
-            if (mAmplitude < -1 || mAmplitude == 0 || mAmplitude > 255) {
-                throw new IllegalArgumentException(
-                        "amplitude must either be DEFAULT_AMPLITUDE, "
-                        + "or between 1 and 255 inclusive (amplitude=" + mAmplitude + ")");
-            }
-            if (mDuration <= 0) {
-                throw new IllegalArgumentException(
-                        "duration must be positive (duration=" + mDuration + ")");
-            }
-        }
-
-        @Override
-        public boolean equals(@Nullable Object o) {
-            if (!(o instanceof VibrationEffect.OneShot)) {
-                return false;
-            }
-            VibrationEffect.OneShot other = (VibrationEffect.OneShot) o;
-            return other.mDuration == mDuration && other.mAmplitude == mAmplitude;
-        }
-
-        @Override
-        public int hashCode() {
-            int result = 17;
-            result += 37 * (int) mDuration;
-            result += 37 * mAmplitude;
-            return result;
-        }
-
-        @Override
-        public String toString() {
-            return "OneShot{mDuration=" + mDuration + ", mAmplitude=" + mAmplitude + "}";
-        }
-
-        @Override
-        public void writeToParcel(Parcel out, int flags) {
-            out.writeInt(PARCEL_TOKEN_ONE_SHOT);
-            out.writeLong(mDuration);
-            out.writeInt(mAmplitude);
-        }
-
-        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-        public static final @android.annotation.NonNull Parcelable.Creator<OneShot> CREATOR =
-            new Parcelable.Creator<OneShot>() {
-                @Override
-                public OneShot createFromParcel(Parcel in) {
-                    // Skip the type token
-                    in.readInt();
-                    return new OneShot(in);
-                }
-                @Override
-                public OneShot[] newArray(int size) {
-                    return new OneShot[size];
-                }
-            };
-    }
-
-    /** @hide */
-    @TestApi
-    public static class Waveform extends VibrationEffect implements Parcelable {
-        private final long[] mTimings;
-        private final int[] mAmplitudes;
-        private final int mRepeat;
-
-        public Waveform(Parcel in) {
-            this(in.createLongArray(), in.createIntArray(), in.readInt());
-        }
-
-        public Waveform(long[] timings, int[] amplitudes, int repeat) {
-            mTimings = new long[timings.length];
-            System.arraycopy(timings, 0, mTimings, 0, timings.length);
-            mAmplitudes = new int[amplitudes.length];
-            System.arraycopy(amplitudes, 0, mAmplitudes, 0, amplitudes.length);
-            mRepeat = repeat;
-        }
-
-        public long[] getTimings() {
-            return mTimings;
-        }
-
-        public int[] getAmplitudes() {
-            return mAmplitudes;
+        @NonNull
+        public List<VibrationEffectSegment> getSegments() {
+            return mSegments;
         }
 
         public int getRepeatIndex() {
-            return mRepeat;
+            return mRepeatIndex;
+        }
+
+        @Override
+        public void validate() {
+            int segmentCount = mSegments.size();
+            boolean hasNonZeroDuration = false;
+            boolean hasNonZeroAmplitude = false;
+            for (int i = 0; i < segmentCount; i++) {
+                VibrationEffectSegment segment = mSegments.get(i);
+                segment.validate();
+                // A segment with unknown duration = -1 still counts as a non-zero duration.
+                hasNonZeroDuration |= segment.getDuration() != 0;
+                hasNonZeroAmplitude |= segment.hasNonZeroAmplitude();
+            }
+            if (!hasNonZeroDuration) {
+                throw new IllegalArgumentException("at least one timing must be non-zero"
+                        + " (segments=" + mSegments + ")");
+            }
+            if (!hasNonZeroAmplitude) {
+                throw new IllegalArgumentException("at least one amplitude must be non-zero"
+                        + " (segments=" + mSegments + ")");
+            }
+            if (mRepeatIndex != -1) {
+                Preconditions.checkArgumentInRange(mRepeatIndex, 0, segmentCount - 1,
+                        "repeat index must be within the bounds of the segments (segments.length="
+                                + segmentCount + ", index=" + mRepeatIndex + ")");
+            }
         }
 
         @Override
         public long getDuration() {
-            if (mRepeat >= 0) {
+            if (mRepeatIndex >= 0) {
                 return Long.MAX_VALUE;
             }
-            long duration = 0;
-            for (long d : mTimings) {
-                duration += d;
-            }
-            return duration;
-        }
-
-        /** @hide */
-        @Override
-        public Waveform scale(float scaleFactor) {
-            if (scaleFactor == 1f) {
-                // Just return this if there's no scaling to be done.
-                return this;
-            }
-            boolean scaled = false;
-            int[] scaledAmplitudes = Arrays.copyOf(mAmplitudes, mAmplitudes.length);
-            for (int i = 0; i < scaledAmplitudes.length; i++) {
-                if (scaledAmplitudes[i] == DEFAULT_AMPLITUDE) {
-                    // Skip amplitudes that are not set.
-                    continue;
+            int segmentCount = mSegments.size();
+            long totalDuration = 0;
+            for (int i = 0; i < segmentCount; i++) {
+                long segmentDuration = mSegments.get(i).getDuration();
+                if (segmentDuration < 0) {
+                    return segmentDuration;
                 }
-                scaled = true;
-                scaledAmplitudes[i] = scale(scaledAmplitudes[i], scaleFactor);
+                totalDuration += segmentDuration;
             }
-            if (!scaled) {
-                // Just return this if no scaling was done.
-                return this;
-            }
-            return new Waveform(mTimings, scaledAmplitudes, mRepeat);
+            return totalDuration;
         }
 
-        /** @hide */
-        @Override
-        public Waveform resolve(int defaultAmplitude) {
-            if (defaultAmplitude > MAX_AMPLITUDE || defaultAmplitude < 0) {
-                throw new IllegalArgumentException(
-                        "Amplitude is negative or greater than MAX_AMPLITUDE");
-            }
-            boolean resolved = false;
-            int[] resolvedAmplitudes = Arrays.copyOf(mAmplitudes, mAmplitudes.length);
-            for (int i = 0; i < resolvedAmplitudes.length; i++) {
-                if (resolvedAmplitudes[i] == DEFAULT_AMPLITUDE) {
-                    resolvedAmplitudes[i] = defaultAmplitude;
-                    resolved = true;
-                }
-            }
-            if (!resolved) {
-                return this;
-            }
-            return new Waveform(mTimings, resolvedAmplitudes, mRepeat);
-        }
-
-        /** @hide */
-        @Override
-        public void validate() {
-            if (mTimings.length != mAmplitudes.length) {
-                throw new IllegalArgumentException(
-                        "timing and amplitude arrays must be of equal length"
-                        + " (timings.length=" + mTimings.length
-                        + ", amplitudes.length=" + mAmplitudes.length + ")");
-            }
-            if (!hasNonZeroEntry(mTimings)) {
-                throw new IllegalArgumentException("at least one timing must be non-zero"
-                        + " (timings=" + Arrays.toString(mTimings) + ")");
-            }
-            for (long timing : mTimings) {
-                if (timing < 0) {
-                    throw new IllegalArgumentException("timings must all be >= 0"
-                            + " (timings=" + Arrays.toString(mTimings) + ")");
-                }
-            }
-            for (int amplitude : mAmplitudes) {
-                if (amplitude < -1 || amplitude > 255) {
-                    throw new IllegalArgumentException(
-                            "amplitudes must all be DEFAULT_AMPLITUDE or between 0 and 255"
-                            + " (amplitudes=" + Arrays.toString(mAmplitudes) + ")");
-                }
-            }
-            if (mRepeat < -1 || mRepeat >= mTimings.length) {
-                throw new IllegalArgumentException(
-                        "repeat index must be within the bounds of the timings array"
-                        + " (timings.length=" + mTimings.length + ", index=" + mRepeat + ")");
-            }
-        }
-
-        @Override
-        public boolean equals(@Nullable Object o) {
-            if (!(o instanceof VibrationEffect.Waveform)) {
-                return false;
-            }
-            VibrationEffect.Waveform other = (VibrationEffect.Waveform) o;
-            return Arrays.equals(mTimings, other.mTimings)
-                && Arrays.equals(mAmplitudes, other.mAmplitudes)
-                && mRepeat == other.mRepeat;
-        }
-
-        @Override
-        public int hashCode() {
-            int result = 17;
-            result += 37 * Arrays.hashCode(mTimings);
-            result += 37 * Arrays.hashCode(mAmplitudes);
-            result += 37 * mRepeat;
-            return result;
-        }
-
-        @Override
-        public String toString() {
-            return "Waveform{mTimings=" + Arrays.toString(mTimings)
-                + ", mAmplitudes=" + Arrays.toString(mAmplitudes)
-                + ", mRepeat=" + mRepeat
-                + "}";
-        }
-
-        @Override
-        public void writeToParcel(Parcel out, int flags) {
-            out.writeInt(PARCEL_TOKEN_WAVEFORM);
-            out.writeLongArray(mTimings);
-            out.writeIntArray(mAmplitudes);
-            out.writeInt(mRepeat);
-        }
-
-        private static boolean hasNonZeroEntry(long[] vals) {
-            for (long val : vals) {
-                if (val != 0) {
-                    return true;
-                }
-            }
-            return false;
-        }
-
-
-        public static final @android.annotation.NonNull Parcelable.Creator<Waveform> CREATOR =
-            new Parcelable.Creator<Waveform>() {
-                @Override
-                public Waveform createFromParcel(Parcel in) {
-                    // Skip the type token
-                    in.readInt();
-                    return new Waveform(in);
-                }
-                @Override
-                public Waveform[] newArray(int size) {
-                    return new Waveform[size];
-                }
-            };
-    }
-
-    /** @hide */
-    @TestApi
-    public static class Prebaked extends VibrationEffect implements Parcelable {
-        private final int mEffectId;
-        private final boolean mFallback;
-        private final int mEffectStrength;
-        @Nullable
-        private final VibrationEffect mFallbackEffect;
-
-        public Prebaked(Parcel in) {
-            mEffectId = in.readInt();
-            mFallback = in.readByte() != 0;
-            mEffectStrength = in.readInt();
-            mFallbackEffect = in.readParcelable(VibrationEffect.class.getClassLoader());
-        }
-
-        public Prebaked(int effectId, boolean fallback, int effectStrength) {
-            mEffectId = effectId;
-            mFallback = fallback;
-            mEffectStrength = effectStrength;
-            mFallbackEffect = null;
-        }
-
-        /** @hide */
-        public Prebaked(int effectId, int effectStrength, @NonNull VibrationEffect fallbackEffect) {
-            mEffectId = effectId;
-            mFallback = true;
-            mEffectStrength = effectStrength;
-            mFallbackEffect = fallbackEffect;
-        }
-
-        public int getId() {
-            return mEffectId;
-        }
-
-        /**
-         * Whether the effect should fall back to a generic pattern if there's no hardware specific
-         * implementation of it.
-         */
-        public boolean shouldFallback() {
-            return mFallback;
-        }
-
-        @Override
-        public long getDuration() {
-            return -1;
-        }
-
-        /** @hide */
-        @Override
-        public Prebaked resolve(int defaultAmplitude) {
-            if (mFallbackEffect != null) {
-                VibrationEffect resolvedFallback = mFallbackEffect.resolve(defaultAmplitude);
-                if (!mFallbackEffect.equals(resolvedFallback)) {
-                    return new Prebaked(mEffectId, mEffectStrength, resolvedFallback);
-                }
-            }
-            return this;
-        }
-
-        /** @hide */
-        @Override
-        public Prebaked scale(float scaleFactor) {
-            if (mFallbackEffect != null) {
-                VibrationEffect scaledFallback = mFallbackEffect.scale(scaleFactor);
-                if (!mFallbackEffect.equals(scaledFallback)) {
-                    return new Prebaked(mEffectId, mEffectStrength, scaledFallback);
-                }
-            }
-            // Prebaked effect strength cannot be scaled with this method.
-            return this;
-        }
-
-        /**
-         * Set the effect strength.
-         */
-        public int getEffectStrength() {
-            return mEffectStrength;
-        }
-
-        /**
-         * Return the fallback effect, if set.
-         *
-         * @hide
-         */
-        @Nullable
-        public VibrationEffect getFallbackEffect() {
-            return mFallbackEffect;
-        }
-
-        private static boolean isValidEffectStrength(int strength) {
-            switch (strength) {
-                case EffectStrength.LIGHT:
-                case EffectStrength.MEDIUM:
-                case EffectStrength.STRONG:
-                    return true;
-                default:
-                    return false;
-            }
-        }
-
-        /** @hide */
-        @Override
-        public void validate() {
-            switch (mEffectId) {
-                case EFFECT_CLICK:
-                case EFFECT_DOUBLE_CLICK:
-                case EFFECT_TICK:
-                case EFFECT_TEXTURE_TICK:
-                case EFFECT_THUD:
-                case EFFECT_POP:
-                case EFFECT_HEAVY_CLICK:
-                    break;
-                default:
-                    if (mEffectId < RINGTONES[0] || mEffectId > RINGTONES[RINGTONES.length - 1]) {
-                        throw new IllegalArgumentException(
-                                "Unknown prebaked effect type (value=" + mEffectId + ")");
-                    }
-            }
-            if (!isValidEffectStrength(mEffectStrength)) {
-                throw new IllegalArgumentException(
-                        "Unknown prebaked effect strength (value=" + mEffectStrength + ")");
-            }
-        }
-
-        @Override
-        public boolean equals(@Nullable Object o) {
-            if (!(o instanceof VibrationEffect.Prebaked)) {
-                return false;
-            }
-            VibrationEffect.Prebaked other = (VibrationEffect.Prebaked) o;
-            return mEffectId == other.mEffectId
-                && mFallback == other.mFallback
-                && mEffectStrength == other.mEffectStrength
-                && Objects.equals(mFallbackEffect, other.mFallbackEffect);
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(mEffectId, mFallback, mEffectStrength, mFallbackEffect);
-        }
-
-        @Override
-        public String toString() {
-            return "Prebaked{mEffectId=" + effectIdToString(mEffectId)
-                + ", mEffectStrength=" + effectStrengthToString(mEffectStrength)
-                + ", mFallback=" + mFallback
-                + ", mFallbackEffect=" + mFallbackEffect
-                + "}";
-        }
-
-
-        @Override
-        public void writeToParcel(Parcel out, int flags) {
-            out.writeInt(PARCEL_TOKEN_EFFECT);
-            out.writeInt(mEffectId);
-            out.writeByte((byte) (mFallback ? 1 : 0));
-            out.writeInt(mEffectStrength);
-            out.writeParcelable(mFallbackEffect, flags);
-        }
-
-        public static final @NonNull Parcelable.Creator<Prebaked> CREATOR =
-            new Parcelable.Creator<Prebaked>() {
-                @Override
-                public Prebaked createFromParcel(Parcel in) {
-                    // Skip the type token
-                    in.readInt();
-                    return new Prebaked(in);
-                }
-                @Override
-                public Prebaked[] newArray(int size) {
-                    return new Prebaked[size];
-                }
-            };
-    }
-
-    /** @hide */
-    public static final class Composed extends VibrationEffect implements Parcelable {
-        private final ArrayList<Composition.PrimitiveEffect> mPrimitiveEffects;
-
-        /**
-         * @hide
-         */
-        @SuppressWarnings("unchecked")
-        public Composed(@NonNull Parcel in) {
-            this(in.readArrayList(Composed.class.getClassLoader()));
-        }
-
-        /**
-         * @hide
-         */
-        public Composed(List<Composition.PrimitiveEffect> effects) {
-            mPrimitiveEffects = new ArrayList<>(Objects.requireNonNull(effects));
-        }
-
-        /**
-         * @hide
-         */
         @NonNull
-        public List<Composition.PrimitiveEffect> getPrimitiveEffects() {
-            return mPrimitiveEffects;
-        }
-
         @Override
-        public long getDuration() {
-            return -1;
+        public Composed resolve(int defaultAmplitude) {
+            int segmentCount = mSegments.size();
+            ArrayList<VibrationEffectSegment> resolvedSegments = new ArrayList<>(segmentCount);
+            for (int i = 0; i < segmentCount; i++) {
+                resolvedSegments.add(mSegments.get(i).resolve(defaultAmplitude));
+            }
+            if (resolvedSegments.equals(mSegments)) {
+                return this;
+            }
+            Composed resolved = new Composed(resolvedSegments, mRepeatIndex);
+            resolved.validate();
+            return resolved;
         }
 
-        /** @hide */
-        @Override
-        public VibrationEffect resolve(int defaultAmplitude) {
-            // Primitive effects already have default primitive intensity set, so ignore this.
-            return this;
-        }
-
-        /** @hide */
+        @NonNull
         @Override
         public Composed scale(float scaleFactor) {
-            if (scaleFactor == 1f) {
-                // Just return this if there's no scaling to be done.
+            int segmentCount = mSegments.size();
+            ArrayList<VibrationEffectSegment> scaledSegments = new ArrayList<>(segmentCount);
+            for (int i = 0; i < segmentCount; i++) {
+                scaledSegments.add(mSegments.get(i).scale(scaleFactor));
+            }
+            if (scaledSegments.equals(mSegments)) {
                 return this;
             }
-            final int primitiveCount = mPrimitiveEffects.size();
-            List<Composition.PrimitiveEffect> scaledPrimitives = new ArrayList<>();
-            for (int i = 0; i < primitiveCount; i++) {
-                Composition.PrimitiveEffect primitive = mPrimitiveEffects.get(i);
-                scaledPrimitives.add(new Composition.PrimitiveEffect(
-                        primitive.id, scale(primitive.scale, scaleFactor), primitive.delay));
-            }
-            return new Composed(scaledPrimitives);
+            Composed scaled = new Composed(scaledSegments, mRepeatIndex);
+            scaled.validate();
+            return scaled;
         }
 
-        /** @hide */
+        @NonNull
         @Override
-        public void validate() {
-            final int primitiveCount = mPrimitiveEffects.size();
-            for (int i = 0; i < primitiveCount; i++) {
-                Composition.PrimitiveEffect primitive = mPrimitiveEffects.get(i);
-                Composition.checkPrimitive(primitive.id);
-                Preconditions.checkArgumentInRange(primitive.scale, 0.0f, 1.0f, "scale");
-                Preconditions.checkArgumentNonNegative(primitive.delay,
-                        "Primitive delay must be zero or positive");
+        public Composed applyEffectStrength(int effectStrength) {
+            int segmentCount = mSegments.size();
+            ArrayList<VibrationEffectSegment> scaledSegments = new ArrayList<>(segmentCount);
+            for (int i = 0; i < segmentCount; i++) {
+                scaledSegments.add(mSegments.get(i).applyEffectStrength(effectStrength));
             }
+            if (scaledSegments.equals(mSegments)) {
+                return this;
+            }
+            Composed scaled = new Composed(scaledSegments, mRepeatIndex);
+            scaled.validate();
+            return scaled;
         }
 
         @Override
-        public void writeToParcel(@NonNull Parcel out, int flags) {
-            out.writeInt(PARCEL_TOKEN_COMPOSITION);
-            out.writeList(mPrimitiveEffects);
+        public boolean equals(@Nullable Object o) {
+            if (!(o instanceof Composed)) {
+                return false;
+            }
+            Composed other = (Composed) o;
+            return mSegments.equals(other.mSegments) && mRepeatIndex == other.mRepeatIndex;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(mSegments, mRepeatIndex);
+        }
+
+        @Override
+        public String toString() {
+            return "Composed{segments=" + mSegments
+                    + ", repeat=" + mRepeatIndex
+                    + "}";
         }
 
         @Override
@@ -1063,34 +696,20 @@
         }
 
         @Override
-        public boolean equals(@Nullable Object o) {
-            if (this == o) return true;
-            if (o == null || getClass() != o.getClass()) return false;
-            Composed composed = (Composed) o;
-            return mPrimitiveEffects.equals(composed.mPrimitiveEffects);
+        public void writeToParcel(@NonNull Parcel out, int flags) {
+            out.writeList(mSegments);
+            out.writeInt(mRepeatIndex);
         }
 
-        @Override
-        public int hashCode() {
-            return Objects.hash(mPrimitiveEffects);
-        }
-
-        @Override
-        public String toString() {
-            return "Composed{mPrimitiveEffects=" + mPrimitiveEffects + '}';
-        }
-
-        public static final @NonNull Parcelable.Creator<Composed> CREATOR =
-                new Parcelable.Creator<Composed>() {
+        @NonNull
+        public static final Creator<Composed> CREATOR =
+                new Creator<Composed>() {
                     @Override
-                    public Composed createFromParcel(@NonNull Parcel in) {
-                        // Skip the type token
-                        in.readInt();
+                    public Composed createFromParcel(Parcel in) {
                         return new Composed(in);
                     }
 
                     @Override
-                    @NonNull
                     public Composed[] newArray(int size) {
                         return new Composed[size];
                     }
@@ -1115,7 +734,7 @@
                 PRIMITIVE_LOW_TICK,
         })
         @Retention(RetentionPolicy.SOURCE)
-        public @interface Primitive {}
+        public @interface PrimitiveType {}
 
         /**
          * No haptic effect. Used to generate extended delays between primitives.
@@ -1166,9 +785,46 @@
         public static final int PRIMITIVE_LOW_TICK = 8;
 
 
-        private ArrayList<PrimitiveEffect> mEffects = new ArrayList<>();
+        private final ArrayList<VibrationEffectSegment> mSegments = new ArrayList<>();
+        private int mRepeatIndex = -1;
 
-        Composition() { }
+        Composition() {}
+
+        /**
+         * Add a haptic effect to the end of the current composition.
+         *
+         * <p>Similar to {@link #addEffect(VibrationEffect, int)} , but with no delay applied.
+         *
+         * @param effect The effect to add to this composition as a primitive
+         * @return The {@link Composition} object to enable adding multiple primitives in one chain.
+         * @hide
+         */
+        @TestApi
+        @NonNull
+        public Composition addEffect(@NonNull VibrationEffect effect) {
+            return addEffect(effect, /* delay= */ 0);
+        }
+
+        /**
+         * Add a haptic effect to the end of the current composition.
+         *
+         * @param effect The effect to add to this composition as a primitive
+         * @param delay  The amount of time in milliseconds to wait before playing this primitive
+         * @return The {@link Composition} object to enable adding multiple primitives in one chain.
+         * @hide
+         */
+        @TestApi
+        @NonNull
+        public Composition addEffect(@NonNull VibrationEffect effect,
+                @IntRange(from = 0) int delay) {
+            Preconditions.checkArgumentNonnegative(delay);
+            if (delay > 0) {
+                // Created a segment sustaining the zero amplitude to represent the delay.
+                addSegment(new StepSegment(/* amplitude= */ 0, /* frequency= */ 0,
+                        /* duration= */ delay));
+            }
+            return addSegments(effect);
+        }
 
         /**
          * Add a haptic primitive to the end of the current composition.
@@ -1181,9 +837,8 @@
          * @return The {@link Composition} object to enable adding multiple primitives in one chain.
          */
         @NonNull
-        public Composition addPrimitive(@Primitive int primitiveId) {
-            addPrimitive(primitiveId, /*scale*/ 1.0f, /*delay*/ 0);
-            return this;
+        public Composition addPrimitive(@PrimitiveType int primitiveId) {
+            return addPrimitive(primitiveId, /*scale*/ 1.0f, /*delay*/ 0);
         }
 
         /**
@@ -1197,10 +852,9 @@
          * @return The {@link Composition} object to enable adding multiple primitives in one chain.
          */
         @NonNull
-        public Composition addPrimitive(@Primitive int primitiveId,
+        public Composition addPrimitive(@PrimitiveType int primitiveId,
                 @FloatRange(from = 0f, to = 1f) float scale) {
-            addPrimitive(primitiveId, scale, /*delay*/ 0);
-            return this;
+            return addPrimitive(primitiveId, scale, /*delay*/ 0);
         }
 
         /**
@@ -1213,9 +867,36 @@
          * @return The {@link Composition} object to enable adding multiple primitives in one chain.
          */
         @NonNull
-        public Composition addPrimitive(@Primitive int primitiveId,
+        public Composition addPrimitive(@PrimitiveType int primitiveId,
                 @FloatRange(from = 0f, to = 1f) float scale, @IntRange(from = 0) int delay) {
-            mEffects.add(new PrimitiveEffect(checkPrimitive(primitiveId), scale, delay));
+            PrimitiveSegment primitive = new PrimitiveSegment(primitiveId, scale,
+                    delay);
+            primitive.validate();
+            return addSegment(primitive);
+        }
+
+        private Composition addSegment(VibrationEffectSegment segment) {
+            if (mRepeatIndex >= 0) {
+                throw new IllegalStateException(
+                        "Composition already have a repeating effect so any new primitive would be"
+                                + " unreachable.");
+            }
+            mSegments.add(segment);
+            return this;
+        }
+
+        private Composition addSegments(VibrationEffect effect) {
+            if (mRepeatIndex >= 0) {
+                throw new IllegalStateException(
+                        "Composition already have a repeating effect so any new primitive would be"
+                                + " unreachable.");
+            }
+            Composed composed = (Composed) effect;
+            if (composed.getRepeatIndex() >= 0) {
+                // Start repeating from the index relative to the composed waveform.
+                mRepeatIndex = mSegments.size() + composed.getRepeatIndex();
+            }
+            mSegments.addAll(composed.getSegments());
             return this;
         }
 
@@ -1230,22 +911,13 @@
          */
         @NonNull
         public VibrationEffect compose() {
-            if (mEffects.isEmpty()) {
+            if (mSegments.isEmpty()) {
                 throw new IllegalStateException(
                         "Composition must have at least one element to compose.");
             }
-            return new VibrationEffect.Composed(mEffects);
-        }
-
-        /**
-         * @throws IllegalArgumentException throws if the primitive ID is not within the valid range
-         * @hide
-         *
-         */
-        static int checkPrimitive(int primitiveId) {
-            Preconditions.checkArgumentInRange(primitiveId, PRIMITIVE_NOOP, PRIMITIVE_LOW_TICK,
-                    "primitiveId");
-            return primitiveId;
+            VibrationEffect effect = new Composed(mSegments, mRepeatIndex);
+            effect.validate();
+            return effect;
         }
 
         /**
@@ -1254,7 +926,7 @@
          * @return The ID in a human readable format.
          * @hide
          */
-        public static String primitiveToString(@Primitive int id) {
+        public static String primitiveToString(@PrimitiveType int id) {
             switch (id) {
                 case PRIMITIVE_NOOP:
                     return "PRIMITIVE_NOOP";
@@ -1278,90 +950,172 @@
                     return Integer.toString(id);
             }
         }
+    }
 
+    /**
+     * A builder for waveform haptic effects.
+     *
+     * <p>Waveform vibrations constitute of one or more timed segments where the vibration
+     * amplitude, frequency or both can linearly ramp to new values.
+     *
+     * <p>Waveform segments may have zero duration, which represent a jump to new vibration
+     * amplitude and/or frequency values.
+     *
+     * <p>Waveform segments may have the same start and end vibration amplitude and frequency,
+     * which represent a step where the amplitude and frequency are maintained for that duration.
+     *
+     * @hide
+     * @see VibrationEffect#startWaveform()
+     */
+    @TestApi
+    public static final class WaveformBuilder {
+        private ArrayList<VibrationEffectSegment> mSegments = new ArrayList<>();
+
+        WaveformBuilder() {}
 
         /**
-         * @hide
+         * Vibrate with given amplitude for the given duration, in millis, keeping the previous
+         * frequency the same.
+         *
+         * <p>If the duration is zero the vibrator will jump to new amplitude.
+         *
+         * @param amplitude The amplitude for this step
+         * @param duration  The duration of this step in milliseconds
+         * @return The {@link WaveformBuilder} object to enable adding multiple steps in chain.
          */
-        public static class PrimitiveEffect implements Parcelable {
-            public int id;
-            public float scale;
-            public int delay;
+        @SuppressLint("MissingGetterMatchingBuilder")
+        @NonNull
+        public WaveformBuilder addStep(@FloatRange(from = 0f, to = 1f) float amplitude,
+                @IntRange(from = 0) int duration) {
+            return addStep(amplitude, getPreviousFrequency(), duration);
+        }
 
-            PrimitiveEffect(int id, float scale, int delay) {
-                this.id = id;
-                this.scale = scale;
-                this.delay = delay;
+        /**
+         * Vibrate with given amplitude for the given duration, in millis, keeping the previous
+         * vibration frequency the same.
+         *
+         * <p>If the duration is zero the vibrator will jump to new amplitude.
+         *
+         * @param amplitude The amplitude for this step
+         * @param frequency The frequency for this step
+         * @param duration  The duration of this step in milliseconds
+         * @return The {@link WaveformBuilder} object to enable adding multiple steps in chain.
+         */
+        @SuppressLint("MissingGetterMatchingBuilder")
+        @NonNull
+        public WaveformBuilder addStep(@FloatRange(from = 0f, to = 1f) float amplitude,
+                @FloatRange(from = -1f, to = 1f) float frequency,
+                @IntRange(from = 0) int duration) {
+            mSegments.add(new StepSegment(amplitude, frequency, duration));
+            return this;
+        }
+
+        /**
+         * Ramp vibration linearly for the given duration, in millis, from previous amplitude value
+         * to the given one, keeping previous frequency.
+         *
+         * <p>If the duration is zero the vibrator will jump to new amplitude.
+         *
+         * @param amplitude The final amplitude this ramp should reach
+         * @param duration  The duration of this ramp in milliseconds
+         * @return The {@link WaveformBuilder} object to enable adding multiple steps in chain.
+         */
+        @SuppressLint("MissingGetterMatchingBuilder")
+        @NonNull
+        public WaveformBuilder addRamp(@FloatRange(from = 0f, to = 1f) float amplitude,
+                @IntRange(from = 0) int duration) {
+            return addRamp(amplitude, getPreviousFrequency(), duration);
+        }
+
+        /**
+         * Ramp vibration linearly for the given duration, in millis, from previous amplitude and
+         * frequency values to the given ones.
+         *
+         * <p>If the duration is zero the vibrator will jump to new amplitude and frequency.
+         *
+         * @param amplitude The final amplitude this ramp should reach
+         * @param frequency The final frequency this ramp should reach
+         * @param duration  The duration of this ramp in milliseconds
+         * @return The {@link WaveformBuilder} object to enable adding multiple steps in chain.
+         */
+        @SuppressLint("MissingGetterMatchingBuilder")
+        @NonNull
+        public WaveformBuilder addRamp(@FloatRange(from = 0f, to = 1f) float amplitude,
+                @FloatRange(from = -1f, to = 1f) float frequency,
+                @IntRange(from = 0) int duration) {
+            mSegments.add(new RampSegment(getPreviousAmplitude(), amplitude, getPreviousFrequency(),
+                    frequency, duration));
+            return this;
+        }
+
+        /**
+         * Compose all of the steps together into a single {@link VibrationEffect}.
+         *
+         * The {@link WaveformBuilder} object is still valid after this call, so you can
+         * continue adding more primitives to it and generating more {@link VibrationEffect}s by
+         * calling this method again.
+         *
+         * @return The {@link VibrationEffect} resulting from the composition of the steps.
+         */
+        @NonNull
+        public VibrationEffect build() {
+            return build(/* repeat= */ -1);
+        }
+
+        /**
+         * Compose all of the steps together into a single {@link VibrationEffect}.
+         *
+         * <p>To cause the pattern to repeat, pass the index at which to start the repetition
+         * (starting at 0), or -1 to disable repeating.
+         *
+         * <p>The {@link WaveformBuilder} object is still valid after this call, so you can
+         * continue adding more primitives to it and generating more {@link VibrationEffect}s by
+         * calling this method again.
+         *
+         * @return The {@link VibrationEffect} resulting from the composition of the steps.
+         */
+        @NonNull
+        public VibrationEffect build(int repeat) {
+            if (mSegments.isEmpty()) {
+                throw new IllegalStateException(
+                        "WaveformBuilder must have at least one element to build.");
             }
+            VibrationEffect effect = new Composed(mSegments, repeat);
+            effect.validate();
+            return effect;
+        }
 
-            @Override
-            public void writeToParcel(Parcel dest, int flags) {
-                dest.writeInt(id);
-                dest.writeFloat(scale);
-                dest.writeInt(delay);
+        private float getPreviousFrequency() {
+            if (!mSegments.isEmpty()) {
+                VibrationEffectSegment segment = mSegments.get(mSegments.size() - 1);
+                if (segment instanceof StepSegment) {
+                    return ((StepSegment) segment).getFrequency();
+                } else if (segment instanceof RampSegment) {
+                    return ((RampSegment) segment).getEndFrequency();
+                }
             }
+            return 0;
+        }
 
-            @Override
-            public int describeContents() {
-                return 0;
+        private float getPreviousAmplitude() {
+            if (!mSegments.isEmpty()) {
+                VibrationEffectSegment segment = mSegments.get(mSegments.size() - 1);
+                if (segment instanceof StepSegment) {
+                    return ((StepSegment) segment).getAmplitude();
+                } else if (segment instanceof RampSegment) {
+                    return ((RampSegment) segment).getEndAmplitude();
+                }
             }
-
-            @Override
-            public String toString() {
-                return "PrimitiveEffect{"
-                        + "id=" + primitiveToString(id)
-                        + ", scale=" + scale
-                        + ", delay=" + delay
-                        + '}';
-            }
-
-            @Override
-            public boolean equals(@Nullable Object o) {
-                if (this == o) return true;
-                if (o == null || getClass() != o.getClass()) return false;
-                PrimitiveEffect that = (PrimitiveEffect) o;
-                return id == that.id
-                        && Float.compare(that.scale, scale) == 0
-                        && delay == that.delay;
-            }
-
-            @Override
-            public int hashCode() {
-                return Objects.hash(id, scale, delay);
-            }
-
-
-            public static final @NonNull Parcelable.Creator<PrimitiveEffect> CREATOR =
-                    new Parcelable.Creator<PrimitiveEffect>() {
-                        @Override
-                        public PrimitiveEffect createFromParcel(Parcel in) {
-                            return new PrimitiveEffect(in.readInt(), in.readFloat(), in.readInt());
-                        }
-                        @Override
-                        public PrimitiveEffect[] newArray(int size) {
-                            return new PrimitiveEffect[size];
-                        }
-                    };
+            return 0;
         }
     }
 
-    public static final @NonNull Parcelable.Creator<VibrationEffect> CREATOR =
+    @NonNull
+    public static final Parcelable.Creator<VibrationEffect> CREATOR =
             new Parcelable.Creator<VibrationEffect>() {
                 @Override
                 public VibrationEffect createFromParcel(Parcel in) {
-                    int token = in.readInt();
-                    if (token == PARCEL_TOKEN_ONE_SHOT) {
-                        return new OneShot(in);
-                    } else if (token == PARCEL_TOKEN_WAVEFORM) {
-                        return new Waveform(in);
-                    } else if (token == PARCEL_TOKEN_EFFECT) {
-                        return new Prebaked(in);
-                    } else if (token == PARCEL_TOKEN_COMPOSITION) {
-                        return new Composed(in);
-                    } else {
-                        throw new IllegalStateException(
-                                "Unexpected vibration event type token in parcel.");
-                    }
+                    return new Composed(in);
                 }
                 @Override
                 public VibrationEffect[] newArray(int size) {
diff --git a/core/java/android/os/Vibrator.java b/core/java/android/os/Vibrator.java
index b90d438..a0f70c8 100644
--- a/core/java/android/os/Vibrator.java
+++ b/core/java/android/os/Vibrator.java
@@ -467,7 +467,7 @@
      */
     @NonNull
     public boolean[] arePrimitivesSupported(
-            @NonNull @VibrationEffect.Composition.Primitive int... primitiveIds) {
+            @NonNull @VibrationEffect.Composition.PrimitiveType int... primitiveIds) {
         return new boolean[primitiveIds.length];
     }
 
@@ -478,7 +478,7 @@
      * @return Whether primitives effects are supported.
      */
     public final boolean areAllPrimitivesSupported(
-            @NonNull @VibrationEffect.Composition.Primitive int... primitiveIds) {
+            @NonNull @VibrationEffect.Composition.PrimitiveType int... primitiveIds) {
         for (boolean supported : arePrimitivesSupported(primitiveIds)) {
             if (!supported) {
                 return false;
diff --git a/core/java/android/os/VibratorInfo.java b/core/java/android/os/VibratorInfo.java
index 3121b95..671daa0 100644
--- a/core/java/android/os/VibratorInfo.java
+++ b/core/java/android/os/VibratorInfo.java
@@ -16,9 +16,14 @@
 
 package android.os;
 
+import android.annotation.FloatRange;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.hardware.vibrator.Braking;
 import android.hardware.vibrator.IVibrator;
+import android.util.Log;
+import android.util.MathUtils;
+import android.util.Range;
 import android.util.SparseBooleanArray;
 
 import java.util.ArrayList;
@@ -41,28 +46,32 @@
     @Nullable
     private final SparseBooleanArray mSupportedEffects;
     @Nullable
+    private final SparseBooleanArray mSupportedBraking;
+    @Nullable
     private final SparseBooleanArray mSupportedPrimitives;
-    private final float mResonantFrequency;
     private final float mQFactor;
+    private final FrequencyMapping mFrequencyMapping;
 
     VibratorInfo(Parcel in) {
         mId = in.readInt();
         mCapabilities = in.readLong();
         mSupportedEffects = in.readSparseBooleanArray();
+        mSupportedBraking = in.readSparseBooleanArray();
         mSupportedPrimitives = in.readSparseBooleanArray();
-        mResonantFrequency = in.readFloat();
         mQFactor = in.readFloat();
+        mFrequencyMapping = in.readParcelable(VibratorInfo.class.getClassLoader());
     }
 
     /** @hide */
-    public VibratorInfo(int id, long capabilities, int[] supportedEffects,
-            int[] supportedPrimitives, float resonantFrequency, float qFactor) {
+    public VibratorInfo(int id, long capabilities, int[] supportedEffects, int[] supportedBraking,
+            int[] supportedPrimitives, float qFactor, @NonNull FrequencyMapping frequencyMapping) {
         mId = id;
         mCapabilities = capabilities;
         mSupportedEffects = toSparseBooleanArray(supportedEffects);
+        mSupportedBraking = toSparseBooleanArray(supportedBraking);
         mSupportedPrimitives = toSparseBooleanArray(supportedPrimitives);
-        mResonantFrequency = resonantFrequency;
         mQFactor = qFactor;
+        mFrequencyMapping = frequencyMapping;
     }
 
     @Override
@@ -70,9 +79,10 @@
         dest.writeInt(mId);
         dest.writeLong(mCapabilities);
         dest.writeSparseBooleanArray(mSupportedEffects);
+        dest.writeSparseBooleanArray(mSupportedBraking);
         dest.writeSparseBooleanArray(mSupportedPrimitives);
-        dest.writeFloat(mResonantFrequency);
         dest.writeFloat(mQFactor);
+        dest.writeParcelable(mFrequencyMapping, flags);
     }
 
     @Override
@@ -91,15 +101,16 @@
         VibratorInfo that = (VibratorInfo) o;
         return mId == that.mId && mCapabilities == that.mCapabilities
                 && Objects.equals(mSupportedEffects, that.mSupportedEffects)
+                && Objects.equals(mSupportedBraking, that.mSupportedBraking)
                 && Objects.equals(mSupportedPrimitives, that.mSupportedPrimitives)
-                && Objects.equals(mResonantFrequency, that.mResonantFrequency)
-                && Objects.equals(mQFactor, that.mQFactor);
+                && Objects.equals(mQFactor, that.mQFactor)
+                && Objects.equals(mFrequencyMapping, that.mFrequencyMapping);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(mId, mCapabilities, mSupportedEffects, mSupportedPrimitives,
-                mResonantFrequency, mQFactor);
+        return Objects.hash(mId, mCapabilities, mSupportedEffects, mSupportedBraking,
+                mSupportedPrimitives, mQFactor, mFrequencyMapping);
     }
 
     @Override
@@ -109,9 +120,10 @@
                 + ", mCapabilities=" + Arrays.toString(getCapabilitiesNames())
                 + ", mCapabilities flags=" + Long.toBinaryString(mCapabilities)
                 + ", mSupportedEffects=" + Arrays.toString(getSupportedEffectsNames())
+                + ", mSupportedBraking=" + Arrays.toString(getSupportedBrakingNames())
                 + ", mSupportedPrimitives=" + Arrays.toString(getSupportedPrimitivesNames())
-                + ", mResonantFrequency=" + mResonantFrequency
                 + ", mQFactor=" + mQFactor
+                + ", mFrequencyMapping=" + mFrequencyMapping
                 + '}';
     }
 
@@ -130,6 +142,23 @@
     }
 
     /**
+     * Returns a default value to be applied to composed PWLE effects for braking.
+     *
+     * @return a supported braking value, one of android.hardware.vibrator.Braking.*
+     */
+    public int getDefaultBraking() {
+        if (mSupportedBraking != null) {
+            int size = mSupportedBraking.size();
+            for (int i = 0; i < size; i++) {
+                if (mSupportedBraking.keyAt(i) != Braking.NONE) {
+                    return mSupportedBraking.keyAt(i);
+                }
+            }
+        }
+        return Braking.NONE;
+    }
+
+    /**
      * Query whether the vibrator supports the given effect.
      *
      * @param effectId Which effects to query for.
@@ -143,7 +172,7 @@
         if (mSupportedEffects == null) {
             return Vibrator.VIBRATION_EFFECT_SUPPORT_UNKNOWN;
         }
-        return mSupportedEffects.get(effectId, false) ? Vibrator.VIBRATION_EFFECT_SUPPORT_YES
+        return mSupportedEffects.get(effectId) ? Vibrator.VIBRATION_EFFECT_SUPPORT_YES
                 : Vibrator.VIBRATION_EFFECT_SUPPORT_NO;
     }
 
@@ -153,9 +182,10 @@
      * @param primitiveId Which primitives to query for.
      * @return Whether the primitive is supported.
      */
-    public boolean isPrimitiveSupported(@VibrationEffect.Composition.Primitive int primitiveId) {
+    public boolean isPrimitiveSupported(
+            @VibrationEffect.Composition.PrimitiveType int primitiveId) {
         return hasCapability(IVibrator.CAP_COMPOSE_EFFECTS) && mSupportedPrimitives != null
-                && mSupportedPrimitives.get(primitiveId, false);
+                && mSupportedPrimitives.get(primitiveId);
     }
 
     /**
@@ -176,7 +206,7 @@
      *         this vibrator is a composite of multiple physical devices.
      */
     public float getResonantFrequency() {
-        return mResonantFrequency;
+        return mFrequencyMapping.mResonantFrequencyHz;
     }
 
     /**
@@ -189,6 +219,52 @@
         return mQFactor;
     }
 
+    /**
+     * Return a range of relative frequency values supported by the vibrator.
+     *
+     * @return A range of relative frequency values supported. The range will always contain the
+     * value 0, representing the device resonant frequency. Devices without frequency control will
+     * return the range [0,0]. Devices with frequency control will always return a range containing
+     * the safe range [-1, 1].
+     * @hide
+     */
+    public Range<Float> getFrequencyRange() {
+        return mFrequencyMapping.mRelativeFrequencyRange;
+    }
+
+    /**
+     * Return the maximum amplitude the vibrator can play at given relative frequency.
+     *
+     * @return a value in [0,1] representing the maximum amplitude the device can play at given
+     * relative frequency. Devices without frequency control will return 1 for the input zero
+     * (resonant frequency), and 0 to any other input. Devices with frequency control will return
+     * the supported value, for input in {@code #getFrequencyRange()}, and 0 for any other input.
+     * @hide
+     */
+    @FloatRange(from = 0, to = 1)
+    public float getMaxAmplitude(float relativeFrequency) {
+        if (mFrequencyMapping.isEmpty()) {
+            // The vibrator has not provided values for frequency mapping.
+            // Return the expected behavior for devices without frequency control.
+            return Float.compare(relativeFrequency, 0) == 0 ? 1 : 0;
+        }
+        return mFrequencyMapping.getMaxAmplitude(relativeFrequency);
+    }
+
+    /**
+     * Return absolute frequency value for this vibrator, in hertz, that corresponds to given
+     * relative frequency.
+     *
+     * @retur a value in hertz that corresponds to given relative frequency. Input values outside
+     * {@link #getFrequencyRange()} will return {@link Float#NaN}. Devices without frequency control
+     * will return {@link Float#NaN} for any input.
+     * @hide
+     */
+    @FloatRange(from = 0)
+    public float getAbsoluteFrequency(float relativeFrequency) {
+        return mFrequencyMapping.toHertz(relativeFrequency);
+    }
+
     private String[] getCapabilitiesNames() {
         List<String> names = new ArrayList<>();
         if (hasCapability(IVibrator.CAP_ON_CALLBACK)) {
@@ -200,12 +276,18 @@
         if (hasCapability(IVibrator.CAP_COMPOSE_EFFECTS)) {
             names.add("COMPOSE_EFFECTS");
         }
+        if (hasCapability(IVibrator.CAP_COMPOSE_PWLE_EFFECTS)) {
+            names.add("COMPOSE_PWLE_EFFECTS");
+        }
         if (hasCapability(IVibrator.CAP_ALWAYS_ON_CONTROL)) {
             names.add("ALWAYS_ON_CONTROL");
         }
         if (hasCapability(IVibrator.CAP_AMPLITUDE_CONTROL)) {
             names.add("AMPLITUDE_CONTROL");
         }
+        if (hasCapability(IVibrator.CAP_FREQUENCY_CONTROL)) {
+            names.add("FREQUENCY_CONTROL");
+        }
         if (hasCapability(IVibrator.CAP_EXTERNAL_CONTROL)) {
             names.add("EXTERNAL_CONTROL");
         }
@@ -226,6 +308,26 @@
         return names;
     }
 
+    private String[] getSupportedBrakingNames() {
+        if (mSupportedBraking == null) {
+            return new String[0];
+        }
+        String[] names = new String[mSupportedBraking.size()];
+        for (int i = 0; i < mSupportedBraking.size(); i++) {
+            switch (mSupportedBraking.keyAt(i)) {
+                case Braking.NONE:
+                    names[i] = "NONE";
+                    break;
+                case Braking.CLAB:
+                    names[i] = "CLAB";
+                    break;
+                default:
+                    names[i] = Integer.toString(mSupportedBraking.keyAt(i));
+            }
+        }
+        return names;
+    }
+
     private String[] getSupportedPrimitivesNames() {
         if (mSupportedPrimitives == null) {
             return new String[0];
@@ -249,6 +351,210 @@
         return array;
     }
 
+    /**
+     * Describes how frequency should be mapped to absolute values for a specific {@link Vibrator}.
+     *
+     * <p>This mapping is defined by the following parameters:
+     *
+     * <ol>
+     *     <li>{@code minFrequency}, {@code resonantFrequency} and {@code frequencyResolution}, in
+     *         hertz, provided by the vibrator.
+     *     <li>{@code maxAmplitudes} a list of values in [0,1] provided by the vibrator, where
+     *         {@code maxAmplitudes[i]} represents max supported amplitude at frequency
+     *         {@code minFrequency + frequencyResolution * i}.
+     *     <li>{@code maxFrequency = minFrequency + frequencyResolution * (maxAmplitudes.length-1)}
+     *     <li>{@code suggestedSafeRangeHz} is the suggested frequency range in hertz that should be
+     *         mapped to relative values -1 and 1, where 0 maps to {@code resonantFrequency}.
+     * </ol>
+     *
+     * <p>The mapping is defined linearly by the following points:
+     *
+     * <ol>
+     *     <li>{@code toHertz(relativeMinFrequency} = minFrequency
+     *     <li>{@code                   toHertz(-1) = resonantFrequency - safeRange / 2}
+     *     <li>{@code                    toHertz(0) = resonantFrequency}
+     *     <li>{@code                    toHertz(1) = resonantFrequency + safeRange / 2}
+     *     <li>{@code toHertz(relativeMaxFrequency) = maxFrequency}
+     * </ol>
+     *
+     * @hide
+     */
+    public static final class FrequencyMapping implements Parcelable {
+        private final float mMinFrequencyHz;
+        private final float mResonantFrequencyHz;
+        private final float mFrequencyResolutionHz;
+        private final float mSuggestedSafeRangeHz;
+        private final float[] mMaxAmplitudes;
+
+        // Relative fields calculated from input values:
+        private final Range<Float> mRelativeFrequencyRange;
+
+        FrequencyMapping(Parcel in) {
+            this(in.readFloat(), in.readFloat(), in.readFloat(), in.readFloat(),
+                    in.createFloatArray());
+        }
+
+        /** @hide */
+        public FrequencyMapping(float minFrequencyHz, float resonantFrequencyHz,
+                float frequencyResolutionHz, float suggestedSafeRangeHz, float[] maxAmplitudes) {
+            mMinFrequencyHz = minFrequencyHz;
+            mResonantFrequencyHz = resonantFrequencyHz;
+            mFrequencyResolutionHz = frequencyResolutionHz;
+            mSuggestedSafeRangeHz = suggestedSafeRangeHz;
+            mMaxAmplitudes = new float[maxAmplitudes == null ? 0 : maxAmplitudes.length];
+            if (maxAmplitudes != null) {
+                System.arraycopy(maxAmplitudes, 0, mMaxAmplitudes, 0, maxAmplitudes.length);
+            }
+
+            float maxFrequencyHz =
+                    minFrequencyHz + frequencyResolutionHz * (mMaxAmplitudes.length - 1);
+            if (Float.isNaN(resonantFrequencyHz) || Float.isNaN(minFrequencyHz)
+                    || Float.isNaN(frequencyResolutionHz) || Float.isNaN(suggestedSafeRangeHz)
+                    || resonantFrequencyHz < minFrequencyHz
+                    || resonantFrequencyHz > maxFrequencyHz) {
+                // Some required fields are undefined or have bad values.
+                // Leave this mapping empty.
+                mRelativeFrequencyRange = Range.create(0f, 0f);
+                return;
+            }
+
+            // Calculate actual safe range, limiting the suggested one by the device supported range
+            float safeDelta = MathUtils.min(
+                    suggestedSafeRangeHz / 2,
+                    resonantFrequencyHz - minFrequencyHz,
+                    maxFrequencyHz - resonantFrequencyHz);
+            mRelativeFrequencyRange = Range.create(
+                    (minFrequencyHz - resonantFrequencyHz) / safeDelta,
+                    (maxFrequencyHz - resonantFrequencyHz) / safeDelta);
+        }
+
+        /**
+         * Returns true if this frequency mapping is empty, i.e. the only supported relative
+         * frequency is 0 (resonant frequency).
+         */
+        public boolean isEmpty() {
+            return Float.compare(mRelativeFrequencyRange.getLower(),
+                    mRelativeFrequencyRange.getUpper()) == 0;
+        }
+
+        /**
+         * Returns the frequency value in hertz that is mapped to the given relative frequency.
+         *
+         * @return The mapped frequency, in hertz, or {@link Float#NaN} is value outside the device
+         * supported range.
+         */
+        public float toHertz(float relativeFrequency) {
+            if (!mRelativeFrequencyRange.contains(relativeFrequency)) {
+                return Float.NaN;
+            }
+            float relativeMinFrequency = mRelativeFrequencyRange.getLower();
+            if (Float.compare(relativeMinFrequency, 0) == 0) {
+                // relative supported range is [0,0], so toHertz(0) should be the resonant frequency
+                return mResonantFrequencyHz;
+            }
+            float shift = (mMinFrequencyHz - mResonantFrequencyHz) / relativeMinFrequency;
+            return mResonantFrequencyHz + relativeFrequency * shift;
+        }
+
+        /**
+         * Returns the maximum amplitude the vibrator can reach while playing at given relative
+         * frequency.
+         *
+         * @return A value in [0,1] representing the max amplitude supported at given relative
+         * frequency. This will return 0 if frequency is outside supported range, or if max
+         * amplitude mapping is empty.
+         */
+        public float getMaxAmplitude(float relativeFrequency) {
+            float frequencyHz = toHertz(relativeFrequency);
+            if (Float.isNaN(frequencyHz)) {
+                // Unsupported frequency requested, vibrator cannot play at this frequency.
+                return 0;
+            }
+            float position = (frequencyHz - mMinFrequencyHz) / mFrequencyResolutionHz;
+            int floorIndex = (int) Math.floor(position);
+            int ceilIndex = (int) Math.ceil(position);
+            if (floorIndex < 0 || floorIndex >= mMaxAmplitudes.length) {
+                if (mMaxAmplitudes.length > 0) {
+                    // This should never happen if the setup of relative frequencies was correct.
+                    Log.w(TAG, "Max amplitudes has " + mMaxAmplitudes.length
+                            + " entries and was expected to cover the frequency " + frequencyHz
+                            + " Hz when starting at min frequency of " + mMinFrequencyHz
+                            + " Hz with resolution of " + mFrequencyResolutionHz + " Hz.");
+                }
+                return 0;
+            }
+            if (floorIndex != ceilIndex && ceilIndex < mMaxAmplitudes.length) {
+                // Value in between two mapped frequency values, use the lowest supported one.
+                return MathUtils.min(mMaxAmplitudes[floorIndex], mMaxAmplitudes[ceilIndex]);
+            }
+            return mMaxAmplitudes[floorIndex];
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            dest.writeFloat(mMinFrequencyHz);
+            dest.writeFloat(mResonantFrequencyHz);
+            dest.writeFloat(mFrequencyResolutionHz);
+            dest.writeFloat(mSuggestedSafeRangeHz);
+            dest.writeFloatArray(mMaxAmplitudes);
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) {
+                return true;
+            }
+            if (!(o instanceof FrequencyMapping)) {
+                return false;
+            }
+            FrequencyMapping that = (FrequencyMapping) o;
+            return Float.compare(mMinFrequencyHz, that.mMinFrequencyHz) == 0
+                    && Float.compare(mResonantFrequencyHz, that.mResonantFrequencyHz) == 0
+                    && Float.compare(mFrequencyResolutionHz, that.mFrequencyResolutionHz) == 0
+                    && Float.compare(mSuggestedSafeRangeHz, that.mSuggestedSafeRangeHz) == 0
+                    && Arrays.equals(mMaxAmplitudes, that.mMaxAmplitudes);
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(mMinFrequencyHz, mFrequencyResolutionHz, mFrequencyResolutionHz,
+                    mSuggestedSafeRangeHz, mMaxAmplitudes);
+        }
+
+        @Override
+        public String toString() {
+            return "FrequencyMapping{"
+                    + "mRelativeFrequencyRange=" + mRelativeFrequencyRange
+                    + ", mMinFrequency=" + mMinFrequencyHz
+                    + ", mResonantFrequency=" + mResonantFrequencyHz
+                    + ", mMaxFrequency="
+                    + (mMinFrequencyHz + mFrequencyResolutionHz * (mMaxAmplitudes.length - 1))
+                    + ", mFrequencyResolution=" + mFrequencyResolutionHz
+                    + ", mSuggestedSafeRange=" + mSuggestedSafeRangeHz
+                    + ", mMaxAmplitudes count=" + mMaxAmplitudes.length
+                    + '}';
+        }
+
+        @NonNull
+        public static final Creator<FrequencyMapping> CREATOR =
+                new Creator<FrequencyMapping>() {
+                    @Override
+                    public FrequencyMapping createFromParcel(Parcel in) {
+                        return new FrequencyMapping(in);
+                    }
+
+                    @Override
+                    public FrequencyMapping[] newArray(int size) {
+                        return new FrequencyMapping[size];
+                    }
+                };
+    }
+
     @NonNull
     public static final Creator<VibratorInfo> CREATOR =
             new Creator<VibratorInfo>() {
diff --git a/core/java/android/os/storage/IStorageManager.aidl b/core/java/android/os/storage/IStorageManager.aidl
index 98b4e0b..9385402 100644
--- a/core/java/android/os/storage/IStorageManager.aidl
+++ b/core/java/android/os/storage/IStorageManager.aidl
@@ -201,4 +201,6 @@
     void notifyAppIoBlocked(in String volumeUuid, int uid, int tid, int reason) = 91;
     void notifyAppIoResumed(in String volumeUuid, int uid, int tid, int reason) = 92;
     PendingIntent getManageSpaceActivityIntent(in String packageName, int requestCode) = 93;
-    }
+    boolean isAppIoBlocked(in String volumeUuid, int uid, int tid, int reason) = 94;
+    int getExternalStorageMountMode(int uid, in String packageName) = 95;
+}
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index c967deb..77c794c 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -2124,6 +2124,52 @@
         }
     }
 
+
+    /** @hide */
+    @IntDef(prefix = { "MOUNT_MODE_" }, value = {
+            MOUNT_MODE_EXTERNAL_NONE,
+            MOUNT_MODE_EXTERNAL_DEFAULT,
+            MOUNT_MODE_EXTERNAL_INSTALLER,
+            MOUNT_MODE_EXTERNAL_PASS_THROUGH,
+            MOUNT_MODE_EXTERNAL_ANDROID_WRITABLE
+    })
+    /** @hide */
+    public @interface MountMode {}
+
+    /**
+     * No external storage should be mounted.
+     * @hide
+     */
+    @SystemApi
+    public static final int MOUNT_MODE_EXTERNAL_NONE = IVold.REMOUNT_MODE_NONE;
+    /**
+     * Default external storage should be mounted.
+     * @hide
+     */
+    @SystemApi
+    public static final int MOUNT_MODE_EXTERNAL_DEFAULT = IVold.REMOUNT_MODE_DEFAULT;
+    /**
+     * Mount mode for package installers which should give them access to
+     * all obb dirs in addition to their package sandboxes
+     * @hide
+     */
+    @SystemApi
+    public static final int MOUNT_MODE_EXTERNAL_INSTALLER = IVold.REMOUNT_MODE_INSTALLER;
+    /**
+     * The lower file system should be bind mounted directly on external storage
+     * @hide
+     */
+    @SystemApi
+    public static final int MOUNT_MODE_EXTERNAL_PASS_THROUGH = IVold.REMOUNT_MODE_PASS_THROUGH;
+
+    /**
+     * Use the regular scoped storage filesystem, but Android/ should be writable.
+     * Used to support the applications hosting DownloadManager and the MTP server.
+     * @hide
+     */
+    @SystemApi
+    public static final int MOUNT_MODE_EXTERNAL_ANDROID_WRITABLE =
+            IVold.REMOUNT_MODE_ANDROID_WRITABLE;
     /**
      * Flag indicating that a disk space allocation request should operate in an
      * aggressive mode. This flag should only be rarely used in situations that
@@ -2301,6 +2347,28 @@
     }
 
     /**
+     * Returns the External Storage mount mode corresponding to the given uid and packageName.
+     * These mount modes specify different views and access levels for
+     * different apps on external storage.
+     *
+     * @params uid UID of the application
+     * @params packageName name of the package
+     * @return {@code MountMode} for the given uid and packageName.
+     *
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.WRITE_MEDIA_STORAGE)
+    @SystemApi
+    @MountMode
+    public int getExternalStorageMountMode(int uid, @NonNull String packageName) {
+        try {
+            return mStorageManager.getExternalStorageMountMode(uid, packageName);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Allocate the requested number of bytes for your application to use in the
      * given open file. This will cause the system to delete any cached files
      * necessary to satisfy your request.
@@ -2728,12 +2796,20 @@
     }
 
     /**
+     * Reason to provide if app IO is blocked/resumed for unknown reasons
+     *
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public static final int APP_IO_BLOCKED_REASON_UNKNOWN = 0;
+
+    /**
      * Reason to provide if app IO is blocked/resumed because of transcoding
      *
      * @hide
      */
     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
-    public static final int APP_IO_BLOCKED_REASON_TRANSCODING = 0;
+    public static final int APP_IO_BLOCKED_REASON_TRANSCODING = 1;
 
     /**
      * Constants for use with
@@ -2744,7 +2820,8 @@
      */
     @Retention(RetentionPolicy.SOURCE)
     @IntDef(prefix = { "APP_IO_BLOCKED_REASON_" }, value = {
-            APP_IO_BLOCKED_REASON_TRANSCODING
+                APP_IO_BLOCKED_REASON_TRANSCODING,
+                APP_IO_BLOCKED_REASON_UNKNOWN,
     })
     public @interface AppIoBlockedReason {}
 
@@ -2803,6 +2880,30 @@
         }
     }
 
+    /**
+     * Check if {@code uid} with {@code tid} is blocked on IO for {@code reason}.
+     *
+     * This requires {@link ExternalStorageService} the
+     * {@link android.Manifest.permission#WRITE_MEDIA_STORAGE} permission.
+     *
+     * @param volumeUuid the UUID of the storage volume to check IO blocked status
+     * @param uid the UID of the app to check IO blocked status
+     * @param tid the tid of the app to check IO blocked status
+     * @param reason the reason to check IO blocked status for
+     *
+     * @hide
+     */
+    @TestApi
+    public boolean isAppIoBlocked(@NonNull UUID volumeUuid, int uid, int tid,
+            @AppIoBlockedReason int reason) {
+        Objects.requireNonNull(volumeUuid);
+        try {
+            return mStorageManager.isAppIoBlocked(convert(volumeUuid), uid, tid, reason);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
     private final Object mFuseAppLoopLock = new Object();
 
     @GuardedBy("mFuseAppLoopLock")
diff --git a/core/java/android/os/storage/StorageVolume.java b/core/java/android/os/storage/StorageVolume.java
index b5abe2a..36177c4 100644
--- a/core/java/android/os/storage/StorageVolume.java
+++ b/core/java/android/os/storage/StorageVolume.java
@@ -16,6 +16,8 @@
 
 package android.os.storage;
 
+import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
@@ -289,9 +291,14 @@
         return mMaxFileSize;
     }
 
-    /** {@hide} */
+    /**
+     * Returns the user that owns this volume
+     *
+     * {@hide}
+     */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
-    public UserHandle getOwner() {
+    @SystemApi(client = MODULE_LIBRARIES)
+    public @NonNull UserHandle getOwner() {
         return mOwner;
     }
 
diff --git a/core/java/android/os/vibrator/PrebakedSegment.java b/core/java/android/os/vibrator/PrebakedSegment.java
new file mode 100644
index 0000000..78b4346
--- /dev/null
+++ b/core/java/android/os/vibrator/PrebakedSegment.java
@@ -0,0 +1,184 @@
+/*
+ * 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 android.os.vibrator;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.TestApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.VibrationEffect;
+
+import java.util.Objects;
+
+/**
+ * Representation of {@link VibrationEffectSegment} that plays a prebaked vibration effect.
+ *
+ * @hide
+ */
+@TestApi
+public final class PrebakedSegment extends VibrationEffectSegment {
+    private final int mEffectId;
+    private final boolean mFallback;
+    private final int mEffectStrength;
+
+    PrebakedSegment(@NonNull Parcel in) {
+        mEffectId = in.readInt();
+        mFallback = in.readByte() != 0;
+        mEffectStrength = in.readInt();
+    }
+
+    /** @hide */
+    public PrebakedSegment(int effectId, boolean shouldFallback, int effectStrength) {
+        mEffectId = effectId;
+        mFallback = shouldFallback;
+        mEffectStrength = effectStrength;
+    }
+
+    public int getEffectId() {
+        return mEffectId;
+    }
+
+    public int getEffectStrength() {
+        return mEffectStrength;
+    }
+
+    /** Return true if a fallback effect should be played if this effect is not supported. */
+    public boolean shouldFallback() {
+        return mFallback;
+    }
+
+    @Override
+    public long getDuration() {
+        return -1;
+    }
+
+    @Override
+    public boolean hasNonZeroAmplitude() {
+        return true;
+    }
+
+    @NonNull
+    @Override
+    public PrebakedSegment resolve(int defaultAmplitude) {
+        return this;
+    }
+
+    @NonNull
+    @Override
+    public PrebakedSegment scale(float scaleFactor) {
+        // Prebaked effect strength cannot be scaled with this method.
+        return this;
+    }
+
+    @NonNull
+    @Override
+    public PrebakedSegment applyEffectStrength(int effectStrength) {
+        if (effectStrength != mEffectStrength && isValidEffectStrength(effectStrength)) {
+            return new PrebakedSegment(mEffectId, mFallback, effectStrength);
+        }
+        return this;
+    }
+
+    private static boolean isValidEffectStrength(int strength) {
+        switch (strength) {
+            case VibrationEffect.EFFECT_STRENGTH_LIGHT:
+            case VibrationEffect.EFFECT_STRENGTH_MEDIUM:
+            case VibrationEffect.EFFECT_STRENGTH_STRONG:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    @Override
+    public void validate() {
+        switch (mEffectId) {
+            case VibrationEffect.EFFECT_CLICK:
+            case VibrationEffect.EFFECT_DOUBLE_CLICK:
+            case VibrationEffect.EFFECT_TICK:
+            case VibrationEffect.EFFECT_TEXTURE_TICK:
+            case VibrationEffect.EFFECT_THUD:
+            case VibrationEffect.EFFECT_POP:
+            case VibrationEffect.EFFECT_HEAVY_CLICK:
+                break;
+            default:
+                int[] ringtones = VibrationEffect.RINGTONES;
+                if (mEffectId < ringtones[0] || mEffectId > ringtones[ringtones.length - 1]) {
+                    throw new IllegalArgumentException(
+                            "Unknown prebaked effect type (value=" + mEffectId + ")");
+                }
+        }
+        if (!isValidEffectStrength(mEffectStrength)) {
+            throw new IllegalArgumentException(
+                    "Unknown prebaked effect strength (value=" + mEffectStrength + ")");
+        }
+    }
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        if (!(o instanceof PrebakedSegment)) {
+            return false;
+        }
+        PrebakedSegment other = (PrebakedSegment) o;
+        return mEffectId == other.mEffectId
+                && mFallback == other.mFallback
+                && mEffectStrength == other.mEffectStrength;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mEffectId, mFallback, mEffectStrength);
+    }
+
+    @Override
+    public String toString() {
+        return "Prebaked{effect=" + VibrationEffect.effectIdToString(mEffectId)
+                + ", strength=" + VibrationEffect.effectStrengthToString(mEffectStrength)
+                + ", fallback=" + mFallback
+                + "}";
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel out, int flags) {
+        out.writeInt(PARCEL_TOKEN_PREBAKED);
+        out.writeInt(mEffectId);
+        out.writeByte((byte) (mFallback ? 1 : 0));
+        out.writeInt(mEffectStrength);
+    }
+
+    @NonNull
+    public static final Parcelable.Creator<PrebakedSegment> CREATOR =
+            new Parcelable.Creator<PrebakedSegment>() {
+                @Override
+                public PrebakedSegment createFromParcel(Parcel in) {
+                    // Skip the type token
+                    in.readInt();
+                    return new PrebakedSegment(in);
+                }
+
+                @Override
+                public PrebakedSegment[] newArray(int size) {
+                    return new PrebakedSegment[size];
+                }
+            };
+}
diff --git a/core/java/android/os/vibrator/PrimitiveSegment.java b/core/java/android/os/vibrator/PrimitiveSegment.java
new file mode 100644
index 0000000..2ef29cb
--- /dev/null
+++ b/core/java/android/os/vibrator/PrimitiveSegment.java
@@ -0,0 +1,155 @@
+/*
+ * 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 android.os.vibrator;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.TestApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.VibrationEffect;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.Objects;
+
+/**
+ * Representation of {@link VibrationEffectSegment} that plays a primitive vibration effect after a
+ * specified delay and applying a given scale.
+ *
+ * @hide
+ */
+@TestApi
+public final class PrimitiveSegment extends VibrationEffectSegment {
+    private final int mPrimitiveId;
+    private final float mScale;
+    private final int mDelay;
+
+    PrimitiveSegment(@NonNull Parcel in) {
+        this(in.readInt(), in.readFloat(), in.readInt());
+    }
+
+    /** @hide */
+    public PrimitiveSegment(int id, float scale, int delay) {
+        mPrimitiveId = id;
+        mScale = scale;
+        mDelay = delay;
+    }
+
+    public int getPrimitiveId() {
+        return mPrimitiveId;
+    }
+
+    public float getScale() {
+        return mScale;
+    }
+
+    public int getDelay() {
+        return mDelay;
+    }
+
+    @Override
+    public long getDuration() {
+        return -1;
+    }
+
+    @Override
+    public boolean hasNonZeroAmplitude() {
+        // Every primitive plays a vibration with a non-zero amplitude, even at scale == 0.
+        return true;
+    }
+
+    @NonNull
+    @Override
+    public PrimitiveSegment resolve(int defaultAmplitude) {
+        return this;
+    }
+
+    @NonNull
+    @Override
+    public PrimitiveSegment scale(float scaleFactor) {
+        return new PrimitiveSegment(mPrimitiveId, VibrationEffect.scale(mScale, scaleFactor),
+                mDelay);
+    }
+
+    @NonNull
+    @Override
+    public PrimitiveSegment applyEffectStrength(int effectStrength) {
+        return this;
+    }
+
+    @Override
+    public void validate() {
+        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");
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeInt(PARCEL_TOKEN_PRIMITIVE);
+        dest.writeInt(mPrimitiveId);
+        dest.writeFloat(mScale);
+        dest.writeInt(mDelay);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public String toString() {
+        return "Primitive{"
+                + "primitive=" + VibrationEffect.Composition.primitiveToString(mPrimitiveId)
+                + ", scale=" + mScale
+                + ", delay=" + mDelay
+                + '}';
+    }
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        PrimitiveSegment that = (PrimitiveSegment) o;
+        return mPrimitiveId == that.mPrimitiveId
+                && Float.compare(that.mScale, mScale) == 0
+                && mDelay == that.mDelay;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mPrimitiveId, mScale, mDelay);
+    }
+
+    @NonNull
+    public static final Parcelable.Creator<PrimitiveSegment> CREATOR =
+            new Parcelable.Creator<PrimitiveSegment>() {
+                @Override
+                public PrimitiveSegment createFromParcel(Parcel in) {
+                    // Skip the type token
+                    in.readInt();
+                    return new PrimitiveSegment(in);
+                }
+
+                @Override
+                public PrimitiveSegment[] newArray(int size) {
+                    return new PrimitiveSegment[size];
+                }
+            };
+}
diff --git a/core/java/android/os/vibrator/RampSegment.java b/core/java/android/os/vibrator/RampSegment.java
new file mode 100644
index 0000000..aad87c5
--- /dev/null
+++ b/core/java/android/os/vibrator/RampSegment.java
@@ -0,0 +1,176 @@
+/*
+ * 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 android.os.vibrator;
+
+import android.annotation.NonNull;
+import android.annotation.TestApi;
+import android.os.Parcel;
+import android.os.VibrationEffect;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.Objects;
+
+/**
+ * Representation of {@link VibrationEffectSegment} that ramps vibration amplitude and/or frequency
+ * for a specified duration.
+ *
+ * @hide
+ */
+@TestApi
+public final class RampSegment extends VibrationEffectSegment {
+    private final float mStartAmplitude;
+    private final float mStartFrequency;
+    private final float mEndAmplitude;
+    private final float mEndFrequency;
+    private final int mDuration;
+
+    RampSegment(@NonNull Parcel in) {
+        this(in.readFloat(), in.readFloat(), in.readFloat(), in.readFloat(), in.readInt());
+    }
+
+    /** @hide */
+    public RampSegment(float startAmplitude, float endAmplitude, float startFrequency,
+            float endFrequency, int duration) {
+        mStartAmplitude = startAmplitude;
+        mEndAmplitude = endAmplitude;
+        mStartFrequency = startFrequency;
+        mEndFrequency = endFrequency;
+        mDuration = duration;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (!(o instanceof RampSegment)) {
+            return false;
+        }
+        RampSegment other = (RampSegment) o;
+        return Float.compare(mStartAmplitude, other.mStartAmplitude) == 0
+                && Float.compare(mEndAmplitude, other.mEndAmplitude) == 0
+                && Float.compare(mStartFrequency, other.mStartFrequency) == 0
+                && Float.compare(mEndFrequency, other.mEndFrequency) == 0
+                && mDuration == other.mDuration;
+    }
+
+    public float getStartAmplitude() {
+        return mStartAmplitude;
+    }
+
+    public float getEndAmplitude() {
+        return mEndAmplitude;
+    }
+
+    public float getStartFrequency() {
+        return mStartFrequency;
+    }
+
+    public float getEndFrequency() {
+        return mEndFrequency;
+    }
+
+    @Override
+    public long getDuration() {
+        return mDuration;
+    }
+
+    @Override
+    public boolean hasNonZeroAmplitude() {
+        return mStartAmplitude > 0 || mEndAmplitude > 0;
+    }
+
+    @Override
+    public void validate() {
+        Preconditions.checkArgumentNonnegative(mDuration,
+                "Durations must all be >= 0, got " + mDuration);
+        Preconditions.checkArgumentInRange(mStartAmplitude, 0f, 1f, "startAmplitude");
+        Preconditions.checkArgumentInRange(mEndAmplitude, 0f, 1f, "endAmplitude");
+    }
+
+
+    @NonNull
+    @Override
+    public RampSegment resolve(int defaultAmplitude) {
+        // Default amplitude is not supported for ramping.
+        return this;
+    }
+
+    @NonNull
+    @Override
+    public RampSegment scale(float scaleFactor) {
+        float newStartAmplitude = VibrationEffect.scale(mStartAmplitude, scaleFactor);
+        float newEndAmplitude = VibrationEffect.scale(mEndAmplitude, scaleFactor);
+        if (Float.compare(mStartAmplitude, newStartAmplitude) == 0
+                && Float.compare(mEndAmplitude, newEndAmplitude) == 0) {
+            return this;
+        }
+        return new RampSegment(newStartAmplitude, newEndAmplitude, mStartFrequency, mEndFrequency,
+                mDuration);
+    }
+
+    @NonNull
+    @Override
+    public RampSegment applyEffectStrength(int effectStrength) {
+        return this;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mStartAmplitude, mEndAmplitude, mStartFrequency, mEndFrequency,
+                mDuration);
+    }
+
+    @Override
+    public String toString() {
+        return "Ramp{startAmplitude=" + mStartAmplitude
+                + ", endAmplitude=" + mEndAmplitude
+                + ", startFrequency=" + mStartFrequency
+                + ", endFrequency=" + mEndFrequency
+                + ", duration=" + mDuration
+                + "}";
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel out, int flags) {
+        out.writeInt(PARCEL_TOKEN_RAMP);
+        out.writeFloat(mStartAmplitude);
+        out.writeFloat(mEndAmplitude);
+        out.writeFloat(mStartFrequency);
+        out.writeFloat(mEndFrequency);
+        out.writeInt(mDuration);
+    }
+
+    @NonNull
+    public static final Creator<RampSegment> CREATOR =
+            new Creator<RampSegment>() {
+                @Override
+                public RampSegment createFromParcel(Parcel in) {
+                    // Skip the type token
+                    in.readInt();
+                    return new RampSegment(in);
+                }
+
+                @Override
+                public RampSegment[] newArray(int size) {
+                    return new RampSegment[size];
+                }
+            };
+}
diff --git a/core/java/android/os/vibrator/StepSegment.java b/core/java/android/os/vibrator/StepSegment.java
new file mode 100644
index 0000000..11209e0
--- /dev/null
+++ b/core/java/android/os/vibrator/StepSegment.java
@@ -0,0 +1,163 @@
+/*
+ * 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 android.os.vibrator;
+
+import android.annotation.NonNull;
+import android.annotation.TestApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.VibrationEffect;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.Objects;
+
+/**
+ * Representation of {@link VibrationEffectSegment} that holds a fixed vibration amplitude and
+ * frequency for a specified duration.
+ *
+ * @hide
+ */
+@TestApi
+public final class StepSegment extends VibrationEffectSegment {
+    private final float mAmplitude;
+    private final float mFrequency;
+    private final int mDuration;
+
+    StepSegment(@NonNull Parcel in) {
+        this(in.readFloat(), in.readFloat(), in.readInt());
+    }
+
+    /** @hide */
+    public StepSegment(float amplitude, float frequency, int duration) {
+        mAmplitude = amplitude;
+        mFrequency = frequency;
+        mDuration = duration;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (!(o instanceof StepSegment)) {
+            return false;
+        }
+        StepSegment other = (StepSegment) o;
+        return Float.compare(mAmplitude, other.mAmplitude) == 0
+                && Float.compare(mFrequency, other.mFrequency) == 0
+                && mDuration == other.mDuration;
+    }
+
+    public float getAmplitude() {
+        return mAmplitude;
+    }
+
+    public float getFrequency() {
+        return mFrequency;
+    }
+
+    @Override
+    public long getDuration() {
+        return mDuration;
+    }
+
+    @Override
+    public boolean hasNonZeroAmplitude() {
+        // DEFAULT_AMPLITUDE == -1 is still a non-zero amplitude that will be resolved later.
+        return Float.compare(mAmplitude, 0) != 0;
+    }
+
+    @Override
+    public void validate() {
+        Preconditions.checkArgumentNonnegative(mDuration,
+                "Durations must all be >= 0, got " + mDuration);
+        if (Float.compare(mAmplitude, VibrationEffect.DEFAULT_AMPLITUDE) != 0) {
+            Preconditions.checkArgumentInRange(mAmplitude, 0f, 1f, "amplitude");
+        }
+    }
+
+    @NonNull
+    @Override
+    public StepSegment resolve(int defaultAmplitude) {
+        if (defaultAmplitude > VibrationEffect.MAX_AMPLITUDE || defaultAmplitude <= 0) {
+            throw new IllegalArgumentException(
+                    "amplitude must be between 1 and 255 inclusive (amplitude="
+                            + defaultAmplitude + ")");
+        }
+        if (Float.compare(mAmplitude, VibrationEffect.DEFAULT_AMPLITUDE) != 0) {
+            return this;
+        }
+        return new StepSegment((float) defaultAmplitude / VibrationEffect.MAX_AMPLITUDE, mFrequency,
+                mDuration);
+    }
+
+    @NonNull
+    @Override
+    public StepSegment scale(float scaleFactor) {
+        if (Float.compare(mAmplitude, VibrationEffect.DEFAULT_AMPLITUDE) == 0) {
+            return this;
+        }
+        return new StepSegment(VibrationEffect.scale(mAmplitude, scaleFactor), mFrequency,
+                mDuration);
+    }
+
+    @NonNull
+    @Override
+    public StepSegment applyEffectStrength(int effectStrength) {
+        return this;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mAmplitude, mFrequency, mDuration);
+    }
+
+    @Override
+    public String toString() {
+        return "Step{amplitude=" + mAmplitude
+                + ", frequency=" + mFrequency
+                + ", duration=" + mDuration
+                + "}";
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel out, int flags) {
+        out.writeInt(PARCEL_TOKEN_STEP);
+        out.writeFloat(mAmplitude);
+        out.writeFloat(mFrequency);
+        out.writeInt(mDuration);
+    }
+
+    @NonNull
+    public static final Parcelable.Creator<StepSegment> CREATOR =
+            new Parcelable.Creator<StepSegment>() {
+                @Override
+                public StepSegment createFromParcel(Parcel in) {
+                    // Skip the type token
+                    in.readInt();
+                    return new StepSegment(in);
+                }
+
+                @Override
+                public StepSegment[] newArray(int size) {
+                    return new StepSegment[size];
+                }
+            };
+}
diff --git a/core/java/android/os/vibrator/VibrationEffectSegment.java b/core/java/android/os/vibrator/VibrationEffectSegment.java
new file mode 100644
index 0000000..5b42845
--- /dev/null
+++ b/core/java/android/os/vibrator/VibrationEffectSegment.java
@@ -0,0 +1,118 @@
+/*
+ * 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 android.os.vibrator;
+
+import android.annotation.NonNull;
+import android.annotation.TestApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.VibrationEffect;
+
+/**
+ * Representation of a single segment of a {@link VibrationEffect}.
+ *
+ * <p>Vibration effects are represented as a sequence of segments that describes how vibration
+ * amplitude and frequency changes over time. Segments can be described as one of the following:
+ *
+ * <ol>
+ *     <li>A predefined vibration effect;
+ *     <li>A composable effect primitive;
+ *     <li>Fixed amplitude and frequency values to be held for a specified duration;
+ *     <li>Pairs of amplitude and frequency values to be ramped to for a specified duration;
+ * </ol>
+ *
+ * @hide
+ */
+@TestApi
+@SuppressWarnings({"ParcelNotFinal", "ParcelCreator"}) // Parcel only extended here.
+public abstract class VibrationEffectSegment implements Parcelable {
+    static final int PARCEL_TOKEN_PREBAKED = 1;
+    static final int PARCEL_TOKEN_PRIMITIVE = 2;
+    static final int PARCEL_TOKEN_STEP = 3;
+    static final int PARCEL_TOKEN_RAMP = 4;
+
+    /** Prevent subclassing from outside of this package */
+    VibrationEffectSegment() {
+    }
+
+    /**
+     * Gets the estimated duration of the segment in milliseconds.
+     *
+     * <p>For segments with an unknown duration (e.g. prebaked or primitive effects where the length
+     * is device and potentially run-time dependent), this returns -1.
+     */
+    public abstract long getDuration();
+
+    /** Returns true if this segment plays at a non-zero amplitude at some point. */
+    public abstract boolean hasNonZeroAmplitude();
+
+    /** Validates the segment, throwing exceptions if any parameter is invalid. */
+    public abstract void validate();
+
+    /**
+     * Resolves amplitudes set to {@link VibrationEffect#DEFAULT_AMPLITUDE}.
+     *
+     * <p>This might fail with {@link IllegalArgumentException} if value is non-positive or larger
+     * than {@link VibrationEffect#MAX_AMPLITUDE}.
+     */
+    @NonNull
+    public abstract <T extends VibrationEffectSegment> T resolve(int defaultAmplitude);
+
+    /**
+     * Scale the segment intensity with the given factor.
+     *
+     * @param scaleFactor scale factor to be applied to the intensity. Values within [0,1) will
+     *                    scale down the intensity, values larger than 1 will scale up
+     */
+    @NonNull
+    public abstract <T extends VibrationEffectSegment> T scale(float scaleFactor);
+
+    /**
+     * Applies given effect strength to prebaked effects.
+     *
+     * @param effectStrength new effect strength to be applied, one of
+     *                       VibrationEffect.EFFECT_STRENGTH_*.
+     */
+    @NonNull
+    public abstract <T extends VibrationEffectSegment> T applyEffectStrength(int effectStrength);
+
+    @NonNull
+    public static final Creator<VibrationEffectSegment> CREATOR =
+            new Creator<VibrationEffectSegment>() {
+                @Override
+                public VibrationEffectSegment createFromParcel(Parcel in) {
+                    switch (in.readInt()) {
+                        case PARCEL_TOKEN_STEP:
+                            return new StepSegment(in);
+                        case PARCEL_TOKEN_RAMP:
+                            return new RampSegment(in);
+                        case PARCEL_TOKEN_PREBAKED:
+                            return new PrebakedSegment(in);
+                        case PARCEL_TOKEN_PRIMITIVE:
+                            return new PrimitiveSegment(in);
+                        default:
+                            throw new IllegalStateException(
+                                    "Unexpected vibration event type token in parcel.");
+                    }
+                }
+
+                @Override
+                public VibrationEffectSegment[] newArray(int size) {
+                    return new VibrationEffectSegment[size];
+                }
+            };
+}
diff --git a/core/java/android/permission/IPermissionManager.aidl b/core/java/android/permission/IPermissionManager.aidl
index 8c105be..ef075e1 100644
--- a/core/java/android/permission/IPermissionManager.aidl
+++ b/core/java/android/permission/IPermissionManager.aidl
@@ -16,6 +16,7 @@
 
 package android.permission;
 
+import android.content.AttributionSource;
 import android.content.pm.ParceledListSlice;
 import android.content.pm.PermissionGroupInfo;
 import android.content.pm.PermissionInfo;
@@ -85,4 +86,8 @@
     boolean setAutoRevokeExempted(String packageName, boolean exempted, int userId);
 
     boolean isAutoRevokeExempted(String packageName, int userId);
+
+    AttributionSource registerAttributionSource(in AttributionSource source);
+
+    boolean isRegisteredAttributionSource(in AttributionSource source);
 }
diff --git a/core/java/android/permission/PermGroupUsage.java b/core/java/android/permission/PermGroupUsage.java
index c94c0ff..440d6f2 100644
--- a/core/java/android/permission/PermGroupUsage.java
+++ b/core/java/android/permission/PermGroupUsage.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.TestApi;
 
 /**
  * Represents the usage of a permission group by an app. Supports package name, user, permission
@@ -26,6 +27,7 @@
  *
  * @hide
  */
+@TestApi
 public final class PermGroupUsage {
 
     private final String mPackageName;
@@ -36,7 +38,19 @@
     private final boolean mIsPhoneCall;
     private final CharSequence mAttribution;
 
-    PermGroupUsage(@NonNull String packageName, int uid,
+    /**
+     *
+     * @param packageName The package name of the using app
+     * @param uid The uid of the using app
+     * @param permGroupName The name of the permission group being used
+     * @param lastAccess The time of last access
+     * @param isActive Whether this is active
+     * @param isPhoneCall Whether this is a usage by the phone
+     * @param attribution An optional string attribution to show
+     * @hide
+     */
+    @TestApi
+    public PermGroupUsage(@NonNull String packageName, int uid,
             @NonNull String permGroupName, long lastAccess, boolean isActive, boolean isPhoneCall,
             @Nullable CharSequence attribution) {
         this.mPackageName = packageName;
@@ -48,30 +62,58 @@
         this.mAttribution = attribution;
     }
 
+    /**
+     * @hide
+     */
+    @TestApi
     public @NonNull String getPackageName() {
         return mPackageName;
     }
 
+    /**
+     * @hide
+     */
+    @TestApi
     public int getUid() {
         return mUid;
     }
 
+    /**
+     * @hide
+     */
+    @TestApi
     public @NonNull String getPermGroupName() {
         return mPermGroupName;
     }
 
+    /**
+     * @hide
+     */
+    @TestApi
     public long getLastAccess() {
         return mLastAccess;
     }
 
+    /**
+     * @hide
+     */
+    @TestApi
     public boolean isActive() {
         return mIsActive;
     }
 
+    /**
+     * @hide
+     */
+    @TestApi
     public boolean isPhoneCall() {
         return mIsPhoneCall;
     }
 
+    /**
+     * @hide
+     */
+    @TestApi
     public @Nullable CharSequence getAttribution() {
         return mAttribution;
     }
@@ -80,6 +122,7 @@
     public String toString() {
         return getClass().getSimpleName() + "@" + Integer.toHexString(System.identityHashCode(this))
                 + " packageName: " + mPackageName + ", UID: " + mUid + ", permGroup: "
-                + mPermGroupName + ", isActive: " + mIsActive + ", attribution: " + mAttribution;
+                + mPermGroupName + ", lastAccess: " + mLastAccess + ", isActive: " + mIsActive
+                + ", attribution: " + mAttribution;
     }
 }
diff --git a/core/java/android/permission/PermissionManager.java b/core/java/android/permission/PermissionManager.java
index 177e422..936cbfc 100644
--- a/core/java/android/permission/PermissionManager.java
+++ b/core/java/android/permission/PermissionManager.java
@@ -26,6 +26,7 @@
 import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
+import android.annotation.TestApi;
 import android.annotation.UserIdInt;
 import android.app.ActivityManager;
 import android.app.ActivityThread;
@@ -43,6 +44,7 @@
 import android.content.pm.permission.SplitPermissionInfoParcelable;
 import android.location.LocationManager;
 import android.media.AudioManager;
+import android.content.AttributionSource;
 import android.os.Build;
 import android.os.Handler;
 import android.os.Looper;
@@ -79,6 +81,9 @@
     private static final String LOG_TAG = PermissionManager.class.getName();
 
     /** @hide */
+    public static final String LOG_TAG_TRACE_GRANTS = "PermissionGrantTrace";
+
+    /** @hide */
     public static final String KILL_APP_REASON_PERMISSIONS_REVOKED =
             "permissions revoked";
     /** @hide */
@@ -102,6 +107,8 @@
      * Note: Changing this won't do anything on its own - you should also change the filtering in
      * {@link #shouldTraceGrant}.
      *
+     * See log output for tag {@link #LOG_TAG_TRACE_GRANTS}
+     *
      * @hide
      */
     public static final boolean DEBUG_TRACE_GRANTS = false;
@@ -318,8 +325,10 @@
     }
 
     /** @hide */
-    public static boolean shouldTraceGrant(String packageName, String permissionName, int userId) {
+    public static boolean shouldTraceGrant(
+            @NonNull String packageName, @NonNull String permissionName, int userId) {
         // To be modified when debugging
+        // template: if ("".equals(packageName) && "".equals(permissionName)) return true;
         return false;
     }
 
@@ -347,7 +356,8 @@
             @NonNull String permissionName, @NonNull UserHandle user) {
         if (DEBUG_TRACE_GRANTS
                 && shouldTraceGrant(packageName, permissionName, user.getIdentifier())) {
-            Log.i(LOG_TAG, "App " + mContext.getPackageName() + " is granting " + packageName + " "
+            Log.i(LOG_TAG_TRACE_GRANTS, "App " + mContext.getPackageName() + " is granting "
+                    + packageName + " "
                     + permissionName + " for user " + user.getIdentifier(), new RuntimeException());
         }
         try {
@@ -851,6 +861,7 @@
      *
      * @hide
      */
+    @TestApi
     @NonNull
     @RequiresPermission(Manifest.permission.GET_APP_OPS_STATS)
     public List<PermGroupUsage> getIndicatorAppOpUsageData() {
@@ -1089,6 +1100,48 @@
                 callingFeatureId, pid, uid);
     }
 
+    /**
+     * Registers an attribution source with the OS. An app can only register an attribution
+     * source for itself. Once an attribution source has been registered another app can
+     * check whether this registration exists and thus trust the payload in the source
+     * object. This is important for permission checking and specifically for app op blaming
+     * since a malicious app should not be able to force the OS to blame another app
+     * that doesn't participate in an attribution chain.
+     *
+     * @param source The attribution source to register.
+     *
+     * @see #isRegisteredAttributionSource(AttributionSource)
+     *
+     * @hide
+     */
+    public @NonNull AttributionSource registerAttributionSource(@NonNull AttributionSource source) {
+        try {
+            return mPermissionManager.registerAttributionSource(source);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+        return null;
+    }
+
+    /**
+     * Checks whether an attribution source is registered.
+     *
+     * @param source The attribution source to check.
+     * @return Whether this is a registered source.
+     *
+     * @see #registerAttributionSource(AttributionSource)
+     *
+     * @hide
+     */
+    public boolean isRegisteredAttributionSource(@NonNull AttributionSource source) {
+        try {
+            return mPermissionManager.isRegisteredAttributionSource(source);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+        return false;
+    }
+
     /* @hide */
     private static int checkPermissionUncached(@Nullable String permission, int pid, int uid) {
         final IActivityManager am = ActivityManager.getService();
diff --git a/core/java/android/permission/PermissionUsageHelper.java b/core/java/android/permission/PermissionUsageHelper.java
index 80a3e16..2d6fa3c 100644
--- a/core/java/android/permission/PermissionUsageHelper.java
+++ b/core/java/android/permission/PermissionUsageHelper.java
@@ -71,13 +71,10 @@
     private static final String PROPERTY_PERMISSIONS_HUB_2_ENABLED = "permissions_hub_2_enabled";
 
     /** How long after an access to show it as "recent" */
-    private static final String RECENT_ACCESS_TIME_MS = "recent_acccess_time_ms";
+    private static final String RECENT_ACCESS_TIME_MS = "recent_access_time_ms";
 
     /** How long after an access to show it as "running" */
-    private static final String RUNNING_ACCESS_TIME_MS = "running_acccess_time_ms";
-
-    /** The name of the expected voice IME subtype */
-    private static final String VOICE_IME_SUBTYPE = "voice";
+    private static final String RUNNING_ACCESS_TIME_MS = "running_access_time_ms";
 
     private static final String SYSTEM_PKG = "android";
 
@@ -279,13 +276,15 @@
                             opEntry.getAttributedOpEntries().get(attributionTag);
 
                     long lastAccessTime = attrOpEntry.getLastAccessTime(opFlags);
+                    if (attrOpEntry.isRunning()) {
+                        lastAccessTime = now;
+                    }
+
                     if (lastAccessTime < recentThreshold && !attrOpEntry.isRunning()) {
                         continue;
                     }
 
-                    if (packageName.equals(SYSTEM_PKG)
-                            || (!shouldShowPermissionsHub()
-                            && !isUserSensitive(packageName, user, op))) {
+                    if (!shouldShowPermissionsHub() && !isUserSensitive(packageName, user, op)) {
                         continue;
                     }
 
@@ -372,8 +371,10 @@
                 proxyLabels.put(usage, new ArrayList<>());
                 proxyUids.add(usage.uid);
             }
-            if (!mostRecentUsages.containsKey(usage.uid) || usage.lastAccessTime
-                    > mostRecentUsages.get(usage.uid).lastAccessTime) {
+            // If this usage is not by the system, and is more recent than the next-most recent
+            // for it's uid, save it.
+            if (!usage.packageName.equals(SYSTEM_PKG) && (!mostRecentUsages.containsKey(usage.uid)
+                    || usage.lastAccessTime > mostRecentUsages.get(usage.uid).lastAccessTime)) {
                 mostRecentUsages.put(usage.uid, usage);
             }
         }
@@ -416,20 +417,22 @@
                 }
 
                 proxyUids.add(currentUsage.uid);
-                try {
-                    PackageManager userPkgManager =
-                            getUserContext(currentUsage.getUser()).getPackageManager();
-                    ApplicationInfo appInfo = userPkgManager.getApplicationInfo(
-                            currentUsage.packageName, 0);
-                    CharSequence appLabel = appInfo.loadLabel(userPkgManager);
-                    // If we don't already have the app label, and it's not the same as the main
-                    // app, add it
-                    if (!proxyLabelList.contains(appLabel)
-                            && !currentUsage.packageName.equals(start.packageName)) {
-                        proxyLabelList.add(appLabel);
+                // Don't add an app label for the main app, or the system app
+                if (!currentUsage.packageName.equals(start.packageName)
+                        && !currentUsage.packageName.equals(SYSTEM_PKG)) {
+                    try {
+                        PackageManager userPkgManager =
+                                getUserContext(currentUsage.getUser()).getPackageManager();
+                        ApplicationInfo appInfo = userPkgManager.getApplicationInfo(
+                                currentUsage.packageName, 0);
+                        CharSequence appLabel = appInfo.loadLabel(userPkgManager);
+                        // If we don't already have the app label add it
+                        if (!proxyLabelList.contains(appLabel)) {
+                            proxyLabelList.add(appLabel);
+                        }
+                    } catch (PackageManager.NameNotFoundException e) {
+                        // Ignore
                     }
-                } catch (PackageManager.NameNotFoundException e) {
-                    // Ignore
                 }
                 iterNum++;
             }
diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java
index e9bbcc79..03b5a2e 100644
--- a/core/java/android/provider/DeviceConfig.java
+++ b/core/java/android/provider/DeviceConfig.java
@@ -108,6 +108,13 @@
     public static final String NAMESPACE_APP_HIBERNATION = "app_hibernation";
 
     /**
+     * Namespace for all AppSearch related features.
+     * @hide
+     */
+    @SystemApi
+    public static final String NAMESPACE_APPSEARCH = "appsearch";
+
+    /**
      * Namespace for app standby configurations.
      *
      * @hide
@@ -250,6 +257,14 @@
     public static final String NAMESPACE_JOB_SCHEDULER = "jobscheduler";
 
     /**
+     * Namespace for all media related features.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String NAMESPACE_MEDIA = "media";
+
+    /**
      * Namespace for all media native related features.
      *
      * @hide
@@ -358,6 +373,38 @@
     public static final String NAMESPACE_SETTINGS_STATS = "settings_stats";
 
     /**
+     * Namespace for all statsd java features that can be applied immediately.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String NAMESPACE_STATSD_JAVA = "statsd_java";
+
+    /**
+     * Namespace for all statsd java features that are applied on boot.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String NAMESPACE_STATSD_JAVA_BOOT = "statsd_java_boot";
+
+    /**
+     * Namespace for all statsd native features that can be applied immediately.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String NAMESPACE_STATSD_NATIVE = "statsd_native";
+
+    /**
+     * Namespace for all statsd native features that are applied on boot.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String NAMESPACE_STATSD_NATIVE_BOOT = "statsd_native_boot";
+
+    /**
      * Namespace for storage-related features.
      *
      * @deprecated Replace storage namespace with storage_native_boot.
@@ -456,7 +503,8 @@
      */
     @NonNull
     private static final List<String> PUBLIC_NAMESPACES =
-            Arrays.asList(NAMESPACE_TEXTCLASSIFIER, NAMESPACE_RUNTIME);
+            Arrays.asList(NAMESPACE_TEXTCLASSIFIER, NAMESPACE_RUNTIME, NAMESPACE_STATSD_JAVA,
+                    NAMESPACE_STATSD_JAVA_BOOT);
     /**
      * Privacy related properties definitions.
      *
@@ -505,38 +553,6 @@
             "connectivity_thermal_power_manager";
 
     /**
-     * Namespace for all statsd java features that can be applied immediately.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final String NAMESPACE_STATSD_JAVA = "statsd_java";
-
-    /**
-     * Namespace for all statsd java features that are applied on boot.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final String NAMESPACE_STATSD_JAVA_BOOT = "statsd_java_boot";
-
-    /**
-     * Namespace for all statsd native features that can be applied immediately.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final String NAMESPACE_STATSD_NATIVE = "statsd_native";
-
-    /**
-     * Namespace for all statsd native features that are applied on boot.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final String NAMESPACE_STATSD_NATIVE_BOOT = "statsd_native_boot";
-
-    /**
      * Namespace for configuration related features.
      *
      * @hide
@@ -646,7 +662,7 @@
      * @param name      The name of the property to look up.
      * @param defaultValue The value to return if the property does not exist or has no non-null
      *                     value.
-     * @return the corresponding value, or defaultValue if none exists.
+     * @return the correspondfing value, or defaultValue if none exists.
      * @hide
      */
     @SystemApi
diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java
index 0fea484..620fa65 100644
--- a/core/java/android/provider/DocumentsContract.java
+++ b/core/java/android/provider/DocumentsContract.java
@@ -236,10 +236,21 @@
     public static final String
             ACTION_DOCUMENT_ROOT_SETTINGS = "android.provider.action.DOCUMENT_ROOT_SETTINGS";
 
-    /** {@hide} */
+    /**
+     * External Storage Provider's authority string
+     * {@hide}
+     */
+    @SystemApi
     public static final String EXTERNAL_STORAGE_PROVIDER_AUTHORITY =
             "com.android.externalstorage.documents";
 
+    /**
+     * Download Manager's authority string
+     * {@hide}
+     */
+    @SystemApi
+    public static final String DOWNLOADS_PROVIDER_AUTHORITY = Downloads.Impl.AUTHORITY;
+
     /** {@hide} */
     public static final String EXTERNAL_STORAGE_PRIMARY_EMULATED_ROOT_ID = "primary";
 
diff --git a/core/java/android/provider/DocumentsProvider.java b/core/java/android/provider/DocumentsProvider.java
index b704d66..a5a24c0 100644
--- a/core/java/android/provider/DocumentsProvider.java
+++ b/core/java/android/provider/DocumentsProvider.java
@@ -1102,8 +1102,7 @@
             // signed with platform signature can hold MANAGE_DOCUMENTS, we are going to check for
             // MANAGE_DOCUMENTS or associated URI permission here instead
             final Uri rootUri = extraUri;
-            enforceWritePermissionInner(rootUri, getCallingPackage(), getCallingAttributionTag(),
-                    null);
+            enforceWritePermissionInner(rootUri, getCallingAttributionSource());
 
             final String rootId = DocumentsContract.getRootId(rootUri);
             ejectRoot(rootId);
@@ -1121,8 +1120,7 @@
         }
 
         if (METHOD_IS_CHILD_DOCUMENT.equals(method)) {
-            enforceReadPermissionInner(documentUri, getCallingPackage(),
-                    getCallingAttributionTag(), null);
+            enforceReadPermissionInner(documentUri, getCallingAttributionSource());
 
             final Uri childUri = extraTargetUri;
             final String childAuthority = childUri.getAuthority();
@@ -1134,8 +1132,7 @@
                             && isChildDocument(documentId, childId));
 
         } else if (METHOD_CREATE_DOCUMENT.equals(method)) {
-            enforceWritePermissionInner(documentUri, getCallingPackage(),
-                    getCallingAttributionTag(), null);
+            enforceWritePermissionInner(documentUri, getCallingAttributionSource());
 
             final String mimeType = extras.getString(Document.COLUMN_MIME_TYPE);
             final String displayName = extras.getString(Document.COLUMN_DISPLAY_NAME);
@@ -1149,8 +1146,7 @@
             out.putParcelable(DocumentsContract.EXTRA_URI, newDocumentUri);
 
         } else if (METHOD_CREATE_WEB_LINK_INTENT.equals(method)) {
-            enforceWritePermissionInner(documentUri, getCallingPackage(),
-                    getCallingAttributionTag(), null);
+            enforceWritePermissionInner(documentUri, getCallingAttributionSource());
 
             final Bundle options = extras.getBundle(DocumentsContract.EXTRA_OPTIONS);
             final IntentSender intentSender = createWebLinkIntent(documentId, options);
@@ -1158,8 +1154,7 @@
             out.putParcelable(DocumentsContract.EXTRA_RESULT, intentSender);
 
         } else if (METHOD_RENAME_DOCUMENT.equals(method)) {
-            enforceWritePermissionInner(documentUri, getCallingPackage(),
-                    getCallingAttributionTag(), null);
+            enforceWritePermissionInner(documentUri, getCallingAttributionSource());
 
             final String displayName = extras.getString(Document.COLUMN_DISPLAY_NAME);
             final String newDocumentId = renameDocument(documentId, displayName);
@@ -1183,8 +1178,7 @@
             }
 
         } else if (METHOD_DELETE_DOCUMENT.equals(method)) {
-            enforceWritePermissionInner(documentUri, getCallingPackage(),
-                    getCallingAttributionTag(), null);
+            enforceWritePermissionInner(documentUri, getCallingAttributionSource());
             deleteDocument(documentId);
 
             // Document no longer exists, clean up any grants.
@@ -1194,10 +1188,8 @@
             final Uri targetUri = extraTargetUri;
             final String targetId = DocumentsContract.getDocumentId(targetUri);
 
-            enforceReadPermissionInner(documentUri, getCallingPackage(),
-                    getCallingAttributionTag(), null);
-            enforceWritePermissionInner(targetUri, getCallingPackage(), getCallingAttributionTag(),
-                    null);
+            enforceReadPermissionInner(documentUri, getCallingAttributionSource());
+            enforceWritePermissionInner(targetUri, getCallingAttributionSource());
 
             final String newDocumentId = copyDocument(documentId, targetId);
 
@@ -1220,12 +1212,9 @@
             final Uri targetUri = extraTargetUri;
             final String targetId = DocumentsContract.getDocumentId(targetUri);
 
-            enforceWritePermissionInner(documentUri, getCallingPackage(),
-                    getCallingAttributionTag(), null);
-            enforceReadPermissionInner(parentSourceUri, getCallingPackage(),
-                    getCallingAttributionTag(), null);
-            enforceWritePermissionInner(targetUri, getCallingPackage(), getCallingAttributionTag(),
-                    null);
+            enforceWritePermissionInner(documentUri, getCallingAttributionSource());
+            enforceReadPermissionInner(parentSourceUri, getCallingAttributionSource());
+            enforceWritePermissionInner(targetUri, getCallingAttributionSource());
 
             final String newDocumentId = moveDocument(documentId, parentSourceId, targetId);
 
@@ -1246,10 +1235,8 @@
             final Uri parentSourceUri = extraParentUri;
             final String parentSourceId = DocumentsContract.getDocumentId(parentSourceUri);
 
-            enforceReadPermissionInner(parentSourceUri, getCallingPackage(),
-                    getCallingAttributionTag(), null);
-            enforceWritePermissionInner(documentUri, getCallingPackage(),
-                    getCallingAttributionTag(), null);
+            enforceReadPermissionInner(parentSourceUri, getCallingAttributionSource());
+            enforceWritePermissionInner(documentUri, getCallingAttributionSource());
             removeDocument(documentId, parentSourceId);
 
             // It's responsibility of the provider to revoke any grants, as the document may be
@@ -1258,8 +1245,7 @@
             final boolean isTreeUri = isTreeUri(documentUri);
 
             if (isTreeUri) {
-                enforceReadPermissionInner(documentUri, getCallingPackage(),
-                        getCallingAttributionTag(), null);
+                enforceReadPermissionInner(documentUri, getCallingAttributionSource());
             } else {
                 getContext().enforceCallingPermission(Manifest.permission.MANAGE_DOCUMENTS, null);
             }
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 52517b0..22d74ca 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -470,8 +470,8 @@
      * to be shown, with the "package" scheme. That is "package:com.my.app".
      * <p>
      * Output: Nothing.
-     * @hide
      */
+    @SuppressLint("ActionValue")
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
     public static final String ACTION_APP_OPEN_BY_DEFAULT_SETTINGS =
             "com.android.settings.APP_OPEN_BY_DEFAULT_SETTINGS";
@@ -1068,8 +1068,8 @@
      * Output: Nothing.
      */
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
-    public static final String ACTION_MANAGE_ALL_SUBSCRIPTIONS_SETTINGS =
-            "android.settings.MANAGE_ALL_SUBSCRIPTIONS_SETTINGS";
+    public static final String ACTION_MANAGE_ALL_SIM_PROFILES_SETTINGS =
+            "android.settings.MANAGE_ALL_SIM_PROFILES_SETTINGS";
 
     /**
      * Activity Action: Show screen for controlling which apps can draw on top of other apps.
@@ -2754,7 +2754,7 @@
                     arg.putBoolean(CALL_METHOD_OVERRIDEABLE_BY_RESTORE_KEY, true);
                 }
                 IContentProvider cp = mProviderHolder.getProvider(cr);
-                cp.call(cr.getPackageName(), cr.getAttributionTag(),
+                cp.call(cr.getAttributionSource(),
                         mProviderHolder.mUri.getAuthority(), mCallSetCommand, name, arg);
             } catch (RemoteException e) {
                 Log.w(TAG, "Can't set key " + name + " in " + mUri, e);
@@ -2774,7 +2774,7 @@
                 args.putString(CALL_METHOD_PREFIX_KEY, prefix);
                 args.putSerializable(CALL_METHOD_FLAGS_KEY, keyValues);
                 IContentProvider cp = mProviderHolder.getProvider(cr);
-                Bundle bundle = cp.call(cr.getPackageName(), cr.getAttributionTag(),
+                Bundle bundle = cp.call(cr.getAttributionSource(),
                         mProviderHolder.mUri.getAuthority(),
                         mCallSetAllCommand, null, args);
                 return bundle.getBoolean(KEY_CONFIG_SET_RETURN);
@@ -2862,14 +2862,14 @@
                     if (Settings.isInSystemServer() && Binder.getCallingUid() != Process.myUid()) {
                         final long token = Binder.clearCallingIdentity();
                         try {
-                            b = cp.call(cr.getPackageName(), cr.getAttributionTag(),
+                            b = cp.call(cr.getAttributionSource(),
                                     mProviderHolder.mUri.getAuthority(), mCallGetCommand, name,
                                     args);
                         } finally {
                             Binder.restoreCallingIdentity(token);
                         }
                     } else {
-                        b = cp.call(cr.getPackageName(), cr.getAttributionTag(),
+                        b = cp.call(cr.getAttributionSource(),
                                 mProviderHolder.mUri.getAuthority(), mCallGetCommand, name, args);
                     }
                     if (b != null) {
@@ -2939,13 +2939,13 @@
                 if (Settings.isInSystemServer() && Binder.getCallingUid() != Process.myUid()) {
                     final long token = Binder.clearCallingIdentity();
                     try {
-                        c = cp.query(cr.getPackageName(), cr.getAttributionTag(), mUri,
+                        c = cp.query(cr.getAttributionSource(), mUri,
                                 SELECT_VALUE_PROJECTION, queryArgs, null);
                     } finally {
                         Binder.restoreCallingIdentity(token);
                     }
                 } else {
-                    c = cp.query(cr.getPackageName(), cr.getAttributionTag(), mUri,
+                    c = cp.query(cr.getAttributionSource(), mUri,
                             SELECT_VALUE_PROJECTION, queryArgs, null);
                 }
                 if (c == null) {
@@ -3051,7 +3051,7 @@
                 }
 
                 // Fetch all flags for the namespace at once for caching purposes
-                Bundle b = cp.call(cr.getPackageName(), cr.getAttributionTag(),
+                Bundle b = cp.call(cr.getAttributionSource(),
                         mProviderHolder.mUri.getAuthority(), mCallListCommand, null, args);
                 if (b == null) {
                     // Invalid response, return an empty map
@@ -5877,7 +5877,7 @@
                 }
                 arg.putInt(CALL_METHOD_RESET_MODE_KEY, mode);
                 IContentProvider cp = sProviderHolder.getProvider(resolver);
-                cp.call(resolver.getPackageName(), resolver.getAttributionTag(),
+                cp.call(resolver.getAttributionSource(),
                         sProviderHolder.mUri.getAuthority(), CALL_METHOD_RESET_SECURE, null, arg);
             } catch (RemoteException e) {
                 Log.w(TAG, "Can't reset do defaults for " + CONTENT_URI, e);
@@ -6291,6 +6291,20 @@
                 "selected_input_method_subtype";
 
         /**
+         * The {@link android.view.inputmethod.InputMethodInfo.InputMethodInfo#getId() ID} of the
+         * default voice input method.
+         * <p>
+         * This stores the last known default voice IME. If the related system config value changes,
+         * this is reset by InputMethodManagerService.
+         * <p>
+         * This IME is not necessarily in the enabled IME list. That state is still stored in
+         * {@link #ENABLED_INPUT_METHODS}.
+         *
+         * @hide
+         */
+        public static final String DEFAULT_VOICE_INPUT_METHOD = "default_voice_input_method";
+
+        /**
          * Setting to record the history of input method subtype, holding the pair of ID of IME
          * and its last used subtype.
          * @hide
@@ -8523,6 +8537,15 @@
                 "one_handed_tutorial_show_count";
 
         /**
+         * Indicates whether transform is enabled.
+         * <p>
+         * Type: int (0 for false, 1 for true)
+         *
+         * @hide
+         */
+        public static final String TRANSFORM_ENABLED = "transform_enabled";
+
+        /**
          * The current night mode that has been selected by the user.  Owned
          * and controlled by UiModeManagerService.  Constants are as per
          * UiModeManager.
@@ -9153,6 +9176,22 @@
         public static final String ASSIST_GESTURE_SETUP_COMPLETE = "assist_gesture_setup_complete";
 
         /**
+         * Whether the assistant can be triggered by a touch gesture.
+         *
+         * @hide
+         */
+        public static final String ASSIST_TOUCH_GESTURE_ENABLED =
+                "assist_touch_gesture_enabled";
+
+        /**
+         * Whether the assistant can be triggered by long-pressing the home button
+         *
+         * @hide
+         */
+        public static final String ASSIST_LONG_PRESS_HOME_ENABLED =
+                "assist_long_press_home_enabled";
+
+        /**
          * Control whether Trust Agents are in active unlock or extend unlock mode.
          * @hide
          */
@@ -9717,6 +9756,12 @@
                 "accessibility_magnification_mode";
 
         /**
+         * Magnification mode value that is a default value for the magnification logging feature.
+         * @hide
+         */
+        public static final int ACCESSIBILITY_MAGNIFICATION_MODE_NONE = 0x0;
+
+        /**
          * Magnification mode value that magnifies whole display.
          * @hide
          */
@@ -9748,6 +9793,7 @@
          * @hide
          */
         @TestApi
+        @Readable
         public static final String ACCESSIBILITY_MAGNIFICATION_CAPABILITY =
                 "accessibility_magnification_capability";
 
@@ -13112,7 +13158,7 @@
          * @see #ENABLE_RESTRICTED_BUCKET
          * @hide
          */
-        public static final int DEFAULT_ENABLE_RESTRICTED_BUCKET = 0;
+        public static final int DEFAULT_ENABLE_RESTRICTED_BUCKET = 1;
 
         /**
          * Whether or not app auto restriction is enabled. When it is enabled, settings app will
@@ -14032,6 +14078,40 @@
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
         public static final int ZEN_MODE_ALARMS = 3;
 
+        /**
+         * A comma-separated list of HDR formats that have been disabled by the user.
+         * <p>
+         * If present, these formats will not be reported to apps, even if the display supports
+         * them. This list is treated as empty if the ARE_USER_DISABLED_HDR_FORMATS_ALLOWED setting
+         * is '1'.
+         * </p>
+         * @hide
+         */
+        @TestApi
+        @Readable
+        @SuppressLint("NoSettingsProvider")
+        public static final String USER_DISABLED_HDR_FORMATS = "user_disabled_hdr_formats";
+
+        /**
+         * Whether or not user-disabled HDR formats are allowed.
+         * <p>
+         * The value is boolean (1 or 0). The value '1' means the user preference for disabling a
+         * format is ignored, and the disabled formats are still reported to apps (if supported
+         * by the display). The value '0' means the user-disabled formats are not reported to
+         * apps, even if the display supports them.
+         * </p><p>
+         * The list of formats disabled by the user are contained in the
+         * USER_DISABLED_HDR_FORMATS setting. This list is treated as empty when the value of
+         * this setting is '1'.
+         * </p>
+         * @hide
+         */
+        @TestApi
+        @Readable
+        @SuppressLint("NoSettingsProvider")
+        public static final String ARE_USER_DISABLED_HDR_FORMATS_ALLOWED =
+                "are_user_disabled_hdr_formats_allowed";
+
         /** @hide */ public static String zenModeToString(int mode) {
             if (mode == ZEN_MODE_IMPORTANT_INTERRUPTIONS) return "ZEN_MODE_IMPORTANT_INTERRUPTIONS";
             if (mode == ZEN_MODE_ALARMS) return "ZEN_MODE_ALARMS";
@@ -14856,7 +14936,7 @@
                 }
                 arg.putInt(CALL_METHOD_RESET_MODE_KEY, mode);
                 IContentProvider cp = sProviderHolder.getProvider(resolver);
-                cp.call(resolver.getPackageName(), resolver.getAttributionTag(),
+                cp.call(resolver.getAttributionSource(),
                         sProviderHolder.mUri.getAuthority(), CALL_METHOD_RESET_GLOBAL, null, arg);
             } catch (RemoteException e) {
                 Log.w(TAG, "Can't reset do defaults for " + CONTENT_URI, e);
@@ -15795,49 +15875,6 @@
         public static final String SHOW_NEW_NOTIF_DISMISS = "show_new_notif_dismiss";
 
         /**
-         * Whether to enforce the new notification rules (aka rules that are only applied to
-         * notifications from apps targeting S) on all notifications.
-         * - Collapsed custom view notifications will get the new 76dp height instead of 106dp.
-         * - Custom view notifications will be partially decorated.
-         * - Large icons will be given an aspect ratio of up to 16:9.
-         *
-         * Values are:
-         * 0: Disabled (Only apps targeting S will receive the new rules)
-         * 1: Enabled (All apps will receive the new rules)
-         * @hide
-         */
-        @Readable
-        public static final String BACKPORT_S_NOTIF_RULES = "backport_s_notif_rules";
-
-        /**
-         * The decoration to put on fully custom views that target S.
-         *
-         * <p>Values are:
-         * <br>0: DECORATION_NONE: no decorations.
-         * <br>1: DECORATION_MINIMAL: most minimal template; just the icon and the expander.
-         * <br>2: DECORATION_PARTIAL: basic template without the top line.
-         * <br>3: DECORATION_FULL_COMPATIBLE: basic template with the top line; 40dp of height.
-         * <br>4: DECORATION_FULL_CONSTRAINED: basic template with the top line;  28dp of height.
-         * <p>See {@link android.app.Notification.DevFlags} for more details.
-         * @hide
-         */
-        public static final String FULLY_CUSTOM_VIEW_NOTIF_DECORATION =
-                "fully_custom_view_notif_decoration";
-
-        /**
-         * The decoration to put on decorated custom views that target S.
-         *
-         * <p>Values are:
-         * <br>2: DECORATION_PARTIAL: basic template without the top line.
-         * <br>3: DECORATION_FULL_COMPATIBLE: basic template with the top line; 40dp of height.
-         * <br>4: DECORATION_FULL_CONSTRAINED: basic template with the top line;  28dp of height.
-         * <p>See {@link android.app.Notification.DevFlags} for more details.
-         * @hide
-         */
-        public static final String DECORATED_CUSTOM_VIEW_NOTIF_DECORATION =
-                "decorated_custom_view_notif_decoration";
-
-        /**
          * Block untrusted touches mode.
          *
          * Can be one of:
@@ -16038,7 +16075,7 @@
                     arg.putString(Settings.CALL_METHOD_PREFIX_KEY, createPrefix(namespace));
                 }
                 IContentProvider cp = sProviderHolder.getProvider(resolver);
-                cp.call(resolver.getPackageName(), resolver.getAttributionTag(),
+                cp.call(resolver.getAttributionSource(),
                         sProviderHolder.mUri.getAuthority(), CALL_METHOD_RESET_CONFIG, null, arg);
             } catch (RemoteException e) {
                 Log.w(TAG, "Can't reset to defaults for " + DeviceConfig.CONTENT_URI, e);
@@ -16067,7 +16104,7 @@
                 arg.putInt(CALL_METHOD_USER_KEY, userHandle);
                 arg.putParcelable(CALL_METHOD_MONITOR_CALLBACK_KEY, callback);
                 IContentProvider cp = sProviderHolder.getProvider(resolver);
-                cp.call(resolver.getPackageName(), resolver.getAttributionTag(),
+                cp.call(resolver.getAttributionSource(),
                         sProviderHolder.mUri.getAuthority(),
                         CALL_METHOD_REGISTER_MONITOR_CALLBACK_CONFIG, null, arg);
             } catch (RemoteException e) {
diff --git a/core/java/android/provider/TEST_MAPPING b/core/java/android/provider/TEST_MAPPING
index ae2836f..c55572e 100644
--- a/core/java/android/provider/TEST_MAPPING
+++ b/core/java/android/provider/TEST_MAPPING
@@ -19,6 +19,14 @@
         },
         {
             "name": "SettingsProviderTest"
+        },
+        {
+            "name": "CtsAppSecurityHostTestCases",
+            "options": [
+                {
+                    "include-filter": "android.appsecurity.cts.ReadableSettingsFieldsTest"
+                }
+            ]
         }
     ]
 }
diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java
index 374de9c..38945f5 100644
--- a/core/java/android/provider/Telephony.java
+++ b/core/java/android/provider/Telephony.java
@@ -4559,6 +4559,15 @@
         public static final String VOICE_REG_STATE = "voice_reg_state";
 
         /**
+         * An integer value indicating the current data service state.
+         * <p>
+         * Valid values: {@link ServiceState#STATE_IN_SERVICE},
+         * {@link ServiceState#STATE_OUT_OF_SERVICE}, {@link ServiceState#STATE_EMERGENCY_ONLY},
+         * {@link ServiceState#STATE_POWER_OFF}.
+         */
+        public static final String DATA_REG_STATE = "data_reg_state";
+
+        /**
          * The current registered operator numeric id.
          * <p>
          * In GSM/UMTS, numeric format is 3 digit country code plus 2 or 3 digit
@@ -4574,6 +4583,24 @@
          * This is the same as {@link ServiceState#getIsManualSelection()}.
          */
         public static final String IS_MANUAL_NETWORK_SELECTION = "is_manual_network_selection";
+
+        /**
+         * The current data network type.
+         * <p>
+         * This is the same as {@link TelephonyManager#getDataNetworkType()}.
+         */
+        public static final String DATA_NETWORK_TYPE = "data_network_type";
+
+        /**
+         * An integer value indicating the current duplex mode if the radio technology is LTE,
+         * LTE-CA or NR.
+         * <p>
+         * Valid values: {@link ServiceState#DUPLEX_MODE_UNKNOWN},
+         * {@link ServiceState#DUPLEX_MODE_FDD}, {@link ServiceState#DUPLEX_MODE_TDD}.
+         * <p>
+         * This is the same as {@link ServiceState#getDuplexMode()}.
+         */
+        public static final String DUPLEX_MODE = "duplex_mode";
     }
 
     /**
@@ -5317,5 +5344,14 @@
          * @hide
          */
         public static final String COLUMN_D2D_STATUS_SHARING = "d2d_sharing_status";
+
+        /**
+         * TelephonyProvider column name for information selected contacts that allow device to
+         * device sharing.
+         *
+         * @hide
+         */
+        public static final String COLUMN_D2D_STATUS_SHARING_SELECTED_CONTACTS =
+                "d2d_sharing_contacts";
     }
 }
diff --git a/core/java/android/service/autofill/AutofillService.java b/core/java/android/service/autofill/AutofillService.java
index 04a4ca4..13274c6 100644
--- a/core/java/android/service/autofill/AutofillService.java
+++ b/core/java/android/service/autofill/AutofillService.java
@@ -38,6 +38,8 @@
 import android.view.autofill.AutofillManager;
 import android.view.autofill.AutofillValue;
 
+import com.android.internal.os.IResultReceiver;
+
 /**
  * An {@code AutofillService} is a service used to automatically fill the contents of the screen
  * on behalf of a given user - for more information about autofill, read
@@ -575,6 +577,20 @@
      */
     public static final String SERVICE_META_DATA = "android.autofill";
 
+    /**
+     * Name of the {@link IResultReceiver} extra used to return the primary result of a request.
+     *
+     * @hide
+     */
+    public static final String EXTRA_RESULT = "result";
+
+    /**
+     * Name of the {@link IResultReceiver} extra used to return the error reason of a request.
+     *
+     * @hide
+     */
+    public static final String EXTRA_ERROR = "error";
+
     private final IAutoFillService mInterface = new IAutoFillService.Stub() {
         @Override
         public void onConnectedStateChanged(boolean connected) {
@@ -603,6 +619,14 @@
                     AutofillService::onSaveRequest,
                     AutofillService.this, request, new SaveCallback(callback)));
         }
+
+        @Override
+        public void onSavedPasswordCountRequest(IResultReceiver receiver) {
+            mHandler.sendMessage(obtainMessage(
+                    AutofillService::onSavedDatasetsInfoRequest,
+                    AutofillService.this,
+                    new SavedDatasetsInfoCallbackImpl(receiver, SavedDatasetsInfo.TYPE_PASSWORDS)));
+        }
     };
 
     private Handler mHandler;
@@ -673,6 +697,19 @@
             @NonNull SaveCallback callback);
 
     /**
+     * Called from system settings to display information about the datasets the user saved to this
+     * service.
+     *
+     * <p>There is no timeout for the request, but it's recommended to return the result within a
+     * few seconds, or the user may navigate away from the activity that would display the result.
+     *
+     * @param callback callback for responding to the request
+     */
+    public void onSavedDatasetsInfoRequest(@NonNull SavedDatasetsInfoCallback callback) {
+        callback.onError(SavedDatasetsInfoCallback.ERROR_UNSUPPORTED);
+    }
+
+    /**
      * Called when the Android system disconnects from the service.
      *
      * <p> At this point this service may no longer be an active {@link AutofillService}.
diff --git a/core/java/android/service/autofill/IAutoFillService.aidl b/core/java/android/service/autofill/IAutoFillService.aidl
index 23a1a3f..d88e094 100644
--- a/core/java/android/service/autofill/IAutoFillService.aidl
+++ b/core/java/android/service/autofill/IAutoFillService.aidl
@@ -31,4 +31,5 @@
     void onConnectedStateChanged(boolean connected);
     void onFillRequest(in FillRequest request, in IFillCallback callback);
     void onSaveRequest(in SaveRequest request, in ISaveCallback callback);
+    void onSavedPasswordCountRequest(in IResultReceiver receiver);
 }
diff --git a/core/java/android/service/autofill/SavedDatasetsInfo.java b/core/java/android/service/autofill/SavedDatasetsInfo.java
new file mode 100644
index 0000000..6a4d2b8
--- /dev/null
+++ b/core/java/android/service/autofill/SavedDatasetsInfo.java
@@ -0,0 +1,186 @@
+/*
+ * 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 android.service.autofill;
+
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.StringDef;
+
+import com.android.internal.util.DataClass;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * A result returned from
+ * {@link AutofillService#onSavedDatasetsInfoRequest(SavedDatasetsInfoCallback)}.
+ */
+@DataClass(
+        genToString = true,
+        genHiddenConstDefs = true,
+        genEqualsHashCode = true)
+public final class SavedDatasetsInfo {
+
+    /**
+     * Any other type of datasets.
+     */
+    public static final String TYPE_OTHER = "other";
+
+    /**
+     * Datasets such as login credentials.
+     */
+    public static final String TYPE_PASSWORDS = "passwords";
+
+    /**
+     * The type of the datasets that this info is about.
+     */
+    @NonNull
+    @Type
+    private final String mType;
+
+    /**
+     * The number of datasets of {@link #getType() this type} that the user has saved to the
+     * service.
+     */
+    @IntRange(from = 0)
+    private final int mCount;
+
+
+    // Code below generated by codegen v1.0.22.
+    //
+    // DO NOT MODIFY!
+    // CHECKSTYLE:OFF Generated code
+    //
+    // To regenerate run:
+    // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/service/autofill/SavedDatasetsInfo.java
+    //
+    // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
+    //   Settings > Editor > Code Style > Formatter Control
+    //@formatter:off
+
+
+    /** @hide */
+    @StringDef(prefix = "TYPE_", value = {
+        TYPE_OTHER,
+        TYPE_PASSWORDS
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    @DataClass.Generated.Member
+    public @interface Type {}
+
+    /**
+     * Creates a new SavedDatasetsInfo.
+     *
+     * @param type
+     *   The type of the datasets.
+     * @param count
+     *   The number of datasets of this type that the user has saved to the service.
+     */
+    @DataClass.Generated.Member
+    public SavedDatasetsInfo(
+            @NonNull @Type String type,
+            @IntRange(from = 0) int count) {
+        this.mType = type;
+
+        if (!(java.util.Objects.equals(mType, TYPE_OTHER))
+                && !(java.util.Objects.equals(mType, TYPE_PASSWORDS))) {
+            throw new java.lang.IllegalArgumentException(
+                    "type was " + mType + " but must be one of: "
+                            + "TYPE_OTHER(" + TYPE_OTHER + "), "
+                            + "TYPE_PASSWORDS(" + TYPE_PASSWORDS + ")");
+        }
+
+        com.android.internal.util.AnnotationValidations.validate(
+                NonNull.class, null, mType);
+        this.mCount = count;
+        com.android.internal.util.AnnotationValidations.validate(
+                IntRange.class, null, mCount,
+                "from", 0);
+
+        // onConstructed(); // You can define this method to get a callback
+    }
+
+    /**
+     * The type of the datasets.
+     */
+    @DataClass.Generated.Member
+    public @NonNull @Type String getType() {
+        return mType;
+    }
+
+    /**
+     * The number of datasets of this type that the user has saved to the service.
+     */
+    @DataClass.Generated.Member
+    public @IntRange(from = 0) int getCount() {
+        return mCount;
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public String toString() {
+        // You can override field toString logic by defining methods like:
+        // String fieldNameToString() { ... }
+
+        return "SavedDatasetsInfo { " +
+                "type = " + mType + ", " +
+                "count = " + mCount +
+        " }";
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public boolean equals(@android.annotation.Nullable Object o) {
+        // You can override field equality logic by defining either of the methods like:
+        // boolean fieldNameEquals(SavedDatasetsInfo other) { ... }
+        // boolean fieldNameEquals(FieldType otherValue) { ... }
+
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        @SuppressWarnings("unchecked")
+        SavedDatasetsInfo that = (SavedDatasetsInfo) o;
+        //noinspection PointlessBooleanExpression
+        return true
+                && java.util.Objects.equals(mType, that.mType)
+                && mCount == that.mCount;
+    }
+
+    @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 + java.util.Objects.hashCode(mType);
+        _hash = 31 * _hash + mCount;
+        return _hash;
+    }
+
+    @DataClass.Generated(
+            time = 1615325704446L,
+            codegenVersion = "1.0.22",
+            sourceFile = "frameworks/base/core/java/android/service/autofill/SavedDatasetsInfo.java",
+            inputSignatures = "public static final  java.lang.String TYPE_OTHER\npublic static final  java.lang.String TYPE_PASSWORDS\nprivate final @android.annotation.NonNull @android.service.autofill.SavedDatasetsInfo.Type java.lang.String mType\nprivate final @android.annotation.IntRange int mCount\nclass SavedDatasetsInfo extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genToString=true, genHiddenConstDefs=true, genEqualsHashCode=true)")
+    @Deprecated
+    private void __metadata() {}
+
+
+    //@formatter:on
+    // End of generated code
+
+}
diff --git a/core/java/android/service/autofill/SavedDatasetsInfoCallback.java b/core/java/android/service/autofill/SavedDatasetsInfoCallback.java
new file mode 100644
index 0000000..a47105a
--- /dev/null
+++ b/core/java/android/service/autofill/SavedDatasetsInfoCallback.java
@@ -0,0 +1,72 @@
+/*
+ * 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 android.service.autofill;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Set;
+
+/**
+ * Handles the response to
+ * {@link AutofillService#onSavedDatasetsInfoRequest(SavedDatasetsInfoCallback)}.
+ * <p>
+ * Use {@link #onSuccess(Set)} to return the computed info about the datasets the user saved to this
+ * service. If there was an error querying the info, or if the service is unable to do so at this
+ * time (for example, if the user isn't logged in), call {@link #onError(int)}.
+ * <p>
+ * This callback can be used only once.
+ */
+public interface SavedDatasetsInfoCallback {
+
+    /** @hide */
+    @IntDef(prefix = {"ERROR_"}, value = {
+            ERROR_OTHER,
+            ERROR_UNSUPPORTED,
+            ERROR_NEEDS_USER_ACTION
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    @interface Error {
+    }
+
+    /**
+     * The result could not be computed for any other reason.
+     */
+    int ERROR_OTHER = 0;
+    /**
+     * The service does not support this request.
+     */
+    int ERROR_UNSUPPORTED = 1;
+    /**
+     * The result cannot be computed until the user takes some action, such as setting up their
+     * account.
+     */
+    int ERROR_NEEDS_USER_ACTION = 2;
+
+    /**
+     * Successfully respond to the request with the info on each type of saved datasets.
+     */
+    void onSuccess(@NonNull Set<SavedDatasetsInfo> results);
+
+    /**
+     * Respond to the request with an error. System settings may display a suitable notice to the
+     * user.
+     */
+    void onError(@Error int error);
+}
diff --git a/core/java/android/service/autofill/SavedDatasetsInfoCallbackImpl.java b/core/java/android/service/autofill/SavedDatasetsInfoCallbackImpl.java
new file mode 100644
index 0000000..b8a8cde
--- /dev/null
+++ b/core/java/android/service/autofill/SavedDatasetsInfoCallbackImpl.java
@@ -0,0 +1,93 @@
+/*
+ * 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 android.service.autofill;
+
+import static android.service.autofill.AutofillService.EXTRA_ERROR;
+import static android.service.autofill.AutofillService.EXTRA_RESULT;
+
+import static com.android.internal.util.Preconditions.checkArgumentInRange;
+
+import static java.util.Objects.requireNonNull;
+
+import android.annotation.NonNull;
+import android.os.Bundle;
+import android.os.DeadObjectException;
+import android.os.RemoteException;
+import android.util.Log;
+
+import com.android.internal.os.IResultReceiver;
+
+import java.util.Set;
+
+final class SavedDatasetsInfoCallbackImpl implements SavedDatasetsInfoCallback {
+    private static final String TAG = "AutofillService";
+
+    @NonNull
+    private final IResultReceiver mReceiver;
+    @NonNull
+    private final String mType;
+
+    /**
+     * Creates a {@link SavedDatasetsInfoCallback} that returns the {@link
+     * SavedDatasetsInfo#getCount() number} of saved datasets of {@code type} to the {@code
+     * receiver}.
+     */
+    SavedDatasetsInfoCallbackImpl(@NonNull IResultReceiver receiver, @NonNull String type) {
+        mReceiver = requireNonNull(receiver);
+        mType = requireNonNull(type);
+    }
+
+    @Override
+    public void onSuccess(@NonNull Set<SavedDatasetsInfo> results) {
+        requireNonNull(results);
+        if (results.isEmpty()) {
+            send(1, null);
+            return;
+        }
+        int count = -1;
+        for (SavedDatasetsInfo info : results) {
+            if (mType.equals(info.getType())) {
+                count = info.getCount();
+            }
+        }
+        if (count < 0) {
+            send(1, null);
+            return;
+        }
+        Bundle bundle = new Bundle(/* capacity= */ 1);
+        bundle.putInt(EXTRA_RESULT, count);
+        send(0, bundle);
+    }
+
+    @Override
+    public void onError(@Error int error) {
+        checkArgumentInRange(error, ERROR_OTHER, ERROR_NEEDS_USER_ACTION, "error");
+        Bundle bundle = new Bundle(/* capacity= */ 1);
+        bundle.putInt(EXTRA_ERROR, error);
+        send(1, bundle);
+    }
+
+    private void send(int resultCode, Bundle bundle) {
+        try {
+            mReceiver.send(resultCode, bundle);
+        } catch (DeadObjectException e) {
+            Log.w(TAG, "Failed to send onSavedPasswordCountRequest result: " + e);
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+}
diff --git a/core/java/android/service/autofill/augmented/AugmentedAutofillService.java b/core/java/android/service/autofill/augmented/AugmentedAutofillService.java
index aeeaa97..d9a310f 100644
--- a/core/java/android/service/autofill/augmented/AugmentedAutofillService.java
+++ b/core/java/android/service/autofill/augmented/AugmentedAutofillService.java
@@ -618,7 +618,7 @@
                         mFirstOnSuccessTime = SystemClock.elapsedRealtime();
                         duration = mFirstOnSuccessTime - mFirstRequestTime;
                         if (sDebug) {
-                            Log.d(TAG, "Service responded nothing in " + formatDuration(duration));
+                            Log.d(TAG, "Inline response in " + formatDuration(duration));
                         }
                     }
                 } break;
diff --git a/core/java/android/service/dataloader/DataLoaderService.java b/core/java/android/service/dataloader/DataLoaderService.java
index ad6316c..3ad80d3 100644
--- a/core/java/android/service/dataloader/DataLoaderService.java
+++ b/core/java/android/service/dataloader/DataLoaderService.java
@@ -19,7 +19,6 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
-import android.annotation.SystemApi;
 import android.app.Service;
 import android.content.Intent;
 import android.content.pm.DataLoaderParams;
@@ -41,25 +40,15 @@
 
 /**
  * The base class for implementing data loader service to control data loaders. Expecting
- * Incremental Service to bind to a children class of this.
- *
- * WARNING: This is a system API to aid internal development.
- * Use at your own risk. It will change or be removed without warning.
- *
- * TODO(b/136132412): update with latest API design
- *
- * @hide
+ * Installation Session to bind to a children class of this.
  */
-@SystemApi
 public abstract class DataLoaderService extends Service {
     private static final String TAG = "DataLoaderService";
     private final DataLoaderBinderService mBinder = new DataLoaderBinderService();
 
     /**
      * Managed DataLoader interface. Each instance corresponds to a single installation session.
-     * @hide
      */
-    @SystemApi
     public interface DataLoader {
         /**
          * A virtual constructor.
@@ -88,9 +77,7 @@
      * DataLoader factory method.
      *
      * @return An instance of a DataLoader.
-     * @hide
      */
-    @SystemApi
     public @Nullable DataLoader onCreateDataLoader(@NonNull DataLoaderParams dataLoaderParams) {
         return null;
     }
@@ -156,10 +143,7 @@
 
     /**
      * Used by the DataLoaderService implementations.
-     *
-     * @hide
      */
-    @SystemApi
     public static final class FileSystemConnector {
         /**
          * Create a wrapper for a native instance.
diff --git a/core/java/android/service/displayhash/DisplayHasherService.java b/core/java/android/service/displayhash/DisplayHasherService.java
index 2105d84..d300cf1 100644
--- a/core/java/android/service/displayhash/DisplayHasherService.java
+++ b/core/java/android/service/displayhash/DisplayHasherService.java
@@ -52,6 +52,16 @@
             "android.service.displayhash.extra.VERIFIED_DISPLAY_HASH";
 
     /**
+     * Name under which a DisplayHasherService component publishes information
+     * about itself.  This meta-data must reference an XML resource containing a
+     * {@link com.android.internal.R.styleable#DisplayHasherService} tag.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String SERVICE_META_DATA = "android.displayhash.display_hasher_service";
+
+    /**
      * The {@link Intent} action that must be declared as handled by a service in its manifest
      * for the system to recognize it as a DisplayHash providing service.
      *
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index bf5f24d..09c3b2e 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -251,6 +251,10 @@
     public static final int REASON_SNOOZED = 18;
     /** Notification was canceled due to timeout */
     public static final int REASON_TIMEOUT = 19;
+    /** Notification was canceled due to the backing channel being deleted */
+    public static final int REASON_CHANNEL_REMOVED = 20;
+    /** Notification was canceled due to the app's storage being cleared */
+    public static final int REASON_CLEAR_DATA = 21;
 
     /**
      * @hide
diff --git a/core/java/android/service/notification/ScheduleCalendar.java b/core/java/android/service/notification/ScheduleCalendar.java
index 6ed966e..314c97d 100644
--- a/core/java/android/service/notification/ScheduleCalendar.java
+++ b/core/java/android/service/notification/ScheduleCalendar.java
@@ -57,25 +57,18 @@
     }
 
     /**
-     * Sets next alarm of the schedule if the saved next alarm has passed or is further
-     * in the future than given nextAlarm
+     * Sets next alarm of the schedule
      * @param now current time in milliseconds
      * @param nextAlarm time of next alarm in milliseconds
      */
     public void maybeSetNextAlarm(long now, long nextAlarm) {
         if (mSchedule != null && mSchedule.exitAtAlarm) {
-            // alarm canceled
             if (nextAlarm == 0) {
+                // alarm canceled
                 mSchedule.nextAlarm = 0;
-            }
-            // only allow alarms in the future
-            if (nextAlarm > now) {
-                if (mSchedule.nextAlarm == 0 || mSchedule.nextAlarm < now) {
-                    mSchedule.nextAlarm = nextAlarm;
-                } else {
-                    // store earliest alarm
-                    mSchedule.nextAlarm = Math.min(mSchedule.nextAlarm, nextAlarm);
-                }
+            } else if (nextAlarm > now) {
+                // only allow alarms in the future
+                mSchedule.nextAlarm = nextAlarm;
             } else if (mSchedule.nextAlarm < now) {
                 if (DEBUG) {
                     Log.d(TAG, "All alarms are in the past " + mSchedule.nextAlarm);
diff --git a/core/java/android/service/storage/ExternalStorageService.java b/core/java/android/service/storage/ExternalStorageService.java
index da1f457..05f37d7 100644
--- a/core/java/android/service/storage/ExternalStorageService.java
+++ b/core/java/android/service/storage/ExternalStorageService.java
@@ -175,7 +175,7 @@
      *
      * @param packageName the package name of the ANR'ing app
      * @param uid the uid of the ANR'ing app
-     * @param tid the tid of the ANR'ing app
+     * @param tid the thread id of the ANR'ing app
      * @param reason the reason the app is ANR'ing
      */
     public void onAnrDelayStarted(@NonNull String packageName, int uid, int tid,
diff --git a/core/java/android/service/translation/ITranslationCallback.aidl b/core/java/android/service/translation/ITranslationCallback.aidl
index 333cb57..893c9d0 100644
--- a/core/java/android/service/translation/ITranslationCallback.aidl
+++ b/core/java/android/service/translation/ITranslationCallback.aidl
@@ -24,6 +24,6 @@
  * @hide
  */
 oneway interface ITranslationCallback {
-    void onTranslationComplete(in TranslationResponse translationResponse);
+    void onTranslationResponse(in TranslationResponse translationResponse);
     void onError();
 }
diff --git a/core/java/android/service/translation/ITranslationService.aidl b/core/java/android/service/translation/ITranslationService.aidl
index 8d798c3..297f00a4 100644
--- a/core/java/android/service/translation/ITranslationService.aidl
+++ b/core/java/android/service/translation/ITranslationService.aidl
@@ -16,7 +16,8 @@
 
 package android.service.translation;
 
-import android.view.translation.TranslationSpec;
+import android.os.ResultReceiver;
+import android.view.translation.TranslationContext;
 import com.android.internal.os.IResultReceiver;
 
 /**
@@ -31,6 +32,9 @@
 oneway interface ITranslationService {
     void onConnected();
     void onDisconnected();
-    void onCreateTranslationSession(in TranslationSpec sourceSpec, in TranslationSpec destSpec,
-         int sessionId, in IResultReceiver receiver);
+    void onCreateTranslationSession(in TranslationContext translationContext, int sessionId,
+         in IResultReceiver receiver);
+
+    void onTranslationCapabilitiesRequest(int sourceFormat, int targetFormat,
+         in ResultReceiver receiver);
 }
diff --git a/core/java/android/service/translation/OnTranslationResultCallbackWrapper.java b/core/java/android/service/translation/OnTranslationResultCallbackWrapper.java
index 345c69c..10a2aa2 100644
--- a/core/java/android/service/translation/OnTranslationResultCallbackWrapper.java
+++ b/core/java/android/service/translation/OnTranslationResultCallbackWrapper.java
@@ -51,12 +51,12 @@
     @Override
     public void onTranslationSuccess(@Nullable TranslationResponse response) {
         assertNotCalled();
-        if (mCalled.getAndSet(true)) {
-            throw new IllegalStateException("Already called");
+        if (mCalled.getAndSet(response.isFinalResponse())) {
+            throw new IllegalStateException("Already called with complete response");
         }
 
         try {
-            mCallback.onTranslationComplete(response);
+            mCallback.onTranslationResponse(response);
         } catch (RemoteException e) {
             if (e instanceof DeadObjectException) {
                 Log.w(TAG, "Process is dead, ignore.");
diff --git a/core/java/android/service/translation/TranslationService.java b/core/java/android/service/translation/TranslationService.java
index d14a87f..7edf2e2 100644
--- a/core/java/android/service/translation/TranslationService.java
+++ b/core/java/android/service/translation/TranslationService.java
@@ -34,15 +34,21 @@
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.RemoteException;
+import android.os.ResultReceiver;
+import android.util.ArraySet;
 import android.util.Log;
 import android.view.translation.ITranslationDirectManager;
+import android.view.translation.TranslationCapability;
+import android.view.translation.TranslationContext;
 import android.view.translation.TranslationManager;
 import android.view.translation.TranslationRequest;
 import android.view.translation.TranslationResponse;
 import android.view.translation.TranslationSpec;
 
 import com.android.internal.os.IResultReceiver;
-import com.android.internal.util.SyncResultReceiver;
+
+import java.util.Set;
+import java.util.function.Consumer;
 
 /**
  * Service for translating text.
@@ -93,10 +99,20 @@
         }
 
         @Override
-        public void onCreateTranslationSession(TranslationSpec sourceSpec, TranslationSpec destSpec,
+        public void onCreateTranslationSession(TranslationContext translationContext,
                 int sessionId, IResultReceiver receiver) throws RemoteException {
             mHandler.sendMessage(obtainMessage(TranslationService::handleOnCreateTranslationSession,
-                    TranslationService.this, sourceSpec, destSpec, sessionId, receiver));
+                    TranslationService.this, translationContext, sessionId, receiver));
+        }
+
+        @Override
+        public void onTranslationCapabilitiesRequest(@TranslationSpec.DataFormat int sourceFormat,
+                @TranslationSpec.DataFormat int targetFormat,
+                @NonNull ResultReceiver resultReceiver) throws RemoteException {
+            mHandler.sendMessage(
+                    obtainMessage(TranslationService::handleOnTranslationCapabilitiesRequest,
+                            TranslationService.this, sourceFormat, targetFormat,
+                            resultReceiver));
         }
     };
 
@@ -139,30 +155,10 @@
 
                 @Override
                 public void onTranslationRequest(TranslationRequest request, int sessionId,
-                        ITranslationCallback callback, IResultReceiver receiver)
+                        ITranslationCallback callback)
                         throws RemoteException {
-                    // TODO(b/176464808): Currently, the API is used for both sync and async case.
-                    // It may work now, but maybe two methods is more cleaner. To think how to
-                    // define the APIs for these two cases.
-                    final ITranslationCallback cb = callback != null
-                            ? callback
-                            : new ITranslationCallback.Stub() {
-                                @Override
-                                public void onTranslationComplete(
-                                        TranslationResponse translationResponse)
-                                        throws RemoteException {
-                                    receiver.send(0,
-                                            SyncResultReceiver.bundleFor(translationResponse));
-                                }
-
-                                @Override
-                                public void onError() throws RemoteException {
-                                    //TODO: implement default error callback
-                                }
-                            };
-                    // TODO(b/176464808): make it a private member of client
                     final OnTranslationResultCallback translationResultCallback =
-                            new OnTranslationResultCallbackWrapper(cb);
+                            new OnTranslationResultCallbackWrapper(callback);
                     mHandler.sendMessage(obtainMessage(TranslationService::onTranslationRequest,
                             TranslationService.this, request, sessionId, mCancellationSignal,
                             translationResultCallback));
@@ -215,14 +211,13 @@
     /**
      * TODO: fill in javadoc.
      *
-     * @param sourceSpec
-     * @param destSpec
+     * @param translationContext
      * @param sessionId
      */
     // TODO(b/176464808): the session id won't be unique cross client/server process. Need to find
     // solution to make it's safe.
-    public abstract void onCreateTranslationSession(@NonNull TranslationSpec sourceSpec,
-            @NonNull TranslationSpec destSpec, int sessionId);
+    public abstract void onCreateTranslationSession(@NonNull TranslationContext translationContext,
+            int sessionId);
 
     /**
      * TODO: fill in javadoc.
@@ -243,12 +238,27 @@
             @NonNull CancellationSignal cancellationSignal,
             @NonNull OnTranslationResultCallback callback);
 
+    /**
+     * TODO: fill in javadoc
+     * TODO: make this abstract again once aiai is ready.
+     *
+     * <p>Must call {@code callback.accept} to pass back the set of translation capabilities.</p>
+     *
+     * @param sourceFormat
+     * @param targetFormat
+     * @param callback
+     */
+    public abstract void onTranslationCapabilitiesRequest(
+            @TranslationSpec.DataFormat int sourceFormat,
+            @TranslationSpec.DataFormat int targetFormat,
+            @NonNull Consumer<Set<TranslationCapability>> callback);
+
     // TODO(b/176464808): Need to handle client dying case
 
-    // TODO(b/176464808): Need to handle the failure case. e.g. if the specs does not support
+    // TODO(b/176464808): Need to handle the failure case. e.g. if the context is not supported.
 
-    private void handleOnCreateTranslationSession(@NonNull TranslationSpec sourceSpec,
-            @NonNull TranslationSpec destSpec, int sessionId, IResultReceiver resultReceiver) {
+    private void handleOnCreateTranslationSession(@NonNull TranslationContext translationContext,
+            int sessionId, IResultReceiver resultReceiver) {
         try {
             final Bundle extras = new Bundle();
             extras.putBinder(EXTRA_SERVICE_BINDER, mClientInterface.asBinder());
@@ -257,6 +267,24 @@
         } catch (RemoteException e) {
             Log.w(TAG, "RemoteException sending client interface: " + e);
         }
-        onCreateTranslationSession(sourceSpec, destSpec, sessionId);
+        onCreateTranslationSession(translationContext, sessionId);
+    }
+
+    private void handleOnTranslationCapabilitiesRequest(
+            @TranslationSpec.DataFormat int sourceFormat,
+            @TranslationSpec.DataFormat int targetFormat,
+            @NonNull ResultReceiver resultReceiver) {
+        onTranslationCapabilitiesRequest(sourceFormat, targetFormat,
+                new Consumer<Set<TranslationCapability>>() {
+                    @Override
+                    public void accept(Set<TranslationCapability> values) {
+                        final ArraySet<TranslationCapability> capabilities = new ArraySet<>(values);
+                        final Bundle bundle = new Bundle();
+                        bundle.putParcelableArray(TranslationManager.EXTRA_CAPABILITIES,
+                                capabilities.toArray(new TranslationCapability[0]));
+                        resultReceiver.send(TranslationManager.STATUS_SYNC_CALL_SUCCESS, bundle);
+                    }
+                });
+
     }
 }
diff --git a/core/java/android/service/translation/TranslationServiceInfo.java b/core/java/android/service/translation/TranslationServiceInfo.java
index 18cc29d..c7017b2 100644
--- a/core/java/android/service/translation/TranslationServiceInfo.java
+++ b/core/java/android/service/translation/TranslationServiceInfo.java
@@ -100,9 +100,9 @@
         if (!Manifest.permission.BIND_TRANSLATION_SERVICE.equals(si.permission)) {
             Slog.w(TAG, "TranslationServiceInfo from '" + si.packageName
                     + "' does not require permission "
-                    + Manifest.permission.BIND_CONTENT_CAPTURE_SERVICE);
+                    + Manifest.permission.BIND_TRANSLATION_SERVICE);
             throw new SecurityException("Service does not require permission "
-                    + Manifest.permission.BIND_CONTENT_CAPTURE_SERVICE);
+                    + Manifest.permission.BIND_TRANSLATION_SERVICE);
         }
 
         mServiceInfo = si;
diff --git a/core/java/android/service/voice/AbstractHotwordDetector.java b/core/java/android/service/voice/AbstractHotwordDetector.java
new file mode 100644
index 0000000..e4eefc4
--- /dev/null
+++ b/core/java/android/service/voice/AbstractHotwordDetector.java
@@ -0,0 +1,105 @@
+/*
+ * 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 android.service.voice;
+
+import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.media.AudioFormat;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.ParcelFileDescriptor;
+import android.os.PersistableBundle;
+import android.os.RemoteException;
+import android.util.Slog;
+
+import com.android.internal.app.IVoiceInteractionManagerService;
+
+/** Base implementation of {@link HotwordDetector}. */
+abstract class AbstractHotwordDetector implements HotwordDetector {
+    private static final String TAG = AbstractHotwordDetector.class.getSimpleName();
+    private static final boolean DEBUG = false;
+
+    private final IVoiceInteractionManagerService mManagerService;
+    private final Handler mHandler;
+    private final HotwordDetector.Callback mCallback;
+
+    AbstractHotwordDetector(
+            IVoiceInteractionManagerService managerService,
+            HotwordDetector.Callback callback) {
+        mManagerService = managerService;
+        // TODO: this needs to be supplied from above
+        mHandler = new Handler(Looper.getMainLooper());
+        mCallback = callback;
+    }
+
+    /**
+     * Detect hotword from an externally supplied stream of data.
+     *
+     * @return a writeable file descriptor that clients can start writing data in the given format.
+     * In order to stop detection, clients can close the given stream.
+     */
+    @Nullable
+    @Override
+    public boolean startRecognition(
+            @NonNull ParcelFileDescriptor audioStream,
+            @NonNull AudioFormat audioFormat,
+            @Nullable PersistableBundle options) {
+        if (DEBUG) {
+            Slog.i(TAG, "#recognizeHotword");
+        }
+
+        // TODO: consider closing existing session.
+
+        try {
+            mManagerService.startListeningFromExternalSource(
+                    audioStream,
+                    audioFormat,
+                    options,
+                    new BinderCallback(mHandler, mCallback));
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+
+        return true;
+    }
+
+    private static class BinderCallback
+            extends IMicrophoneHotwordDetectionVoiceInteractionCallback.Stub {
+        private final Handler mHandler;
+        // TODO: these need to be weak references.
+        private final HotwordDetector.Callback mCallback;
+
+        BinderCallback(Handler handler, HotwordDetector.Callback callback) {
+            this.mHandler = handler;
+            this.mCallback = callback;
+        }
+
+        /** TODO: onDetected */
+        @Override
+        public void onDetected(
+                @Nullable HotwordDetectedResult hotwordDetectedResult,
+                @Nullable AudioFormat audioFormat,
+                @Nullable ParcelFileDescriptor audioStreamIgnored) {
+            mHandler.sendMessage(obtainMessage(
+                    HotwordDetector.Callback::onDetected,
+                    mCallback,
+                    new AlwaysOnHotwordDetector.EventPayload(audioFormat, hotwordDetectedResult)));
+        }
+    }
+}
diff --git a/core/java/android/service/voice/AlwaysOnHotwordDetector.java b/core/java/android/service/voice/AlwaysOnHotwordDetector.java
index def13db..8ca0e7c 100644
--- a/core/java/android/service/voice/AlwaysOnHotwordDetector.java
+++ b/core/java/android/service/voice/AlwaysOnHotwordDetector.java
@@ -41,12 +41,14 @@
 import android.os.AsyncTask;
 import android.os.Binder;
 import android.os.Build;
-import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Message;
+import android.os.ParcelFileDescriptor;
+import android.os.PersistableBundle;
 import android.os.RemoteException;
 import android.os.SharedMemory;
+import android.service.voice.HotwordDetectionService.InitializationStatus;
 import android.util.Slog;
 
 import com.android.internal.app.IHotwordRecognitionStatusCallback;
@@ -67,7 +69,7 @@
  *                    mark and track it as such.
  */
 @SystemApi
-public class AlwaysOnHotwordDetector {
+public class AlwaysOnHotwordDetector extends AbstractHotwordDetector {
     //---- States of Keyphrase availability. Return codes for onAvailabilityChanged() ----//
     /**
      * Indicates that this hotword detector is no longer valid for any recognition
@@ -239,18 +241,6 @@
     public @interface ModelParams {}
 
     /**
-     * Indicates that the given audio data is a false alert for {@link VoiceInteractionService}.
-     */
-    public static final int HOTWORD_DETECTION_FALSE_ALERT = 0;
-
-    /** @hide */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(flag = true, prefix = { "HOTWORD_DETECTION_" }, value = {
-            HOTWORD_DETECTION_FALSE_ALERT,
-    })
-    public @interface HotwordDetectionResult {}
-
-    /**
      * Controls the sensitivity threshold adjustment factor for a given model.
      * Negative value corresponds to less sensitive model (high threshold) and
      * a positive value corresponds to a more sensitive model (low threshold).
@@ -271,6 +261,7 @@
     private static final int MSG_DETECTION_PAUSE = 4;
     private static final int MSG_DETECTION_RESUME = 5;
     private static final int MSG_HOTWORD_REJECTED = 6;
+    private static final int MSG_HOTWORD_STATUS_REPORTED = 7;
 
     private final String mText;
     private final Locale mLocale;
@@ -354,14 +345,35 @@
         // Raw data associated with the event.
         // This is the audio that triggered the keyphrase if {@code isTriggerAudio} is true.
         private final byte[] mData;
+        private final HotwordDetectedResult mHotwordDetectedResult;
+        private final ParcelFileDescriptor mAudioStream;
 
         private EventPayload(boolean triggerAvailable, boolean captureAvailable,
                 AudioFormat audioFormat, int captureSession, byte[] data) {
+            this(triggerAvailable, captureAvailable, audioFormat, captureSession, data, null,
+                    null);
+        }
+
+        EventPayload(AudioFormat audioFormat, HotwordDetectedResult hotwordDetectedResult) {
+            this(false, false, audioFormat, -1, null, hotwordDetectedResult, null);
+        }
+
+        EventPayload(AudioFormat audioFormat,
+                HotwordDetectedResult hotwordDetectedResult,
+                ParcelFileDescriptor audioStream) {
+            this(false, false, audioFormat, -1, null, hotwordDetectedResult, audioStream);
+        }
+
+        private EventPayload(boolean triggerAvailable, boolean captureAvailable,
+                AudioFormat audioFormat, int captureSession, byte[] data,
+                HotwordDetectedResult hotwordDetectedResult, ParcelFileDescriptor audioStream) {
             mTriggerAvailable = triggerAvailable;
             mCaptureAvailable = captureAvailable;
             mCaptureSession = captureSession;
             mAudioFormat = audioFormat;
             mData = data;
+            mHotwordDetectedResult = hotwordDetectedResult;
+            mAudioStream = audioStream;
         }
 
         /**
@@ -417,12 +429,39 @@
                 return null;
             }
         }
+
+        /**
+         * Returns {@link HotwordDetectedResult} associated with the hotword event, passed from
+         * {@link HotwordDetectionService}.
+         */
+        @Nullable
+        public HotwordDetectedResult getHotwordDetectedResult() {
+            return mHotwordDetectedResult;
+        }
+
+        /**
+         * Returns a stream with bytes corresponding to the open audio stream with hotword data.
+         *
+         * <p>This data represents an audio stream in the format returned by
+         * {@link #getCaptureAudioFormat}.
+         *
+         * <p>Clients are expected to start consuming the stream within 1 second of receiving the
+         * event.
+         *
+         * <p>When this method returns a non-null, clients must close this stream when it's no
+         * longer needed. Failing to do so will result in microphone being open for longer periods
+         * of time, and app being attributed for microphone usage.
+         */
+        @Nullable
+        public ParcelFileDescriptor getAudioStream() {
+            return mAudioStream;
+        }
     }
 
     /**
      * Callbacks for always-on hotword detection.
      */
-    public static abstract class Callback {
+    public abstract static class Callback implements HotwordDetector.Callback {
 
         /**
          * Updates the availability state of the active keyphrase and locale on every keyphrase
@@ -478,11 +517,23 @@
         public abstract void onRecognitionResumed();
 
         /**
-         * Called when the validated result is invalid.
+         * Called when the {@link HotwordDetectionService second stage detection} did not detect the
+         * keyphrase.
          *
-         * @param reason The reason why the validated result is invalid.
+         * @param result Info about the second stage detection result, provided by the
+         *         {@link HotwordDetectionService}.
          */
-        public void onRejected(@HotwordDetectionResult int reason) {}
+        public void onRejected(@Nullable HotwordRejectedResult result) {
+        }
+
+        /**
+         * Called when the {@link HotwordDetectionService} is created by the system and given a
+         * short amount of time to report it's initialization state.
+         *
+         * @param status Info about initialization state of {@link HotwordDetectionService}.
+         */
+        public void onHotwordDetectionServiceInitialized(@InitializationStatus int status) {
+        }
     }
 
     /**
@@ -494,8 +545,8 @@
      * @param supportHotwordDetectionService {@code true} if hotword detection service should be
      * triggered, otherwise {@code false}.
      * @param options Application configuration data provided by the
-     * {@link VoiceInteractionService}. The system strips out any remotable objects or other
-     * contents that can be used to communicate with other processes.
+     * {@link VoiceInteractionService}. PersistableBundle does not allow any remotable objects or
+     * other contents that can be used to communicate with other processes.
      * @param sharedMemory The unrestricted data blob provided by the
      * {@link VoiceInteractionService}. Use this to provide the hotword models data or other
      * such data to the trusted process.
@@ -505,19 +556,21 @@
     public AlwaysOnHotwordDetector(String text, Locale locale, Callback callback,
             KeyphraseEnrollmentInfo keyphraseEnrollmentInfo,
             IVoiceInteractionManagerService modelManagementService, int targetSdkVersion,
-            boolean supportHotwordDetectionService, @Nullable Bundle options,
+            boolean supportHotwordDetectionService, @Nullable PersistableBundle options,
             @Nullable SharedMemory sharedMemory) {
+        super(modelManagementService, callback);
+
+        mHandler = new MyHandler();
         mText = text;
         mLocale = locale;
         mKeyphraseEnrollmentInfo = keyphraseEnrollmentInfo;
         mExternalCallback = callback;
-        mHandler = new MyHandler();
         mInternalCallback = new SoundTriggerListener(mHandler);
         mModelManagementService = modelManagementService;
         mTargetSdkVersion = targetSdkVersion;
         mSupportHotwordDetectionService = supportHotwordDetectionService;
         if (mSupportHotwordDetectionService) {
-            setHotwordDetectionServiceConfig(options, sharedMemory);
+            updateStateLocked(options, sharedMemory, mInternalCallback);
         }
         try {
             Identity identity = new Identity();
@@ -533,30 +586,42 @@
     /**
      * Set configuration and pass read-only data to hotword detection service.
      *
-     * @param options Application configuration data provided by the
-     * {@link VoiceInteractionService}. The system strips out any remotable objects or other
-     * contents that can be used to communicate with other processes.
-     * @param sharedMemory The unrestricted data blob provided by the
-     * {@link VoiceInteractionService}. Use this to provide the hotword models data or other
+     * @param options Application configuration data to provide to the
+     * {@link HotwordDetectionService}. PersistableBundle does not allow any remotable objects or
+     * other contents that can be used to communicate with other processes.
+     * @param sharedMemory The unrestricted data blob to provide to the
+     * {@link HotwordDetectionService}. Use this to provide the hotword models data or other
      * such data to the trusted process.
      *
-     * @throws IllegalStateException if it doesn't support hotword detection service.
-     *
-     * @hide
+     * @throws IllegalStateException if this AlwaysOnHotwordDetector wasn't specified to use a
+     * {@link HotwordDetectionService} when it was created. In addition, if this
+     * AlwaysOnHotwordDetector is in an invalid or error state.
      */
-    public final void setHotwordDetectionServiceConfig(@Nullable Bundle options,
+    public final void updateState(@Nullable PersistableBundle options,
             @Nullable SharedMemory sharedMemory) {
         if (DBG) {
-            Slog.d(TAG, "setHotwordDetectionServiceConfig()");
+            Slog.d(TAG, "updateState()");
         }
-        if (!mSupportHotwordDetectionService) {
-            throw new IllegalStateException(
-                    "setHotwordDetectionServiceConfig called, but it doesn't support hotword"
-                            + " detection service");
+        synchronized (mLock) {
+            if (!mSupportHotwordDetectionService) {
+                throw new IllegalStateException(
+                        "updateState called, but it doesn't support hotword detection service");
+            }
+            if (mAvailability == STATE_INVALID || mAvailability == STATE_ERROR) {
+                throw new IllegalStateException(
+                        "updateState called on an invalid detector or error state");
+            }
+            updateStateLocked(options, sharedMemory, null /* callback */);
         }
+    }
 
+    private void updateStateLocked(@Nullable PersistableBundle options,
+            @Nullable SharedMemory sharedMemory, IHotwordRecognitionStatusCallback callback) {
+        if (DBG) {
+            Slog.d(TAG, "updateStateLocked()");
+        }
         try {
-            mModelManagementService.setHotwordDetectionServiceConfig(options, sharedMemory);
+            mModelManagementService.updateState(options, sharedMemory, callback);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -667,6 +732,17 @@
     }
 
     /**
+     * Starts recognition for the associated keyphrase.
+     *
+     * @see #startRecognition(int)
+     */
+    @RequiresPermission(allOf = {RECORD_AUDIO, CAPTURE_AUDIO_HOTWORD})
+    @Override
+    public boolean startRecognition() {
+        return startRecognition(0);
+    }
+
+    /**
      * Stops recognition for the associated keyphrase.
      * Caller must be the active voice interaction service via
      * Settings.Secure.VOICE_INTERACTION_SERVICE.
@@ -680,6 +756,7 @@
      *         {@link VoiceInteractionService} hosting this detector has been shut down.
      */
     @RequiresPermission(allOf = {RECORD_AUDIO, CAPTURE_AUDIO_HOTWORD})
+    @Override
     public boolean stopRecognition() {
         if (DBG) Slog.d(TAG, "stopRecognition()");
         synchronized (mLock) {
@@ -1069,13 +1146,13 @@
         }
 
         @Override
-        public void onRejected(int reason) {
+        public void onRejected(HotwordRejectedResult result) {
             if (DBG) {
-                Slog.d(TAG, "onRejected(" + reason + ")");
+                Slog.d(TAG, "onRejected(" + result + ")");
             } else {
                 Slog.i(TAG, "onRejected");
             }
-            Message.obtain(mHandler, MSG_HOTWORD_REJECTED, reason).sendToTarget();
+            Message.obtain(mHandler, MSG_HOTWORD_REJECTED, result).sendToTarget();
         }
 
         @Override
@@ -1095,6 +1172,18 @@
             Slog.i(TAG, "onRecognitionResumed");
             mHandler.sendEmptyMessage(MSG_DETECTION_RESUME);
         }
+
+        @Override
+        public void onStatusReported(int status) {
+            if (DBG) {
+                Slog.d(TAG, "onStatusReported(" + status + ")");
+            } else {
+                Slog.i(TAG, "onStatusReported");
+            }
+            Message message = Message.obtain(mHandler, MSG_HOTWORD_STATUS_REPORTED);
+            message.arg1 = status;
+            message.sendToTarget();
+        }
     }
 
     class MyHandler extends Handler {
@@ -1124,7 +1213,10 @@
                     mExternalCallback.onRecognitionResumed();
                     break;
                 case MSG_HOTWORD_REJECTED:
-                    mExternalCallback.onRejected(msg.arg1);
+                    mExternalCallback.onRejected((HotwordRejectedResult) msg.obj);
+                    break;
+                case MSG_HOTWORD_STATUS_REPORTED:
+                    mExternalCallback.onHotwordDetectionServiceInitialized(msg.arg1);
                     break;
                 default:
                     super.handleMessage(msg);
diff --git a/core/java/android/service/voice/HotwordDetectionService.java b/core/java/android/service/voice/HotwordDetectionService.java
index fcef26f..7c14c2e 100644
--- a/core/java/android/service/voice/HotwordDetectionService.java
+++ b/core/java/android/service/voice/HotwordDetectionService.java
@@ -20,6 +20,7 @@
 
 import android.annotation.CallSuper;
 import android.annotation.DurationMillisLong;
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SdkConstant;
@@ -27,16 +28,22 @@
 import android.app.Service;
 import android.content.Intent;
 import android.media.AudioFormat;
-import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.ParcelFileDescriptor;
+import android.os.PersistableBundle;
 import android.os.RemoteException;
 import android.os.SharedMemory;
 import android.util.Log;
 
+import com.android.internal.app.IHotwordRecognitionStatusCallback;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.Locale;
+import java.util.function.IntConsumer;
 
 /**
  * Implemented by an application that wants to offer detection for hotword. The system will
@@ -50,6 +57,57 @@
     // TODO (b/177502877): Set the Debug flag to false before shipping.
     private static final boolean DBG = true;
 
+    private static final long UPDATE_TIMEOUT_MILLIS = 5000;
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(flag = true, prefix = { "INITIALIZATION_STATUS_" }, value = {
+            INITIALIZATION_STATUS_SUCCESS,
+            INITIALIZATION_STATUS_CUSTOM_ERROR_1,
+            INITIALIZATION_STATUS_CUSTOM_ERROR_2,
+            INITIALIZATION_STATUS_UNKNOWN,
+    })
+    public @interface InitializationStatus {}
+
+    /**
+     * Indicates that the updated status is successful.
+     */
+    public static final int INITIALIZATION_STATUS_SUCCESS = 0;
+
+    /**
+     * Indicates that the updated status is failure for some application specific reasons.
+     */
+    public static final int INITIALIZATION_STATUS_CUSTOM_ERROR_1 = 1;
+
+    /**
+     * Indicates that the updated status is failure for some application specific reasons.
+     */
+    public static final int INITIALIZATION_STATUS_CUSTOM_ERROR_2 = 2;
+
+    /**
+     * Indicates that the callback wasn’t invoked within the timeout.
+     * This is used by system.
+     */
+    public static final int INITIALIZATION_STATUS_UNKNOWN = 100;
+
+    /**
+     * Source for the given audio stream.
+     *
+     * @hide
+     */
+    @Documented
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({
+            AUDIO_SOURCE_MICROPHONE,
+            AUDIO_SOURCE_EXTERNAL
+    })
+    @interface AudioSource {}
+
+    /** @hide */
+    public static final int AUDIO_SOURCE_MICROPHONE = 1;
+    /** @hide */
+    public static final int AUDIO_SOURCE_EXTERNAL = 2;
+
     /**
      * The {@link Intent} that must be declared as handled by the service.
      * To be supported, the service must also require the
@@ -73,23 +131,59 @@
             if (DBG) {
                 Log.d(TAG, "#detectFromDspSource");
             }
-            mHandler.sendMessage(obtainMessage(HotwordDetectionService::onDetectFromDspSource,
+            mHandler.sendMessage(obtainMessage(HotwordDetectionService::onDetect,
                     HotwordDetectionService.this,
                     audioStream,
                     audioFormat,
                     timeoutMillis,
-                    new DspHotwordDetectionCallback(callback)));
+                    new Callback(callback)));
         }
 
         @Override
-        public void setConfig(Bundle options, SharedMemory sharedMemory) throws RemoteException {
+        public void updateState(PersistableBundle options, SharedMemory sharedMemory,
+                IHotwordRecognitionStatusCallback callback) throws RemoteException {
             if (DBG) {
-                Log.d(TAG, "#setConfig");
+                Log.d(TAG, "#updateState");
             }
-            mHandler.sendMessage(obtainMessage(HotwordDetectionService::onUpdateState,
+            mHandler.sendMessage(obtainMessage(HotwordDetectionService::onUpdateStateInternal,
                     HotwordDetectionService.this,
                     options,
-                    sharedMemory));
+                    sharedMemory,
+                    callback));
+        }
+
+        @Override
+        public void detectFromMicrophoneSource(
+                ParcelFileDescriptor audioStream,
+                @AudioSource int audioSource,
+                AudioFormat audioFormat,
+                PersistableBundle options,
+                IDspHotwordDetectionCallback callback)
+                throws RemoteException {
+            if (DBG) {
+                Log.d(TAG, "#detectFromMicrophoneSource");
+            }
+            switch (audioSource) {
+                case AUDIO_SOURCE_MICROPHONE:
+                    mHandler.sendMessage(obtainMessage(
+                            HotwordDetectionService::onDetect,
+                            HotwordDetectionService.this,
+                            audioStream,
+                            audioFormat,
+                            new Callback(callback)));
+                    break;
+                case AUDIO_SOURCE_EXTERNAL:
+                    mHandler.sendMessage(obtainMessage(
+                            HotwordDetectionService::onDetect,
+                            HotwordDetectionService.this,
+                            audioStream,
+                            audioFormat,
+                            options,
+                            new Callback(callback)));
+                    break;
+                default:
+                    Log.i(TAG, "Unsupported audio source " + audioSource);
+            }
         }
     };
 
@@ -112,79 +206,167 @@
     }
 
     /**
-     * Detect the audio data generated from Dsp.
-     *
-     * <p>Note: the clients are supposed to call {@code close} on the input stream when they are
-     * done with the operation in order to free up resources.
+     * Called when the device hardware (such as a DSP) detected the hotword, to request second stage
+     * validation before handing over the audio to the {@link AlwaysOnHotwordDetector}.
+     * <p>
+     * After {@code callback} is invoked or {@code timeoutMillis} has passed, the system closes
+     * {@code audioStream} and invokes the appropriate {@link AlwaysOnHotwordDetector.Callback
+     * callback}.
      *
      * @param audioStream Stream containing audio bytes returned from DSP
      * @param audioFormat Format of the supplied audio
      * @param timeoutMillis Timeout in milliseconds for the operation to invoke the callback. If
      *                      the application fails to abide by the timeout, system will close the
      *                      microphone and cancel the operation.
-     * @param callback Use {@link HotwordDetectionService#DspHotwordDetectionCallback} to return
-     * the detected result.
+     * @param callback The callback to use for responding to the detection request.
      *
      * @hide
      */
     @SystemApi
-    public void onDetectFromDspSource(
+    public void onDetect(
             @NonNull ParcelFileDescriptor audioStream,
             @NonNull AudioFormat audioFormat,
             @DurationMillisLong long timeoutMillis,
-            @NonNull DspHotwordDetectionCallback callback) {
+            @NonNull Callback callback) {
+        // TODO: Add a helpful error message.
+        throw new UnsupportedOperationException();
     }
 
     /**
      * Called when the {@link VoiceInteractionService#createAlwaysOnHotwordDetector(String, Locale,
-     * Bundle, SharedMemory, AlwaysOnHotwordDetector.Callback)} or {@link AlwaysOnHotwordDetector#
-     * setHotwordDetectionServiceConfig(Bundle, SharedMemory)} requests an update of the hotword
-     * detection parameters.
+     * PersistableBundle, SharedMemory, AlwaysOnHotwordDetector.Callback)} or
+     * {@link AlwaysOnHotwordDetector#updateState(PersistableBundle, SharedMemory)} requests an
+     * update of the hotword detection parameters.
      *
-     * @param options Application configuration data provided by the
-     * {@link VoiceInteractionService}. The system strips out any remotable objects or other
-     * contents that can be used to communicate with other processes.
-     * @param sharedMemory The unrestricted data blob provided by the
-     * {@link VoiceInteractionService}. Use this to provide the hotword models data or other
+     * @param options Application configuration data to provide to the
+     * {@link HotwordDetectionService}. PersistableBundle does not allow any remotable objects or
+     * other contents that can be used to communicate with other processes.
+     * @param sharedMemory The unrestricted data blob to provide to the
+     * {@link HotwordDetectionService}. Use this to provide the hotword models data or other
      * such data to the trusted process.
+     * @param callbackTimeoutMillis Timeout in milliseconds for the operation to invoke the
+     * statusCallback.
+     * @param statusCallback Use this to return the updated result. This is non-null only when the
+     * {@link HotwordDetectionService} is being initialized; and it is null if the state is updated
+     * after that.
      *
      * @hide
      */
     @SystemApi
-    public void onUpdateState(@Nullable Bundle options, @Nullable SharedMemory sharedMemory) {
+    public void onUpdateState(
+            @Nullable PersistableBundle options,
+            @Nullable SharedMemory sharedMemory,
+            @DurationMillisLong long callbackTimeoutMillis,
+            @Nullable @InitializationStatus IntConsumer statusCallback) {
+        // TODO: Handle the unimplemented case by throwing?
     }
 
     /**
-     * Callback for returning the detected result.
+     * Called when the {@link VoiceInteractionService} requests that this service
+     * {@link HotwordDetector#startRecognition() start} hotword recognition on audio coming directly
+     * from the device microphone.
+     * <p>
+     * On such a request, the system streams mic audio to this service through {@code audioStream}.
+     * Audio is streamed until {@link HotwordDetector#stopRecognition()} is called, at which point
+     * the system closes {code audioStream}.
+     * <p>
+     * On successful detection of a hotword within {@code audioStream}, call
+     * {@link Callback#onDetected(HotwordDetectedResult)}. The system continues to stream audio
+     * through {@code audioStream}; {@code callback} is reusable.
+     *
+     * @param audioStream Stream containing audio bytes returned from a microphone
+     * @param audioFormat Format of the supplied audio
+     * @param callback The callback to use for responding to the detection request.
+     * {@link Callback#onRejected(HotwordRejectedResult) callback.onRejected} cannot be used here.
+     */
+    public void onDetect(
+            @NonNull ParcelFileDescriptor audioStream,
+            @NonNull AudioFormat audioFormat,
+            @NonNull Callback callback) {
+        // TODO: Add a helpful error message.
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Called when the {@link VoiceInteractionService} requests that this service
+     * {@link HotwordDetector#startRecognition(ParcelFileDescriptor, AudioFormat,
+     * PersistableBundle)} run} hotword recognition on audio coming from an external connected
+     * microphone.
+     * <p>
+     * Upon invoking the {@code callback}, the system closes {@code audioStream} and sends the
+     * detection result to the {@link HotwordDetector.Callback hotword detector}.
+     *
+     * @param audioStream Stream containing audio bytes returned from a microphone
+     * @param audioFormat Format of the supplied audio
+     * @param options Options supporting detection, such as configuration specific to the source of
+     * the audio, provided through
+     * {@link HotwordDetector#startRecognition(ParcelFileDescriptor, AudioFormat,
+     * PersistableBundle)}.
+     * @param callback The callback to use for responding to the detection request.
+     */
+    public void onDetect(
+            @NonNull ParcelFileDescriptor audioStream,
+            @NonNull AudioFormat audioFormat,
+            @Nullable PersistableBundle options,
+            @NonNull Callback callback) {
+        // TODO: Add a helpful error message.
+        throw new UnsupportedOperationException();
+    }
+
+    private void onUpdateStateInternal(@Nullable PersistableBundle options,
+            @Nullable SharedMemory sharedMemory, IHotwordRecognitionStatusCallback callback) {
+        // TODO (b/183684347): Implement timeout case.
+        IntConsumer intConsumer = null;
+        if (callback != null) {
+            intConsumer =
+                    value -> {
+                        try {
+                            callback.onStatusReported(value);
+                        } catch (RemoteException e) {
+                            throw e.rethrowFromSystemServer();
+                        }
+                    };
+        }
+        onUpdateState(options, sharedMemory, UPDATE_TIMEOUT_MILLIS, intConsumer);
+    }
+
+    /**
+     * Callback for returning the detection result.
      *
      * @hide
      */
     @SystemApi
-    public static final class DspHotwordDetectionCallback {
+    public static final class Callback {
         // TODO: need to make sure we don't store remote references, but not a high priority.
         private final IDspHotwordDetectionCallback mRemoteCallback;
 
-        private DspHotwordDetectionCallback(IDspHotwordDetectionCallback remoteCallback) {
+        private Callback(IDspHotwordDetectionCallback remoteCallback) {
             mRemoteCallback = remoteCallback;
         }
 
         /**
          * Called when the detected result is valid.
          */
-        public void onDetected() {
+        public void onDetected(@Nullable HotwordDetectedResult hotwordDetectedResult) {
             try {
-                mRemoteCallback.onDetected();
+                mRemoteCallback.onDetected(hotwordDetectedResult);
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
         }
 
         /**
-         * Called when the detected result is invalid.
+         * Informs the {@link HotwordDetector} that the keyphrase was not detected.
+         * <p>
+         * This cannot not be used when recognition is done through
+         * {@link #onDetect(ParcelFileDescriptor, AudioFormat, Callback)}.
+         *
+         * @param result Info about the second stage detection result. This is provided to
+         *         the {@link HotwordDetector}.
          */
-        public void onRejected() {
+        public void onRejected(@Nullable HotwordRejectedResult result) {
             try {
-                mRemoteCallback.onRejected();
+                mRemoteCallback.onRejected(result);
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
diff --git a/core/java/android/service/voice/HotwordDetector.java b/core/java/android/service/voice/HotwordDetector.java
index abf49b7..f4e5dda 100644
--- a/core/java/android/service/voice/HotwordDetector.java
+++ b/core/java/android/service/voice/HotwordDetector.java
@@ -16,8 +16,18 @@
 
 package android.service.voice;
 
+import static android.Manifest.permission.CAPTURE_AUDIO_HOTWORD;
+import static android.Manifest.permission.RECORD_AUDIO;
+
 import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
+import android.media.AudioFormat;
+import android.os.ParcelFileDescriptor;
+import android.os.PersistableBundle;
+import android.service.voice.HotwordDetectionService.InitializationStatus;
 
 /**
  * Basic functionality for hotword detectors.
@@ -40,11 +50,108 @@
     int CONFIDENCE_LEVEL_HIGH = 3;
 
     /** @hide */
-    @IntDef(prefix = { "CONFIDENCE_LEVEL_" }, value = {
+    @IntDef(prefix = {"CONFIDENCE_LEVEL_"}, value = {
             CONFIDENCE_LEVEL_NONE,
             CONFIDENCE_LEVEL_LOW,
             CONFIDENCE_LEVEL_MEDIUM,
             CONFIDENCE_LEVEL_HIGH
     })
-    @interface HotwordConfidenceLevelValue {}
+    @interface HotwordConfidenceLevelValue {
+    }
+
+    /**
+     * Starts hotword recognition.
+     * <p>
+     * On calling this, the system streams audio from the device microphone to this application's
+     * {@link HotwordDetectionService}. Audio is streamed until {@link #stopRecognition()} is
+     * called.
+     * <p>
+     * On detection of a hotword,
+     * {@link AlwaysOnHotwordDetector.Callback#onDetected(AlwaysOnHotwordDetector.EventPayload)}
+     * is called on the callback provided when creating this {@link HotwordDetector}.
+     * <p>
+     * There is a noticeable impact on battery while recognition is active, so make sure to call
+     * {@link #stopRecognition()} when detection isn't needed.
+     * <p>
+     * Calling this again while recognition is active does nothing.
+     *
+     * @return true if the request to start recognition succeeded
+     */
+    @RequiresPermission(allOf = {RECORD_AUDIO, CAPTURE_AUDIO_HOTWORD})
+    boolean startRecognition();
+
+    /**
+     * Stops hotword recognition.
+     *
+     * @return true if the request to stop recognition succeeded
+     */
+    boolean stopRecognition();
+
+    /**
+     * Starts hotword recognition on audio coming from an external connected microphone.
+     * <p>
+     * {@link #stopRecognition()} must be called before {@code audioStream} is closed.
+     *
+     * @param audioStream stream containing the audio bytes to run detection on
+     * @param audioFormat format of the encoded audio
+     * @param options options supporting detection, such as configuration specific to the
+     *         source of the audio. This will be provided to the {@link HotwordDetectionService}.
+     *         PersistableBundle does not allow any remotable objects or other contents that can be
+     *         used to communicate with other processes.
+     * @return true if the request to start recognition succeeded
+     */
+    boolean startRecognition(
+            @NonNull ParcelFileDescriptor audioStream,
+            @NonNull AudioFormat audioFormat,
+            @Nullable PersistableBundle options);
+
+    /**
+     * The callback to notify of detection events.
+     */
+    interface Callback {
+
+        /**
+         * Called when the keyphrase is spoken.
+         *
+         * @param eventPayload Payload data for the detection event.
+         */
+        // TODO: Consider creating a new EventPayload that the AOHD one subclasses.
+        void onDetected(@NonNull AlwaysOnHotwordDetector.EventPayload eventPayload);
+
+        /**
+         * Called when the detection fails due to an error.
+         */
+        void onError();
+
+        /**
+         * Called when the recognition is paused temporarily for some reason.
+         * This is an informational callback, and the clients shouldn't be doing anything here
+         * except showing an indication on their UI if they have to.
+         */
+        void onRecognitionPaused();
+
+        /**
+         * Called when the recognition is resumed after it was temporarily paused.
+         * This is an informational callback, and the clients shouldn't be doing anything here
+         * except showing an indication on their UI if they have to.
+         */
+        void onRecognitionResumed();
+
+        /**
+         * Called when the {@link HotwordDetectionService second stage detection} did not detect the
+         * keyphrase.
+         *
+         * @param result Info about the second stage detection result, provided by the
+         *         {@link HotwordDetectionService}.
+         */
+        void onRejected(@Nullable HotwordRejectedResult result);
+
+        /**
+         * Called when the {@link HotwordDetectionService} is created by the system and given a
+         * short amount of time to report it's initialization state.
+         *
+         * @param status Info about initialization state of {@link HotwordDetectionService}.
+         */
+        void onHotwordDetectionServiceInitialized(@InitializationStatus int status);
+    }
 }
diff --git a/core/java/android/service/voice/IDspHotwordDetectionCallback.aidl b/core/java/android/service/voice/IDspHotwordDetectionCallback.aidl
index bb95bb8..c6b10ff 100644
--- a/core/java/android/service/voice/IDspHotwordDetectionCallback.aidl
+++ b/core/java/android/service/voice/IDspHotwordDetectionCallback.aidl
@@ -16,19 +16,25 @@
 
 package android.service.voice;
 
+import android.service.voice.HotwordDetectedResult;
+import android.service.voice.HotwordRejectedResult;
+
 /**
  * Callback for returning the detected result from the HotwordDetectionService.
  *
  * @hide
  */
+// TODO: Rename this.
 oneway interface IDspHotwordDetectionCallback {
+
     /**
      * Called when the detected result is valid.
      */
-    void onDetected();
+    void onDetected(
+        in HotwordDetectedResult hotwordDetectedResult);
 
     /**
-     * Called when the detected result is invalid.
+     * Sends {@code result} to the HotwordDetector.
      */
-    void onRejected();
+    void onRejected(in HotwordRejectedResult result);
 }
diff --git a/core/java/android/service/voice/IHotwordDetectionService.aidl b/core/java/android/service/voice/IHotwordDetectionService.aidl
index 8f0874a..cac8333 100644
--- a/core/java/android/service/voice/IHotwordDetectionService.aidl
+++ b/core/java/android/service/voice/IHotwordDetectionService.aidl
@@ -17,11 +17,13 @@
 package android.service.voice;
 
 import android.media.AudioFormat;
-import android.os.Bundle;
 import android.os.ParcelFileDescriptor;
+import android.os.PersistableBundle;
 import android.os.SharedMemory;
 import android.service.voice.IDspHotwordDetectionCallback;
 
+import com.android.internal.app.IHotwordRecognitionStatusCallback;
+
 /**
  * Provide the interface to communicate with hotword detection service.
  *
@@ -29,10 +31,18 @@
  */
 oneway interface IHotwordDetectionService {
     void detectFromDspSource(
-    in ParcelFileDescriptor audioStream,
-    in AudioFormat audioFormat,
-    long timeoutMillis,
-    in IDspHotwordDetectionCallback callback);
+        in ParcelFileDescriptor audioStream,
+        in AudioFormat audioFormat,
+        long timeoutMillis,
+        in IDspHotwordDetectionCallback callback);
 
-    void setConfig(in Bundle options, in SharedMemory sharedMemory);
+    void detectFromMicrophoneSource(
+        in ParcelFileDescriptor audioStream,
+        int audioSource,
+        in AudioFormat audioFormat,
+        in PersistableBundle options,
+        in IDspHotwordDetectionCallback callback);
+
+    void updateState(in PersistableBundle options, in SharedMemory sharedMemory,
+            in IHotwordRecognitionStatusCallback callback);
 }
diff --git a/core/java/android/service/voice/IMicrophoneHotwordDetectionVoiceInteractionCallback.aidl b/core/java/android/service/voice/IMicrophoneHotwordDetectionVoiceInteractionCallback.aidl
new file mode 100644
index 0000000..80f20fe
--- /dev/null
+++ b/core/java/android/service/voice/IMicrophoneHotwordDetectionVoiceInteractionCallback.aidl
@@ -0,0 +1,36 @@
+/*
+ * 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 android.service.voice;
+
+import android.media.AudioFormat;
+import android.service.voice.HotwordDetectedResult;
+
+/**
+ * Callback for returning the detected result from the HotwordDetectionService.
+ *
+ * @hide
+ */
+oneway interface IMicrophoneHotwordDetectionVoiceInteractionCallback {
+
+    /**
+     * Called when the detected result is valid.
+     */
+    void onDetected(
+        in HotwordDetectedResult hotwordDetectedResult,
+        in AudioFormat audioFormat,
+        in ParcelFileDescriptor audioStream);
+}
diff --git a/core/java/android/service/voice/SoftwareHotwordDetector.java b/core/java/android/service/voice/SoftwareHotwordDetector.java
new file mode 100644
index 0000000..376596b
--- /dev/null
+++ b/core/java/android/service/voice/SoftwareHotwordDetector.java
@@ -0,0 +1,146 @@
+/*
+ * 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 android.service.voice;
+
+import static android.Manifest.permission.RECORD_AUDIO;
+
+import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
+
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.media.AudioFormat;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.ParcelFileDescriptor;
+import android.os.PersistableBundle;
+import android.os.RemoteException;
+import android.os.SharedMemory;
+import android.util.Slog;
+
+import com.android.internal.app.IVoiceInteractionManagerService;
+
+import java.io.PrintWriter;
+
+/**
+ * Manages hotword detection not relying on a specific hardware.
+ *
+ * <p>On devices where DSP is available it's strongly recommended to use
+ * {@link AlwaysOnHotwordDetector}.
+ *
+ * @hide
+ **/
+class SoftwareHotwordDetector extends AbstractHotwordDetector {
+    private static final String TAG = SoftwareHotwordDetector.class.getSimpleName();
+    private static final boolean DEBUG = true;
+
+    private final IVoiceInteractionManagerService mManagerService;
+    private final HotwordDetector.Callback mCallback;
+    private final AudioFormat mAudioFormat;
+    private final Handler mHandler;
+    private final Object mLock = new Object();
+
+    SoftwareHotwordDetector(
+            IVoiceInteractionManagerService managerService,
+            AudioFormat audioFormat,
+            PersistableBundle options,
+            SharedMemory sharedMemory,
+            HotwordDetector.Callback callback) {
+        super(managerService, callback);
+
+        mManagerService = managerService;
+        mAudioFormat = audioFormat;
+        mCallback = callback;
+        mHandler = new Handler(Looper.getMainLooper());
+
+        try {
+            mManagerService.updateState(options, sharedMemory, null /* callback */);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    @RequiresPermission(RECORD_AUDIO)
+    @Override
+    public boolean startRecognition() {
+        if (DEBUG) {
+            Slog.i(TAG, "#startRecognition");
+        }
+
+        maybeCloseExistingSession();
+
+        try {
+            mManagerService.startListeningFromMic(
+                    mAudioFormat, new BinderCallback(mHandler, mCallback));
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+
+        return true;
+    }
+
+    /** TODO: stopRecognition */
+    @RequiresPermission(RECORD_AUDIO)
+    @Override
+    public boolean stopRecognition() {
+        if (DEBUG) {
+            Slog.i(TAG, "#stopRecognition");
+        }
+
+        try {
+            mManagerService.stopListeningFromMic();
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+
+        return true;
+    }
+
+    private void maybeCloseExistingSession() {
+        // TODO: needs to be synchronized.
+        // TODO: implement this
+    }
+
+    private static class BinderCallback
+            extends IMicrophoneHotwordDetectionVoiceInteractionCallback.Stub {
+        private final Handler mHandler;
+        // TODO: this needs to be a weak reference.
+        private final HotwordDetector.Callback mCallback;
+
+        BinderCallback(Handler handler, HotwordDetector.Callback callback) {
+            this.mHandler = handler;
+            this.mCallback = callback;
+        }
+
+        /** TODO: onDetected */
+        @Override
+        public void onDetected(
+                @Nullable HotwordDetectedResult hotwordDetectedResult,
+                @Nullable AudioFormat audioFormat,
+                @Nullable ParcelFileDescriptor audioStream) {
+            mHandler.sendMessage(obtainMessage(
+                    HotwordDetector.Callback::onDetected,
+                    mCallback,
+                    new AlwaysOnHotwordDetector.EventPayload(
+                            audioFormat, hotwordDetectedResult, audioStream)));
+        }
+    }
+
+    /** @hide */
+    public void dump(String prefix, PrintWriter pw) {
+        // TODO: implement this
+    }
+}
diff --git a/core/java/android/service/voice/VoiceInteractionService.java b/core/java/android/service/voice/VoiceInteractionService.java
index 9ba39a1..2a25227 100644
--- a/core/java/android/service/voice/VoiceInteractionService.java
+++ b/core/java/android/service/voice/VoiceInteractionService.java
@@ -29,10 +29,12 @@
 import android.content.Context;
 import android.content.Intent;
 import android.hardware.soundtrigger.KeyphraseEnrollmentInfo;
+import android.media.AudioFormat;
 import android.media.voice.KeyphraseModelManager;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
+import android.os.PersistableBundle;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SharedMemory;
@@ -133,6 +135,7 @@
     private KeyphraseEnrollmentInfo mKeyphraseEnrollmentInfo;
 
     private AlwaysOnHotwordDetector mHotwordDetector;
+    private SoftwareHotwordDetector mSoftwareHotwordDetector;
 
     /**
      * Called when a user has activated an affordance to launch voice assist from the Keyguard.
@@ -342,8 +345,8 @@
      * @param keyphrase The keyphrase that's being used, for example "Hello Android".
      * @param locale The locale for which the enrollment needs to be performed.
      * @param options Application configuration data provided by the
-     * {@link VoiceInteractionService}. The system strips out any remotable objects or other
-     * contents that can be used to communicate with other processes.
+     * {@link VoiceInteractionService}. PersistableBundle does not allow any remotable objects or
+     * other contents that can be used to communicate with other processes.
      * @param sharedMemory The unrestricted data blob provided by the
      * {@link VoiceInteractionService}. Use this to provide the hotword models data or other
      * such data to the trusted process.
@@ -358,7 +361,7 @@
     public final AlwaysOnHotwordDetector createAlwaysOnHotwordDetector(
             @SuppressLint("MissingNullability") String keyphrase,  // TODO: nullability properly
             @SuppressLint({"MissingNullability", "UseIcu"}) Locale locale,
-            @Nullable Bundle options,
+            @Nullable PersistableBundle options,
             @Nullable SharedMemory sharedMemory,
             @SuppressLint("MissingNullability") AlwaysOnHotwordDetector.Callback callback) {
         return createAlwaysOnHotwordDetectorInternal(keyphrase, locale,
@@ -370,7 +373,7 @@
             @SuppressLint("MissingNullability") String keyphrase,  // TODO: nullability properly
             @SuppressLint({"MissingNullability", "UseIcu"}) Locale locale,
             boolean supportHotwordDetectionService,
-            @Nullable Bundle options,
+            @Nullable PersistableBundle options,
             @Nullable SharedMemory sharedMemory,
             @SuppressLint("MissingNullability") AlwaysOnHotwordDetector.Callback callback) {
         if (mSystemService == null) {
@@ -388,6 +391,60 @@
     }
 
     /**
+     * Creates a {@link HotwordDetector} and initializes the application's
+     * {@link HotwordDetectionService} using {@code options} and {code sharedMemory}.
+     *
+     * <p>To be able to call this, you need to set android:hotwordDetectionService in the
+     * android.voice_interaction metadata file to a valid hotword detection service, and set
+     * android:isolatedProcess="true" in the hotword detection service's declaration. Otherwise,
+     * this throws an {@link IllegalStateException}.
+     *
+     * <p>This instance must be retained and used by the client.
+     * Calling this a second time invalidates the previously created hotword detector
+     * which can no longer be used to manage recognition.
+     *
+     * <p>Using this has a noticeable impact on battery, since the microphone is kept open
+     * for the lifetime of the recognition {@link HotwordDetector#startRecognition() session}. On
+     * devices where hardware filtering is available (such as through a DSP), it's highly
+     * recommended to use {@link #createAlwaysOnHotwordDetector} instead.
+     *
+     * @param audioFormat Format of the audio to be passed to {@link HotwordDetectionService}.
+     * @param options Application configuration data to be provided to the
+     * {@link HotwordDetectionService}. PersistableBundle does not allow any remotable objects or
+     * other contents that can be used to communicate with other processes.
+     * @param sharedMemory The unrestricted data blob to be provided to the
+     * {@link HotwordDetectionService}. Use this to provide hotword models or other such data to the
+     * sandboxed process.
+     * @param callback The callback to notify of detection events.
+     * @return A hotword detector for the given audio format.
+     *
+     * @see #createAlwaysOnHotwordDetector(String, Locale, PersistableBundle, SharedMemory,
+     * AlwaysOnHotwordDetector.Callback)
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.MANAGE_HOTWORD_DETECTION)
+    @NonNull
+    public final HotwordDetector createHotwordDetector(
+            @NonNull AudioFormat audioFormat,
+            @Nullable PersistableBundle options,
+            @Nullable SharedMemory sharedMemory,
+            @NonNull HotwordDetector.Callback callback) {
+        if (mSystemService == null) {
+            throw new IllegalStateException("Not available until onReady() is called");
+        }
+        synchronized (mLock) {
+            // Allow only one concurrent recognition via the APIs.
+            safelyShutdownHotwordDetector();
+            mSoftwareHotwordDetector =
+                    new SoftwareHotwordDetector(
+                            mSystemService, audioFormat, options, sharedMemory, callback);
+        }
+        return mSoftwareHotwordDetector;
+    }
+
+    /**
      * Creates an {@link KeyphraseModelManager} to use for enrolling voice models outside of the
      * pre-bundled system voice models.
      * @hide
@@ -430,26 +487,45 @@
 
     private void safelyShutdownHotwordDetector() {
         synchronized (mLock) {
-            if (mHotwordDetector == null) {
-                return;
-            }
-
-            try {
-                mHotwordDetector.stopRecognition();
-            } catch (Exception ex) {
-                // Ignore.
-            }
-
-            try {
-                mHotwordDetector.invalidate();
-            } catch (Exception ex) {
-                // Ignore.
-            }
-
-            mHotwordDetector = null;
+            shutdownDspHotwordDetectorLocked();
+            shutdownMicrophoneHotwordDetectorLocked();
         }
     }
 
+    private void shutdownDspHotwordDetectorLocked() {
+        if (mHotwordDetector == null) {
+            return;
+        }
+
+        try {
+            mHotwordDetector.stopRecognition();
+        } catch (Exception ex) {
+            // Ignore.
+        }
+
+        try {
+            mHotwordDetector.invalidate();
+        } catch (Exception ex) {
+            // Ignore.
+        }
+
+        mHotwordDetector = null;
+    }
+
+    private void shutdownMicrophoneHotwordDetectorLocked() {
+        if (mSoftwareHotwordDetector == null) {
+            return;
+        }
+
+        try {
+            mSoftwareHotwordDetector.stopRecognition();
+        } catch (Exception ex) {
+            // Ignore.
+        }
+
+        mSoftwareHotwordDetector = null;
+    }
+
     /**
      * Provide hints to be reflected in the system UI.
      *
@@ -477,6 +553,13 @@
             } else {
                 mHotwordDetector.dump("    ", pw);
             }
+
+            pw.println("  MicrophoneHotwordDetector");
+            if (mSoftwareHotwordDetector == null) {
+                pw.println("    NULL");
+            } else {
+                mSoftwareHotwordDetector.dump("    ", pw);
+            }
         }
     }
 }
diff --git a/core/java/android/speech/IRecognitionService.aidl b/core/java/android/speech/IRecognitionService.aidl
index cc1cded..9a5e534 100644
--- a/core/java/android/speech/IRecognitionService.aidl
+++ b/core/java/android/speech/IRecognitionService.aidl
@@ -17,6 +17,7 @@
 package android.speech;
 
 import android.os.Bundle;
+import android.content.AttributionSource;
 import android.content.Intent;
 import android.speech.IRecognitionListener;
 
@@ -39,11 +40,10 @@
      *        this intent can contain extra parameters to manipulate the behavior of the recognition
      *        client. For more information see {@link RecognizerIntent}.
      * @param listener to receive callbacks, note that this must be non-null
-     * @param packageName the package name calling this API
-     * @param featureId The feature in the package
+     * @param attributionSource The attribution source of the caller.
      */
     void startListening(in Intent recognizerIntent, in IRecognitionListener listener,
-            String packageName, String featureId, int callingUid);
+            in AttributionSource attributionSource);
 
     /**
      * Stops listening for speech. Speech captured so far will be recognized as
@@ -51,18 +51,14 @@
      * is called during the speech capturing.
      *
      * @param listener to receive callbacks, note that this must be non-null
-     * @param packageName the package name calling this API
-     * @param featureId The feature in the package
      */
-    void stopListening(in IRecognitionListener listener, String packageName, String featureId);
+    void stopListening(in IRecognitionListener listener);
 
     /**
      * Cancels the speech recognition.
      *
      * @param listener to receive callbacks, note that this must be non-null
      * @param packageName the package name calling this API
-     * @param featureId The feature in the package
-     * @param isShutdown Whether the cancellation is caused by a client calling #shutdown
      */
-    void cancel(in IRecognitionListener listener, String packageName, String featureId, boolean isShutdown);
+    void cancel(in IRecognitionListener listener, boolean isShutdown);
 }
diff --git a/core/java/android/speech/RecognitionService.java b/core/java/android/speech/RecognitionService.java
index fd584f1..4afa9473 100644
--- a/core/java/android/speech/RecognitionService.java
+++ b/core/java/android/speech/RecognitionService.java
@@ -16,11 +16,16 @@
 
 package android.speech;
 
+import android.Manifest;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
+import android.annotation.SuppressLint;
+import android.app.AppOpsManager;
 import android.app.Service;
+import android.content.Context;
+import android.content.ContextParams;
 import android.content.Intent;
 import android.content.PermissionChecker;
 import android.os.Binder;
@@ -28,13 +33,13 @@
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Message;
+import android.content.AttributionSource;
 import android.os.Process;
 import android.os.RemoteException;
 import android.util.Log;
 
-import com.android.internal.util.Preconditions;
-
 import java.lang.ref.WeakReference;
+import java.util.Objects;
 
 /**
  * This class provides a base class for recognition service implementations. This class should be
@@ -86,13 +91,13 @@
             switch (msg.what) {
                 case MSG_START_LISTENING:
                     StartListeningArgs args = (StartListeningArgs) msg.obj;
-                    dispatchStartListening(args.mIntent, args.mListener, args.mCallingUid);
+                    dispatchStartListening(args.mIntent, args.mListener, args.mAttributionSource);
                     break;
                 case MSG_STOP_LISTENING:
                     dispatchStopListening((IRecognitionListener) msg.obj);
                     break;
                 case MSG_CANCEL:
-                    dispatchCancel((IRecognitionListener) msg.obj);
+                    dispatchCancel((IRecognitionListener) msg.obj, msg.arg1 == 1);
                     break;
                 case MSG_RESET:
                     dispatchClearCallback();
@@ -102,10 +107,11 @@
     };
 
     private void dispatchStartListening(Intent intent, final IRecognitionListener listener,
-            int callingUid) {
+            @NonNull AttributionSource attributionSource) {
         if (mCurrentCallback == null) {
             if (DBG) Log.d(TAG, "created new mCurrentCallback, listener = " + listener.asBinder());
-            mCurrentCallback = new Callback(listener, callingUid);
+            mCurrentCallback = new Callback(listener, attributionSource);
+
             RecognitionService.this.onStartListening(intent, mCurrentCallback);
         } else {
             try {
@@ -133,13 +139,16 @@
         }
     }
 
-    private void dispatchCancel(IRecognitionListener listener) {
+    private void dispatchCancel(IRecognitionListener listener, boolean shutDown) {
         if (mCurrentCallback == null) {
             if (DBG) Log.d(TAG, "cancel called with no preceding startListening - ignoring");
         } else if (mCurrentCallback.mListener.asBinder() != listener.asBinder()) {
             Log.w(TAG, "cancel called by client who did not call startListening - ignoring");
         } else { // the correct state
             RecognitionService.this.onCancel(mCurrentCallback);
+            if (shutDown) {
+                mCurrentCallback.finishRecordAudioOpAttributionToCallerIfNeeded();
+            }
             mCurrentCallback = null;
             if (DBG) Log.d(TAG, "canceling - setting mCurrentCallback to null");
         }
@@ -153,12 +162,13 @@
         public final Intent mIntent;
 
         public final IRecognitionListener mListener;
-        public final int mCallingUid;
+        public final @NonNull AttributionSource mAttributionSource;
 
-        public StartListeningArgs(Intent intent, IRecognitionListener listener, int callingUid) {
+        public StartListeningArgs(Intent intent, IRecognitionListener listener,
+                @NonNull AttributionSource attributionSource) {
             this.mIntent = intent;
             this.mListener = listener;
-            this.mCallingUid = callingUid;
+            this.mAttributionSource = attributionSource;
         }
     }
 
@@ -247,18 +257,19 @@
      */
     public class Callback {
         private final IRecognitionListener mListener;
-        private final int mCallingUid;
+        private final @NonNull AttributionSource mCallingAttributionSource;
+        private @Nullable Context mAttributionContext;
 
-        private Callback(IRecognitionListener listener, int callingUid) {
+        private Callback(IRecognitionListener listener,
+                @NonNull AttributionSource attributionSource) {
             mListener = listener;
-            mCallingUid = callingUid;
+            mCallingAttributionSource = attributionSource;
         }
 
         /**
          * The service should call this method when the user has started to speak.
          */
         public void beginningOfSpeech() throws RemoteException {
-            if (DBG) Log.d(TAG, "beginningOfSpeech");
             mListener.onBeginningOfSpeech();
         }
 
@@ -270,6 +281,7 @@
          *        single channel audio stream. The sample rate is implementation dependent.
          */
         public void bufferReceived(byte[] buffer) throws RemoteException {
+            startRecordAudioOpAttributionToCallerIfNeeded();
             mListener.onBufferReceived(buffer);
         }
 
@@ -302,6 +314,7 @@
          *        {@link SpeechRecognizer#RESULTS_RECOGNITION} as a parameter
          */
         public void partialResults(Bundle partialResults) throws RemoteException {
+            startRecordAudioOpAttributionToCallerIfNeeded();
             mListener.onPartialResults(partialResults);
         }
 
@@ -323,6 +336,7 @@
          *        {@link SpeechRecognizer#RESULTS_RECOGNITION} as a parameter
          */
         public void results(Bundle results) throws RemoteException {
+            startRecordAudioOpAttributionToCallerIfNeeded();
             Message.obtain(mHandler, MSG_RESET).sendToTarget();
             mListener.onResults(results);
         }
@@ -342,7 +356,65 @@
          * is being processed. This is obtained from {@link Binder#getCallingUid()}.
          */
         public int getCallingUid() {
-            return mCallingUid;
+            return mCallingAttributionSource.getUid();
+        }
+
+        /**
+         * Gets the permission identity of the calling app. If you want to attribute
+         * the mic access to the calling app you can create an attribution context
+         * via {@link android.content.Context#createContext(android.content.ContextParams)}
+         * and passing this identity to {@link
+         * android.content.ContextParams.Builder#setNextAttributionSource(AttributionSource)}.
+         *
+         *
+         *
+         *
+         * @return The permission identity of the calling app.
+         *
+         * @see android.content.ContextParams.Builder#setNextAttributionSource(
+         * AttributionSource)
+         */
+        @SuppressLint("CallbackMethodName")
+        public @NonNull AttributionSource getCallingAttributionSource() {
+            return mCallingAttributionSource;
+        }
+
+        private void startRecordAudioOpAttributionToCallerIfNeeded() throws RemoteException {
+            if (!isProxyingRecordAudioToCaller()) {
+                final int result = PermissionChecker.checkPermissionAndStartDataDelivery(
+                        RecognitionService.this, Manifest.permission.RECORD_AUDIO,
+                        getAttributionContextForCaller().getAttributionSource(),
+                        /*message*/ null);
+                if (result == PermissionChecker.PERMISSION_GRANTED) {
+                    return;
+                }
+                error(SpeechRecognizer.ERROR_INSUFFICIENT_PERMISSIONS);
+            }
+        }
+
+        private @NonNull Context getAttributionContextForCaller() {
+            if (mAttributionContext == null) {
+                mAttributionContext = createContext(new ContextParams.Builder()
+                        .setNextAttributionSource(mCallingAttributionSource)
+                        .build());
+            }
+            return mAttributionContext;
+        }
+
+        void finishRecordAudioOpAttributionToCallerIfNeeded() {
+            if (isProxyingRecordAudioToCaller()) {
+                final String op = AppOpsManager.permissionToOp(Manifest.permission.RECORD_AUDIO);
+                PermissionChecker.finishDataDelivery(RecognitionService.this,
+                        op, getAttributionContextForCaller().getAttributionSource());
+            }
+        }
+
+        private boolean isProxyingRecordAudioToCaller() {
+            final int op = AppOpsManager.permissionToOpCode(Manifest.permission.RECORD_AUDIO);
+            final AppOpsManager appOpsManager = getSystemService(AppOpsManager.class);
+            return appOpsManager.isProxying(op, getAttributionTag(),
+                    mCallingAttributionSource.getUid(),
+                    mCallingAttributionSource.getPackageName());
         }
     }
 
@@ -356,44 +428,35 @@
 
         @Override
         public void startListening(Intent recognizerIntent, IRecognitionListener listener,
-                String packageName, String featureId, int callingUid) {
-            Preconditions.checkNotNull(packageName);
-
+                @NonNull AttributionSource attributionSource) {
+            Objects.requireNonNull(attributionSource);
+            attributionSource.enforceCallingUid();
             if (DBG) Log.d(TAG, "startListening called by:" + listener.asBinder());
             final RecognitionService service = mServiceRef.get();
-            if (service != null && service.checkPermissions(listener, true /*forDataDelivery*/,
-                    packageName, featureId)) {
+            if (service != null) {
                 service.mHandler.sendMessage(Message.obtain(service.mHandler,
                         MSG_START_LISTENING, service.new StartListeningArgs(
-                                recognizerIntent, listener, callingUid)));
+                                recognizerIntent, listener, attributionSource)));
             }
         }
 
         @Override
-        public void stopListening(IRecognitionListener listener, String packageName,
-                String featureId) {
-            Preconditions.checkNotNull(packageName);
-
+        public void stopListening(IRecognitionListener listener) {
             if (DBG) Log.d(TAG, "stopListening called by:" + listener.asBinder());
             final RecognitionService service = mServiceRef.get();
-            if (service != null && service.checkPermissions(listener, false /*forDataDelivery*/,
-                    packageName, featureId)) {
+            if (service != null) {
                 service.mHandler.sendMessage(Message.obtain(service.mHandler,
                         MSG_STOP_LISTENING, listener));
             }
         }
 
         @Override
-        public void cancel(IRecognitionListener listener, String packageName,
-                String featureId, boolean isShutdown) {
-            Preconditions.checkNotNull(packageName);
-
+        public void cancel(IRecognitionListener listener, boolean isShutdown) {
             if (DBG) Log.d(TAG, "cancel called by:" + listener.asBinder());
             final RecognitionService service = mServiceRef.get();
-            if (service != null && service.checkPermissions(listener, false /*forDataDelivery*/,
-                    packageName, featureId)) {
+            if (service != null) {
                 service.mHandler.sendMessage(Message.obtain(service.mHandler,
-                        MSG_CANCEL, listener));
+                        MSG_CANCEL, isShutdown ? 1 : 0, 0, listener));
             }
         }
 
diff --git a/core/java/android/speech/SpeechRecognizer.java b/core/java/android/speech/SpeechRecognizer.java
index 9b93a64..7aa5ee5 100644
--- a/core/java/android/speech/SpeechRecognizer.java
+++ b/core/java/android/speech/SpeechRecognizer.java
@@ -386,8 +386,7 @@
             return;
         }
         try {
-            mService.startListening(recognizerIntent, mListener, mContext.getOpPackageName(),
-                    mContext.getAttributionTag(), android.os.Process.myUid());
+            mService.startListening(recognizerIntent, mListener, mContext.getAttributionSource());
             if (DBG) Log.d(TAG, "service start listening command succeded");
         } catch (final RemoteException e) {
             Log.e(TAG, "startListening() failed", e);
@@ -401,8 +400,7 @@
             return;
         }
         try {
-            mService.stopListening(mListener, mContext.getOpPackageName(),
-                    mContext.getAttributionTag());
+            mService.stopListening(mListener);
             if (DBG) Log.d(TAG, "service stop listening command succeded");
         } catch (final RemoteException e) {
             Log.e(TAG, "stopListening() failed", e);
@@ -416,11 +414,7 @@
             return;
         }
         try {
-            mService.cancel(
-                    mListener,
-                    mContext.getOpPackageName(),
-                    mContext.getAttributionTag(),
-                    false /* isShutdown */);
+            mService.cancel(mListener, /*isShutdown*/ false);
             if (DBG) Log.d(TAG, "service cancel command succeded");
         } catch (final RemoteException e) {
             Log.e(TAG, "cancel() failed", e);
@@ -463,8 +457,7 @@
     public void destroy() {
         if (mService != null) {
             try {
-                mService.cancel(mListener, mContext.getOpPackageName(),
-                        mContext.getAttributionTag(), true /* isShutdown */);
+                mService.cancel(mListener, /*isShutdown*/ true);
             } catch (final RemoteException e) {
                 // Not important
             }
diff --git a/core/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java
index d47ae27..49065aa 100644
--- a/core/java/android/telephony/PhoneStateListener.java
+++ b/core/java/android/telephony/PhoneStateListener.java
@@ -343,11 +343,14 @@
     /**
      *  Listen for display info changed event.
      *
-     *  Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE
-     *  READ_PHONE_STATE} or that the calling app has carrier privileges (see
-     *  {@link TelephonyManager#hasCarrierPrivileges}).
+     * For clients compiled on Android 11 SDK, requires permission:
+     * {@link android.Manifest.permission#READ_PHONE_STATE} or that the calling app has carrier
+     * privileges (see {@link TelephonyManager#hasCarrierPrivileges}).
+     * For clients compiled on Android 12 SDK or newer,
+     * {@link android.Manifest.permission#READ_PHONE_STATE} or carrier privileges is not required
+     * anymore.
      *
-     *  @see #onDisplayInfoChanged
+     * @see #onDisplayInfoChanged
      * @deprecated Use {@link TelephonyCallback.DisplayInfoListener} instead.
      */
     @Deprecated
@@ -700,6 +703,10 @@
      * calling {@link TelephonyManager#getCallState()} from within this callback may return a
      * different state than the callback reports.
      *
+     * Requires Permission:
+     * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} for applications
+     * targeting API level 31+.
+     *
      * @param state call state
      * @param phoneNumber call phone number. If application does not have
      * {@link android.Manifest.permission#READ_CALL_LOG READ_CALL_LOG} permission or carrier
@@ -709,6 +716,7 @@
      * @deprecated Use {@link TelephonyCallback.CallStateListener} instead.
      */
     @Deprecated
+    @RequiresPermission(value = android.Manifest.permission.READ_PHONE_STATE, conditional = true)
     public void onCallStateChanged(@CallState int state, String phoneNumber) {
         // default implementation empty
     }
@@ -981,8 +989,12 @@
      * <p> The {@link TelephonyDisplayInfo} contains status information shown to the user based on
      * carrier policy.
      *
-     * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE} or that the calling
-     * app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}).
+     * For clients compiled on Android 11 SDK, requires permission:
+     * {@link android.Manifest.permission#READ_PHONE_STATE} or that the calling app has carrier
+     * privileges (see {@link TelephonyManager#hasCarrierPrivileges}).
+     * For clients compiled on Android 12 SDK or newer,
+     * {@link android.Manifest.permission#READ_PHONE_STATE} or carrier privileges is not required
+     * anymore.
      *
      * @param telephonyDisplayInfo The display information.
      * @deprecated Use {@link TelephonyCallback.DisplayInfoListener} instead.
diff --git a/core/java/android/telephony/TelephonyCallback.java b/core/java/android/telephony/TelephonyCallback.java
index d000000..1ab6e0f 100644
--- a/core/java/android/telephony/TelephonyCallback.java
+++ b/core/java/android/telephony/TelephonyCallback.java
@@ -752,6 +752,7 @@
          *
          * @param state the current call state
          */
+        @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
         public void onCallStateChanged(@Annotation.CallState int state);
     }
 
@@ -1057,7 +1058,6 @@
          *
          * @param telephonyDisplayInfo The display information.
          */
-        @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
         public void onDisplayInfoChanged(@NonNull TelephonyDisplayInfo telephonyDisplayInfo);
     }
 
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index 919c6e5..913ceae 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -71,7 +71,7 @@
         DEFAULT_FLAGS.put("settings_silky_home", "true");
         DEFAULT_FLAGS.put("settings_contextual_home", "false");
         DEFAULT_FLAGS.put(SETTINGS_PROVIDER_MODEL, "false");
-        DEFAULT_FLAGS.put(SETTINGS_USE_NEW_BACKUP_ELIGIBILITY_RULES, "false");
+        DEFAULT_FLAGS.put(SETTINGS_USE_NEW_BACKUP_ELIGIBILITY_RULES, "true");
         DEFAULT_FLAGS.put(SETTINGS_ENABLE_SECURITY_HUB, "false");
     }
 
diff --git a/core/java/android/util/Slog.java b/core/java/android/util/Slog.java
index d3eaeae..2a43222 100644
--- a/core/java/android/util/Slog.java
+++ b/core/java/android/util/Slog.java
@@ -26,6 +26,10 @@
 import java.util.Locale;
 
 /**
+ * API for sending log output to the {@link Log#LOG_ID_SYSTEM} buffer.
+ *
+ * <p>Should be used by system components. Use {@code adb logcat --buffer=system} to fetch the logs.
+ *
  * @hide
  */
 public final class Slog {
@@ -51,6 +55,12 @@
 
     /**
      * Logs a {@link Log.VERBOSE} message.
+     *
+     * <p><strong>Note: </strong>the message will only be formatted if {@link Log#WARN} logging is
+     * enabled for the given {@code tag}, but the compiler will still create an intermediate array
+     * of the objects for the {@code vargars}, which could affect garbage collection. So, if you're
+     * calling this method in a critical path, make sure to explicitly do the check before calling
+     * it.
      */
     public static void v(String tag, String format, @Nullable Object... args) {
         if (!Log.isLoggable(tag, Log.VERBOSE)) return;
@@ -71,6 +81,12 @@
 
     /**
      * Logs a {@link Log.DEBUG} message.
+     *
+     * <p><strong>Note: </strong>the message will only be formatted if {@link Log#WARN} logging is
+     * enabled for the given {@code tag}, but the compiler will still create an intermediate array
+     * of the objects for the {@code vargars}, which could affect garbage collection. So, if you're
+     * calling this method in a critical path, make sure to explicitly do the check before calling
+     * it.
      */
     public static void d(String tag, String format, @Nullable Object... args) {
         if (!Log.isLoggable(tag, Log.DEBUG)) return;
@@ -90,6 +106,12 @@
 
     /**
      * Logs a {@link Log.INFO} message.
+     *
+     * <p><strong>Note: </strong>the message will only be formatted if {@link Log#WARN} logging is
+     * enabled for the given {@code tag}, but the compiler will still create an intermediate array
+     * of the objects for the {@code vargars}, which could affect garbage collection. So, if you're
+     * calling this method in a critical path, make sure to explicitly do the check before calling
+     * it.
      */
     public static void i(String tag, String format, @Nullable Object... args) {
         if (!Log.isLoggable(tag, Log.INFO)) return;
@@ -114,6 +136,12 @@
 
     /**
      * Logs a {@link Log.WARN} message.
+     *
+     * <p><strong>Note: </strong>the message will only be formatted if {@link Log#WARN} logging is
+     * enabled for the given {@code tag}, but the compiler will still create an intermediate array
+     * of the objects for the {@code vargars}, which could affect garbage collection. So, if you're
+     * calling this method in a critical path, make sure to explicitly do the check before calling
+     * it.
      */
     public static void w(String tag, String format, @Nullable Object... args) {
         if (!Log.isLoggable(tag, Log.WARN)) return;
@@ -123,6 +151,12 @@
 
     /**
      * Logs a {@link Log.WARN} message with an exception
+     *
+     * <p><strong>Note: </strong>the message will only be formatted if {@link Log#WARN} logging is
+     * enabled for the given {@code tag}, but the compiler will still create an intermediate array
+     * of the objects for the {@code vargars}, which could affect garbage collection. So, if you're
+     * calling this method in a critical path, make sure to explicitly do the check before calling
+     * it.
      */
     public static void w(String tag, Exception exception, String format, @Nullable Object... args) {
         if (!Log.isLoggable(tag, Log.WARN)) return;
@@ -143,6 +177,12 @@
 
     /**
      * Logs a {@link Log.ERROR} message.
+     *
+     * <p><strong>Note: </strong>the message will only be formatted if {@link Log#WARN} logging is
+     * enabled for the given {@code tag}, but the compiler will still create an intermediate array
+     * of the objects for the {@code vargars}, which could affect garbage collection. So, if you're
+     * calling this method in a critical path, make sure to explicitly do the check before calling
+     * it.
      */
     public static void e(String tag, String format, @Nullable Object... args) {
         if (!Log.isLoggable(tag, Log.ERROR)) return;
@@ -152,6 +192,12 @@
 
     /**
      * Logs a {@link Log.ERROR} message with an exception
+     *
+     * <p><strong>Note: </strong>the message will only be formatted if {@link Log#WARN} logging is
+     * enabled for the given {@code tag}, but the compiler will still create an intermediate array
+     * of the objects for the {@code vargars}, which could affect garbage collection. So, if you're
+     * calling this method in a critical path, make sure to explicitly do the check before calling
+     * it.
      */
     public static void e(String tag, Exception exception, String format, @Nullable Object... args) {
         if (!Log.isLoggable(tag, Log.ERROR)) return;
diff --git a/core/java/android/util/SparseDoubleArray.java b/core/java/android/util/SparseDoubleArray.java
new file mode 100644
index 0000000..dc93a47
--- /dev/null
+++ b/core/java/android/util/SparseDoubleArray.java
@@ -0,0 +1,166 @@
+/*
+ * 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 android.util;
+
+/**
+ * SparseDoubleArrays map integers to doubles.  Unlike a normal array of doubles,
+ * there can be gaps in the indices.  It is intended to be more memory efficient
+ * than using a HashMap to map Integers to Doubles, both because it avoids
+ * auto-boxing keys and values and its data structure doesn't rely on an extra entry object
+ * for each mapping.
+ *
+ * <p>Note that this container keeps its mappings in an array data structure,
+ * using a binary search to find keys.  The implementation is not intended to be appropriate for
+ * data structures
+ * that may contain large numbers of items.  It is generally slower than a traditional
+ * HashMap, since lookups require a binary search and adds and removes require inserting
+ * and deleting entries in the array.  For containers holding up to hundreds of items,
+ * the performance difference is not significant, less than 50%.</p>
+ *
+ * <p>It is possible to iterate over the items in this container using
+ * {@link #keyAt(int)} and {@link #valueAt(int)}. Iterating over the keys using
+ * <code>keyAt(int)</code> with ascending values of the index will return the
+ * keys in ascending order, or the values corresponding to the keys in ascending
+ * order in the case of <code>valueAt(int)</code>.</p>
+ *
+ * @see SparseLongArray
+ *
+ * @hide
+ */
+public class SparseDoubleArray implements Cloneable {
+    /**
+     * The int->double map, but storing the doubles as longs using
+     * {@link Double#doubleToRawLongBits(double)}.
+     */
+    private SparseLongArray mValues;
+
+    /** Creates a new SparseDoubleArray containing no mappings. */
+    public SparseDoubleArray() {
+        this(10);
+    }
+
+    /**
+     * Creates a new SparseDoubleArray, containing no mappings, that will not
+     * require any additional memory allocation to store the specified
+     * number of mappings.  If you supply an initial capacity of 0, the
+     * sparse array will be initialized with a light-weight representation
+     * not requiring any additional array allocations.
+     */
+    public SparseDoubleArray(int initialCapacity) {
+        mValues = new SparseLongArray(initialCapacity);
+    }
+
+    @Override
+    public SparseDoubleArray clone() {
+        SparseDoubleArray clone = null;
+        try {
+            clone = (SparseDoubleArray) super.clone();
+            clone.mValues = mValues.clone();
+        } catch (CloneNotSupportedException cnse) {
+            /* ignore */
+        }
+        return clone;
+    }
+
+    /**
+     * Gets the double mapped from the specified key, or <code>0</code>
+     * if no such mapping has been made.
+     */
+    public double get(int key) {
+        final int index = mValues.indexOfKey(key);
+        if (index < 0) {
+            return 0.0d;
+        }
+        return valueAt(index);
+    }
+
+    /**
+     * Adds a mapping from the specified key to the specified value,
+     * replacing the previous mapping from the specified key if there
+     * was one.
+     */
+    public void put(int key, double value) {
+        mValues.put(key, Double.doubleToRawLongBits(value));
+    }
+
+    /**
+     * Adds a mapping from the specified key to the specified value,
+     * <b>adding</b> its value to the previous mapping from the specified key if there
+     * was one.
+     *
+     * <p>This differs from {@link #put} because instead of replacing any previous value, it adds
+     * (in the numerical sense) to it.
+     */
+    public void add(int key, double summand) {
+        final double oldValue = get(key);
+        put(key, oldValue + summand);
+    }
+
+    /** Returns the number of key-value mappings that this SparseDoubleArray currently stores. */
+    public int size() {
+        return mValues.size();
+    }
+
+    /**
+     * Given an index in the range <code>0...size()-1</code>, returns
+     * the key from the <code>index</code>th key-value mapping that this
+     * SparseDoubleArray stores.
+     *
+     * @see SparseLongArray#keyAt(int)
+     */
+    public int keyAt(int index) {
+        return mValues.keyAt(index);
+    }
+
+    /**
+     * Given an index in the range <code>0...size()-1</code>, returns
+     * the value from the <code>index</code>th key-value mapping that this
+     * SparseDoubleArray stores.
+     *
+     * @see SparseLongArray#valueAt(int)
+     */
+    public double valueAt(int index) {
+        return Double.longBitsToDouble(mValues.valueAt(index));
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * <p>This implementation composes a string by iterating over its mappings.
+     */
+    @Override
+    public String toString() {
+        if (size() <= 0) {
+            return "{}";
+        }
+
+        StringBuilder buffer = new StringBuilder(size() * 34);
+        buffer.append('{');
+        for (int i = 0; i < size(); i++) {
+            if (i > 0) {
+                buffer.append(", ");
+            }
+            int key = keyAt(i);
+            buffer.append(key);
+            buffer.append('=');
+            double value = valueAt(i);
+            buffer.append(value);
+        }
+        buffer.append('}');
+        return buffer.toString();
+    }
+}
diff --git a/core/java/android/util/SparseLongArray.java b/core/java/android/util/SparseLongArray.java
index b0916d3..f2bc0c5 100644
--- a/core/java/android/util/SparseLongArray.java
+++ b/core/java/android/util/SparseLongArray.java
@@ -164,7 +164,7 @@
     }
 
     /**
-     * Returns the number of key-value mappings that this SparseIntArray
+     * Returns the number of key-value mappings that this SparseLongArray
      * currently stores.
      */
     public int size() {
@@ -246,7 +246,7 @@
     }
 
     /**
-     * Removes all key-value mappings from this SparseIntArray.
+     * Removes all key-value mappings from this SparseLongArray.
      */
     public void clear() {
         mSize = 0;
diff --git a/core/java/android/util/imetracing/ImeTracing.java b/core/java/android/util/imetracing/ImeTracing.java
index b28cfb8..2fcaec9 100644
--- a/core/java/android/util/imetracing/ImeTracing.java
+++ b/core/java/android/util/imetracing/ImeTracing.java
@@ -130,6 +130,16 @@
     public abstract void triggerManagerServiceDump(String where);
 
     /**
+     * Being called while taking a bugreport so that tracing files can be included in the bugreport
+     * when the IME tracing is running.  Does nothing otherwise.
+     *
+     * @param pw Print writer
+     */
+    public void saveForBugreport(@Nullable PrintWriter pw) {
+        // does nothing by default.
+    }
+
+    /**
      * Sets whether ime tracing is enabled.
      *
      * @param enabled Tells whether ime tracing should be enabled or disabled.
@@ -153,11 +163,6 @@
     }
 
     /**
-     * Writes the current tracing data to the specific output proto file.
-     */
-    public abstract void writeTracesToFiles();
-
-    /**
      * Starts a new IME trace if one is not already started.
      *
      * @param pw Print writer
@@ -171,14 +176,6 @@
      */
     public abstract void stopTrace(@Nullable PrintWriter pw);
 
-    /**
-     * Stops the IME trace if one was previously started.
-     *
-     * @param pw Print writer
-     * @param writeToFile If the current buffer should be written to disk or not
-     */
-    public abstract void stopTrace(@Nullable PrintWriter pw, boolean writeToFile);
-
     private static boolean isSystemProcess() {
         return ActivityThread.isSystem();
     }
diff --git a/core/java/android/util/imetracing/ImeTracingClientImpl.java b/core/java/android/util/imetracing/ImeTracingClientImpl.java
index 35a81b7..17cdc46 100644
--- a/core/java/android/util/imetracing/ImeTracingClientImpl.java
+++ b/core/java/android/util/imetracing/ImeTracingClientImpl.java
@@ -99,18 +99,10 @@
     }
 
     @Override
-    public void writeTracesToFiles() {
-    }
-
-    @Override
     public void startTrace(PrintWriter pw) {
     }
 
     @Override
     public void stopTrace(PrintWriter pw) {
     }
-
-    @Override
-    public void stopTrace(PrintWriter pw, boolean writeToFile) {
-    }
 }
diff --git a/core/java/android/util/imetracing/ImeTracingServerImpl.java b/core/java/android/util/imetracing/ImeTracingServerImpl.java
index 77f017a..06e4c50 100644
--- a/core/java/android/util/imetracing/ImeTracingServerImpl.java
+++ b/core/java/android/util/imetracing/ImeTracingServerImpl.java
@@ -139,14 +139,6 @@
         }
     }
 
-    @GuardedBy("mEnabledLock")
-    @Override
-    public void writeTracesToFiles() {
-        synchronized (mEnabledLock) {
-            writeTracesToFilesLocked();
-        }
-    }
-
     private void writeTracesToFilesLocked() {
         try {
             ProtoOutputStream clientsProto = new ProtoOutputStream();
@@ -192,12 +184,6 @@
 
     @Override
     public void stopTrace(@Nullable PrintWriter pw) {
-        stopTrace(pw, true /* writeToFile */);
-    }
-
-    @GuardedBy("mEnabledLock")
-    @Override
-    public void stopTrace(@Nullable PrintWriter pw, boolean writeToFile) {
         if (IS_USER) {
             Log.w(TAG, "Warn: Tracing is not supported on user builds.");
             return;
@@ -213,9 +199,35 @@
                     + TRACE_FILENAME_CLIENTS + ", " + TRACE_FILENAME_IMS + ", "
                     + TRACE_FILENAME_IMMS);
             sEnabled = false;
-            if (writeToFile) {
-                writeTracesToFilesLocked();
+            writeTracesToFilesLocked();
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void saveForBugreport(@Nullable PrintWriter pw) {
+        if (IS_USER) {
+            return;
+        }
+        synchronized (mEnabledLock) {
+            if (!isAvailable() || !isEnabled()) {
+                return;
             }
+            // Temporarily stop accepting logs from trace event providers.  There is a small chance
+            // that we may drop some trace events while writing the file, but we currently need to
+            // live with that.  Note that addToBuffer() also has a bug that it doesn't do
+            // read-acquire so flipping sEnabled here doesn't even guarantee that addToBuffer() will
+            // temporarily stop accepting incoming events...
+            // TODO(b/175761228): Implement atomic snapshot to avoid downtime.
+            // TODO(b/175761228): Fix synchronization around sEnabled.
+            sEnabled = false;
+            logAndPrintln(pw, "Writing traces in " + TRACE_DIRNAME + ": "
+                    + TRACE_FILENAME_CLIENTS + ", " + TRACE_FILENAME_IMS + ", "
+                    + TRACE_FILENAME_IMMS);
+            writeTracesToFilesLocked();
+            sEnabled = true;
         }
     }
 
diff --git a/core/java/android/uwb/AngleMeasurement.java b/core/java/android/uwb/AngleMeasurement.java
index 8c771ba..3d60373 100644
--- a/core/java/android/uwb/AngleMeasurement.java
+++ b/core/java/android/uwb/AngleMeasurement.java
@@ -48,7 +48,10 @@
      * @throws IllegalArgumentException if the radians, errorRadians, or confidenceLevel is out of
      *                                  allowed range
      */
-    public AngleMeasurement(double radians, double errorRadians, double confidenceLevel) {
+    public AngleMeasurement(
+            @FloatRange(from = -Math.PI, to = +Math.PI) double radians,
+            @FloatRange(from = 0.0, to = +Math.PI) double errorRadians,
+            @FloatRange(from = 0.0, to = 1.0) double confidenceLevel) {
         if (radians < -Math.PI || radians > Math.PI) {
             throw new IllegalArgumentException("Invalid radians: " + radians);
         }
diff --git a/core/java/android/view/ContentInfo.java b/core/java/android/view/ContentInfo.java
index 547bc9d..b55d9b3 100644
--- a/core/java/android/view/ContentInfo.java
+++ b/core/java/android/view/ContentInfo.java
@@ -26,6 +26,7 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.util.Pair;
+import android.view.inputmethod.InputContentInfo;
 
 import com.android.internal.util.Preconditions;
 
@@ -141,6 +142,10 @@
     private final Uri mLinkUri;
     @Nullable
     private final Bundle mExtras;
+    @Nullable
+    private final InputContentInfo mInputContentInfo;
+    @Nullable
+    private final DragAndDropPermissions mDragAndDropPermissions;
 
     private ContentInfo(Builder b) {
         this.mClip = Objects.requireNonNull(b.mClip);
@@ -149,6 +154,23 @@
         this.mFlags = Preconditions.checkFlagsArgument(b.mFlags, FLAG_CONVERT_TO_PLAIN_TEXT);
         this.mLinkUri = b.mLinkUri;
         this.mExtras = b.mExtras;
+        this.mInputContentInfo = b.mInputContentInfo;
+        this.mDragAndDropPermissions = b.mDragAndDropPermissions;
+    }
+
+    /**
+     * If the content came from a source that supports proactive release of URI permissions
+     * (e.g. IME), releases permissions; otherwise a no-op.
+     *
+     * @hide
+     */
+    public void releasePermissions() {
+        if (mInputContentInfo != null) {
+            mInputContentInfo.releasePermission();
+        }
+        if (mDragAndDropPermissions != null) {
+            mDragAndDropPermissions.release();
+        }
     }
 
     @NonNull
@@ -275,6 +297,10 @@
         private Uri mLinkUri;
         @Nullable
         private Bundle mExtras;
+        @Nullable
+        private InputContentInfo mInputContentInfo;
+        @Nullable
+        private DragAndDropPermissions mDragAndDropPermissions;
 
         /**
          * Creates a new builder initialized with the data from the given builder.
@@ -285,6 +311,8 @@
             mFlags = other.mFlags;
             mLinkUri = other.mLinkUri;
             mExtras = other.mExtras;
+            mInputContentInfo = other.mInputContentInfo;
+            mDragAndDropPermissions = other.mDragAndDropPermissions;
         }
 
         /**
@@ -355,6 +383,31 @@
         }
 
         /**
+         * Set the {@link InputContentInfo} object if the content is coming from the IME. This can
+         * be used for proactive cleanup of permissions.
+         *
+         * @hide
+         */
+        @NonNull
+        public Builder setInputContentInfo(@Nullable InputContentInfo inputContentInfo) {
+            mInputContentInfo = inputContentInfo;
+            return this;
+        }
+
+        /**
+         * Set the {@link DragAndDropPermissions} object if the content is coming via drag-and-drop.
+         * This can be used for proactive cleanup of permissions.
+         *
+         * @hide
+         */
+        @NonNull
+        public Builder setDragAndDropPermissions(@Nullable DragAndDropPermissions permissions) {
+            mDragAndDropPermissions = permissions;
+            return this;
+        }
+
+
+        /**
          * @return A new {@link ContentInfo} instance with the data from this builder.
          */
         @NonNull
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index d484f4d4..bf152cb 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -44,6 +44,7 @@
 import android.os.Parcelable;
 import android.os.Process;
 import android.os.SystemClock;
+import android.util.ArraySet;
 import android.util.DisplayMetrics;
 import android.util.Log;
 
@@ -1066,7 +1067,47 @@
     public HdrCapabilities getHdrCapabilities() {
         synchronized (mLock) {
             updateDisplayInfoLocked();
-            return mDisplayInfo.hdrCapabilities;
+            if (mDisplayInfo.userDisabledHdrTypes.length == 0) {
+                return mDisplayInfo.hdrCapabilities;
+            }
+            ArraySet<Integer> enabledTypesSet = new ArraySet<>();
+            for (int supportedType : mDisplayInfo.hdrCapabilities.getSupportedHdrTypes()) {
+                boolean typeDisabled = false;
+                for (int userDisabledType : mDisplayInfo.userDisabledHdrTypes) {
+                    if (supportedType == userDisabledType) {
+                        typeDisabled = true;
+                        break;
+                    }
+                }
+                if (!typeDisabled) {
+                    enabledTypesSet.add(supportedType);
+                }
+            }
+            int[] enabledTypes = new int[enabledTypesSet.size()];
+            int index = 0;
+            for (int enabledType : enabledTypesSet) {
+                enabledTypes[index++] = enabledType;
+            }
+            return new HdrCapabilities(enabledTypes,
+                    mDisplayInfo.hdrCapabilities.mMaxLuminance,
+                    mDisplayInfo.hdrCapabilities.mMaxAverageLuminance,
+                    mDisplayInfo.hdrCapabilities.mMinLuminance);
+        }
+    }
+
+    /**
+     * @hide
+     * Returns the display's HDR supported types.
+     *
+     * @see #isHdr()
+     * @see HdrCapabilities#getSupportedHdrTypes()
+     */
+    @TestApi
+    @NonNull
+    public int[] getReportedHdrTypes() {
+        synchronized (mLock) {
+            updateDisplayInfoLocked();
+            return mDisplayInfo.hdrCapabilities.getSupportedHdrTypes();
         }
     }
 
@@ -1079,7 +1120,7 @@
     public boolean isHdr() {
         synchronized (mLock) {
             updateDisplayInfoLocked();
-            return mDisplayInfo.isHdr();
+            return !(getHdrCapabilities().getSupportedHdrTypes().length == 0);
         }
     }
 
@@ -1855,6 +1896,14 @@
         public static final int HDR_TYPE_HDR10_PLUS = 4;
 
         /** @hide */
+        public static final int[] HDR_TYPES = {
+                HDR_TYPE_DOLBY_VISION,
+                HDR_TYPE_HDR10,
+                HDR_TYPE_HLG,
+                HDR_TYPE_HDR10_PLUS
+        };
+
+        /** @hide */
         @IntDef(prefix = { "HDR_TYPE_" }, value = {
                 HDR_TYPE_DOLBY_VISION,
                 HDR_TYPE_HDR10,
diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java
index 9aaf5c0..36be9f8 100644
--- a/core/java/android/view/DisplayInfo.java
+++ b/core/java/android/view/DisplayInfo.java
@@ -198,6 +198,9 @@
     /** The display's HDR capabilities */
     public Display.HdrCapabilities hdrCapabilities;
 
+    /** The formats disabled by user **/
+    public int[] userDisabledHdrTypes = {};
+
     /**
      * Indicates whether the display can be switched into a mode with minimal post
      * processing.
@@ -363,6 +366,7 @@
                 && colorMode == other.colorMode
                 && Arrays.equals(supportedColorModes, other.supportedColorModes)
                 && Objects.equals(hdrCapabilities, other.hdrCapabilities)
+                && Arrays.equals(userDisabledHdrTypes, other.userDisabledHdrTypes)
                 && minimalPostProcessingSupported == other.minimalPostProcessingSupported
                 && logicalDensityDpi == other.logicalDensityDpi
                 && physicalXDpi == other.physicalXDpi
@@ -412,6 +416,7 @@
         supportedColorModes = Arrays.copyOf(
                 other.supportedColorModes, other.supportedColorModes.length);
         hdrCapabilities = other.hdrCapabilities;
+        userDisabledHdrTypes = other.userDisabledHdrTypes;
         minimalPostProcessingSupported = other.minimalPostProcessingSupported;
         logicalDensityDpi = other.logicalDensityDpi;
         physicalXDpi = other.physicalXDpi;
@@ -478,6 +483,11 @@
         brightnessMaximum = source.readFloat();
         brightnessDefault = source.readFloat();
         roundedCorners = source.readTypedObject(RoundedCorners.CREATOR);
+        int numUserDisabledFormats = source.readInt();
+        userDisabledHdrTypes = new int[numUserDisabledFormats];
+        for (int i = 0; i < numUserDisabledFormats; i++) {
+            userDisabledHdrTypes[i] = source.readInt();
+        }
     }
 
     @Override
@@ -528,6 +538,10 @@
         dest.writeFloat(brightnessMaximum);
         dest.writeFloat(brightnessDefault);
         dest.writeTypedObject(roundedCorners, flags);
+        dest.writeInt(userDisabledHdrTypes.length);
+        for (int i = 0; i < userDisabledHdrTypes.length; i++) {
+            dest.writeInt(userDisabledHdrTypes[i]);
+        }
     }
 
     @Override
@@ -729,6 +743,8 @@
         sb.append(Arrays.toString(supportedModes));
         sb.append(", hdrCapabilities ");
         sb.append(hdrCapabilities);
+        sb.append(", userDisabledHdrTypes ");
+        sb.append(Arrays.toString(userDisabledHdrTypes));
         sb.append(", minimalPostProcessingSupported ");
         sb.append(minimalPostProcessingSupported);
         sb.append(", rotation ");
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index a42126f..d0a3e4b 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -777,11 +777,20 @@
     VerifiedDisplayHash verifyDisplayHash(in DisplayHash displayHash);
 
     /**
-     * Registers a listener for a {@link android.app.WindowContext} to handle configuration changes
-     * from the server side.
+     * Call to enable or disable the throttling when generating a display hash. This should only be
+     * used for testing. Throttling is enabled by default.
+     *
+     * Must be called from a process that has {@link android.Manifest.permission#READ_FRAME_BUFFER}
+     * permission.
+     */
+     void setDisplayHashThrottlingEnabled(boolean enable);
+
+    /**
+     * Registers a listener for a {@link android.window.WindowContext} to handle configuration
+     * changes from the server side.
      * <p>
      * Note that this API should be invoked after calling
-     * {@link android.app.WindowTokenClient#attachContext(WindowContext)}
+     * {@link android.window.WindowTokenClient#attachContext(Context)}
      * </p>
      *
      * @param clientToken the window context's token
diff --git a/core/java/android/view/ImeInsetsSourceConsumer.java b/core/java/android/view/ImeInsetsSourceConsumer.java
index f4d5a7b..0686104 100644
--- a/core/java/android/view/ImeInsetsSourceConsumer.java
+++ b/core/java/android/view/ImeInsetsSourceConsumer.java
@@ -50,13 +50,9 @@
         super(ITYPE_IME, state, transactionSupplier, controller);
     }
 
-    public void applyImeVisibility(boolean setVisible) {
-        mController.applyImeVisibility(setVisible);
-    }
-
     @Override
-    public void onWindowFocusGained() {
-        super.onWindowFocusGained();
+    public void onWindowFocusGained(boolean hasViewFocus) {
+        super.onWindowFocusGained(hasViewFocus);
         getImm().registerImeConsumer(this);
     }
 
@@ -68,8 +64,14 @@
     }
 
     @Override
-    void hide(boolean animationFinished, @AnimationType int animationType) {
+    public void hide() {
         super.hide();
+        mIsRequestedVisibleAwaitingControl = false;
+    }
+
+    @Override
+    void hide(boolean animationFinished, @AnimationType int animationType) {
+        hide();
 
         if (animationFinished) {
             // remove IME surface as IME has finished hide animation.
@@ -126,6 +128,9 @@
             hide();
             removeSurface();
         }
+        if (control != null) {
+            mIsRequestedVisibleAwaitingControl = false;
+        }
     }
 
     @Override
diff --git a/core/java/android/view/InputEventAssigner.java b/core/java/android/view/InputEventAssigner.java
index c159a12..7fac6c5 100644
--- a/core/java/android/view/InputEventAssigner.java
+++ b/core/java/android/view/InputEventAssigner.java
@@ -45,13 +45,13 @@
 public class InputEventAssigner {
     private static final String TAG = "InputEventAssigner";
     private boolean mHasUnprocessedDown = false;
-    private int mEventId = INVALID_INPUT_EVENT_ID;
+    private int mDownEventId = INVALID_INPUT_EVENT_ID;
 
     /**
-     * Notify InputEventAssigner that the Choreographer callback has been processed. This will reset
-     * the 'down' state to assign the latest input event to the current frame.
+     * Notify InputEventAssigner that a frame has been processed. We no longer need to keep track of
+     * the DOWN event because a frame has already been produced for it.
      */
-    public void onChoreographerCallback() {
+    public void notifyFrameProcessed() {
         // Mark completion of this frame. Use newest input event from now on.
         mHasUnprocessedDown = false;
     }
@@ -62,31 +62,22 @@
      * @return the id of the input event to use for the current frame
      */
     public int processEvent(InputEvent event) {
-        if (event instanceof KeyEvent) {
-            // We will not do any special handling for key events
-            return event.getId();
-        }
-
         if (event instanceof MotionEvent) {
             MotionEvent motionEvent = (MotionEvent) event;
-            final int action = motionEvent.getActionMasked();
-
-            if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
-                mHasUnprocessedDown = false;
+            if (motionEvent.isFromSource(SOURCE_TOUCHSCREEN)) {
+                final int action = motionEvent.getActionMasked();
+                if (action == MotionEvent.ACTION_DOWN) {
+                    mHasUnprocessedDown = true;
+                    mDownEventId = event.getId();
+                }
+                if (mHasUnprocessedDown && action == MotionEvent.ACTION_MOVE) {
+                    return mDownEventId;
+                }
+                if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
+                    mHasUnprocessedDown = false;
+                }
             }
-            if (motionEvent.isFromSource(SOURCE_TOUCHSCREEN) && action == MotionEvent.ACTION_DOWN) {
-                mHasUnprocessedDown = true;
-                mEventId = event.getId();
-                // This will remain 'true' even if we receive a MOVE event, as long as choreographer
-                // hasn't invoked the 'CALLBACK_INPUT' callback.
-            }
-            // Don't update the event id if we haven't processed DOWN yet.
-            if (!mHasUnprocessedDown) {
-                mEventId = event.getId();
-            }
-            return mEventId;
         }
-
-        throw new IllegalArgumentException("Received unexpected " + event);
+        return event.getId();
     }
 }
diff --git a/core/java/android/view/InsetsAnimationControlImpl.java b/core/java/android/view/InsetsAnimationControlImpl.java
index 7a61df8..a67ec10 100644
--- a/core/java/android/view/InsetsAnimationControlImpl.java
+++ b/core/java/android/view/InsetsAnimationControlImpl.java
@@ -269,7 +269,7 @@
         }
         mShownOnFinish = shown;
         mFinished = true;
-        setInsetsAndAlpha(shown ? mShownInsets : mHiddenInsets, 1f /* alpha */, 1f /* fraction */,
+        setInsetsAndAlpha(shown ? mShownInsets : mHiddenInsets, mPendingAlpha, 1f /* fraction */,
                 true /* allowWhenFinished */);
 
         if (DEBUG) Log.d(TAG, "notify control request finished for types: " + mTypes);
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index 8bf78db3..c001ec9 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -189,16 +189,34 @@
     }
 
     private static final String TAG = "InsetsController";
-    private static final int ANIMATION_DURATION_SHOW_MS = 275;
-    private static final int ANIMATION_DURATION_HIDE_MS = 340;
+    private static final int ANIMATION_DURATION_MOVE_IN_MS = 275;
+    private static final int ANIMATION_DURATION_MOVE_OUT_MS = 340;
+    private static final int ANIMATION_DURATION_FADE_IN_MS = 500;
+    private static final int ANIMATION_DURATION_FADE_OUT_MS = 1500;
+
+    private static final int ANIMATION_DELAY_DIM_MS = 500;
 
     private static final int ANIMATION_DURATION_SYNC_IME_MS = 285;
     private static final int ANIMATION_DURATION_UNSYNC_IME_MS = 200;
 
     private static final int PENDING_CONTROL_TIMEOUT_MS = 2000;
 
-    public static final Interpolator SYSTEM_BARS_INTERPOLATOR =
+    private static final Interpolator SYSTEM_BARS_INSETS_INTERPOLATOR =
             new PathInterpolator(0.4f, 0f, 0.2f, 1f);
+    private static final Interpolator SYSTEM_BARS_ALPHA_INTERPOLATOR =
+            new PathInterpolator(0.3f, 0f, 1f, 1f);
+    private static final Interpolator SYSTEM_BARS_DIM_INTERPOLATOR = alphaFraction -> {
+        // While playing dim animation, alphaFraction is changed from 1f to 0f. Here changes it to
+        // time-based fraction for computing delay and interpolation.
+        float fraction = 1 - alphaFraction;
+        final float fractionDelay = (float) ANIMATION_DELAY_DIM_MS / ANIMATION_DURATION_FADE_OUT_MS;
+        if (fraction <= fractionDelay) {
+            return 1f;
+        } else {
+            float innerFraction = (fraction - fractionDelay) / (1f - fractionDelay);
+            return 1f - SYSTEM_BARS_ALPHA_INTERPOLATOR.getInterpolation(innerFraction);
+        }
+    };
     private static final Interpolator SYNC_IME_INTERPOLATOR =
             new PathInterpolator(0.2f, 0f, 0f, 1f);
     private static final Interpolator LINEAR_OUT_SLOW_IN_INTERPOLATOR =
@@ -206,6 +224,9 @@
     private static final Interpolator FAST_OUT_LINEAR_IN_INTERPOLATOR =
             new PathInterpolator(0.4f, 0f, 1f, 1f);
 
+    /** The amount IME will move up/down when animating in floating mode. */
+    private static final int FLOATING_IME_BOTTOM_INSET_DP = -80;
+
     static final boolean DEBUG = false;
     static final boolean WARN = false;
 
@@ -278,14 +299,12 @@
     public static class InternalAnimationControlListener
             implements WindowInsetsAnimationControlListener {
 
-        /** The amount IME will move up/down when animating in floating mode. */
-        protected static final int FLOATING_IME_BOTTOM_INSET = -80;
-
         private WindowInsetsAnimationController mController;
         private ValueAnimator mAnimator;
         private final boolean mShow;
         private final boolean mHasAnimationCallbacks;
         private final @InsetsType int mRequestedTypes;
+        private final @Behavior int mBehavior;
         private final long mDurationMs;
         private final boolean mDisable;
         private final int mFloatingImeBottomInset;
@@ -301,10 +320,12 @@
         };
 
         public InternalAnimationControlListener(boolean show, boolean hasAnimationCallbacks,
-                int requestedTypes, boolean disable, int floatingImeBottomInset) {
+                @InsetsType int requestedTypes, @Behavior int behavior, boolean disable,
+                int floatingImeBottomInset) {
             mShow = show;
             mHasAnimationCallbacks = hasAnimationCallbacks;
             mRequestedTypes = requestedTypes;
+            mBehavior = behavior;
             mDurationMs = calculateDurationMs();
             mDisable = disable;
             mFloatingImeBottomInset = floatingImeBottomInset;
@@ -335,7 +356,7 @@
             Insets end = mShow
                     ? controller.getShownStateInsets()
                     : hiddenInsets;
-            Interpolator insetsInterpolator = getInterpolator();
+            Interpolator insetsInterpolator = getInsetsInterpolator();
             Interpolator alphaInterpolator = getAlphaInterpolator();
             mAnimator.addUpdateListener(animation -> {
                 float rawFraction = animation.getAnimatedFraction();
@@ -379,7 +400,7 @@
                     + mRequestedTypes);
         }
 
-        Interpolator getInterpolator() {
+        protected Interpolator getInsetsInterpolator() {
             if ((mRequestedTypes & ime()) != 0) {
                 if (mHasAnimationCallbacks) {
                     return SYNC_IME_INTERPOLATOR;
@@ -389,7 +410,12 @@
                     return FAST_OUT_LINEAR_IN_INTERPOLATOR;
                 }
             } else {
-                return SYSTEM_BARS_INTERPOLATOR;
+                if (mBehavior == BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE) {
+                    return SYSTEM_BARS_INSETS_INTERPOLATOR;
+                } else {
+                    // Makes insets stay at the shown position.
+                    return input -> mShow ? 1f : 0f;
+                }
             }
         }
 
@@ -405,7 +431,15 @@
                     return FAST_OUT_LINEAR_IN_INTERPOLATOR;
                 }
             } else {
-                return input -> 1f;
+                if (mBehavior == BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE) {
+                    return input -> 1f;
+                } else {
+                    if (mShow) {
+                        return SYSTEM_BARS_ALPHA_INTERPOLATOR;
+                    } else {
+                        return SYSTEM_BARS_DIM_INTERPOLATOR;
+                    }
+                }
             }
         }
 
@@ -429,7 +463,11 @@
                     return ANIMATION_DURATION_UNSYNC_IME_MS;
                 }
             } else {
-                return mShow ? ANIMATION_DURATION_SHOW_MS : ANIMATION_DURATION_HIDE_MS;
+                if (mBehavior == BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE) {
+                    return mShow ? ANIMATION_DURATION_MOVE_IN_MS : ANIMATION_DURATION_MOVE_OUT_MS;
+                } else {
+                    return mShow ? ANIMATION_DURATION_FADE_IN_MS : ANIMATION_DURATION_FADE_OUT_MS;
+                }
             }
         }
     }
@@ -882,7 +920,8 @@
         hide(types, false /* fromIme */);
     }
 
-    void hide(@InsetsType int types, boolean fromIme) {
+    @VisibleForTesting
+    public void hide(@InsetsType int types, boolean fromIme) {
         if (fromIme) {
             ImeTracing.getInstance().triggerClientDump("InsetsController#hide",
                     mHost.getInputMethodManager(), null /* icProto */);
@@ -1263,8 +1302,8 @@
     /**
      * Called when current window gains focus.
      */
-    public void onWindowFocusGained() {
-        getSourceConsumer(ITYPE_IME).onWindowFocusGained();
+    public void onWindowFocusGained(boolean hasViewFocused) {
+        getSourceConsumer(ITYPE_IME).onWindowFocusGained(hasViewFocused);
     }
 
     /**
@@ -1274,19 +1313,6 @@
         getSourceConsumer(ITYPE_IME).onWindowFocusLost();
     }
 
-    /**
-     * Used by {@link ImeInsetsSourceConsumer} when IME decides to be shown/hidden.
-     * @hide
-     */
-    @VisibleForTesting
-    public void applyImeVisibility(boolean setVisible) {
-        if (setVisible) {
-            show(Type.IME, true /* fromIme */);
-        } else {
-            hide(Type.IME);
-        }
-    }
-
     @VisibleForTesting
     public @AnimationType int getAnimationType(@InternalInsetsType int type) {
         for (int i = mRunningAnimations.size() - 1; i >= 0; i--) {
@@ -1340,8 +1366,9 @@
             final InsetsSourceControl imeControl = consumer != null ? consumer.getControl() : null;
             // Skip showing animation once that made by system for some reason.
             // (e.g. starting window with IME snapshot)
-            if (imeControl != null && show) {
-                skipAnim = imeControl.getAndClearSkipAnimationOnce();
+            if (imeControl != null) {
+                skipAnim = imeControl.getAndClearSkipAnimationOnce() && show
+                        && consumer.hasViewFocusWhenWindowFocusGain();
             }
         }
         applyAnimation(types, show, fromIme, skipAnim);
@@ -1358,14 +1385,14 @@
 
         boolean hasAnimationCallbacks = mHost.hasAnimationCallbacks();
         final InternalAnimationControlListener listener = new InternalAnimationControlListener(
-                show, hasAnimationCallbacks, types, skipAnim || mAnimationsDisabled,
-                mHost.dipToPx(InternalAnimationControlListener.FLOATING_IME_BOTTOM_INSET));
+                show, hasAnimationCallbacks, types, mHost.getSystemBarsBehavior(),
+                skipAnim || mAnimationsDisabled, mHost.dipToPx(FLOATING_IME_BOTTOM_INSET_DP));
 
         // We are about to playing the default animation (show/hide). Passing a null frame indicates
         // the controlled types should be animated regardless of the frame.
         controlAnimationUnchecked(
                 types, null /* cancellationSignal */, listener, null /* frame */, fromIme,
-                listener.getDurationMs(), listener.getInterpolator(),
+                listener.getDurationMs(), listener.getInsetsInterpolator(),
                 show ? ANIMATION_TYPE_SHOW : ANIMATION_TYPE_HIDE,
                 show ? LAYOUT_INSETS_DURING_ANIMATION_SHOWN : LAYOUT_INSETS_DURING_ANIMATION_HIDDEN,
                 !hasAnimationCallbacks /* useInsetsAnimationThread */);
diff --git a/core/java/android/view/InsetsSourceConsumer.java b/core/java/android/view/InsetsSourceConsumer.java
index fd1c3b8..bc50dbe 100644
--- a/core/java/android/view/InsetsSourceConsumer.java
+++ b/core/java/android/view/InsetsSourceConsumer.java
@@ -81,6 +81,11 @@
     private final Supplier<Transaction> mTransactionSupplier;
     private @Nullable InsetsSourceControl mSourceControl;
     private boolean mHasWindowFocus;
+
+    /**
+     * Whether the view has focus returned by {@link #onWindowFocusGained(boolean)}.
+     */
+    private boolean mHasViewFocusWhenWindowFocusGain;
     private Rect mPendingFrame;
     private Rect mPendingVisibleFrame;
 
@@ -223,8 +228,9 @@
     /**
      * Called when current window gains focus
      */
-    public void onWindowFocusGained() {
+    public void onWindowFocusGained(boolean hasViewFocus) {
         mHasWindowFocus = true;
+        mHasViewFocusWhenWindowFocusGain = hasViewFocus;
     }
 
     /**
@@ -238,6 +244,10 @@
         return mHasWindowFocus;
     }
 
+    boolean hasViewFocusWhenWindowFocusGain() {
+        return mHasViewFocusWhenWindowFocusGain;
+    }
+
     boolean applyLocalVisibilityOverride() {
         final InsetsSource source = mState.peekSource(mType);
         final boolean isVisible = source != null ? source.isVisible() : getDefaultVisibility(mType);
diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java
index 6801c27..dea32cd 100644
--- a/core/java/android/view/MotionEvent.java
+++ b/core/java/android/view/MotionEvent.java
@@ -16,6 +16,7 @@
 
 package android.view;
 
+import static android.hardware.input.InputManager.APP_USES_RAW_INPUT_COORDS;
 import static android.view.Display.DEFAULT_DISPLAY;
 
 import static java.lang.annotation.RetentionPolicy.SOURCE;
@@ -23,6 +24,7 @@
 import android.annotation.IntDef;
 import android.annotation.Nullable;
 import android.annotation.TestApi;
+import android.compat.Compatibility;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.graphics.Matrix;
 import android.os.Build;
@@ -2672,6 +2674,7 @@
      * @see #AXIS_X
      */
     public final float getRawX() {
+        Compatibility.reportChange(APP_USES_RAW_INPUT_COORDS);
         return nativeGetRawAxisValue(mNativePtr, AXIS_X, 0, HISTORY_CURRENT);
     }
 
@@ -2685,6 +2688,7 @@
      * @see #AXIS_Y
      */
     public final float getRawY() {
+        Compatibility.reportChange(APP_USES_RAW_INPUT_COORDS);
         return nativeGetRawAxisValue(mNativePtr, AXIS_Y, 0, HISTORY_CURRENT);
     }
 
@@ -2701,6 +2705,7 @@
      * @see #AXIS_X
      */
     public float getRawX(int pointerIndex) {
+        Compatibility.reportChange(APP_USES_RAW_INPUT_COORDS);
         return nativeGetRawAxisValue(mNativePtr, AXIS_X, pointerIndex, HISTORY_CURRENT);
     }
 
@@ -2717,6 +2722,7 @@
      * @see #AXIS_Y
      */
     public float getRawY(int pointerIndex) {
+        Compatibility.reportChange(APP_USES_RAW_INPUT_COORDS);
         return nativeGetRawAxisValue(mNativePtr, AXIS_Y, pointerIndex, HISTORY_CURRENT);
     }
 
diff --git a/core/java/android/view/NotificationTopLineView.java b/core/java/android/view/NotificationTopLineView.java
index 05636de..bd20f5b 100644
--- a/core/java/android/view/NotificationTopLineView.java
+++ b/core/java/android/view/NotificationTopLineView.java
@@ -26,6 +26,9 @@
 
 import com.android.internal.R;
 
+import java.util.HashSet;
+import java.util.Set;
+
 /**
  * The top line of content in a notification view.
  * This includes the text views and badges but excludes the icon and the expander.
@@ -34,17 +37,23 @@
  */
 @RemoteViews.RemoteView
 public class NotificationTopLineView extends ViewGroup {
+    private final OverflowAdjuster mOverflowAdjuster = new OverflowAdjuster();
     private final int mGravityY;
     private final int mChildMinWidth;
+    private final int mChildHideWidth;
     @Nullable private View mAppName;
     @Nullable private View mTitle;
     private View mHeaderText;
+    private View mHeaderTextDivider;
     private View mSecondaryHeaderText;
+    private View mSecondaryHeaderTextDivider;
     private OnClickListener mFeedbackListener;
     private HeaderTouchListener mTouchListener = new HeaderTouchListener();
     private View mFeedbackIcon;
     private int mHeaderTextMarginEnd;
 
+    private Set<View> mViewsToDisappear = new HashSet<>();
+
     private int mMaxAscent;
     private int mMaxDescent;
 
@@ -66,6 +75,7 @@
         super(context, attrs, defStyleAttr, defStyleRes);
         Resources res = getResources();
         mChildMinWidth = res.getDimensionPixelSize(R.dimen.notification_header_shrink_min_width);
+        mChildHideWidth = res.getDimensionPixelSize(R.dimen.notification_header_shrink_hide_width);
 
         // NOTE: Implementation only supports TOP, BOTTOM, and CENTER_VERTICAL gravities,
         // with CENTER_VERTICAL being the default.
@@ -88,7 +98,9 @@
         mAppName = findViewById(R.id.app_name_text);
         mTitle = findViewById(R.id.title);
         mHeaderText = findViewById(R.id.header_text);
+        mHeaderTextDivider = findViewById(R.id.header_text_divider);
         mSecondaryHeaderText = findViewById(R.id.header_text_secondary);
+        mSecondaryHeaderTextDivider = findViewById(R.id.header_text_secondary_divider);
         mFeedbackIcon = findViewById(R.id.feedback);
     }
 
@@ -125,48 +137,37 @@
             maxChildHeight = Math.max(maxChildHeight, childHeight);
         }
 
+        mViewsToDisappear.clear();
         // Ensure that there is at least enough space for the icons
         int endMargin = Math.max(mHeaderTextMarginEnd, getPaddingEnd());
         if (totalWidth > givenWidth - endMargin) {
             int overFlow = totalWidth - givenWidth + endMargin;
 
-            // First shrink the app name, down to a minimum size
-            overFlow = shrinkViewForOverflow(heightSpec, overFlow, mAppName, mChildMinWidth);
-
-            // Next, shrink the header text (this usually has subText)
-            //   This shrinks the subtext first, but not all the way (yet!)
-            overFlow = shrinkViewForOverflow(heightSpec, overFlow, mHeaderText, mChildMinWidth);
-
-            // Next, shrink the secondary header text  (this rarely has conversationTitle)
-            overFlow = shrinkViewForOverflow(heightSpec, overFlow, mSecondaryHeaderText, 0);
-
-            // Next, shrink the title text (this has contentTitle; only in headerless views)
-            overFlow = shrinkViewForOverflow(heightSpec, overFlow, mTitle, mChildMinWidth);
-
-            // Finally, if there is still overflow, shrink the header down to 0 if still necessary.
-            shrinkViewForOverflow(heightSpec, overFlow, mHeaderText, 0);
+            mOverflowAdjuster.resetForOverflow(overFlow, heightSpec)
+                    // First shrink the app name, down to a minimum size
+                    .adjust(mAppName, null, mChildMinWidth)
+                    // Next, shrink the header text (this usually has subText)
+                    //   This shrinks the subtext first, but not all the way (yet!)
+                    .adjust(mHeaderText, mHeaderTextDivider, mChildMinWidth)
+                    // Next, shrink the secondary header text  (this rarely has conversationTitle)
+                    .adjust(mSecondaryHeaderText, mSecondaryHeaderTextDivider, 0)
+                    // Next, shrink the title text (this has contentTitle; only in headerless views)
+                    .adjust(mTitle, null, mChildMinWidth)
+                    // Next, shrink the header down to 0 if still necessary.
+                    .adjust(mHeaderText, mHeaderTextDivider, 0)
+                    // Finally, shrink the title to 0 if necessary (media is super cramped)
+                    .adjust(mTitle, null, 0)
+                    // Clean up
+                    .finish();
         }
         setMeasuredDimension(givenWidth, wrapHeight ? maxChildHeight : givenHeight);
     }
 
-    private int shrinkViewForOverflow(int heightSpec, int overFlow, View targetView,
-            int minimumWidth) {
-        if (targetView != null) {
-            final int oldWidth = targetView.getMeasuredWidth();
-            if (overFlow > 0 && targetView.getVisibility() != GONE && oldWidth > minimumWidth) {
-                // we're still too big
-                int newSize = Math.max(minimumWidth, oldWidth - overFlow);
-                int childWidthSpec = MeasureSpec.makeMeasureSpec(newSize, MeasureSpec.AT_MOST);
-                targetView.measure(childWidthSpec, heightSpec);
-                overFlow -= oldWidth - newSize;
-            }
-        }
-        return overFlow;
-    }
-
     @Override
     protected void onLayout(boolean changed, int l, int t, int r, int b) {
-        int left = getPaddingStart();
+        final boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
+        final int width = getWidth();
+        int start = getPaddingStart();
         int childCount = getChildCount();
         int ownHeight = b - t;
         int childSpace = ownHeight - mPaddingTop - mPaddingBottom;
@@ -182,8 +183,6 @@
             }
             int childHeight = child.getMeasuredHeight();
             MarginLayoutParams params = (MarginLayoutParams) child.getLayoutParams();
-            int layoutLeft;
-            int layoutRight;
 
             // Calculate vertical alignment of the views, accounting for the view baselines
             int childTop;
@@ -219,19 +218,16 @@
                 default:
                     childTop = mPaddingTop;
             }
-
-            left += params.getMarginStart();
-            int right = left + child.getMeasuredWidth();
-            layoutLeft = left;
-            layoutRight = right;
-            left = right + params.getMarginEnd();
-
-            if (getLayoutDirection() == LAYOUT_DIRECTION_RTL) {
-                int ltrLeft = layoutLeft;
-                layoutLeft = getWidth() - layoutRight;
-                layoutRight = getWidth() - ltrLeft;
+            if (mViewsToDisappear.contains(child)) {
+                child.layout(start, childTop, start, childTop + childHeight);
+            } else {
+                start += params.getMarginStart();
+                int end = start + child.getMeasuredWidth();
+                int layoutLeft = isRtl ? width - end : start;
+                int layoutRight = isRtl ? width - start : end;
+                start = end + params.getMarginEnd();
+                child.layout(layoutLeft, childTop, layoutRight, childTop + childHeight);
             }
-            child.layout(layoutLeft, childTop, layoutRight, childTop + childHeight);
         }
         updateTouchListener();
     }
@@ -400,4 +396,83 @@
         }
         return mTouchListener.onTouchUp(upX, upY, downX, downY);
     }
+
+    private final class OverflowAdjuster {
+        private int mOverflow;
+        private int mHeightSpec;
+        private View mRegrowView;
+
+        OverflowAdjuster resetForOverflow(int overflow, int heightSpec) {
+            mOverflow = overflow;
+            mHeightSpec = heightSpec;
+            mRegrowView = null;
+            return this;
+        }
+
+        /**
+         * Shrink the targetView's width by up to overFlow, down to minimumWidth.
+         * @param targetView the view to shrink the width of
+         * @param targetDivider a divider view which should be set to 0 width if the targetView is
+         * @param minimumWidth the minimum width allowed for the targetView
+         * @return this object
+         */
+        OverflowAdjuster adjust(View targetView, View targetDivider, int minimumWidth) {
+            if (mOverflow <= 0 || targetView == null || targetView.getVisibility() == View.GONE) {
+                return this;
+            }
+            final int oldWidth = targetView.getMeasuredWidth();
+            if (oldWidth <= minimumWidth) {
+                return this;
+            }
+            // we're too big
+            int newSize = Math.max(minimumWidth, oldWidth - mOverflow);
+            if (minimumWidth == 0 && newSize < mChildHideWidth
+                    && mRegrowView != null && mRegrowView != targetView) {
+                // View is so small it's better to hide it entirely (and its divider and margins)
+                // so we can give that space back to another previously shrunken view.
+                newSize = 0;
+            }
+
+            int childWidthSpec = MeasureSpec.makeMeasureSpec(newSize, MeasureSpec.AT_MOST);
+            targetView.measure(childWidthSpec, mHeightSpec);
+            mOverflow -= oldWidth - newSize;
+
+            if (newSize == 0) {
+                mViewsToDisappear.add(targetView);
+                mOverflow -= getHorizontalMargins(targetView);
+                if (targetDivider != null && targetDivider.getVisibility() != GONE) {
+                    mViewsToDisappear.add(targetDivider);
+                    int oldDividerWidth = targetDivider.getMeasuredWidth();
+                    int dividerWidthSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.AT_MOST);
+                    targetDivider.measure(dividerWidthSpec, mHeightSpec);
+                    mOverflow -= (oldDividerWidth + getHorizontalMargins(targetDivider));
+                }
+            }
+            if (mOverflow < 0 && mRegrowView != null) {
+                // We're now under-flowing, so regrow the last view.
+                final int regrowCurrentSize = mRegrowView.getMeasuredWidth();
+                final int maxSize = regrowCurrentSize - mOverflow;
+                int regrowWidthSpec = MeasureSpec.makeMeasureSpec(maxSize, MeasureSpec.AT_MOST);
+                mRegrowView.measure(regrowWidthSpec, mHeightSpec);
+                finish();
+                return this;
+            }
+
+            if (newSize != 0) {
+                // if we shrunk this view (but did not completely hide it) store it for potential
+                // re-growth if we proactively shorten a future view.
+                mRegrowView = targetView;
+            }
+            return this;
+        }
+
+        void finish() {
+            resetForOverflow(0, 0);
+        }
+
+        private int getHorizontalMargins(View view) {
+            MarginLayoutParams params = (MarginLayoutParams) view.getLayoutParams();
+            return params.getMarginStart() + params.getMarginEnd();
+        }
+    }
 }
diff --git a/core/java/android/view/OWNERS b/core/java/android/view/OWNERS
index 31f6f6a..4a1d685 100644
--- a/core/java/android/view/OWNERS
+++ b/core/java/android/view/OWNERS
@@ -9,6 +9,7 @@
 ogunwale@google.com
 jjaggi@google.com
 roosa@google.com
+jreck@google.com
 
 # Display
 per-file Display*.java = file:/services/core/java/com/android/server/display/OWNERS
diff --git a/core/java/android/view/RoundedCorner.java b/core/java/android/view/RoundedCorner.java
index 56b4383..d10fc44 100644
--- a/core/java/android/view/RoundedCorner.java
+++ b/core/java/android/view/RoundedCorner.java
@@ -29,16 +29,10 @@
 
 /**
  * Represents a rounded corner of the display.
- *
- * <code>
- *       ________
- *     /        ^
- *    /         | Radius
- *    |         v
- *    |       X <- Center point
- *    |<----->
- *     Radius
- * </code>
+ * <p>
+ * <img src="{@docRoot}reference/android/images/rounded_corner/rounded-corner-info.png" height="120"
+ * alt="A figure to describe what the rounded corner radius and the center point are. "/>
+ * </p>
  *
  * <p>Note: The rounded corner formed by the radius and the center is an approximation.</p>
  *
diff --git a/core/java/android/view/SoundEffectConstants.java b/core/java/android/view/SoundEffectConstants.java
index f177451..bd86a47 100644
--- a/core/java/android/view/SoundEffectConstants.java
+++ b/core/java/android/view/SoundEffectConstants.java
@@ -16,11 +16,14 @@
 
 package android.view;
 
+import android.annotation.IntDef;
 import android.media.AudioManager;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.annotations.VisibleForTesting.Visibility;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.Random;
 
 /**
@@ -34,25 +37,55 @@
 
     public static final int CLICK = 0;
 
+    /** Effect id for a navigation left */
     public static final int NAVIGATION_LEFT = 1;
+    /** Effect id for a navigation up */
     public static final int NAVIGATION_UP = 2;
+    /** Effect id for a navigation right */
     public static final int NAVIGATION_RIGHT = 3;
+    /** Effect id for a navigation down */
     public static final int NAVIGATION_DOWN = 4;
-    /** Sound effect for a repeatedly triggered navigation, e.g. due to long pressing a button */
+    /** Effect id for a repeatedly triggered navigation left, e.g. due to long pressing a button */
     public static final int NAVIGATION_REPEAT_LEFT = 5;
-    /** @see #NAVIGATION_REPEAT_LEFT */
+    /** Effect id for a repeatedly triggered navigation up, e.g. due to long pressing a button */
     public static final int NAVIGATION_REPEAT_UP = 6;
-    /** @see #NAVIGATION_REPEAT_LEFT */
+    /** Effect id for a repeatedly triggered navigation right, e.g. due to long pressing a button */
     public static final int NAVIGATION_REPEAT_RIGHT = 7;
-    /** @see #NAVIGATION_REPEAT_LEFT */
+    /** Effect id for a repeatedly triggered navigation down, e.g. due to long pressing a button */
     public static final int NAVIGATION_REPEAT_DOWN = 8;
 
+    /** @hide */
+    @IntDef(value = {
+            CLICK,
+            NAVIGATION_LEFT,
+            NAVIGATION_UP,
+            NAVIGATION_RIGHT,
+            NAVIGATION_DOWN,
+            NAVIGATION_REPEAT_LEFT,
+            NAVIGATION_REPEAT_UP,
+            NAVIGATION_REPEAT_RIGHT,
+            NAVIGATION_REPEAT_DOWN
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface SoundEffect {}
+
+    /** @hide */
+    @IntDef(prefix = { "NAVIGATION_" }, value = {
+            NAVIGATION_LEFT,
+            NAVIGATION_UP,
+            NAVIGATION_RIGHT,
+            NAVIGATION_DOWN,
+            NAVIGATION_REPEAT_LEFT,
+            NAVIGATION_REPEAT_UP,
+            NAVIGATION_REPEAT_RIGHT,
+            NAVIGATION_REPEAT_DOWN
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface NavigationSoundEffect {}
+
     /**
      * Get the sonification constant for the focus directions.
-     * @param direction One of {@link View#FOCUS_UP}, {@link View#FOCUS_DOWN},
-     *     {@link View#FOCUS_LEFT}, {@link View#FOCUS_RIGHT}, {@link View#FOCUS_FORWARD}
-     *     or {@link View#FOCUS_BACKWARD}
-
+     * @param direction The direction of the focus.
      * @return The appropriate sonification constant.
      * @throws {@link IllegalArgumentException} when the passed direction is not one of the
      *     documented values.
@@ -76,16 +109,14 @@
 
     /**
      * Get the sonification constant for the focus directions
-     * @param direction One of {@link View#FOCUS_UP}, {@link View#FOCUS_DOWN},
-     *     {@link View#FOCUS_LEFT}, {@link View#FOCUS_RIGHT}, {@link View#FOCUS_FORWARD}
-     *     or {@link View#FOCUS_BACKWARD}
+     * @param direction The direction of the focus.
      * @param repeating True if the user long-presses a direction
      * @return The appropriate sonification constant
      * @throws IllegalArgumentException when the passed direction is not one of the
      *      documented values.
      */
-    public static int getConstantForFocusDirection(@View.FocusDirection int direction,
-            boolean repeating) {
+    public static @NavigationSoundEffect int getConstantForFocusDirection(
+            @View.FocusDirection int direction, boolean repeating) {
         if (repeating) {
             switch (direction) {
                 case View.FOCUS_RIGHT:
@@ -112,7 +143,7 @@
      * @hide
      */
     @VisibleForTesting(visibility = Visibility.PACKAGE)
-    public static boolean isNavigationRepeat(int effectId) {
+    public static boolean isNavigationRepeat(@NavigationSoundEffect int effectId) {
         return effectId == SoundEffectConstants.NAVIGATION_REPEAT_DOWN
                 || effectId == SoundEffectConstants.NAVIGATION_REPEAT_LEFT
                 || effectId == SoundEffectConstants.NAVIGATION_REPEAT_RIGHT
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 85d4878..b2a84a2 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -190,6 +190,8 @@
     private static native void nativeReparent(long transactionObj, long nativeObject,
             long newParentNativeObject);
 
+    private static native void nativeOverrideHdrTypes(IBinder displayToken, int[] modes);
+
     private static native void nativeSetInputWindowInfo(long transactionObj, long nativeObject,
             InputWindowHandle handle);
 
@@ -2204,6 +2206,18 @@
     }
 
     /**
+     * Overrides HDR modes for a display device.
+     *
+     * If the caller does not have ACCESS_SURFACE_FLINGER permission, this will throw a Security
+     * Exception.
+     * @hide
+     */
+    @TestApi
+    public static void overrideHdrTypes(@NonNull IBinder displayToken, @NonNull int[] modes) {
+        nativeOverrideHdrTypes(displayToken, modes);
+    }
+
+    /**
      * @hide
      */
     @UnsupportedAppUsage
@@ -2244,6 +2258,8 @@
      *
      * @hide
      */
+    @TestApi
+    @NonNull
     public static IBinder getInternalDisplayToken() {
         final long[] physicalDisplayIds = getPhysicalDisplayIds();
         if (physicalDisplayIds.length == 0) {
diff --git a/core/java/android/view/SurfaceControlViewHost.java b/core/java/android/view/SurfaceControlViewHost.java
index 870fd8c..11b161a 100644
--- a/core/java/android/view/SurfaceControlViewHost.java
+++ b/core/java/android/view/SurfaceControlViewHost.java
@@ -79,6 +79,26 @@
             mInputToken = inputToken;
         }
 
+        /**
+         * Constructs a copy of {@code SurfacePackage} with an independent lifetime.
+         *
+         * The caller can use this to create an independent copy in situations where ownership of
+         * the {@code SurfacePackage} would be transferred elsewhere, such as attaching to a
+         * {@code SurfaceView}, returning as {@code Binder} result value, etc. The caller is
+         * responsible for releasing this copy when its done.
+         *
+         * @param other {@code SurfacePackage} to create a copy of.
+         */
+        public SurfacePackage(@NonNull SurfacePackage other) {
+            SurfaceControl otherSurfaceControl = other.mSurfaceControl;
+            if (otherSurfaceControl != null && otherSurfaceControl.isValid()) {
+                mSurfaceControl = new SurfaceControl();
+                mSurfaceControl.copyFrom(otherSurfaceControl, "SurfacePackage");
+            }
+            mAccessibilityEmbeddedConnection = other.mAccessibilityEmbeddedConnection;
+            mInputToken = other.mInputToken;
+        }
+
         private SurfacePackage(Parcel in) {
             mSurfaceControl = new SurfaceControl();
             mSurfaceControl.readFromParcel(in);
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 3ffe0c6..82106b0 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -1296,7 +1296,7 @@
             mBlastBufferQueue.destroy();
         }
         mBlastBufferQueue = new BLASTBufferQueue(name, mBlastSurfaceControl, mSurfaceWidth,
-                mSurfaceHeight, mFormat, true /* TODO */);
+                mSurfaceHeight, mFormat);
     }
 
     private void onDrawFinished() {
@@ -1389,6 +1389,8 @@
             // If we are using BLAST, merge the transaction with the viewroot buffer transaction.
             viewRoot.mergeWithNextTransaction(mRtTransaction, frameNumber);
             return;
+        } else {
+            mRtTransaction.apply();
         }
     }
 
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 7455b8b..63a7dea 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -107,6 +107,7 @@
 import android.util.FloatProperty;
 import android.util.LayoutDirection;
 import android.util.Log;
+import android.util.LongSparseArray;
 import android.util.LongSparseLongArray;
 import android.util.Pair;
 import android.util.Pools.SynchronizedPool;
@@ -151,6 +152,9 @@
 import android.view.inspector.InspectableProperty;
 import android.view.inspector.InspectableProperty.EnumEntry;
 import android.view.inspector.InspectableProperty.FlagEntry;
+import android.view.translation.TranslationCapability;
+import android.view.translation.TranslationSpec.DataFormat;
+import android.view.translation.ViewTranslationCallback;
 import android.view.translation.ViewTranslationRequest;
 import android.view.translation.ViewTranslationResponse;
 import android.widget.Checkable;
@@ -5253,6 +5257,9 @@
     @Nullable
     private String[] mOnReceiveContentMimeTypes;
 
+    @Nullable
+    private ViewTranslationCallback mViewTranslationCallback;
+
     /**
      * Simple constructor to use when creating a view from code.
      *
@@ -26136,9 +26143,9 @@
      * <p>The sound effect will only be played if sound effects are enabled by the user, and
      * {@link #isSoundEffectsEnabled()} is true.
      *
-     * @param soundConstant One of the constants defined in {@link SoundEffectConstants}
+     * @param soundConstant One of the constants defined in {@link SoundEffectConstants}.
      */
-    public void playSoundEffect(int soundConstant) {
+    public void playSoundEffect(@SoundEffectConstants.SoundEffect int soundConstant) {
         if (mAttachInfo == null || mAttachInfo.mRootCallbacks == null || !isSoundEffectsEnabled()) {
             return;
         }
@@ -26794,8 +26801,10 @@
             if (permissions != null) {
                 permissions.takeTransient();
             }
-            final ContentInfo payload = new ContentInfo.Builder(
-                    event.getClipData(), SOURCE_DRAG_AND_DROP).build();
+            final ContentInfo payload =
+                    new ContentInfo.Builder(event.getClipData(), SOURCE_DRAG_AND_DROP)
+                            .setDragAndDropPermissions(permissions)
+                            .build();
             ContentInfo remainingPayload = performReceiveContent(payload);
             // Return true unless none of the payload was consumed.
             return remainingPayload != payload;
@@ -30718,71 +30727,141 @@
     }
 
     /**
-     * Returns a {@link ViewTranslationRequest} to the {@link onStartUiTranslation} which represents
-     * the content to be translated.
+     * Returns a {@link ViewTranslationRequest} which represents the content to be translated.
      *
-     * <p>The default implementation does nothing and return null.</p>
+     * <p>The default implementation does nothing and returns null.</p>
      *
-     * @hide
-     *
-     * @return the {@link ViewTranslationRequest} which contains the information to be translated.
+     * @param supportedFormats the supported translation formats. For now, the only possible value
+     * is the {@link android.view.translation.TranslationSpec#DATA_FORMAT_TEXT}.
+     * @return the {@link ViewTranslationRequest} which contains the information to be translated or
+     * {@code null} if this View doesn't support translation.
+     * The {@link AutofillId} must be set on the returned value.
      */
     @Nullable
-    //TODO(b/178046780): initial version for demo. Will mark public when the design is reviewed.
-    public ViewTranslationRequest onCreateTranslationRequest() {
+    public ViewTranslationRequest onCreateTranslationRequest(
+            @NonNull @DataFormat int[] supportedFormats) {
         return null;
     }
 
     /**
-     * Called when the user wants to show the original text instead of the translated text.
+     * Returns a {@link ViewTranslationRequest} list which represents the content to be translated
+     * in the virtual view. This is called if this view returned a virtual view structure
+     * from {@link #onProvideContentCaptureStructure} and the system determined that those virtual
+     * views were relevant for translation.
      *
-     * @hide
+     * <p>The default implementation does nothing.</p>
      *
-     * <p> The default implementation does nothing.
+     * @param virtualChildIds the virtual child ids which represents the child views in the virtual
+     * view.
+     * @param supportedFormats the supported translation formats. For now, the only possible value
+     * is the {@link android.view.translation.TranslationSpec#DATA_FORMAT_TEXT}.
+     * @param requestsCollector a {@link ViewTranslationRequest} collector that will be called
+     * multiple times to collect the information to be translated in the virtual view. One
+     * {@link ViewTranslationRequest} per virtual child. The {@link ViewTranslationRequest} must
+     * contains the {@link AutofillId} corresponding to the virtualChildIds.
      */
-    //TODO(b/178046780): initial version for demo. Will mark public when the design is reviewed.
-    public void onPauseUiTranslation() {
+    @SuppressLint("NullableCollection")
+    public void onCreateTranslationRequests(@NonNull long[] virtualChildIds,
+            @NonNull @DataFormat int[] supportedFormats,
+            @NonNull Consumer<ViewTranslationRequest> requestsCollector) {
         // no-op
     }
 
     /**
-     * User can switch back to show the original text, this method called when the user wants to
-     * re-show the translated text again.
+     * Returns a {@link ViewTranslationCallback} that is used to display/hide the translated
+     * information. If the View supports displaying translated content, it should implement
+     * {@link ViewTranslationCallback}.
      *
-     * @hide
+     * <p>The default implementation returns null if developers don't set the customized
+     * {@link ViewTranslationCallback} by {@link #setViewTranslationCallback} </p>
+     *
+     * @return a {@link ViewTranslationCallback} that is used to control how to display the
+     * translated information or {@code null} if this View doesn't support translation.
+     */
+    @Nullable
+    public ViewTranslationCallback getViewTranslationCallback() {
+        return mViewTranslationCallback;
+    }
+
+    /**
+     * Sets a {@link ViewTranslationCallback} that is used to display/hide the translated
+     * information. Developers can provide the customized implementation for show/hide translated
+     * information.
+     *
+     * @param callback a {@link ViewTranslationCallback} that is used to control how to display the
+     * translated information
+     */
+    public void setViewTranslationCallback(@NonNull ViewTranslationCallback callback) {
+        mViewTranslationCallback = callback;
+    }
+
+    /**
+     * Called when the content from {@link View#onCreateTranslationRequest} had been translated by
+     * the TranslationService.
      *
      * <p> The default implementation does nothing.</p>
+     *
+     * @param response a {@link ViewTranslationResponse} that contains the translated information
+     * which can be shown in the view.
      */
-    //TODO(b/178046780): initial version for demo. Will mark public when the design is reviewed.
-    public void onRestoreUiTranslation() {
+    public void onTranslationResponse(@NonNull ViewTranslationResponse response) {
         // no-op
     }
 
     /**
-     * Called when the user finish the Ui translation and no longer to show the translated text.
-     *
-     * @hide
+     * Called when the content from {@link View#onCreateTranslationRequest} had been translated by
+     * the TranslationService.
      *
      * <p> The default implementation does nothing.</p>
+     *
+     * @param response a {@link ViewTranslationResponse} SparseArray for the request that send by
+     * {@link View#onCreateTranslationRequests} that contains the translated information which can
+     * be shown in the view. The key of SparseArray is
+     * the virtual child ids.
      */
-    //TODO(b/178046780): initial version for demo. Will mark public when the design is reviewed.
-    public void onFinishUiTranslation() {
+    public void onTranslationResponse(@NonNull LongSparseArray<ViewTranslationResponse> response) {
         // no-op
     }
 
     /**
-     * Called when the request from {@link onStartUiTranslation} is completed by the translation
-     * service so that the translation result can be shown.
+     * Dispatch to collect the {@link ViewTranslationRequest}s for translation purpose by traversing
+     * the hierarchy when the app requests ui translation. Typically, this method should only be
+     * overridden by subclasses that provide a view hierarchy (such as {@link ViewGroup}). Other
+     * classes should override {@link View#onCreateTranslationRequest}. When requested to start the
+     * ui translation, the system will call this method to traverse the view hierarchy to call
+     * {@link View#onCreateTranslationRequest} to build {@link ViewTranslationRequest}s and create a
+     * {@link android.view.translation.Translator} to translate the requests. All the
+     * {@link ViewTranslationRequest}s will be added when the traversal is done.
      *
-     * @hide
+     * <p> The default implementation will call {@link View#onCreateTranslationRequest} to build
+     * {@link ViewTranslationRequest} if the view should be translated. </p>
      *
-     * <p> The default implementation does nothing.</p>
-     *
-     * @param response the translated information which can be shown in the view.
+     * @param viewIds a map for the view's {@link AutofillId} and its virtual child ids or
+     * {@code null} if the view doesn't have virtual child that should be translated. The virtual
+     * child ids are the same virtual ids provided by ContentCapture.
+     * @param supportedFormats the supported translation formats. For now, the only possible value
+     * is the {@link android.view.translation.TranslationSpec#DATA_FORMAT_TEXT}.
+     * @param capability a {@link TranslationCapability} that holds translation capability.
+     * information, e.g. source spec, target spec.
+     * @param requests fill in with {@link ViewTranslationRequest}s for translation purpose.
      */
-    //TODO(b/178046780): initial version for demo. Will mark public when the design is reviewed.
-    public void onTranslationComplete(@NonNull ViewTranslationResponse response) {
-        // no-op
+    public void dispatchRequestTranslation(@NonNull Map<AutofillId, long[]> viewIds,
+            @NonNull @DataFormat int[] supportedFormats,
+            @Nullable TranslationCapability capability,
+            @NonNull List<ViewTranslationRequest> requests) {
+        AutofillId autofillId = getAutofillId();
+        if (viewIds.containsKey(autofillId)) {
+            if (viewIds.get(autofillId) == null) {
+                ViewTranslationRequest request = onCreateTranslationRequest(supportedFormats);
+                if (request != null && request.getKeys().size() > 0) {
+                    requests.add(request);
+                }
+            } else {
+                onCreateTranslationRequests(viewIds.get(autofillId), supportedFormats, request -> {
+                    requests.add(request);
+                });
+            }
+        }
     }
 
     /**
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 38a5937..8198254 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -65,9 +65,13 @@
 import android.view.animation.AnimationUtils;
 import android.view.animation.LayoutAnimationController;
 import android.view.animation.Transformation;
+import android.view.autofill.AutofillId;
 import android.view.autofill.Helper;
 import android.view.inspector.InspectableProperty;
 import android.view.inspector.InspectableProperty.EnumEntry;
+import android.view.translation.TranslationCapability;
+import android.view.translation.TranslationSpec.DataFormat;
+import android.view.translation.ViewTranslationRequest;
 
 import com.android.internal.R;
 
@@ -9264,4 +9268,25 @@
             mParent.onDescendantUnbufferedRequested();
         }
     }
+
+    /**
+     * {@inheritDoc}
+     *
+     * The implementation calls {@link #dispatchRequestTranslation} for all the child views.
+     */
+    @Override
+    public void dispatchRequestTranslation(@NonNull Map<AutofillId, long[]> viewIds,
+            @NonNull @DataFormat int[] supportedFormats,
+            @Nullable TranslationCapability capability,
+            @NonNull List<ViewTranslationRequest> requests) {
+        super.dispatchRequestTranslation(viewIds, supportedFormats, capability, requests);
+        final int childCount = getChildCount();
+        if (childCount == 0) {
+            return;
+        }
+        for (int i = 0; i < childCount; ++i) {
+            final View child = getChildAt(i);
+            child.dispatchRequestTranslation(viewIds, supportedFormats, capability, requests);
+        }
+    }
 }
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index e4fb611..426c950 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -330,7 +330,6 @@
 
     private boolean mUseBLASTAdapter;
     private boolean mForceDisableBLAST;
-    private boolean mEnableTripleBuffering;
 
     private boolean mFastScrollSoundEffectsEnabled;
 
@@ -474,6 +473,7 @@
         FrameInfo frameInfo = mChoreographer.mFrameInfo;
         mViewFrameInfo.populateFrameInfo(frameInfo);
         mViewFrameInfo.reset();
+        mInputEventAssigner.notifyFrameProcessed();
         return frameInfo;
     }
 
@@ -1179,9 +1179,6 @@
                 if ((res & WindowManagerGlobal.ADD_FLAG_USE_BLAST) != 0) {
                     mUseBLASTAdapter = true;
                 }
-                if ((res & WindowManagerGlobal.ADD_FLAG_USE_TRIPLE_BUFFERING) != 0) {
-                    mEnableTripleBuffering = true;
-                }
 
                 if (view instanceof RootViewSurfaceTaker) {
                     mInputQueueCallback =
@@ -1373,17 +1370,10 @@
             // can be used by code on the system process to escape that and enable
             // HW accelerated drawing.  (This is basically for the lock screen.)
 
-            final boolean fakeHwAccelerated = (attrs.privateFlags &
-                    WindowManager.LayoutParams.PRIVATE_FLAG_FAKE_HARDWARE_ACCELERATED) != 0;
             final boolean forceHwAccelerated = (attrs.privateFlags &
                     WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED) != 0;
 
-            if (fakeHwAccelerated) {
-                // This is exclusively for the preview windows the window manager
-                // shows for launching applications, so they will look more like
-                // the app being launched.
-                mAttachInfo.mHardwareAccelerationRequested = true;
-            } else if (ThreadedRenderer.sRendererEnabled || forceHwAccelerated) {
+            if (ThreadedRenderer.sRendererEnabled || forceHwAccelerated) {
                 if (mAttachInfo.mThreadedRenderer != null) {
                     mAttachInfo.mThreadedRenderer.destroy();
                 }
@@ -1907,7 +1897,7 @@
         Surface ret = null;
         if (mBlastBufferQueue == null) {
             mBlastBufferQueue = new BLASTBufferQueue(mTag, mSurfaceControl, width, height,
-                    format, mEnableTripleBuffering);
+                    format);
             // We only return the Surface the first time, as otherwise
             // it hasn't changed and there is no need to update.
             ret = mBlastBufferQueue.createSurface();
@@ -3354,8 +3344,9 @@
         }
         // TODO (b/131181940): Make sure this doesn't leak Activity with mActivityConfigCallback
         // config changes.
+        final View focusedView = mView != null ? mView.findFocus() : null;
         if (hasWindowFocus) {
-            mInsetsController.onWindowFocusGained();
+            mInsetsController.onWindowFocusGained(focusedView != null /* hasViewFocused */);
         } else {
             mInsetsController.onWindowFocusLost();
         }
@@ -3404,8 +3395,7 @@
 
             // Note: must be done after the focus change callbacks,
             // so all of the view state is set up correctly.
-            mImeFocusController.onPostWindowFocus(mView != null ? mView.findFocus() : null,
-                    hasWindowFocus, mWindowAttributes);
+            mImeFocusController.onPostWindowFocus(focusedView, hasWindowFocus, mWindowAttributes);
 
             if (hasWindowFocus) {
                 // Clear the forward bit.  We can just do this directly, since
@@ -4303,7 +4293,7 @@
                 mChoreographer.getFrameTimeNanos() / TimeUtils.NANOS_PER_MS;
 
         boolean useAsyncReport = false;
-        if (!dirty.isEmpty() || mIsAnimating || accessibilityFocusDirty) {
+        if (!dirty.isEmpty() || mIsAnimating || accessibilityFocusDirty || mNextDrawUseBlastSync) {
             if (isHardwareEnabled()) {
                 // If accessibility focus moved, always invalidate the root.
                 boolean invalidateRoot = accessibilityFocusDirty || mInvalidateRootRequested;
@@ -7764,7 +7754,7 @@
      * {@inheritDoc}
      */
     @Override
-    public void playSoundEffect(int effectId) {
+    public void playSoundEffect(@SoundEffectConstants.SoundEffect int effectId) {
         checkThread();
 
         try {
@@ -8502,11 +8492,6 @@
             consumedBatches = false;
         }
         doProcessInputEvents();
-        if (consumedBatches) {
-            // Must be done after we processed the input events, to mark the completion of the frame
-            // from the input point of view
-            mInputEventAssigner.onChoreographerCallback();
-        }
         return consumedBatches;
     }
 
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 04512c9..93c3cab 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -2218,26 +2218,6 @@
         public int flags;
 
         /**
-         * If the window has requested hardware acceleration, but this is not
-         * allowed in the process it is in, then still render it as if it is
-         * hardware accelerated.  This is used for the starting preview windows
-         * in the system process, which don't need to have the overhead of
-         * hardware acceleration (they are just a static rendering), but should
-         * be rendered as such to match the actual window of the app even if it
-         * is hardware accelerated.
-         * Even if the window isn't hardware accelerated, still do its rendering
-         * as if it was.
-         * Like {@link #FLAG_HARDWARE_ACCELERATED} except for trusted system windows
-         * that need hardware acceleration (e.g. LockScreen), where hardware acceleration
-         * is generally disabled. This flag must be specified in addition to
-         * {@link #FLAG_HARDWARE_ACCELERATED} to enable hardware acceleration for system
-         * windows.
-         *
-         * @hide
-         */
-        public static final int PRIVATE_FLAG_FAKE_HARDWARE_ACCELERATED = 0x00000001;
-
-        /**
          * In the system process, we globally do not use hardware acceleration
          * because there are many threads doing UI there and they conflict.
          * If certain parts of the UI that really do want to use hardware
@@ -2463,7 +2443,6 @@
          * @hide
          */
         @IntDef(flag = true, prefix="PRIVATE_FLAG_", value = {
-                PRIVATE_FLAG_FAKE_HARDWARE_ACCELERATED,
                 PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED,
                 PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS,
                 SYSTEM_FLAG_SHOW_FOR_ALL_USERS,
@@ -2499,10 +2478,6 @@
         @UnsupportedAppUsage
         @ViewDebug.ExportedProperty(flagMapping = {
                 @ViewDebug.FlagToString(
-                        mask = PRIVATE_FLAG_FAKE_HARDWARE_ACCELERATED,
-                        equals = PRIVATE_FLAG_FAKE_HARDWARE_ACCELERATED,
-                        name = "FAKE_HARDWARE_ACCELERATED"),
-                @ViewDebug.FlagToString(
                         mask = PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED,
                         equals = PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED,
                         name = "FORCE_HARDWARE_ACCELERATED"),
@@ -2967,7 +2942,7 @@
         public IBinder token = null;
 
         /**
-         * The token of {@link android.app.WindowContext}. It is usually a
+         * The token of {@link android.window.WindowContext}. It is usually a
          * {@link android.app.WindowTokenClient} and is used for associating the params with an
          * existing node in the WindowManager hierarchy and getting the corresponding
          * {@link Configuration} and {@link android.content.res.Resources} values with updates
diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java
index 47ac1ee..18013e8 100644
--- a/core/java/android/view/WindowManagerGlobal.java
+++ b/core/java/android/view/WindowManagerGlobal.java
@@ -118,7 +118,6 @@
 
     public static final int ADD_FLAG_IN_TOUCH_MODE = 0x1;
     public static final int ADD_FLAG_APP_VISIBLE = 0x2;
-    public static final int ADD_FLAG_USE_TRIPLE_BUFFERING = 0x4;
     public static final int ADD_FLAG_USE_BLAST = 0x8;
 
     /**
diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java
index 8dce852..2bed311 100644
--- a/core/java/android/view/WindowManagerImpl.java
+++ b/core/java/android/view/WindowManagerImpl.java
@@ -36,6 +36,7 @@
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.window.WindowContext;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.os.IResultReceiver;
@@ -110,7 +111,7 @@
         return new WindowManagerImpl(displayContext, mParentWindow, mWindowContextToken);
     }
 
-    /** Creates a {@link WindowManager} for a {@link android.app.WindowContext}. */
+    /** Creates a {@link WindowManager} for a {@link WindowContext}. */
     public static WindowManager createWindowContextWindowManager(Context context) {
         final IBinder clientToken = context.getWindowContextToken();
         return new WindowManagerImpl(context, null /* parentWindow */, clientToken);
diff --git a/core/java/android/view/WindowMetrics.java b/core/java/android/view/WindowMetrics.java
index d96c5c8..52e4e15 100644
--- a/core/java/android/view/WindowMetrics.java
+++ b/core/java/android/view/WindowMetrics.java
@@ -51,7 +51,7 @@
      * final WindowMetrics metrics = windowManager.getCurrentWindowMetrics();
      * // Gets all excluding insets
      * final WindowInsets windowInsets = metrics.getWindowInsets();
-     * Insets insets = windowInsets.getInsetsIgnoreVisibility(WindowInsets.Type.navigationBars()
+     * Insets insets = windowInsets.getInsetsIgnoringVisibility(WindowInsets.Type.navigationBars()
      *         | WindowInsets.Type.displayCutout());
      *
      * int insetsWidth = insets.right + insets.left;
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index b0b9d24..a169cb0 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -1921,20 +1921,20 @@
             if (client == null) return; // NOTE: getClient() already logged it..
 
             final SyncResultReceiver receiver = new SyncResultReceiver(SYNC_CALLS_TIMEOUT_MS);
-            final ComponentName componentName = client.autofillClientGetComponentName();
+            final ComponentName clientActivity = client.autofillClientGetComponentName();
 
             if (!mEnabledForAugmentedAutofillOnly && mOptions != null
-                    && mOptions.isAutofillDisabledLocked(componentName)) {
+                    && mOptions.isAutofillDisabledLocked(clientActivity)) {
                 if (mOptions.isAugmentedAutofillEnabled(mContext)) {
                     if (sDebug) {
-                        Log.d(TAG, "startSession(" + componentName + "): disabled by service but "
-                                + "whitelisted for augmented autofill");
+                        Log.d(TAG, "startSession(" + clientActivity + "): disabled by service but "
+                                + "allowlisted for augmented autofill");
                         flags |= FLAG_ADD_CLIENT_ENABLED_FOR_AUGMENTED_AUTOFILL_ONLY;
                     }
                 } else {
                     if (sDebug) {
-                        Log.d(TAG, "startSession(" + componentName + "): ignored because "
-                                + "disabled by service and not whitelisted for augmented autofill");
+                        Log.d(TAG, "startSession(" + clientActivity + "): ignored because "
+                                + "disabled by service and not allowlisted for augmented autofill");
                     }
                     setSessionFinished(AutofillManager.STATE_DISABLED_BY_SERVICE, null);
                     client.autofillClientResetableStateAvailable();
@@ -1951,7 +1951,7 @@
 
             mService.startSession(client.autofillClientGetActivityToken(),
                     mServiceClient.asBinder(), id, bounds, value, mContext.getUserId(),
-                    mCallback != null, flags, componentName,
+                    mCallback != null, flags, clientActivity,
                     isCompatibilityModeEnabledLocked(), receiver);
             mSessionId = receiver.getIntResult();
             if (mSessionId != NO_SESSION) {
@@ -1959,7 +1959,7 @@
             }
             final int extraFlags = receiver.getOptionalExtraIntResult(0);
             if ((extraFlags & RECEIVER_FLAG_SESSION_FOR_AUGMENTED_AUTOFILL_ONLY) != 0) {
-                if (sDebug) Log.d(TAG, "startSession(" + componentName + "): for augmented only");
+                if (sDebug) Log.d(TAG, "startSession(" + clientActivity + "): for augmented only");
                 mForAugmentedAutofillOnly = true;
             }
             client.autofillClientResetableStateAvailable();
diff --git a/core/java/android/view/contentcapture/ContentCaptureEvent.java b/core/java/android/view/contentcapture/ContentCaptureEvent.java
index 2b12230..ce01469 100644
--- a/core/java/android/view/contentcapture/ContentCaptureEvent.java
+++ b/core/java/android/view/contentcapture/ContentCaptureEvent.java
@@ -143,6 +143,9 @@
     private @Nullable ContentCaptureContext mClientContext;
     private @Nullable Insets mInsets;
 
+    /** Only used in the main Content Capture session, no need to parcel */
+    private boolean mTextHasComposingSpan;
+
     /** @hide */
     public ContentCaptureEvent(int sessionId, int type, long eventTime) {
         mSessionId = sessionId;
@@ -243,11 +246,21 @@
 
     /** @hide */
     @NonNull
-    public ContentCaptureEvent setText(@Nullable CharSequence text) {
+    public ContentCaptureEvent setText(@Nullable CharSequence text, boolean hasComposingSpan) {
         mText = text;
+        mTextHasComposingSpan = hasComposingSpan;
         return this;
     }
 
+    /**
+     * The value is not parcelled, become false after parcelled.
+     * @hide
+     */
+    @NonNull
+    public boolean getTextHasComposingSpan() {
+        return mTextHasComposingSpan;
+    }
+
     /** @hide */
     @NonNull
     public ContentCaptureEvent setInsets(@NonNull Insets insets) {
@@ -361,7 +374,7 @@
             throw new IllegalArgumentException("mergeEvent(): got "
                     + "TYPE_VIEW_DISAPPEARED event with neither id or ids: " + event);
         } else if (eventType == TYPE_VIEW_TEXT_CHANGED) {
-            setText(event.getText());
+            setText(event.getText(), event.getTextHasComposingSpan());
         } else {
             Log.e(TAG, "mergeEvent(" + getTypeAsString(eventType)
                     + ") does not support this event type.");
@@ -479,7 +492,7 @@
             if (node != null) {
                 event.setViewNode(node);
             }
-            event.setText(parcel.readCharSequence());
+            event.setText(parcel.readCharSequence(), false);
             if (type == TYPE_SESSION_STARTED || type == TYPE_SESSION_FINISHED) {
                 event.setParentSessionId(parcel.readInt());
             }
diff --git a/core/java/android/view/contentcapture/MainContentCaptureSession.java b/core/java/android/view/contentcapture/MainContentCaptureSession.java
index 5ca793e..f196f75 100644
--- a/core/java/android/view/contentcapture/MainContentCaptureSession.java
+++ b/core/java/android/view/contentcapture/MainContentCaptureSession.java
@@ -43,12 +43,15 @@
 import android.os.IBinder;
 import android.os.IBinder.DeathRecipient;
 import android.os.RemoteException;
+import android.text.Spannable;
 import android.text.TextUtils;
+import android.util.ArrayMap;
 import android.util.LocalLog;
 import android.util.Log;
 import android.util.TimeUtils;
 import android.view.autofill.AutofillId;
 import android.view.contentcapture.ViewNode.ViewStructureImpl;
+import android.view.inputmethod.BaseInputConnection;
 
 import com.android.internal.os.IResultReceiver;
 
@@ -57,6 +60,7 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 /**
@@ -147,6 +151,12 @@
     private final LocalLog mFlushHistory;
 
     /**
+     * If the event in the buffer is of type {@link TYPE_VIEW_TEXT_CHANGED}, this value
+     * indicates whether the event has composing span or not.
+     */
+    private final Map<AutofillId, Boolean> mLastComposingSpan = new ArrayMap<>();
+
+    /**
      * Binder object used to update the session state.
      */
     @NonNull
@@ -335,26 +345,47 @@
         // Some type of events can be merged together
         boolean addEvent = true;
 
-        if (!mEvents.isEmpty() && eventType == TYPE_VIEW_TEXT_CHANGED) {
-            final ContentCaptureEvent lastEvent = mEvents.get(mEvents.size() - 1);
+        if (eventType == TYPE_VIEW_TEXT_CHANGED) {
+            // We determine whether to add or merge the current event by following criteria:
+            // 1. Don't have composing span: always add.
+            // 2. Have composing span:
+            //    2.1 either last or current text is empty: add.
+            //    2.2 last event doesn't have composing span: add.
+            // Otherwise, merge.
 
-            // We merge two consecutive text change event, unless one of them clears the text.
-            if (lastEvent.getType() == TYPE_VIEW_TEXT_CHANGED
-                    && lastEvent.getId().equals(event.getId())) {
-                boolean bothNonEmpty = !TextUtils.isEmpty(lastEvent.getText())
-                        && !TextUtils.isEmpty(event.getText());
-                boolean equalContent = TextUtils.equals(lastEvent.getText(), event.getText());
-                if (equalContent) {
-                    addEvent = false;
-                } else if (bothNonEmpty) {
-                    lastEvent.mergeEvent(event);
-                    addEvent = false;
-                }
-                if (!addEvent && sVerbose) {
-                    Log.v(TAG, "Buffering VIEW_TEXT_CHANGED event, updated text="
-                            + getSanitizedString(event.getText()));
+            final CharSequence text = event.getText();
+            final boolean textHasComposingSpan = event.getTextHasComposingSpan();
+
+            if (textHasComposingSpan && !mLastComposingSpan.isEmpty()) {
+                final Boolean lastEventHasComposingSpan = mLastComposingSpan.get(event.getId());
+                if (lastEventHasComposingSpan != null && lastEventHasComposingSpan.booleanValue()) {
+                    ContentCaptureEvent lastEvent = null;
+                    for (int index = mEvents.size() - 1; index >= 0; index--) {
+                        final ContentCaptureEvent tmpEvent = mEvents.get(index);
+                        if (event.getId().equals(tmpEvent.getId())) {
+                            lastEvent = tmpEvent;
+                            break;
+                        }
+                    }
+                    if (lastEvent != null) {
+                        final CharSequence lastText = lastEvent.getText();
+                        final boolean bothNonEmpty = !TextUtils.isEmpty(lastText)
+                                && !TextUtils.isEmpty(text);
+                        boolean equalContent = TextUtils.equals(lastText, text);
+                        if (equalContent) {
+                            addEvent = false;
+                        } else if (bothNonEmpty && lastEventHasComposingSpan) {
+                            lastEvent.mergeEvent(event);
+                            addEvent = false;
+                        }
+                        if (!addEvent && sVerbose) {
+                            Log.v(TAG, "Buffering VIEW_TEXT_CHANGED event, updated text="
+                                    + getSanitizedString(text));
+                        }
+                    }
                 }
             }
+            mLastComposingSpan.put(event.getId(), textHasComposingSpan);
         }
 
         if (!mEvents.isEmpty() && eventType == TYPE_VIEW_DISAPPEARED) {
@@ -374,6 +405,11 @@
             mEvents.add(event);
         }
 
+        // TODO: we need to change when the flush happens so that we don't flush while the
+        //  composing span hasn't changed. But we might need to keep flushing the events for the
+        //  non-editable views and views that don't have the composing state; otherwise some other
+        //  Content Capture features may be delayed.
+
         final int numberEvents = mEvents.size();
 
         final boolean bufferEvent = numberEvents < maxBufferSize;
@@ -550,6 +586,7 @@
                 ? Collections.emptyList()
                 : mEvents;
         mEvents = null;
+        mLastComposingSpan.clear();
         return new ParceledListSlice<>(events);
     }
 
@@ -677,9 +714,16 @@
     }
 
     void notifyViewTextChanged(int sessionId, @NonNull AutofillId id, @Nullable CharSequence text) {
+        // Since the same CharSequence instance may be reused in the TextView, we need to make
+        // a copy of its content so that its value will not be changed by subsequent updates
+        // in the TextView.
+        final String eventText = text == null ? null : text.toString();
+        final boolean textHasComposingSpan =
+                text instanceof Spannable && BaseInputConnection.getComposingSpanStart(
+                        (Spannable) text) >= 0;
         mHandler.post(() -> sendEvent(
                 new ContentCaptureEvent(sessionId, TYPE_VIEW_TEXT_CHANGED)
-                        .setAutofillId(id).setText(text)));
+                        .setAutofillId(id).setText(eventText, textHasComposingSpan)));
     }
 
     /** Public because is also used by ViewRootImpl */
diff --git a/core/java/android/view/displayhash/DisplayHashManager.java b/core/java/android/view/displayhash/DisplayHashManager.java
index 6b0c1a6..69dfc38 100644
--- a/core/java/android/view/displayhash/DisplayHashManager.java
+++ b/core/java/android/view/displayhash/DisplayHashManager.java
@@ -21,7 +21,9 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
 import android.annotation.SystemService;
+import android.annotation.TestApi;
 import android.os.RemoteException;
 import android.util.ArraySet;
 import android.util.Log;
@@ -94,4 +96,19 @@
             return null;
         }
     }
+
+    /**
+     * Call to enable or disable the throttling when generating a display hash. This should only be
+     * used for testing. Throttling is enabled by default.
+     *
+     * @hide
+     */
+    @TestApi
+    @RequiresPermission(android.Manifest.permission.READ_FRAME_BUFFER)
+    public void setDisplayHashThrottlingEnabled(boolean enable) {
+        try {
+            WindowManagerGlobal.getWindowManagerService().setDisplayHashThrottlingEnabled(enable);
+        } catch (RemoteException e) {
+        }
+    }
 }
diff --git a/core/java/android/view/displayhash/DisplayHashResultCallback.java b/core/java/android/view/displayhash/DisplayHashResultCallback.java
index 04d29ee..6e3d9a8 100644
--- a/core/java/android/view/displayhash/DisplayHashResultCallback.java
+++ b/core/java/android/view/displayhash/DisplayHashResultCallback.java
@@ -72,13 +72,20 @@
      */
     int DISPLAY_HASH_ERROR_INVALID_HASH_ALGORITHM = -5;
 
+    /**
+     * The caller requested to generate the hash too frequently. The caller should try again at a
+     * after some time has passed to ensure the system isn't overloaded.
+     */
+    int DISPLAY_HASH_ERROR_TOO_MANY_REQUESTS = -6;
+
     /** @hide */
     @IntDef(prefix = {"DISPLAY_HASH_ERROR_"}, value = {
             DISPLAY_HASH_ERROR_UNKNOWN,
             DISPLAY_HASH_ERROR_INVALID_BOUNDS,
             DISPLAY_HASH_ERROR_MISSING_WINDOW,
             DISPLAY_HASH_ERROR_NOT_VISIBLE_ON_SCREEN,
-            DISPLAY_HASH_ERROR_INVALID_HASH_ALGORITHM
+            DISPLAY_HASH_ERROR_INVALID_HASH_ALGORITHM,
+            DISPLAY_HASH_ERROR_TOO_MANY_REQUESTS
     })
     @Retention(RetentionPolicy.SOURCE)
     @interface DisplayHashErrorCode {
diff --git a/core/java/android/view/inputmethod/BaseInputConnection.java b/core/java/android/view/inputmethod/BaseInputConnection.java
index 37220fe..9f796c0 100644
--- a/core/java/android/view/inputmethod/BaseInputConnection.java
+++ b/core/java/android/view/inputmethod/BaseInputConnection.java
@@ -608,7 +608,12 @@
         Preconditions.checkArgumentNonnegative(afterLength);
 
         final Editable content = getEditable();
-        if (content == null) return null;
+        // If {@link #getEditable()} is null or {@code mEditable} is equal to {@link #getEditable()}
+        // (a.k.a, a fake editable), it means we cannot get valid content from the editable, so
+        // fallback to retrieve surrounding text from other APIs.
+        if (content == null || mEditable == content) {
+            return InputConnection.super.getSurroundingText(beforeLength, afterLength, flags);
+        }
 
         int selStart = Selection.getSelectionStart(content);
         int selEnd = Selection.getSelectionEnd(content);
@@ -954,10 +959,10 @@
         }
         final ClipData clip = new ClipData(inputContentInfo.getDescription(),
                 new ClipData.Item(inputContentInfo.getContentUri()));
-        final ContentInfo payload =
-                new ContentInfo.Builder(clip, SOURCE_INPUT_METHOD)
+        final ContentInfo payload = new ContentInfo.Builder(clip, SOURCE_INPUT_METHOD)
                 .setLinkUri(inputContentInfo.getLinkUri())
                 .setExtras(opts)
+                .setInputContentInfo(inputContentInfo)
                 .build();
         return mTargetView.performReceiveContent(payload) == null;
     }
diff --git a/core/java/android/view/inputmethod/InputConnection.java b/core/java/android/view/inputmethod/InputConnection.java
index 34a60bb..38019c9 100644
--- a/core/java/android/view/inputmethod/InputConnection.java
+++ b/core/java/android/view/inputmethod/InputConnection.java
@@ -325,16 +325,16 @@
 
         CharSequence textBeforeCursor = getTextBeforeCursor(beforeLength, flags);
         if (textBeforeCursor == null) {
-            textBeforeCursor = "";
+            return null;
+        }
+        CharSequence textAfterCursor = getTextAfterCursor(afterLength, flags);
+        if (textAfterCursor == null) {
+            return null;
         }
         CharSequence selectedText = getSelectedText(flags);
         if (selectedText == null) {
             selectedText = "";
         }
-        CharSequence textAfterCursor = getTextAfterCursor(afterLength, flags);
-        if (textAfterCursor == null) {
-            textAfterCursor = "";
-        }
         CharSequence surroundingText =
                 TextUtils.concat(textBeforeCursor, selectedText, textAfterCursor);
         return new SurroundingText(surroundingText, textBeforeCursor.length(),
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 9872dc0..6edd071 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -511,7 +511,6 @@
     static final int MSG_TIMEOUT_INPUT_EVENT = 6;
     static final int MSG_FLUSH_INPUT_EVENT = 7;
     static final int MSG_REPORT_FULLSCREEN_MODE = 10;
-    static final int MSG_APPLY_IME_VISIBILITY = 20;
     static final int MSG_UPDATE_ACTIVITY_VIEW_TO_SCREEN_MATRIX = 30;
 
     private static boolean isAutofillUIShowing(View servedView) {
@@ -985,17 +984,6 @@
                     }
                     return;
                 }
-                case MSG_APPLY_IME_VISIBILITY: {
-                    synchronized (mH) {
-                        if (mImeInsetsConsumer != null) {
-                            ImeTracing.getInstance().triggerClientDump(
-                                    "ImeInsetsSourceConsumer#applyImeVisibility",
-                                    InputMethodManager.this, null /* icProto */);
-                            mImeInsetsConsumer.applyImeVisibility(msg.arg1 != 0);
-                        }
-                    }
-                    return;
-                }
                 case MSG_UPDATE_ACTIVITY_VIEW_TO_SCREEN_MATRIX: {
                     final float[] matrixValues = (float[]) msg.obj;
                     final int bindSequence = msg.arg1;
@@ -1090,12 +1078,6 @@
         }
 
         @Override
-        public void applyImeVisibility(boolean setVisible) {
-            mH.obtainMessage(MSG_APPLY_IME_VISIBILITY, setVisible ? 1 : 0, 0)
-                    .sendToTarget();
-        }
-
-        @Override
         public void updateActivityViewToScreenMatrix(int bindSequence, float[] matrixValues) {
             mH.obtainMessage(MSG_UPDATE_ACTIVITY_VIEW_TO_SCREEN_MATRIX, bindSequence, 0,
                     matrixValues).sendToTarget();
@@ -2035,10 +2017,12 @@
             }
             mServedInputConnectionWrapper = servedContext;
 
-            try {
-                if (DEBUG) Log.v(TAG, "START INPUT: view=" + dumpViewInfo(view) + " ic="
+            if (DEBUG) {
+                Log.v(TAG, "START INPUT: view=" + dumpViewInfo(view) + " ic="
                         + ic + " tba=" + tba + " startInputFlags="
                         + InputMethodDebug.startInputFlagsToString(startInputFlags));
+            }
+            try {
                 final Completable.InputBindResult value = Completable.createInputBindResult();
                 mService.startInputOrWindowGainedFocus(
                         startInputReason, mClient, windowGainingFocus, startInputFlags,
@@ -2046,37 +2030,37 @@
                         view.getContext().getApplicationInfo().targetSdkVersion,
                         ResultCallbacks.of(value));
                 res = Completable.getResult(value);
-                if (DEBUG) Log.v(TAG, "Starting input: Bind result=" + res);
-                if (res == null) {
-                    Log.wtf(TAG, "startInputOrWindowGainedFocus must not return"
-                            + " null. startInputReason="
-                            + InputMethodDebug.startInputReasonToString(startInputReason)
-                            + " editorInfo=" + tba
-                            + " startInputFlags="
-                            + InputMethodDebug.startInputFlagsToString(startInputFlags));
-                    return false;
-                }
-                mActivityViewToScreenMatrix = res.getActivityViewToScreenMatrix();
-                mIsInputMethodSuppressingSpellChecker = res.isInputMethodSuppressingSpellChecker;
-                if (res.id != null) {
-                    setInputChannelLocked(res.channel);
-                    mBindSequence = res.sequence;
-                    mCurMethod = res.method; // for @UnsupportedAppUsage
-                    mCurrentInputMethodSession = InputMethodSessionWrapper.createOrNull(res.method);
-                    mCurId = res.id;
-                } else if (res.channel != null && res.channel != mCurChannel) {
-                    res.channel.dispose();
-                }
-                switch (res.result) {
-                    case InputBindResult.ResultCode.ERROR_NOT_IME_TARGET_WINDOW:
-                        mRestartOnNextWindowFocus = true;
-                        break;
-                }
-                if (mCurrentInputMethodSession != null && mCompletions != null) {
-                    mCurrentInputMethodSession.displayCompletions(mCompletions);
-                }
             } catch (RemoteException e) {
-                Log.w(TAG, "IME died: " + mCurId, e);
+                throw e.rethrowFromSystemServer();
+            }
+            if (DEBUG) Log.v(TAG, "Starting input: Bind result=" + res);
+            if (res == null) {
+                Log.wtf(TAG, "startInputOrWindowGainedFocus must not return"
+                        + " null. startInputReason="
+                        + InputMethodDebug.startInputReasonToString(startInputReason)
+                        + " editorInfo=" + tba
+                        + " startInputFlags="
+                        + InputMethodDebug.startInputFlagsToString(startInputFlags));
+                return false;
+            }
+            mActivityViewToScreenMatrix = res.getActivityViewToScreenMatrix();
+            mIsInputMethodSuppressingSpellChecker = res.isInputMethodSuppressingSpellChecker;
+            if (res.id != null) {
+                setInputChannelLocked(res.channel);
+                mBindSequence = res.sequence;
+                mCurMethod = res.method; // for @UnsupportedAppUsage
+                mCurrentInputMethodSession = InputMethodSessionWrapper.createOrNull(res.method);
+                mCurId = res.id;
+            } else if (res.channel != null && res.channel != mCurChannel) {
+                res.channel.dispose();
+            }
+            switch (res.result) {
+                case InputBindResult.ResultCode.ERROR_NOT_IME_TARGET_WINDOW:
+                    mRestartOnNextWindowFocus = true;
+                    break;
+            }
+            if (mCurrentInputMethodSession != null && mCompletions != null) {
+                mCurrentInputMethodSession.displayCompletions(mCompletions);
             }
         }
 
diff --git a/core/java/android/view/translation/ITranslationDirectManager.aidl b/core/java/android/view/translation/ITranslationDirectManager.aidl
index 46475b7..525a779 100644
--- a/core/java/android/view/translation/ITranslationDirectManager.aidl
+++ b/core/java/android/view/translation/ITranslationDirectManager.aidl
@@ -18,7 +18,6 @@
 
 import android.view.translation.TranslationRequest;
 import android.service.translation.ITranslationCallback;
-import com.android.internal.os.IResultReceiver;
 
 /**
   * Interface between an app (TranslationManager / Translator) and the remote TranslationService
@@ -28,6 +27,6 @@
   */
 oneway interface ITranslationDirectManager {
     void onTranslationRequest(in TranslationRequest request, int sessionId,
-         in ITranslationCallback callback, in IResultReceiver receiver);
+         in ITranslationCallback callback);
     void onFinishTranslationSession(int sessionId);
 }
diff --git a/core/java/android/view/translation/ITranslationManager.aidl b/core/java/android/view/translation/ITranslationManager.aidl
index d347f31..9c53f46 100644
--- a/core/java/android/view/translation/ITranslationManager.aidl
+++ b/core/java/android/view/translation/ITranslationManager.aidl
@@ -18,7 +18,9 @@
 
 import android.os.IBinder;
 import android.os.IRemoteCallback;
+import android.os.ResultReceiver;
 import android.view.autofill.AutofillId;
+import android.view.translation.TranslationContext;
 import android.view.translation.TranslationSpec;
 import com.android.internal.os.IResultReceiver;
 
@@ -30,18 +32,19 @@
  * {@hide}
  */
 oneway interface ITranslationManager {
-    void getSupportedLocales(in IResultReceiver receiver, int userId);
-    void onSessionCreated(in TranslationSpec sourceSpec, in TranslationSpec destSpec,
+    void onTranslationCapabilitiesRequest(int sourceFormat, int destFormat,
+         in ResultReceiver receiver, int userId);
+    void onSessionCreated(in TranslationContext translationContext,
          int sessionId, in IResultReceiver receiver, int userId);
 
     void updateUiTranslationState(int state, in TranslationSpec sourceSpec,
-         in TranslationSpec destSpec, in List<AutofillId> viewIds, IBinder token, int taskId,
+         in TranslationSpec targetSpec, in List<AutofillId> viewIds, IBinder token, int taskId,
          int userId);
     // deprecated
     void updateUiTranslationStateByTaskId(int state, in TranslationSpec sourceSpec,
-         in TranslationSpec destSpec, in List<AutofillId> viewIds, int taskId,
-         int userId);
+         in TranslationSpec targetSpec, in List<AutofillId> viewIds, int taskId, int userId);
 
     void registerUiTranslationStateCallback(in IRemoteCallback callback, int userId);
     void unregisterUiTranslationStateCallback(in IRemoteCallback callback, int userId);
+    void getServiceSettingsActivity(in IResultReceiver result, int userId);
 }
diff --git a/services/core/java/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneIdValidator.java b/core/java/android/view/translation/TranslationCapability.aidl
similarity index 61%
copy from services/core/java/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneIdValidator.java
copy to core/java/android/view/translation/TranslationCapability.aidl
index cab5ad2..3a80b17 100644
--- a/services/core/java/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneIdValidator.java
+++ b/core/java/android/view/translation/TranslationCapability.aidl
@@ -14,17 +14,6 @@
  * limitations under the License.
  */
 
-package com.android.server.timezonedetector.location;
+package android.view.translation;
 
-import android.annotation.NonNull;
-
-import com.android.i18n.timezone.ZoneInfoDb;
-
-class ZoneInfoDbTimeZoneIdValidator implements
-        LocationTimeZoneProvider.TimeZoneIdValidator {
-
-    @Override
-    public boolean isValid(@NonNull String timeZoneId) {
-        return ZoneInfoDb.getInstance().hasTimeZone(timeZoneId);
-    }
-}
+parcelable TranslationCapability;
diff --git a/core/java/android/view/translation/TranslationCapability.java b/core/java/android/view/translation/TranslationCapability.java
new file mode 100644
index 0000000..28b2113
--- /dev/null
+++ b/core/java/android/view/translation/TranslationCapability.java
@@ -0,0 +1,289 @@
+/*
+ * 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 android.view.translation;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcelable;
+
+import com.android.internal.util.DataClass;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+
+/**
+ * Capability class holding information for a pair of {@link TranslationSpec}s.
+ *
+ * <p>Holds information and limitations on how to create a {@link TranslationContext} which can
+ * be used by {@link TranslationManager#createTranslator(TranslationContext)}.
+ */
+@DataClass(genHiddenConstDefs = true, genToString = true, genConstructor = false)
+public final class TranslationCapability implements Parcelable {
+
+    /**
+     * TODO: fill in javadoc
+     */
+    public static final @ModelState int STATE_AVAILABLE_TO_DOWNLOAD = 1;
+    /**
+     * TODO: fill in javadoc
+     */
+    public static final @ModelState int STATE_DOWNLOADING = 2;
+    /**
+     * TODO: fill in javadoc
+     */
+    public static final @ModelState int STATE_ON_DEVICE = 3;
+
+    /**
+     * The state of translation readiness between {@code mSourceSpec} and {@code mTargetSpec}.
+     */
+    private final @ModelState int mState;
+
+    /**
+     * {@link TranslationSpec} describing the source data specs for this
+     * capability.
+     */
+    @NonNull
+    private final TranslationSpec mSourceSpec;
+
+    /**
+     * {@link TranslationSpec} describing the target data specs for this
+     * capability.
+     */
+    @NonNull
+    private final TranslationSpec mTargetSpec;
+
+    /**
+     * Whether ui translation for the source-target {@link TranslationSpec}s is enabled.
+     *
+     * <p>Translation service will still support translation requests for this capability.</p>
+     */
+    private final boolean mUiTranslationEnabled;
+
+    /**
+     * Translation flags for settings that are supported by the
+     * {@link android.service.translation.TranslationService} between the {@link TranslationSpec}s
+     * provided in this capability.
+     */
+    private final @TranslationContext.TranslationFlag int mSupportedTranslationFlags;
+
+    /**
+     * Constructor for creating a {@link TranslationCapability}.
+     *
+     * @hide
+     */
+    @SystemApi
+    public TranslationCapability(@ModelState int state, @NonNull TranslationSpec sourceSpec,
+            @NonNull TranslationSpec targetSpec, boolean uiTranslationEnabled,
+            @TranslationContext.TranslationFlag int supportedTranslationFlags) {
+        Objects.requireNonNull(sourceSpec, "sourceSpec should not be null");
+        Objects.requireNonNull(targetSpec, "targetSpec should not be null");
+
+        this.mState = state;
+        this.mSourceSpec = sourceSpec;
+        this.mTargetSpec = targetSpec;
+        this.mUiTranslationEnabled = uiTranslationEnabled;
+        this.mSupportedTranslationFlags = supportedTranslationFlags;
+    }
+
+
+
+    // Code below generated by codegen v1.0.22.
+    //
+    // DO NOT MODIFY!
+    // CHECKSTYLE:OFF Generated code
+    //
+    // To regenerate run:
+    // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/view/translation/TranslationCapability.java
+    //
+    // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
+    //   Settings > Editor > Code Style > Formatter Control
+    //@formatter:off
+
+
+    /** @hide */
+    @IntDef(prefix = "STATE_", value = {
+        STATE_AVAILABLE_TO_DOWNLOAD,
+        STATE_DOWNLOADING,
+        STATE_ON_DEVICE
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    @DataClass.Generated.Member
+    public @interface ModelState {}
+
+    /** @hide */
+    @DataClass.Generated.Member
+    public static String modelStateToString(@ModelState int value) {
+        switch (value) {
+            case STATE_AVAILABLE_TO_DOWNLOAD:
+                    return "STATE_AVAILABLE_TO_DOWNLOAD";
+            case STATE_DOWNLOADING:
+                    return "STATE_DOWNLOADING";
+            case STATE_ON_DEVICE:
+                    return "STATE_ON_DEVICE";
+            default: return Integer.toHexString(value);
+        }
+    }
+
+    /**
+     * The state of translation readiness between {@code mSourceSpec} and {@code mTargetSpec}.
+     */
+    @DataClass.Generated.Member
+    public @ModelState int getState() {
+        return mState;
+    }
+
+    /**
+     * {@link TranslationSpec} describing the source data specs for this
+     * capability.
+     */
+    @DataClass.Generated.Member
+    public @NonNull TranslationSpec getSourceSpec() {
+        return mSourceSpec;
+    }
+
+    /**
+     * {@link TranslationSpec} describing the target data specs for this
+     * capability.
+     */
+    @DataClass.Generated.Member
+    public @NonNull TranslationSpec getTargetSpec() {
+        return mTargetSpec;
+    }
+
+    /**
+     * Whether ui translation for the source-target {@link TranslationSpec}s is enabled.
+     *
+     * <p>Translation service will still support translation requests for this capability.</p>
+     */
+    @DataClass.Generated.Member
+    public boolean isUiTranslationEnabled() {
+        return mUiTranslationEnabled;
+    }
+
+    /**
+     * Translation flags for settings that are supported by the
+     * {@link android.service.translation.TranslationService} between the {@link TranslationSpec}s
+     * provided in this capability.
+     */
+    @DataClass.Generated.Member
+    public @TranslationContext.TranslationFlag int getSupportedTranslationFlags() {
+        return mSupportedTranslationFlags;
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public String toString() {
+        // You can override field toString logic by defining methods like:
+        // String fieldNameToString() { ... }
+
+        return "TranslationCapability { " +
+                "state = " + modelStateToString(mState) + ", " +
+                "sourceSpec = " + mSourceSpec + ", " +
+                "targetSpec = " + mTargetSpec + ", " +
+                "uiTranslationEnabled = " + mUiTranslationEnabled + ", " +
+                "supportedTranslationFlags = " + mSupportedTranslationFlags +
+        " }";
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public void writeToParcel(@NonNull android.os.Parcel dest, int flags) {
+        // You can override field parcelling by defining methods like:
+        // void parcelFieldName(Parcel dest, int flags) { ... }
+
+        byte flg = 0;
+        if (mUiTranslationEnabled) flg |= 0x8;
+        dest.writeByte(flg);
+        dest.writeInt(mState);
+        dest.writeTypedObject(mSourceSpec, flags);
+        dest.writeTypedObject(mTargetSpec, flags);
+        dest.writeInt(mSupportedTranslationFlags);
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public int describeContents() { return 0; }
+
+    /** @hide */
+    @SuppressWarnings({"unchecked", "RedundantCast"})
+    @DataClass.Generated.Member
+    /* package-private */ TranslationCapability(@NonNull android.os.Parcel in) {
+        // You can override field unparcelling by defining methods like:
+        // static FieldType unparcelFieldName(Parcel in) { ... }
+
+        byte flg = in.readByte();
+        boolean uiTranslationEnabled = (flg & 0x8) != 0;
+        int state = in.readInt();
+        TranslationSpec sourceSpec = (TranslationSpec) in.readTypedObject(TranslationSpec.CREATOR);
+        TranslationSpec targetSpec = (TranslationSpec) in.readTypedObject(TranslationSpec.CREATOR);
+        int supportedTranslationFlags = in.readInt();
+
+        this.mState = state;
+
+        if (!(mState == STATE_AVAILABLE_TO_DOWNLOAD)
+                && !(mState == STATE_DOWNLOADING)
+                && !(mState == STATE_ON_DEVICE)) {
+            throw new java.lang.IllegalArgumentException(
+                    "state was " + mState + " but must be one of: "
+                            + "STATE_AVAILABLE_TO_DOWNLOAD(" + STATE_AVAILABLE_TO_DOWNLOAD + "), "
+                            + "STATE_DOWNLOADING(" + STATE_DOWNLOADING + "), "
+                            + "STATE_ON_DEVICE(" + STATE_ON_DEVICE + ")");
+        }
+
+        this.mSourceSpec = sourceSpec;
+        com.android.internal.util.AnnotationValidations.validate(
+                NonNull.class, null, mSourceSpec);
+        this.mTargetSpec = targetSpec;
+        com.android.internal.util.AnnotationValidations.validate(
+                NonNull.class, null, mTargetSpec);
+        this.mUiTranslationEnabled = uiTranslationEnabled;
+        this.mSupportedTranslationFlags = supportedTranslationFlags;
+        com.android.internal.util.AnnotationValidations.validate(
+                TranslationContext.TranslationFlag.class, null, mSupportedTranslationFlags);
+
+        // onConstructed(); // You can define this method to get a callback
+    }
+
+    @DataClass.Generated.Member
+    public static final @NonNull Parcelable.Creator<TranslationCapability> CREATOR
+            = new Parcelable.Creator<TranslationCapability>() {
+        @Override
+        public TranslationCapability[] newArray(int size) {
+            return new TranslationCapability[size];
+        }
+
+        @Override
+        public TranslationCapability createFromParcel(@NonNull android.os.Parcel in) {
+            return new TranslationCapability(in);
+        }
+    };
+
+    @DataClass.Generated(
+            time = 1616438309593L,
+            codegenVersion = "1.0.22",
+            sourceFile = "frameworks/base/core/java/android/view/translation/TranslationCapability.java",
+            inputSignatures = "public static final @android.view.translation.TranslationCapability.ModelState int STATE_AVAILABLE_TO_DOWNLOAD\npublic static final @android.view.translation.TranslationCapability.ModelState int STATE_DOWNLOADING\npublic static final @android.view.translation.TranslationCapability.ModelState int STATE_ON_DEVICE\nprivate final @android.view.translation.TranslationCapability.ModelState int mState\nprivate final @android.annotation.NonNull android.view.translation.TranslationSpec mSourceSpec\nprivate final @android.annotation.NonNull android.view.translation.TranslationSpec mTargetSpec\nprivate final  boolean mUiTranslationEnabled\nprivate final @android.view.translation.TranslationContext.TranslationFlag int mSupportedTranslationFlags\nclass TranslationCapability extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genHiddenConstDefs=true, genToString=true, genConstructor=false)")
+    @Deprecated
+    private void __metadata() {}
+
+
+    //@formatter:on
+    // End of generated code
+
+}
diff --git a/services/core/java/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneIdValidator.java b/core/java/android/view/translation/TranslationContext.aidl
similarity index 61%
copy from services/core/java/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneIdValidator.java
copy to core/java/android/view/translation/TranslationContext.aidl
index cab5ad2..cb6c23f 100644
--- a/services/core/java/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneIdValidator.java
+++ b/core/java/android/view/translation/TranslationContext.aidl
@@ -14,17 +14,6 @@
  * limitations under the License.
  */
 
-package com.android.server.timezonedetector.location;
+package android.view.translation;
 
-import android.annotation.NonNull;
-
-import com.android.i18n.timezone.ZoneInfoDb;
-
-class ZoneInfoDbTimeZoneIdValidator implements
-        LocationTimeZoneProvider.TimeZoneIdValidator {
-
-    @Override
-    public boolean isValid(@NonNull String timeZoneId) {
-        return ZoneInfoDb.getInstance().hasTimeZone(timeZoneId);
-    }
-}
+parcelable TranslationContext;
diff --git a/core/java/android/view/translation/TranslationContext.java b/core/java/android/view/translation/TranslationContext.java
new file mode 100644
index 0000000..1d3d182
--- /dev/null
+++ b/core/java/android/view/translation/TranslationContext.java
@@ -0,0 +1,309 @@
+/*
+ * 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 android.view.translation;
+
+import android.annotation.NonNull;
+import android.os.Parcelable;
+
+import com.android.internal.util.DataClass;
+
+/**
+ * Info class holding information for {@link Translator}s and used by
+ * {@link TranslationManager#createTranslator(TranslationContext)}.
+ */
+@DataClass(genHiddenConstDefs = true, genToString = true, genBuilder = true)
+public final class TranslationContext implements Parcelable {
+
+    /**
+     * This context will perform translations in low latency mode.
+     */
+    public static final @TranslationFlag int FLAG_LOW_LATENCY = 0x1;
+    /**
+     * This context will enable the {@link Translator} to return transliteration results.
+     */
+    public static final @TranslationFlag int FLAG_TRANSLITERATION = 0x2;
+    /**
+     * This context will enable the {@link Translator} to return dictionary results.
+     */
+    public static final @TranslationFlag int FLAG_DICTIONARY_DESCRIPTION = 0x4;
+
+    /**
+     * {@link TranslationSpec} describing the source data to be translated.
+     */
+    @NonNull
+    private final TranslationSpec mSourceSpec;
+
+    /**
+     * {@link TranslationSpec} describing the target translated data.
+     */
+    @NonNull
+    private final TranslationSpec mTargetSpec;
+
+    /**
+     * Translation flags to be used by the {@link Translator}
+     */
+    private final @TranslationFlag int mTranslationFlags;
+
+    private static int defaultTranslationFlags() {
+        return 0;
+    }
+
+    @DataClass.Suppress({"setSourceSpec", "setTargetSpec"})
+    abstract static class BaseBuilder {
+
+    }
+
+
+
+    // Code below generated by codegen v1.0.22.
+    //
+    // DO NOT MODIFY!
+    // CHECKSTYLE:OFF Generated code
+    //
+    // To regenerate run:
+    // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/view/translation/TranslationContext.java
+    //
+    // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
+    //   Settings > Editor > Code Style > Formatter Control
+    //@formatter:off
+
+
+    /** @hide */
+    @android.annotation.IntDef(flag = true, prefix = "FLAG_", value = {
+        FLAG_LOW_LATENCY,
+        FLAG_TRANSLITERATION,
+        FLAG_DICTIONARY_DESCRIPTION
+    })
+    @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE)
+    @DataClass.Generated.Member
+    public @interface TranslationFlag {}
+
+    /** @hide */
+    @DataClass.Generated.Member
+    public static String translationFlagToString(@TranslationFlag int value) {
+        return com.android.internal.util.BitUtils.flagsToString(
+                value, TranslationContext::singleTranslationFlagToString);
+    }
+
+    @DataClass.Generated.Member
+    static String singleTranslationFlagToString(@TranslationFlag int value) {
+        switch (value) {
+            case FLAG_LOW_LATENCY:
+                    return "FLAG_LOW_LATENCY";
+            case FLAG_TRANSLITERATION:
+                    return "FLAG_TRANSLITERATION";
+            case FLAG_DICTIONARY_DESCRIPTION:
+                    return "FLAG_DICTIONARY_DESCRIPTION";
+            default: return Integer.toHexString(value);
+        }
+    }
+
+    @DataClass.Generated.Member
+    /* package-private */ TranslationContext(
+            @NonNull TranslationSpec sourceSpec,
+            @NonNull TranslationSpec targetSpec,
+            @TranslationFlag int translationFlags) {
+        this.mSourceSpec = sourceSpec;
+        com.android.internal.util.AnnotationValidations.validate(
+                NonNull.class, null, mSourceSpec);
+        this.mTargetSpec = targetSpec;
+        com.android.internal.util.AnnotationValidations.validate(
+                NonNull.class, null, mTargetSpec);
+        this.mTranslationFlags = translationFlags;
+
+        com.android.internal.util.Preconditions.checkFlagsArgument(
+                mTranslationFlags,
+                FLAG_LOW_LATENCY
+                        | FLAG_TRANSLITERATION
+                        | FLAG_DICTIONARY_DESCRIPTION);
+
+        // onConstructed(); // You can define this method to get a callback
+    }
+
+    /**
+     * {@link TranslationSpec} describing the source data to be translated.
+     */
+    @DataClass.Generated.Member
+    public @NonNull TranslationSpec getSourceSpec() {
+        return mSourceSpec;
+    }
+
+    /**
+     * {@link TranslationSpec} describing the target translated data.
+     */
+    @DataClass.Generated.Member
+    public @NonNull TranslationSpec getTargetSpec() {
+        return mTargetSpec;
+    }
+
+    /**
+     * Translation flags to be used by the {@link Translator}
+     */
+    @DataClass.Generated.Member
+    public @TranslationFlag int getTranslationFlags() {
+        return mTranslationFlags;
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public String toString() {
+        // You can override field toString logic by defining methods like:
+        // String fieldNameToString() { ... }
+
+        return "TranslationContext { " +
+                "sourceSpec = " + mSourceSpec + ", " +
+                "targetSpec = " + mTargetSpec + ", " +
+                "translationFlags = " + translationFlagToString(mTranslationFlags) +
+        " }";
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public void writeToParcel(@NonNull android.os.Parcel dest, int flags) {
+        // You can override field parcelling by defining methods like:
+        // void parcelFieldName(Parcel dest, int flags) { ... }
+
+        dest.writeTypedObject(mSourceSpec, flags);
+        dest.writeTypedObject(mTargetSpec, flags);
+        dest.writeInt(mTranslationFlags);
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public int describeContents() { return 0; }
+
+    /** @hide */
+    @SuppressWarnings({"unchecked", "RedundantCast"})
+    @DataClass.Generated.Member
+    /* package-private */ TranslationContext(@NonNull android.os.Parcel in) {
+        // You can override field unparcelling by defining methods like:
+        // static FieldType unparcelFieldName(Parcel in) { ... }
+
+        TranslationSpec sourceSpec = (TranslationSpec) in.readTypedObject(TranslationSpec.CREATOR);
+        TranslationSpec targetSpec = (TranslationSpec) in.readTypedObject(TranslationSpec.CREATOR);
+        int translationFlags = in.readInt();
+
+        this.mSourceSpec = sourceSpec;
+        com.android.internal.util.AnnotationValidations.validate(
+                NonNull.class, null, mSourceSpec);
+        this.mTargetSpec = targetSpec;
+        com.android.internal.util.AnnotationValidations.validate(
+                NonNull.class, null, mTargetSpec);
+        this.mTranslationFlags = translationFlags;
+
+        com.android.internal.util.Preconditions.checkFlagsArgument(
+                mTranslationFlags,
+                FLAG_LOW_LATENCY
+                        | FLAG_TRANSLITERATION
+                        | FLAG_DICTIONARY_DESCRIPTION);
+
+        // onConstructed(); // You can define this method to get a callback
+    }
+
+    @DataClass.Generated.Member
+    public static final @NonNull Parcelable.Creator<TranslationContext> CREATOR
+            = new Parcelable.Creator<TranslationContext>() {
+        @Override
+        public TranslationContext[] newArray(int size) {
+            return new TranslationContext[size];
+        }
+
+        @Override
+        public TranslationContext createFromParcel(@NonNull android.os.Parcel in) {
+            return new TranslationContext(in);
+        }
+    };
+
+    /**
+     * A builder for {@link TranslationContext}
+     */
+    @SuppressWarnings("WeakerAccess")
+    @DataClass.Generated.Member
+    public static final class Builder extends BaseBuilder {
+
+        private @NonNull TranslationSpec mSourceSpec;
+        private @NonNull TranslationSpec mTargetSpec;
+        private @TranslationFlag int mTranslationFlags;
+
+        private long mBuilderFieldsSet = 0L;
+
+        /**
+         * Creates a new Builder.
+         *
+         * @param sourceSpec
+         *   {@link TranslationSpec} describing the source data to be translated.
+         * @param targetSpec
+         *   {@link TranslationSpec} describing the target translated data.
+         */
+        public Builder(
+                @NonNull TranslationSpec sourceSpec,
+                @NonNull TranslationSpec targetSpec) {
+            mSourceSpec = sourceSpec;
+            com.android.internal.util.AnnotationValidations.validate(
+                    NonNull.class, null, mSourceSpec);
+            mTargetSpec = targetSpec;
+            com.android.internal.util.AnnotationValidations.validate(
+                    NonNull.class, null, mTargetSpec);
+        }
+
+        /**
+         * Translation flags to be used by the {@link Translator}
+         */
+        @DataClass.Generated.Member
+        public @NonNull Builder setTranslationFlags(@TranslationFlag int value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x4;
+            mTranslationFlags = value;
+            return this;
+        }
+
+        /** Builds the instance. This builder should not be touched after calling this! */
+        public @NonNull TranslationContext build() {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x8; // Mark builder used
+
+            if ((mBuilderFieldsSet & 0x4) == 0) {
+                mTranslationFlags = defaultTranslationFlags();
+            }
+            TranslationContext o = new TranslationContext(
+                    mSourceSpec,
+                    mTargetSpec,
+                    mTranslationFlags);
+            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 = 1616199021789L,
+            codegenVersion = "1.0.22",
+            sourceFile = "frameworks/base/core/java/android/view/translation/TranslationContext.java",
+            inputSignatures = "public static final @android.view.translation.TranslationContext.TranslationFlag int FLAG_LOW_LATENCY\npublic static final @android.view.translation.TranslationContext.TranslationFlag int FLAG_TRANSLITERATION\npublic static final @android.view.translation.TranslationContext.TranslationFlag int FLAG_DICTIONARY_DESCRIPTION\nprivate final @android.annotation.NonNull android.view.translation.TranslationSpec mSourceSpec\nprivate final @android.annotation.NonNull android.view.translation.TranslationSpec mTargetSpec\nprivate final @android.view.translation.TranslationContext.TranslationFlag int mTranslationFlags\nprivate static  int defaultTranslationFlags()\nclass TranslationContext extends java.lang.Object implements [android.os.Parcelable]\nclass BaseBuilder extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genHiddenConstDefs=true, genToString=true, genBuilder=true)\nclass BaseBuilder extends java.lang.Object implements []")
+    @Deprecated
+    private void __metadata() {}
+
+
+    //@formatter:on
+    // End of generated code
+
+}
diff --git a/core/java/android/view/translation/TranslationManager.java b/core/java/android/view/translation/TranslationManager.java
index 6554e1a..b89488b 100644
--- a/core/java/android/view/translation/TranslationManager.java
+++ b/core/java/android/view/translation/TranslationManager.java
@@ -21,13 +21,15 @@
 import android.annotation.RequiresFeature;
 import android.annotation.SystemService;
 import android.annotation.WorkerThread;
+import android.app.PendingIntent;
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.RemoteException;
-import android.service.translation.TranslationService;
+import android.os.SynchronousResultReceiver;
 import android.util.ArrayMap;
+import android.util.ArraySet;
 import android.util.Log;
 import android.util.Pair;
 import android.util.SparseArray;
@@ -35,10 +37,12 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.SyncResultReceiver;
 
+import java.util.ArrayList;
 import java.util.Collections;
-import java.util.List;
 import java.util.Objects;
 import java.util.Random;
+import java.util.Set;
+import java.util.concurrent.TimeoutException;
 import java.util.concurrent.atomic.AtomicInteger;
 
 /**
@@ -55,9 +59,9 @@
     private static final String TAG = "TranslationManager";
 
     /**
-     * Timeout for calls to system_server.
+     * Timeout for calls to system_server, default 1 minute.
      */
-    static final int SYNC_CALLS_TIMEOUT_MS = 5000;
+    static final int SYNC_CALLS_TIMEOUT_MS = 60_000;
     /**
      * The result code from result receiver success.
      * @hide
@@ -69,6 +73,17 @@
      */
     public static final int STATUS_SYNC_CALL_FAIL = 2;
 
+    /**
+     * Name of the extra used to pass the translation capabilities.
+     * @hide
+     */
+    public static final String EXTRA_CAPABILITIES = "translation_capabilities";
+
+    // TODO: implement update listeners and propagate updates.
+    @GuardedBy("mLock")
+    private final ArrayMap<Pair<Integer, Integer>, ArrayList<PendingIntent>>
+            mTranslationCapabilityUpdateListeners = new ArrayMap<>();
+
     private static final Random ID_GENERATOR = new Random();
     private final Object mLock = new Object();
 
@@ -87,7 +102,7 @@
 
     @NonNull
     @GuardedBy("mLock")
-    private final ArrayMap<Pair<TranslationSpec, TranslationSpec>, Integer> mTranslatorIds =
+    private final ArrayMap<TranslationContext, Integer> mTranslatorIds =
             new ArrayMap<>();
 
     @NonNull
@@ -106,27 +121,23 @@
     }
 
     /**
-     * Create a Translator for translation.
+     * Creates an on-device Translator for natural language translation.
      *
      * <p><strong>NOTE: </strong>Call on a worker thread.
      *
-     * @param sourceSpec {@link TranslationSpec} for the data to be translated.
-     * @param destSpec {@link TranslationSpec} for the translated data.
-     * @return a {@link Translator} to be used for calling translation APIs.
+     * @param translationContext {@link TranslationContext} containing the specs for creating the
+     *                                                     Translator.
      */
     @Nullable
     @WorkerThread
-    public Translator createTranslator(@NonNull TranslationSpec sourceSpec,
-            @NonNull TranslationSpec destSpec) {
-        Objects.requireNonNull(sourceSpec, "sourceSpec cannot be null");
-        Objects.requireNonNull(sourceSpec, "destSpec cannot be null");
+    public Translator createOnDeviceTranslator(@NonNull TranslationContext translationContext) {
+        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.
-            final Pair<TranslationSpec, TranslationSpec> specs = new Pair<>(sourceSpec, destSpec);
-            if (mTranslatorIds.containsKey(specs)) {
-                return mTranslators.get(mTranslatorIds.get(specs));
+            if (mTranslatorIds.containsKey(translationContext)) {
+                return mTranslators.get(mTranslatorIds.get(translationContext));
             }
 
             int translatorId;
@@ -134,7 +145,7 @@
                 translatorId = Math.abs(ID_GENERATOR.nextInt());
             } while (translatorId == 0 || mTranslators.indexOfKey(translatorId) >= 0);
 
-            final Translator newTranslator = new Translator(mContext, sourceSpec, destSpec,
+            final Translator newTranslator = new Translator(mContext, translationContext,
                     translatorId, this, mHandler, mService);
             // Start the Translator session and wait for the result
             newTranslator.start();
@@ -143,7 +154,7 @@
                     return null;
                 }
                 mTranslators.put(translatorId, newTranslator);
-                mTranslatorIds.put(specs, translatorId);
+                mTranslatorIds.put(translationContext, translatorId);
                 return newTranslator;
             } catch (Translator.ServiceBinderReceiver.TimeoutException e) {
                 // TODO(b/176464808): maybe make SyncResultReceiver.TimeoutException constructor
@@ -154,33 +165,180 @@
         }
     }
 
+    /** @deprecated Use {@link #createOnDeviceTranslator(TranslationContext)} */
+    @Deprecated
+    @Nullable
+    @WorkerThread
+    public Translator createTranslator(@NonNull TranslationContext translationContext) {
+        return createOnDeviceTranslator(translationContext);
+    }
+
     /**
-     * Returns a list of locales supported by the {@link TranslationService}.
+     * Returns a set of {@link TranslationCapability}s describing the capabilities for on-device
+     * {@link Translator}s.
+     *
+     * <p>These translation capabilities contains a source and target {@link TranslationSpec}
+     * representing the data expected for both ends of translation process. The capabilities
+     * provides the information and limitations for generating a {@link TranslationContext}.
+     * The context object can then be used by {@link #createTranslator(TranslationContext)} to
+     * obtain a {@link Translator} for translations.</p>
      *
      * <p><strong>NOTE: </strong>Call on a worker thread.
      *
-     * TODO: Change to correct language/locale format
+     * @param sourceFormat data format for the input data to be translated.
+     * @param targetFormat data format for the expected translated output data.
+     * @return A set of {@link TranslationCapability}s.
      */
     @NonNull
     @WorkerThread
-    public List<String> getSupportedLocales() {
+    public Set<TranslationCapability> getOnDeviceTranslationCapabilities(
+            @TranslationSpec.DataFormat int sourceFormat,
+            @TranslationSpec.DataFormat int targetFormat) {
         try {
-            // TODO: implement it
-            final SyncResultReceiver receiver = new SyncResultReceiver(SYNC_CALLS_TIMEOUT_MS);
-            mService.getSupportedLocales(receiver, mContext.getUserId());
-            int resutCode = receiver.getIntResult();
-            if (resutCode != STATUS_SYNC_CALL_SUCCESS) {
-                return Collections.emptyList();
+            final SynchronousResultReceiver receiver = new SynchronousResultReceiver();
+            mService.onTranslationCapabilitiesRequest(sourceFormat, targetFormat, receiver,
+                    mContext.getUserId());
+            final SynchronousResultReceiver.Result result =
+                    receiver.awaitResult(SYNC_CALLS_TIMEOUT_MS);
+            if (result.resultCode != STATUS_SYNC_CALL_SUCCESS) {
+                return Collections.emptySet();
             }
-            return receiver.getParcelableResult();
+            return new ArraySet<>(
+                    (TranslationCapability[]) result.bundle.getParcelableArray(EXTRA_CAPABILITIES));
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
-        } catch (SyncResultReceiver.TimeoutException e) {
-            Log.e(TAG, "Timed out getting supported locales: " + e);
-            return Collections.emptyList();
+        } catch (TimeoutException e) {
+            Log.e(TAG, "Timed out getting supported translation capabilities: " + e);
+            return Collections.emptySet();
         }
     }
 
+    /** @deprecated Use {@link #getOnDeviceTranslationCapabilities(int, int)} */
+    @Deprecated
+    @NonNull
+    @WorkerThread
+    public Set<TranslationCapability> getTranslationCapabilities(
+            @TranslationSpec.DataFormat int sourceFormat,
+            @TranslationSpec.DataFormat int targetFormat) {
+        return getOnDeviceTranslationCapabilities(sourceFormat, targetFormat);
+    }
+
+    /**
+     * Registers a {@link PendingIntent} to listen for updates on states of on-device
+     * {@link TranslationCapability}s.
+     *
+     * <p>IMPORTANT: the pending intent must be called to start a service, or a broadcast if it is
+     * an explicit intent.</p>
+     *
+     * @param sourceFormat data format for the input data to be translated.
+     * @param targetFormat data format for the expected translated output data.
+     * @param pendingIntent the pending intent to invoke when updates are received.
+     */
+    public void addOnDeviceTranslationCapabilityUpdateListener(
+            @TranslationSpec.DataFormat int sourceFormat,
+            @TranslationSpec.DataFormat int targetFormat,
+            @NonNull PendingIntent pendingIntent) {
+        Objects.requireNonNull(pendingIntent, "pending intent should not be null");
+
+        synchronized (mLock) {
+            final Pair<Integer, Integer> formatPair = new Pair<>(sourceFormat, targetFormat);
+            mTranslationCapabilityUpdateListeners.computeIfAbsent(formatPair,
+                    (formats) -> new ArrayList<>()).add(pendingIntent);
+        }
+    }
+
+    /**
+     * @deprecated Use {@link #addOnDeviceTranslationCapabilityUpdateListener(int, int,
+     *  PendingIntent)}
+     */
+    @Deprecated
+    public void addTranslationCapabilityUpdateListener(
+            @TranslationSpec.DataFormat int sourceFormat,
+            @TranslationSpec.DataFormat int targetFormat,
+            @NonNull PendingIntent pendingIntent) {
+        addOnDeviceTranslationCapabilityUpdateListener(sourceFormat, targetFormat, pendingIntent);
+    }
+
+    /**
+     * Unregisters a {@link PendingIntent} to listen for updates on states of on-device
+     * {@link TranslationCapability}s.
+     *
+     * @param sourceFormat data format for the input data to be translated.
+     * @param targetFormat data format for the expected translated output data.
+     * @param pendingIntent the pending intent to unregister
+     */
+    public void removeOnDeviceTranslationCapabilityUpdateListener(
+            @TranslationSpec.DataFormat int sourceFormat,
+            @TranslationSpec.DataFormat int targetFormat,
+            @NonNull PendingIntent pendingIntent) {
+        Objects.requireNonNull(pendingIntent, "pending intent should not be null");
+
+        synchronized (mLock) {
+            final Pair<Integer, Integer> formatPair = new Pair<>(sourceFormat, targetFormat);
+            if (mTranslationCapabilityUpdateListeners.containsKey(formatPair)) {
+                final ArrayList<PendingIntent> intents =
+                        mTranslationCapabilityUpdateListeners.get(formatPair);
+                if (intents.contains(pendingIntent)) {
+                    intents.remove(pendingIntent);
+                } else {
+                    Log.w(TAG, "pending intent=" + pendingIntent + " does not exist in "
+                            + "mTranslationCapabilityUpdateListeners");
+                }
+            } else {
+                Log.w(TAG, "format pair=" + formatPair + " does not exist in "
+                        + "mTranslationCapabilityUpdateListeners");
+            }
+        }
+    }
+
+    /**
+     * @deprecated Use {@link #removeOnDeviceTranslationCapabilityUpdateListener(int, int,
+     *  PendingIntent)}
+     */
+    @Deprecated
+    public void removeTranslationCapabilityUpdateListener(
+            @TranslationSpec.DataFormat int sourceFormat,
+            @TranslationSpec.DataFormat int targetFormat,
+            @NonNull PendingIntent pendingIntent) {
+        removeOnDeviceTranslationCapabilityUpdateListener(
+                sourceFormat, targetFormat, pendingIntent);
+    }
+
+    //TODO: Add method to propagate updates to mTCapabilityUpdateListeners
+
+    /**
+     * Returns an immutable PendingIntent which can be used to launch an activity to view/edit
+     * on-device translation settings.
+     *
+     * @return An immutable PendingIntent or {@code null} if one of reason met:
+     * <ul>
+     *     <li>Device manufacturer (OEM) does not provide TranslationService.</li>
+     *     <li>The TranslationService doesn't provide the Settings.</li>
+     * </ul>
+     **/
+    @Nullable
+    public PendingIntent getOnDeviceTranslationSettingsActivityIntent() {
+        final SyncResultReceiver resultReceiver = new SyncResultReceiver(SYNC_CALLS_TIMEOUT_MS);
+        try {
+            mService.getServiceSettingsActivity(resultReceiver, mContext.getUserId());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+        try {
+            return resultReceiver.getParcelableResult();
+        } catch (SyncResultReceiver.TimeoutException e) {
+            Log.e(TAG, "Fail to get translation service settings activity.");
+            return null;
+        }
+    }
+
+    /** @deprecated Use {@link #getOnDeviceTranslationSettingsActivityIntent()} */
+    @Deprecated
+    @Nullable
+    public PendingIntent getTranslationSettingsActivityIntent() {
+        return getOnDeviceTranslationSettingsActivityIntent();
+    }
+
     void removeTranslator(int id) {
         synchronized (mLock) {
             mTranslators.remove(id);
diff --git a/core/java/android/view/translation/TranslationResponse.java b/core/java/android/view/translation/TranslationResponse.java
index 03731e1..35040f1 100644
--- a/core/java/android/view/translation/TranslationResponse.java
+++ b/core/java/android/view/translation/TranslationResponse.java
@@ -67,6 +67,14 @@
     @NonNull
     private final SparseArray<ViewTranslationResponse> mViewTranslationResponses;
 
+    /**
+     * Whether this response contains complete translated values, or is the final response in a
+     * series of partial responses.
+     *
+     * <p>This is {@code true} by default.</p>
+     */
+    private final boolean mFinalResponse;
+
     abstract static class BaseBuilder {
 
         /**
@@ -122,6 +130,10 @@
         return new SparseArray<>();
     }
 
+    private static boolean defaultFinalResponse() {
+        return true;
+    }
+
 
 
 
@@ -166,7 +178,8 @@
     /* package-private */ TranslationResponse(
             @TranslationStatus int translationStatus,
             @NonNull SparseArray<TranslationResponseValue> translationResponseValues,
-            @NonNull SparseArray<ViewTranslationResponse> viewTranslationResponses) {
+            @NonNull SparseArray<ViewTranslationResponse> viewTranslationResponses,
+            boolean finalResponse) {
         this.mTranslationStatus = translationStatus;
 
         if (!(mTranslationStatus == TRANSLATION_STATUS_SUCCESS)
@@ -185,6 +198,7 @@
         this.mViewTranslationResponses = viewTranslationResponses;
         com.android.internal.util.AnnotationValidations.validate(
                 NonNull.class, null, mViewTranslationResponses);
+        this.mFinalResponse = finalResponse;
 
         // onConstructed(); // You can define this method to get a callback
     }
@@ -215,6 +229,17 @@
         return mViewTranslationResponses;
     }
 
+    /**
+     * Whether this response contains complete translated values, or is the final response in a
+     * series of partial responses.
+     *
+     * <p>This is {@code true} by default.</p>
+     */
+    @DataClass.Generated.Member
+    public boolean isFinalResponse() {
+        return mFinalResponse;
+    }
+
     @Override
     @DataClass.Generated.Member
     public String toString() {
@@ -224,7 +249,8 @@
         return "TranslationResponse { " +
                 "translationStatus = " + translationStatusToString(mTranslationStatus) + ", " +
                 "translationResponseValues = " + mTranslationResponseValues + ", " +
-                "viewTranslationResponses = " + mViewTranslationResponses +
+                "viewTranslationResponses = " + mViewTranslationResponses + ", " +
+                "finalResponse = " + mFinalResponse +
         " }";
     }
 
@@ -234,6 +260,9 @@
         // You can override field parcelling by defining methods like:
         // void parcelFieldName(Parcel dest, int flags) { ... }
 
+        byte flg = 0;
+        if (mFinalResponse) flg |= 0x8;
+        dest.writeByte(flg);
         dest.writeInt(mTranslationStatus);
         dest.writeSparseArray(mTranslationResponseValues);
         dest.writeSparseArray(mViewTranslationResponses);
@@ -250,6 +279,8 @@
         // You can override field unparcelling by defining methods like:
         // static FieldType unparcelFieldName(Parcel in) { ... }
 
+        byte flg = in.readByte();
+        boolean finalResponse = (flg & 0x8) != 0;
         int translationStatus = in.readInt();
         SparseArray<TranslationResponseValue> translationResponseValues = (SparseArray) in.readSparseArray(TranslationResponseValue.class.getClassLoader());
         SparseArray<ViewTranslationResponse> viewTranslationResponses = (SparseArray) in.readSparseArray(ViewTranslationResponse.class.getClassLoader());
@@ -272,6 +303,7 @@
         this.mViewTranslationResponses = viewTranslationResponses;
         com.android.internal.util.AnnotationValidations.validate(
                 NonNull.class, null, mViewTranslationResponses);
+        this.mFinalResponse = finalResponse;
 
         // onConstructed(); // You can define this method to get a callback
     }
@@ -300,6 +332,7 @@
         private @TranslationStatus int mTranslationStatus;
         private @NonNull SparseArray<TranslationResponseValue> mTranslationResponseValues;
         private @NonNull SparseArray<ViewTranslationResponse> mViewTranslationResponses;
+        private boolean mFinalResponse;
 
         private long mBuilderFieldsSet = 0L;
 
@@ -360,10 +393,24 @@
             return this;
         }
 
+        /**
+         * Whether this response contains complete translated values, or is the final response in a
+         * series of partial responses.
+         *
+         * <p>This is {@code true} by default.</p>
+         */
+        @DataClass.Generated.Member
+        public @NonNull Builder setFinalResponse(boolean value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x8;
+            mFinalResponse = value;
+            return this;
+        }
+
         /** Builds the instance. This builder should not be touched after calling this! */
         public @NonNull TranslationResponse build() {
             checkNotUsed();
-            mBuilderFieldsSet |= 0x8; // Mark builder used
+            mBuilderFieldsSet |= 0x10; // Mark builder used
 
             if ((mBuilderFieldsSet & 0x2) == 0) {
                 mTranslationResponseValues = defaultTranslationResponseValues();
@@ -371,15 +418,19 @@
             if ((mBuilderFieldsSet & 0x4) == 0) {
                 mViewTranslationResponses = defaultViewTranslationResponses();
             }
+            if ((mBuilderFieldsSet & 0x8) == 0) {
+                mFinalResponse = defaultFinalResponse();
+            }
             TranslationResponse o = new TranslationResponse(
                     mTranslationStatus,
                     mTranslationResponseValues,
-                    mViewTranslationResponses);
+                    mViewTranslationResponses,
+                    mFinalResponse);
             return o;
         }
 
         private void checkNotUsed() {
-            if ((mBuilderFieldsSet & 0x8) != 0) {
+            if ((mBuilderFieldsSet & 0x10) != 0) {
                 throw new IllegalStateException(
                         "This Builder should not be reused. Use a new Builder instance instead");
             }
@@ -387,10 +438,10 @@
     }
 
     @DataClass.Generated(
-            time = 1614211889478L,
+            time = 1616189850232L,
             codegenVersion = "1.0.22",
             sourceFile = "frameworks/base/core/java/android/view/translation/TranslationResponse.java",
-            inputSignatures = "public static final  int TRANSLATION_STATUS_SUCCESS\npublic static final  int TRANSLATION_STATUS_UNKNOWN_ERROR\npublic static final  int TRANSLATION_STATUS_CONTEXT_UNSUPPORTED\nprivate final @android.view.translation.TranslationResponse.TranslationStatus int mTranslationStatus\nprivate final @android.annotation.NonNull android.util.SparseArray<android.view.translation.TranslationResponseValue> mTranslationResponseValues\nprivate final @android.annotation.NonNull android.util.SparseArray<android.view.translation.ViewTranslationResponse> mViewTranslationResponses\nprivate static  android.util.SparseArray<android.view.translation.TranslationResponseValue> defaultTranslationResponseValues()\nprivate static  android.util.SparseArray<android.view.translation.ViewTranslationResponse> defaultViewTranslationResponses()\nclass TranslationResponse extends java.lang.Object implements [android.os.Parcelable]\npublic @android.annotation.NonNull @java.lang.SuppressWarnings android.view.translation.TranslationResponse.Builder setTranslationResponseValue(int,android.view.translation.TranslationResponseValue)\npublic @android.annotation.NonNull @java.lang.SuppressWarnings android.view.translation.TranslationResponse.Builder setViewTranslationResponse(int,android.view.translation.ViewTranslationResponse)\nclass BaseBuilder extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genBuilder=true, genToString=true, genHiddenConstDefs=true)\npublic @android.annotation.NonNull @java.lang.SuppressWarnings android.view.translation.TranslationResponse.Builder setTranslationResponseValue(int,android.view.translation.TranslationResponseValue)\npublic @android.annotation.NonNull @java.lang.SuppressWarnings android.view.translation.TranslationResponse.Builder setViewTranslationResponse(int,android.view.translation.ViewTranslationResponse)\nclass BaseBuilder extends java.lang.Object implements []")
+            inputSignatures = "public static final  int TRANSLATION_STATUS_SUCCESS\npublic static final  int TRANSLATION_STATUS_UNKNOWN_ERROR\npublic static final  int TRANSLATION_STATUS_CONTEXT_UNSUPPORTED\nprivate final @android.view.translation.TranslationResponse.TranslationStatus int mTranslationStatus\nprivate final @android.annotation.NonNull android.util.SparseArray<android.view.translation.TranslationResponseValue> mTranslationResponseValues\nprivate final @android.annotation.NonNull android.util.SparseArray<android.view.translation.ViewTranslationResponse> mViewTranslationResponses\nprivate final  boolean mFinalResponse\nprivate static  android.util.SparseArray<android.view.translation.TranslationResponseValue> defaultTranslationResponseValues()\nprivate static  android.util.SparseArray<android.view.translation.ViewTranslationResponse> defaultViewTranslationResponses()\nprivate static  boolean defaultFinalResponse()\nclass TranslationResponse extends java.lang.Object implements [android.os.Parcelable]\npublic @android.annotation.NonNull @java.lang.SuppressWarnings android.view.translation.TranslationResponse.Builder setTranslationResponseValue(int,android.view.translation.TranslationResponseValue)\npublic @android.annotation.NonNull @java.lang.SuppressWarnings android.view.translation.TranslationResponse.Builder setViewTranslationResponse(int,android.view.translation.ViewTranslationResponse)\nclass BaseBuilder extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genBuilder=true, genToString=true, genHiddenConstDefs=true)\npublic @android.annotation.NonNull @java.lang.SuppressWarnings android.view.translation.TranslationResponse.Builder setTranslationResponseValue(int,android.view.translation.TranslationResponseValue)\npublic @android.annotation.NonNull @java.lang.SuppressWarnings android.view.translation.TranslationResponse.Builder setViewTranslationResponse(int,android.view.translation.ViewTranslationResponse)\nclass BaseBuilder extends java.lang.Object implements []")
     @Deprecated
     private void __metadata() {}
 
diff --git a/core/java/android/view/translation/Translator.java b/core/java/android/view/translation/Translator.java
index 3e1e6db..6b26e06 100644
--- a/core/java/android/view/translation/Translator.java
+++ b/core/java/android/view/translation/Translator.java
@@ -19,11 +19,12 @@
 import static android.view.translation.TranslationManager.STATUS_SYNC_CALL_FAIL;
 import static android.view.translation.TranslationManager.SYNC_CALLS_TIMEOUT_MS;
 
+import android.annotation.CallbackExecutor;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SuppressLint;
-import android.annotation.WorkerThread;
 import android.content.Context;
+import android.os.Binder;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
@@ -33,17 +34,17 @@
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.os.IResultReceiver;
-import com.android.internal.util.SyncResultReceiver;
 
 import java.io.PrintWriter;
 import java.lang.ref.WeakReference;
 import java.util.Objects;
 import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executor;
 import java.util.concurrent.TimeUnit;
 import java.util.function.Consumer;
 
 /**
- * The {@link Translator} for translation, defined by a source and a dest {@link TranslationSpec}.
+ * The {@link Translator} for translation, defined by a {@link TranslationContext}.
  */
 @SuppressLint("NotCloseable")
 public class Translator {
@@ -61,10 +62,7 @@
     private final Context mContext;
 
     @NonNull
-    private final TranslationSpec mSourceSpec;
-
-    @NonNull
-    private final TranslationSpec mDestSpec;
+    private final TranslationContext mTranslationContext;
 
     @NonNull
     private final TranslationManager mManager;
@@ -163,13 +161,11 @@
      * @hide
      */
     public Translator(@NonNull Context context,
-            @NonNull TranslationSpec sourceSpec,
-            @NonNull TranslationSpec destSpec, int sessionId,
+            @NonNull TranslationContext translationContext, int sessionId,
             @NonNull TranslationManager translationManager, @NonNull Handler handler,
             @Nullable ITranslationManager systemServerBinder) {
         mContext = context;
-        mSourceSpec = sourceSpec;
-        mDestSpec = destSpec;
+        mTranslationContext = translationContext;
         mId = sessionId;
         mManager = translationManager;
         mHandler = handler;
@@ -182,7 +178,7 @@
      */
     void start() {
         try {
-            mSystemServerBinder.onSessionCreated(mSourceSpec, mDestSpec, mId,
+            mSystemServerBinder.onSessionCreated(mTranslationContext, mId,
                     mServiceBinderReceiver, mContext.getUserId());
         } catch (RemoteException e) {
             Log.w(TAG, "RemoteException calling startSession(): " + e);
@@ -222,26 +218,28 @@
 
     /** @hide */
     public void dump(@NonNull String prefix, @NonNull PrintWriter pw) {
-        pw.print(prefix); pw.print("sourceSpec: "); pw.println(mSourceSpec);
-        pw.print(prefix); pw.print("destSpec: "); pw.println(mDestSpec);
+        pw.print(prefix); pw.print("translationContext: "); pw.println(mTranslationContext);
     }
 
     /**
      * Requests a translation for the provided {@link TranslationRequest} using the Translator's
      * source spec and destination spec.
      *
-     * <p><strong>NOTE: </strong>Call on a worker thread.
-     *
      * @param request {@link TranslationRequest} request to be translate.
      *
      * @return {@link TranslationRequest} containing translated request,
      *         or null if translation could not be done.
      * @throws IllegalStateException if this TextClassification session was destroyed when calls
      */
+    //TODO: Add cancellation signal
     @Nullable
-    @WorkerThread
-    public TranslationResponse translate(@NonNull TranslationRequest request) {
+    public void translate(@NonNull TranslationRequest request,
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull Consumer<TranslationResponse> callback) {
         Objects.requireNonNull(request, "Translation request cannot be null");
+        Objects.requireNonNull(executor, "Executor cannot be null");
+        Objects.requireNonNull(callback, "Callback cannot be null");
+
         if (isDestroyed()) {
             // TODO(b/176464808): Disallow multiple Translator now, it will throw
             //  IllegalStateException. Need to discuss if we can allow multiple Translators.
@@ -249,21 +247,13 @@
                     "This translator has been destroyed");
         }
 
-        TranslationResponse response = null;
+        final ITranslationCallback responseCallback =
+                new TranslationResponseCallbackImpl(callback, executor);
         try {
-            final SyncResultReceiver receiver = new SyncResultReceiver(SYNC_CALLS_TIMEOUT_MS);
-            mDirectServiceBinder.onTranslationRequest(request, mId, null, receiver);
-
-            response = receiver.getParcelableResult();
+            mDirectServiceBinder.onTranslationRequest(request, mId, responseCallback);
         } catch (RemoteException e) {
             Log.w(TAG, "RemoteException calling requestTranslate(): " + e);
-        }  catch (SyncResultReceiver.TimeoutException e) {
-            Log.e(TAG, "Timed out calling requestTranslate: " + e);
         }
-        if (sDEBUG) {
-            Log.v(TAG, "Receive translation response: " + response);
-        }
-        return response;
     }
 
     /**
@@ -299,15 +289,16 @@
     // TODO: add methods for UI-toolkit case.
     /** @hide */
     public void requestUiTranslate(@NonNull TranslationRequest request,
-            @NonNull Consumer<TranslationResponse> responseCallback) {
+            @NonNull Executor executor,
+            @NonNull Consumer<TranslationResponse> callback) {
         if (mDirectServiceBinder == null) {
             Log.wtf(TAG, "Translator created without proper initialization.");
             return;
         }
-        final ITranslationCallback callback =
-                new TranslationResponseCallbackImpl(responseCallback);
+        final ITranslationCallback translationCallback =
+                new TranslationResponseCallbackImpl(callback, executor);
         try {
-            mDirectServiceBinder.onTranslationRequest(request, mId, callback, null);
+            mDirectServiceBinder.onTranslationRequest(request, mId, translationCallback);
         } catch (RemoteException e) {
             Log.w(TAG, "RemoteException calling flushRequest");
         }
@@ -315,26 +306,46 @@
 
     private static class TranslationResponseCallbackImpl extends ITranslationCallback.Stub {
 
-        private final WeakReference<Consumer<TranslationResponse>> mResponseCallback;
+        private final WeakReference<Consumer<TranslationResponse>> mCallback;
+        private final WeakReference<Executor> mExecutor;
 
-        TranslationResponseCallbackImpl(Consumer<TranslationResponse> responseCallback) {
-            mResponseCallback = new WeakReference<>(responseCallback);
+        TranslationResponseCallbackImpl(Consumer<TranslationResponse> callback, Executor executor) {
+            mCallback = new WeakReference<>(callback);
+            mExecutor = new WeakReference<>(executor);
         }
 
         @Override
-        public void onTranslationComplete(TranslationResponse response) throws RemoteException {
-            provideTranslationResponse(response);
+        public void onTranslationResponse(TranslationResponse response) throws RemoteException {
+            final Consumer<TranslationResponse> callback = mCallback.get();
+            final Runnable runnable =
+                    () -> callback.accept(response);
+            if (callback != null) {
+                final Executor executor = mExecutor.get();
+                final long token = Binder.clearCallingIdentity();
+                try {
+                    executor.execute(runnable);
+                } finally {
+                    restoreCallingIdentity(token);
+                }
+            }
         }
 
         @Override
         public void onError() throws RemoteException {
-            provideTranslationResponse(null);
-        }
+            final Consumer<TranslationResponse>  callback = mCallback.get();
+            final Runnable runnable = () -> callback.accept(
+                    new TranslationResponse.Builder(
+                            TranslationResponse.TRANSLATION_STATUS_UNKNOWN_ERROR)
+                            .build());
 
-        private void provideTranslationResponse(TranslationResponse response) {
-            final Consumer<TranslationResponse> responseCallback = mResponseCallback.get();
-            if (responseCallback != null) {
-                responseCallback.accept(response);
+            if (callback != null) {
+                final Executor executor = mExecutor.get();
+                final long token = Binder.clearCallingIdentity();
+                try {
+                    executor.execute(runnable);
+                } finally {
+                    restoreCallingIdentity(token);
+                }
             }
         }
     }
diff --git a/core/java/android/view/translation/UiTranslationController.java b/core/java/android/view/translation/UiTranslationController.java
index 9f90b3b..0fa6e16 100644
--- a/core/java/android/view/translation/UiTranslationController.java
+++ b/core/java/android/view/translation/UiTranslationController.java
@@ -31,8 +31,10 @@
 import android.os.Process;
 import android.util.ArrayMap;
 import android.util.Log;
+import android.util.LongSparseArray;
 import android.util.Pair;
 import android.util.SparseArray;
+import android.util.SparseIntArray;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewRootImpl;
@@ -46,7 +48,8 @@
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.function.Consumer;
+import java.util.Map;
+import java.util.function.BiConsumer;
 
 /**
  * A controller to manage the ui translation requests for the {@link Activity}.
@@ -77,6 +80,7 @@
     private final HandlerThread mWorkerThread;
     @NonNull
     private final Handler mWorkerHandler;
+    private int mCurrentState;
 
     public UiTranslationController(Activity activity, Context context) {
         mActivity = activity;
@@ -101,6 +105,9 @@
         }
         Log.i(TAG, "updateUiTranslationState state: " + stateToString(state)
                 + (DEBUG ? ", views: " + views : ""));
+        synchronized (mLock) {
+            mCurrentState = state;
+        }
         switch (state) {
             case STATE_UI_TRANSLATION_STARTED:
                 final Pair<TranslationSpec, TranslationSpec> specs =
@@ -114,14 +121,14 @@
                 }
                 break;
             case STATE_UI_TRANSLATION_PAUSED:
-                runForEachView(View::onPauseUiTranslation);
+                runForEachView((view, callback) -> callback.onHideTranslation(view));
                 break;
             case STATE_UI_TRANSLATION_RESUMED:
-                runForEachView(View::onRestoreUiTranslation);
+                runForEachView((view, callback) -> callback.onShowTranslation(view));
                 break;
             case STATE_UI_TRANSLATION_FINISHED:
                 destroyTranslators();
-                runForEachView(View::onFinishUiTranslation);
+                runForEachView((view, callback) -> callback.onClearTranslation(view));
                 synchronized (mLock) {
                     mViews.clear();
                 }
@@ -219,7 +226,6 @@
         pw.print(outerPrefix); pw.print("isContainsView: "); pw.println(isContainsView);
     }
 
-
     /**
      * The method is used by {@link Translator}, it will be called when the translation is done. The
      * translation result can be get from here.
@@ -232,11 +238,95 @@
         }
         final SparseArray<ViewTranslationResponse> translatedResult =
                 response.getViewTranslationResponses();
-        onTranslationCompleted(translatedResult);
+        final SparseArray<ViewTranslationResponse> viewsResult = new SparseArray<>();
+        final SparseArray<LongSparseArray<ViewTranslationResponse>> virtualViewsResult =
+                new SparseArray<>();
+        // TODO: use another structure to prevent autoboxing?
+        final List<Integer> viewIds = new ArrayList<>();
+
+        for (int i = 0; i < translatedResult.size(); i++) {
+            final ViewTranslationResponse result = translatedResult.valueAt(i);
+            final AutofillId autofillId = result.getAutofillId();
+            if (!viewIds.contains(autofillId.getViewId())) {
+                viewIds.add(autofillId.getViewId());
+            }
+            if (autofillId.isNonVirtual()) {
+                viewsResult.put(translatedResult.keyAt(i), result);
+            } else {
+                final boolean isVirtualViewAdded =
+                        virtualViewsResult.indexOfKey(autofillId.getViewId()) >= 0;
+                final LongSparseArray<ViewTranslationResponse> childIds =
+                        isVirtualViewAdded ? virtualViewsResult.get(autofillId.getViewId())
+                                : new LongSparseArray<>();
+                childIds.put(autofillId.getVirtualChildLongId(), result);
+                if (!isVirtualViewAdded) {
+                    virtualViewsResult.put(autofillId.getViewId(), childIds);
+                }
+            }
+        }
+        // Traverse tree and get views by the responsed AutofillId
+        findViewsTraversalByAutofillIds(viewIds);
+
+        if (viewsResult.size() > 0) {
+            onTranslationCompleted(viewsResult);
+        }
+        if (virtualViewsResult.size() > 0) {
+            onVirtualViewTranslationCompleted(virtualViewsResult);
+        }
     }
 
+    /**
+     * The method is used to handle the translation result for the vertual views.
+     */
+    private void onVirtualViewTranslationCompleted(
+            SparseArray<LongSparseArray<ViewTranslationResponse>> translatedResult) {
+        if (!mActivity.isResumed()) {
+            if (DEBUG) {
+                Log.v(TAG, "onTranslationCompleted: Activity is not resumed.");
+            }
+            return;
+        }
+        synchronized (mLock) {
+            if (mCurrentState == STATE_UI_TRANSLATION_FINISHED) {
+                Log.w(TAG, "onTranslationCompleted: the translation state is finished now. "
+                        + "Skip to show the translated text.");
+                return;
+            }
+            for (int i = 0; i < translatedResult.size(); i++) {
+                final AutofillId autofillId = new AutofillId(translatedResult.keyAt(i));
+                final View view = mViews.get(autofillId).get();
+                if (view == null) {
+                    Log.w(TAG, "onTranslationCompleted: the view for autofill id " + autofillId
+                            + " may be gone.");
+                    continue;
+                }
+                final LongSparseArray<ViewTranslationResponse> virtualChildResponse =
+                        translatedResult.valueAt(i);
+                mActivity.runOnUiThread(() -> {
+                    if (view.getViewTranslationCallback() == null) {
+                        if (DEBUG) {
+                            Log.d(TAG, view + " doesn't support showing translation because of "
+                                    + "null ViewTranslationCallback.");
+                        }
+                        return;
+                    }
+                    view.onTranslationResponse(virtualChildResponse);
+                    if (view.getViewTranslationCallback() != null) {
+                        view.getViewTranslationCallback().onShowTranslation(view);
+                    }
+                });
+            }
+        }
+    }
+
+    /**
+     * The method is used to handle the translation result for non-vertual views.
+     */
     private void onTranslationCompleted(SparseArray<ViewTranslationResponse> translatedResult) {
         if (!mActivity.isResumed()) {
+            if (DEBUG) {
+                Log.v(TAG, "onTranslationCompleted: Activity is not resumed.");
+            }
             return;
         }
         final int resultCount = translatedResult.size();
@@ -244,8 +334,13 @@
             Log.v(TAG, "onTranslationCompleted: receive " + resultCount + " responses.");
         }
         synchronized (mLock) {
+            if (mCurrentState == STATE_UI_TRANSLATION_FINISHED) {
+                Log.w(TAG, "onTranslationCompleted: the translation state is finished now. "
+                        + "Skip to show the translated text.");
+                return;
+            }
             for (int i = 0; i < resultCount; i++) {
-                final ViewTranslationResponse response = translatedResult.get(i);
+                final ViewTranslationResponse response = translatedResult.valueAt(i);
                 final AutofillId autofillId = response.getAutofillId();
                 if (autofillId == null) {
                     continue;
@@ -256,18 +351,30 @@
                             + " may be gone.");
                     continue;
                 }
-                mActivity.runOnUiThread(() -> view.onTranslationComplete(response));
+                mActivity.runOnUiThread(() -> {
+                    if (view.getViewTranslationCallback() == null) {
+                        if (DEBUG) {
+                            Log.d(TAG, view + " doesn't support showing translation because of "
+                                    + "null ViewTranslationCallback.");
+                        }
+                        return;
+                    }
+                    view.onTranslationResponse(response);
+                    if (view.getViewTranslationCallback() != null) {
+                        view.getViewTranslationCallback().onShowTranslation(view);
+                    }
+                });
             }
         }
     }
 
     /**
-     * Called when there is an ui translation request comes to request view translation.
+     * Creates a Translator for the given source and target translation specs and start the ui
+     * translation when the Translator is created successfully.
      */
     @WorkerThread
     private void createTranslatorAndStart(TranslationSpec sourceSpec, TranslationSpec destSpec,
             List<AutofillId> views) {
-        // Create Translator
         final Translator translator = createTranslatorIfNeeded(sourceSpec, destSpec);
         if (translator == null) {
             Log.w(TAG, "Can not create Translator for sourceSpec:" + sourceSpec + " destSpec:"
@@ -287,7 +394,7 @@
         final TranslationRequest request = new TranslationRequest.Builder()
                 .setViewTranslationRequests(requests)
                 .build();
-        translator.requestUiTranslate(request, this::onTranslationCompleted);
+        translator.requestUiTranslate(request, (r) -> r.run(), this::onTranslationCompleted);
     }
 
     /**
@@ -295,96 +402,134 @@
      */
     private void onUiTranslationStarted(Translator translator, List<AutofillId> views) {
         synchronized (mLock) {
-            // Find Views collect the translation data
-            final ArrayList<ViewTranslationRequest> requests = new ArrayList<>();
-            final ArrayList<View> foundViews = new ArrayList<>();
-            findViewsTraversalByAutofillIds(views, foundViews);
-            for (int i = 0; i < foundViews.size(); i++) {
-                final View view = foundViews.get(i);
-                final int currentCount = i;
-                mActivity.runOnUiThread(() -> {
-                    final ViewTranslationRequest request = view.onCreateTranslationRequest();
-                    if (request != null
-                            && request.getKeys().size() > 0) {
-                        requests.add(request);
+            // Filter the request views's AutofillId
+            SparseIntArray virtualViewChildCount = getRequestVirtualViewChildCount(views);
+            Map<AutofillId, long[]> viewIds = new ArrayMap<>();
+            for (int i = 0; i < views.size(); i++) {
+                AutofillId autofillId = views.get(i);
+                if (autofillId.isNonVirtual()) {
+                    viewIds.put(autofillId, null);
+                } else {
+                    // The virtual id get from content capture is long, see getVirtualChildLongId()
+                    // e.g. 1001, 1001:2, 1002:1 -> 1001, <1,2>; 1002, <1>
+                    AutofillId virtualViewAutofillId = new AutofillId(autofillId.getViewId());
+                    long[] childs;
+                    if (viewIds.containsKey(virtualViewAutofillId)) {
+                        childs = viewIds.get(virtualViewAutofillId);
+                    } else {
+                        int childCount = virtualViewChildCount.get(autofillId.getViewId());
+                        childs = new long[childCount];
+                        viewIds.put(virtualViewAutofillId, childs);
                     }
-                    if (currentCount == (foundViews.size() - 1)) {
-                        Log.v(TAG, "onUiTranslationStarted: collect " + requests.size()
-                                + " requests.");
-                        mWorkerHandler.sendMessage(PooledLambda.obtainMessage(
-                                UiTranslationController::sendTranslationRequest,
-                                UiTranslationController.this, translator, requests));
-                    }
-                });
+                    int end = childs.length - 1;
+                    childs[end] = autofillId.getVirtualChildLongId();
+                }
             }
+            ArrayList<ViewTranslationRequest> requests = new ArrayList<>();
+            int[] supportedFormats = getSupportedFormatsLocked();
+            ArrayList<ViewRootImpl> roots =
+                    WindowManagerGlobal.getInstance().getRootViews(mActivity.getActivityToken());
+            mActivity.runOnUiThread(() -> {
+                // traverse the hierarchy to collect ViewTranslationRequests
+                for (int rootNum = 0; rootNum < roots.size(); rootNum++) {
+                    View rootView = roots.get(rootNum).getView();
+                    // TODO(b/183589662): call getTranslationCapabilities() for capability
+                    rootView.dispatchRequestTranslation(viewIds, supportedFormats, /* capability */
+                            null, requests);
+                }
+                mWorkerHandler.sendMessage(PooledLambda.obtainMessage(
+                        UiTranslationController::sendTranslationRequest,
+                        UiTranslationController.this, translator, requests));
+            });
         }
     }
 
-    private void findViewsTraversalByAutofillIds(List<AutofillId> sourceViewIds,
-            ArrayList<View> foundViews) {
+    private SparseIntArray getRequestVirtualViewChildCount(List<AutofillId> views) {
+        SparseIntArray virtualViewCount = new SparseIntArray();
+        for (int i = 0; i < views.size(); i++) {
+            AutofillId autofillId = views.get(i);
+            if (!autofillId.isNonVirtual()) {
+                int virtualViewId = autofillId.getViewId();
+                if (virtualViewCount.indexOfKey(virtualViewId) < 0) {
+                    virtualViewCount.put(virtualViewId, 1);
+                } else {
+                    virtualViewCount.put(virtualViewId, (virtualViewCount.get(virtualViewId) + 1));
+                }
+            }
+        }
+        return virtualViewCount;
+    }
+
+    private int[] getSupportedFormatsLocked() {
+        // We only support text now
+        return new int[] {TranslationSpec.DATA_FORMAT_TEXT};
+    }
+
+    private void findViewsTraversalByAutofillIds(List<Integer> sourceViewIds) {
         final ArrayList<ViewRootImpl> roots =
                 WindowManagerGlobal.getInstance().getRootViews(mActivity.getActivityToken());
         for (int rootNum = 0; rootNum < roots.size(); rootNum++) {
             final View rootView = roots.get(rootNum).getView();
             if (rootView instanceof ViewGroup) {
-                findViewsTraversalByAutofillIds((ViewGroup) rootView, sourceViewIds, foundViews);
+                findViewsTraversalByAutofillIds((ViewGroup) rootView, sourceViewIds);
             } else {
-                addViewIfNeeded(sourceViewIds, rootView, foundViews);
+                addViewIfNeeded(sourceViewIds, rootView);
             }
         }
     }
 
     private void findViewsTraversalByAutofillIds(ViewGroup viewGroup,
-            List<AutofillId> sourceViewIds, ArrayList<View> foundViews) {
+            List<Integer> sourceViewIds) {
         final int childCount = viewGroup.getChildCount();
         for (int i = 0; i < childCount; ++i) {
             final View child = viewGroup.getChildAt(i);
             if (child instanceof ViewGroup) {
-                findViewsTraversalByAutofillIds((ViewGroup) child, sourceViewIds, foundViews);
+                findViewsTraversalByAutofillIds((ViewGroup) child, sourceViewIds);
             } else {
-                addViewIfNeeded(sourceViewIds, child, foundViews);
+                addViewIfNeeded(sourceViewIds, child);
             }
         }
     }
 
-    private void addViewIfNeeded(List<AutofillId> sourceViewIds, View view,
-            ArrayList<View> foundViews) {
+    private void addViewIfNeeded(List<Integer> sourceViewIds, View view) {
         final AutofillId autofillId = view.getAutofillId();
-        if (sourceViewIds.contains(autofillId)) {
+        if (sourceViewIds.contains(autofillId.getViewId()) && !mViews.containsKey(autofillId)) {
             mViews.put(autofillId, new WeakReference<>(view));
-            foundViews.add(view);
         }
     }
 
-    private void runForEachView(Consumer<View> action) {
+    private void runForEachView(BiConsumer<View, ViewTranslationCallback> action) {
         synchronized (mLock) {
             final ArrayMap<AutofillId, WeakReference<View>> views = new ArrayMap<>(mViews);
             mActivity.runOnUiThread(() -> {
                 final int viewCounts = views.size();
                 for (int i = 0; i < viewCounts; i++) {
                     final View view = views.valueAt(i).get();
-                    if (view == null) {
+                    if (view == null || view.getViewTranslationCallback() == null) {
                         if (DEBUG) {
-                            Log.d(TAG, "View was gone for autofillid = " + views.keyAt(i));
+                            Log.d(TAG, "View was gone or ViewTranslationCallback for autofillid "
+                                    + "= " + views.keyAt(i));
                         }
                         continue;
                     }
-                    action.accept(view);
+                    action.accept(view, view.getViewTranslationCallback());
                 }
             });
         }
     }
 
     private Translator createTranslatorIfNeeded(
-            TranslationSpec sourceSpec, TranslationSpec destSpec) {
+            TranslationSpec sourceSpec, TranslationSpec targetSpec) {
         final TranslationManager tm = mContext.getSystemService(TranslationManager.class);
         if (tm == null) {
             Log.e(TAG, "Can not find TranslationManager when trying to create translator.");
             return null;
         }
-        final Translator translator = tm.createTranslator(sourceSpec, destSpec);
+        final TranslationContext translationContext = new TranslationContext(sourceSpec,
+                targetSpec, /* translationFlags= */ 0);
+        final Translator translator = tm.createTranslator(translationContext);
         if (translator != null) {
-            final Pair<TranslationSpec, TranslationSpec> specs = new Pair<>(sourceSpec, destSpec);
+            final Pair<TranslationSpec, TranslationSpec> specs = new Pair<>(sourceSpec, targetSpec);
             mTranslators.put(specs, translator);
         }
         return translator;
diff --git a/core/java/android/view/translation/UiTranslationManager.java b/core/java/android/view/translation/UiTranslationManager.java
index 852ffe8..62868ac 100644
--- a/core/java/android/view/translation/UiTranslationManager.java
+++ b/core/java/android/view/translation/UiTranslationManager.java
@@ -127,10 +127,13 @@
      * @param destSpec {@link TranslationSpec} for the translated data.
      * @param viewIds A list of the {@link View}'s {@link AutofillId} which needs to be translated
      * @param taskId the Activity Task id which needs ui translation
+     * @deprecated Use {@code startTranslation(TranslationSpec, TranslationSpec, List<AutofillId>,
+     * ActivityId)} instead.
      *
      * @hide
+     * @removed
      */
-    // TODO, hide the APIs
+    @Deprecated
     @RequiresPermission(android.Manifest.permission.MANAGE_UI_TRANSLATION)
     @SystemApi
     public void startTranslation(@NonNull TranslationSpec sourceSpec,
@@ -193,10 +196,13 @@
      * NOTE: Please use {@code finishTranslation(ActivityId)} instead.
      *
      * @param taskId the Activity Task id which needs ui translation
+     * @deprecated Use {@code finishTranslation(ActivityId)} instead.
      *
      * @hide
+     * @removed
+     *
      */
-    // TODO, hide the APIs
+    @Deprecated
     @RequiresPermission(android.Manifest.permission.MANAGE_UI_TRANSLATION)
     @SystemApi
     public void finishTranslation(int taskId) {
@@ -240,10 +246,12 @@
      * NOTE: Please use {@code pauseTranslation(ActivityId)} instead.
      *
      * @param taskId the Activity Task id which needs ui translation
+     * @deprecated Use {@code pauseTranslation(ActivityId)} instead.
      *
      * @hide
+     * @removed
      */
-    // TODO, hide the APIs
+    @Deprecated
     @RequiresPermission(android.Manifest.permission.MANAGE_UI_TRANSLATION)
     @SystemApi
     public void pauseTranslation(int taskId) {
@@ -287,10 +295,12 @@
      * NOTE: Please use {@code resumeTranslation(ActivityId)} instead.
      *
      * @param taskId the Activity Task id which needs ui translation
+     * @deprecated Use {@code resumeTranslation(ActivityId)} instead.
      *
      * @hide
+     * @removed
      */
-    // TODO, hide the APIs
+    @Deprecated
     @RequiresPermission(android.Manifest.permission.MANAGE_UI_TRANSLATION)
     @SystemApi
     public void resumeTranslation(int taskId) {
diff --git a/core/java/android/view/translation/ViewTranslationCallback.java b/core/java/android/view/translation/ViewTranslationCallback.java
new file mode 100644
index 0000000..c895984
--- /dev/null
+++ b/core/java/android/view/translation/ViewTranslationCallback.java
@@ -0,0 +1,51 @@
+/*
+ * 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 android.view.translation;
+
+import android.annotation.NonNull;
+import android.annotation.UiThread;
+import android.view.View;
+
+/**
+ * Callback for handling the translated information show or hide in the {@link View}. See {@link
+ * View#onTranslationResponse} for how to get the translated information.
+ */
+@UiThread
+public interface ViewTranslationCallback {
+    /**
+     * Called when the translated text is ready to show or if the user has requested to reshow the
+     * translated content after hiding it. This may be called before the translation results are
+     * returned through the {@link View#onTranslationResponse}.
+     *
+     * @return {@code true} if the View handles showing the translation.
+     */
+    boolean onShowTranslation(@NonNull View view);
+    /**
+     * Called when the user wants to show the original text instead of the translated text. This
+     * may be called before the translation results are returned through the
+     * {@link View#onTranslationResponse}.
+     *
+     * @return {@code true} if the View handles hiding the translation.
+     */
+    boolean onHideTranslation(@NonNull View view);
+    /**
+     * Called when the user finish the Ui translation and no longer to show the translated text.
+     *
+     * @return {@code true} if the View handles clearing the translation.
+     */
+    boolean onClearTranslation(@NonNull View view);
+}
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 487d13e..6d4fa65 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -45,6 +45,7 @@
 import android.print.PrintDocumentAdapter;
 import android.util.AttributeSet;
 import android.util.Log;
+import android.util.LongSparseArray;
 import android.util.SparseArray;
 import android.view.DragEvent;
 import android.view.KeyEvent;
@@ -64,6 +65,9 @@
 import android.view.inputmethod.InputConnection;
 import android.view.inspector.InspectableProperty;
 import android.view.textclassifier.TextClassifier;
+import android.view.translation.TranslationSpec.DataFormat;
+import android.view.translation.ViewTranslationRequest;
+import android.view.translation.ViewTranslationResponse;
 import android.widget.AbsoluteLayout;
 
 import java.io.BufferedWriter;
@@ -73,6 +77,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.Executor;
+import java.util.function.Consumer;
 
 /**
  * A View that displays web pages.
@@ -2854,6 +2859,20 @@
         return mProvider.getViewDelegate().isVisibleToUserForAutofill(virtualId);
     }
 
+    @Override
+    @Nullable
+    public void onCreateTranslationRequests(@NonNull long[] virtualChildIds,
+            @NonNull @DataFormat int[] supportedFormats,
+            @NonNull Consumer<ViewTranslationRequest> requestsCollector) {
+        mProvider.getViewDelegate().onCreateTranslationRequests(virtualChildIds, supportedFormats,
+                requestsCollector);
+    }
+
+    @Override
+    public void onTranslationResponse(@NonNull LongSparseArray<ViewTranslationResponse> response) {
+        mProvider.getViewDelegate().onTranslationResponse(response);
+    }
+
     /** @hide */
     @Override
     public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
diff --git a/core/java/android/webkit/WebViewProvider.java b/core/java/android/webkit/WebViewProvider.java
index 18a110b..2647360 100644
--- a/core/java/android/webkit/WebViewProvider.java
+++ b/core/java/android/webkit/WebViewProvider.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.SuppressLint;
 import android.annotation.SystemApi;
 import android.content.Intent;
 import android.content.res.Configuration;
@@ -33,6 +34,7 @@
 import android.os.Handler;
 import android.os.Message;
 import android.print.PrintDocumentAdapter;
+import android.util.LongSparseArray;
 import android.util.SparseArray;
 import android.view.DragEvent;
 import android.view.KeyEvent;
@@ -47,6 +49,9 @@
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputConnection;
 import android.view.textclassifier.TextClassifier;
+import android.view.translation.TranslationSpec.DataFormat;
+import android.view.translation.ViewTranslationRequest;
+import android.view.translation.ViewTranslationResponse;
 import android.webkit.WebView.HitTestResult;
 import android.webkit.WebView.PictureListener;
 import android.webkit.WebView.VisualStateCallback;
@@ -56,6 +61,7 @@
 import java.io.File;
 import java.util.Map;
 import java.util.concurrent.Executor;
+import java.util.function.Consumer;
 
 /**
  * WebView backend provider interface: this interface is the abstract backend to a WebView
@@ -358,6 +364,20 @@
                 @SuppressWarnings("unused") int flags) {
         }
 
+        @SuppressLint("NullableCollection")
+        @Nullable
+        default void onCreateTranslationRequests(
+                @NonNull @SuppressWarnings("unused") long[] virtualChildIds,
+                @NonNull @SuppressWarnings("unused") @DataFormat int[] supportedFormats,
+                @NonNull @SuppressWarnings("unused")
+                        Consumer<ViewTranslationRequest> requestsCollector) {
+        }
+
+        default void onTranslationResponse(
+                @NonNull @SuppressWarnings("unused")
+                        LongSparseArray<ViewTranslationResponse> response) {
+        }
+
         public AccessibilityNodeProvider getAccessibilityNodeProvider();
 
         public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info);
diff --git a/core/java/android/widget/EdgeEffect.java b/core/java/android/widget/EdgeEffect.java
index 5f55887..1951194 100644
--- a/core/java/android/widget/EdgeEffect.java
+++ b/core/java/android/widget/EdgeEffect.java
@@ -117,12 +117,12 @@
     /**
      * The natural frequency of the stretch spring.
      */
-    private static final double NATURAL_FREQUENCY = 14.4222;
+    private static final double NATURAL_FREQUENCY = 17.55;
 
     /**
      * The damping ratio of the stretch spring.
      */
-    private static final double DAMPING_RATIO = 0.875;
+    private static final double DAMPING_RATIO = 0.92;
 
     /** @hide */
     @IntDef({TYPE_GLOW, TYPE_STRETCH})
@@ -130,11 +130,11 @@
     public @interface EdgeEffectType {
     }
 
-    private static final float LINEAR_STRETCH_INTENSITY = 0.03f;
+    private static final float LINEAR_STRETCH_INTENSITY = 0.06f;
 
-    private static final float EXP_STRETCH_INTENSITY = 0.02f;
+    private static final float EXP_STRETCH_INTENSITY = 0.06f;
 
-    private static final float SCROLL_DIST_AFFECTED_BY_EXP_STRETCH = 0.4f;
+    private static final float SCROLL_DIST_AFFECTED_BY_EXP_STRETCH = 0.33f;
 
     @SuppressWarnings("UnusedDeclaration")
     private static final String TAG = "EdgeEffect";
@@ -640,6 +640,12 @@
                     mWidth,
                     mHeight
             );
+        } else {
+            // This is TYPE_STRETCH and drawing into a Canvas that isn't a Recording Canvas,
+            // so no effect can be shown. Just end the effect.
+            mState = STATE_IDLE;
+            mDistance = 0;
+            mVelocity = 0;
         }
 
         boolean oneLastFrame = false;
@@ -771,8 +777,9 @@
      * considered at rest or false if it is still animating.
      */
     private boolean isAtEquilibrium() {
-        double displacement = mDistance * mHeight; // in pixels
-        return Math.abs(mVelocity) < VELOCITY_THRESHOLD
+        double displacement = mDistance * mHeight * LINEAR_STRETCH_INTENSITY; // in pixels
+        double velocity = mVelocity * LINEAR_STRETCH_INTENSITY;
+        return Math.abs(velocity) < VELOCITY_THRESHOLD
                 && Math.abs(displacement) < VALUE_THRESHOLD;
     }
 
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 238ce85..48e25c51 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -2894,8 +2894,8 @@
             final int originalLength = mTextView.getText().length();
             Selection.setSelection((Spannable) mTextView.getText(), offset);
             final ClipData clip = event.getClipData();
-            final ContentInfo payload =
-                    new ContentInfo.Builder(clip, SOURCE_DRAG_AND_DROP)
+            final ContentInfo payload = new ContentInfo.Builder(clip, SOURCE_DRAG_AND_DROP)
+                    .setDragAndDropPermissions(permissions)
                     .build();
             mTextView.performReceiveContent(payload);
             if (dragDropIntoItself) {
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 319e788..29c78b5 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -5476,14 +5476,14 @@
     /**
      * Object allowing the modification of a context to overload the system's dynamic colors.
      *
-     * Only colors from {@link android.R.color#system_primary_0} to
-     * {@link android.R.color#system_neutral_1000} can be overloaded.
+     * Only colors from {@link android.R.color#system_accent1_0} to
+     * {@link android.R.color#system_neutral2_1000} can be overloaded.
      * @hide
      */
     public static final class ColorResources {
         // Set of valid colors resources.
-        private static final int FIRST_RESOURCE_COLOR_ID = android.R.color.system_primary_0;
-        private static final int LAST_RESOURCE_COLOR_ID = android.R.color.system_neutral_1000;
+        private static final int FIRST_RESOURCE_COLOR_ID = android.R.color.system_neutral1_0;
+        private static final int LAST_RESOURCE_COLOR_ID = android.R.color.system_accent3_1000;
         // Size, in bytes, of an entry in the array of colors in an ARSC file.
         private static final int ARSC_ENTRY_SIZE = 16;
 
@@ -6342,6 +6342,9 @@
     /**
      * Set the ID of the top-level view of the XML layout.
      *
+     * The view's ID is changed right after inflation, before it gets added to its parent. The ID
+     * of a given view can never change after the initial inflation.
+     *
      * Set to {@link View#NO_ID} to reset and simply keep the id defined in the XML layout.
      *
      * @throws UnsupportedOperationException if the method is called on a RemoteViews defined in
diff --git a/core/java/android/widget/SpellChecker.java b/core/java/android/widget/SpellChecker.java
index a63305e..287c182 100644
--- a/core/java/android/widget/SpellChecker.java
+++ b/core/java/android/widget/SpellChecker.java
@@ -20,12 +20,10 @@
 import android.text.Editable;
 import android.text.Selection;
 import android.text.Spanned;
-import android.text.TextUtils;
 import android.text.method.WordIterator;
 import android.text.style.SpellCheckSpan;
 import android.text.style.SuggestionSpan;
 import android.util.Log;
-import android.util.LruCache;
 import android.util.Range;
 import android.view.textservice.SentenceSuggestionsInfo;
 import android.view.textservice.SpellCheckerSession;
@@ -98,10 +96,6 @@
 
     private Runnable mSpellRunnable;
 
-    private static final int SUGGESTION_SPAN_CACHE_SIZE = 10;
-    private final LruCache<Long, SuggestionSpan> mSuggestionSpanCache =
-            new LruCache<Long, SuggestionSpan>(SUGGESTION_SPAN_CACHE_SIZE);
-
     public SpellChecker(TextView textView) {
         mTextView = textView;
 
@@ -144,7 +138,6 @@
 
         // Remove existing misspelled SuggestionSpans
         mTextView.removeMisspelledSpans((Editable) mTextView.getText());
-        mSuggestionSpanCache.evictAll();
     }
 
     private void setLocale(Locale locale) {
@@ -410,16 +403,7 @@
                     }
                     if (spellCheckSpanStart >= 0 && spellCheckSpanEnd > spellCheckSpanStart
                             && end > start) {
-                        final Long key = Long.valueOf(TextUtils.packRangeInLong(start, end));
-                        final SuggestionSpan tempSuggestionSpan = mSuggestionSpanCache.get(key);
-                        if (tempSuggestionSpan != null) {
-                            if (DBG) {
-                                Log.i(TAG, "Remove existing misspelled span. "
-                                        + editable.subSequence(start, end));
-                            }
-                            editable.removeSpan(tempSuggestionSpan);
-                            mSuggestionSpanCache.remove(key);
-                        }
+                        removeErrorSuggestionSpan(editable, start, end, RemoveReason.OBSOLETE);
                     }
                 }
                 return spellCheckSpan;
@@ -428,6 +412,35 @@
         return null;
     }
 
+    private enum RemoveReason {
+        /**
+         * Indicates the previous SuggestionSpan is replaced by a new SuggestionSpan.
+         */
+        REPLACE,
+        /**
+         * Indicates the previous SuggestionSpan is removed because corresponding text is
+         * considered as valid words now.
+         */
+        OBSOLETE,
+    }
+
+    private static void removeErrorSuggestionSpan(
+            Editable editable, int start, int end, RemoveReason reason) {
+        SuggestionSpan[] spans = editable.getSpans(start, end, SuggestionSpan.class);
+        for (SuggestionSpan span : spans) {
+            if (editable.getSpanStart(span) == start
+                    && editable.getSpanEnd(span) == end
+                    && (span.getFlags() & (SuggestionSpan.FLAG_MISSPELLED
+                    | SuggestionSpan.FLAG_GRAMMAR_ERROR)) != 0) {
+                if (DBG) {
+                    Log.i(TAG, "Remove existing misspelled/grammar error span on "
+                            + editable.subSequence(start, end) + ", reason: " + reason);
+                }
+                editable.removeSpan(span);
+            }
+        }
+    }
+
     @Override
     public void onGetSuggestions(SuggestionsInfo[] results) {
         final Editable editable = (Editable) mTextView.getText();
@@ -543,16 +556,7 @@
         }
         SuggestionSpan suggestionSpan =
                 new SuggestionSpan(mTextView.getContext(), suggestions, flags);
-        final Long key = Long.valueOf(TextUtils.packRangeInLong(start, end));
-        final SuggestionSpan tempSuggestionSpan = mSuggestionSpanCache.get(key);
-        if (tempSuggestionSpan != null) {
-            if (DBG) {
-                Log.i(TAG, "Cached span on the same position is cleard. "
-                        + editable.subSequence(start, end));
-            }
-            editable.removeSpan(tempSuggestionSpan);
-        }
-        mSuggestionSpanCache.put(key, suggestionSpan);
+        removeErrorSuggestionSpan(editable, start, end, RemoveReason.REPLACE);
         editable.setSpan(suggestionSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
 
         mTextView.invalidateRegion(start, end, false /* No cursor involved */);
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 940a3c9..ffaa315 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -195,7 +195,9 @@
 import android.view.textservice.SpellCheckerSubtype;
 import android.view.textservice.TextServicesManager;
 import android.view.translation.TranslationRequestValue;
+import android.view.translation.TranslationSpec;
 import android.view.translation.UiTranslationController;
+import android.view.translation.ViewTranslationCallback;
 import android.view.translation.ViewTranslationRequest;
 import android.view.translation.ViewTranslationResponse;
 import android.widget.RemoteViews.RemoteView;
@@ -203,6 +205,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.FastMath;
 import com.android.internal.util.Preconditions;
 import com.android.internal.widget.EditableInputConnection;
@@ -737,7 +740,7 @@
     private MovementMethod mMovement;
 
     private TransformationMethod mTransformation;
-    private TranslationTransformationMethod mTranslationTransformation;
+    private TextViewTranslationCallback mDefaultTranslationCallback;
     @UnsupportedAppUsage
     private boolean mAllowTransformationLengthChange;
     @UnsupportedAppUsage
@@ -13857,136 +13860,104 @@
     }
 
     /**
-     * Provides a {@link ViewTranslationRequest} that represents the content to be translated via
-     * translation service.
+     * Returns a {@link ViewTranslationRequest} which represents the content to be translated.
      *
-     * <p>NOTE: When overriding the method, it should not translate the password. We also suggest
-     * that not translating the text is selectable or editable. We use the transformation method to
-     * implement showing the translated text. The TextView does not support the transformation
-     * method text length change. If the text is selectable or editable, it will crash while
-     * selecting the text. To support it, it needs broader changes to text APIs, we only allow to
-     * translate non selectable and editable text now.
+     * <p>NOTE: When overriding the method, it should not translate the password. If the subclass
+     * uses {@link TransformationMethod} to display the translated result, it's also not recommend
+     * to translate text is selectable or editable.
      *
-     * @hide
+     * @param supportedFormats the supported translation format. The value could be {@link
+     *                         android.view.translation.TranslationSpec#DATA_FORMAT_TEXT}.
+     * @return the {@link ViewTranslationRequest} which contains the information to be translated.
      */
     @Nullable
     @Override
-    public ViewTranslationRequest onCreateTranslationRequest() {
-        if (mText == null || mText.length() == 0) {
+    public ViewTranslationRequest onCreateTranslationRequest(@NonNull int[] supportedFormats) {
+        if (supportedFormats == null || supportedFormats.length == 0) {
             // TODO(b/182433547): remove before S release
             if (UiTranslationController.DEBUG) {
-                Log.w(LOG_TAG, "Cannot create translation request for the empty text.");
+                Log.w(LOG_TAG, "Do not provide the support translation formats.");
             }
             return null;
         }
-        // Not translate password, editable text and not important for translation
-        // TODO(b/177214256): support selectable text translation. It needs to broader changes to
-        //  text selection apis, not support in S.
-        boolean isPassword = isAnyPasswordInputType() || hasPasswordTransformationMethod();
-        if (isTextEditable() || isPassword || isTextSelectable()) {
-            // TODO(b/182433547): remove before S release
-            if (UiTranslationController.DEBUG) {
-                Log.w(LOG_TAG, "Cannot create translation request. editable = " + isTextEditable()
-                        + ", isPassword = " + isPassword + ", selectable = " + isTextSelectable());
+        ViewTranslationRequest.Builder requestBuilder =
+                new ViewTranslationRequest.Builder(getAutofillId());
+        // Support Text translation
+        if (ArrayUtils.contains(supportedFormats, TranslationSpec.DATA_FORMAT_TEXT)) {
+            if (mText == null || mText.length() == 0) {
+                // TODO(b/182433547): remove before S release
+                if (UiTranslationController.DEBUG) {
+                    Log.w(LOG_TAG, "Cannot create translation request for the empty text.");
+                }
+                return null;
             }
-            return null;
+            boolean isPassword = isAnyPasswordInputType() || hasPasswordTransformationMethod();
+            // TODO(b/177214256): support selectable text translation.
+            //  We use the TransformationMethod to implement showing the translated text. The
+            //  TextView does not support the text length change for TransformationMethod. If the
+            //  text is selectable or editable, it will crash while selecting the text. To support
+            //  it, it needs broader changes to text APIs, we only allow to translate non selectable
+            //  and editable text in S.
+            if (isTextEditable() || isPassword || isTextSelectable()) {
+                // TODO(b/182433547): remove before S release
+                if (UiTranslationController.DEBUG) {
+                    Log.w(LOG_TAG, "Cannot create translation request. editable = "
+                            + isTextEditable() + ", isPassword = " + isPassword + ", selectable = "
+                            + isTextSelectable());
+                }
+                return null;
+            }
+            // TODO(b/176488462): apply the view's important for translation
+            requestBuilder.setValue(ViewTranslationRequest.ID_TEXT,
+                    TranslationRequestValue.forText(mText));
         }
-        // TODO(b/176488462): apply the view's important for translation property
-        // TODO(b/174283799): remove the spans from the mText and save the spans information
-        // TODO: use fixed ids for request texts.
-        ViewTranslationRequest request =
-                new ViewTranslationRequest.Builder(getAutofillId())
-                        .setValue(ViewTranslationRequest.ID_TEXT,
-                                TranslationRequestValue.forText(mText))
-                        .build();
-        return request;
+        return requestBuilder.build();
     }
 
     /**
-     * Provides the implementation that pauses the ongoing Ui translation, it will show the original
-     * text instead of the translated text and restore the original transformation method.
+     * Returns a {@link ViewTranslationCallback} that is used to display the translated information.
+     * The default implementation will use a {@link TransformationMethod} that allow to replace the
+     * current {@link TransformationMethod} to transform the original text to the translated text
+     * display.
      *
-     * <p>NOTE: If this method is overridden, other translation related methods such as
-     * {@link onRestoreUiTranslation}, {@link onFinishUiTranslation}, {@link onTranslationComplete}
-     * should also be overridden.
-     *
-     * @hide
+     * @return a {@link ViewTranslationCallback} that is used to control how to display the
+     * translated information or {@code null} if this View doesn't support translation.
      */
+    @Nullable
     @Override
-    public void onPauseUiTranslation() {
-        // Restore to original text content.
-        if (mTranslationTransformation != null) {
-            setTransformationMethod(mTranslationTransformation.getOriginalTransformationMethod());
-        } else {
-            // TODO(b/182433547): remove before S release
-            Log.w(LOG_TAG, "onPauseUiTranslation(): no translated text.");
+    public ViewTranslationCallback getViewTranslationCallback() {
+        return getDefaultViewTranslationCallback();
+    }
+
+    private ViewTranslationCallback getDefaultViewTranslationCallback() {
+        if (mDefaultTranslationCallback == null) {
+            mDefaultTranslationCallback = new TextViewTranslationCallback();
         }
+        return mDefaultTranslationCallback;
     }
 
     /**
-     * Provides the implementation that restoes the paused Ui translation, it will show the
-     * translated text again if the text had been translated. This method will replace the current
-     * tansformation method with {@link TranslationTransformationMethod}.
      *
-     * <p>NOTE: If this method is overridden, other translation related methods such as
-     * {@link onPauseUiTranslation}, {@link onFinishUiTranslation}, {@link onTranslationComplete}
-     * should also be overridden.
+     * Called when the content from {@link #onCreateTranslationRequest} had been translated by the
+     * TranslationService. The default implementation will replace the current
+     * {@link TransformationMethod} to transform the original text to the translated text display.
      *
-     * @hide
+     * @param response a {@link ViewTranslationResponse} that contains the translated information
+     * which can be shown in the view.
      */
     @Override
-    public void onRestoreUiTranslation() {
-        if (mTranslationTransformation != null) {
-            setTransformationMethod(mTranslationTransformation);
-        } else {
-            // TODO(b/182433547): remove before S release
-            Log.w(LOG_TAG, "onRestoreUiTranslation(): no translated text.");
-        }
-    }
-
-    /**
-     * Provides the implementation that finishes the current Ui translation and it's no longer to
-     * show the translated text. This method restores the original transformation method and resets
-     * the saved {@link TranslationTransformationMethod}.
-     *
-     * <p>NOTE: If this method is overridden, other translation related methods such as
-     * {@link onPauseUiTranslation}, {@link onRestoreUiTranslation}, {@link onTranslationComplete}
-     * should also be overridden.
-     *
-     * @hide
-     */
-    @Override
-    public void onFinishUiTranslation() {
-        // Restore to original text content and clear TranslationTransformation
-        if (mTranslationTransformation != null) {
-            setTransformationMethod(mTranslationTransformation.getOriginalTransformationMethod());
-            mTranslationTransformation = null;
-        } else {
-            // TODO(b/182433547): remove before S release
-            Log.w(LOG_TAG, "onFinishUiTranslation(): no translated text.");
-        }
-    }
-
-    /**
-     * Default {@link TextView} implementation after the translation request is done by the
-     * translation service, it's ok to show the translated text. This method will save the original
-     * transformation method and replace the current transformation method with
-     * {@link TranslationTransformationMethod}.
-     *
-     * <p>NOTE: If this method is overridden, other translation related methods such as
-     * {@link onPauseUiTranslation}, {@link onRestoreUiTranslation}, {@link onFinishUiTranslation}
-     * should also be overridden.
-     *
-     * @hide
-     */
-    @Override
-    public void onTranslationComplete(@NonNull ViewTranslationResponse response) {
-        // Show the translated text.
-        TransformationMethod originalTranslationMethod = mTranslationTransformation != null
-                ? mTranslationTransformation.getOriginalTransformationMethod() : mTransformation;
-        mTranslationTransformation =
+    public void onTranslationResponse(@NonNull ViewTranslationResponse response) {
+        // TODO(b/183467275): Use the overridden ViewTranslationCallback instead of our default
+        //  implementation if the view has overridden getViewTranslationCallback.
+        TextViewTranslationCallback callback =
+                (TextViewTranslationCallback) getDefaultViewTranslationCallback();
+        TranslationTransformationMethod oldTranslationMethod =
+                callback.getTranslationTransformation();
+        TransformationMethod originalTranslationMethod = oldTranslationMethod != null
+                ? oldTranslationMethod.getOriginalTransformationMethod() : mTransformation;
+        TranslationTransformationMethod newTranslationMethod =
                 new TranslationTransformationMethod(response, originalTranslationMethod);
         // TODO(b/178353965): well-handle setTransformationMethod.
-        setTransformationMethod(mTranslationTransformation);
+        callback.setTranslationTransformation(newTranslationMethod);
     }
 }
diff --git a/core/java/android/widget/TextViewTranslationCallback.java b/core/java/android/widget/TextViewTranslationCallback.java
new file mode 100644
index 0000000..296d93c
--- /dev/null
+++ b/core/java/android/widget/TextViewTranslationCallback.java
@@ -0,0 +1,120 @@
+/*
+ * 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 android.widget;
+
+import android.annotation.NonNull;
+import android.text.method.TranslationTransformationMethod;
+import android.util.Log;
+import android.view.View;
+import android.view.translation.UiTranslationManager;
+import android.view.translation.ViewTranslationCallback;
+import android.view.translation.ViewTranslationResponse;
+
+/**
+ * Default implementation for {@link ViewTranslationCallback} for {@link TextView} components.
+ * This class handles how to display the translated information for {@link TextView}.
+ *
+ * @hide
+ */
+public class TextViewTranslationCallback implements ViewTranslationCallback {
+
+    private static final String TAG = "TextViewTranslationCallback";
+
+    private static final boolean DEBUG = Log.isLoggable(UiTranslationManager.LOG_TAG, Log.DEBUG);
+
+    private TranslationTransformationMethod mTranslationTransformation;
+
+    /**
+     * Invoked by the platform when receiving the successful {@link ViewTranslationResponse} for the
+     * view that provides the translatable information by {@link View#createTranslationRequest} and
+     * sent by the platform.
+     */
+    void setTranslationTransformation(TranslationTransformationMethod method) {
+        if (method == null) {
+            if (DEBUG) {
+                Log.w(TAG, "setTranslationTransformation: should not set null "
+                        + "TranslationTransformationMethod");
+            }
+            return;
+        }
+        mTranslationTransformation = method;
+    }
+
+    TranslationTransformationMethod getTranslationTransformation() {
+        return mTranslationTransformation;
+    }
+
+    private void clearTranslationTransformation() {
+        if (DEBUG) {
+            Log.v(TAG, "clearTranslationTransformation: " + mTranslationTransformation);
+        }
+        mTranslationTransformation = null;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean onShowTranslation(@NonNull View view) {
+        if (mTranslationTransformation != null) {
+            ((TextView) view).setTransformationMethod(mTranslationTransformation);
+        } else {
+            if (DEBUG) {
+                // TODO(b/182433547): remove before S release
+                Log.w(TAG, "onShowTranslation(): no translated text.");
+            }
+        }
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean onHideTranslation(@NonNull View view) {
+        // Restore to original text content.
+        if (mTranslationTransformation != null) {
+            ((TextView) view).setTransformationMethod(
+                    mTranslationTransformation.getOriginalTransformationMethod());
+        } else {
+            if (DEBUG) {
+                // TODO(b/182433547): remove before S release
+                Log.w(TAG, "onHideTranslation(): no translated text.");
+            }
+        }
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean onClearTranslation(@NonNull View view) {
+        // Restore to original text content and clear TranslationTransformation
+        if (mTranslationTransformation != null) {
+            ((TextView) view).setTransformationMethod(
+                    mTranslationTransformation.getOriginalTransformationMethod());
+            clearTranslationTransformation();
+        } else {
+            if (DEBUG) {
+                // TODO(b/182433547): remove before S release
+                Log.w(TAG, "onClearTranslation(): no translated text.");
+            }
+        }
+        return true;
+    }
+}
diff --git a/core/java/android/window/SplashScreenView.java b/core/java/android/window/SplashScreenView.java
index 3709aa1..9789d70 100644
--- a/core/java/android/window/SplashScreenView.java
+++ b/core/java/android/window/SplashScreenView.java
@@ -15,6 +15,7 @@
  */
 package android.window;
 
+import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
 import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
 
 import android.annotation.ColorInt;
@@ -32,6 +33,7 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.SystemClock;
+import android.os.Trace;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.view.LayoutInflater;
@@ -183,6 +185,7 @@
          * Create SplashScreenWindowView object from materials.
          */
         public SplashScreenView build() {
+            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "SplashScreenView#build");
             final LayoutInflater layoutInflater = LayoutInflater.from(mContext);
             final SplashScreenView view = (SplashScreenView)
                     layoutInflater.inflate(R.layout.splash_screen_view, null, false);
@@ -208,14 +211,14 @@
                 view.mParceledIconBitmap = mParceledIconBitmap;
             }
             // branding image
-            if (mBrandingImageHeight > 0 && mBrandingImageWidth > 0) {
+            if (mBrandingImageHeight > 0 && mBrandingImageWidth > 0 && mBrandingDrawable != null) {
                 final ViewGroup.LayoutParams params = view.mBrandingImageView.getLayoutParams();
                 params.width = mBrandingImageWidth;
                 params.height = mBrandingImageHeight;
                 view.mBrandingImageView.setLayoutParams(params);
-            }
-            if (mBrandingDrawable != null) {
                 view.mBrandingImageView.setBackground(mBrandingDrawable);
+            } else {
+                view.mBrandingImageView.setVisibility(GONE);
             }
             if (mParceledBrandingBitmap != null) {
                 view.mParceledBrandingBitmap = mParceledBrandingBitmap;
@@ -226,6 +229,7 @@
                         + view.mBrandingImageView + " drawable: " + mBrandingDrawable
                         + " size w: " + mBrandingImageWidth + " h: " + mBrandingImageHeight);
             }
+            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
             return view;
         }
     }
diff --git a/core/java/android/window/WindowContext.java b/core/java/android/window/WindowContext.java
new file mode 100644
index 0000000..375f4cf
--- /dev/null
+++ b/core/java/android/window/WindowContext.java
@@ -0,0 +1,125 @@
+/*
+ * 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 android.window;
+
+import static android.view.WindowManagerImpl.createWindowContextWindowManager;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.UiContext;
+import android.content.ComponentCallbacks;
+import android.content.ComponentCallbacksController;
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.content.res.Configuration;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.view.WindowManager;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.lang.ref.Reference;
+
+/**
+ * {@link WindowContext} is a context for non-activity windows such as
+ * {@link android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY} windows or system
+ * windows. Its resources and configuration are adjusted to the area of the display that will be
+ * used when a new window is added via {@link android.view.WindowManager#addView}.
+ *
+ * @see Context#createWindowContext(int, Bundle)
+ * @hide
+ */
+@UiContext
+public class WindowContext extends ContextWrapper {
+    private final WindowManager mWindowManager;
+    private final @WindowManager.LayoutParams.WindowType int mType;
+    private final @Nullable Bundle mOptions;
+    private final ComponentCallbacksController mCallbacksController =
+            new ComponentCallbacksController();
+    private final WindowContextController mController;
+
+    /**
+     * Default constructor. Will generate a {@link WindowTokenClient} and attach this context to
+     * the token.
+     *
+     * @param base Base {@link Context} for this new instance.
+     * @param type Window type to be used with this context.
+     * @hide
+     */
+    public WindowContext(@NonNull Context base, int type, @Nullable Bundle options) {
+        super(base);
+
+        mType = type;
+        mOptions = options;
+        mWindowManager = createWindowContextWindowManager(this);
+        IBinder token = getWindowContextToken();
+        mController = new WindowContextController(token);
+
+        Reference.reachabilityFence(this);
+    }
+
+    /**
+     * Registers this {@link WindowContext} with {@link com.android.server.wm.WindowManagerService}
+     * to receive configuration changes of the associated {@link WindowManager} node.
+     */
+    public void registerWithServer() {
+        mController.registerListener(mType, getDisplayId(), mOptions);
+    }
+
+    @Override
+    public Object getSystemService(String name) {
+        if (WINDOW_SERVICE.equals(name)) {
+            return mWindowManager;
+        }
+        return super.getSystemService(name);
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        release();
+        super.finalize();
+    }
+
+    /** Used for test to invoke because we can't invoke finalize directly. */
+    @VisibleForTesting
+    public void release() {
+        mController.unregisterListenerIfNeeded();
+        destroy();
+    }
+
+    @Override
+    public void destroy() {
+        mCallbacksController.clearCallbacks();
+        // Called to the base ContextImpl to do final clean-up.
+        getBaseContext().destroy();
+        Reference.reachabilityFence(this);
+    }
+
+    @Override
+    public void registerComponentCallbacks(@NonNull ComponentCallbacks callback) {
+        mCallbacksController.registerCallbacks(callback);
+    }
+
+    @Override
+    public void unregisterComponentCallbacks(@NonNull ComponentCallbacks callback) {
+        mCallbacksController.unregisterCallbacks(callback);
+    }
+
+    /** Dispatch {@link Configuration} to each {@link ComponentCallbacks}. */
+    void dispatchConfigurationChanged(@NonNull Configuration newConfig) {
+        mCallbacksController.dispatchConfigurationChanged(newConfig);
+    }
+}
diff --git a/core/java/android/window/WindowContextController.java b/core/java/android/window/WindowContextController.java
new file mode 100644
index 0000000..6143414
--- /dev/null
+++ b/core/java/android/window/WindowContextController.java
@@ -0,0 +1,96 @@
+/*
+ * 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 android.window;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.view.IWindowManager;
+import android.view.WindowManager.LayoutParams.WindowType;
+import android.view.WindowManagerGlobal;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+/**
+ * The controller to manage {@link WindowContext} listener, such as registering and unregistering
+ * the listener.
+ *
+ * @hide
+ */
+public class WindowContextController {
+    private final IWindowManager mWms;
+    @VisibleForTesting
+    public boolean mListenerRegistered;
+    @NonNull
+    private final IBinder mToken;
+
+    /**
+     * Window Context Controller constructor
+     *
+     * @param token The token to register to the window context listener. It is usually from
+     *              {@link Context#getWindowContextToken()}.
+     */
+    public WindowContextController(@NonNull IBinder token) {
+        mToken = token;
+        mWms = WindowManagerGlobal.getWindowManagerService();
+    }
+
+    /** Used for test only. DO NOT USE it in production code. */
+    @VisibleForTesting
+    public WindowContextController(@NonNull IBinder token, IWindowManager mockWms) {
+        mToken = token;
+        mWms = mockWms;
+    }
+
+    /**
+     * Registers the {@code mToken} to the window context listener.
+     *
+     * @param type The window type of the {@link WindowContext}
+     * @param displayId The {@link Context#getDisplayId() ID of display} to associate with
+     * @param options The window context launched option
+     */
+    public void registerListener(@WindowType int type, int displayId,  @Nullable Bundle options) {
+        if (mListenerRegistered) {
+            throw new UnsupportedOperationException("A Window Context can only register a listener"
+                    + " once.");
+        }
+        try {
+            mListenerRegistered = mWms.registerWindowContextListener(mToken, type, displayId,
+                    options);
+        }  catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Unregisters the window context listener associated with the {@code mToken} if it has been
+     * registered.
+     */
+    public void unregisterListenerIfNeeded() {
+        if (mListenerRegistered) {
+            try {
+                mWms.unregisterWindowContextListener(mToken);
+                mListenerRegistered = false;
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+    }
+}
diff --git a/core/java/android/app/WindowTokenClient.java b/core/java/android/window/WindowTokenClient.java
similarity index 74%
rename from core/java/android/app/WindowTokenClient.java
rename to core/java/android/window/WindowTokenClient.java
index 2298e84..b2fe4d9 100644
--- a/core/java/android/app/WindowTokenClient.java
+++ b/core/java/android/window/WindowTokenClient.java
@@ -13,9 +13,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package android.app;
+package android.window;
 
 import android.annotation.NonNull;
+import android.app.ActivityThread;
+import android.app.IWindowToken;
+import android.app.ResourcesManager;
 import android.content.Context;
 import android.content.res.Configuration;
 import android.os.Bundle;
@@ -25,18 +28,22 @@
 import java.lang.ref.WeakReference;
 
 /**
- * Client implementation of {@link IWindowToken}. It can receive configuration change callbacks from
- * server when window token config is updated or when it is moved between displays, and update the
- * resources associated with this token on the client side. This will make sure that
- * {@link WindowContext} instances will have updated resources and configuration.
+ * This class is used to receive {@link Configuration} changes from the associated window manager
+ * node on the server side, and apply the change to the {@link Context#getResources() associated
+ * Resources} of the attached {@link Context}. It is also used as
+ * {@link Context#getWindowContextToken() the token of non-Activity UI Contexts}.
+ *
+ * @see WindowContext
+ * @see android.view.IWindowManager#registerWindowContextListener(IBinder, int, int, Bundle)
+ *
  * @hide
  */
 public class WindowTokenClient extends IWindowToken.Stub {
     /**
      * Attached {@link Context} for this window token to update configuration and resources.
-     * Initialized by {@link #attachContext(WindowContext)}.
+     * Initialized by {@link #attachContext(Context)}.
      */
-    private WeakReference<WindowContext> mContextRef = null;
+    private WeakReference<Context> mContextRef = null;
 
     private final ResourcesManager mResourcesManager = ResourcesManager.getInstance();
 
@@ -50,13 +57,11 @@
      * @param context context to be attached
      * @throws IllegalStateException if attached context has already existed.
      */
-    void attachContext(@NonNull WindowContext context) {
+    public void attachContext(@NonNull Context context) {
         if (mContextRef != null) {
             throw new IllegalStateException("Context is already attached.");
         }
         mContextRef = new WeakReference<>(context);
-        final ContextImpl impl = ContextImpl.getImpl(context);
-        impl.setResources(impl.createWindowContextResources());
     }
 
     @Override
@@ -72,6 +77,10 @@
         if (displayChanged || configChanged) {
             // TODO(ag/9789103): update resource manager logic to track non-activity tokens
             mResourcesManager.updateResourcesForActivity(this, newConfig, newDisplayId);
+            if (context instanceof WindowContext) {
+                ActivityThread.currentActivityThread().getHandler().post(
+                        () -> ((WindowContext) context).dispatchConfigurationChanged(newConfig));
+            }
         }
         if (displayChanged) {
             context.updateDisplay(newDisplayId);
@@ -80,7 +89,7 @@
 
     @Override
     public void onWindowTokenRemoved() {
-        final WindowContext context = mContextRef.get();
+        final Context context = mContextRef.get();
         if (context != null) {
             context.destroy();
             mContextRef.clear();
diff --git a/core/java/com/android/internal/accessibility/util/AccessibilityStatsLogUtils.java b/core/java/com/android/internal/accessibility/util/AccessibilityStatsLogUtils.java
index 7baa53b..a600a94 100644
--- a/core/java/com/android/internal/accessibility/util/AccessibilityStatsLogUtils.java
+++ b/core/java/com/android/internal/accessibility/util/AccessibilityStatsLogUtils.java
@@ -133,6 +133,17 @@
                 duration);
     }
 
+    /**
+     * Logs the activated mode of the magnification when the IME window is shown on the screen.
+     * Calls this when the magnification is enabled and the IME window is shown on the screen.
+     *
+     * @param mode The activated magnification mode.
+     */
+    public static void logMagnificationModeWithImeOn(int mode) {
+        FrameworkStatsLog.write(FrameworkStatsLog.MAGNIFICATION_MODE_WITH_IME_ON_REPORTED,
+                convertToLoggingMagnificationMode(mode));
+    }
+
     private static int convertToLoggingShortcutType(@ShortcutType int shortcutType) {
         switch (shortcutType) {
             case ACCESSIBILITY_BUTTON:
diff --git a/core/java/com/android/internal/app/AppPredictionServiceResolverComparator.java b/core/java/com/android/internal/app/AppPredictionServiceResolverComparator.java
index 26af615..b76ef0f 100644
--- a/core/java/com/android/internal/app/AppPredictionServiceResolverComparator.java
+++ b/core/java/com/android/internal/app/AppPredictionServiceResolverComparator.java
@@ -28,11 +28,9 @@
 import android.content.pm.ResolveInfo;
 import android.os.Message;
 import android.os.UserHandle;
-import android.provider.DeviceConfig;
 import android.util.Log;
 
 import com.android.internal.app.ResolverActivity.ResolvedComponentInfo;
-import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
 
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -62,11 +60,6 @@
     // back to using the ResolverRankerService.
     private ResolverRankerServiceResolverComparator mResolverRankerService;
 
-    private boolean mAppendDirectShareEnabled = DeviceConfig.getBoolean(
-            DeviceConfig.NAMESPACE_SYSTEMUI,
-            SystemUiDeviceConfigFlags.APPEND_DIRECT_SHARE_ENABLED,
-            true);
-
     AppPredictionServiceResolverComparator(
                 Context context,
                 Intent intent,
@@ -183,9 +176,6 @@
         if (mResolverRankerService != null) {
             return mResolverRankerService.getScore(name);
         }
-        if (mAppendDirectShareEnabled && !mTargetScores.isEmpty()) {
-            return mTargetScores.get(name);
-        }
         Integer rank = mTargetRanks.get(name);
         if (rank == null) {
             Log.w(TAG, "Score requested for unknown component. Did you call compute yet?");
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index d4d8536..862c900 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -256,15 +256,6 @@
             SystemUiDeviceConfigFlags.HASH_SALT_MAX_DAYS,
             DEFAULT_SALT_EXPIRATION_DAYS);
 
-    private boolean mAppendDirectShareEnabled = DeviceConfig.getBoolean(
-            DeviceConfig.NAMESPACE_SYSTEMUI,
-            SystemUiDeviceConfigFlags.APPEND_DIRECT_SHARE_ENABLED,
-            true);
-    private boolean mChooserTargetRankingEnabled = DeviceConfig.getBoolean(
-            DeviceConfig.NAMESPACE_SYSTEMUI,
-            SystemUiDeviceConfigFlags.CHOOSER_TARGET_RANKING_ENABLED,
-            true);
-
     private Bundle mReplacementExtras;
     private IntentSender mChosenComponentSender;
     private IntentSender mRefinementIntentSender;
@@ -472,16 +463,10 @@
         private static final int SHORTCUT_MANAGER_SHARE_TARGET_RESULT = 4;
         private static final int SHORTCUT_MANAGER_SHARE_TARGET_RESULT_COMPLETED = 5;
         private static final int LIST_VIEW_UPDATE_MESSAGE = 6;
-        private static final int CHOOSER_TARGET_RANKING_SCORE = 7;
 
         private static final int WATCHDOG_TIMEOUT_MAX_MILLIS = 10000;
         private static final int WATCHDOG_TIMEOUT_MIN_MILLIS = 3000;
 
-        private static final int DEFAULT_DIRECT_SHARE_TIMEOUT_MILLIS = 1500;
-        private int mDirectShareTimeout = DeviceConfig.getInt(DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.SHARE_SHEET_DIRECT_SHARE_TIMEOUT,
-                DEFAULT_DIRECT_SHARE_TIMEOUT_MILLIS);
-
         private boolean mMinTimeoutPassed = false;
 
         private void removeAllMessages() {
@@ -491,7 +476,6 @@
             removeMessages(CHOOSER_TARGET_SERVICE_RESULT);
             removeMessages(SHORTCUT_MANAGER_SHARE_TARGET_RESULT);
             removeMessages(SHORTCUT_MANAGER_SHARE_TARGET_RESULT_COMPLETED);
-            removeMessages(CHOOSER_TARGET_RANKING_SCORE);
         }
 
         private void restartServiceRequestTimer() {
@@ -501,14 +485,13 @@
 
             if (DEBUG) {
                 Log.d(TAG, "queryTargets setting watchdog timer for "
-                        + mDirectShareTimeout + "-"
                         + WATCHDOG_TIMEOUT_MAX_MILLIS + "ms");
             }
 
             sendEmptyMessageDelayed(CHOOSER_TARGET_SERVICE_WATCHDOG_MIN_TIMEOUT,
                     WATCHDOG_TIMEOUT_MIN_MILLIS);
             sendEmptyMessageDelayed(CHOOSER_TARGET_SERVICE_WATCHDOG_MAX_TIMEOUT,
-                    mAppendDirectShareEnabled ? mDirectShareTimeout : WATCHDOG_TIMEOUT_MAX_MILLIS);
+                    WATCHDOG_TIMEOUT_MAX_MILLIS);
         }
 
         private void maybeStopServiceRequestTimer() {
@@ -608,17 +591,6 @@
                     getChooserActivityLogger().logSharesheetDirectLoadComplete();
                     break;
 
-                case CHOOSER_TARGET_RANKING_SCORE:
-                    if (DEBUG) Log.d(TAG, "CHOOSER_TARGET_RANKING_SCORE");
-                    final ChooserTargetRankingInfo scoreInfo = (ChooserTargetRankingInfo) msg.obj;
-                    ChooserListAdapter adapterForUserHandle =
-                            mChooserMultiProfilePagerAdapter.getListAdapterForUserHandle(
-                                    scoreInfo.userHandle);
-                    if (adapterForUserHandle != null) {
-                        adapterForUserHandle.addChooserTargetRankingScore(scoreInfo.scores);
-                    }
-                    break;
-
                 default:
                     super.handleMessage(msg);
             }
@@ -878,24 +850,14 @@
             final List<ShortcutManager.ShareShortcutInfo> shareShortcutInfos =
                     new ArrayList<>();
 
-            // Separate ChooserTargets ranking scores and ranked Shortcuts.
             List<AppTarget> shortcutResults = new ArrayList<>();
-            List<AppTarget> chooserTargetScores = new ArrayList<>();
             for (AppTarget appTarget : resultList) {
                 if (appTarget.getShortcutInfo() == null) {
                     continue;
                 }
-                if (appTarget.getShortcutInfo().getId().equals(CHOOSER_TARGET)) {
-                    chooserTargetScores.add(appTarget);
-                } else {
-                    shortcutResults.add(appTarget);
-                }
+                shortcutResults.add(appTarget);
             }
             resultList = shortcutResults;
-            if (mChooserTargetRankingEnabled) {
-                sendChooserTargetRankingScore(chooserTargetScores,
-                        chooserListAdapter.getUserHandle());
-            }
             for (AppTarget appTarget : resultList) {
                 shareShortcutInfos.add(new ShortcutManager.ShareShortcutInfo(
                         appTarget.getShortcutInfo(),
@@ -2148,14 +2110,6 @@
         return true;
     }
 
-    private void sendChooserTargetRankingScore(List<AppTarget> chooserTargetScores,
-            UserHandle userHandle) {
-        final Message msg = Message.obtain();
-        msg.what = ChooserHandler.CHOOSER_TARGET_RANKING_SCORE;
-        msg.obj = new ChooserTargetRankingInfo(chooserTargetScores, userHandle);
-        mChooserHandler.sendMessage(msg);
-    }
-
     private void sendShareShortcutInfoList(
                 List<ShortcutManager.ShareShortcutInfo> resultList,
                 ChooserListAdapter chooserListAdapter,
@@ -2376,9 +2330,6 @@
     }
 
     private void sendImpressionToAppPredictor(TargetInfo targetInfo, ChooserListAdapter adapter) {
-        if (!mChooserTargetRankingEnabled) {
-            return;
-        }
         AppPredictor directShareAppPredictor = getAppPredictorForDirectShareIfEnabled(
                 mChooserMultiProfilePagerAdapter.getCurrentUserHandle());
         if (directShareAppPredictor == null) {
@@ -2399,11 +2350,6 @@
                 targetIds.add(new AppTargetId(
                         String.format("%s/%s/%s", shortcutId, componentName.flattenToString(),
                                 SHORTCUT_TARGET)));
-            } else {
-                String titleHash = ChooserUtil.md5(chooserTarget.getTitle().toString());
-                targetIds.add(new AppTargetId(
-                        String.format("%s/%s/%s", titleHash, componentName.flattenToString(),
-                                CHOOSER_TARGET)));
             }
         }
         directShareAppPredictor.notifyLaunchLocationShown(LAUNCH_LOCATION_DIRECT_SHARE, targetIds);
@@ -2423,29 +2369,6 @@
         if (mDirectShareAppTargetCache != null) {
             appTarget = mDirectShareAppTargetCache.get(chooserTarget);
         }
-        if (mChooserTargetRankingEnabled && appTarget == null) {
-            // Send ChooserTarget sharing info to AppPredictor.
-            ComponentName componentName = mChooserTargetComponentNameCache.getOrDefault(
-                    chooserTarget.getComponentName(), chooserTarget.getComponentName());
-            try {
-                appTarget = new AppTarget.Builder(
-                        new AppTargetId(componentName.flattenToString()),
-                        new ShortcutInfo.Builder(
-                                createPackageContextAsUser(
-                                        componentName.getPackageName(),
-                                        0 /* flags */,
-                                        getUser()),
-                                CHOOSER_TARGET)
-                            .setActivity(componentName)
-                            .setShortLabel(ChooserUtil.md5(chooserTarget.getTitle().toString()))
-                            .build())
-                        .setClassName(componentName.getClassName())
-                        .build();
-            } catch (NameNotFoundException e) {
-                Log.e(TAG, "Could not look up service " + componentName
-                        + "; component name not found");
-            }
-        }
         // This is a direct share click that was provided by the APS
         if (appTarget != null) {
             directShareAppPredictor.notifyAppTargetEvent(
@@ -3971,9 +3894,7 @@
                 // until they start to scroll
                 ChooserListAdapter adapter =
                         mChooserMultiProfilePagerAdapter.getActiveListAdapter();
-                int validTargets =
-                        mAppendDirectShareEnabled ? adapter.getNumServiceTargetsForExpand()
-                                : adapter.getSelectableServiceTargetCount();
+                int validTargets = adapter.getSelectableServiceTargetCount();
                 if (validTargets <= maxTargetsPerRow) {
                     mHideDirectShareExpansion = true;
                     return;
diff --git a/core/java/com/android/internal/app/ChooserListAdapter.java b/core/java/com/android/internal/app/ChooserListAdapter.java
index 5700668..cc2b12a 100644
--- a/core/java/com/android/internal/app/ChooserListAdapter.java
+++ b/core/java/com/android/internal/app/ChooserListAdapter.java
@@ -21,7 +21,6 @@
 
 import android.app.ActivityManager;
 import android.app.prediction.AppPredictor;
-import android.app.prediction.AppTarget;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -37,7 +36,6 @@
 import android.provider.DeviceConfig;
 import android.service.chooser.ChooserTarget;
 import android.util.Log;
-import android.util.Pair;
 import android.view.View;
 import android.view.ViewGroup;
 
@@ -53,21 +51,13 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
-import java.util.stream.Collectors;
 
 public class ChooserListAdapter extends ResolverListAdapter {
     private static final String TAG = "ChooserListAdapter";
     private static final boolean DEBUG = false;
 
-    private boolean mAppendDirectShareEnabled = DeviceConfig.getBoolean(
-            DeviceConfig.NAMESPACE_SYSTEMUI,
-            SystemUiDeviceConfigFlags.APPEND_DIRECT_SHARE_ENABLED,
-            true);
-
     private boolean mEnableStackedApps = true;
 
     public static final int NO_POSITION = -1;
@@ -79,8 +69,6 @@
 
     private static final int MAX_SUGGESTED_APP_TARGETS = 4;
     private static final int MAX_CHOOSER_TARGETS_PER_APP = 2;
-    private static final int MAX_SERVICE_TARGET_APP = 8;
-    private static final int DEFAULT_DIRECT_SHARE_RANKING_SCORE = 1000;
 
     /** {@link #getBaseScore} */
     public static final float CALLER_TARGET_SCORE_BOOST = 900.f;
@@ -94,17 +82,11 @@
 
     private int mNumShortcutResults = 0;
     private Map<DisplayResolveInfo, LoadIconTask> mIconLoaders = new HashMap<>();
+    private boolean mApplySharingAppLimits;
 
     // Reserve spots for incoming direct share targets by adding placeholders
     private ChooserTargetInfo
             mPlaceHolderTargetInfo = new ChooserActivity.PlaceHolderTargetInfo();
-    private int mValidServiceTargetsNum = 0;
-    private int mAvailableServiceTargetsNum = 0;
-    private final Map<ComponentName, Pair<List<ChooserTargetInfo>, Integer>>
-            mParkingDirectShareTargets = new HashMap<>();
-    private final Map<ComponentName, Map<String, Integer>> mChooserTargetScores = new HashMap<>();
-    private Set<ComponentName> mPendingChooserTargetService = new HashSet<>();
-    private Set<ComponentName> mShortcutComponents = new HashSet<>();
     private final List<ChooserTargetInfo> mServiceTargets = new ArrayList<>();
     private final List<DisplayResolveInfo> mCallerTargets = new ArrayList<>();
 
@@ -183,6 +165,10 @@
                 if (mCallerTargets.size() == MAX_SUGGESTED_APP_TARGETS) break;
             }
         }
+        mApplySharingAppLimits = DeviceConfig.getBoolean(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                SystemUiDeviceConfigFlags.APPLY_SHARING_APP_LIMITS_IN_SYSUI,
+                true);
     }
 
     AppPredictor getAppPredictor() {
@@ -209,9 +195,6 @@
 
     void refreshListView() {
         if (mListViewDataChanged) {
-            if (mAppendDirectShareEnabled) {
-                appendServiceTargetsWithQuota();
-            }
             super.notifyDataSetChanged();
         }
         mListViewDataChanged = false;
@@ -221,10 +204,6 @@
     private void createPlaceHolders() {
         mNumShortcutResults = 0;
         mServiceTargets.clear();
-        mValidServiceTargetsNum = 0;
-        mParkingDirectShareTargets.clear();
-        mPendingChooserTargetService.clear();
-        mShortcutComponents.clear();
         for (int i = 0; i < mChooserListCommunicator.getMaxRankedTargets(); i++) {
             mServiceTargets.add(mPlaceHolderTargetInfo);
         }
@@ -517,33 +496,30 @@
                     + targets.size()
                     + " targets");
         }
-        if (mAppendDirectShareEnabled) {
-            parkTargetIntoMemory(origTarget, targets, targetType, directShareToShortcutInfos,
-                    pendingChooserTargetServiceConnections);
-            return;
-        }
         if (targets.size() == 0) {
             return;
         }
-
         final float baseScore = getBaseScore(origTarget, targetType);
         Collections.sort(targets, mBaseTargetComparator);
-
         final boolean isShortcutResult =
                 (targetType == TARGET_TYPE_SHORTCUTS_FROM_SHORTCUT_MANAGER
                         || targetType == TARGET_TYPE_SHORTCUTS_FROM_PREDICTION_SERVICE);
         final int maxTargets = isShortcutResult ? mMaxShortcutTargetsPerApp
                 : MAX_CHOOSER_TARGETS_PER_APP;
+        final int targetsLimit = mApplySharingAppLimits ? Math.min(targets.size(), maxTargets)
+                : targets.size();
         float lastScore = 0;
         boolean shouldNotify = false;
-        for (int i = 0, count = Math.min(targets.size(), maxTargets); i < count; i++) {
+        for (int i = 0, count = targetsLimit; i < count; i++) {
             final ChooserTarget target = targets.get(i);
             float targetScore = target.getScore();
-            targetScore *= baseScore;
-            if (i > 0 && targetScore >= lastScore) {
-                // Apply a decay so that the top app can't crowd out everything else.
-                // This incents ChooserTargetServices to define what's truly better.
-                targetScore = lastScore * 0.95f;
+            if (mApplySharingAppLimits) {
+                targetScore *= baseScore;
+                if (i > 0 && targetScore >= lastScore) {
+                    // Apply a decay so that the top app can't crowd out everything else.
+                    // This incents ChooserTargetServices to define what's truly better.
+                    targetScore = lastScore * 0.95f;
+                }
             }
             UserHandle userHandle = getUserHandle();
             Context contextAsUser = mContext.createContextAsUser(userHandle, 0 /* flags */);
@@ -561,7 +537,8 @@
                 Log.d(TAG, " => " + target.toString() + " score=" + targetScore
                         + " base=" + target.getScore()
                         + " lastScore=" + lastScore
-                        + " baseScore=" + baseScore);
+                        + " baseScore=" + baseScore
+                        + " applyAppLimit=" + mApplySharingAppLimits);
             }
 
             lastScore = targetScore;
@@ -573,217 +550,13 @@
     }
 
     /**
-     * Store ChooserTarget ranking scores info wrapped in {@code targets}.
-     */
-    public void addChooserTargetRankingScore(List<AppTarget> targets) {
-        Log.i(TAG, "addChooserTargetRankingScore " + targets.size() + " targets score.");
-        for (AppTarget target : targets) {
-            if (target.getShortcutInfo() == null) {
-                continue;
-            }
-            ShortcutInfo shortcutInfo = target.getShortcutInfo();
-            if (!shortcutInfo.getId().equals(ChooserActivity.CHOOSER_TARGET)
-                    || shortcutInfo.getActivity() == null) {
-                continue;
-            }
-            ComponentName componentName = shortcutInfo.getActivity();
-            if (!mChooserTargetScores.containsKey(componentName)) {
-                mChooserTargetScores.put(componentName, new HashMap<>());
-            }
-            mChooserTargetScores.get(componentName).put(shortcutInfo.getShortLabel().toString(),
-                    target.getRank());
-        }
-        mChooserTargetScores.keySet().forEach(key -> rankTargetsWithinComponent(key));
-    }
-
-    /**
-     * Rank chooserTargets of the given {@code componentName} in mParkingDirectShareTargets as per
-     * available scores stored in mChooserTargetScores.
-     */
-    private void rankTargetsWithinComponent(ComponentName componentName) {
-        if (!mParkingDirectShareTargets.containsKey(componentName)
-                || !mChooserTargetScores.containsKey(componentName)) {
-            return;
-        }
-        Map<String, Integer> scores = mChooserTargetScores.get(componentName);
-        Collections.sort(mParkingDirectShareTargets.get(componentName).first, (o1, o2) -> {
-            // The score has been normalized between 0 and 2000, the default is 1000.
-            int score1 = scores.getOrDefault(
-                    ChooserUtil.md5(o1.getChooserTarget().getTitle().toString()),
-                    DEFAULT_DIRECT_SHARE_RANKING_SCORE);
-            int score2 = scores.getOrDefault(
-                    ChooserUtil.md5(o2.getChooserTarget().getTitle().toString()),
-                    DEFAULT_DIRECT_SHARE_RANKING_SCORE);
-            return score2 - score1;
-        });
-    }
-
-    /**
-     * Park {@code targets} into memory for the moment to surface them later when view is refreshed.
-     * Components pending on ChooserTargetService query are also recorded.
-     */
-    private void parkTargetIntoMemory(DisplayResolveInfo origTarget, List<ChooserTarget> targets,
-            @ChooserActivity.ShareTargetType int targetType,
-            Map<ChooserTarget, ShortcutInfo> directShareToShortcutInfos,
-            List<ChooserActivity.ChooserTargetServiceConnection>
-                    pendingChooserTargetServiceConnections) {
-        ComponentName origComponentName = origTarget != null ? origTarget.getResolvedComponentName()
-                : !targets.isEmpty() ? targets.get(0).getComponentName() : null;
-        Log.i(TAG,
-                "parkTargetIntoMemory " + origComponentName + ", " + targets.size() + " targets");
-        mPendingChooserTargetService = pendingChooserTargetServiceConnections.stream()
-                .map(ChooserActivity.ChooserTargetServiceConnection::getComponentName)
-                .filter(componentName -> !componentName.equals(origComponentName))
-                .collect(Collectors.toSet());
-        // Park targets in memory
-        if (!targets.isEmpty()) {
-            final boolean isShortcutResult =
-                    (targetType == TARGET_TYPE_SHORTCUTS_FROM_SHORTCUT_MANAGER
-                            || targetType == TARGET_TYPE_SHORTCUTS_FROM_PREDICTION_SERVICE);
-            Context contextAsUser = mContext.createContextAsUser(getUserHandle(),
-                    0 /* flags */);
-            List<ChooserTargetInfo> parkingTargetInfos = targets.stream()
-                    .map(target ->
-                            new SelectableTargetInfo(
-                                    contextAsUser, origTarget, target, target.getScore(),
-                                    mSelectableTargetInfoCommunicator,
-                                    (isShortcutResult ? directShareToShortcutInfos.get(target)
-                                            : null))
-                    )
-                    .collect(Collectors.toList());
-            Pair<List<ChooserTargetInfo>, Integer> parkingTargetInfoPair =
-                    mParkingDirectShareTargets.getOrDefault(origComponentName,
-                            new Pair<>(new ArrayList<>(), 0));
-            for (ChooserTargetInfo target : parkingTargetInfos) {
-                if (!checkDuplicateTarget(target, parkingTargetInfoPair.first)
-                        && !checkDuplicateTarget(target, mServiceTargets)) {
-                    parkingTargetInfoPair.first.add(target);
-                    mAvailableServiceTargetsNum++;
-                }
-            }
-            mParkingDirectShareTargets.put(origComponentName, parkingTargetInfoPair);
-            rankTargetsWithinComponent(origComponentName);
-            if (isShortcutResult) {
-                mShortcutComponents.add(origComponentName);
-            }
-        }
-        notifyDataSetChanged();
-    }
-
-    /**
-     * Append targets of top ranked share app into direct share row with quota limit. Remove
-     * appended ones from memory.
-     */
-    private void appendServiceTargetsWithQuota() {
-        int maxRankedTargets = mChooserListCommunicator.getMaxRankedTargets();
-        List<ComponentName> topComponentNames = getTopComponentNames(maxRankedTargets);
-        float totalScore = 0f;
-        for (ComponentName component : topComponentNames) {
-            if (!mPendingChooserTargetService.contains(component)
-                    && !mParkingDirectShareTargets.containsKey(component)) {
-                continue;
-            }
-            totalScore += super.getScore(component);
-        }
-        boolean shouldWaitPendingService = false;
-        for (ComponentName component : topComponentNames) {
-            if (!mPendingChooserTargetService.contains(component)
-                    && !mParkingDirectShareTargets.containsKey(component)) {
-                continue;
-            }
-            float score = super.getScore(component);
-            int quota = Math.round(maxRankedTargets * score / totalScore);
-            if (mPendingChooserTargetService.contains(component) && quota >= 1) {
-                shouldWaitPendingService = true;
-            }
-            if (!mParkingDirectShareTargets.containsKey(component)) {
-                continue;
-            }
-            // Append targets into direct share row as per quota.
-            Pair<List<ChooserTargetInfo>, Integer> parkingTargetsItem =
-                    mParkingDirectShareTargets.get(component);
-            List<ChooserTargetInfo> parkingTargets = parkingTargetsItem.first;
-            int insertedNum = parkingTargetsItem.second;
-            while (insertedNum < quota && !parkingTargets.isEmpty()) {
-                if (!checkDuplicateTarget(parkingTargets.get(0), mServiceTargets)) {
-                    mServiceTargets.add(mValidServiceTargetsNum, parkingTargets.get(0));
-                    mValidServiceTargetsNum++;
-                    insertedNum++;
-                }
-                parkingTargets.remove(0);
-            }
-            Log.i(TAG, " appendServiceTargetsWithQuota component=" + component
-                    + " appendNum=" + (insertedNum - parkingTargetsItem.second));
-            if (DEBUG) {
-                Log.d(TAG, " appendServiceTargetsWithQuota component=" + component
-                        + " score=" + score
-                        + " totalScore=" + totalScore
-                        + " quota=" + quota);
-            }
-            mParkingDirectShareTargets.put(component, new Pair<>(parkingTargets, insertedNum));
-        }
-        if (!shouldWaitPendingService) {
-            fillAllServiceTargets();
-        }
-    }
-
-    /**
-     * Append all remaining targets (parking in memory) into direct share row as per their ranking.
-     */
-    private void fillAllServiceTargets() {
-        if (mParkingDirectShareTargets.isEmpty()) {
-            return;
-        }
-        Log.i(TAG, " fillAllServiceTargets");
-        List<ComponentName> topComponentNames = getTopComponentNames(MAX_SERVICE_TARGET_APP);
-        // Append all remaining targets of top recommended components into direct share row.
-        for (ComponentName component : topComponentNames) {
-            if (!mParkingDirectShareTargets.containsKey(component)) {
-                continue;
-            }
-            mParkingDirectShareTargets.get(component).first.stream()
-                    .filter(target -> !checkDuplicateTarget(target, mServiceTargets))
-                    .forEach(target -> {
-                        mServiceTargets.add(mValidServiceTargetsNum, target);
-                        mValidServiceTargetsNum++;
-                    });
-            mParkingDirectShareTargets.remove(component);
-        }
-        // Append all remaining shortcuts targets into direct share row.
-        mParkingDirectShareTargets.entrySet().stream()
-                .filter(entry -> mShortcutComponents.contains(entry.getKey()))
-                .map(entry -> entry.getValue())
-                .map(pair -> pair.first)
-                .forEach(targets -> {
-                    for (ChooserTargetInfo target : targets) {
-                        if (!checkDuplicateTarget(target, mServiceTargets)) {
-                            mServiceTargets.add(mValidServiceTargetsNum, target);
-                            mValidServiceTargetsNum++;
-                        }
-                    }
-                });
-        mParkingDirectShareTargets.clear();
-    }
-
-    private boolean checkDuplicateTarget(ChooserTargetInfo target,
-            List<ChooserTargetInfo> destination) {
-        // Check for duplicates and abort if found
-        for (ChooserTargetInfo otherTargetInfo : destination) {
-            if (target.isSimilar(otherTargetInfo)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
      * The return number have to exceed a minimum limit to make direct share area expandable. When
      * append direct share targets is enabled, return count of all available targets parking in the
      * memory; otherwise, it is shortcuts count which will help reduce the amount of visible
      * shuffling due to older-style direct share targets.
      */
     int getNumServiceTargetsForExpand() {
-        return mAppendDirectShareEnabled ? mAvailableServiceTargetsNum : mNumShortcutResults;
+        return mNumShortcutResults;
     }
 
     /**
@@ -801,16 +574,11 @@
         if (target == null) {
             return CALLER_TARGET_SCORE_BOOST;
         }
-
-        if (targetType == TARGET_TYPE_SHORTCUTS_FROM_PREDICTION_SERVICE) {
-            return SHORTCUT_TARGET_SCORE_BOOST;
-        }
-
         float score = super.getScore(target);
-        if (targetType == TARGET_TYPE_SHORTCUTS_FROM_SHORTCUT_MANAGER) {
+        if (targetType == TARGET_TYPE_SHORTCUTS_FROM_SHORTCUT_MANAGER
+                || targetType == TARGET_TYPE_SHORTCUTS_FROM_PREDICTION_SERVICE) {
             return score * SHORTCUT_TARGET_SCORE_BOOST;
         }
-
         return score;
     }
 
@@ -820,9 +588,6 @@
      */
     public void completeServiceTargetLoading() {
         mServiceTargets.removeIf(o -> o instanceof ChooserActivity.PlaceHolderTargetInfo);
-        if (mAppendDirectShareEnabled) {
-            fillAllServiceTargets();
-        }
         if (mServiceTargets.isEmpty()) {
             mServiceTargets.add(new ChooserActivity.EmptyTargetInfo());
         }
diff --git a/core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java b/core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java
index dd837fc..3b6a877 100644
--- a/core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java
+++ b/core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java
@@ -194,12 +194,12 @@
         if (mIsSendAction) {
             showEmptyState(activeListAdapter,
                     R.drawable.ic_sharing_disabled,
-                    R.string.resolver_cant_share_with_work_apps,
+                    R.string.resolver_cross_profile_blocked,
                     R.string.resolver_cant_share_with_work_apps_explanation);
         } else {
             showEmptyState(activeListAdapter,
                     R.drawable.ic_sharing_disabled,
-                    R.string.resolver_cant_access_work_apps,
+                    R.string.resolver_cross_profile_blocked,
                     R.string.resolver_cant_access_work_apps_explanation);
         }
     }
@@ -209,44 +209,31 @@
         if (mIsSendAction) {
             showEmptyState(activeListAdapter,
                     R.drawable.ic_sharing_disabled,
-                    R.string.resolver_cant_share_with_personal_apps,
+                    R.string.resolver_cross_profile_blocked,
                     R.string.resolver_cant_share_with_personal_apps_explanation);
         } else {
             showEmptyState(activeListAdapter,
                     R.drawable.ic_sharing_disabled,
-                    R.string.resolver_cant_access_personal_apps,
+                    R.string.resolver_cross_profile_blocked,
                     R.string.resolver_cant_access_personal_apps_explanation);
         }
     }
 
     @Override
     protected void showNoPersonalAppsAvailableEmptyState(ResolverListAdapter listAdapter) {
-        if (mIsSendAction) {
-            showEmptyState(listAdapter,
-                    R.drawable.ic_no_apps,
-                    R.string.resolver_no_personal_apps_available_share,
-                    /* subtitleRes */ 0);
-        } else {
-            showEmptyState(listAdapter,
-                    R.drawable.ic_no_apps,
-                    R.string.resolver_no_personal_apps_available_resolve,
-                    /* subtitleRes */ 0);
-        }
+        showEmptyState(listAdapter,
+                R.drawable.ic_no_apps,
+                R.string.resolver_no_personal_apps_available,
+                /* subtitleRes */ 0);
+
     }
 
     @Override
     protected void showNoWorkAppsAvailableEmptyState(ResolverListAdapter listAdapter) {
-        if (mIsSendAction) {
-            showEmptyState(listAdapter,
-                    R.drawable.ic_no_apps,
-                    R.string.resolver_no_work_apps_available_share,
-                    /* subtitleRes */ 0);
-        } else {
-            showEmptyState(listAdapter,
-                    R.drawable.ic_no_apps,
-                    R.string.resolver_no_work_apps_available_resolve,
-                    /* subtitleRes */ 0);
-        }
+        showEmptyState(listAdapter,
+                R.drawable.ic_no_apps,
+                R.string.resolver_no_work_apps_available,
+                /* subtitleRes */ 0);
     }
 
     void setEmptyStateBottomOffset(int bottomOffset) {
diff --git a/core/java/com/android/internal/app/IAppOpsService.aidl b/core/java/com/android/internal/app/IAppOpsService.aidl
index eecd0cf..01bb199 100644
--- a/core/java/com/android/internal/app/IAppOpsService.aidl
+++ b/core/java/com/android/internal/app/IAppOpsService.aidl
@@ -20,6 +20,7 @@
 import android.app.AsyncNotedAppOp;
 import android.app.SyncNotedAppOp;
 import android.app.RuntimeAppOpAccessMessage;
+import android.content.AttributionSource;
 import android.content.pm.ParceledListSlice;
 import android.os.Bundle;
 import android.os.RemoteCallback;
@@ -52,17 +53,13 @@
     // End of methods also called by native code.
     // Any new method exposed to native must be added after the last one, do not reorder
 
-    int noteProxyOperation(int code, int proxiedUid, String proxiedPackageName,
-            String proxiedAttributionTag, int proxyUid, String proxyPackageName,
-            String proxyAttributionTag, boolean shouldCollectAsyncNotedOp, String message,
-            boolean shouldCollectMessage);
-    int startProxyOperation(IBinder clientId, int code, int proxiedUid, String proxiedPackageName,
-            @nullable String proxiedAttributionTag, int proxyUid, String proxyPackageName,
-            @nullable String proxyAttributionTag, boolean startIfModeDefault,
-            boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage);
-    void finishProxyOperation(IBinder clientId, int code, int proxiedUid, String proxiedPackageName,
-            @nullable String proxiedAttributionTag, int proxyUid, String proxyPackageName,
-            @nullable String proxyAttributionTag);
+    int noteProxyOperation(int code, in AttributionSource attributionSource,
+            boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage,
+            boolean skipProxyOperation);
+    int startProxyOperation(IBinder clientId, int code, in AttributionSource attributionSource,
+            boolean startIfModeDefault, boolean shouldCollectAsyncNotedOp, String message,
+            boolean shouldCollectMessage, boolean skipProxyOperation);
+    void finishProxyOperation(IBinder clientId, int code, in AttributionSource attributionSource);
 
     // Remaining methods are only used in Java.
     int checkPackage(int uid, String packageName);
@@ -83,6 +80,7 @@
     void setHistoryParameters(int mode, long baseSnapshotInterval, int compressionStep);
     void addHistoricalOps(in AppOpsManager.HistoricalOps ops);
     void resetHistoryParameters();
+    void resetPackageOpsNoHistory(String packageName);
     void clearHistory();
     void rebootHistory(long offlineDurationMillis);
     List<AppOpsManager.PackageOps> getUidOps(int uid, in int[] ops);
@@ -100,6 +98,8 @@
     void startWatchingActive(in int[] ops, IAppOpsActiveCallback callback);
     void stopWatchingActive(IAppOpsActiveCallback callback);
     boolean isOperationActive(int code, int uid, String packageName);
+    boolean isProxying(int op, String proxyPackageName, String proxyAttributionTag, int proxiedUid,
+            String proxiedPackageName);
 
     void startWatchingStarted(in int[] ops, IAppOpsStartedCallback callback);
     void stopWatchingStarted(IAppOpsStartedCallback callback);
diff --git a/core/java/com/android/internal/app/IHotwordRecognitionStatusCallback.aidl b/core/java/com/android/internal/app/IHotwordRecognitionStatusCallback.aidl
index 65bd841..9bec505 100644
--- a/core/java/com/android/internal/app/IHotwordRecognitionStatusCallback.aidl
+++ b/core/java/com/android/internal/app/IHotwordRecognitionStatusCallback.aidl
@@ -17,6 +17,7 @@
 package com.android.internal.app;
 
 import android.hardware.soundtrigger.SoundTrigger;
+import android.service.voice.HotwordRejectedResult;
 
 /**
  * @hide
@@ -41,11 +42,13 @@
     void onGenericSoundTriggerDetected(in SoundTrigger.GenericRecognitionEvent recognitionEvent);
 
     /**
-     * Called when the validated result is invalid.
+     * Called when the {@link HotwordDetectionService second stage detection} did not detect the
+     * keyphrase.
      *
-     * @param reason The reason why the validated result is invalid.
+     * @param result Info about the second stage detection result, provided by the
+     *         {@link HotwordDetectionService}.
      */
-    void onRejected(int reason);
+    void onRejected(in HotwordRejectedResult result);
 
     /**
      * Called when the detection fails due to an error.
@@ -63,4 +66,12 @@
      * Called when the recognition is resumed after it was temporarily paused.
      */
     void onRecognitionResumed();
+
+    /**
+     * Called when the {@link HotwordDetectionService} reported the result for requesting update
+     * state action.
+     *
+     * @param status The status about the result of requesting update state action.
+     */
+    void onStatusReported(int status);
 }
diff --git a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
index 592f7c7..fffeb02 100644
--- a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
+++ b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
@@ -18,11 +18,15 @@
 
 import android.content.ComponentName;
 import android.content.Intent;
+import android.media.AudioFormat;
 import android.media.permission.Identity;
 import android.os.Bundle;
+import android.os.ParcelFileDescriptor;
+import android.os.PersistableBundle;
 import android.os.RemoteCallback;
 import android.os.SharedMemory;
 
+import com.android.internal.app.IHotwordRecognitionStatusCallback;
 import com.android.internal.app.IVoiceActionCheckCallback;
 import com.android.internal.app.IVoiceInteractionSessionShowCallback;
 import com.android.internal.app.IVoiceInteractor;
@@ -32,6 +36,7 @@
 import android.hardware.soundtrigger.SoundTrigger;
 import android.service.voice.IVoiceInteractionService;
 import android.service.voice.IVoiceInteractionSession;
+import android.service.voice.IMicrophoneHotwordDetectionVoiceInteractionCallback;
 
 interface IVoiceInteractionManagerService {
     void showSession(in Bundle sessionArgs, int flags);
@@ -228,17 +233,33 @@
     /**
      * Set configuration and pass read-only data to hotword detection service.
      *
-     * @param options Application configuration data provided by the
-     * {@link VoiceInteractionService}. The system strips out any remotable objects or other
-     * contents that can be used to communicate with other processes.
-     * @param sharedMemory The unrestricted data blob provided by the
-     * {@link VoiceInteractionService}. Use this to provide the hotword models data or other
+     * @param options Application configuration data to provide to the
+     * {@link HotwordDetectionService}. PersistableBundle does not allow any remotable objects or
+     * other contents that can be used to communicate with other processes.
+     * @param sharedMemory The unrestricted data blob to provide to the
+     * {@link HotwordDetectionService}. Use this to provide the hotword models data or other
      * such data to the trusted process.
+     * @param callback Use this to report {@link HotwordDetectionService} status.
      */
-    void setHotwordDetectionServiceConfig(in Bundle options, in SharedMemory sharedMemory);
+    void updateState(
+            in PersistableBundle options,
+            in SharedMemory sharedMemory,
+            in IHotwordRecognitionStatusCallback callback);
 
     /**
      * Requests to shutdown hotword detection service.
      */
     void shutdownHotwordDetectionService();
+
+    void startListeningFromMic(
+        in AudioFormat audioFormat,
+        in IMicrophoneHotwordDetectionVoiceInteractionCallback callback);
+
+    void stopListeningFromMic();
+
+    void startListeningFromExternalSource(
+        in ParcelFileDescriptor audioStream,
+        in AudioFormat audioFormat,
+        in PersistableBundle options,
+        in IMicrophoneHotwordDetectionVoiceInteractionCallback callback);
 }
diff --git a/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java b/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java
index 2464fc7..622f166 100644
--- a/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java
+++ b/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java
@@ -205,7 +205,7 @@
     protected void showNoPersonalToWorkIntentsEmptyState(ResolverListAdapter activeListAdapter) {
         showEmptyState(activeListAdapter,
                 R.drawable.ic_sharing_disabled,
-                R.string.resolver_cant_access_work_apps,
+                R.string.resolver_cross_profile_blocked,
                 R.string.resolver_cant_access_work_apps_explanation);
     }
 
@@ -213,7 +213,7 @@
     protected void showNoWorkToPersonalIntentsEmptyState(ResolverListAdapter activeListAdapter) {
         showEmptyState(activeListAdapter,
                 R.drawable.ic_sharing_disabled,
-                R.string.resolver_cant_access_personal_apps,
+                R.string.resolver_cross_profile_blocked,
                 R.string.resolver_cant_access_personal_apps_explanation);
     }
 
@@ -221,7 +221,7 @@
     protected void showNoPersonalAppsAvailableEmptyState(ResolverListAdapter listAdapter) {
         showEmptyState(listAdapter,
                 R.drawable.ic_no_apps,
-                R.string.resolver_no_personal_apps_available_resolve,
+                R.string.resolver_no_personal_apps_available,
                 /* subtitleRes */ 0);
     }
 
@@ -229,7 +229,7 @@
     protected void showNoWorkAppsAvailableEmptyState(ResolverListAdapter listAdapter) {
         showEmptyState(listAdapter,
                 R.drawable.ic_no_apps,
-                R.string.resolver_no_work_apps_available_resolve,
+                R.string.resolver_no_work_apps_available,
                 /* subtitleRes */ 0);
     }
 
diff --git a/core/java/com/android/internal/app/SuspendedAppActivity.java b/core/java/com/android/internal/app/SuspendedAppActivity.java
index 762297d..86f29a8 100644
--- a/core/java/com/android/internal/app/SuspendedAppActivity.java
+++ b/core/java/com/android/internal/app/SuspendedAppActivity.java
@@ -106,13 +106,17 @@
     }
 
     private String resolveTitle() {
-        final int titleId = (mSuppliedDialogInfo != null) ? mSuppliedDialogInfo.getTitleResId()
-                : ID_NULL;
-        if (titleId != ID_NULL && mSuspendingAppResources != null) {
-            try {
-                return mSuspendingAppResources.getString(titleId);
-            } catch (Resources.NotFoundException nfe) {
-                Slog.e(TAG, "Could not resolve string resource id " + titleId);
+        if (mSuppliedDialogInfo != null) {
+            final int titleId = mSuppliedDialogInfo.getTitleResId();
+            final String title = mSuppliedDialogInfo.getTitle();
+            if (titleId != ID_NULL && mSuspendingAppResources != null) {
+                try {
+                    return mSuspendingAppResources.getString(titleId);
+                } catch (Resources.NotFoundException nfe) {
+                    Slog.e(TAG, "Could not resolve string resource id " + titleId);
+                }
+            } else if (title != null) {
+                return title;
             }
         }
         return getString(R.string.app_suspended_title);
@@ -159,13 +163,17 @@
                 Slog.w(TAG, "Unknown neutral button action: " + mNeutralButtonAction);
                 return null;
         }
-        final int buttonTextId = (mSuppliedDialogInfo != null)
-                ? mSuppliedDialogInfo.getNeutralButtonTextResId() : ID_NULL;
-        if (buttonTextId != ID_NULL && mSuspendingAppResources != null) {
-            try {
-                return mSuspendingAppResources.getString(buttonTextId);
-            } catch (Resources.NotFoundException nfe) {
-                Slog.e(TAG, "Could not resolve string resource id " + buttonTextId);
+        if (mSuppliedDialogInfo != null) {
+            final int buttonTextId = mSuppliedDialogInfo.getNeutralButtonTextResId();
+            final String buttonText = mSuppliedDialogInfo.getNeutralButtonText();
+            if (buttonTextId != ID_NULL && mSuspendingAppResources != null) {
+                try {
+                    return mSuspendingAppResources.getString(buttonTextId);
+                } catch (Resources.NotFoundException nfe) {
+                    Slog.e(TAG, "Could not resolve string resource id " + buttonTextId);
+                }
+            } else if (buttonText != null) {
+                return buttonText;
             }
         }
         return getString(defaultButtonTextId);
diff --git a/core/java/com/android/internal/compat/CompatibilityOverrideConfig.java b/core/java/com/android/internal/compat/CompatibilityOverrideConfig.java
index 1c222a7..9a02b7b 100644
--- a/core/java/com/android/internal/compat/CompatibilityOverrideConfig.java
+++ b/core/java/com/android/internal/compat/CompatibilityOverrideConfig.java
@@ -40,8 +40,7 @@
         overrides = new HashMap<>();
         for (int i = 0; i < keyCount; i++) {
             long key = in.readLong();
-            PackageOverride override = in.readParcelable(PackageOverride.class.getClassLoader());
-            overrides.put(key, override);
+            overrides.put(key, PackageOverride.createFromParcel(in));
         }
     }
 
@@ -55,7 +54,7 @@
         dest.writeInt(overrides.size());
         for (Long key : overrides.keySet()) {
             dest.writeLong(key);
-            dest.writeParcelable(overrides.get(key), 0);
+            overrides.get(key).writeToParcel(dest);
         }
     }
 
diff --git a/core/java/com/android/internal/compat/IPlatformCompat.aidl b/core/java/com/android/internal/compat/IPlatformCompat.aidl
index 249c134..afcd0b0 100644
--- a/core/java/com/android/internal/compat/IPlatformCompat.aidl
+++ b/core/java/com/android/internal/compat/IPlatformCompat.aidl
@@ -151,15 +151,23 @@
     void setOverrides(in CompatibilityChangeConfig overrides, in String packageName);
 
     /**
-     * Adds overrides to compatibility changes.
+     * Adds overrides to compatibility changes on release builds.
      *
-     * <p>Kills the app to allow the changes to take effect.
+     * <p>The caller to this API needs to hold
+     * {@code android.permission.OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD} and all change ids
+     * in {@code overrides} need to annotated with {@link android.compat.annotation.Overridable}.
+     *
+     * A release build in this definition means that {@link android.os.Build#IS_DEBUGGABLE} needs to
+     * be {@code false}.
+     *
+     * <p>Note that this does not kill the app, and therefore overrides read from the app process
+     * will not be updated. Overrides read from the system process do take effect.
      *
      * @param overrides   parcelable containing the compat change overrides to be applied
      * @param packageName the package name of the app whose changes will be overridden
      * @throws SecurityException if overriding changes is not permitted
      */
-    void setOverridesFromInstaller(in CompatibilityOverrideConfig overrides, in String packageName);
+    void setOverridesOnReleaseBuilds(in CompatibilityOverrideConfig overrides, in String packageName);
 
     /**
      * Adds overrides to compatibility changes.
diff --git a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
index 52801fa..c7a36ee 100644
--- a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
+++ b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
@@ -130,12 +130,6 @@
     // Flags related to media notifications
 
     /**
-     * (boolean) If {@code true}, enables the seekbar in compact media notifications.
-     */
-    public static final String COMPACT_MEDIA_SEEKBAR_ENABLED =
-            "compact_media_notification_seekbar_enabled";
-
-    /**
      * (int) Maximum number of days to retain the salt for hashing direct share targets in logging
      */
     public static final String HASH_SALT_MAX_DAYS = "hash_salt_max_days";
@@ -380,11 +374,6 @@
      */
     public static final String SCREENSHOT_CORNER_FLOW = "enable_screenshot_corner_flow";
 
-    /**
-     * (boolean) Whether scrolling screenshots are enabled.
-     */
-    public static final String SCREENSHOT_SCROLLING_ENABLED = "enable_screenshot_scrolling";
-
     // Flags related to Nav Bar
 
     /**
@@ -415,6 +404,12 @@
     public static final String CHOOSER_TARGET_RANKING_ENABLED = "chooser_target_ranking_enabled";
 
     /**
+     * (boolean) Whether dark launch of remote prediction service is enabled.
+     */
+    public static final String DARK_LAUNCH_REMOTE_PREDICTION_SERVICE_ENABLED =
+            "dark_launch_remote_prediction_service_enabled";
+
+    /**
      * (boolean) Whether to enable pinch resizing for PIP.
      */
     public static final String PIP_PINCH_RESIZE = "pip_pinch_resize";
@@ -473,6 +468,14 @@
      */
     public static final String SHARE_USE_SERVICE_TARGETS = "share_use_service_targets";
 
+    /**
+     * (boolean) If true, SysUI provides guardrails for app usage of Direct Share by enforcing
+     * limits on number of targets per app & adjusting scores for apps providing many targets. If
+     * false, this step is skipped. This should be true unless the ranking provider configured by
+     * [some other flag] is expected to manage these incentives.
+     */
+    public static final String APPLY_SHARING_APP_LIMITS_IN_SYSUI =
+            "apply_sharing_app_limits_in_sysui";
 
     /*
      * (long) The duration that the home button must be pressed before triggering Assist
diff --git a/core/java/com/android/internal/display/BrightnessSynchronizer.java b/core/java/com/android/internal/display/BrightnessSynchronizer.java
index fae5862..6776c27 100644
--- a/core/java/com/android/internal/display/BrightnessSynchronizer.java
+++ b/core/java/com/android/internal/display/BrightnessSynchronizer.java
@@ -20,6 +20,7 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.database.ContentObserver;
+import android.hardware.display.DisplayManager;
 import android.net.Uri;
 import android.os.Handler;
 import android.os.Looper;
@@ -28,6 +29,7 @@
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.util.MathUtils;
+import android.view.Display;
 
 import java.util.LinkedList;
 import java.util.Queue;
@@ -52,6 +54,7 @@
     // This value is approximately 1/3 of the smallest possible brightness value.
     public static final float EPSILON = 0.001f;
 
+    private DisplayManager mDisplayManager;
     private final Context mContext;
 
     private final Queue<Object> mWriteHistory = new LinkedList<>();
@@ -87,11 +90,15 @@
      * value, if float is invalid. If both are invalid, use default float value from config.
      */
     public void startSynchronizing() {
+        if (mDisplayManager == null) {
+            mDisplayManager = mContext.getSystemService(DisplayManager.class);
+        }
+
         final BrightnessSyncObserver brightnessSyncObserver;
         brightnessSyncObserver = new BrightnessSyncObserver(mHandler);
         brightnessSyncObserver.startObserving();
 
-        final float currentFloatBrightness = getScreenBrightnessFloat(mContext);
+        final float currentFloatBrightness = getScreenBrightnessFloat();
         final int currentIntBrightness = getScreenBrightnessInt(mContext);
 
         if (!Float.isNaN(currentFloatBrightness)) {
@@ -101,9 +108,7 @@
         } else {
             final float defaultBrightness = mContext.getResources().getFloat(
                     com.android.internal.R.dimen.config_screenBrightnessSettingDefaultFloat);
-            Settings.System.putFloatForUser(mContext.getContentResolver(),
-                    Settings.System.SCREEN_BRIGHTNESS_FLOAT, defaultBrightness,
-                    UserHandle.USER_CURRENT);
+            mDisplayManager.setBrightness(Display.DEFAULT_DISPLAY, defaultBrightness);
 
         }
     }
@@ -135,7 +140,7 @@
     /**
      * Translates specified value from the float brightness system to the int brightness system,
      * given the min/max of each range.  Accounts for special values such as OFF and invalid values.
-     * Value returned as a float privimite (to preserve precision), but is a value within the
+     * Value returned as a float primitive (to preserve precision), but is a value within the
      * int-system range.
      */
     public static float brightnessFloatToIntRange(float brightnessFloat) {
@@ -152,10 +157,8 @@
         }
     }
 
-    private static float getScreenBrightnessFloat(Context context) {
-        return Settings.System.getFloatForUser(context.getContentResolver(),
-                Settings.System.SCREEN_BRIGHTNESS_FLOAT, PowerManager.BRIGHTNESS_INVALID_FLOAT,
-                UserHandle.USER_CURRENT);
+    private float getScreenBrightnessFloat() {
+        return mDisplayManager.getBrightness(Display.DEFAULT_DISPLAY);
     }
 
     private static int getScreenBrightnessInt(Context context) {
@@ -184,9 +187,7 @@
             float newBrightnessFloat = brightnessIntToFloat(value);
             mWriteHistory.offer(newBrightnessFloat);
             mPreferredSettingValue = newBrightnessFloat;
-            Settings.System.putFloatForUser(mContext.getContentResolver(),
-                    Settings.System.SCREEN_BRIGHTNESS_FLOAT, newBrightnessFloat,
-                    UserHandle.USER_CURRENT);
+            mDisplayManager.setBrightness(Display.DEFAULT_DISPLAY, newBrightnessFloat);
         }
     }
 
@@ -255,7 +256,7 @@
                 mHandler.removeMessages(MSG_UPDATE_FLOAT);
                 mHandler.obtainMessage(MSG_UPDATE_FLOAT, currentBrightness, 0).sendToTarget();
             } else if (BRIGHTNESS_FLOAT_URI.equals(uri)) {
-                float currentFloat = getScreenBrightnessFloat(mContext);
+                float currentFloat = getScreenBrightnessFloat();
                 int toSend = Float.floatToIntBits(currentFloat);
                 mHandler.removeMessages(MSG_UPDATE_INT);
                 mHandler.obtainMessage(MSG_UPDATE_INT, toSend, 0).sendToTarget();
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 7f87885..b0920b0 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -89,6 +89,7 @@
 import android.util.Printer;
 import android.util.Slog;
 import android.util.SparseArray;
+import android.util.SparseDoubleArray;
 import android.util.SparseIntArray;
 import android.util.SparseLongArray;
 import android.util.TimeUtils;
@@ -169,7 +170,7 @@
     private static final int MAGIC = 0xBA757475; // 'BATSTATS'
 
     // Current on-disk Parcel version
-    static final int VERSION = 195;
+    static final int VERSION = 196;
 
     // The maximum number of names wakelocks we will keep track of
     // per uid; once the limit is reached, we batch the remaining wakelocks
@@ -1013,6 +1014,9 @@
     @Nullable BluetoothPowerCalculator mBluetoothPowerCalculator = null;
     /** Cpu Power calculator for attributing measured cpu charge consumption to uids */
     @Nullable CpuPowerCalculator mCpuPowerCalculator = null;
+    /** Mobile Radio Power calculator for attributing measured radio charge consumption to uids */
+    @Nullable
+    MobileRadioPowerCalculator mMobileRadioPowerCalculator = null;
     /** Wifi Power calculator for attributing measured wifi charge consumption to uids */
     @Nullable WifiPowerCalculator mWifiPowerCalculator = null;
 
@@ -1194,6 +1198,7 @@
 
     public BatteryStatsImpl(Clocks clocks) {
         init(clocks);
+        mStartClockTimeMs = System.currentTimeMillis();
         mStatsFile = null;
         mCheckinFile = null;
         mDailyFile = null;
@@ -6981,6 +6986,16 @@
     }
 
     @Override
+    public long getGnssMeasuredBatteryConsumptionUC() {
+        return getPowerBucketConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_GNSS);
+    }
+
+    @Override
+    public long getMobileRadioMeasuredBatteryConsumptionUC() {
+        return getPowerBucketConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_MOBILE_RADIO);
+    }
+
+    @Override
     public long getScreenOnMeasuredBatteryConsumptionUC() {
         return getPowerBucketConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_SCREEN_ON);
     }
@@ -7840,6 +7855,16 @@
         }
 
         @Override
+        public long getGnssMeasuredBatteryConsumptionUC() {
+            return getMeasuredBatteryConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_GNSS);
+        }
+
+        @Override
+        public long getMobileRadioMeasuredBatteryConsumptionUC() {
+            return getMeasuredBatteryConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_MOBILE_RADIO);
+        }
+
+        @Override
         public long getScreenOnMeasuredBatteryConsumptionUC() {
             return getMeasuredBatteryConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_SCREEN_ON);
         }
@@ -7878,6 +7903,27 @@
             return (topTimeUs < fgTimeUs) ? topTimeUs : fgTimeUs;
         }
 
+
+        /**
+         * Gets the uid's time spent using the GNSS since last marked. Also sets the mark time for
+         * the GNSS timer.
+         */
+        private long markGnssTimeUs(long elapsedRealtimeMs) {
+            final Sensor sensor = mSensorStats.get(Sensor.GPS);
+            if (sensor == null) {
+                return 0;
+            }
+
+            final StopwatchTimer timer = sensor.mTimer;
+            if (timer == null) {
+                return 0;
+            }
+
+            final long gnssTimeUs = timer.getTimeSinceMarkLocked(elapsedRealtimeMs * 1000);
+            timer.setMark(elapsedRealtimeMs);
+            return gnssTimeUs;
+        }
+
         public StopwatchTimer createAudioTurnedOnTimerLocked() {
             if (mAudioTurnedOnTimer == null) {
                 mAudioTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, AUDIO_TURNED_ON,
@@ -11821,7 +11867,7 @@
      * Distribute Cell radio energy info and network traffic to apps.
      */
     public void noteModemControllerActivity(@Nullable final ModemActivityInfo activityInfo,
-            long elapsedRealtimeMs, long uptimeMs) {
+            final long consumedChargeUC, long elapsedRealtimeMs, long uptimeMs) {
         if (DEBUG_ENERGY) {
             Slog.d(TAG, "Updating mobile radio stats with " + activityInfo);
         }
@@ -11852,6 +11898,16 @@
                 return;
             }
 
+            final SparseDoubleArray uidEstimatedConsumptionMah;
+            if (consumedChargeUC > 0 && mMobileRadioPowerCalculator != null
+                    && mGlobalMeasuredEnergyStats != null) {
+                mGlobalMeasuredEnergyStats.updateStandardBucket(
+                        MeasuredEnergyStats.POWER_BUCKET_MOBILE_RADIO, consumedChargeUC);
+                uidEstimatedConsumptionMah = new SparseDoubleArray();
+            } else {
+                uidEstimatedConsumptionMah = null;
+            }
+
             if (deltaInfo != null) {
                 mHasModemReporting = true;
                 mModemActivity.getIdleTimeCounter().addCountLocked(
@@ -11896,7 +11952,7 @@
                     mTmpRailStats.resetCellularTotalEnergyUsed();
                 }
             }
-            long radioTimeUs = mMobileRadioActivePerAppTimer.getTimeSinceMarkLocked(
+            long totalAppRadioTimeUs = mMobileRadioActivePerAppTimer.getTimeSinceMarkLocked(
                     elapsedRealtimeMs * 1000);
             mMobileRadioActivePerAppTimer.setMark(elapsedRealtimeMs);
 
@@ -11956,12 +12012,21 @@
 
                         // Distribute total radio active time in to this app.
                         final long appPackets = entry.rxPackets + entry.txPackets;
-                        final long appRadioTimeUs = (radioTimeUs * appPackets) / totalPackets;
+                        final long appRadioTimeUs =
+                                (totalAppRadioTimeUs * appPackets) / totalPackets;
                         u.noteMobileRadioActiveTimeLocked(appRadioTimeUs);
 
+                        // Distribute measured mobile radio charge consumption based on app radio
+                        // active time
+                        if (uidEstimatedConsumptionMah != null) {
+                            uidEstimatedConsumptionMah.add(u.getUid(),
+                                    mMobileRadioPowerCalculator.calcPowerFromRadioActiveDurationMah(
+                                            appRadioTimeUs / 1000));
+                        }
+
                         // Remove this app from the totals, so that we don't lose any time
                         // due to rounding.
-                        radioTimeUs -= appRadioTimeUs;
+                        totalAppRadioTimeUs -= appRadioTimeUs;
                         totalPackets -= appPackets;
 
                         if (deltaInfo != null) {
@@ -11986,12 +12051,51 @@
                     }
                 }
 
-                if (radioTimeUs > 0) {
+                if (totalAppRadioTimeUs > 0) {
                     // Whoops, there is some radio time we can't blame on an app!
-                    mMobileRadioActiveUnknownTime.addCountLocked(radioTimeUs);
+                    mMobileRadioActiveUnknownTime.addCountLocked(totalAppRadioTimeUs);
                     mMobileRadioActiveUnknownCount.addCountLocked(1);
                 }
 
+
+                // Update the MeasuredEnergyStats information.
+                if (uidEstimatedConsumptionMah != null) {
+                    double totalEstimatedConsumptionMah = 0.0;
+
+                    // Estimate total active radio power consumption since last mark.
+                    final long totalRadioTimeMs = mMobileRadioActiveTimer.getTimeSinceMarkLocked(
+                            elapsedRealtimeMs * 1000) / 1000;
+                    mMobileRadioActiveTimer.setMark(elapsedRealtimeMs);
+                    totalEstimatedConsumptionMah +=
+                            mMobileRadioPowerCalculator.calcPowerFromRadioActiveDurationMah(
+                                    totalRadioTimeMs);
+
+                    // Estimate idle power consumption at each signal strength level
+                    final int numSignalStrengthLevels = mPhoneSignalStrengthsTimer.length;
+                    for (int strengthLevel = 0; strengthLevel < numSignalStrengthLevels;
+                            strengthLevel++) {
+                        final long strengthLevelDurationMs =
+                                mPhoneSignalStrengthsTimer[strengthLevel].getTimeSinceMarkLocked(
+                                        elapsedRealtimeMs * 1000) / 1000;
+                        mPhoneSignalStrengthsTimer[strengthLevel].setMark(elapsedRealtimeMs);
+
+                        totalEstimatedConsumptionMah +=
+                                mMobileRadioPowerCalculator.calcIdlePowerAtSignalStrengthMah(
+                                        strengthLevelDurationMs, strengthLevel);
+                    }
+
+                    // Estimate total active radio power consumption since last mark.
+                    final long scanTimeMs = mPhoneSignalScanningTimer.getTimeSinceMarkLocked(
+                            elapsedRealtimeMs * 1000) / 1000;
+                    mPhoneSignalScanningTimer.setMark(elapsedRealtimeMs);
+                    totalEstimatedConsumptionMah +=
+                            mMobileRadioPowerCalculator.calcScanTimePowerMah(scanTimeMs);
+
+                    distributeEnergyToUidsLocked(MeasuredEnergyStats.POWER_BUCKET_MOBILE_RADIO,
+                            consumedChargeUC, uidEstimatedConsumptionMah,
+                            totalEstimatedConsumptionMah);
+                }
+
                 mNetworkStatsPool.release(delta);
                 delta = null;
             }
@@ -12451,7 +12555,7 @@
         // 'double counted' and will simply exceed the realtime that elapsed.
         // If multidisplay becomes a reality, this is probably more reasonable than pooling.
 
-        // On the first pass, collect total time since mark so that we can normalize power.
+        // Collect total time since mark so that we can normalize power.
         final SparseDoubleArray fgTimeUsArray = new SparseDoubleArray();
         final long elapsedRealtimeUs = elapsedRealtimeMs * 1000;
         // TODO(b/175726779): Update and optimize the algorithm (e.g. avoid iterating over ALL uids)
@@ -12466,6 +12570,50 @@
     }
 
     /**
+     * Accumulate GNSS charge consumption and distribute it to the correct state and the apps.
+     *
+     * @param chargeUC amount of charge (microcoulombs) used by GNSS since this was last called.
+     */
+    @GuardedBy("this")
+    public void updateGnssMeasuredEnergyStatsLocked(long chargeUC, long elapsedRealtimeMs) {
+        if (DEBUG_ENERGY) Slog.d(TAG, "Updating gnss stats: " + chargeUC);
+        if (mGlobalMeasuredEnergyStats == null) {
+            return;
+        }
+
+        if (!mOnBatteryInternal || chargeUC <= 0) {
+            // There's nothing further to update.
+            return;
+        }
+        if (mIgnoreNextExternalStats) {
+            // Although under ordinary resets we won't get here, and typically a new sync will
+            // happen right after the reset, strictly speaking we need to set all mark times to now.
+            final int uidStatsSize = mUidStats.size();
+            for (int i = 0; i < uidStatsSize; i++) {
+                final Uid uid = mUidStats.valueAt(i);
+                uid.markGnssTimeUs(elapsedRealtimeMs);
+            }
+            return;
+        }
+
+        mGlobalMeasuredEnergyStats.updateStandardBucket(MeasuredEnergyStats.POWER_BUCKET_GNSS,
+                chargeUC);
+
+        // Collect the per uid time since mark so that we can normalize power.
+        final SparseDoubleArray gnssTimeUsArray = new SparseDoubleArray();
+        // TODO(b/175726779): Update and optimize the algorithm (e.g. avoid iterating over ALL uids)
+        final int uidStatsSize = mUidStats.size();
+        for (int i = 0; i < uidStatsSize; i++) {
+            final Uid uid = mUidStats.valueAt(i);
+            final long gnssTimeUs = uid.markGnssTimeUs(elapsedRealtimeMs);
+            if (gnssTimeUs == 0) continue;
+            gnssTimeUsArray.put(uid.getUid(), (double) gnssTimeUs);
+        }
+        distributeEnergyToUidsLocked(MeasuredEnergyStats.POWER_BUCKET_GNSS, chargeUC,
+                gnssTimeUsArray, 0);
+    }
+
+    /**
      * Accumulate Custom power bucket charge, globally and for each app.
      *
      * @param totalChargeUC charge (microcoulombs) used for this bucket since this was last called.
@@ -12548,81 +12696,6 @@
     }
 
     /**
-     * SparseDoubleArray map integers to doubles.
-     * Its implementation is the same as that of {@link SparseLongArray}; see there for details.
-     *
-     * @see SparseLongArray
-     */
-    private static class SparseDoubleArray {
-        /**
-         * The int->double map, but storing the doubles as longs using
-         * {@link Double.doubleToRawLongBits(double)}.
-         */
-        private final SparseLongArray mValues = new SparseLongArray();
-
-        /**
-         * Gets the double mapped from the specified key, or <code>0</code>
-         * if no such mapping has been made.
-         */
-        public double get(int key) {
-            if (mValues.indexOfKey(key) >= 0) {
-                return Double.longBitsToDouble(mValues.get(key));
-            }
-            return 0;
-        }
-
-        /**
-         * Adds a mapping from the specified key to the specified value,
-         * replacing the previous mapping from the specified key if there
-         * was one.
-         */
-        public void put(int key, double value) {
-            mValues.put(key, Double.doubleToRawLongBits(value));
-        }
-
-        /**
-         * Adds a mapping from the specified key to the specified value,
-         * <b>adding</b> to the previous mapping from the specified key if there
-         * was one.
-         */
-        public void add(int key, double summand) {
-            final double oldValue = get(key);
-            put(key, oldValue + summand);
-        }
-
-        /**
-         * Returns the number of key-value mappings that this SparseDoubleArray
-         * currently stores.
-         */
-        public int size() {
-            return mValues.size();
-        }
-
-        /**
-         * Given an index in the range <code>0...size()-1</code>, returns
-         * the key from the <code>index</code>th key-value mapping that this
-         * SparseDoubleArray stores.
-         *
-         * @see SparseLongArray#keyAt(int)
-         */
-        public int keyAt(int index) {
-            return mValues.keyAt(index);
-        }
-
-        /**
-         * Given an index in the range <code>0...size()-1</code>, returns
-         * the value from the <code>index</code>th key-value mapping that this
-         * SparseDoubleArray stores.
-         *
-         * @see SparseLongArray#valueAt(int)
-         */
-        public double valueAt(int index) {
-            return Double.longBitsToDouble(mValues.valueAt(index));
-        }
-
-    }
-
-    /**
      * Read and record Rail Energy data.
      */
     public void updateRailStatsLocked() {
@@ -14467,6 +14540,9 @@
             if (supportedStandardBuckets[MeasuredEnergyStats.POWER_BUCKET_CPU]) {
                 mCpuPowerCalculator = new CpuPowerCalculator(mPowerProfile);
             }
+            if (supportedStandardBuckets[MeasuredEnergyStats.POWER_BUCKET_MOBILE_RADIO]) {
+                mMobileRadioPowerCalculator = new MobileRadioPowerCalculator(mPowerProfile);
+            }
             if (supportedStandardBuckets[MeasuredEnergyStats.POWER_BUCKET_WIFI]) {
                 mWifiPowerCalculator = new WifiPowerCalculator(mPowerProfile);
             }
@@ -16598,6 +16674,8 @@
         // Pull the clock time.  This may update the time and make a new history entry
         // if we had originally pulled a time before the RTC was set.
         getStartClockTime();
+
+        updateSystemServiceCallStats();
     }
 
     public void dumpLocked(Context context, PrintWriter pw, int flags, int reqUid, long histStart) {
diff --git a/core/java/com/android/internal/os/BatteryUsageStatsProvider.java b/core/java/com/android/internal/os/BatteryUsageStatsProvider.java
index 6dd612e..f8ae0c1 100644
--- a/core/java/com/android/internal/os/BatteryUsageStatsProvider.java
+++ b/core/java/com/android/internal/os/BatteryUsageStatsProvider.java
@@ -21,9 +21,7 @@
 import android.os.BatteryStats;
 import android.os.BatteryUsageStats;
 import android.os.BatteryUsageStatsQuery;
-import android.os.Bundle;
 import android.os.UidBatteryConsumer;
-import android.os.UserHandle;
 import android.util.SparseArray;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -88,29 +86,31 @@
     }
 
     /**
+     * Returns true if the last update was too long ago for the tolerances specified
+     * by the supplied queries.
+     */
+    public boolean shouldUpdateStats(List<BatteryUsageStatsQuery> queries,
+            long lastUpdateTimeStampMs) {
+        long allowableStatsAge = Long.MAX_VALUE;
+        for (int i = queries.size() - 1; i >= 0; i--) {
+            BatteryUsageStatsQuery query = queries.get(i);
+            allowableStatsAge = Math.min(allowableStatsAge, query.getMaxStatsAge());
+        }
+
+        return mStats.mClocks.elapsedRealtime() - lastUpdateTimeStampMs > allowableStatsAge;
+    }
+
+    /**
      * Returns snapshots of battery attribution data, one per supplied query.
      */
     public List<BatteryUsageStats> getBatteryUsageStats(List<BatteryUsageStatsQuery> queries) {
-
-        // TODO(b/174186345): instead of BatteryStatsHelper, use PowerCalculators directly.
-        final BatteryStatsHelper batteryStatsHelper = new BatteryStatsHelper(mContext,
-                false /* collectBatteryBroadcast */);
-        batteryStatsHelper.create((Bundle) null);
-        final List<UserHandle> users = new ArrayList<>();
-        for (int i = 0; i < queries.size(); i++) {
-            BatteryUsageStatsQuery query = queries.get(i);
-            for (int userId : query.getUserIds()) {
-                UserHandle userHandle = UserHandle.of(userId);
-                if (!users.contains(userHandle)) {
-                    users.add(userHandle);
-                }
-            }
-        }
-        batteryStatsHelper.refreshStats(BatteryStats.STATS_SINCE_CHARGED, users);
-
         ArrayList<BatteryUsageStats> results = new ArrayList<>(queries.size());
-        for (int i = 0; i < queries.size(); i++) {
-            results.add(getBatteryUsageStats(queries.get(i)));
+        synchronized (mStats) {
+            mStats.prepareForDumpLocked();
+
+            for (int i = 0; i < queries.size(); i++) {
+                results.add(getBatteryUsageStats(queries.get(i)));
+            }
         }
         return results;
     }
@@ -134,7 +134,7 @@
 
         final BatteryUsageStats.Builder batteryUsageStatsBuilder =
                 new BatteryUsageStats.Builder(customPowerComponentCount, customTimeComponentCount)
-                        .setStatsStartRealtime(mStats.getStatsStartRealtime() / 1000);
+                        .setStatsStartTimestamp(mStats.getStartClockTime());
 
         SparseArray<? extends BatteryStats.Uid> uidStats = mStats.getUidStats();
         for (int i = uidStats.size() - 1; i >= 0; i--) {
diff --git a/core/java/com/android/internal/os/BluetoothPowerCalculator.java b/core/java/com/android/internal/os/BluetoothPowerCalculator.java
index db14034..75a9813 100644
--- a/core/java/com/android/internal/os/BluetoothPowerCalculator.java
+++ b/core/java/com/android/internal/os/BluetoothPowerCalculator.java
@@ -84,16 +84,16 @@
 
         // Subtract what the apps used, but clamp to 0.
         final long systemComponentDurationMs = Math.max(0, systemDurationMs - total.durationMs);
-        final double systemComponentPowerMah = Math.max(0, systemPowerMah - total.powerMah);
-        if (DEBUG && systemComponentPowerMah != 0) {
+        if (DEBUG) {
             Log.d(TAG, "Bluetooth active: time=" + (systemComponentDurationMs)
-                    + " power=" + formatCharge(systemComponentPowerMah));
+                    + " power=" + formatCharge(systemPowerMah));
         }
         systemBatteryConsumerBuilder
                 .setUsageDurationMillis(BatteryConsumer.TIME_COMPONENT_BLUETOOTH,
                         systemComponentDurationMs)
                 .setConsumedPower(BatteryConsumer.POWER_COMPONENT_BLUETOOTH,
-                        systemComponentPowerMah);
+                        Math.max(systemPowerMah, total.powerMah))
+                .setPowerConsumedByApps(total.powerMah);
     }
 
     private void calculateApp(UidBatteryConsumer.Builder app, PowerAndDuration total,
diff --git a/core/java/com/android/internal/os/GnssPowerCalculator.java b/core/java/com/android/internal/os/GnssPowerCalculator.java
index df25cda..97c4fd8 100644
--- a/core/java/com/android/internal/os/GnssPowerCalculator.java
+++ b/core/java/com/android/internal/os/GnssPowerCalculator.java
@@ -61,7 +61,17 @@
             long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query,
             double averageGnssPowerMa) {
         final long durationMs = computeDuration(u, rawRealtimeUs, BatteryStats.STATS_SINCE_CHARGED);
-        double powerMah = computePower(durationMs, averageGnssPowerMa);
+
+        final long measuredChargeUC = u.getGnssMeasuredBatteryConsumptionUC();
+        final boolean isMeasuredPowerAvailable = !query.shouldForceUsePowerProfileModel()
+                && measuredChargeUC != BatteryStats.POWER_DATA_UNAVAILABLE;
+
+        final double powerMah;
+        if (isMeasuredPowerAvailable) {
+            powerMah = uCtoMah(measuredChargeUC);
+        } else {
+            powerMah = computePower(durationMs, averageGnssPowerMa);
+        }
         app.setUsageDurationMillis(BatteryConsumer.TIME_COMPONENT_GNSS, durationMs)
                 .setConsumedPower(BatteryConsumer.POWER_COMPONENT_GNSS, powerMah);
     }
@@ -73,15 +83,25 @@
         for (int i = sippers.size() - 1; i >= 0; i--) {
             final BatterySipper app = sippers.get(i);
             if (app.drainType == BatterySipper.DrainType.APP) {
-                calculateApp(app, app.uidObj, rawRealtimeUs, statsType, averageGnssPowerMa);
+                calculateApp(app, app.uidObj, rawRealtimeUs, statsType, averageGnssPowerMa, false);
             }
         }
     }
 
     protected void calculateApp(BatterySipper app, BatteryStats.Uid u, long rawRealtimeUs,
-            int statsType, double averageGnssPowerMa) {
+            int statsType, double averageGnssPowerMa, boolean shouldForceUsePowerProfileModel) {
         final long durationMs = computeDuration(u, rawRealtimeUs, BatteryStats.STATS_SINCE_CHARGED);
-        double powerMah = computePower(durationMs, averageGnssPowerMa);
+
+        final long measuredChargeUC = u.getGnssMeasuredBatteryConsumptionUC();
+        final boolean isMeasuredPowerAvailable = shouldForceUsePowerProfileModel
+                && measuredChargeUC != BatteryStats.POWER_DATA_UNAVAILABLE;
+
+        final double powerMah;
+        if (isMeasuredPowerAvailable) {
+            powerMah = uCtoMah(measuredChargeUC);
+        } else {
+            powerMah = computePower(durationMs, averageGnssPowerMa);
+        }
 
         app.gpsTimeMs = durationMs;
         app.gpsPowerMah = powerMah;
diff --git a/core/java/com/android/internal/os/MobileRadioPowerCalculator.java b/core/java/com/android/internal/os/MobileRadioPowerCalculator.java
index 22001d4..f6ef30c 100644
--- a/core/java/com/android/internal/os/MobileRadioPowerCalculator.java
+++ b/core/java/com/android/internal/os/MobileRadioPowerCalculator.java
@@ -42,8 +42,9 @@
 
     private static class PowerAndDuration {
         public long durationMs;
-        public double powerMah;
+        public double remainingPowerMah;
         public long totalAppDurationMs;
+        public double totalAppPowerMah;
         public long signalDurationMs;
         public long noCoverageDurationMs;
     }
@@ -96,26 +97,33 @@
         for (int i = uidBatteryConsumerBuilders.size() - 1; i >= 0; i--) {
             final UidBatteryConsumer.Builder app = uidBatteryConsumerBuilders.valueAt(i);
             final BatteryStats.Uid uid = app.getBatteryStatsUid();
-            calculateApp(app, uid, powerPerPacketMah, total);
+            calculateApp(app, uid, powerPerPacketMah, total,
+                    query.shouldForceUsePowerProfileModel());
         }
 
-        calculateRemaining(total, batteryStats, rawRealtimeUs);
+        calculateRemaining(total, batteryStats, rawRealtimeUs,
+                query.shouldForceUsePowerProfileModel());
 
-        if (total.powerMah != 0) {
+        if (total.remainingPowerMah != 0 || total.totalAppPowerMah != 0) {
             builder.getOrCreateSystemBatteryConsumerBuilder(
                     SystemBatteryConsumer.DRAIN_TYPE_MOBILE_RADIO)
                     .setUsageDurationMillis(BatteryConsumer.TIME_COMPONENT_MOBILE_RADIO,
                             total.durationMs)
-                    .setConsumedPower(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO, total.powerMah);
+                    .setConsumedPower(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO,
+                            total.remainingPowerMah + total.totalAppPowerMah)
+                    .setPowerConsumedByApps(total.totalAppPowerMah);
         }
     }
 
     private void calculateApp(UidBatteryConsumer.Builder app, BatteryStats.Uid u,
-            double powerPerPacketMah, PowerAndDuration total) {
+            double powerPerPacketMah, PowerAndDuration total,
+            boolean shouldForceUsePowerProfileModel) {
         final long radioActiveDurationMs = calculateDuration(u, BatteryStats.STATS_SINCE_CHARGED);
         total.totalAppDurationMs += radioActiveDurationMs;
 
-        final double powerMah = calculatePower(u, powerPerPacketMah, radioActiveDurationMs);
+        final double powerMah = calculatePower(u, powerPerPacketMah, radioActiveDurationMs,
+                shouldForceUsePowerProfileModel);
+        total.totalAppPowerMah += powerMah;
 
         app.setUsageDurationMillis(BatteryConsumer.TIME_COMPONENT_MOBILE_RADIO,
                 radioActiveDurationMs)
@@ -132,20 +140,20 @@
             final BatterySipper app = sippers.get(i);
             if (app.drainType == BatterySipper.DrainType.APP) {
                 final BatteryStats.Uid u = app.uidObj;
-                calculateApp(app, u, statsType, mobilePowerPerPacket, total);
+                calculateApp(app, u, statsType, mobilePowerPerPacket, total, false);
             }
         }
 
         BatterySipper radio = new BatterySipper(BatterySipper.DrainType.CELL, null, 0);
-        calculateRemaining(total, batteryStats, rawRealtimeUs);
-        if (total.powerMah != 0) {
+        calculateRemaining(total, batteryStats, rawRealtimeUs, false);
+        if (total.remainingPowerMah != 0) {
             if (total.signalDurationMs != 0) {
                 radio.noCoveragePercent =
                         total.noCoverageDurationMs * 100.0 / total.signalDurationMs;
             }
             radio.mobileActive = total.durationMs;
             radio.mobileActiveCount = batteryStats.getMobileRadioActiveUnknownCount(statsType);
-            radio.mobileRadioPowerMah = total.powerMah;
+            radio.mobileRadioPowerMah = total.remainingPowerMah;
             radio.sumPower();
         }
         if (radio.totalPowerMah > 0) {
@@ -154,9 +162,12 @@
     }
 
     private void calculateApp(BatterySipper app, BatteryStats.Uid u, int statsType,
-            double powerPerPacketMah, PowerAndDuration total) {
+            double powerPerPacketMah, PowerAndDuration total,
+            boolean shouldForceUsePowerProfileModel) {
         app.mobileActive = calculateDuration(u, statsType);
-        app.mobileRadioPowerMah = calculatePower(u, powerPerPacketMah, app.mobileActive);
+
+        app.mobileRadioPowerMah = calculatePower(u, powerPerPacketMah, app.mobileActive,
+                shouldForceUsePowerProfileModel);
         total.totalAppDurationMs += app.mobileActive;
 
         // Add cost of mobile traffic.
@@ -183,11 +194,19 @@
     }
 
     private double calculatePower(BatteryStats.Uid u, double powerPerPacketMah,
-            long radioActiveDurationMs) {
+            long radioActiveDurationMs, boolean shouldForceUsePowerProfileModel) {
+
+        final long measuredChargeUC = u.getMobileRadioMeasuredBatteryConsumptionUC();
+        final boolean isMeasuredPowerAvailable = !shouldForceUsePowerProfileModel
+                && measuredChargeUC != BatteryStats.POWER_DATA_UNAVAILABLE;
+        if (isMeasuredPowerAvailable) {
+            return uCtoMah(measuredChargeUC);
+        }
+
         if (radioActiveDurationMs > 0) {
             // We are tracking when the radio is up, so can use the active time to
             // determine power use.
-            return mActivePowerEstimator.calculatePower(radioActiveDurationMs);
+            return calcPowerFromRadioActiveDurationMah(radioActiveDurationMs);
         } else {
             // We are not tracking when the radio is up, so must approximate power use
             // based on the number of packets.
@@ -202,18 +221,29 @@
     }
 
     private void calculateRemaining(MobileRadioPowerCalculator.PowerAndDuration total,
-            BatteryStats batteryStats, long rawRealtimeUs) {
+            BatteryStats batteryStats, long rawRealtimeUs,
+            boolean shouldForceUsePowerProfileModel) {
         long signalTimeMs = 0;
         double powerMah = 0;
+
+        final long measuredChargeUC = batteryStats.getMobileRadioMeasuredBatteryConsumptionUC();
+        final boolean isMeasuredPowerAvailable = !shouldForceUsePowerProfileModel
+                && measuredChargeUC != BatteryStats.POWER_DATA_UNAVAILABLE;
+        if (isMeasuredPowerAvailable) {
+            powerMah = uCtoMah(measuredChargeUC);
+        }
+
         for (int i = 0; i < NUM_SIGNAL_STRENGTH_LEVELS; i++) {
             long strengthTimeMs = batteryStats.getPhoneSignalStrengthTime(i, rawRealtimeUs,
                     BatteryStats.STATS_SINCE_CHARGED) / 1000;
-            final double p = mIdlePowerEstimators[i].calculatePower(strengthTimeMs);
-            if (DEBUG && p != 0) {
-                Log.d(TAG, "Cell strength #" + i + ": time=" + strengthTimeMs + " power="
-                        + formatCharge(p));
+            if (!isMeasuredPowerAvailable) {
+                final double p = calcIdlePowerAtSignalStrengthMah(strengthTimeMs, i);
+                if (DEBUG && p != 0) {
+                    Log.d(TAG, "Cell strength #" + i + ": time=" + strengthTimeMs + " power="
+                            + formatCharge(p));
+                }
+                powerMah += p;
             }
-            powerMah += p;
             signalTimeMs += strengthTimeMs;
             if (i == 0) {
                 total.noCoverageDurationMs = strengthTimeMs;
@@ -222,29 +252,57 @@
 
         final long scanningTimeMs = batteryStats.getPhoneSignalScanningTime(rawRealtimeUs,
                 BatteryStats.STATS_SINCE_CHARGED) / 1000;
-        final double p = mScanPowerEstimator.calculatePower(scanningTimeMs);
-        if (DEBUG && p != 0) {
-            Log.d(TAG, "Cell radio scanning: time=" + scanningTimeMs + " power=" + formatCharge(p));
-        }
-        powerMah += p;
         long radioActiveTimeMs = batteryStats.getMobileRadioActiveTime(rawRealtimeUs,
                 BatteryStats.STATS_SINCE_CHARGED) / 1000;
         long remainingActiveTimeMs = radioActiveTimeMs - total.totalAppDurationMs;
-        if (remainingActiveTimeMs > 0) {
-            powerMah += mActivePowerEstimator.calculatePower(remainingActiveTimeMs);
+
+        if (!isMeasuredPowerAvailable) {
+            final double p = calcScanTimePowerMah(scanningTimeMs);
+            if (DEBUG && p != 0) {
+                Log.d(TAG, "Cell radio scanning: time=" + scanningTimeMs + " power=" + formatCharge(
+                        p));
+            }
+            powerMah += p;
+
+            if (remainingActiveTimeMs > 0) {
+                powerMah += calcPowerFromRadioActiveDurationMah(remainingActiveTimeMs);
+            }
         }
         total.durationMs = radioActiveTimeMs;
-        total.powerMah = powerMah;
+        total.remainingPowerMah = powerMah;
         total.signalDurationMs = signalTimeMs;
     }
 
     /**
+     * Calculates active radio power consumption (in milliamp-hours) from active radio duration.
+     */
+    public double calcPowerFromRadioActiveDurationMah(long radioActiveDurationMs) {
+        return mActivePowerEstimator.calculatePower(radioActiveDurationMs);
+    }
+
+    /**
+     * Calculates idle radio power consumption (in milliamp-hours) for time spent at a cell signal
+     * strength level.
+     * see {@link CellSignalStrength#getNumSignalStrengthLevels()}
+     */
+    public double calcIdlePowerAtSignalStrengthMah(long strengthTimeMs, int strengthLevel) {
+        return mIdlePowerEstimators[strengthLevel].calculatePower(strengthTimeMs);
+    }
+
+    /**
+     * Calculates radio scan power consumption (in milliamp-hours) from scan time.
+     */
+    public double calcScanTimePowerMah(long scanningTimeMs) {
+        return mScanPowerEstimator.calculatePower(scanningTimeMs);
+    }
+
+    /**
      * Return estimated power (in mAh) of sending or receiving a packet with the mobile radio.
      */
     private double getMobilePowerPerPacket(BatteryStats stats, long rawRealtimeUs, int statsType) {
         final long radioDataUptimeMs =
                 stats.getMobileRadioActiveTime(rawRealtimeUs, statsType) / 1000;
-        final double mobilePower = mActivePowerEstimator.calculatePower(radioDataUptimeMs);
+        final double mobilePower = calcPowerFromRadioActiveDurationMah(radioDataUptimeMs);
 
         final long mobileRx = stats.getNetworkActivityPackets(BatteryStats.NETWORK_MOBILE_RX_DATA,
                 statsType);
diff --git a/core/java/com/android/internal/os/ScreenPowerCalculator.java b/core/java/com/android/internal/os/ScreenPowerCalculator.java
index d94bb31..ad57444 100644
--- a/core/java/com/android/internal/os/ScreenPowerCalculator.java
+++ b/core/java/com/android/internal/os/ScreenPowerCalculator.java
@@ -66,11 +66,7 @@
                 batteryStats, rawRealtimeUs, BatteryStats.STATS_SINCE_CHARGED,
                 query.shouldForceUsePowerProfileModel());
 
-        builder.getOrCreateSystemBatteryConsumerBuilder(SystemBatteryConsumer.DRAIN_TYPE_SCREEN)
-                .setUsageDurationMillis(BatteryConsumer.TIME_COMPONENT_USAGE,
-                        totalPowerAndDuration.durationMs)
-                .setConsumedPower(BatteryConsumer.POWER_COMPONENT_USAGE,
-                        totalPowerAndDuration.powerMah);
+        double totalAppPower = 0;
 
         // Now deal with each app's UidBatteryConsumer. The results are stored in the
         // BatteryConsumer.POWER_COMPONENT_SCREEN power component, which is considered smeared,
@@ -87,11 +83,20 @@
                                 appPowerAndDuration.durationMs)
                         .setConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN,
                                 appPowerAndDuration.powerMah);
+                totalAppPower += appPowerAndDuration.powerMah;
             }
         } else {
             smearScreenBatteryDrain(uidBatteryConsumerBuilders, totalPowerAndDuration,
                     rawRealtimeUs);
+            totalAppPower = totalPowerAndDuration.powerMah;
         }
+
+        builder.getOrCreateSystemBatteryConsumerBuilder(SystemBatteryConsumer.DRAIN_TYPE_SCREEN)
+                .setUsageDurationMillis(BatteryConsumer.TIME_COMPONENT_USAGE,
+                        totalPowerAndDuration.durationMs)
+                .setConsumedPower(BatteryConsumer.POWER_COMPONENT_USAGE,
+                        Math.max(totalPowerAndDuration.powerMah, totalAppPower))
+                .setPowerConsumedByApps(totalAppPower);
     }
 
     /**
diff --git a/core/java/com/android/internal/os/WifiPowerCalculator.java b/core/java/com/android/internal/os/WifiPowerCalculator.java
index b6bfde7..d95506b 100644
--- a/core/java/com/android/internal/os/WifiPowerCalculator.java
+++ b/core/java/com/android/internal/os/WifiPowerCalculator.java
@@ -121,7 +121,8 @@
                 .setUsageDurationMillis(BatteryConsumer.TIME_COMPONENT_WIFI,
                         powerDurationAndTraffic.durationMs)
                 .setConsumedPower(BatteryConsumer.POWER_COMPONENT_WIFI,
-                        powerDurationAndTraffic.powerMah);
+                        totalAppPowerMah + powerDurationAndTraffic.powerMah)
+                .setPowerConsumedByApps(totalAppPowerMah);
     }
 
     /**
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 39bde74..611fe29 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -32,6 +32,7 @@
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -2508,6 +2509,7 @@
             if (mDecor.mForceWindowDrawsBarBackgrounds) {
                 params.privateFlags |= PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS;
             }
+            params.privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION;
         }
         if (a.getBoolean(R.styleable.Window_windowLightStatusBar, false)) {
             decor.setSystemUiVisibility(
diff --git a/core/java/com/android/internal/power/MeasuredEnergyStats.java b/core/java/com/android/internal/power/MeasuredEnergyStats.java
index 845b3e5..00a0627 100644
--- a/core/java/com/android/internal/power/MeasuredEnergyStats.java
+++ b/core/java/com/android/internal/power/MeasuredEnergyStats.java
@@ -54,7 +54,9 @@
     public static final int POWER_BUCKET_CPU = 3;
     public static final int POWER_BUCKET_WIFI = 4;
     public static final int POWER_BUCKET_BLUETOOTH = 5;
-    public static final int NUMBER_STANDARD_POWER_BUCKETS = 6; // Buckets above this are custom.
+    public static final int POWER_BUCKET_GNSS = 6;
+    public static final int POWER_BUCKET_MOBILE_RADIO = 7;
+    public static final int NUMBER_STANDARD_POWER_BUCKETS = 8; // Buckets above this are custom.
 
     @IntDef(prefix = {"POWER_BUCKET_"}, value = {
             POWER_BUCKET_UNKNOWN,
@@ -64,6 +66,8 @@
             POWER_BUCKET_CPU,
             POWER_BUCKET_WIFI,
             POWER_BUCKET_BLUETOOTH,
+            POWER_BUCKET_GNSS,
+            POWER_BUCKET_MOBILE_RADIO,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface StandardPowerBucket {
diff --git a/core/java/com/android/internal/view/IInputMethodClient.aidl b/core/java/com/android/internal/view/IInputMethodClient.aidl
index ec9a0a2..49dbbaa 100644
--- a/core/java/com/android/internal/view/IInputMethodClient.aidl
+++ b/core/java/com/android/internal/view/IInputMethodClient.aidl
@@ -28,7 +28,6 @@
     void setActive(boolean active, boolean fullscreen, boolean reportToImeController);
     void scheduleStartInputIfNecessary(boolean fullscreen);
     void reportFullscreenMode(boolean fullscreen);
-    void applyImeVisibility(boolean setVisible);
     void updateActivityViewToScreenMatrix(int bindSequence, in float[] matrixValues);
     void setImeTraceEnabled(boolean enabled);
 }
diff --git a/core/java/com/android/internal/widget/MediaNotificationView.java b/core/java/com/android/internal/widget/MediaNotificationView.java
index f42d5da..8ff3c10 100644
--- a/core/java/com/android/internal/widget/MediaNotificationView.java
+++ b/core/java/com/android/internal/widget/MediaNotificationView.java
@@ -19,31 +19,19 @@
 import android.annotation.Nullable;
 import android.content.Context;
 import android.util.AttributeSet;
-import android.view.NotificationHeaderView;
-import android.view.View;
-import android.view.ViewGroup;
 import android.widget.FrameLayout;
-import android.widget.ImageView;
 import android.widget.RemoteViews;
 
 import java.util.ArrayList;
 
 /**
- * A TextView that can float around an image on the end.
+ * The Layout class which handles template details for the Notification.MediaStyle
  *
  * @hide
  */
 @RemoteViews.RemoteView
 public class MediaNotificationView extends FrameLayout {
 
-    private final int mNotificationContentMarginEnd;
-    private final int mNotificationContentImageMarginEnd;
-    private ImageView mRightIcon;
-    private View mActions;
-    private NotificationHeaderView mHeader;
-    private View mMainColumn;
-    private View mMediaContent;
-    private int mImagePushIn;
     private ArrayList<VisibilityChangeListener> mListeners;
 
     public MediaNotificationView(Context context) {
@@ -58,120 +46,14 @@
         this(context, attrs, defStyleAttr, 0);
     }
 
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        boolean hasIcon = mRightIcon.getVisibility() != GONE;
-        if (!hasIcon) {
-            resetHeaderIndention();
-        }
-        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-        int mode = MeasureSpec.getMode(widthMeasureSpec);
-        boolean reMeasure = false;
-        mImagePushIn = 0;
-        if (hasIcon && mode != MeasureSpec.UNSPECIFIED) {
-            int size = MeasureSpec.getSize(widthMeasureSpec);
-            size = size - mActions.getMeasuredWidth();
-            ViewGroup.MarginLayoutParams layoutParams =
-                    (MarginLayoutParams) mRightIcon.getLayoutParams();
-            int imageEndMargin = layoutParams.getMarginEnd();
-            size -= imageEndMargin;
-            int fullHeight = mMediaContent.getMeasuredHeight();
-            if (size > fullHeight) {
-                size = fullHeight;
-            } else if (size < fullHeight) {
-                size = Math.max(0, size);
-                mImagePushIn = fullHeight - size;
-            }
-            if (layoutParams.width != fullHeight || layoutParams.height != fullHeight) {
-                layoutParams.width = fullHeight;
-                layoutParams.height = fullHeight;
-                mRightIcon.setLayoutParams(layoutParams);
-                reMeasure = true;
-            }
-
-            // lets ensure that the main column doesn't run into the image
-            ViewGroup.MarginLayoutParams params
-                    = (MarginLayoutParams) mMainColumn.getLayoutParams();
-            int marginEnd = size + imageEndMargin + mNotificationContentMarginEnd;
-            if (marginEnd != params.getMarginEnd()) {
-                params.setMarginEnd(marginEnd);
-                mMainColumn.setLayoutParams(params);
-                reMeasure = true;
-            }
-            // TODO(b/172652345): validate all this logic (especially positioning of expand button)
-            // margin for the entire header line
-            int headerMarginEnd = imageEndMargin;
-            // margin for the header text (not including the expand button and other icons)
-            int headerExtraMarginEnd = Math.max(0,
-                    size + imageEndMargin - mHeader.getTopLineBaseMarginEnd());
-            if (headerExtraMarginEnd != mHeader.getTopLineExtraMarginEnd()) {
-                mHeader.setTopLineExtraMarginEnd(headerExtraMarginEnd);
-                reMeasure = true;
-            }
-            params = (MarginLayoutParams) mHeader.getLayoutParams();
-            if (params.getMarginEnd() != headerMarginEnd) {
-                params.setMarginEnd(headerMarginEnd);
-                mHeader.setLayoutParams(params);
-                reMeasure = true;
-            }
-            if (mHeader.getPaddingEnd() != mNotificationContentImageMarginEnd) {
-                mHeader.setPaddingRelative(mHeader.getPaddingStart(),
-                        mHeader.getPaddingTop(),
-                        mNotificationContentImageMarginEnd,
-                        mHeader.getPaddingBottom());
-                reMeasure = true;
-            }
-        }
-        if (reMeasure) {
-            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-        }
-    }
-
-    @Override
-    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
-        super.onLayout(changed, left, top, right, bottom);
-        if (mImagePushIn > 0) {
-            if (this.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
-                mImagePushIn *= -1;
-            }
-            mRightIcon.layout(mRightIcon.getLeft() + mImagePushIn, mRightIcon.getTop(),
-                    mRightIcon.getRight()  + mImagePushIn, mRightIcon.getBottom());
-        }
-    }
-
-    private void resetHeaderIndention() {
-        if (mHeader.getPaddingEnd() != mNotificationContentMarginEnd) {
-            mHeader.setPaddingRelative(mHeader.getPaddingStart(),
-                    mHeader.getPaddingTop(),
-                    mNotificationContentMarginEnd,
-                    mHeader.getPaddingBottom());
-        }
-        ViewGroup.MarginLayoutParams headerParams =
-                (MarginLayoutParams) mHeader.getLayoutParams();
-        headerParams.setMarginEnd(0);
-        if (headerParams.getMarginEnd() != 0) {
-            headerParams.setMarginEnd(0);
-            mHeader.setLayoutParams(headerParams);
-        }
-    }
-
     public MediaNotificationView(Context context, AttributeSet attrs, int defStyleAttr,
             int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
-        mNotificationContentMarginEnd = context.getResources().getDimensionPixelSize(
-                com.android.internal.R.dimen.notification_content_margin_end);
-        mNotificationContentImageMarginEnd = context.getResources().getDimensionPixelSize(
-                com.android.internal.R.dimen.notification_content_image_margin_end);
     }
 
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
-        mRightIcon = findViewById(com.android.internal.R.id.right_icon);
-        mActions = findViewById(com.android.internal.R.id.media_actions);
-        mHeader = findViewById(com.android.internal.R.id.notification_header);
-        mMainColumn = findViewById(com.android.internal.R.id.notification_main_column);
-        mMediaContent = findViewById(com.android.internal.R.id.notification_media_content);
     }
 
     @Override
diff --git a/core/java/com/android/internal/widget/NotificationExpandButton.java b/core/java/com/android/internal/widget/NotificationExpandButton.java
index fc4cc57..7a8ead6 100644
--- a/core/java/com/android/internal/widget/NotificationExpandButton.java
+++ b/core/java/com/android/internal/widget/NotificationExpandButton.java
@@ -20,6 +20,7 @@
 import android.annotation.Nullable;
 import android.content.Context;
 import android.content.res.ColorStateList;
+import android.graphics.PorterDuff;
 import android.graphics.Rect;
 import android.util.AttributeSet;
 import android.view.RemotableViewMethod;
@@ -165,11 +166,13 @@
     private void updateColors() {
         if (shouldShowNumber() && !mDisallowColor) {
             mPillView.setBackgroundTintList(ColorStateList.valueOf(mHighlightPillColor));
-            mIconView.setColorFilter(mHighlightTextColor);
+            mPillView.setBackgroundTintMode(PorterDuff.Mode.SRC_IN);
+            mIconView.setColorFilter(mHighlightTextColor, PorterDuff.Mode.SRC_IN);
             mNumberView.setTextColor(mHighlightTextColor);
         } else {
             mPillView.setBackgroundTintList(ColorStateList.valueOf(mDefaultPillColor));
-            mIconView.setColorFilter(mDefaultTextColor);
+            mPillView.setBackgroundTintMode(PorterDuff.Mode.SRC_IN);
+            mIconView.setColorFilter(mDefaultTextColor, PorterDuff.Mode.SRC_IN);
             mNumberView.setTextColor(mDefaultTextColor);
         }
     }
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index f49a834..20d257e 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -221,7 +221,6 @@
 
             static_libs: [
                 "libasync_safe",
-                "libconnectivityframeworkutils",
                 "libbinderthreadstateutils",
                 "libdmabufinfo",
                 "libgif",
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 94ac183..0c3f265 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -156,7 +156,6 @@
 extern int register_android_service_DataLoaderService(JNIEnv* env);
 extern int register_android_os_incremental_IncrementalManager(JNIEnv* env);
 extern int register_android_net_LocalSocketImpl(JNIEnv* env);
-extern int register_android_net_NetworkUtils(JNIEnv* env);
 extern int register_android_text_AndroidCharacter(JNIEnv *env);
 extern int register_android_text_Hyphenator(JNIEnv *env);
 extern int register_android_opengl_classes(JNIEnv *env);
@@ -1548,7 +1547,6 @@
         REG_JNI(register_android_os_Trace),
         REG_JNI(register_android_os_UEventObserver),
         REG_JNI(register_android_net_LocalSocketImpl),
-        REG_JNI(register_android_net_NetworkUtils),
         REG_JNI(register_android_os_MemoryFile),
         REG_JNI(register_android_os_SharedMemory),
         REG_JNI(register_android_os_incremental_IncrementalManager),
diff --git a/core/jni/android_graphics_BLASTBufferQueue.cpp b/core/jni/android_graphics_BLASTBufferQueue.cpp
index b790056..b46b5a2 100644
--- a/core/jni/android_graphics_BLASTBufferQueue.cpp
+++ b/core/jni/android_graphics_BLASTBufferQueue.cpp
@@ -68,7 +68,7 @@
 };
 
 static jlong nativeCreate(JNIEnv* env, jclass clazz, jstring jName, jlong surfaceControl,
-                          jlong width, jlong height, jint format, jboolean enableTripleBuffering) {
+                          jlong width, jlong height, jint format) {
     String8 str8;
     if (jName) {
         const jchar* str16 = env->GetStringCritical(jName, nullptr);
@@ -81,7 +81,7 @@
     std::string name = str8.string();
     sp<BLASTBufferQueue> queue =
             new BLASTBufferQueue(name, reinterpret_cast<SurfaceControl*>(surfaceControl), width,
-                                 height, format, enableTripleBuffering);
+                                 height, format);
     queue->incStrong((void*)nativeCreate);
     return reinterpret_cast<jlong>(queue.get());
 }
@@ -140,7 +140,7 @@
 static const JNINativeMethod gMethods[] = {
         /* name, signature, funcPtr */
         // clang-format off
-        {"nativeCreate", "(Ljava/lang/String;JJJIZ)J", (void*)nativeCreate},
+        {"nativeCreate", "(Ljava/lang/String;JJJI)J", (void*)nativeCreate},
         {"nativeGetSurface", "(JZ)Landroid/view/Surface;", (void*)nativeGetSurface},
         {"nativeDestroy", "(J)V", (void*)nativeDestroy},
         {"nativeSetNextTransaction", "(JJ)V", (void*)nativeSetNextTransaction},
diff --git a/core/jni/android_media_AudioDescriptor.h b/core/jni/android_media_AudioDescriptor.h
new file mode 100644
index 0000000..680ac3f
--- /dev/null
+++ b/core/jni/android_media_AudioDescriptor.h
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_MEDIA_EXTRAAUDIODESCRIPTOR_H
+#define ANDROID_MEDIA_EXTRAAUDIODESCRIPTOR_H
+
+#include <system/audio.h>
+#include <utils/Errors.h>
+
+namespace android {
+
+// keep these values in sync with ExtraAudioDescriptor.java
+#define STANDARD_NONE 0
+#define STANDARD_EDID 1
+
+static inline status_t audioStandardFromNative(audio_standard_t nStandard, int* standard) {
+    status_t result = NO_ERROR;
+    switch (nStandard) {
+        case AUDIO_STANDARD_NONE:
+            *standard = STANDARD_NONE;
+            break;
+        case AUDIO_STANDARD_EDID:
+            *standard = STANDARD_EDID;
+            break;
+        default:
+            result = BAD_VALUE;
+    }
+    return result;
+}
+
+} // namespace android
+
+#endif // ANDROID_MEDIA_EXTRAAUDIODESCRIPTOR_H
\ No newline at end of file
diff --git a/core/jni/android_media_AudioProfile.h b/core/jni/android_media_AudioProfile.h
new file mode 100644
index 0000000..446bd64
--- /dev/null
+++ b/core/jni/android_media_AudioProfile.h
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_MEDIA_AUDIOPROFILE_H
+#define ANDROID_MEDIA_AUDIOPROFILE_H
+
+#include <system/audio.h>
+#include <utils/Errors.h>
+
+namespace android {
+
+// keep these values in sync with AudioProfile.java
+#define ENCAPSULATION_TYPE_NONE 0
+#define ENCAPSULATION_TYPE_IEC61937 1
+
+static inline status_t audioEncapsulationTypeFromNative(
+        audio_encapsulation_type_t nEncapsulationType, int* encapsulationType) {
+    status_t result = NO_ERROR;
+    switch (nEncapsulationType) {
+        case AUDIO_ENCAPSULATION_TYPE_NONE:
+            *encapsulationType = ENCAPSULATION_TYPE_NONE;
+            break;
+        case AUDIO_ENCAPSULATION_TYPE_IEC61937:
+            *encapsulationType = ENCAPSULATION_TYPE_IEC61937;
+            break;
+        default:
+            result = BAD_VALUE;
+    }
+    return result;
+}
+
+} // namespace android
+
+#endif // ANDROID_MEDIA_AUDIOPROFILE_H
\ No newline at end of file
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index f102edc..6f9a381 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -34,10 +34,12 @@
 #include <system/audio.h>
 #include <system/audio_policy.h>
 #include "android_media_AudioAttributes.h"
+#include "android_media_AudioDescriptor.h"
 #include "android_media_AudioDeviceAttributes.h"
 #include "android_media_AudioEffectDescriptor.h"
 #include "android_media_AudioErrors.h"
 #include "android_media_AudioFormat.h"
+#include "android_media_AudioProfile.h"
 #include "android_media_MicrophoneInfo.h"
 
 // ----------------------------------------------------------------------------
@@ -176,6 +178,9 @@
 
 static struct { jmethodID add; } gListMethods;
 
+static jclass gAudioDescriptorClass;
+static jmethodID gAudiODescriptorCstor;
+
 //
 // JNI Initialization for OpenSLES routing
 //
@@ -1217,6 +1222,7 @@
     jobject jAudioPortConfig = NULL;
     jstring jDeviceName = NULL;
     jobject jAudioProfiles = NULL;
+    jobject jAudioDescriptors = nullptr;
     bool useInMask;
 
     ALOGV("convertAudioPortFromNative id %d role %d type %d name %s",
@@ -1293,13 +1299,21 @@
             }
         }
 
+        int encapsulationType;
+        if (audioEncapsulationTypeFromNative(nAudioPort->audio_profiles[i].encapsulation_type,
+                                             &encapsulationType) != NO_ERROR) {
+            ALOGW("Unknown encapsualtion type for JAVA API: %u",
+                  nAudioPort->audio_profiles[i].encapsulation_type);
+            continue;
+        }
+
         ScopedLocalRef<jobject>
                 jAudioProfile(env,
                               env->NewObject(gAudioProfileClass, gAudioProfileCstor,
                                              audioFormatFromNative(
                                                      nAudioPort->audio_profiles[i].format),
                                              jSamplingRates.get(), jChannelMasks.get(),
-                                             jChannelIndexMasks.get()));
+                                             jChannelIndexMasks.get(), encapsulationType));
         if (jAudioProfile == nullptr) {
             jStatus = (jint)AUDIO_JAVA_ERROR;
             goto exit;
@@ -1307,6 +1321,42 @@
         env->CallBooleanMethod(jAudioProfiles, gArrayListMethods.add, jAudioProfile.get());
     }
 
+    jAudioDescriptors = env->NewObject(gArrayListClass, gArrayListMethods.cstor);
+    if (jAudioDescriptors == nullptr) {
+        jStatus = (jint)AUDIO_JAVA_ERROR;
+        goto exit;
+    }
+    for (size_t i = 0; i < nAudioPort->num_extra_audio_descriptors; ++i) {
+        const auto &extraAudioDescriptor = nAudioPort->extra_audio_descriptors[i];
+        ScopedLocalRef<jobject> jAudioDescriptor(env);
+        if (extraAudioDescriptor.descriptor_length == 0) {
+            continue;
+        }
+        int standard;
+        if (audioStandardFromNative(extraAudioDescriptor.standard, &standard) != NO_ERROR) {
+            ALOGW("Unknown standard for JAVA API: %u", extraAudioDescriptor.standard);
+            continue;
+        }
+        int encapsulationType;
+        if (audioEncapsulationTypeFromNative(extraAudioDescriptor.encapsulation_type,
+                                             &encapsulationType) != NO_ERROR) {
+            ALOGW("Unknown encapsualtion type for JAVA API: %u",
+                  extraAudioDescriptor.encapsulation_type);
+            continue;
+        }
+        ScopedLocalRef<jbyteArray> jDescriptor(env,
+                                               env->NewByteArray(
+                                                       extraAudioDescriptor.descriptor_length));
+        env->SetByteArrayRegion(jDescriptor.get(), 0, extraAudioDescriptor.descriptor_length,
+                                reinterpret_cast<const jbyte *>(extraAudioDescriptor.descriptor));
+        jAudioDescriptor =
+                ScopedLocalRef<jobject>(env,
+                                        env->NewObject(gAudioDescriptorClass, gAudiODescriptorCstor,
+                                                       standard, encapsulationType,
+                                                       jDescriptor.get()));
+        env->CallBooleanMethod(jAudioDescriptors, gArrayListMethods.add, jAudioDescriptor.get());
+    }
+
     // gains
     jGains = env->NewObjectArray(nAudioPort->num_gains,
                                           gAudioGainClass, NULL);
@@ -1365,7 +1415,7 @@
         *jAudioPort =
                 env->NewObject(gAudioDevicePortClass, gAudioDevicePortCstor, jHandle, jDeviceName,
                                jAudioProfiles, jGains, nAudioPort->ext.device.type, jAddress,
-                               jEncapsulationModes, jEncapsulationMetadataTypes);
+                               jEncapsulationModes, jEncapsulationMetadataTypes, jAudioDescriptors);
         env->DeleteLocalRef(jAddress);
     } else if (nAudioPort->type == AUDIO_PORT_TYPE_MIX) {
         ALOGV("convertAudioPortFromNative is a mix");
@@ -1414,6 +1464,9 @@
     if (jAudioPortConfig != NULL) {
         env->DeleteLocalRef(jAudioPortConfig);
     }
+    if (jAudioDescriptors != nullptr) {
+        env->DeleteLocalRef(jAudioDescriptors);
+    }
 
     return jStatus;
 }
@@ -2790,7 +2843,8 @@
     gAudioDevicePortCstor =
             GetMethodIDOrDie(env, audioDevicePortClass, "<init>",
                              "(Landroid/media/AudioHandle;Ljava/lang/String;Ljava/util/List;"
-                             "[Landroid/media/AudioGain;ILjava/lang/String;[I[I)V");
+                             "[Landroid/media/AudioGain;ILjava/lang/String;[I[I"
+                             "Ljava/util/List;)V");
 
     // When access AudioPort as AudioDevicePort
     gAudioPortFields.mType = GetFieldIDOrDie(env, audioDevicePortClass, "mType", "I");
@@ -2909,7 +2963,11 @@
 
     jclass audioProfileClass = FindClassOrDie(env, "android/media/AudioProfile");
     gAudioProfileClass = MakeGlobalRefOrDie(env, audioProfileClass);
-    gAudioProfileCstor = GetMethodIDOrDie(env, audioProfileClass, "<init>", "(I[I[I[I)V");
+    gAudioProfileCstor = GetMethodIDOrDie(env, audioProfileClass, "<init>", "(I[I[I[II)V");
+
+    jclass audioDescriptorClass = FindClassOrDie(env, "android/media/AudioDescriptor");
+    gAudioDescriptorClass = MakeGlobalRefOrDie(env, audioDescriptorClass);
+    gAudiODescriptorCstor = GetMethodIDOrDie(env, audioDescriptorClass, "<init>", "(II[B)V");
 
     AudioSystem::addErrorCallback(android_media_AudioSystem_error_callback);
 
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index 2e4be14..29f8ccf 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -487,9 +487,15 @@
     }
 
     void markVintf() {
+        AutoMutex _l(mLock);
         mVintf = true;
     }
 
+    void forceDowngradeToSystemStability() {
+        AutoMutex _l(mLock);
+        mVintf = false;
+    }
+
     sp<IBinder> getExtension() {
         AutoMutex _l(mLock);
         sp<JavaBBinder> b = mBinder.promote();
@@ -1005,6 +1011,12 @@
     jbh->markVintf();
 }
 
+static void android_os_Binder_forceDowngradeToSystemStability(JNIEnv* env, jobject clazz) {
+    JavaBBinderHolder* jbh =
+        (JavaBBinderHolder*) env->GetLongField(clazz, gBinderOffsets.mObject);
+    jbh->forceDowngradeToSystemStability();
+}
+
 static void android_os_Binder_flushPendingCommands(JNIEnv* env, jobject clazz)
 {
     IPCThreadState::self()->flushCommands();
@@ -1069,6 +1081,7 @@
     { "clearCallingWorkSource", "()J", (void*)android_os_Binder_clearCallingWorkSource },
     { "restoreCallingWorkSource", "(J)V", (void*)android_os_Binder_restoreCallingWorkSource },
     { "markVintfStability", "()V", (void*)android_os_Binder_markVintfStability},
+    { "forceDowngradeToSystemStability", "()V", (void*)android_os_Binder_forceDowngradeToSystemStability},
     { "flushPendingCommands", "()V", (void*)android_os_Binder_flushPendingCommands },
     { "getNativeBBinderHolder", "()J", (void*)android_os_Binder_getNativeBBinderHolder },
     { "getNativeFinalizer", "()J", (void*)android_os_Binder_getNativeFinalizer },
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index d4b5c2b..dd62bb1 100644
--- a/core/jni/android_util_Process.cpp
+++ b/core/jni/android_util_Process.cpp
@@ -52,6 +52,7 @@
 #include <string.h>
 #include <sys/epoll.h>
 #include <sys/errno.h>
+#include <sys/pidfd.h>
 #include <sys/resource.h>
 #include <sys/stat.h>
 #include <sys/syscall.h>
@@ -1316,14 +1317,8 @@
     return removeAllProcessGroups();
 }
 
-// Wrapper function to the syscall pidfd_open, which creates a file
-// descriptor that refers to the process whose PID is specified in pid.
-static inline int sys_pidfd_open(pid_t pid, unsigned int flags) {
-    return syscall(__NR_pidfd_open, pid, flags);
-}
-
 static jint android_os_Process_nativePidFdOpen(JNIEnv* env, jobject, jint pid, jint flags) {
-    int fd = sys_pidfd_open(pid, flags);
+    int fd = pidfd_open(pid, flags);
     if (fd < 0) {
         jniThrowErrnoException(env, "nativePidFdOpen", errno);
         return -1;
diff --git a/core/jni/android_view_InputEventSender.cpp b/core/jni/android_view_InputEventSender.cpp
index 52d21a8..10927b9 100644
--- a/core/jni/android_view_InputEventSender.cpp
+++ b/core/jni/android_view_InputEventSender.cpp
@@ -18,28 +18,28 @@
 
 //#define LOG_NDEBUG 0
 
-#include <nativehelper/JNIHelp.h>
-
 #include <android_runtime/AndroidRuntime.h>
-#include <log/log.h>
-#include <utils/Looper.h>
 #include <input/InputTransport.h>
+#include <log/log.h>
+#include <nativehelper/JNIHelp.h>
+#include <nativehelper/ScopedLocalRef.h>
+#include <utils/Looper.h>
 #include "android_os_MessageQueue.h"
 #include "android_view_InputChannel.h"
 #include "android_view_KeyEvent.h"
 #include "android_view_MotionEvent.h"
+#include "core_jni_helpers.h"
 
-#include <nativehelper/ScopedLocalRef.h>
+#include <inttypes.h>
 #include <unordered_map>
 
-#include "core_jni_helpers.h"
 
 using android::base::Result;
 
 namespace android {
 
 // Log debug messages about the dispatch cycle.
-static const bool kDebugDispatchCycle = false;
+static constexpr bool kDebugDispatchCycle = false;
 
 static struct {
     jclass clazz;
@@ -74,8 +74,10 @@
         return mInputPublisher.getChannel()->getName();
     }
 
-    virtual int handleEvent(int receiveFd, int events, void* data);
+    int handleEvent(int receiveFd, int events, void* data) override;
     status_t receiveFinishedSignals(JNIEnv* env);
+    bool notifyFinishedSignal(JNIEnv* env, jobject sender, const InputPublisher::Finished& finished,
+                              bool skipCallbacks);
 };
 
 NativeInputEventSender::NativeInputEventSender(JNIEnv* env, jobject senderWeak,
@@ -196,8 +198,13 @@
         ALOGD("channel '%s' ~ Receiving finished signals.", getInputChannelName().c_str());
     }
 
-    ScopedLocalRef<jobject> senderObj(env, NULL);
-    bool skipCallbacks = false;
+    ScopedLocalRef<jobject> senderObj(env, jniGetReferent(env, mSenderWeakGlobal));
+    if (!senderObj.get()) {
+        ALOGW("channel '%s' ~ Sender object was finalized without being disposed.",
+              getInputChannelName().c_str());
+        return DEAD_OBJECT;
+    }
+    bool skipCallbacks = false; // stop calling Java functions after an exception occurs
     for (;;) {
         Result<InputPublisher::Finished> result = mInputPublisher.receiveFinishedSignal();
         if (!result.ok()) {
@@ -206,45 +213,55 @@
                 return OK;
             }
             ALOGE("channel '%s' ~ Failed to consume finished signals.  status=%d",
-                    getInputChannelName().c_str(), status);
+                  getInputChannelName().c_str(), status);
             return status;
         }
 
-        auto it = mPublishedSeqMap.find(result->seq);
-        if (it == mPublishedSeqMap.end()) {
-            continue;
-        }
-
-        uint32_t seq = it->second;
-        mPublishedSeqMap.erase(it);
-
-        if (kDebugDispatchCycle) {
-            ALOGD("channel '%s' ~ Received finished signal, seq=%u, handled=%s, pendingEvents=%zu.",
-                  getInputChannelName().c_str(), seq, result->handled ? "true" : "false",
-                  mPublishedSeqMap.size());
-        }
-
-        if (!skipCallbacks) {
-            if (!senderObj.get()) {
-                senderObj.reset(jniGetReferent(env, mSenderWeakGlobal));
-                if (!senderObj.get()) {
-                    ALOGW("channel '%s' ~ Sender object was finalized without being disposed.",
-                          getInputChannelName().c_str());
-                    return DEAD_OBJECT;
-                }
-            }
-
-            env->CallVoidMethod(senderObj.get(),
-                                gInputEventSenderClassInfo.dispatchInputEventFinished,
-                                static_cast<jint>(seq), static_cast<jboolean>(result->handled));
-            if (env->ExceptionCheck()) {
-                ALOGE("Exception dispatching finished signal.");
-                skipCallbacks = true;
-            }
+        const bool notified = notifyFinishedSignal(env, senderObj.get(), *result, skipCallbacks);
+        if (!notified) {
+            skipCallbacks = true;
         }
     }
 }
 
+/**
+ * Invoke the Java function dispatchInputEventFinished for the received "Finished" signal.
+ * Set the variable 'skipCallbacks' to 'true' if a Java exception occurred.
+ * Java function will only be called if 'skipCallbacks' is originally 'false'.
+ *
+ * Return "false" if an exception occurred while calling the Java function
+ *        "true" otherwise
+ */
+bool NativeInputEventSender::notifyFinishedSignal(JNIEnv* env, jobject sender,
+                                                  const InputPublisher::Finished& finished,
+                                                  bool skipCallbacks) {
+    auto it = mPublishedSeqMap.find(finished.seq);
+    if (it == mPublishedSeqMap.end()) {
+        ALOGW("Received 'finished' signal for unknown seq number = %" PRIu32, finished.seq);
+        // Since this is coming from the receiver (typically app), it's possible that an app
+        // does something wrong and sends bad data. Just ignore and process other events.
+        return true;
+    }
+    const uint32_t seq = it->second;
+    mPublishedSeqMap.erase(it);
+
+    if (kDebugDispatchCycle) {
+        ALOGD("channel '%s' ~ Received finished signal, seq=%u, handled=%s, pendingEvents=%zu.",
+              getInputChannelName().c_str(), seq, finished.handled ? "true" : "false",
+              mPublishedSeqMap.size());
+    }
+    if (skipCallbacks) {
+        return true;
+    }
+
+    env->CallVoidMethod(sender, gInputEventSenderClassInfo.dispatchInputEventFinished,
+                        static_cast<jint>(seq), static_cast<jboolean>(finished.handled));
+    if (env->ExceptionCheck()) {
+        ALOGE("Exception dispatching finished signal for seq=%" PRIu32, seq);
+        return false;
+    }
+    return true;
+}
 
 static jlong nativeInit(JNIEnv* env, jclass clazz, jobject senderWeak,
         jobject inputChannelObj, jobject messageQueueObj) {
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index f54ffc5..5f41105 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -1460,6 +1460,27 @@
     transaction->reparent(ctrl, newParent);
 }
 
+static void nativeOverrideHdrTypes(JNIEnv* env, jclass clazz, jobject tokenObject,
+                                   jintArray jHdrTypes) {
+    sp<IBinder> token(ibinderForJavaObject(env, tokenObject));
+    if (token == nullptr || jHdrTypes == nullptr) return;
+
+    int* hdrTypes = env->GetIntArrayElements(jHdrTypes, 0);
+    int numHdrTypes = env->GetArrayLength(jHdrTypes);
+
+    std::vector<ui::Hdr> hdrTypesVector;
+    for (int i = 0; i < numHdrTypes; i++) {
+        hdrTypesVector.push_back(static_cast<ui::Hdr>(hdrTypes[i]));
+    }
+    env->ReleaseIntArrayElements(jHdrTypes, hdrTypes, 0);
+
+    status_t error = SurfaceComposerClient::overrideHdrTypes(token, hdrTypesVector);
+    if (error != NO_ERROR) {
+        jniThrowExceptionFmt(env, "java/lang/SecurityException",
+                             "ACCESS_SURFACE_FLINGER is missing");
+    }
+}
+
 static void nativeSetAutoLowLatencyMode(JNIEnv* env, jclass clazz, jobject tokenObject, jboolean on) {
     sp<IBinder> token(ibinderForJavaObject(env, tokenObject));
     if (token == NULL) return;
@@ -1658,10 +1679,12 @@
             jobject jJankData = env->NewObject(gJankDataClassInfo.clazz,
                     gJankDataClassInfo.ctor, jankData[i].frameVsyncId, jankData[i].jankType);
             env->SetObjectArrayElement(jJankDataArray, i, jJankData);
+            env->DeleteLocalRef(jJankData);
         }
         env->CallVoidMethod(target,
                 gJankDataListenerClassInfo.onJankDataAvailable,
                 jJankDataArray);
+        env->DeleteLocalRef(jJankDataArray);
         env->DeleteLocalRef(target);
     }
 
@@ -1819,6 +1842,8 @@
             (void*)nativeSetGameContentType },
     {"nativeGetCompositionDataspaces", "()[I",
             (void*)nativeGetCompositionDataspaces},
+    {"nativeOverrideHdrTypes", "(Landroid/os/IBinder;[I)V",
+                (void*)nativeOverrideHdrTypes },
     {"nativeClearContentFrameStats", "(J)Z",
             (void*)nativeClearContentFrameStats },
     {"nativeGetContentFrameStats", "(JLandroid/view/WindowContentFrameStats;)Z",
diff --git a/core/proto/android/providers/settings/secure.proto b/core/proto/android/providers/settings/secure.proto
index dca6002..530cb44 100644
--- a/core/proto/android/providers/settings/secure.proto
+++ b/core/proto/android/providers/settings/secure.proto
@@ -123,6 +123,8 @@
         optional SettingProto gesture_silence_alerts_enabled = 7 [ (android.privacy).dest = DEST_AUTOMATIC ];
         optional SettingProto gesture_wake_enabled = 8 [ (android.privacy).dest = DEST_AUTOMATIC ];
         optional SettingProto gesture_setup_complete = 9 [ (android.privacy).dest = DEST_AUTOMATIC ];
+        optional SettingProto touch_gesture_enabled = 10 [ (android.privacy).dest = DEST_AUTOMATIC ];
+        optional SettingProto long_press_home_enabled = 11 [ (android.privacy).dest = DEST_AUTOMATIC ];
     }
     optional Assist assist = 7;
 
@@ -296,6 +298,7 @@
         optional SettingProto subtype_history = 5 [ (android.privacy).dest = DEST_AUTOMATIC ];
         optional SettingProto selected_input_method_subtype = 6 [ (android.privacy).dest = DEST_AUTOMATIC ];
         optional SettingProto show_ime_with_hard_keyboard = 7 [ (android.privacy).dest = DEST_AUTOMATIC ];
+        optional SettingProto default_voice_input_method = 8 [ (android.privacy).dest = DEST_AUTOMATIC ];
     }
     optional InputMethods input_methods = 26;
 
diff --git a/core/proto/android/server/biometrics.proto b/core/proto/android/server/biometrics.proto
index bbb0edd..4f3ae28 100644
--- a/core/proto/android/server/biometrics.proto
+++ b/core/proto/android/server/biometrics.proto
@@ -178,4 +178,6 @@
     CM_DETECT_INTERACTION = 13;
     CM_INVALIDATION_REQUESTER = 14;
     CM_INVALIDATE = 15;
+    CM_STOP_USER = 16;
+    CM_START_USER = 17;
 }
\ No newline at end of file
diff --git a/core/proto/android/server/powermanagerservice.proto b/core/proto/android/server/powermanagerservice.proto
index 0d23946..acb7429 100644
--- a/core/proto/android/server/powermanagerservice.proto
+++ b/core/proto/android/server/powermanagerservice.proto
@@ -58,6 +58,9 @@
         optional bool is_screen_bright = 1;
         optional bool is_screen_dim = 2;
         optional bool is_screen_dream = 3;
+        optional int64 last_user_activity_time_ms = 4;
+        optional int64 last_user_activity_time_no_change_lights_ms = 5;
+        optional int32 display_group_id = 6;
     }
     // A com.android.server.power.PowerManagerService.UidState object.
     message UidStateProto {
@@ -109,7 +112,7 @@
     // The time we decided to do next long check. (In milliseconds timestamp)
     optional int64 notify_long_next_check_ms = 19;
     // Summarizes the effect of the user activity timer.
-    optional UserActivityProto user_activity = 20;
+    repeated UserActivityProto user_activity = 20;
     // If true, instructs the display controller to wait for the proximity
     // sensor to go negative before turning the screen on.
     optional bool is_request_wait_for_negative_proximity = 21;
@@ -134,8 +137,8 @@
     // Timestamp of the last time the device was put to sleep.
     optional int64 last_sleep_time_ms = 30;
     // Timestamp of the last call to user activity.
-    optional int64 last_user_activity_time_ms = 31;
-    optional int64 last_user_activity_time_no_change_lights_ms = 32;
+    optional int64 last_user_activity_time_ms = 31 [deprecated = true];
+    optional int64 last_user_activity_time_no_change_lights_ms = 32 [deprecated = true];
     // Timestamp of last interactive power hint.
     optional int64 last_interactive_power_hint_time_ms = 33;
     // Timestamp of the last screen brightness boost.
diff --git a/core/proto/android/server/vibrator/vibratormanagerservice.proto b/core/proto/android/server/vibrator/vibratormanagerservice.proto
index aab054f..7b97524d 100644
--- a/core/proto/android/server/vibrator/vibratormanagerservice.proto
+++ b/core/proto/android/server/vibrator/vibratormanagerservice.proto
@@ -21,40 +21,49 @@
 
 import "frameworks/base/core/proto/android/privacy.proto";
 
-message OneShotProto {
-    option (.android.msg_privacy).dest = DEST_AUTOMATIC;
-    repeated int32 duration = 1;
-    repeated int32 amplitude = 2;
-}
-
-message WaveformProto {
+message StepSegmentProto {
    option (.android.msg_privacy).dest = DEST_AUTOMATIC;
-   repeated int32 timings = 1;
-   repeated int32 amplitudes = 2;
-   required bool repeat = 3;
+   optional int32 duration = 1;
+   optional float amplitude = 2;
+   optional float frequency = 3;
 }
 
-message PrebakedProto {
+message RampSegmentProto {
+    option (.android.msg_privacy).dest = DEST_AUTOMATIC;
+    optional int32 duration = 1;
+    optional float startAmplitude = 2;
+    optional float endAmplitude = 3;
+    optional float startFrequency = 4;
+    optional float endFrequency = 5;
+}
+
+message PrebakedSegmentProto {
     option (.android.msg_privacy).dest = DEST_AUTOMATIC;
     optional int32 effect_id = 1;
     optional int32 effect_strength = 2;
     optional int32 fallback = 3;
 }
 
-message ComposedProto {
+message PrimitiveSegmentProto {
     option (.android.msg_privacy).dest = DEST_AUTOMATIC;
-    repeated int32 effect_ids = 1;
-    repeated float effect_scales = 2;
-    repeated int32 delays = 3;
+    optional int32 primitive_id = 1;
+    optional float scale = 2;
+    optional int32 delay = 3;
+}
+
+message SegmentProto {
+    option (.android.msg_privacy).dest = DEST_AUTOMATIC;
+    optional PrebakedSegmentProto prebaked = 1;
+    optional PrimitiveSegmentProto primitive = 2;
+    optional StepSegmentProto step = 3;
+    optional RampSegmentProto ramp = 4;
 }
 
 // A com.android.os.VibrationEffect object.
 message VibrationEffectProto {
     option (.android.msg_privacy).dest = DEST_AUTOMATIC;
-    optional OneShotProto oneshot = 1;
-    optional WaveformProto waveform = 2;
-    optional PrebakedProto prebaked = 3;
-    optional ComposedProto composed = 4;
+    optional SegmentProto segments = 1;
+    required int32 repeat = 2;
 }
 
 message SyncVibrationEffectProto {
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 45fd96a..00b165e 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -575,6 +575,7 @@
     <protected-broadcast android:name="android.intent.action.MEDIA_RESOURCE_GRANTED" />
     <protected-broadcast android:name="android.app.action.NETWORK_LOGS_AVAILABLE" />
     <protected-broadcast android:name="android.app.action.SECURITY_LOGS_AVAILABLE" />
+    <protected-broadcast android:name="android.app.action.COMPLIANCE_ACKNOWLEDGEMENT_REQUIRED" />
 
     <protected-broadcast android:name="android.app.action.INTERRUPTION_FILTER_CHANGED" />
     <protected-broadcast android:name="android.app.action.INTERRUPTION_FILTER_CHANGED_INTERNAL" />
@@ -1230,7 +1231,7 @@
         android:description="@string/permdesc_answerPhoneCalls"
         android:protectionLevel="dangerous|runtime" />
 
-    <!-- Allows a calling application which manages it own calls through the self-managed
+    <!-- Allows a calling application which manages its own calls through the self-managed
          {@link android.telecom.ConnectionService} APIs.  See
          {@link android.telecom.PhoneAccount#CAPABILITY_SELF_MANAGED} for more information on the
          self-managed ConnectionService APIs.
@@ -1312,7 +1313,7 @@
         android:permissionGroup="android.permission-group.UNDEFINED"
         android:label="@string/permlab_recordBackgroundAudio"
         android:description="@string/permdesc_recordBackgroundAudio"
-        android:protectionLevel="internal" />
+        android:protectionLevel="internal|role" />
 
     <!-- ====================================================================== -->
     <!-- Permissions for activity recognition                        -->
@@ -1388,6 +1389,14 @@
         android:backgroundPermission="android.permission.BACKGROUND_CAMERA"
         android:protectionLevel="dangerous|instant" />
 
+    <!-- Required to be able to discover and connect to nearby Bluetooth devices.
+         <p>Protection level: dangerous -->
+    <permission-group android:name="android.permission-group.NEARBY_DEVICES"
+        android:icon="@drawable/ic_qs_bluetooth"
+        android:label="@string/permgrouplab_nearby_devices"
+        android:description="@string/permgroupdesc_nearby_devices"
+        android:priority="750" />
+
     <!-- @SystemApi @TestApi Required to be able to access the camera device in the background.
          This permission is not intended to be held by apps.
          <p>Protection level: internal
@@ -1396,7 +1405,7 @@
             android:permissionGroup="android.permission-group.UNDEFINED"
             android:label="@string/permlab_backgroundCamera"
             android:description="@string/permdesc_backgroundCamera"
-            android:protectionLevel="internal" />
+            android:protectionLevel="internal|role" />
 
     <!-- @SystemApi Required in addition to android.permission.CAMERA to be able to access
            system only camera devices.
@@ -1930,6 +1939,22 @@
         android:label="@string/permlab_bluetooth"
         android:protectionLevel="normal" />
 
+    <!-- Required to be able to discover and pair nearby Bluetooth devices.
+         <p>Protection level: dangerous -->
+    <permission android:name="android.permission.BLUETOOTH_SCAN"
+        android:permissionGroup="android.permission-group.UNDEFINED"
+        android:description="@string/permdesc_bluetooth_scan"
+        android:label="@string/permlab_bluetooth_scan"
+        android:protectionLevel="dangerous" />
+
+    <!-- Required to be able to connect to paired Bluetooth devices.
+         <p>Protection level: dangerous -->
+    <permission android:name="android.permission.BLUETOOTH_CONNECT"
+        android:permissionGroup="android.permission-group.UNDEFINED"
+        android:description="@string/permdesc_bluetooth_connect"
+        android:label="@string/permlab_bluetooth_connect"
+        android:protectionLevel="dangerous" />
+
     <!-- @SystemApi @TestApi Allows an application to suspend other apps, which will prevent the
          user from using them until they are unsuspended.
          @hide
@@ -1963,6 +1988,12 @@
     <permission android:name="android.permission.BLUETOOTH_STACK"
         android:protectionLevel="signature" />
 
+    <!-- Allows uhid write access for creating virtual input devices
+         @hide
+    -->
+    <permission android:name="android.permission.VIRTUAL_INPUT_DEVICE"
+        android:protectionLevel="signature" />
+
     <!-- Allows applications to perform I/O operations over NFC.
          <p>Protection level: normal
     -->
@@ -1985,6 +2016,12 @@
         android:label="@string/permlab_preferredPaymentInfo"
         android:protectionLevel="normal" />
 
+    <!-- @SystemApi Allows access to set NFC controller always on states.
+         <p>Protection level: signature|privileged
+         @hide -->
+    <permission android:name="android.permission.NFC_SET_CONTROLLER_ALWAYS_ON"
+        android:protectionLevel="signature|privileged" />
+
     <!-- @SystemApi Allows an internal user to use privileged SecureElement APIs.
          Applications holding this permission can access OMAPI reset system API
          and bypass OMAPI AccessControlEnforcer.
@@ -2659,9 +2696,10 @@
     <permission android:name="android.permission.CREATE_USERS"
         android:protectionLevel="signature" />
 
-    <!-- @TestApi @hide Allows an application to query user info for all users on the device. -->
-    <permission android:name="android.permission.QUERY_USERS"
-                android:protectionLevel="signature" />
+    <!-- @SystemApi @hide Allows an application to access data blobs across users.
+         This permission is not available to third party applications. -->
+    <permission android:name="android.permission.ACCESS_BLOBS_ACROSS_USERS"
+        android:protectionLevel="signature|privileged|development" />
 
     <!-- @hide Allows an application to set the profile owners and the device owner.
          This permission is not available to third party applications.-->
@@ -2943,6 +2981,15 @@
     <permission android:name="android.permission.SUGGEST_MANUAL_TIME_AND_ZONE"
         android:protectionLevel="signature" />
 
+    <!-- Allows system clock time suggestions from an external clock / time source to be made.
+         The nature of "external" could be highly form-factor specific. Example, times
+         obtained via the VHAL for Android Auto OS.
+         <p>Not for use by third-party applications.
+         @SystemApi @hide
+    -->
+    <permission android:name="android.permission.SUGGEST_EXTERNAL_TIME"
+        android:protectionLevel="signature|privileged" />
+
     <!-- Allows applications like settings to manage configuration associated with automatic time
          and time zone detection.
          <p>Not for use by third-party applications.
@@ -3447,6 +3494,14 @@
     <permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW"
         android:protectionLevel="signature" />
 
+    <!-- Allows an application to avoid all toast rate limiting restrictions.
+         <p>Not for use by third-party applications.
+         @hide
+    -->
+    <permission android:name="android.permission.UNLIMITED_TOASTS"
+                android:protectionLevel="signature" />
+    <uses-permission android:name="android.permission.UNLIMITED_TOASTS" />
+
     <!-- @SystemApi Allows an application to use
          {@link android.view.WindowManager.LayoutsParams#SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS}
          to hide non-system-overlay windows.
@@ -3550,7 +3605,7 @@
          @hide
     -->
     <permission android:name="android.permission.GET_TOP_ACTIVITY_INFO"
-        android:protectionLevel="signature" />
+        android:protectionLevel="signature|recents" />
 
     <!-- Allows an application to retrieve the current state of keys and
          switches.
@@ -3955,6 +4010,15 @@
     <permission android:name="android.permission.SET_KEYBOARD_LAYOUT"
         android:protectionLevel="signature" />
 
+    <!-- Allows an app to schedule a prioritized alarm that can be used to perform
+         background work even when the device is in doze.
+         <p>Not for use by third-party applications.
+         @hide
+         @SystemApi
+     -->
+    <permission android:name="android.permission.SCHEDULE_PRIORITIZED_ALARM"
+                android:protectionLevel="signature|privileged"/>
+
     <!-- Allows an app to use exact alarm scheduling APIs to perform timing
          sensitive background work.
      -->
@@ -4184,6 +4248,11 @@
     <permission android:name="android.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE"
                 android:protectionLevel="normal" />
 
+    <!-- Allows an application to create new companion device associations.
+         @hide -->
+    <permission android:name="android.permission.ASSOCIATE_COMPANION_DEVICES"
+        android:protectionLevel="internal|role" />
+
     <!-- @SystemApi Allows an application to use SurfaceFlinger's low level features.
          <p>Not for use by third-party applications.
          @hide
@@ -4397,6 +4466,13 @@
     <permission android:name="android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS"
         android:protectionLevel="signature|privileged" />
 
+    <!-- @SystemApi Allows an application to disable system sound effects when the user exits one of
+         the application's activities.
+         <p>Not for use by third-party applications.</p>
+         @hide -->
+    <permission android:name="android.permission.DISABLE_SYSTEM_SOUND_EFFECTS"
+        android:protectionLevel="signature|privileged" />
+
     <!-- @SystemApi Allows an application to provide remote displays.
          <p>Not for use by third-party applications.</p>
          @hide -->
@@ -4484,7 +4560,7 @@
     <permission android:name="android.permission.FACTORY_TEST"
         android:protectionLevel="signature" />
 
-    <!-- @hide @TestApi Allows an application to broadcast the intent {@link
+    <!-- @hide @TestApi @SystemApi Allows an application to broadcast the intent {@link
          android.content.Intent#ACTION_CLOSE_SYSTEM_DIALOGS}.
          <p>Not for use by third-party applications.
     -->
@@ -4907,6 +4983,11 @@
     <permission android:name="android.permission.SET_INITIAL_LOCK"
         android:protectionLevel="signature|setup"/>
 
+    <!-- @TestApi Allows applications to set and verify lockscreen credentials.
+        @hide -->
+    <permission android:name="android.permission.SET_AND_VERIFY_LOCKSCREEN_CREDENTIALS"
+                android:protectionLevel="signature"/>
+
     <!-- Allows managing (adding, removing) fingerprint templates. Reserved for the system. @hide -->
     <permission android:name="android.permission.MANAGE_FINGERPRINT"
         android:protectionLevel="signature|privileged" />
@@ -5369,12 +5450,6 @@
     <permission android:name="android.permission.WATCH_APPOPS"
         android:protectionLevel="signature|privileged" />
 
-    <!-- Allows an application to directly open the "Open by default" page inside a package's
-         Details screen.
-         @hide <p>Not for use by third-party applications. -->
-    <permission android:name="android.permission.OPEN_APP_OPEN_BY_DEFAULT_SETTINGS"
-                android:protectionLevel="signature" />
-
     <!-- Allows hidden API checks to be disabled when starting a process.
          @hide <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.DISABLE_HIDDEN_API_CHECKS"
@@ -5501,9 +5576,17 @@
     <permission android:name="android.permission.READ_COMPAT_CHANGE_CONFIG"
                 android:protectionLevel="signature|privileged" />
     <!-- Allows an app to override compat change config.
+         This permission only allows to override config on debuggable builds or test-apks and is
+         therefore a less powerful version of OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD.
          @hide  <p>Not for use by third-party applications.</p> -->
     <permission android:name="android.permission.OVERRIDE_COMPAT_CHANGE_CONFIG"
                 android:protectionLevel="signature|privileged" />
+    <uses-permission android:name="android.permission.OVERRIDE_COMPAT_CHANGE_CONFIG"/>
+    <!-- @SystemApi Allows an app to override compat change config on release builds.
+        Only ChangeIds that are annotated as @Overridable can be overridden on release builds.
+        @hide -->
+    <permission android:name="android.permission.OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD"
+                android:protectionLevel="signature|privileged" />
 
     <!-- Allows input events to be monitored. Very dangerous!  @hide -->
     <permission android:name="android.permission.MONITOR_INPUT"
@@ -5605,12 +5688,31 @@
     <permission android:name="android.permission.RENOUNCE_PERMISSIONS"
                 android:protectionLevel="signature|privileged" />
 
+    <!-- Allows an application to read nearby streaming policy. The policy allows the device
+         to stream its notifications and apps to nearby devices.
+         @hide -->
+    <permission android:name="android.permission.READ_NEARBY_STREAMING_POLICY"
+        android:protectionLevel="signature|privileged" />
+
     <!-- @SystemApi Allows the holder to set the source of the data when setting a clip on the
          clipboard.
          @hide -->
     <permission android:name="android.permission.SET_CLIP_SOURCE"
                 android:protectionLevel="signature|recents" />
 
+    <!-- Allows an application to request installs that update existing packages do so without
+         user action via
+         {@link android.content.pm.PackageInstaller.SessionParams#setRequireUserAction(boolean)}.
+         This permission only grants the ability to make the request and is not a guarantee that the
+         request will be honored. In order to execute the install, the caller must also have the
+         "android.permission.REQUEST_INSTALL_PACKAGES" or "android.permission.INSTALL_PACKAGES"
+         permissions.
+         <p>Protection level: normal
+    -->
+    <permission android:name="android.permission.UPDATE_PACKAGES_WITHOUT_USER_ACTION"
+                android:protectionLevel="normal" />
+    <uses-permission android:name="android.permission.UPDATE_PACKAGES_WITHOUT_USER_ACTION"/>
+
     <!-- Attribution for Geofencing service. -->
     <attribution android:tag="GeofencingService" android:label="@string/geofencing_service"/>
     <!-- Attribution for Country Detector. -->
diff --git a/core/res/remote_color_resources_res/values/colors.xml b/core/res/remote_color_resources_res/values/colors.xml
index 295f16e..e4bcae43 100644
--- a/core/res/remote_color_resources_res/values/colors.xml
+++ b/core/res/remote_color_resources_res/values/colors.xml
@@ -1,40 +1,64 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
   <!-- Note: the values of the colors doesn't really matter (they will always be overwritten before used), but they help a lot debugging, to find out which color is where in the ARSC file. -->
-  <color name="system_primary_0">#01010101</color>
-  <color name="system_primary_50">#02020202</color>
-  <color name="system_primary_100">#03030303</color>
-  <color name="system_primary_200">#04040404</color>
-  <color name="system_primary_300">#05050505</color>
-  <color name="system_primary_400">#06060606</color>
-  <color name="system_primary_500">#07070707</color>
-  <color name="system_primary_600">#08080808</color>
-  <color name="system_primary_700">#09090909</color>
-  <color name="system_primary_800">#0a0a0a0a</color>
-  <color name="system_primary_900">#0b0b0b0b</color>
-  <color name="system_primary_1000">#0c0c0c0c</color>
-  <color name="system_secondary_0">#10101010</color>
-  <color name="system_secondary_50">#20202020</color>
-  <color name="system_secondary_100">#30303030</color>
-  <color name="system_secondary_200">#40404040</color>
-  <color name="system_secondary_300">#50505050</color>
-  <color name="system_secondary_400">#60606060</color>
-  <color name="system_secondary_500">#70707070</color>
-  <color name="system_secondary_600">#80808080</color>
-  <color name="system_secondary_700">#90909090</color>
-  <color name="system_secondary_800">#a0a0a0a0</color>
-  <color name="system_secondary_900">#b0b0b0b0</color>
-  <color name="system_secondary_1000">#c0c0c0c0</color>
-  <color name="system_neutral_0">#1f1f1f1f</color>
-  <color name="system_neutral_50">#2f2f2f2f</color>
-  <color name="system_neutral_100">#3f3f3f3f</color>
-  <color name="system_neutral_200">#4f4f4f4f</color>
-  <color name="system_neutral_300">#5f5f5f5f</color>
-  <color name="system_neutral_400">#6f6f6f6f</color>
-  <color name="system_neutral_500">#7f7f7f7f</color>
-  <color name="system_neutral_600">#8f8f8f8f</color>
-  <color name="system_neutral_700">#9f9f9f9f</color>
-  <color name="system_neutral_800">#afafafaf</color>
-  <color name="system_neutral_900">#bfbfbfbf</color>
-  <color name="system_neutral_1000">#cfcfcfcf</color>
+  <color name="system_accent1_0">#ffffff</color>
+  <color name="system_accent1_50">#91fff4</color>
+  <color name="system_accent1_100">#83f6e5</color>
+  <color name="system_accent1_200">#65d9c9</color>
+  <color name="system_accent1_300">#45bdae</color>
+  <color name="system_accent1_400">#1fa293</color>
+  <color name="system_accent1_500">#008377</color>
+  <color name="system_accent1_600">#006d61</color>
+  <color name="system_accent1_700">#005449</color>
+  <color name="system_accent1_800">#003c33</color>
+  <color name="system_accent1_900">#00271e</color>
+  <color name="system_accent1_1000">#000000</color>
+  <color name="system_accent2_0">#ffffff</color>
+  <color name="system_accent2_50">#91fff4</color>
+  <color name="system_accent2_100">#83f6e5</color>
+  <color name="system_accent2_200">#65d9c9</color>
+  <color name="system_accent2_300">#45bdae</color>
+  <color name="system_accent2_400">#1fa293</color>
+  <color name="system_accent2_500">#008377</color>
+  <color name="system_accent2_600">#006d61</color>
+  <color name="system_accent2_700">#005449</color>
+  <color name="system_accent2_800">#003c33</color>
+  <color name="system_accent2_900">#00271e</color>
+  <color name="system_accent2_1000">#000000</color>
+  <color name="system_accent3_0">#ffffff</color>
+  <color name="system_accent3_50">#91fff4</color>
+  <color name="system_accent3_100">#83f6e5</color>
+  <color name="system_accent3_200">#65d9c9</color>
+  <color name="system_accent3_300">#45bdae</color>
+  <color name="system_accent3_400">#1fa293</color>
+  <color name="system_accent3_500">#008377</color>
+  <color name="system_accent3_600">#006d61</color>
+  <color name="system_accent3_700">#005449</color>
+  <color name="system_accent3_800">#003c33</color>
+  <color name="system_accent3_900">#00271e</color>
+  <color name="system_accent3_1000">#000000</color>
+  <color name="system_neutral1_0">#ffffff</color>
+  <color name="system_neutral1_50">#f0f0f0</color>
+  <color name="system_neutral1_100">#e2e2e2</color>
+  <color name="system_neutral1_200">#c6c6c6</color>
+  <color name="system_neutral1_300">#ababab</color>
+  <color name="system_neutral1_400">#909090</color>
+  <color name="system_neutral1_500">#757575</color>
+  <color name="system_neutral1_600">#5e5e5e</color>
+  <color name="system_neutral1_700">#464646</color>
+  <color name="system_neutral1_800">#303030</color>
+  <color name="system_neutral1_900">#1b1b1b</color>
+  <color name="system_neutral1_1000">#000000</color>
+  <color name="system_neutral2_0">#ffffff</color>
+  <color name="system_neutral2_50">#f0f0f0</color>
+  <color name="system_neutral2_100">#e2e2e2</color>
+  <color name="system_neutral2_200">#c6c6c6</color>
+  <color name="system_neutral2_300">#ababab</color>
+  <color name="system_neutral2_400">#909090</color>
+  <color name="system_neutral2_500">#757575</color>
+  <color name="system_neutral2_600">#5e5e5e</color>
+  <color name="system_neutral2_700">#464646</color>
+  <color name="system_neutral2_800">#303030</color>
+  <color name="system_neutral2_900">#1b1b1b</color>
+  <color name="system_neutral2_1000">#000000</color>
 </resources>
diff --git a/core/res/remote_color_resources_res/values/public.xml b/core/res/remote_color_resources_res/values/public.xml
index e628f09..9616628 100644
--- a/core/res/remote_color_resources_res/values/public.xml
+++ b/core/res/remote_color_resources_res/values/public.xml
@@ -1,41 +1,65 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
   <public-group type="color" first-id="0x0106001d">
-    <public name="system_primary_0" />
-    <public name="system_primary_50" />
-    <public name="system_primary_100" />
-    <public name="system_primary_200" />
-    <public name="system_primary_300" />
-    <public name="system_primary_400" />
-    <public name="system_primary_500" />
-    <public name="system_primary_600" />
-    <public name="system_primary_700" />
-    <public name="system_primary_800" />
-    <public name="system_primary_900" />
-    <public name="system_primary_1000" />
-    <public name="system_secondary_0" />
-    <public name="system_secondary_50" />
-    <public name="system_secondary_100" />
-    <public name="system_secondary_200" />
-    <public name="system_secondary_300" />
-    <public name="system_secondary_400" />
-    <public name="system_secondary_500" />
-    <public name="system_secondary_600" />
-    <public name="system_secondary_700" />
-    <public name="system_secondary_800" />
-    <public name="system_secondary_900" />
-    <public name="system_secondary_1000" />
-    <public name="system_neutral_0" />
-    <public name="system_neutral_50" />
-    <public name="system_neutral_100" />
-    <public name="system_neutral_200" />
-    <public name="system_neutral_300" />
-    <public name="system_neutral_400" />
-    <public name="system_neutral_500" />
-    <public name="system_neutral_600" />
-    <public name="system_neutral_700" />
-    <public name="system_neutral_800" />
-    <public name="system_neutral_900" />
-    <public name="system_neutral_1000" />
+    <public name="system_accent1_0" />
+    <public name="system_accent1_50" />
+    <public name="system_accent1_100" />
+    <public name="system_accent1_200" />
+    <public name="system_accent1_300" />
+    <public name="system_accent1_400" />
+    <public name="system_accent1_500" />
+    <public name="system_accent1_600" />
+    <public name="system_accent1_700" />
+    <public name="system_accent1_800" />
+    <public name="system_accent1_900" />
+    <public name="system_accent1_1000" />
+    <public name="system_accent2_0" />
+    <public name="system_accent2_50" />
+    <public name="system_accent2_100" />
+    <public name="system_accent2_200" />
+    <public name="system_accent2_300" />
+    <public name="system_accent2_400" />
+    <public name="system_accent2_500" />
+    <public name="system_accent2_600" />
+    <public name="system_accent2_700" />
+    <public name="system_accent2_800" />
+    <public name="system_accent2_900" />
+    <public name="system_accent2_1000" />
+    <public name="system_accent3_0" />
+    <public name="system_accent3_50" />
+    <public name="system_accent3_100" />
+    <public name="system_accent3_200" />
+    <public name="system_accent3_300" />
+    <public name="system_accent3_400" />
+    <public name="system_accent3_500" />
+    <public name="system_accent3_600" />
+    <public name="system_accent3_700" />
+    <public name="system_accent3_800" />
+    <public name="system_accent3_900" />
+    <public name="system_accent3_1000" />
+    <public name="system_neutral1_0" />
+    <public name="system_neutral1_50" />
+    <public name="system_neutral1_100" />
+    <public name="system_neutral1_200" />
+    <public name="system_neutral1_300" />
+    <public name="system_neutral1_400" />
+    <public name="system_neutral1_500" />
+    <public name="system_neutral1_600" />
+    <public name="system_neutral1_700" />
+    <public name="system_neutral1_800" />
+    <public name="system_neutral1_900" />
+    <public name="system_neutral1_1000" />
+    <public name="system_neutral2_0" />
+    <public name="system_neutral2_50" />
+    <public name="system_neutral2_100" />
+    <public name="system_neutral2_200" />
+    <public name="system_neutral2_300" />
+    <public name="system_neutral2_400" />
+    <public name="system_neutral2_500" />
+    <public name="system_neutral2_600" />
+    <public name="system_neutral2_700" />
+    <public name="system_neutral2_800" />
+    <public name="system_neutral2_900" />
+    <public name="system_neutral2_1000" />
   </public-group>
 </resources>
diff --git a/core/res/res/color/text_color_primary_device_default_dark.xml b/core/res/res/color/text_color_primary_device_default_dark.xml
index 90d6b07..5926fde 100644
--- a/core/res/res/color/text_color_primary_device_default_dark.xml
+++ b/core/res/res/color/text_color_primary_device_default_dark.xml
@@ -17,7 +17,6 @@
 <!-- Please see primary_text_material_dark.xml -->
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:state_enabled="false"
-          android:alpha="?attr/disabledAlpha"
-          android:color="@color/system_primary_50"/>
-    <item android:color="@color/system_primary_50"/>
+          android:color="@color/system_neutral1_500"/>
+    <item android:color="@color/system_neutral1_50"/>
 </selector>
diff --git a/core/res/res/color/text_color_primary_device_default_light.xml b/core/res/res/color/text_color_primary_device_default_light.xml
index bdc4fa9..1379523 100644
--- a/core/res/res/color/text_color_primary_device_default_light.xml
+++ b/core/res/res/color/text_color_primary_device_default_light.xml
@@ -17,7 +17,6 @@
 <!-- Please see primary_text_material_light.xml -->
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:state_enabled="false"
-          android:alpha="?attr/disabledAlpha"
-          android:color="@color/system_primary_900"/>
-    <item android:color="@color/system_primary_900"/>
+          android:color="@color/system_neutral1_400"/>
+    <item android:color="@color/system_neutral1_900"/>
 </selector>
diff --git a/core/res/res/color/text_color_secondary_device_default_dark.xml b/core/res/res/color/text_color_secondary_device_default_dark.xml
index 799636ad..f79fd62 100644
--- a/core/res/res/color/text_color_secondary_device_default_dark.xml
+++ b/core/res/res/color/text_color_secondary_device_default_dark.xml
@@ -18,6 +18,6 @@
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:state_enabled="false"
           android:alpha="?attr/disabledAlpha"
-          android:color="@color/system_primary_200"/>
-    <item android:color="@color/system_primary_200"/>
+          android:color="@color/system_neutral2_200"/>
+    <item android:color="@color/system_neutral2_200"/>
 </selector>
diff --git a/core/res/res/color/text_color_secondary_device_default_light.xml b/core/res/res/color/text_color_secondary_device_default_light.xml
index 4793bb8..c58f565 100644
--- a/core/res/res/color/text_color_secondary_device_default_light.xml
+++ b/core/res/res/color/text_color_secondary_device_default_light.xml
@@ -18,6 +18,6 @@
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:state_enabled="false"
           android:alpha="?attr/disabledAlpha"
-          android:color="@color/system_primary_700"/>
-    <item android:color="@color/system_primary_700"/>
+          android:color="@color/system_neutral2_700"/>
+    <item android:color="@color/system_neutral2_700"/>
 </selector>
diff --git a/core/res/res/color/text_color_tertiary_device_default_dark.xml b/core/res/res/color/text_color_tertiary_device_default_dark.xml
index c828631..63fdc81 100644
--- a/core/res/res/color/text_color_tertiary_device_default_dark.xml
+++ b/core/res/res/color/text_color_tertiary_device_default_dark.xml
@@ -18,6 +18,6 @@
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:state_enabled="false"
           android:alpha="?attr/disabledAlpha"
-          android:color="@color/system_primary_400"/>
-    <item android:color="@color/system_primary_400"/>
+          android:color="@color/system_neutral2_400"/>
+    <item android:color="@color/system_neutral2_400"/>
 </selector>
diff --git a/core/res/res/color/text_color_tertiary_device_default_light.xml b/core/res/res/color/text_color_tertiary_device_default_light.xml
index 82c420a..1ad6f6a 100644
--- a/core/res/res/color/text_color_tertiary_device_default_light.xml
+++ b/core/res/res/color/text_color_tertiary_device_default_light.xml
@@ -18,6 +18,6 @@
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:state_enabled="false"
           android:alpha="?attr/disabledAlpha"
-          android:color="@color/system_primary_500"/>
-    <item android:color="@color/system_primary_500"/>
+          android:color="@color/system_neutral2_500"/>
+    <item android:color="@color/system_neutral2_500"/>
 </selector>
diff --git a/core/res/res/drawable/bottomsheet_background.xml b/core/res/res/drawable/bottomsheet_background.xml
index 3a8ad71..00d53004 100644
--- a/core/res/res/drawable/bottomsheet_background.xml
+++ b/core/res/res/drawable/bottomsheet_background.xml
@@ -18,5 +18,5 @@
     <corners
         android:topLeftRadius="@dimen/config_bottomDialogCornerRadius"
         android:topRightRadius="@dimen/config_bottomDialogCornerRadius"/>
-    <solid android:color="?attr/colorBackgroundFloating" />
+    <solid android:color="?attr/colorBackground" />
 </shape>
diff --git a/core/res/res/drawable/chooser_action_button_bg.xml b/core/res/res/drawable/chooser_action_button_bg.xml
index 0dd9e9c7..18bbd93 100644
--- a/core/res/res/drawable/chooser_action_button_bg.xml
+++ b/core/res/res/drawable/chooser_action_button_bg.xml
@@ -15,7 +15,7 @@
   ~ limitations under the License
   -->
 <ripple xmlns:android="http://schemas.android.com/apk/res/android"
-        android:color="@color/lighter_gray">
+        android:color="?android:attr/colorControlHighlight">
     <item>
         <inset
             android:insetLeft="0dp"
@@ -23,10 +23,8 @@
             android:insetRight="0dp"
             android:insetBottom="8dp">
             <shape android:shape="rectangle">
-              <corners android:radius="16dp"></corners>
-                <stroke android:width="1dp"
-                        android:color="?attr/opacityListDivider" />
-                <solid android:color="?attr/colorBackgroundFloating" />
+                <corners android:radius="16dp" />
+                <solid android:color="@color/system_neutral2_100" />
             </shape>
         </inset>
     </item>
diff --git a/core/res/res/layout/chooser_action_button.xml b/core/res/res/layout/chooser_action_button.xml
index 6af7937..def429e 100644
--- a/core/res/res/layout/chooser_action_button.xml
+++ b/core/res/res/layout/chooser_action_button.xml
@@ -19,12 +19,13 @@
     android:paddingStart="12dp"
     android:paddingEnd="12dp"
     android:drawablePadding="8dp"
-    android:textColor="?android:textColorPrimary"
+    android:textColor="@color/text_color_primary_device_default_light"
     android:textSize="12sp"
     android:maxWidth="192dp"
     android:singleLine="true"
     android:clickable="true"
     android:background="@drawable/chooser_action_button_bg"
-    android:drawableTint="@color/chooser_chip_icon"
+    android:drawableTint="@color/text_color_primary_device_default_light"
     android:drawableTintMode="src_in"
+    style="?android:attr/borderlessButtonStyle"
     />
diff --git a/core/res/res/layout/chooser_grid.xml b/core/res/res/layout/chooser_grid.xml
index c0de693..10683b1 100644
--- a/core/res/res/layout/chooser_grid.xml
+++ b/core/res/res/layout/chooser_grid.xml
@@ -67,7 +67,7 @@
         android:layout_height="wrap_content"
         android:layout_alignParentTop="true"
         android:layout_centerHorizontal="true"
-        android:background="?attr/colorBackgroundFloating">
+        android:background="?attr/colorBackground">
         <LinearLayout
             android:orientation="vertical"
             android:layout_width="match_parent"
@@ -84,7 +84,7 @@
                 android:layout_alwaysShow="true"
                 android:layout_width="match_parent"
                 android:layout_height="1dp"
-                android:background="?attr/colorBackgroundFloating"
+                android:background="?attr/colorBackground"
                 android:foreground="?attr/dividerVertical" />
             <FrameLayout
                 android:id="@android:id/tabcontent"
diff --git a/core/res/res/layout/chooser_grid_preview_file.xml b/core/res/res/layout/chooser_grid_preview_file.xml
index 2a39215..d8c1d17 100644
--- a/core/res/res/layout/chooser_grid_preview_file.xml
+++ b/core/res/res/layout/chooser_grid_preview_file.xml
@@ -24,7 +24,7 @@
     android:layout_height="wrap_content"
     android:orientation="vertical"
     android:paddingBottom="@dimen/chooser_view_spacing"
-    android:background="?attr/colorBackgroundFloating">
+    android:background="?attr/colorBackground">
 
   <LinearLayout
       android:layout_width="@dimen/chooser_preview_width"
diff --git a/core/res/res/layout/chooser_grid_preview_image.xml b/core/res/res/layout/chooser_grid_preview_image.xml
index 62df165..0d04d7f3 100644
--- a/core/res/res/layout/chooser_grid_preview_image.xml
+++ b/core/res/res/layout/chooser_grid_preview_image.xml
@@ -22,14 +22,14 @@
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:orientation="vertical"
-    android:background="?attr/colorBackgroundFloating">
+    android:background="?attr/colorBackground">
   <RelativeLayout
       android:id="@+id/content_preview_image_area"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_gravity="center_horizontal"
       android:paddingBottom="@dimen/chooser_view_spacing"
-      android:background="?attr/colorBackgroundFloating">
+      android:background="?attr/colorBackground">
 
     <view class="com.android.internal.app.ChooserActivity$RoundedRectImageView"
           android:id="@+id/content_preview_image_1_large"
diff --git a/core/res/res/layout/chooser_grid_preview_text.xml b/core/res/res/layout/chooser_grid_preview_text.xml
index 1d18648..bc4f327 100644
--- a/core/res/res/layout/chooser_grid_preview_text.xml
+++ b/core/res/res/layout/chooser_grid_preview_text.xml
@@ -23,7 +23,7 @@
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:orientation="vertical"
-    android:background="?android:attr/colorBackgroundFloating">
+    android:background="?android:attr/colorBackground">
 
   <RelativeLayout
       android:layout_width="@dimen/chooser_preview_width"
diff --git a/core/res/res/layout/chooser_list_per_profile.xml b/core/res/res/layout/chooser_list_per_profile.xml
index 86dc71c..912173c 100644
--- a/core/res/res/layout/chooser_list_per_profile.xml
+++ b/core/res/res/layout/chooser_list_per_profile.xml
@@ -23,7 +23,7 @@
         android:layoutManager="com.android.internal.app.ChooserGridLayoutManager"
         android:id="@+id/resolver_list"
         android:clipToPadding="false"
-        android:background="?attr/colorBackgroundFloating"
+        android:background="?attr/colorBackground"
         android:scrollbars="none"
         android:elevation="1dp"
         android:nestedScrollingEnabled="true" />
diff --git a/core/res/res/layout/notification_material_media_action.xml b/core/res/res/layout/notification_material_media_action.xml
index dd79a0b..5f1b60e 100644
--- a/core/res/res/layout/notification_material_media_action.xml
+++ b/core/res/res/layout/notification_material_media_action.xml
@@ -24,7 +24,6 @@
     android:paddingTop="8dp"
     android:paddingStart="8dp"
     android:paddingEnd="8dp"
-    android:layout_marginEnd="2dp"
     android:gravity="center"
     android:background="@drawable/notification_material_media_action_background"
     android:visibility="gone"
diff --git a/core/res/res/layout/notification_material_media_seekbar.xml b/core/res/res/layout/notification_material_media_seekbar.xml
deleted file mode 100644
index 4aa8acc..0000000
--- a/core/res/res/layout/notification_material_media_seekbar.xml
+++ /dev/null
@@ -1,65 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ 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
-  -->
-
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/notification_media_progress"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:orientation="vertical"
-    android:layout_alignParentBottom="true"
-    >
-    <SeekBar android:id="@+id/notification_media_progress_bar"
-        style="@style/Widget.ProgressBar.Horizontal"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:maxHeight="3dp"
-        android:paddingTop="24dp"
-        android:paddingBottom="24dp"
-        android:clickable="true"
-        android:layout_marginBottom="-24dp"
-        android:layout_marginTop="-12dp"
-        android:splitTrack="false"
-    />
-    <FrameLayout
-        android:id="@+id/notification_media_progress_time"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center"
-        android:layout_marginBottom="11dp"
-        >
-
-        <!-- width is set to "match_parent" to avoid extra layout calls -->
-        <TextView android:id="@+id/notification_media_elapsed_time"
-            style="@style/Widget.DeviceDefault.Notification.Text"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_alignParentLeft="true"
-            android:layout_marginStart="@dimen/notification_content_margin_start"
-            android:gravity="start"
-        />
-
-        <TextView android:id="@+id/notification_media_total_time"
-            style="@style/Widget.DeviceDefault.Notification.Text"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_alignParentRight="true"
-            android:layout_marginEnd="@dimen/notification_content_margin_end"
-            android:gravity="end"
-        />
-    </FrameLayout>
-</LinearLayout>
\ No newline at end of file
diff --git a/core/res/res/layout/notification_template_material_base.xml b/core/res/res/layout/notification_template_material_base.xml
index bad9a6b..e644cd5 100644
--- a/core/res/res/layout/notification_template_material_base.xml
+++ b/core/res/res/layout/notification_template_material_base.xml
@@ -46,20 +46,6 @@
         android:padding="@dimen/notification_icon_circle_padding"
         />
 
-    <ImageView
-        android:id="@+id/right_icon"
-        android:layout_width="@dimen/notification_right_icon_size"
-        android:layout_height="@dimen/notification_right_icon_size"
-        android:layout_gravity="center_vertical|end"
-        android:layout_marginTop="@dimen/notification_right_icon_headerless_margin"
-        android:layout_marginBottom="@dimen/notification_right_icon_headerless_margin"
-        android:layout_marginEnd="@dimen/notification_header_expand_icon_size"
-        android:background="@drawable/notification_large_icon_outline"
-        android:clipToOutline="true"
-        android:importantForAccessibility="no"
-        android:scaleType="centerCrop"
-        />
-
     <FrameLayout
         android:id="@+id/alternate_expand_target"
         android:layout_width="@dimen/notification_content_margin_start"
@@ -68,95 +54,116 @@
         android:importantForAccessibility="no"
         />
 
-    <FrameLayout
-        android:id="@+id/expand_button_touch_container"
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:layout_gravity="end">
-
-        <include layout="@layout/notification_expand_button"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center_vertical|end"
-            />
-
-    </FrameLayout>
-
     <LinearLayout
-        android:id="@+id/notification_headerless_view_column"
+        android:id="@+id/notification_headerless_view_row"
         android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center_vertical"
-        android:layout_marginBottom="@dimen/notification_headerless_margin_twoline"
-        android:layout_marginTop="@dimen/notification_headerless_margin_twoline"
-        android:orientation="vertical"
+        android:layout_height="match_parent"
+        android:layout_marginStart="@dimen/notification_content_margin_start"
+        android:orientation="horizontal"
         >
 
-        <!-- extends ViewGroup -->
-        <NotificationTopLineView
-            android:id="@+id/notification_top_line"
-            android:layout_width="wrap_content"
-            android:layout_height="@dimen/notification_headerless_line_height"
-            android:layout_marginEnd="@dimen/notification_heading_margin_end"
-            android:layout_marginStart="@dimen/notification_content_margin_start"
-            android:clipChildren="false"
-            android:theme="@style/Theme.DeviceDefault.Notification"
-            >
-
-            <!--
-            NOTE: The notification_top_line_views layout contains the app_name_text.
-            In order to include the title view at the beginning, the Notification.Builder
-            has logic to hide that view whenever this title view is to be visible.
-            -->
-
-            <TextView
-                android:id="@+id/title"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_marginEnd="@dimen/notification_header_separating_margin"
-                android:ellipsize="marquee"
-                android:fadingEdge="horizontal"
-                android:singleLine="true"
-                android:textAlignment="viewStart"
-                android:textAppearance="@style/TextAppearance.DeviceDefault.Notification.Title"
-                />
-
-            <include layout="@layout/notification_top_line_views" />
-
-        </NotificationTopLineView>
-
         <LinearLayout
-            android:id="@+id/notification_main_column"
-            android:layout_width="match_parent"
+            android:id="@+id/notification_headerless_view_column"
+            android:layout_width="0px"
             android:layout_height="wrap_content"
-            android:layout_marginEnd="@dimen/notification_heading_margin_end"
-            android:layout_marginStart="@dimen/notification_content_margin_start"
+            android:layout_gravity="center_vertical"
+            android:layout_weight="1"
+            android:layout_marginBottom="@dimen/notification_headerless_margin_twoline"
+            android:layout_marginTop="@dimen/notification_headerless_margin_twoline"
             android:orientation="vertical"
             >
 
-            <com.android.internal.widget.NotificationVanishingFrameLayout
-                android:layout_width="match_parent"
+            <NotificationTopLineView
+                android:id="@+id/notification_top_line"
+                android:layout_width="wrap_content"
                 android:layout_height="@dimen/notification_headerless_line_height"
+                android:clipChildren="false"
+                android:theme="@style/Theme.DeviceDefault.Notification"
                 >
-                <!-- This is the simplest way to keep this text vertically centered without using
-                 gravity="center_vertical" which causes jumpiness in expansion animations. -->
-                <include
-                    layout="@layout/notification_template_text"
-                    android:layout_width="match_parent"
-                    android:layout_height="@dimen/notification_text_height"
-                    android:layout_gravity="center_vertical"
-                    android:layout_marginTop="0dp"
-                    />
-            </com.android.internal.widget.NotificationVanishingFrameLayout>
 
-            <include
-                layout="@layout/notification_template_progress"
+                <!--
+                NOTE: The notification_top_line_views layout contains the app_name_text.
+                In order to include the title view at the beginning, the Notification.Builder
+                has logic to hide that view whenever this title view is to be visible.
+                -->
+
+                <TextView
+                    android:id="@+id/title"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_marginEnd="@dimen/notification_header_separating_margin"
+                    android:ellipsize="marquee"
+                    android:fadingEdge="horizontal"
+                    android:singleLine="true"
+                    android:textAlignment="viewStart"
+                    android:textAppearance="@style/TextAppearance.DeviceDefault.Notification.Title"
+                    />
+
+                <include layout="@layout/notification_top_line_views" />
+
+            </NotificationTopLineView>
+
+            <LinearLayout
+                android:id="@+id/notification_main_column"
                 android:layout_width="match_parent"
-                android:layout_height="@dimen/notification_headerless_line_height"
-                />
+                android:layout_height="wrap_content"
+                android:orientation="vertical"
+                >
+
+                <com.android.internal.widget.NotificationVanishingFrameLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="@dimen/notification_headerless_line_height"
+                    >
+                    <!-- This is the simplest way to keep this text vertically centered without
+                     gravity="center_vertical" which causes jumpiness in expansion animations. -->
+                    <include
+                        layout="@layout/notification_template_text"
+                        android:layout_width="match_parent"
+                        android:layout_height="@dimen/notification_text_height"
+                        android:layout_gravity="center_vertical"
+                        android:layout_marginTop="0dp"
+                        />
+                </com.android.internal.widget.NotificationVanishingFrameLayout>
+
+                <include
+                    layout="@layout/notification_template_progress"
+                    android:layout_width="match_parent"
+                    android:layout_height="@dimen/notification_headerless_line_height"
+                    />
+
+            </LinearLayout>
 
         </LinearLayout>
 
+        <ImageView
+            android:id="@+id/right_icon"
+            android:layout_width="@dimen/notification_right_icon_size"
+            android:layout_height="@dimen/notification_right_icon_size"
+            android:layout_gravity="center_vertical|end"
+            android:layout_marginTop="@dimen/notification_right_icon_headerless_margin"
+            android:layout_marginBottom="@dimen/notification_right_icon_headerless_margin"
+            android:layout_marginStart="@dimen/notification_right_icon_content_margin"
+            android:background="@drawable/notification_large_icon_outline"
+            android:clipToOutline="true"
+            android:importantForAccessibility="no"
+            android:scaleType="centerCrop"
+            />
+
+        <FrameLayout
+            android:id="@+id/expand_button_touch_container"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:minWidth="@dimen/notification_content_margin_end"
+            >
+
+            <include layout="@layout/notification_expand_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_vertical|end"
+                />
+
+        </FrameLayout>
+
     </LinearLayout>
 
 </com.android.internal.widget.NotificationMaxHeightFrameLayout>
diff --git a/core/res/res/layout/notification_template_material_big_media.xml b/core/res/res/layout/notification_template_material_big_media.xml
index aa20ad3..ff64315 100644
--- a/core/res/res/layout/notification_template_material_big_media.xml
+++ b/core/res/res/layout/notification_template_material_big_media.xml
@@ -20,17 +20,8 @@
     android:id="@+id/status_bar_latest_event_content"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:background="#00000000"
     android:tag="bigMediaNarrow"
     >
-    <!-- The size will actually be determined at runtime -->
-    <ImageView
-        android:id="@+id/right_icon"
-        android:layout_width="0dp"
-        android:layout_height="0dp"
-        android:layout_gravity="top|end"
-        android:scaleType="centerCrop"
-        />
 
     <include
         layout="@layout/notification_template_header"
@@ -49,46 +40,27 @@
             android:id="@+id/notification_main_column"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:layout_marginTop="46dp"
+            android:layout_marginTop="@dimen/notification_content_margin_top"
             android:layout_marginStart="@dimen/notification_content_margin_start"
             android:layout_marginBottom="@dimen/notification_content_margin"
             android:layout_marginEnd="@dimen/notification_content_margin_end"
             android:orientation="vertical"
             >
-            <!-- TODO(b/172652345): fix the media style -->
-            <!--<include layout="@layout/notification_template_part_line1"/>-->
-            <!--<include layout="@layout/notification_template_text"/>-->
-
-            <TextView android:id="@+id/title"
-                android:textAppearance="@style/TextAppearance.DeviceDefault.Notification.Title"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:singleLine="true"
-                android:ellipsize="marquee"
-                android:fadingEdge="horizontal"
-                android:textAlignment="viewStart"
-                />
-
-            <com.android.internal.widget.ImageFloatingTextView
-                style="@style/Widget.DeviceDefault.Notification.Text"
-                android:id="@+id/text"
-                android:layout_width="match_parent"
-                android:layout_height="@dimen/notification_text_height"
-                android:layout_gravity="top"
-                android:layout_marginTop="0.5dp"
-                android:ellipsize="marquee"
-                android:fadingEdge="horizontal"
-                android:gravity="top"
-                android:singleLine="true"
-                android:textAlignment="viewStart"
-                />
+            <include layout="@layout/notification_template_part_line1"/>
+            <include layout="@layout/notification_template_text"/>
         </LinearLayout>
 
         <LinearLayout
             android:id="@+id/media_actions"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="-21dp"
+            android:paddingStart="44dp"
+            android:paddingEnd="44dp"
+            android:paddingBottom="@dimen/media_notification_actions_padding_bottom"
+            android:gravity="top"
             android:orientation="horizontal"
             android:layoutDirection="ltr"
-            style="@style/NotificationMediaActionContainer"
             >
 
             <include
@@ -117,10 +89,8 @@
                 />
         </LinearLayout>
 
-        <ViewStub
-            android:id="@+id/notification_media_seekbar_container"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            />
     </LinearLayout>
+
+    <include layout="@layout/notification_template_right_icon" />
+
 </com.android.internal.widget.MediaNotificationView>
diff --git a/core/res/res/layout/notification_template_material_media.xml b/core/res/res/layout/notification_template_material_media.xml
index 542e59d..2991b17 100644
--- a/core/res/res/layout/notification_template_material_media.xml
+++ b/core/res/res/layout/notification_template_material_media.xml
@@ -19,101 +19,173 @@
     android:id="@+id/status_bar_latest_event_content"
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:background="#00000000"
+    android:layout_height="@dimen/notification_min_height"
     android:tag="media"
     >
-    <ImageView android:id="@+id/right_icon"
-        android:layout_width="0dp"
-        android:layout_height="0dp"
-        android:adjustViewBounds="true"
-        android:layout_gravity="top|end"
+
+
+    <ImageView
+        android:id="@+id/left_icon"
+        android:layout_width="@dimen/notification_left_icon_size"
+        android:layout_height="@dimen/notification_left_icon_size"
+        android:layout_gravity="center_vertical|start"
+        android:layout_marginStart="@dimen/notification_left_icon_start"
+        android:background="@drawable/notification_large_icon_outline"
+        android:clipToOutline="true"
+        android:importantForAccessibility="no"
         android:scaleType="centerCrop"
-    />
-    <include layout="@layout/notification_template_header"
-        android:layout_width="match_parent"
-        android:layout_height="@dimen/media_notification_header_height"
+        android:visibility="gone"
         />
+
+    <com.android.internal.widget.CachingIconView
+        android:id="@+id/icon"
+        android:layout_width="@dimen/notification_icon_circle_size"
+        android:layout_height="@dimen/notification_icon_circle_size"
+        android:layout_gravity="center_vertical|start"
+        android:layout_marginStart="@dimen/notification_icon_circle_start"
+        android:background="@drawable/notification_icon_circle"
+        android:padding="@dimen/notification_icon_circle_padding"
+        />
+
+    <FrameLayout
+        android:id="@+id/alternate_expand_target"
+        android:layout_width="@dimen/notification_content_margin_start"
+        android:layout_height="match_parent"
+        android:layout_gravity="start"
+        android:importantForAccessibility="no"
+        />
+
     <LinearLayout
+        android:id="@+id/notification_headerless_view_row"
         android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="vertical"
-        android:id="@+id/notification_media_content"
+        android:layout_height="match_parent"
+        android:layout_marginStart="@dimen/notification_content_margin_start"
+        android:orientation="horizontal"
         >
+
         <LinearLayout
-            android:id="@+id/notification_main_column"
-            android:layout_width="match_parent"
+            android:id="@+id/notification_headerless_view_column"
+            android:layout_width="0px"
             android:layout_height="wrap_content"
-            android:orientation="horizontal"
-            android:layout_marginStart="@dimen/notification_content_margin_start"
-            android:layout_marginTop="46dp"
-            android:layout_alignParentTop="true"
-            android:tag="media"
+            android:layout_gravity="center_vertical"
+            android:layout_weight="1"
+            android:layout_marginBottom="@dimen/notification_headerless_margin_twoline"
+            android:layout_marginTop="@dimen/notification_headerless_margin_twoline"
+            android:orientation="vertical"
             >
+
+            <NotificationTopLineView
+                android:id="@+id/notification_top_line"
+                android:layout_width="wrap_content"
+                android:layout_height="@dimen/notification_headerless_line_height"
+                android:clipChildren="false"
+                android:theme="@style/Theme.DeviceDefault.Notification"
+                >
+
+                <!--
+                NOTE: The notification_top_line_views layout contains the app_name_text.
+                In order to include the title view at the beginning, the Notification.Builder
+                has logic to hide that view whenever this title view is to be visible.
+                -->
+
+                <TextView
+                    android:id="@+id/title"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_marginEnd="@dimen/notification_header_separating_margin"
+                    android:ellipsize="marquee"
+                    android:fadingEdge="horizontal"
+                    android:singleLine="true"
+                    android:textAlignment="viewStart"
+                    android:textAppearance="@style/TextAppearance.DeviceDefault.Notification.Title"
+                    />
+
+                <include layout="@layout/notification_top_line_views" />
+
+            </NotificationTopLineView>
+
             <LinearLayout
-                android:id="@+id/notification_content_container"
+                android:id="@+id/notification_main_column"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:layout_gravity="fill_vertical"
-                android:layout_weight="1"
-                android:paddingBottom="@dimen/notification_content_margin"
                 android:orientation="vertical"
                 >
-                <!-- TODO(b/172652345): fix the media style -->
-                <!--<include layout="@layout/notification_template_part_line1"/>-->
-                <!--<include layout="@layout/notification_template_text"/>-->
 
-                <TextView android:id="@+id/title"
-                    android:textAppearance="@style/TextAppearance.DeviceDefault.Notification.Title"
+                <com.android.internal.widget.NotificationVanishingFrameLayout
                     android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
-                    android:singleLine="true"
-                    android:ellipsize="marquee"
-                    android:fadingEdge="horizontal"
-                    android:textAlignment="viewStart"
+                    android:layout_height="@dimen/notification_headerless_line_height"
+                    >
+                    <!-- This is the simplest way to keep this text vertically centered without
+                     gravity="center_vertical" which causes jumpiness in expansion animations. -->
+                    <include
+                        layout="@layout/notification_template_text"
+                        android:layout_width="match_parent"
+                        android:layout_height="@dimen/notification_text_height"
+                        android:layout_gravity="center_vertical"
+                        android:layout_marginTop="0dp"
+                        />
+                </com.android.internal.widget.NotificationVanishingFrameLayout>
+
+                <include
+                    layout="@layout/notification_template_progress"
+                    android:layout_width="match_parent"
+                    android:layout_height="@dimen/notification_headerless_line_height"
                     />
 
-                <com.android.internal.widget.ImageFloatingTextView
-                    style="@style/Widget.DeviceDefault.Notification.Text"
-                    android:id="@+id/text"
-                    android:layout_width="match_parent"
-                    android:layout_height="@dimen/notification_text_height"
-                    android:layout_gravity="top"
-                    android:layout_marginTop="0.5dp"
-                    android:ellipsize="marquee"
-                    android:fadingEdge="horizontal"
-                    android:gravity="top"
-                    android:singleLine="true"
-                    android:textAlignment="viewStart"
-                    />
             </LinearLayout>
-            <LinearLayout
-                android:id="@+id/media_actions"
+
+        </LinearLayout>
+
+        <ImageView
+            android:id="@+id/right_icon"
+            android:layout_width="@dimen/notification_right_icon_size"
+            android:layout_height="@dimen/notification_right_icon_size"
+            android:layout_gravity="center_vertical|end"
+            android:layout_marginTop="@dimen/notification_right_icon_headerless_margin"
+            android:layout_marginBottom="@dimen/notification_right_icon_headerless_margin"
+            android:layout_marginStart="@dimen/notification_right_icon_content_margin"
+            android:background="@drawable/notification_large_icon_outline"
+            android:clipToOutline="true"
+            android:importantForAccessibility="no"
+            android:scaleType="centerCrop"
+            />
+
+        <LinearLayout
+            android:id="@+id/media_actions"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_vertical"
+            android:layoutDirection="ltr"
+            android:orientation="horizontal"
+            >
+            <include
+                layout="@layout/notification_material_media_action"
+                android:id="@+id/action0"
+                />
+            <include
+                layout="@layout/notification_material_media_action"
+                android:id="@+id/action1"
+                />
+            <include
+                layout="@layout/notification_material_media_action"
+                android:id="@+id/action2"
+                />
+        </LinearLayout>
+
+        <FrameLayout
+            android:id="@+id/expand_button_touch_container"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:minWidth="@dimen/notification_content_margin_end"
+            >
+
+            <include layout="@layout/notification_expand_button"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:layout_gravity="top|end"
-                android:layout_marginStart="10dp"
-                android:layoutDirection="ltr"
-                android:orientation="horizontal"
-                >
-                <include
-                    layout="@layout/notification_material_media_action"
-                    android:id="@+id/action0"
+                android:layout_gravity="center_vertical|end"
                 />
-                <include
-                    layout="@layout/notification_material_media_action"
-                    android:id="@+id/action1"
-                />
-                <include
-                    layout="@layout/notification_material_media_action"
-                    android:id="@+id/action2"
-                />
-            </LinearLayout>
-        </LinearLayout>
-        <ViewStub android:id="@+id/notification_media_seekbar_container"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_alignParentBottom="true"
-        />
+
+        </FrameLayout>
+
     </LinearLayout>
 </com.android.internal.widget.MediaNotificationView>
diff --git a/core/res/res/layout/resolver_empty_states.xml b/core/res/res/layout/resolver_empty_states.xml
index bdcfeb2..8594c33 100644
--- a/core/res/res/layout/resolver_empty_states.xml
+++ b/core/res/res/layout/resolver_empty_states.xml
@@ -84,7 +84,7 @@
     <TextView android:id="@+id/empty"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:background="?attr/colorBackgroundFloating"
+        android:background="?attr/colorBackground"
         android:text="@string/noApplications"
         android:padding="@dimen/chooser_edge_margin_normal"
         android:layout_marginBottom="56dp"
diff --git a/core/res/res/layout/resolver_list.xml b/core/res/res/layout/resolver_list.xml
index 6fde1df..d791598 100644
--- a/core/res/res/layout/resolver_list.xml
+++ b/core/res/res/layout/resolver_list.xml
@@ -68,7 +68,7 @@
         android:layout_alwaysShow="true"
         android:layout_width="match_parent"
         android:layout_height="1dp"
-        android:background="?attr/colorBackgroundFloating"
+        android:background="?attr/colorBackground"
         android:foreground="?attr/dividerVertical" />
 
     <FrameLayout
@@ -76,7 +76,7 @@
         android:visibility="gone"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:background="?attr/colorBackgroundFloating"/>
+        android:background="?attr/colorBackground"/>
 
     <TabHost
         android:id="@+id/profile_tabhost"
@@ -85,7 +85,7 @@
         android:layout_alignParentTop="true"
         android:layout_centerHorizontal="true"
         android:accessibilityTraversalAfter="@id/title"
-        android:background="?attr/colorBackgroundFloating">
+        android:background="?attr/colorBackground">
         <LinearLayout
             android:orientation="vertical"
             android:layout_width="match_parent"
@@ -101,7 +101,7 @@
                 android:visibility="gone"
                 android:layout_width="match_parent"
                 android:layout_height="1dp"
-                android:background="?attr/colorBackgroundFloating"
+                android:background="?attr/colorBackground"
                 android:foreground="?attr/dividerVertical"/>
             <FrameLayout
                 android:id="@android:id/tabcontent"
@@ -120,13 +120,13 @@
         android:layout_height="wrap_content"
         android:layout_alwaysShow="true"
         android:orientation="vertical"
-        android:background="?attr/colorBackgroundFloating"
+        android:background="?attr/colorBackground"
         android:layout_ignoreOffset="true">
         <View
             android:id="@+id/resolver_button_bar_divider"
             android:layout_width="match_parent"
             android:layout_height="1dp"
-            android:background="?attr/colorBackgroundFloating"
+            android:background="?attr/colorBackground"
             android:foreground="?attr/dividerVertical" />
         <LinearLayout
             android:id="@+id/button_bar"
diff --git a/core/res/res/layout/resolver_list_per_profile.xml b/core/res/res/layout/resolver_list_per_profile.xml
index 9410301..d6ca7ab 100644
--- a/core/res/res/layout/resolver_list_per_profile.xml
+++ b/core/res/res/layout/resolver_list_per_profile.xml
@@ -24,7 +24,7 @@
         android:layout_height="wrap_content"
         android:id="@+id/resolver_list"
         android:clipToPadding="false"
-        android:background="?attr/colorBackgroundFloating"
+        android:background="?attr/colorBackground"
         android:elevation="@dimen/resolver_elevation"
         android:nestedScrollingEnabled="true"
         android:scrollbarStyle="outsideOverlay"
diff --git a/core/res/res/layout/resolver_list_with_default.xml b/core/res/res/layout/resolver_list_with_default.xml
index 4a5aa02..7610e73 100644
--- a/core/res/res/layout/resolver_list_with_default.xml
+++ b/core/res/res/layout/resolver_list_with_default.xml
@@ -148,7 +148,7 @@
         android:layout_alwaysShow="true"
         android:layout_width="match_parent"
         android:layout_height="1dp"
-        android:background="?attr/colorBackgroundFloating"
+        android:background="?attr/colorBackground"
         android:foreground="?attr/dividerVertical" />
 
     <FrameLayout
@@ -157,7 +157,7 @@
         android:visibility="gone"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:background="?attr/colorBackgroundFloating"/>
+        android:background="?attr/colorBackground"/>
 
     <TabHost
         android:layout_alwaysShow="true"
@@ -166,7 +166,7 @@
         android:layout_height="wrap_content"
         android:layout_alignParentTop="true"
         android:layout_centerHorizontal="true"
-        android:background="?attr/colorBackgroundFloating">
+        android:background="?attr/colorBackground">
         <LinearLayout
             android:orientation="vertical"
             android:layout_width="match_parent"
@@ -182,7 +182,7 @@
                 android:visibility="gone"
                 android:layout_width="match_parent"
                 android:layout_height="1dp"
-                android:background="?attr/colorBackgroundFloating"
+                android:background="?attr/colorBackground"
                 android:foreground="?attr/dividerVertical"/>
             <FrameLayout
                 android:id="@android:id/tabcontent"
@@ -200,6 +200,6 @@
         android:layout_alwaysShow="true"
         android:layout_width="match_parent"
         android:layout_height="1dp"
-        android:background="?attr/colorBackgroundFloating"
+        android:background="?attr/colorBackground"
         android:foreground="?attr/dividerVertical" />
 </com.android.internal.widget.ResolverDrawerLayout>
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 7d7b731..39de289 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Skemerdiens"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Tydsonebespeurder (geen konnektiwiteit nie)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS-tydopdateringdiens"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Musiekherkenningbestuurderdiens"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Jou toestel sal uitgevee word"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Die administrasieprogram kan nie gebruik word nie. Jou toestel sal nou uitgevee word.\n\nKontak jou organisasie se administrateur as jy vrae het."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Druk is gedeaktiveer deur <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Program loop tans"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Programme wat batterykrag gebruik"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Vergroting"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Toeganklikheidsekuriteitbeleid"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> gebruik tans batterykrag"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> programme gebruik tans batterykrag"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Tik vir besonderhede oor battery- en datagebruik"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Laat die program toe om die statusbalk te wees."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"vou statusbalk in of uit"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Laat die program toe om die statusbalk uit te vou of in te vou."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"wys kennisgewings as volskermaktiwiteite op \'n geslote skerm"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Laat die program toe om kennisgewings as volskermaktiwiteite op \'n geslote toestel te wys"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"installeer kortpaaie"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Stel \'n program in staat om Tuisskerm-kortpaaie by te voeg sonder gebruikerinmenging."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"deïnstalleer kortpaaie"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Gebruik biometrie of skermslot"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Verifieer dat dit jy is"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Gebruik jou biometrie om voort te gaan"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Gebruik jou biometriese data of skermslot om voort te gaan"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometriese hardeware is nie beskikbaar nie"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Stawing is gekanselleer"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Nie herken nie"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Gebruik vingerafdruk"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Gebruik vingerafdruk of skermslot"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Gebruik jou vingerafdruk om voort te gaan"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Gebruik jou vingerafdruk of skermslot om voort te gaan"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Vingerafdrukikoon"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Gebruik gesigslot"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Gebruik gesig- of skermslot"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Gebruik gesigslot om voort te gaan"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Gebruik jou gesig of skermslot om voort te gaan"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Gesig-ikoon"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"Jy hoef nie toestemming te hê om hierdie bladsy oop te maak nie."</string>
     <string name="text_copied" msgid="2531420577879738860">"Teks na knipbord gekopieër."</string>
     <string name="copied" msgid="4675902854553014676">"Gekopieer"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> het uit <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> geplak"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> het uit knipbord geplak"</string>
     <string name="more_item_label" msgid="7419249600215749115">"Meer"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Kieslys+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Skakel af"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Gaan tans <xliff:g id="NAME">%s</xliff:g> na …"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Gaan tans huidige inhoud na"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Ontleed tans mediaberging"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Nuwe <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> werk nie"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Tik om op te stel"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Kies om op te stel"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Jy sal dalk die toestel moet herformateer. Tik om uit te skiet."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"Om foto\'s en media oor te dra"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Blaai deur medialêers"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Kwessie met <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> werk nie"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Tik om reg te stel"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"Niegesteunde <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> werk nie"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"Hierdie toestel steun nie hierdie <xliff:g id="NAME">%s</xliff:g> nie. Tik om in \'n gesteunde formaat op te stel."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"Hierdie toestel steun nie hierdie <xliff:g id="NAME">%s</xliff:g> nie. Kies om in \'n gesteunde formaat op te stel."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Kies om <xliff:g id="NAME">%s</xliff:g> in \'n gesteunde formaat op te stel."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Jy sal dalk die toestel moet herformateer"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> is onverwags verwyder"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Maak media los voordat jy dit verwyder om te keer dat jy inhoud verloor"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Gebruik kortpad"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Kleuromkering"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Kleurkorreksie"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Verminder helderheid"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Ekstra donker"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Het volumesleutels ingehou. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> aangeskakel."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Het volumesleutels ingehou. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> is afgeskakel"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Druk en hou albei volumesleutels drie sekondes lank om <xliff:g id="SERVICE_NAME">%1$s</xliff:g> te gebruik"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Toeganklikheidkortpad op skerm"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Toeganklikheidkortpadkieser op skerm"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Toeganklikheidkortpad"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Maak kennisgewingskerm toe"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g> se onderskrifbalk."</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> is in die BEPERK-groep geplaas"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Nuut: Venstervergrootglas"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Jy kan nou jou hele skerm of \'n deel daarvan vergroot"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Vergroot deel van jou skerm"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Jy kan nou jou hele skerm of \'n spesifieke area vergroot, of tussen die twee opsies wissel."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Skakel aan in Instellings"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Maak toe"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Om voort te gaan, moet &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; toegang tot jou toestel se mikrofoon hê."</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Sensorprivaatheid"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Programikoon"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Programhandelsmerkprent"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Gaan toeganginstellings na"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> kan jou skerm sien en beheer. Tik om na te gaan."</string>
 </resources>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 254ca9c..b8af80f 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"የውጋገን አገልግሎት"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"የሰዓት ሰቅ አንባቢ (ግንኙነት የለም)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"የGNSS ጊዜ ዝመኔ አገልግሎት"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"የሙዚቃ ለይቶ ማወቅ አስተዳዳሪ አገልግሎት"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"የእርስዎ መሣሪያ ይደመሰሳል"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"የአስተዳዳሪ መተግበሪያ ስራ ላይ ሊውል አይችልም። የእርስዎን መሣሪያ አሁን ይደመሰሳል።\n\nጥያቄዎች ካለዎት የድርጅትዎን አስተዳዳሪ ያነጋግሩ።"</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"ማተም በ<xliff:g id="OWNER_APP">%s</xliff:g> ተሰናክሏል።"</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"APP እየሠራ ነው"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"ባትሪ በመፍጀት ላይ ያሉ መተግበሪያዎች"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"ማጉላት"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"የተደራሽነት ደህንነት መመሪያ"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> ባትሪ እየተጠቀመ ነው"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> መተግበሪያዎች ባትሪ እየተጠቀሙ ነው"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"በባትሪ እና ውሂብ አጠቃቀም ላይ ዝርዝሮችን ለማግኘት መታ ያድርጉ"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"የኹናቴ አሞሌ እንዲሆን ለመተግበሪያው ይፈቅዳሉ።"</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"የሁኔታ አሞሌ ዘርጋ/ሰብስብ"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"የሁኔታ አሞሌን ለመዝረጋት እና ለመሰብሰብ ለመተግበሪያው ይፈቅዳሉ።"</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"በአንድ የተቆለፈ መሣሪያ ላይ ማሳወቂያዎችን እንደ የሙሉ ገጽ እይታ እንቅስቃሴዎችን ማሳየት"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"መተግበሪያው በአንድ የተቆለፈ መሣሪያ ላይ ማሳወቂያዎችን እንደ የሙሉ ገጽ እይታ እንቅስቃሴዎች አድርጎ እንዲያሳይ ያስችለዋል"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"አቋራጮችን ይጭናል"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"አንድ መተግበሪያ ያለተጠቃሚ ጣልቃ-ገብነት የመነሻ ማያ ገጽ አቋራጮችን እንዲያክል ያስችለዋል።"</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"አቋራጮችን ያራግፋል"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"ባዮሜትሪክስ ወይም ማያ ገጽ መቆለፊያን ይጠቀሙ"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"እርስዎን መሆንዎን ያረጋግጡ"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"ለመቀጠል ባዮሜትሪክዎን ይጠቀሙ"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"ለመቀጠል የባዮሜትሪክ ወይም የማያ ገጽ ቁልፍዎን ይጠቀሙ"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"ባዮሜትራዊ ሃርድዌር አይገኝም"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"ማረጋገጥ ተሰርዟል"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"አልታወቀም"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"የጣት አሻራ ይጠቀሙ"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"የጣት አሻራ ወይም የማያ ገጽ መቆለፊያ ይጠቀሙ"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"ለመቀጠል የእርስዎን የጣት አሻራ ይጠቀሙ"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"ለመቀጠል የጣት አሻራዎን ወይም የማያ ገጽ ቁልፍዎን ይጠቀሙ"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"የጣት አሻራ አዶ"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"በመልክ መክፈትን ይጠቀሙ"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"የመልክ ወይም የማያ ገጽ መቆለፊያን ይጠቀሙ"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"ለመቀጠል በመልክ መክፈትን ይጠቀሙ"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"ለመቀጠል መልክዎን ወይም የማያ ገጽዎን መቆለፊያ ይጠቀሙ"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"የፊት አዶ"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"ይህን ገጽ  ለመክፈት ፈቃድ የለህም።"</string>
     <string name="text_copied" msgid="2531420577879738860">"ፅሁፍ ወደ ቅንጥብ ሰሌዳ ተገልብጧል።"</string>
     <string name="copied" msgid="4675902854553014676">"ተቀድቷል"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ከ <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> ተለጥፏል"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ከቅንጣብ ሰሌዳ ተለጥፏል"</string>
     <string name="more_item_label" msgid="7419249600215749115">"ተጨማሪ"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"ምናሌ+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"አጥፋ"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"<xliff:g id="NAME">%s</xliff:g>ን በመፈተሽ ላይ…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"አሁን ያለ ይዘትን በመገምገም ላይ"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"የሚዲያ ማከማቻን በመተንተን ላይ"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"አዲስ <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> እየሠራ አይደለም"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"ለማዋቀር መታ ያድርጉ"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"ለማቀናበር ይምረጡ"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"መሣሪያውን ዳግም ቅርጸት መሥራት ሳያስፈልገዎት አይቀርም። ለማስወጣት መታ ያድርጉ።"</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"ፎቶዎችን እና ማህደረመረጃን ለማስተላለፍ"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"የሚዲያ ፋይሎችን ያስሱ"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"ከ<xliff:g id="NAME">%s</xliff:g> ጋር ችግር"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> እየሠራ አይደለም"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"ለማስተካከል መታ ያድርጉ"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"ያልተደገፈ <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> እየሠራ አይደለም"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"ይህ መሣሪያ ይህን <xliff:g id="NAME">%s</xliff:g> አይደግፍም። በሚደገፍ ቅርጸት ለማዘጋጀት መታ ያድርጉ።"</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"ይህ መሣሪያ ይህን <xliff:g id="NAME">%s</xliff:g> አይደግፍም። በሚደገፍ ቅርጸት ለማዘጋጀት ይምረጡ።"</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"<xliff:g id="NAME">%s</xliff:g>ን በሚደገፍ ቅርጸት ለማዋቀር ይምረጡ።"</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"መሣሪያውን ዳግም ቅርጸት መሥራት ሳያስፈልገዎት አይቀርም"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> ሳይታሰብ ተወግዷል"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"ይዘት መጥፋትን ለማስቅረት ከማስወገድ በፊት ማህደረ መረጃን ያስወጡ"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"አቋራጭ ይጠቀሙ"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"ተቃራኒ ቀለም"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"የቀለም ማስተካከያ"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"ብሩህነትን ይቀንሱ"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"የበለጠ ደብዛዛ"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"የድምፅ ቁልፎችን ይዟል። <xliff:g id="SERVICE_NAME">%1$s</xliff:g> በርቷል።"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"የድምፅ ቁልፎችን ይዟል። <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ጠፍተዋል።"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>ን ለመጠቀም ለሦስት ሰከንዶች ሁለቱንም የድምፅ ቁልፎች ተጭነው ይያዙ"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"የማያ ገጽ ላይ ተደራሽነት አቋራጭ"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"የማያ ገጽ ላይ ተደራሽነት አቋራጭ መራጭ"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"የተደራሽነት አቋራጭ"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"የማሳወቂያ ጥላን አሰናብት"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"የ<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> ወደ የRESTRICTED ባልዲ ተከትቷል"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>፦"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"አዲስ፦ የመስኮት ማጉያ"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"አሁን የተወሰነ ወይም ሁሉንም ማያ ገጽዎን ማጉላት ይችላሉ"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"የማያ ገጽዎን ክፍል ያጉሉ"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"አሁን የእርስዎን የሙሉ ገጽ እይታ፣ አንድ የተወሰነ ቦታ ማጉላት ወይም በሁለቱም አማራጮች መካከል መቀያየር ይችላሉ።"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"በቅንብሮች ውስጥ ያብሩ"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"አሰናብት"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"ለመቀጠል፣ &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ወደ መሳሪያዎ ማይክሮፎን መድረስ ይፈልጋል።"</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"ዳሳሽ ግላዊነት"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"የመተግበሪያ አዶ"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"የመተግበሪያ የምርት ስም ምስል"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"የመዳረሻ ቅንብሮችን ይፈትሹ"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> ማያ ገጽዎን ማየት እና መቆጣጠር ይችላል። ለመገምገም መታ ያድርጉ።"</string>
 </resources>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 89ed573..fc94e1c 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -212,6 +212,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"خدمة الغسق"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"أداة التعرّف على المنطقة الزمنية (ليس هناك حاجة للاتصال بالشبكة)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"‏خدمة تعديل وقت GNSS"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"خدمة إدارة التعرّف على الموسيقى"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"سيتم محو بيانات جهازك."</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"تعذّر استخدام تطبيق المشرف. سيتم محو بيانات جهازك الآن.\n\nإذا كانت لديك أسئلة، اتصل بمشرف مؤسستك."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"تم إيقاف الطباعة بواسطة <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -305,6 +306,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"التطبيق قيد التشغيل"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"التطبيقات التي تستهلك البطارية"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"التكبير"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"سياسة أمان \"تسهيل الاستخدام\""</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"يستخدم تطبيق <xliff:g id="APP_NAME">%1$s</xliff:g> البطارية"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"تستخدم <xliff:g id="NUMBER">%1$d</xliff:g> من التطبيقات البطارية"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"انقر للحصول على تفاصيل حول البطارية واستخدام البيانات"</string>
@@ -355,6 +357,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"للسماح للتطبيق بأن يكون شريط الحالة."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"توسيع/تصغير شريط الحالة"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"للسماح للتطبيق بتوسيع شريط الحالة أو تصغيره."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"عرض الإشعارات كأنشطة بملء الشاشة على الأجهزة المُقفَلة"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"السماح للتطبيق بعرض الإشعارات كأنشطة بملء الشاشة على الأجهزة المُقفَلة"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"تثبيت اختصارات"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"للسماح لتطبيق بإضافة اختصارات على الشاشة الرئيسية بدون تدخل المستخدم."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"إزالة الاختصارات"</string>
@@ -566,6 +570,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"استخدام المقاييس الحيوية أو قفل الشاشة"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"إثبات هويتك"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"استخدام المقاييس الحيوية للمتابعة"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"استخدام المقاييس الحيوية أو قفل الشاشة للمتابعة"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"معدّات المقاييس الحيوية غير متاحة."</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"تم إلغاء المصادقة."</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"لم يتم التعرف عليها."</string>
@@ -599,6 +604,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"استخدام بصمة الإصبع"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"استخدام بصمة الإصبع أو قفل الشاشة"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"يمكنك استخدام بصمة الإصبع للمتابعة."</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"استخدام بصمة الإصبع أو قفل الشاشة للمتابعة"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"رمز بصمة الإصبع"</string>
@@ -643,9 +649,10 @@
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"\"فتح القفل بالوجه\" غير متوفر على هذا الجهاز."</string>
     <string name="face_error_security_update_required" msgid="5076017208528750161">"تم إيقاف جهاز الاستشعار مؤقتًا."</string>
     <string name="face_name_template" msgid="3877037340223318119">"الوجه <xliff:g id="FACEID">%d</xliff:g>"</string>
-    <string name="face_app_setting_name" msgid="8130135875458467243">"استخدام ميزة \"فتح القفل بالوجه\""</string>
+    <string name="face_app_setting_name" msgid="8130135875458467243">"استخدام \"فتح القفل بالوجه\""</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"استخدام ميزة \"فتح القفل بالوجه\" أو ميزة \"قفل الشاشة\""</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"استخدام ميزة \"فتح القفل بالوجه\" للمتابعة"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"استخدام ميزة \"فتح القفل بالوجه\" أو ميزة \"قفل الشاشة\" للمتابعة"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"رمز الوجه"</string>
@@ -1009,6 +1016,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"ليس لديك إذن بفتح هذه الصفحة."</string>
     <string name="text_copied" msgid="2531420577879738860">"تم نسخ النص إلى الحافظة."</string>
     <string name="copied" msgid="4675902854553014676">"تم النسخ."</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"تم لصق محتوى في <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> من <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>."</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"تم لصق محتوى في <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> من الحافظة."</string>
     <string name="more_item_label" msgid="7419249600215749115">"المزيد"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"القائمة+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1450,11 +1459,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"إيقاف"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"جارٍ التحقق من <xliff:g id="NAME">%s</xliff:g>…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"جارٍ مراجعة المحتوى الحالي"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"جارٍ تحليل وحدة تخزين الوسائط"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"<xliff:g id="NAME">%s</xliff:g> جديدة"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> لا يعمل."</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"انقر للإعداد."</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"اختيار الوسائط لإعدادها"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"قد تحتاج إلى إعادة تنسيق الجهاز. انقر على إخراج."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"لنقل الصور والوسائط"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"تصفّح ملفات الوسائط"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"هناك مشكلة في <xliff:g id="NAME">%s</xliff:g>."</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> لا يعمل."</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"انقر للإصلاح"</string>
@@ -1463,7 +1475,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"<xliff:g id="NAME">%s</xliff:g> غير متوافق"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> لا يعمل."</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"هذا الجهاز غير متوافق مع <xliff:g id="NAME">%s</xliff:g> هذا. انقر للإعداد بتنسيق متوافق."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"لا يتوافق هذا الجهاز مع <xliff:g id="NAME">%s</xliff:g>. يمكنك النقر للإعداد بتنسيق متوافق."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"عليك الاختيار لإعداد \"<xliff:g id="NAME">%s</xliff:g>\" بتنسيق متوافق."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"قد تحتاج إلى إعادة تنسيق الجهاز."</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"تمت إزالة <xliff:g id="NAME">%s</xliff:g> بشكل غير متوقع"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"إخراج الوسائط قبل الإزالة لتجنّب فقدان المحتوى"</string>
@@ -1765,7 +1777,8 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"استخدام الاختصار"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"قلب الألوان"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"تصحيح الألوان"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"تقليل السطوع"</string>
+    <!-- no translation found for reduce_bright_colors_feature_name (3222994553174604132) -->
+    <skip />
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"تم الضغط مع الاستمرار على مفتاحَي التحكّم في مستوى الصوت. تم تفعيل <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"تم الضغط مع الاستمرار على مفتاحَي التحكّم في مستوى الصوت. تم إيقاف <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"اضغط مع الاستمرار على مفتاحي مستوى الصوت لمدة 3 ثوانٍ لاستخدام <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
@@ -2084,7 +2097,7 @@
     <string name="app_category_news" msgid="1172762719574964544">"الأخبار والمجلات"</string>
     <string name="app_category_maps" msgid="6395725487922533156">"الخرائط والتنقل"</string>
     <string name="app_category_productivity" msgid="1844422703029557883">"الإنتاجية"</string>
-    <string name="app_category_accessibility" msgid="6643521607848547683">"أدوات تمكين الوصول"</string>
+    <string name="app_category_accessibility" msgid="6643521607848547683">"أدوات تسهيل الاستخدام"</string>
     <string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"مساحة التخزين للجهاز"</string>
     <string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"‏تصحيح أخطاء USB"</string>
     <string name="time_picker_hour_label" msgid="4208590187662336864">"ساعة"</string>
@@ -2222,6 +2235,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"اختصار أدوات تمكين الوصول على الشاشة"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"أداة اختيار اختصارات أدوات تمكين الوصول على الشاشة"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"اختصارات أدوات تمكين الوصول"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"إغلاق مركز الإشعارات"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"شريط الشرح لتطبيق <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> في الحزمة \"محظورة\"."</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2359,8 +2373,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"‏جديد: Window Magnifier"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"يمكنك الآن تكبير الشاشة كلها أو جزء منها."</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"تكبير جزء من الشاشة"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"يمكنك الآن تكبير الشاشة كلها أو جزء معيّن منها أو التبديل بين الخيارين."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"التفعيل من خلال \"الإعدادات\""</string>
     <string name="dismiss_action" msgid="1728820550388704784">"إغلاق"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"‏للمتابعة، يحتاج &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; إلى الوصول إلى ميكروفون الجهاز."</string>
@@ -2369,4 +2383,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"الخصوصية في جهاز الاستشعار"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"رمز التطبيق"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"الصورة الذهنية للعلامة التجارية للتطبيق"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"التحقّق من إعدادات الوصول"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"يمكن لخدمة <xliff:g id="SERVICE_NAME">%s</xliff:g> الاطّلاع على شاشتك والتحكّم فيها. انقر لمراجعة الإعدادات."</string>
 </resources>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index 67d2ce0..caebacf 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Twilight সেৱা"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"সময় মণ্ডল চিনাক্তকাৰী (সংযোগ নাই)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS সময় আপডে’ট প্ৰদান কৰা সেৱা"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"সংগীত চিনাক্তকৰণ পৰিচালক সেৱা"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"আপোনাৰ ডিভাইচৰ ডেটা মচা হ\'ব"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"এই প্ৰশাসক এপটো ব্যৱহাৰ কৰিব নোৱাৰি। এতিয়া আপোনাৰ ডিভাইচটোৰ ডেটা মচা হ\'ব।\n\nআপোনাৰ কিবা প্ৰশ্ন থাকিলে আপোনাৰ প্ৰতিষ্ঠানৰ প্ৰশাসকৰ সৈতে যোগাযোগ কৰক।"</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"প্ৰিণ্ট কৰা কাৰ্য <xliff:g id="OWNER_APP">%s</xliff:g>এ অক্ষম কৰি ৰাখিছে।"</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"এপ্ চলি আছে"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"বেটাৰি খৰচ কৰা এপসমূহ"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"বিবৰ্ধন"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"সাধ্য সুবিধাৰ সুৰক্ষা নীতি"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g>এ বেটাৰি ব্যৱহাৰ কৰি আছে"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g>টা এপে বেটাৰি ব্যৱহাৰ কৰি আছে"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"বেটাৰি আৰু ডেটাৰ ব্যৱহাৰৰ বিষয়ে বিশদভাৱে জানিবলৈ টিপক"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"নিজকে স্থিতি দণ্ডৰূপে দেখুওৱাবলৈ এপটোক অনুমতি দিয়ে।"</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"স্থিতি দণ্ড সম্প্ৰসাৰিত বা সংকোচিত কৰক"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"স্থিতি দণ্ড বিস্তাৰিত বা সংকুচিত কৰিবলৈ এপটোক অনুমতি দিয়ে।"</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"কোনো লক কৰি ৰখা ডিভাইচত জাননী পূৰ্ণ স্ক্ৰীনৰ কাৰ্যকলাপ হিচাপে প্ৰদৰ্শন কৰক"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"এপ্‌টোক কোনো লক কৰি ৰখা ডিভাইচত জাননী পূৰ্ণ স্ক্ৰীনৰ কাৰ্যকলাপ হিচাপে প্ৰদৰ্শন কৰিবলৈ অনুমতি দিয়ে"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"শ্বৰ্টকাট ইনষ্টল কৰিব পাৰে"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"এটা এপ্লিকেশ্বনক ব্যৱহাৰকাৰীৰ হস্তক্ষেপৰ অবিহনে গৃহ স্ক্ৰীণ শ্বৰ্টকাট যোগ কৰিবলৈ অনুমতি দিয়ে।"</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"শ্বৰ্টকাট আনইনষ্টল কৰিব পাৰে"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"বায়\'মেট্ৰিক অথবা স্ক্ৰীন লক ব্যৱহাৰ কৰক"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"এইয়া আপুনিয়েই বুলি সত্যাপন কৰক"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"অব্যাহত ৰাখিবলৈ আপোনাৰ বায়\'মেট্ৰিক ব্যৱহাৰ কৰক"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"অব্যাহত ৰাখিবলৈ আপোনাৰ বায়’মেট্ৰিক অথবা স্ক্ৰীন লক ব্যৱহাৰ কৰক"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"বায়োমেট্ৰিক হাৰ্ডৱেৰ উপলব্ধ নহয়"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"বিশ্বাসযোগ্যতাৰ প্ৰমাণীকৰণ বাতিল কৰা হৈছে"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"চিনাক্ত কৰিব পৰা নাই"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ফিংগাৰপ্ৰিণ্ট ব্যৱহাৰ কৰক"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ফিংগাৰপ্ৰিণ্ট অথবা স্ক্ৰীন লক ব্যৱহাৰ কৰক"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"অব্যাহত ৰাখিবলৈ আপোনাৰ ফিংগাৰপ্ৰিণ্ট ব্যৱহাৰ কৰক"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"অব্যাহত ৰাখিবলৈ আপোনাৰ ফিংগাৰপ্ৰিণ্ট অথবা স্ক্ৰীন লক ব্যৱহাৰ কৰক"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"ফিংগাৰপ্ৰিণ্ট আইকন"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"মুখাৱয়বৰে আনলক কৰা ব্যৱহাৰ কৰক"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"মুখাৱয়বৰে আনলক কৰা অথবা স্ক্ৰীন লক ব্যৱহাৰ কৰক"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"অব্যাহত ৰাখিবলৈ মুখাৱয়বৰে আনলক কৰা ব্যৱহাৰ কৰক"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"অব্যাহত ৰাখিবলৈ আপোনাৰ মুখাৱয়ব অথবা স্ক্ৰীন লক ব্যৱহাৰ কৰক"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"মুখমণ্ডলৰ আইকন"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"এই পৃষ্ঠাটো খুলিবলৈ আপোনাৰ অনুমতি নাই।"</string>
     <string name="text_copied" msgid="2531420577879738860">"ক্লিপব\'র্ডলৈ বাৰ্তা প্ৰতিলিপি কৰা হ’ল।"</string>
     <string name="copied" msgid="4675902854553014676">"প্ৰতিলিপি কৰা হ’ল"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>ৰ পৰা <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> পে’ষ্ট কৰা হৈছে"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"ক্লিপব’ৰ্ডৰ পৰা <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> পে’ষ্ট কৰা হৈছে"</string>
     <string name="more_item_label" msgid="7419249600215749115">"অধিক"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"মেনু+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"মেটা+"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"অফ কৰক"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"<xliff:g id="NAME">%s</xliff:g> পৰীক্ষা কৰি থকা হৈছে…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"বৰ্তমানৰ সমলৰ সমীক্ষা কৰি থকা হৈছে"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"মিডিয়া ষ্ট’ৰেজ বিশ্লেষণ কৰি থকা হৈছে"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"নতুন <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g>এ কাম কৰা নাই"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"ছেট আপ কৰিবলৈ টিপক"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"ছেট আপ কৰিবলৈ বাছনি কৰক"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"আপুনি ডিভাইচটো পুনৰ ফৰ্মেট কৰিবলগীয়া হ’ব পাৰে। বাহিৰলৈ উলিয়াবলৈ টিপক।"</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"ফট\' আৰু মিডিয়া স্থানান্তৰণৰ বাবে"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"মিডিয়া ফাইল ব্ৰাউজ কৰক"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"<xliff:g id="NAME">%s</xliff:g>ত কিবা সমস্যা আছে"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g>এ কাম কৰা নাই"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"সমাধান কৰিবলৈ টিপক"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"<xliff:g id="NAME">%s</xliff:g>ক ব্যৱহাৰ কৰিব নোৱাৰি"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g>এ কাম কৰা নাই"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"এই ডিভাইচটোৱে <xliff:g id="NAME">%s</xliff:g>ক ব্যৱহাৰ কৰিব নোৱাৰে। ব্যৱহাৰ কৰিব পৰা ফৰ্মেটত ছেট আপ কৰিবলৈ টিপক।"</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"এই ডিভাইচটোৱে <xliff:g id="NAME">%s</xliff:g>ক চলাব নোৱাৰে। চলাব পৰা কোনো ফৰ্মেটত ছেট আপ কৰিবলৈ বাছনি কৰক।"</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"এটা সমৰ্থিত ফৰ্মেটত <xliff:g id="NAME">%s</xliff:g> ছেট আপ কৰিবলৈ বাছনি কৰক।"</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"আপুনি ডিভাইচটো পুনৰ ফৰ্মেট কৰিবলগীয়া হ’ব পাৰে"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> অপ্ৰত্য়াশিতভাৱে আঁতৰোৱা হ’ল"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"সমল হেৰুওৱাৰ পৰা হাত সাৰিবলৈ আঁতৰোৱাৰ আগতে মিডিয়া বাহিৰ কৰক"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"শ্বৰ্টকাট ব্যৱহাৰ কৰক"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"ৰং বিপৰীতকৰণ"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"ৰং শুধৰণী"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"উজ্জ্বলতা কমাওক"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"অতিৰিক্তভাৱে অনুজ্জ্বল"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ভলিউম কীসমূহ ধৰি ৰাখক। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> অন কৰা হ\'ল।"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ভলিউম কী ধৰি ৰাখিছিল। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> অফ কৰা হ\'ল।"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ব্যৱহাৰ কৰিবলৈ দুয়োটা ভলিউম বুটাম তিনি ছেকেণ্ডৰ বাবে হেঁচি ৰাখক"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"স্ক্ৰীনত সাধ্য সুবিধাৰ শ্বৰ্টকাট"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"স্ক্ৰীনত সাধ্য সুবিধাসমূহৰ শ্বৰ্টকাট বাছনি কৰাৰ সুবিধা"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"সাধ্য সুবিধাৰ শ্বৰ্টকাট"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"জাননী পেনেল অগ্ৰাহ্য কৰক"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<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>ক সীমাবদ্ধ বাকেটটোত ৰখা হৈছে"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"নতুন: ৱিণ্ড’ বিৱৰ্ধক"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"আপুনি সকলো অথবা কেইখনমান স্ক্ৰীন বিবৰ্ধন কৰিব পাৰে"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"আপোনাৰ স্ক্ৰীনখনৰ এটা অংশ বিবৰ্ধন কৰক"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"আপুনি এতিয়া আপোনাৰ পূৰ্ণ স্ক্ৰীন, কোনো নিৰ্দিষ্ট অংশ বিবৰ্ধন কৰিব পাৰে অথবা দুয়োটা বিকল্পৰ মাজত সলনা-সলনি কৰিব পাৰে।"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"ছেটিঙত অন কৰক"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"অগ্ৰাহ্য কৰক"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"অব্যাহত ৰাখিবলৈ &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt;এ আপোনাৰ ডিভাইচৰ মাইক্ৰ’ফ’ন এক্সেছ কৰাৰ আৱশ্যক।"</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"ছেন্সৰ সম্পৰ্কীয় গোপনীয়তাৰ নীতি"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"এপ্লিকেশ্বনৰ চিহ্ন"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"এপ্লিকেশ্বনৰ ব্ৰেণ্ডৰ প্ৰতিচ্ছবি"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"এক্সেছৰ ছেটিং পৰীক্ষা কৰক"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g>এ আপোনাৰ স্ক্ৰীনখন চাব আৰু পৰিচালনা কৰিব পাৰে। পৰ্যালোচনা কৰিবলৈ টিপক।"</string>
 </resources>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 76b5f1b..948b274 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Alaqaranlıq Xidməti"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Saat Qurşağı Aşkarlayıcısı (Bağlantı yoxdur)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS Zaman Güncəlləmə Xidməti"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Musiqi Tanıma Menecer Xidməti"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Cihazınız təmizlənəcəkdir"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Admin tətbiqini istifadə etmək mümkün deyil. Cihaz indi təmizlənəcək.\n\nSualınız varsa, təşkilatın admini ilə əlaqə saxlayın."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Çap <xliff:g id="OWNER_APP">%s</xliff:g> tərəfindən deaktiv edildi."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Tətbiq işləyir"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Batareyadan istifadə edən tətbiqlər"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Böyütmə"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Əlçatımlılıq güvənlik siyasəti"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> batareyadan istifadə edir"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> tətbiq batareyadan istifadə edir"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Batareya və data istifadəsi haqqında ətraflı məlumat üçün klikləyin"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Tətbiqə status paneli olmağa imkan verir."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"status panelini genişlətmək və ya yığmaq"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Tətbiqə status panelini genişləndirməyə və ya yox etməyə imkan verir."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"kilidlənmiş cihazda bildirişlərin tam ekran fəaliyyəti kimi göstərilməsi"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Tətbiqə kilidlənmiş cihazda bildirişləri tam ekran fəaliyyəti kimi göstərməyə icazə verir."</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"qısayolları quraşdır"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"İstifadəçi müdaxiləsi olmadan tətbiqə İş Stolu qısayolları əlavə etməyə icazə verir."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"qısayolları sistemdən sil"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Biometrik məlumatlardan və ya ekran kilidindən istifadə edin"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Kimliyinizi doğrulayın"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Davam etmək üçün biometrik məlumatlarınızdan istifadə edin"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Davam etmək üçün biometrik məlumatlar və ya ekran kilidinizdən istifadə edin"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrik proqram əlçatan deyil"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Doğrulama ləğv edildi"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Tanınmır"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Barmaq izindən istifadə edin"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Barmaq izi və ya ekran kilidindən istifadə edin"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Davam etmək üçün barmaq izinizi istifadə edin"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Davam etmək üçün barmaq izi və ya ekran kilidinizdən istifadə edin"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Barmaq izi ikonası"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Üz ilə kiliddən çıxarmadan istifadə edin"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Üz və ya ekran kilidindən istifadə edin"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Davam etmək üçün üz ilə kiliddən çıxarmadan istifadə edin"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Davam etmək üçün üz və ya ekran kilidinizdən istifadə edin"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Üz işarəsi"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"Bu səhifəni açmaq üçün icazəniz yoxdur."</string>
     <string name="text_copied" msgid="2531420577879738860">"Mətn panoya kopyalandı."</string>
     <string name="copied" msgid="4675902854553014676">"Kopyalandı"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> tətbiqindən əlavə edilib"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> mübadilə buferindən əlavə edilib"</string>
     <string name="more_item_label" msgid="7419249600215749115">"Digər"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Menyu+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Deaktiv edin"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"<xliff:g id="NAME">%s</xliff:g> yoxlanılır…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Cari kontent nəzərdən keçirilir"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Media yaddaşı təhlil olunur"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Yeni <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> işləmir"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Quraşdırmaq üçün klikləyin"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Ayarlamaq üçün seçin"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Cihazı yenidən formatlamaq tələb oluna bilər. Çıxarmaq üçün toxunun."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"Fotoların və medianın köçürülməsi üçün"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Media fayllarına nəzər salın"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"<xliff:g id="NAME">%s</xliff:g> ilə bağlı problem"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> işləmir"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Həll etmək üçün klikləyin"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"Dəstəklənməyən <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> işləmir"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"<xliff:g id="NAME">%s</xliff:g> bu cihaz tərəfindən dəstəklənmir. Dəstəklənən formatda ayarlamaq üçün tıklayın."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"<xliff:g id="NAME">%s</xliff:g> bu cihaz tərəfindən dəstəklənmir. Dəstəklənən formatda ayarlamaq üçün seçin."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"<xliff:g id="NAME">%s</xliff:g> elementinin dəstəklənən formatda ayarlanmasını seçin."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Cihazı yenidən formatlamaq tələb oluna bilər"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> gözlənilmədən çıxarıldı"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Kontenti itirməmək üçün silmədən öncə medianı çıxarın"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Qısayol İstifadə edin"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Rəng İnversiyası"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Rəng korreksiyası"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Parlaqlığı azaldın"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Əlavə qaraltma"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Səs səviyyəsi düymələrinə basıb saxlayın. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> aktiv edildi."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Səs səviyyəsi düymələrinə basılaraq saxlanıb. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> deaktiv edilib."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> istifadə etmək üçün hər iki səs düyməsini üç saniyə basıb saxlayın"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Ekranda Əlçatımlılıq Qısayolu"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Ekranda Əlçatımlılıq Qısayolu Seçicisi"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Əlçatımlılıq Qısayolu"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Bildiriş Göstərişini qapadın"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g> başlıq paneli."</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> MƏHDUDLAŞDIRILMIŞ səbətinə yerləşdirilib"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Yeni: Pəncərə Böyüdücüsü"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"İndi ekranı qismən və ya tam şəkildə böyüdə bilərsiniz"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Ekranın bir hissəsini böyüdün"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"İndi tam ekranı, müəyyən sahəni böyüdə və ya iki seçim arasında keçid edə bilərsiniz."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Ayarlarda aktiv edin"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Qapadın"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Davam etmək üçün &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; tətbiqi cihazın mikrofonuna giriş tələb edir."</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Sensor Məxfiliyi"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Tətbiq ikonası"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Tətbiqin brend şəkli"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Giriş ayarlarını yoxlayın"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> ekranınıza baxa və nəzarət edə bilər. Nəzərdən keçirmək üçün toxunun."</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 97781c7..9c18a07 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -206,6 +206,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Usluga Sumrak"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Detektor vremenske zone (nema internet veze)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS usluga za ažuriranje vremena"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Usluga Menadžer prepoznavanja muzike"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Uređaj će biti obrisan"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Ne možete da koristite ovu aplikaciju za administratore. Uređaj će sada biti obrisan.\n\nAko imate pitanja, kontaktirajte administratora organizacije."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Štampanje je onemogućila aplikacija <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -296,6 +297,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Aktivna aplikacija"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Aplikacije koje troše bateriju"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Uvećanje"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Bezbednosne smernice za pristupačnost"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> koristi bateriju"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"Aplikacije (<xliff:g id="NUMBER">%1$d</xliff:g>) koriste bateriju"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Dodirnite za detalje o bateriji i potrošnji podataka"</string>
@@ -346,6 +348,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Dozvoljava aplikaciji da funkcioniše kao statusna traka."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"proširenje/skupljanje statusne trake"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Dozvoljava aplikaciji da proširuje ili skuplja statusnu traku."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"prikazuje obaveštenja kao aktivnosti preko celog ekrana na zaključanom uređaju"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Omogućava aplikaciji da na zaključanom uređaju prikazuje obaveštenja kao aktivnosti preko celog ekrana."</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"instaliranje prečica"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Omogućava aplikaciji da dodaje prečice na početni ekran bez intervencije korisnika."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"deinstaliranje prečica"</string>
@@ -557,6 +561,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Koristite biometriju ili zaključavanje ekrana"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Potvrdite svoj identitet"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Koristite biometrijski podatak da biste nastavili"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Koristite biometrijski podatak ili zaključavanje ekrana da biste nastavili"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrijski hardver nije dostupan"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Potvrda identiteta je otkazana"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Nije prepoznato"</string>
@@ -590,6 +595,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Koristite otisak prsta"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Koristite otisak prsta ili zaključavanje ekrana"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Nastavite pomoću otiska prsta"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Koristite otisak prsta ili zaključavanje ekrana da biste nastavili"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikona otiska prsta"</string>
@@ -637,6 +643,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Koristite otključavanje licem"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Koristite zaključavanje licem ili zaključavanje ekrana"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Koristite otključavanje licem da biste nastavili"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Koristite lice ili zaključavanje ekrana da biste nastavili"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Ikona lica"</string>
@@ -1000,6 +1007,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"Nemate dozvolu da otvorite ovu stranicu."</string>
     <string name="text_copied" msgid="2531420577879738860">"Tekst je kopiran u privremenu memoriju."</string>
     <string name="copied" msgid="4675902854553014676">"Kopirano je"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"Aplikacija<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> je nalepila podatke iz aplikacije <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"Aplikacija<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> nalepila podatke iz privremene memorije"</string>
     <string name="more_item_label" msgid="7419249600215749115">"Još"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Meni+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1390,11 +1399,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Isključi"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Proverava se <xliff:g id="NAME">%s</xliff:g>…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Pregleda se aktuelni sadržaj"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Analizira se memorijski prostor za medije"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Novi/a <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> ne radi"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Dodirnite da biste podesili"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Izaberite da biste podesili"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Možda morate da reformatirate uređaj. Dodirnite da biste izbacili."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"Za prenos slika i medija"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Pregledajte medijske fajlove"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Problem sa: <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> ne radi"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Dodirnite da biste ispravili"</string>
@@ -1403,7 +1415,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"Uređaj <xliff:g id="NAME">%s</xliff:g> nije podržan"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> ne radi"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"Ovaj uređaj ne podržava ovaj uređaj <xliff:g id="NAME">%s</xliff:g>. Dodirnite da biste podesili podržani format."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"Ovaj uređaj ne podržava ovaj medij (<xliff:g id="NAME">%s</xliff:g>). Izaberite da ga podesite u podržanom formatu."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Izaberite da biste podesili uređaj <xliff:g id="NAME">%s</xliff:g> u podržanom formatu."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Možda morate da reformatirate uređaj"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"Uređaj <xliff:g id="NAME">%s</xliff:g> je neočekivano uklonjen"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Izbacite medijum pre nego što ga uklonite da ne biste izgubili sadržaj"</string>
@@ -1699,7 +1711,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Koristi prečicu"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Inverzija boja"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Korekcija boja"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Smanjite osvetljenost"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Dodatno zatamnjeno"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Držali ste tastere za jačinu zvuka. Usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je uključena."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Držali ste tastere za jačinu zvuka. Usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je isključena."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Pritisnite i zadržite oba tastera za jačinu zvuka tri sekunde da biste koristili <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -2120,6 +2132,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Prečica za pristupačnost na ekranu"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Alatka za biranje prečica za pristupačnost na ekranu"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Prečica za pristupačnost"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Odbaci traku sa obaveštenjima"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Traka sa naslovima aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Paket <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> je dodat u segment OGRANIČENO"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2257,8 +2270,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Novo: Lupa za prozor"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Možete da uvećate deo ekrana ili ceo ekran"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Uvećajte prikaz dela ekrana"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Sada možete da uvećate ceo ekran, određenu oblast ili da prelazite sa jedne opcije na drugu."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Uključite u Podešavanjima"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Odbaci"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"&lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; zahteva pristup mikrofonu uređaja radi nastavljanja."</string>
@@ -2267,4 +2280,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privatnost senzora"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Ikona aplikacije"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Imidž brenda aplikacije"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Proverite podešavanja pristupa"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> može da pregleda i kontroliše ekran. Dodirnite da biste pregledali."</string>
 </resources>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 3267247..5175f47 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -208,6 +208,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Служба Twilight"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Дэтэктар часавога пояса (няма падключэння)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"Служба абнаўлення часу GNSS"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Сэрвіс кіравання распазнаваннем музыкі"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Даныя вашай прылады будуць сцерты"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Немагчыма выкарыстоўваць праграму адміністравання. Звесткі на вашай прыладзе будуць выдалены.\n\nКалі ў вас ёсць пытанні, звярніцеся да адміністратара арганізацыі."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Друк адключаны ўладальнікам праграмы <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -299,6 +300,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Праграма працуе"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Праграмы, якія выкарыстоўваюць акумулятар"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Павелічэнне"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Палітыка бяспекі спецыяльных магчымасцей"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> выкарыстоўвае акумулятар"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"Наступная колькасць праграм выкарыстоўваюць акумулятар: <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Дакраніцеся, каб даведацца пра выкарыстанне трафіка і акумулятара"</string>
@@ -349,6 +351,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Дазваляе прыкладанням быць радком стану."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"разгарнуць/згарнуць радок стану"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Дазваляе прыкладанню разгортваць ці згортваць радок стану."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"паказваць апавяшчэнні ў поўнаэкранным рэжыме на заблакіраванай прыладзе"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Дазваляе праграме паказваць апавяшчэнні ў поўнаэкранным рэжыме на заблакіраванай прыладзе"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"усталёўваць ярлыкі"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Дазваляе праграме дадаваць ярлыкі на Галоўны экран без умяшання карыстальніка."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"выдаляць ярлыкі"</string>
@@ -560,6 +564,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Выкарыстоўваць біяметрыю ці блакіроўку экрана"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Спраўдзіце, што гэта вы"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Каб працягнуць, скарыстайце свае біяметрычныя даныя"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Каб працягнуць, скарыстайце біяметрычныя даныя ці сродак разблакіроўкі экрана"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Біяметрычнае абсталяванне недаступнае"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Аўтэнтыфікацыя скасавана"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Не распазнана"</string>
@@ -593,6 +598,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Выкарыстоўваць адбітак пальца"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Выкарыстоўваць адбітак пальца ці блакіроўку экрана"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Каб працягнуць, выкарыстоўвайце свой адбітак пальца"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Каб працягнуць, скарыстайце адбітак пальца ці сродак разблакіроўкі экрана"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Значок адбіткаў пальцаў"</string>
@@ -640,6 +646,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Ужываць распазнаванне твару"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Выкарыстоўваць распазнаванне твару ці блакіроўку экрана"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Каб працягнуць, скарыстайце распазнаванне твару"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Каб працягнуць, скарыстайце распазнаванне твару ці сродак разблакіроўкі экрана"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Значок твару"</string>
@@ -1003,6 +1010,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"У вас няма дазволу на адкрыццё гэтай старонкі."</string>
     <string name="text_copied" msgid="2531420577879738860">"Тэкст скапіраваны ў буфер абмену."</string>
     <string name="copied" msgid="4675902854553014676">"Скапіравана"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"Праграма \"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>\" была ўстаўлена з праграмы \"<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>\""</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"Праграма \"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>\" была ўстаўлена з буфера абмену"</string>
     <string name="more_item_label" msgid="7419249600215749115">"Больш"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Меню+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta +"</string>
@@ -1410,11 +1419,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Выключыць"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Правяраецца носьбіт <xliff:g id="NAME">%s</xliff:g>…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Правяраецца змесціва"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Ідзе аналіз сховішча мультымедыя"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Знойдзена новая прылада: <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> не працуе"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Дакраніцеся, каб наладзіць"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Выберыце, каб наладзіць"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Магчыма, вам спатрэбіцца перафармаціраваць прыладу. Націсніце, каб выняць."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"Для перадачы фатаграфій і медыяфайлаў"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Пошук медыяфайлаў"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Праблема з носьбітам (<xliff:g id="NAME">%s</xliff:g>)"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> не працуе"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Націсніце, каб выправіць"</string>
@@ -1423,7 +1435,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"<xliff:g id="NAME">%s</xliff:g> не падтрымліваецца"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> не працуе"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"Гэта прылада не падтрымлівае носьбіт <xliff:g id="NAME">%s</xliff:g>. Дакраніцеся, каб наладзіць яго ў фармаце, які падтрымліваецца."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"Гэта прылада не падтрымлівае носьбіт <xliff:g id="NAME">%s</xliff:g>. Выберыце, каб наладзіць яго ў фармаце, які падтрымліваецца."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Выберыце, каб задаць для носьбіта \"<xliff:g id="NAME">%s</xliff:g>\" фармат, які падтрымліваецца."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Магчыма, вам спатрэбіцца перафармаціраваць прыладу"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"Носьбіт <xliff:g id="NAME">%s</xliff:g> нечакана выняты"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Адключыце носьбіт перад тым, як дастаць яго, каб не страціць змесціва"</string>
@@ -1721,7 +1733,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Выкарыстоўваць камбінацыю хуткага доступу"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Інверсія колеру"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Карэкцыя колеру"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Паменшыць яркасць"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Дадатковае памяншэнне яркасці"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Клавішы гучнасці ўтрымліваліся націснутымі. Уключана служба \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\"."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Клавішы гучнасці ўтрымліваліся націснутымі. Служба \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\" выключана."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Каб карыстацца сэрвісам \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\", націсніце і ўтрымлівайце на працягу трох секунд абедзве клавішы гучнасці"</string>
@@ -1733,7 +1745,7 @@
     <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Каб пераключыцца на іншую функцыю, правядзіце ўверх трыма пальцамі і ўтрымлівайце іх на экране."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Павелічэнне"</string>
     <string name="user_switched" msgid="7249833311585228097">"Бягучы карыстальнік <xliff:g id="NAME">%1$s</xliff:g>."</string>
-    <string name="user_switching_message" msgid="1912993630661332336">"Пераход да <xliff:g id="NAME">%1$s</xliff:g>..."</string>
+    <string name="user_switching_message" msgid="1912993630661332336">"Пераход у рэжым \"<xliff:g id="NAME">%1$s</xliff:g>\"..."</string>
     <string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> выходзіць з сістэмы…"</string>
     <string name="owner_name" msgid="8713560351570795743">"Уладальнік"</string>
     <string name="error_message_title" msgid="4082495589294631966">"Памылка"</string>
@@ -2154,6 +2166,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Хуткі доступ да спецыяльных магчымасцей на экране"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Налада хуткага доступу да спецыяльных магчымасцей на экране"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Хуткі доступ"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Закрыць шчыток апавяшчэнняў"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Панэль субцітраў праграмы \"<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>\" дададзены ў АБМЕЖАВАНУЮ групу"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2291,8 +2304,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Новая функцыя Window Magnifier"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Цяпер можна павялічваць увесь экран ці яго частку."</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Павялічыць частку экрана"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Цяпер можна павялічваць увесь экран, яго пэўную частку ці пераключацца паміж гэтымі двума варыянтамі."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Уключыць у Наладах"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Адхіліць"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Каб працягнуць, дайце праграме &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; доступ да мікрафона прылады."</string>
@@ -2301,4 +2314,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Прыватнасць інфармацыі з датчыка"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Значок праграмы"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Відарыс брэнда праграмы"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Праверце налады доступу"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> можа праглядаць экран вашай прылады і кіраваць ім. Націсніце, каб праглядзець."</string>
 </resources>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index ac55c91..0b3e04a 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Услуга Twilight"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Инструмент за установяване на часовата зона (няма връзка)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"Услуга на GNSS за актуализиране на часа"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Услуга за управление на разпознаването на музика"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Данните на устройството ви ще бъдат изтрити"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Приложението за администриране не може да се използва. Сега данните на устройството ви ще бъдат изтрити.\n\nАко имате въпроси, свържете се с администратора на организацията си."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Отпечатването е деактивиранo от <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Приложението работи"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Приложения, използващи батерията"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Увеличение"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Правила за сигурност на услугите за достъпност"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> използва батерията"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> приложения използват батерията"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Докоснете за информация относно използването на батерията и преноса на данни"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Разрешава на приложението да бъде лентата на състоянието."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"разгъване или свиване на лентата на състоянието"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Разрешава на приложението да разгъва или свива лентата на състоянието."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"показване на известия като активности на цял екран на заключено устройство"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Дава възможност на приложението да показва известия като активности на цял екран на заключено устройство"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"инсталиране на преки пътища"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Разрешава на приложението да добавя към началния екран преки пътища без намеса на потребителя."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"деинсталиране на преки пътища"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Използване на биометрични данни или опцията за заключване на екрана"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Потвърдете, че сте вие"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Използвайте биометричните си данни, за да продължите"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Използвайте биометричните си данни или опцията за заключване на екрана, за да продължите"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Биометричният хардуер не е налице"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Удостоверяването бе анулирано"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Не е разпознато"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Използване на отпечатък"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Използване на отпечатък или опцията за заключване на екрана"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Използвайте отпечатъка си, за да продължите"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Използвайте отпечатъка си или опцията за заключване на екрана, за да продължите"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Икона за отпечатък"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Използване на отключв. с лице"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Използване на отключването с лице или опцията за заключване на екрана"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Използвайте функцията за отключване с лице, за да продължите"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Използвайте лицето си или опцията за заключване на екрана, за да продължите"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Икона на лице"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"Нямате разрешение да отворите тази страница."</string>
     <string name="text_copied" msgid="2531420577879738860">"Текстът е копиран в буферната памет."</string>
     <string name="copied" msgid="4675902854553014676">"Копирано"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> постави данни от <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> постави данни от буферната памет"</string>
     <string name="more_item_label" msgid="7419249600215749115">"Още"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Меню+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Изключване"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"<xliff:g id="NAME">%s</xliff:g> се проверява…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Текущото съдържание се преглежда"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Хранилището за мултимедия се анализира"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Ново хранилище (<xliff:g id="NAME">%s</xliff:g>)"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> не работи"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Докоснете, за да настроите"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Изберете, за да настроите"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Може да е необходимо да форматирате отново устройството. Докоснете, за да извадите."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"За прехвърляне на снимки и мултимедия"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Преглед на мултимедийните файлове"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Проблем с хранилището (<xliff:g id="NAME">%s</xliff:g>)"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> не работи"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Докоснете за коригиране"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"<xliff:g id="NAME">%s</xliff:g>: Не се поддържа"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> не работи"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"Устройството не поддържа този носител (<xliff:g id="NAME">%s</xliff:g>). Докоснете, за да настроите в поддържан формат."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"Устройството не поддържа този носител (<xliff:g id="NAME">%s</xliff:g>). Изберете, за да настроите в поддържан формат."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Изберете, за да настроите <xliff:g id="NAME">%s</xliff:g> в поддържан формат."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Може да е необходимо да форматирате отново устройството"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g>: Неочаквано премахване"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Спрете носителя, преди да го премахнете, за да избегнете загубата на съдържание"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Използване на пряк път"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Инвертиране на цветовете"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Коригиране на цветовете"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Намаляване на яркостта"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Допълнително затъмняване"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Задържахте бутоните за силата на звука. Услугата <xliff:g id="SERVICE_NAME">%1$s</xliff:g> е включена."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Задържахте бутоните за силата на звука. Услугата <xliff:g id="SERVICE_NAME">%1$s</xliff:g> е изключена."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"За да използвате <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, натиснете двата бутона за силата на звука и ги задръжте за 3 секунди"</string>
@@ -1689,9 +1701,9 @@
     <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"За превключване между функциите прекарайте три пръста нагоре и задръжте."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ниво на мащаба"</string>
     <string name="user_switched" msgid="7249833311585228097">"Текущ потребител <xliff:g id="NAME">%1$s</xliff:g>."</string>
-    <string name="user_switching_message" msgid="1912993630661332336">"Превключва се към <xliff:g id="NAME">%1$s</xliff:g>…"</string>
+    <string name="user_switching_message" msgid="1912993630661332336">"Превключва се към: <xliff:g id="NAME">%1$s</xliff:g>…"</string>
     <string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> излиза…"</string>
-    <string name="owner_name" msgid="8713560351570795743">"собственик"</string>
+    <string name="owner_name" msgid="8713560351570795743">"Собственик"</string>
     <string name="error_message_title" msgid="4082495589294631966">"Грешка"</string>
     <string name="error_message_change_not_allowed" msgid="843159705042381454">"Тази промяна не е разрешена от администратора ви"</string>
     <string name="app_not_found" msgid="3429506115332341800">"Няма намерено приложение за извършване на това действие"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Пряк път към достъпността на екрана"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Инструмент за избор на пряк път към достъпността на екрана"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Пряк път за достъпност"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Отхвърляне на падащия панел с известия"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Лента за надписи на <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> е поставен в ОГРАНИЧЕНИЯ контейнер"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Ново: Увеличаване на прозорци"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Можете да увеличите целия екран или част от него"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Увеличаване на част от екрана"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Вече можете да увеличавате целия екран или конкретна област от него, както и да превключвате между двете опции."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Включете от настройките"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Отхвърляне"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"За да продължите, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; се нуждае от достъп до микрофона на устройството ви."</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Поверителност на сензорните данни"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Икона на приложението"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Изображение на търговската марка на приложението"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Проверете настройките за достъп"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> може да преглежда и управлява съдържанието на екрана ви. Докоснете за преглед."</string>
 </resources>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index ff25441..678cb21 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"গোধূলি পরিষেবা"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"টাইম জোন ডিটেক্টর (কানেকশন নেই)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS সময় আপডেট পরিষেবা"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"সঙ্গীত স্বীকৃতি পরিচালনার পরিষেবা"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"আপনার ডিভাইসটি মুছে ফেলা হবে"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"অ্যাডমিন অ্যাপটি ব্যবহার করা যাবে না। আপনার ডিভাইসে থাকা সবকিছু এখন মুছে ফেলা হবে।\n\nকোনও প্রশ্ন থাকলে আপনার প্রতিষ্ঠানের অ্যাডমিনের সাথে যোগাযোগ করুন।"</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> প্রিন্টিং বন্ধ রেখেছে।"</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"অ্যাপ চলছে"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"কিছু অ্যাপ ব্যাটারি ব্যবহার করছে"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"বড় করে দেখুন"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"অ্যাক্সেসিবিলিটি সুরক্ষা নীতি"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> অ্যাপটি ব্যাটারি ব্যবহার করছে"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g>টি অ্যাপ ব্যাটারি ব্যবহার করছে"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"ব্যাটারি এবং ডেটার ব্যবহারের বিশদ বিবরণের জন্য ট্যাপ করুন"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"অ্যাপ্লিকেশানটিকে স্থিতি দন্ডে থাকতে দেয়৷"</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"স্ট্যাটাস বার সম্প্রসারিত/সঙ্কুচিত করে"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"অ্যাপ্লিকেশনটিকে স্ট্যাটাস বার প্রসারিত বা সঙ্কুচিত করতে দেয়৷"</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"লক করা ডিভাইসে ফুল স্ক্রিন অ্যাক্টিভিটি হিসাবে বিজ্ঞপ্তি দেখায়"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"এই অ্যাপকে লক করা ডিভাইসে ফুল স্ক্রিন অ্যাক্টিভিটি হিসাবে বিজ্ঞপ্তি দেখানোর অনুমতি দেয়"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"শর্টকাটগুলি ইনস্টল করে"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"একটি অ্যাপ্লিকেশানকে ব্যবহারকারীর হস্তক্ষেপ ছাড়াই হোমস্ক্রীণে শর্টকাটগুলি যোগ করার অনুমতি দেয়৷"</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"শর্টকাটগুলি আনইনস্টল করে"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"বায়োমেট্রিক্স অথবা স্ক্রিন লক ব্যবহার করুন"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"আপনার পরিচয় যাচাই করুন"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"চালিয়ে যেতে আপনার বায়োমেট্রিক্স ব্যবহার করুন"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"চালিয়ে যেতে আপনার বায়োমেট্রিক্স বা স্ক্রিন লক ব্যবহার করুন"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"বায়োমেট্রিক হার্ডওয়্যার পাওয়া যাবে না"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"যাচাইকরণ বাতিল হয়েছে"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"স্বীকৃত নয়"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"আঙ্গুলের ছাপ ব্যবহার করুন"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"আঙ্গুলের ছাপ অথবা স্ক্রিন লক ব্যবহার করুন"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"চালিয়ে যেতে আঙ্গুলের ছাপ ব্যবহার করুন"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"চালিয়ে যেতে আপনার আঙুলের ছাপ বা স্ক্রিন লক ব্য়বহার করুন"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"আঙ্গুলের ছাপ আইকন"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"মুখের সাহায্যে আনলক ব্যবহার করুন"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"মুখ অথবা স্ক্রিন লক ব্যবহার করুন"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"চালিয়ে যেতে মুখের সাহায্যে আনলক ব্যবহার করুন"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"চালিয়ে যেতে আপনার ফেস বা স্ক্রিন লক ব্যবহার করুন"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"ফেস আইকন"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"এই পৃষ্ঠাটি খোলার জন্য আপনার কাছে অনুমতি নেই৷"</string>
     <string name="text_copied" msgid="2531420577879738860">"ক্লিপবোর্ডে পাঠ্য অনুলিপি করা হয়েছে৷"</string>
     <string name="copied" msgid="4675902854553014676">"কপি করা হয়েছে"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> থেকে কপি করা ডেটা <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>-এ পেস্ট করা হয়েছে"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"ক্লিপবোর্ডের ডেটা <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>-এ পেস্ট করা হয়েছে"</string>
     <string name="more_item_label" msgid="7419249600215749115">"আরও"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"মেনু+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"বন্ধ করুন"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"<xliff:g id="NAME">%s</xliff:g> পরীক্ষা করা হচ্ছে…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"বর্তমান কন্টেন্টটি পর্যালোচনা করা হচ্ছে"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"মিডিয়া স্টোরেজ বিশ্লেষণ করা হচ্ছে"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"নতুন <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> কাজ করছে না"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"সেট-আপ করতে ট্যাপ করুন"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"সেটআপ করতে বেছে নিন"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"আপনাকে ডিভাইসটি আবার ফর্ম্যাট করতে হতে পারে। বের করে নিতে ট্যাপ করুন।"</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"ফটো এবং মিডিয়া ট্রান্সফার"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"মিডিয়া ফাইল ব্রাউজ করুন"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"<xliff:g id="NAME">%s</xliff:g> নিয়ে সমস্যা আছে"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> কাজ করছে না"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"ঠিক করতে ট্যাপ করুন"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"<xliff:g id="NAME">%s</xliff:g> অসমর্থিত"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> কাজ করছে না"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"এই ডিভাইসটি <xliff:g id="NAME">%s</xliff:g> সমর্থন করে না। কোনো সমর্থিত ফর্ম্যাটে সেট-আপ করতে আলতো চাপুন।"</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"এই ডিভাইসটি <xliff:g id="NAME">%s</xliff:g> সমর্থন করে না। কোনো সমর্থিত ফর্ম্যাটে সেট-আপ করতে চাইলে বেছে নিন।"</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"<xliff:g id="NAME">%s</xliff:g> সঠিক ফর্ম্যাটে সেটআপ করতে বেছে নিন।"</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"আপনাকে ডিভাইসটি আবার ফর্ম্যাট করতে হতে পারে"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> অপ্রত্যাশিতভাবে মুছে ফেলা হয়েছে"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"মিডিয়া সরিয়ে নেওয়ার আগে সেটি সিস্টেম থেকে ইজেক্ট করুন, নাহলে কন্টেন্ট সেভ নাও হতে পারে"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"শর্টকাট ব্যবহার করুন"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"রঙ উল্টানো"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"রঙ সংশোধন"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"উজ্জ্বলতা কমান"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"অতিরিক্ত কম আলো"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ভলিউম কী ধরে ছিলেন। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> চালু করা হয়েছে।"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ভলিউম কী ধরে ছিলেন। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> বন্ধ করা হয়েছে।"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ব্যবহার করতে ভলিউম কী বোতাম ৩ সেকেন্ডের জন্য চেপে ধরে রাখুন"</string>
@@ -1689,7 +1701,7 @@
     <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"একটি ফিচার থেকে অন্যটিতে যেতে, তিনটি আঙ্গুল দিয়ে উপরের দিকে সোয়াইপ করে ধরে থাকুন।"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"বড় করে দেখা"</string>
     <string name="user_switched" msgid="7249833311585228097">"বর্তমান ব্যবহারকারী <xliff:g id="NAME">%1$s</xliff:g>৷"</string>
-    <string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> নামের ব্যবহারকারীতে যাচ্ছে…"</string>
+    <string name="user_switching_message" msgid="1912993630661332336">"ব্যবহারকারী পরিবর্তন করে <xliff:g id="NAME">%1$s</xliff:g> করা হচ্ছে…"</string>
     <string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g>কে লগ-আউট করা হচ্ছে..."</string>
     <string name="owner_name" msgid="8713560351570795743">"মালিক"</string>
     <string name="error_message_title" msgid="4082495589294631966">"ত্রুটি"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"অন-স্ক্রিন অ্যাক্সেসিবিলিটি শর্টকাট"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"অন-স্ক্রিন অ্যাক্সেসিবিলিটি শর্টকাট বেছে নেওয়ার বিকল্প"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"অ্যাক্সেসিবিলিটি শর্টকাট"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"বিজ্ঞপ্তি শেড বাতিল করুন"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<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> সীমাবদ্ধ গ্রুপে অন্তর্ভুক্ত করা হয়েছে"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"নতুন: উইন্ডো ম্যাগনিফায়ার"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"এখন আপনি কিছু বা সবকটি স্ক্রিন বড় করে দেখতে পারেন"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"স্ক্রিনের কোনও অংশ বড় করে দেখা"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"এখন আপনি সম্পূর্ণ স্ক্রিন বা এর কোনও অংশ বড় করে দেখতে পারেন অথবা দুটি বিকল্পের মধ্যে পারস্পরিক পরিবর্তন করতে পারেন।"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"সেটিংস থেকে চালু করুন"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"বাতিল করুন"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"চালিয়ে যেতে, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; আপনার ডিভাইসের মাইক্রোফোন অ্যাক্সেস করতে চায়।"</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"সেন্সর গোপনীয়তা"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"অ্যাপের আইকন"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"অ্যাপের ব্র্যান্ড ছবি"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"অ্যাক্সেস করার সেটিংস চেক করুন"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> আপনার স্ক্রিন দেখতে ও কন্ট্রোল করতে পারবে। পর্যালোচনা করতে ট্যাপ করুন।"</string>
 </resources>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 25129e4..d6e0f32 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -206,6 +206,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Usluga Twilight"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Detektor vremenske zone (nije povezan)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS usluga za ažuriranje vremena"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Usluga upravitelja prepoznavanja muzike"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Uređaj će biti izbrisan"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Nije moguće koristiti aplikaciju administratora. Potpuno će se izbrisati podaci na vašem uređaju.\n\nAko imate pitanja, obratite se administratoru svoje organizacije."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Štampanje je onemogućila aplikacija <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -296,6 +297,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Pokrenuta aplikacija"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Aplikacije koje troše bateriju"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Uvećavanje"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Pravila o sigurnosti za pristupačnost"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> troši bateriju"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"Broj aplikacija koje troše bateriju: <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Dodirnite za detalje o potrošnji baterije i prijenosa podataka"</string>
@@ -346,6 +348,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Dozvoljava aplikaciji da postane statusna traka."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"proširivanje/sužavanje statusne trake"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Dozvoljava aplikaciji proširivanje ili sužavanje statusne trake."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"prikaz obavještenja kao aktivnosti preko cijelog ekrana na zaključanom uređaju"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Dozvoljava aplikaciji da prikazuje obavještenja kao aktivnosti preko cijelog ekrana na zaključanom uređaju"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"instaliranje prečica"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Omogućava aplikaciji dodavanje prečice za početni ekran bez intervencije korisnika."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"uklanjanje prečica"</string>
@@ -557,6 +561,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Koristi biometriju ili zaključavanje ekrana"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Potvrdite identitet"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Koristite biometriju da nastavite"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Koristite biometriju ili zaključavanje ekrana da nastavite"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrijski hardver nije dostupan"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Autentifikacija je otkazana"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Nije prepoznato"</string>
@@ -590,6 +595,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Koristi otisak prsta"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Koristi otisak prsta ili zaključavanje ekrana"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Nastavite pomoću otiska prsta"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Koristite otisak prsta ili zaključavanje ekrana da nastavite"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikona za otisak prsta"</string>
@@ -637,6 +643,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Koristi otključavanje licem"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Koristi otključavanje licem ili zaključavanje ekrana"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Koristite otključavanje licem da nastavite"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Koristite lice ili zaključavanje ekrana da nastavite"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Ikona lica"</string>
@@ -1000,6 +1007,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"Nemate odobrenje za otvaranje ove stranice."</string>
     <string name="text_copied" msgid="2531420577879738860">"Tekst kopiran u međumemoriju."</string>
     <string name="copied" msgid="4675902854553014676">"Kopirano"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"Aplikacija <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> je zalijepljena iz aplikacije <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"Aplikacija <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> je zalijepljena iz međumemorije"</string>
     <string name="more_item_label" msgid="7419249600215749115">"Više"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Meni+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1390,11 +1399,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Isključi"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Provjeravanje medija <xliff:g id="NAME">%s</xliff:g>…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Pregledanje trenutnog sadržaja"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Analiziranje pohrane za medije"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Novi medij <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> ne funkcionira"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Dodirnite za postavke"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Odaberite da postavite"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Možda ćete morati ponovo formatirati uređaj. Dodirnite da izbacite."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"Za prebacivanje slika i medijskih fajlova"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Pregledajte medijske fajlove"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Problem s medijem <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> ne funkcionira"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Dodirnite da popravite"</string>
@@ -1403,7 +1415,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"Uređaj <xliff:g id="NAME">%s</xliff:g> nije podržan"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> ne funkcionira"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"Ovaj uređaj ne podržava uređaj <xliff:g id="NAME">%s</xliff:g>. Dodirnite da biste ga postavili u podržanom formatu."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"Ovaj uređaj ne podržava uređaj <xliff:g id="NAME">%s</xliff:g>. Dodirnite da ga postavite u podržanom formatu."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Odaberite da postavite medij (<xliff:g id="NAME">%s</xliff:g>) u podržanom formatu."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Možda ćete morati ponovo formatirati uređaj"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"Neočekivano uklonjen uređaj <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Izbacite medij prije uklanjanja da izbjegnete gubitak sadržaja"</string>
@@ -1699,7 +1711,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Koristi prečicu"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Inverzija boja"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Ispravka boja"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Smanjenje osvjetljenja"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Dodatno zatamnjenje"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Držali ste tipke za jačinu zvuka. Usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je uključena."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Držali ste tipke za jačinu zvuka. Usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je isključena."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Pritisnite obje tipke za podešavanje jačine zvuka i držite ih pritisnutim tri sekunde da koristite uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -2120,6 +2132,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Prečica za pristupačnost na ekranu"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Okvir za odabir prečice za pristupačnost na ekranu"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Prečica za pristupačnost"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Odbacite lokaciju za obavještenja"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Traka za natpis aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Paket <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> je stavljen u odjeljak OGRANIČENO"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2257,8 +2270,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Novo: povećalo prozora"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Sada možete uvećati dio ekrana ili cijeli ekran"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Uvećajte dio ekrana"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Sada možete uvećati prikaz preko cijelog ekrana, željeno područje ili prebacivati s jedne opcije na drugu."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Uključite u Postavkama"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Odbaci"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Da nastavite, aplikaciji &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; je potreban pristup mikrofonu vašeg uređaja."</string>
@@ -2267,4 +2280,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privatnost senzora"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Ikona aplikacije"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Slika robne marke za aplikaciju"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Provjerite postavke pristupa"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> može pregledati i kontrolirati vaš ekran. Dodirnite da pregledate."</string>
 </resources>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 6f2af92..5f2904c 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Servei Twilight"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Detector de zona horària (sense connectivitat)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"Servei GNSS d\'actualització horària"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Servei de gestió de reconeixement de música"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"El contingut del dispositiu s\'esborrarà"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"No es pot utilitzar l\'aplicació d\'administració. S\'esborraran les dades del dispositiu.\n\nSi tens cap dubte, contacta amb l\'administrador de la teva organització."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> ha desactivat la impressió."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Aplicació en execució"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Aplicacions que consumeixen bateria"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Ampliació"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Política de seguretat de l\'accessibilitat"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> està consumint bateria"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> aplicacions estan consumint bateria"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Toca per obtenir informació sobre l\'ús de dades i de bateria"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Permet que l\'aplicació sigui la barra d\'estat."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"desplega/contrau la barra d\'estat"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Permet que l\'aplicació desplegui o replegui la barra d\'estat."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"mostrar notificacions com a activitats de pantalla completa en un dispositiu bloquejat"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Permet a l\'aplicació mostrar notificacions com a activitats de pantalla completa en un dispositiu bloquejat"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"instal·lar dreceres"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Permet que una aplicació afegeixi dreceres a la pantalla d\'inici sense la intervenció de l\'usuari."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"desinstal·la dreceres"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Fes servir la biometria o el bloqueig de pantalla"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Verifica que ets tu"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Utilitza la teva biometria per continuar"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Utilitza la biometria o el bloqueig de pantalla per continuar"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Maquinari biomètric no disponible"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"S\'ha cancel·lat l\'autenticació"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"No s\'ha reconegut"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Utilitza l\'empremta digital"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Utilitza l\'empremta digital o el bloqueig de pantalla"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Fes servir l\'empremta digital per continuar"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Utilitza l\'empremta digital o el bloqueig de pantalla per continuar"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Icona d\'empremta digital"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Utilitza el desbloqueig facial"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Utilitza el desbloqueig facial o de pantalla"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Utilitza el desbloqueig facial per continuar"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Utilitza la cara o el bloqueig de pantalla per continuar"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Icona facial"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"No tens permís per obrir aquesta pàgina."</string>
     <string name="text_copied" msgid="2531420577879738860">"Text copiat al Porta-retalls."</string>
     <string name="copied" msgid="4675902854553014676">"S\'ha copiat"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ha enganxat dades de: <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ha enganxat dades del porta-retalls"</string>
     <string name="more_item_label" msgid="7419249600215749115">"Més"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Menú+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1024,7 +1033,7 @@
       <item quantity="other">Darrers <xliff:g id="COUNT_1">%d</xliff:g> dies</item>
       <item quantity="one">Darrer dia (<xliff:g id="COUNT_0">%d</xliff:g>)</item>
     </plurals>
-    <string name="last_month" msgid="1528906781083518683">"El mes passat"</string>
+    <string name="last_month" msgid="1528906781083518683">"Darrer mes"</string>
     <string name="older" msgid="1645159827884647400">"Més antigues"</string>
     <string name="preposition_for_date" msgid="2780767868832729599">"el <xliff:g id="DATE">%s</xliff:g>"</string>
     <string name="preposition_for_time" msgid="4336835286453822053">"a les <xliff:g id="TIME">%s</xliff:g>"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Desactiva"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"S\'està comprovant el suport (<xliff:g id="NAME">%s</xliff:g>)…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"S\'està revisant el contingut actual"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"S\'està analitzant l\'emmagatzematge multimèdia"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Suport extern nou (<xliff:g id="NAME">%s</xliff:g>)"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> no funciona"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Toca per configurar"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Selecciona per configurar"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"És possible que hagis de reformatar el dispositiu. Toca per expulsar."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"Per transferir fotos i fitxers multimèdia"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Cerca fitxers multimèdia"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Problema amb el suport (<xliff:g id="NAME">%s</xliff:g>)"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> no funciona"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Toca per solucionar el problema"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"<xliff:g id="NAME">%s</xliff:g> no és compatible"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> no funciona"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"El dispositiu no admet <xliff:g id="NAME">%s</xliff:g>. Toca per configurar-la en un format compatible."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"Aquest dispositiu no admet <xliff:g id="NAME">%s</xliff:g>. Selecciona-la per configurar-la en un format compatible."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Selecciona per configurar <xliff:g id="NAME">%s</xliff:g> en un format compatible."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"És possible que hagis de reformatar el dispositiu"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"S\'ha extret <xliff:g id="NAME">%s</xliff:g> de manera inesperada"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Expulsa el suport extern abans d\'extreure\'l per evitar perdre\'n el contingut"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Utilitza la drecera"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversió de colors"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Correcció de color"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Reducció de la brillantor"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Extratènue"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"S\'han mantingut premudes les tecles de volum. S\'ha activat <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"S\'han mantingut premudes les tecles de volum. S\'ha desactivat <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Mantén premudes les dues tecles de volum durant 3 segons per fer servir <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -2072,7 +2084,7 @@
       <item quantity="other"><xliff:g id="FILE_NAME_2">%s</xliff:g> i <xliff:g id="COUNT_3">%d</xliff:g> fitxers més</item>
       <item quantity="one"><xliff:g id="FILE_NAME_0">%s</xliff:g> i <xliff:g id="COUNT_1">%d</xliff:g> fitxer més</item>
     </plurals>
-    <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"No hi ha cap recomanació de persones amb qui compartir"</string>
+    <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"No hi ha cap suggeriment de persones amb qui compartir"</string>
     <string name="chooser_all_apps_button_label" msgid="3230427756238666328">"Llista d\'aplicacions"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"Aquesta aplicació no té permís de gravació, però pot capturar àudio a través d\'aquest dispositiu USB."</string>
     <string name="accessibility_system_action_home_label" msgid="3234748160850301870">"Inici"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Drecera d\'accessibilitat en pantalla"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Selector de dreceres d\'accessibilitat en pantalla"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Drecera d\'accessibilitat"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Ignora l\'àrea de notificacions"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Barra de títol de l\'aplicació <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> s\'ha transferit al segment RESTRINGIT"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Novetat: Window Magnifier"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Ara pots ampliar la pantalla completa o una part"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Amplia una part de la pantalla"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Ara pots ampliar la pantalla completa o una àrea concreta, o canviar d\'una opció a l\'altra."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Activa a Configuració"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Ignora"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Per continuar, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; necessita accedir al micròfon del dispositiu."</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privadesa dels sensors"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Icona d\'aplicació"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Imatge de brànding de l\'aplicació"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Comprova la configuració d\'accés"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> pot veure i controlar la teva pantalla. Toca per revisar-ho."</string>
 </resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index bd98662..6732b96 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -208,6 +208,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Služba detekce soumraku"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Detektor časového pásma (bez připojení)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS – služba pro aktualizaci času"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Služba správy rozpoznávání hudby"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Zařízení bude vymazáno"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Aplikaci pro správu nelze použít. Zařízení teď bude vymazáno.\n\nV případě dotazů vám pomůže administrátor organizace."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Aplikace <xliff:g id="OWNER_APP">%s</xliff:g> tisk zakazuje."</string>
@@ -299,6 +300,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Aplikace je spuštěna"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Aplikace spotřebovávají baterii"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Zvětšení"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Zásady zabezpečení přístupnosti"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> využívá baterii"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"Aplikace (<xliff:g id="NUMBER">%1$d</xliff:g>) využívají baterii"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Klepnutím zobrazíte podrobnosti o využití baterie a dat"</string>
@@ -349,6 +351,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Umožňuje aplikaci být stavovým řádkem."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"rozbalení a sbalení stavového řádku"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Umožňuje aplikaci rozbalit či sbalit stavový řádek."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"zobrazovat oznámení na celé obrazovce zamčeného zařízení"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Umožňuje aplikaci zobrazovat oznámení na celé obrazovce zamčeného zařízení"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"instalace zástupců"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Umožňuje aplikaci přidat zástupce na plochu bez zásahu uživatele."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"odinstalace zástupců"</string>
@@ -560,6 +564,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Použít biometrii nebo zámek obrazovky"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Potvrďte, že jste to vy"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Pokračujte biometrickým ověřením"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Pokračujte ověřením pomocí biometrických údajů nebo zámku obrazovky"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrický hardware není k dispozici"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Ověření bylo zrušeno"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Nerozpoznáno"</string>
@@ -593,6 +598,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Použít otisk prstu"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Použít otisk prstu nebo zámek obrazovky"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Pokračujte přiložením prstu"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Pokračujte ověřením pomocí otisku prstu nebo zámku obrazovky"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikona otisku prstů"</string>
@@ -640,6 +646,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Použít odemknutí obličejem"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Použít odemknutí obličejem nebo zámek obrazovky"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Pokračujte odemknutím obličejem"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Pokračujte ověřením pomocí obličeje nebo zámku obrazovky"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Ikona obličeje"</string>
@@ -1003,6 +1010,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"Nemáte povolení otevřít tuto stránku."</string>
     <string name="text_copied" msgid="2531420577879738860">"Text byl zkopírován do schránky."</string>
     <string name="copied" msgid="4675902854553014676">"Zkopírováno"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"Aplikace <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> vložila data z aplikace <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"Aplikace <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> vložila data ze schránky"</string>
     <string name="more_item_label" msgid="7419249600215749115">"Více"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Menu+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1410,11 +1419,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Vypnout"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Kontroluje se <xliff:g id="NAME">%s</xliff:g>…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Kontrola aktuálního obsahu"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Analyzuje se úložiště médií"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Nové médium <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"Médium <xliff:g id="NAME">%s</xliff:g> nefunguje"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Klepnutím médium nastavíte"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Vyberte, pokud chcete nastavit"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Zařízení možná bude nutné znovu naformátovat. Klepnutím ho vyjmete."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"K přenosu fotek a médií"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Procházet soubory na médiu"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Problém s médiem <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"Médium <xliff:g id="NAME">%s</xliff:g> nefunguje"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Problém odstraníte klepnutím"</string>
@@ -1423,7 +1435,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"Úložiště <xliff:g id="NAME">%s</xliff:g> není podporováno"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"Médium <xliff:g id="NAME">%s</xliff:g> nefunguje"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"Úložiště <xliff:g id="NAME">%s</xliff:g> není v tomto zařízení podporováno. Klepnutím zahájíte nastavení v podporovaném formátu."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"Úložiště <xliff:g id="NAME">%s</xliff:g> není v tomto zařízení podporováno. Vyberte ho a zahajte nastavení v podporovaném formátu."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Vyberte, pokud chcete <xliff:g id="NAME">%s</xliff:g> nastavit v podporovaném formátu."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Zařízení možná bude nutné znovu naformátovat"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"Úložiště <xliff:g id="NAME">%s</xliff:g> neočekávaně odpojeno"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Před odebráním médium nejprve odpojte, zabráníte tak ztrátě obsahu"</string>
@@ -1721,7 +1733,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Použít zkratku"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Převrácení barev"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Oprava barev"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Snížit jas"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Velmi tmavé"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Byla podržena tlačítka hlasitosti. Služba <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je zapnutá."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Byla podržena tlačítka hlasitosti. Služba <xliff:g id="SERVICE_NAME">%1$s</xliff:g> byla vypnuta."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Chcete-li používat službu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, tři sekundy podržte stisknutá obě tlačítka hlasitosti"</string>
@@ -1733,7 +1745,7 @@
     <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Chcete-li přepnout mezi funkcemi, přejeďte nahoru třemi prsty a podržte je."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Zvětšení"</string>
     <string name="user_switched" msgid="7249833311585228097">"Aktuální uživatel je <xliff:g id="NAME">%1$s</xliff:g>."</string>
-    <string name="user_switching_message" msgid="1912993630661332336">"Přepínání na účet <xliff:g id="NAME">%1$s</xliff:g>…"</string>
+    <string name="user_switching_message" msgid="1912993630661332336">"Přepínání na uživatele <xliff:g id="NAME">%1$s</xliff:g>…"</string>
     <string name="user_logging_out_message" msgid="7216437629179710359">"Odhlašování uživatele <xliff:g id="NAME">%1$s</xliff:g>…"</string>
     <string name="owner_name" msgid="8713560351570795743">"Vlastník"</string>
     <string name="error_message_title" msgid="4082495589294631966">"Chyba"</string>
@@ -2154,6 +2166,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Zkratka přístupnosti na obrazovce"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Výběr zkratky přístupnosti na obrazovce"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Zkratka přístupnosti"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Zavřít panel oznámení"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Popisek aplikace <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Balíček <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> byl vložen do sekce OMEZENO"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2291,8 +2304,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Novinka: Zvětšení oken"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Nyní můžete zvětšit celou obrazovku nebo její část"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Zvětšit část obrazovky"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Teď můžete zvětšit celou obrazovku, její část nebo přepínat mezi oběma možnostmi."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Zapnout v Nastavení"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Zavřít"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Než budete pokračovat, udělte aplikaci &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; přístup k mikrofonu na zařízení."</string>
@@ -2301,4 +2314,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Ochrana soukromí – senzor"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Ikona aplikace"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Image značky aplikace"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Zkontrolujte nastavení přístupu"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> může zobrazit a ovládat tuto obrazovku. Klepnutím to zkontrolujete."</string>
 </resources>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 70492e0..9dcb4d5 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Tjenesten Twilight"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Tidszoneregistrering (ingen forbindelse)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"Tjeneste til opdatering af GNSS-tid"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Music Recognition Manager Service"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Enheden slettes"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Administrationsappen kan ikke bruges. Enheden vil nu blive ryddet. \n\nKontakt din organisations administrator, hvis du har spørgsmål."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Udskrivning er deaktiveret af <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Appen kører"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Apps, der bruger batteri"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Forstørrelse"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Sikkerhedspolitik for hjælpefunktioner"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> bruger batteri"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> apps bruger batteri"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Tryk for at se info om batteri- og dataforbrug"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Tillader, at appen er statusbjælken."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"udvid/skjul statuslinje"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Tillader, at appen kan udvide og skjule statusbjælken."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"Vis notifikationer som aktiviteter i fuld skærm på en låst enhed"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Tillader, at appen viser notifikationer som aktiviteter i fuld skærm på en låst enhed"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"installere genveje"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Tillader, at en applikation føjer genveje til startskærmen uden brugerindgriben."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"afinstaller genveje"</string>
@@ -556,6 +560,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Brug biometriske systemer eller skærmlås"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Bekræft, at det er dig"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Brug dine biometriske data for at fortsætte"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Brug dine biometriske data eller din skærmlås for at fortsætte"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrisk hardware er ikke tilgængelig"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Godkendelsen blev annulleret"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Ikke genkendt"</string>
@@ -589,6 +594,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Brug fingeraftryk"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Brug fingeraftryk eller skærmlås"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Brug dit fingeraftryk for at fortsætte"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Brug dit fingeraftryk eller din skærmlås for at fortsætte"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikon for fingeraftryk"</string>
@@ -636,6 +642,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Brug ansigtslås"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Brug ansigts- eller skærmlås"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Brug ansigtslås for at fortsætte"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Brug din ansigts- eller skærmlås for at fortsætte"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Ansigt"</string>
@@ -999,6 +1006,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"Du har ikke tilladelse til at åbne denne side."</string>
     <string name="text_copied" msgid="2531420577879738860">"Teksten er kopieret til udklipsholderen."</string>
     <string name="copied" msgid="4675902854553014676">"Kopieret"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> indsatte indhold fra <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> indsatte indhold fra udklipsholderen"</string>
     <string name="more_item_label" msgid="7419249600215749115">"Mere"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Menu+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1372,11 +1381,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Deaktiver"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Tjekker <xliff:g id="NAME">%s</xliff:g>…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Tjekker aktuelt indhold"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Analyserer medielagring"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Nyt <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> fungerer ikke"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Tryk for at konfigurere"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Vælg for at konfigurere"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Du skal muligvis formatere enheden igen. Tryk for at skubbe den ud."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"Til overførsel af billeder og medier"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Gennemse mediefiler"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Problem med <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> fungerer ikke"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Tryk for at løse problemet"</string>
@@ -1385,7 +1397,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"<xliff:g id="NAME">%s</xliff:g> understøttes ikke"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> fungerer ikke"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"Denne enhed understøtter ikke dette <xliff:g id="NAME">%s</xliff:g>. Tryk for at konfigurere det til et understøttet format."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"Denne enhed understøtter ikke dette <xliff:g id="NAME">%s</xliff:g>. Vælg for at konfigurere mediet i et understøttet format."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Vælg for at konfigurere <xliff:g id="NAME">%s</xliff:g> i et understøttet format."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Du skal muligvis formatere enheden igen"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> blev fjernet uventet"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Demonter mediet, inden du fjerner det, så du ikke mister dit indhold"</string>
@@ -1679,7 +1691,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Brug genvej"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Ombytning af farver"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Korriger farve"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Reducer lysstyrken"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Ekstra dæmpet belysning"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Lydstyrkeknapperne blev holdt nede. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> er aktiveret."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Lydstyrkeknapperne blev holdt nede. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> er deaktiveret."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Hold begge lydstyrkeknapper nede i tre sekunder for at bruge <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -2088,6 +2100,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Genvej til hjælpefunktioner på skærmen"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Valg af genvej til hjælpefunktioner på skærmen"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Genvej til hjælpefunktioner"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Luk notifikationspanel"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Titellinje for <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> er blevet placeret i samlingen BEGRÆNSET"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2225,8 +2238,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Nyhed: Forstørrelse af vindue"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Du kan nu forstørre dele af eller hele skærmen"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Forstør en del af din skærm"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Nu kan du forstørre hele skærmen, en del af skærmen eller skifte mellem begge valgmuligheder."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Aktivér i Indstillinger"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Luk"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"&lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; skal have adgang til din enheds mikrofon, før den kan fortsætte."</string>
@@ -2235,4 +2248,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Beskyttelse af sensoroplysninger"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Appens ikon"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Appens brandimage"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Tjek adgangsindstillingerne"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> kan se og styre din skærm. Tryk for at se mere."</string>
 </resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 6e458fa..60cb51d 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Twilight Service"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Zeitzonen-Erkennung (keine Verbindung)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS-Zeitaktualisierungsdienst"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Musikerkennungsverwaltung"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Die Daten auf deinem Gerät werden gelöscht."</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Die Admin-App kann nicht verwendet werden. Die Daten auf deinem Gerät werden nun gelöscht.\n\nBitte wende dich bei Fragen an den Administrator deiner Organisation."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Drucken wurde von <xliff:g id="OWNER_APP">%s</xliff:g> deaktiviert."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"App wird ausgeführt"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Strom verbrauchende Apps"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Vergrößerung"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Sicherheitsrichtlinien für Bedienungshilfen"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> verbraucht Strom"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> Apps verbrauchen Strom"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Für Details zur Akku- und Datennutzung tippen"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Ermöglicht der App, zur Statusleiste zu werden"</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"Statusleiste ein-/ausblenden"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Ermöglicht der App, die Statusleiste ein- oder auszublenden"</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"Benachrichtigungen auf einem gesperrten Gerät als Vollbildaktivitäten anzeigen"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Ermöglicht der App, Benachrichtigungen auf einem gesperrten Gerät als Vollbildaktivitäten anzuzeigen"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"Verknüpfungen installieren"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Ermöglicht einer App das Hinzufügen von Verknüpfungen zum Startbildschirm ohne Eingriff des Nutzers"</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"Verknüpfungen deinstallieren"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Biometrisches Verfahren oder Displaysperre verwenden"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Deine Identität bestätigen"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Mithilfe eines biometrischen Verfahrens fortfahren"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Verwende deine biometrischen Daten oder deine Display-Entsperrmethode, um fortzufahren"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrische Hardware nicht verfügbar"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Authentifizierung abgebrochen"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Nicht erkannt"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Fingerabdruck verwenden"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Fingerabdruck oder Displaysperre verwenden"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Mithilfe deines Fingerabdrucks fortfahren"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Verwende deinen Fingerabdruck oder deine Display-Entsperrmethode, um fortzufahren"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Fingerabdruck-Symbol"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Face Unlock verwenden"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Face Unlock oder Displaysperre verwenden"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Zum Fortfahren Face Unlock verwenden"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Verwende die Gesichtserkennung oder deine Display-Entsperrmethode, um fortzufahren"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Gesichtssymbol"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"Du bist nicht zum Öffnen dieser Seite berechtigt."</string>
     <string name="text_copied" msgid="2531420577879738860">"Text in Zwischenablage kopiert."</string>
     <string name="copied" msgid="4675902854553014676">"Kopiert"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> hat etwas von <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> eingefügt"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> hat etwas aus der Zwischenablage eingefügt"</string>
     <string name="more_item_label" msgid="7419249600215749115">"Mehr"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Menü+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta-Taste +"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Deaktivieren"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"<xliff:g id="NAME">%s</xliff:g> wird geprüft…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Aktuelle Inhalte werden geprüft"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Medienspeicher wird analysiert"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Neues Speichergerät (<xliff:g id="NAME">%s</xliff:g>)"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> funktioniert nicht"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Zum Einrichten tippen"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Zum Einrichten auswählen"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Eventuell musst du das Gerät neu formatieren. Zum Auswerfen tippen."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"Zum Übertragen von Fotos und Medien"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"In Mediendateien stöbern"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Problem mit <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> funktioniert nicht"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Tippen, um das Problem zu beheben"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"<xliff:g id="NAME">%s</xliff:g> nicht unterstützt"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> funktioniert nicht"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"<xliff:g id="NAME">%s</xliff:g> wird von diesem Gerät nicht unterstützt. Zum Einrichten in einem unterstützten Format tippen."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"<xliff:g id="NAME">%s</xliff:g> wird von diesem Gerät nicht unterstützt. Zur Einrichtung eines unterstützten Formats auswählen."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Wähle <xliff:g id="NAME">%s</xliff:g> aus, um das Medium in einem unterstützten Format einzurichten."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Eventuell musst du das Gerät neu formatieren"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> wurde unerwartet entfernt"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Lass das Speichergerät vor dem Entfernen auswerfen, damit keine Daten verloren gehen"</string>
@@ -1677,7 +1689,8 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Verknüpfung verwenden"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Farbumkehr"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Farbkorrektur"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Helligkeit verringern"</string>
+    <!-- no translation found for reduce_bright_colors_feature_name (3222994553174604132) -->
+    <skip />
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Lautstärketasten wurden gedrückt gehalten. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ist aktiviert."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Lautstärketasten wurden gedrückt gehalten. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ist deaktiviert."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Halten Sie beide Lautstärketasten drei Sekunden lang gedrückt, um <xliff:g id="SERVICE_NAME">%1$s</xliff:g> zu verwenden"</string>
@@ -2086,6 +2099,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Kurzbefehl für Bildschirmbedienungshilfen"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Auswahl für Kurzbefehle für Bildschirmbedienungshilfen"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Kurzbefehl für Bedienungshilfen"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Benachrichtigungsleiste schließen"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Untertitelleiste von <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> wurde in den BESCHRÄNKT-Bucket gelegt"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2237,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Neu: Fenstervergrößerung"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Du kannst das Display teilweise oder ganz vergrößern"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Einen Teil des Bildschirms vergrößern"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Du kannst jetzt den gesamten Bildschirm oder einen bestimmten Bereich vergrößern und zwischen beiden Optionen wechseln."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"In den Einstellungen aktivieren"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Schließen"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Zum Fortfahren benötigt, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; Zugriff auf das Mikrofon deines Geräts."</string>
@@ -2233,4 +2247,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Datenschutz für Sensoren"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"App-Symbol"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"App-Branding-Hintergrundbild"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Zugriffseinstellungen prüfen"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> kann deinen Bildschirm sehen und steuern. Zum Prüfen tippen."</string>
 </resources>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 920f09e..d2ea1e6 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Υπηρεσία Twilight"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Εντοπισμός ζώνης ώρας (χωρίς συνδεσιμότητα)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"Υπηρεσία ενημέρωσης ώρας GNSS"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Υπηρεσία διαχείρισης αναγνώρισης μουσικής"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Η συσκευή σας θα διαγραφεί"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Δεν είναι δυνατή η χρήση της εφαρμογής διαχειριστή. Η συσκευή σας θα διαγραφεί.\n\nΕάν έχετε ερωτήσεις, επικοινωνήστε με τον διαχειριστή του οργανισμού σας."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Η εκτύπωση απενεργοποιήθηκε από τον χρήστη <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Η εφαρμογή εκτελείται"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Εφαρμογές που καταναλώνουν μπαταρία"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Μεγιστοποίηση"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Πολιτική ασφαλείας προσβασιμότητας"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> χρησιμοποιεί μπαταρία"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> εφαρμογές χρησιμοποιούν μπαταρία"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Πατήστε για λεπτομέρειες σχετικά με τη χρήση μπαταρίας και δεδομένων"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Επιτρέπει στην εφαρμογή να αποτελεί τη γραμμή κατάστασης."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"αναπτύσσει/συμπτύσσει τη γραμμή κατάστασης"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Επιτρέπει στην εφαρμογή να αναπτύξει ή να συμπτύξει τη γραμμή κατάστασης."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"προβολή ειδοποιήσεων ως δραστηριότητες πλήρους οθόνης σε μια κλειδωμένη συσκευή"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Επιτρέπει στην εφαρμογή να προβάλει ειδοποιήσεις ως δραστηριότητες πλήρους οθόνης σε μια κλειδωμένη συσκευή"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"εγκαθιστά συντομεύσεις"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Επιτρέπει σε μια εφαρμογή την προσθήκη συντομεύσεων στην Αρχική οθόνη χωρίς την παρέμβαση του χρήστη."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"απεγκατάσταση συντομεύσεων"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Χρήση βιομετρικών ή κλειδώματος οθόνης"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Επαλήθευση ταυτότητας"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Χρησιμοποιήστε βιομετρικά για να συνεχίσετε"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Χρήση βιομετρικών στοιχείων ή κλειδώματος οθόνης για συνέχεια"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Δεν υπάρχει διαθέσιμος βιομετρικός εξοπλισμός"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Ο έλεγχος ταυτότητας ακυρώθηκε"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Δεν αναγνωρίστηκε"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Χρήση δακτυλικού αποτυπώματος"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Χρήση δακτυλικού αποτυπώματος ή κλειδώματος οθόνης"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Χρησιμοποιήστε το δακτυλικό αποτύπωμά σας για να συνεχίσετε"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Χρησιμοποιήστε το δακτυλικό σας αποτύπωμα ή το κλείδωμα οθόνης για να συνεχίσετε"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Εικονίδιο δακτυλικών αποτυπωμάτων"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Χρήση Face Unlock"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Χρήση προσώπου ή κλειδώματος οθόνης"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Χρησιμοποιήστε το Face Unlock για να συνεχίσετε"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Χρησιμοποιήστε το πρόσωπό σας ή το κλείδωμα οθόνης για συνέχεια"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Εικ. προσ."</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"Δεν έχετε άδεια για να ανοίξετε αυτήν τη σελίδα."</string>
     <string name="text_copied" msgid="2531420577879738860">"Το κείμενο αντιγράφηκε στο πρόχειρο."</string>
     <string name="copied" msgid="4675902854553014676">"Αντιγράφηκε"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"Η εφαρμογή <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> έκανε επικόλληση από την εφαρμογή <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"Η εφαρμογή <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> έκανε επικόλληση από το πρόχειρο"</string>
     <string name="more_item_label" msgid="7419249600215749115">"Περισσότερα"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Πλήκτρο Menu+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Απενεργοποίηση"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Έλεγχος <xliff:g id="NAME">%s</xliff:g>…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Έλεγχος τρέχοντος περιεχομένου"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Ανάλυση αποθηκευτικού χώρου μέσου"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Νέο <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"Η συσκευή <xliff:g id="NAME">%s</xliff:g> δεν λειτουργεί."</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Πατήστε για ρύθμιση"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Επιλέξτε για ρύθμιση"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Μπορεί να χρειαστεί να διαμορφώσετε ξανά τη συσκευή. Πατήστε για κατάργηση."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"Για μεταφορά φωτ./πολυμέσων"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Περιήγηση στα αρχεία μέσων"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Πρόβλημα με <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"Η συσκευή <xliff:g id="NAME">%s</xliff:g> δεν λειτουργεί."</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Πατήστε για επιδιόρθωση"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"Η κάρτα <xliff:g id="NAME">%s</xliff:g> δεν υποστηρίζεται"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"Η συσκευή <xliff:g id="NAME">%s</xliff:g> δεν λειτουργεί."</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"Αυτή η συσκευή δεν υποστηρίζει αυτό το μέσο <xliff:g id="NAME">%s</xliff:g>. Πατήστε για ρύθμιση σε μια υποστηριζόμενη μορφή."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"Αυτή η συσκευή δεν υποστηρίζει το μέσο <xliff:g id="NAME">%s</xliff:g>. Επιλέξτε να ρυθμιστεί σε μια υποστηριζόμενη μορφή."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Επιλέξτε για να ρυθμίσετε το μέσο <xliff:g id="NAME">%s</xliff:g> σε μια υποστηριζόμενη μορφή."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Μπορεί να χρειαστεί να διαμορφώσετε ξανά τη συσκευή."</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"Μη αναμενόμενη αφαίρεση <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Κάντε εξαγωγή των μέσων πριν τα καταργήσετε, για να μην χάσετε το περιεχόμενό σας"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Χρήση συντόμευσης"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Αντιστροφή χρωμάτων"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Διόρθωση χρωμάτων"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Μείωση φωτεινότητας"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Επιπλέον μείωση φωτεινότητας"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Τα πλήκτρα έντασης είναι πατημένα. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ενεργοποιήθηκε."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Τα πλήκτρα έντασης είναι πατημένα. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>: απενεργοποιημένο"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Πατήστε παρατεταμένα και τα δύο κουμπιά έντασης ήχου για τρία δευτερόλεπτα, ώστε να χρησιμοποιήσετε την υπηρεσία <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Συντόμευση οθόνης για την προσβασιμότητα"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Επιλογέας συντόμευσης οθόνης για την προσβασιμότητα"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Συντόμευση προσβασιμότητας"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Παράβλεψη πλαισίου σκίασης ειδοποιήσεων"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Γραμμή υποτίτλων για την εφαρμογή <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> τοποθετήθηκε στον κάδο ΠΕΡΙΟΡΙΣΜΕΝΗΣ ΠΡΟΣΒΑΣΗΣ."</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Νέο: Μεγέθυνση παραθύρου"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Μεγεθύνετε μέρος ή ολόκληρη την οθόνη σας"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Μεγέθυνση μέρους της οθόνης"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Μπορείτε πλέον να κάνετε μεγέθυνση πλήρους οθόνης, συγκεκριμένης περιοχής ή να κάνετε εναλλαγή μεταξύ των δύο επιλογών."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Ενεργοποίηση στις Ρυθμίσεις"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Παράβλεψη"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Για να συνεχίσετε, η εφαρμογή &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; χρειάζεται πρόσβαση στο μικρόφωνο της συσκευής σας."</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Απόρρητο αισθητήρα"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Εικονίδιο εφαρμογής"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Εικόνα επωνυμίας εφαρμογής"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Ελέγξτε τις ρυθμίσεις προσβασιμότητας"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"Η υπηρεσία <xliff:g id="SERVICE_NAME">%s</xliff:g> μπορεί να βλέπει και να ελέγχει την οθόνη σας. Πατήστε για έλεγχο."</string>
 </resources>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 43a7fb6..d5bc66d 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Twilight Service"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Time zone detector (no connectivity)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS time update service"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Music recognition manager service"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Your device will be erased"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"The admin app can\'t be used. Your device will now be erased.\n\nIf you have questions, contact your organisation\'s admin."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Printing disabled by <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"App running"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Apps consuming battery"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Magnification"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Accessibility security policy"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> is using battery"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> apps are using battery"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Tap for details on battery and data usage"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Allows the app to be the status bar."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"expand/collapse status bar"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Allows the app to expand or collapse the status bar."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"display notifications as full screen activities on a locked device"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Allows the app to display notifications as full screen activities on a locked device"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"Install shortcuts"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Allows an application to add Home screen shortcuts without user intervention."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"uninstall shortcuts"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Use biometrics or screen lock"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Verify that it’s you"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Use your biometric to continue"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Use your biometric or screen lock to continue"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometric hardware unavailable"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Authentication cancelled"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Not recognised"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Use fingerprint"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Use fingerprint or screen lock"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Use your fingerprint to continue"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Use your fingerprint or screen lock to continue"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Fingerprint icon"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Use face unlock"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Use face or screen lock"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Use face unlock to continue"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Use your face or screen lock to continue"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Face icon"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"You don\'t have permission to open this page."</string>
     <string name="text_copied" msgid="2531420577879738860">"Text copied to clipboard."</string>
     <string name="copied" msgid="4675902854553014676">"Copied"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> pasted from <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> pasted from clipboard"</string>
     <string name="more_item_label" msgid="7419249600215749115">"More"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Menu+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Turn off"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Checking <xliff:g id="NAME">%s</xliff:g>…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Reviewing current content"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Analysing media storage"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"New <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> isn’t working"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Tap to set up"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Select to set up"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"You may need to reformat the device. Tap to eject."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"For transferring photos and media"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Browse media files"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Issue with <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> isn’t working"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Tap to fix"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"Unsupported <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> isn’t working"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"This device doesn’t support this <xliff:g id="NAME">%s</xliff:g>. Tap to set up in a supported format."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"This device doesn’t support this <xliff:g id="NAME">%s</xliff:g>. Select to set up in a supported format."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Select to set up <xliff:g id="NAME">%s</xliff:g> in a supported format."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"You may need to reformat the device"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> unexpectedly removed"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Eject media before removing to avoid losing content"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Use Shortcut"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Colour Inversion"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Colour correction"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Reduce brightness"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Extra dim"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned on."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned off."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Press and hold both volume keys for three seconds to use <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"On-screen accessibility shortcut"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"On-screen accessibility shortcut chooser"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Accessibility shortcut"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Dismiss notification shade"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Caption bar of <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> has been put into the RESTRICTED bucket"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"New: Window magnifier"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"You can now magnify some or all of your screen"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Magnify part of your screen"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"You can now magnify your full screen, a specific area, or switch between both options."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Turn on in settings"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Dismiss"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"To continue, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; needs access to your device microphone."</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Sensor privacy"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Application icon"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Application branding image"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Check access settings"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> can view and control your screen. Tap to review."</string>
 </resources>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index 04390c7..11d1780 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Twilight Service"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Time zone detector (no connectivity)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS time update service"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Music recognition manager service"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Your device will be erased"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"The admin app can\'t be used. Your device will now be erased.\n\nIf you have questions, contact your organisation\'s admin."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Printing disabled by <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"App running"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Apps consuming battery"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Magnification"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Accessibility security policy"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> is using battery"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> apps are using battery"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Tap for details on battery and data usage"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Allows the app to be the status bar."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"expand/collapse status bar"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Allows the app to expand or collapse the status bar."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"display notifications as full screen activities on a locked device"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Allows the app to display notifications as full screen activities on a locked device"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"Install shortcuts"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Allows an application to add Home screen shortcuts without user intervention."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"uninstall shortcuts"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Use biometrics or screen lock"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Verify that it’s you"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Use your biometric to continue"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Use your biometric or screen lock to continue"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometric hardware unavailable"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Authentication cancelled"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Not recognised"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Use fingerprint"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Use fingerprint or screen lock"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Use your fingerprint to continue"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Use your fingerprint or screen lock to continue"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Fingerprint icon"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Use face unlock"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Use face or screen lock"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Use face unlock to continue"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Use your face or screen lock to continue"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Face icon"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"You don\'t have permission to open this page."</string>
     <string name="text_copied" msgid="2531420577879738860">"Text copied to clipboard."</string>
     <string name="copied" msgid="4675902854553014676">"Copied"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> pasted from <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> pasted from clipboard"</string>
     <string name="more_item_label" msgid="7419249600215749115">"More"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Menu+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Turn off"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Checking <xliff:g id="NAME">%s</xliff:g>…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Reviewing current content"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Analysing media storage"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"New <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> isn’t working"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Tap to set up"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Select to set up"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"You may need to reformat the device. Tap to eject."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"For transferring photos and media"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Browse media files"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Issue with <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> isn’t working"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Tap to fix"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"Unsupported <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> isn’t working"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"This device doesn’t support this <xliff:g id="NAME">%s</xliff:g>. Tap to set up in a supported format."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"This device doesn’t support this <xliff:g id="NAME">%s</xliff:g>. Select to set up in a supported format."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Select to set up <xliff:g id="NAME">%s</xliff:g> in a supported format."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"You may need to reformat the device"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> unexpectedly removed"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Eject media before removing to avoid losing content"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Use Shortcut"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Colour inversion"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Colour correction"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Reduce brightness"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Extra dim"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned on."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned off."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Press and hold both volume keys for three seconds to use <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"On-screen accessibility shortcut"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"On-screen accessibility shortcut chooser"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Accessibility shortcut"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Dismiss notification shade"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Caption bar of <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> has been put into the RESTRICTED bucket"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"New: Window magnifier"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"You can now magnify some or all of your screen"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Magnify part of your screen"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"You can now magnify your full screen, a specific area, or switch between both options."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Turn on in settings"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Dismiss"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"To continue, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; needs access to your device microphone."</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Sensor privacy"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Application icon"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Application branding image"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Check access settings"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> can view and control your screen. Tap to review."</string>
 </resources>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 84224ed..4e15e60 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Twilight Service"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Time zone detector (no connectivity)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS time update service"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Music recognition manager service"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Your device will be erased"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"The admin app can\'t be used. Your device will now be erased.\n\nIf you have questions, contact your organisation\'s admin."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Printing disabled by <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"App running"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Apps consuming battery"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Magnification"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Accessibility security policy"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> is using battery"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> apps are using battery"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Tap for details on battery and data usage"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Allows the app to be the status bar."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"expand/collapse status bar"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Allows the app to expand or collapse the status bar."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"display notifications as full screen activities on a locked device"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Allows the app to display notifications as full screen activities on a locked device"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"Install shortcuts"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Allows an application to add Home screen shortcuts without user intervention."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"uninstall shortcuts"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Use biometrics or screen lock"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Verify that it’s you"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Use your biometric to continue"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Use your biometric or screen lock to continue"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometric hardware unavailable"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Authentication cancelled"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Not recognised"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Use fingerprint"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Use fingerprint or screen lock"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Use your fingerprint to continue"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Use your fingerprint or screen lock to continue"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Fingerprint icon"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Use face unlock"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Use face or screen lock"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Use face unlock to continue"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Use your face or screen lock to continue"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Face icon"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"You don\'t have permission to open this page."</string>
     <string name="text_copied" msgid="2531420577879738860">"Text copied to clipboard."</string>
     <string name="copied" msgid="4675902854553014676">"Copied"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> pasted from <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> pasted from clipboard"</string>
     <string name="more_item_label" msgid="7419249600215749115">"More"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Menu+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Turn off"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Checking <xliff:g id="NAME">%s</xliff:g>…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Reviewing current content"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Analysing media storage"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"New <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> isn’t working"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Tap to set up"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Select to set up"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"You may need to reformat the device. Tap to eject."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"For transferring photos and media"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Browse media files"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Issue with <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> isn’t working"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Tap to fix"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"Unsupported <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> isn’t working"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"This device doesn’t support this <xliff:g id="NAME">%s</xliff:g>. Tap to set up in a supported format."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"This device doesn’t support this <xliff:g id="NAME">%s</xliff:g>. Select to set up in a supported format."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Select to set up <xliff:g id="NAME">%s</xliff:g> in a supported format."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"You may need to reformat the device"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> unexpectedly removed"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Eject media before removing to avoid losing content"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Use Shortcut"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Colour Inversion"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Colour correction"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Reduce brightness"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Extra dim"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned on."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned off."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Press and hold both volume keys for three seconds to use <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"On-screen accessibility shortcut"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"On-screen accessibility shortcut chooser"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Accessibility shortcut"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Dismiss notification shade"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Caption bar of <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> has been put into the RESTRICTED bucket"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"New: Window magnifier"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"You can now magnify some or all of your screen"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Magnify part of your screen"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"You can now magnify your full screen, a specific area, or switch between both options."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Turn on in settings"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Dismiss"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"To continue, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; needs access to your device microphone."</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Sensor privacy"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Application icon"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Application branding image"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Check access settings"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> can view and control your screen. Tap to review."</string>
 </resources>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index d740e01..60d743b 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Twilight Service"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Time zone detector (no connectivity)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS time update service"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Music recognition manager service"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Your device will be erased"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"The admin app can\'t be used. Your device will now be erased.\n\nIf you have questions, contact your organisation\'s admin."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Printing disabled by <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"App running"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Apps consuming battery"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Magnification"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Accessibility security policy"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> is using battery"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> apps are using battery"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Tap for details on battery and data usage"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Allows the app to be the status bar."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"expand/collapse status bar"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Allows the app to expand or collapse the status bar."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"display notifications as full screen activities on a locked device"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Allows the app to display notifications as full screen activities on a locked device"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"Install shortcuts"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Allows an application to add Home screen shortcuts without user intervention."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"uninstall shortcuts"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Use biometrics or screen lock"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Verify that it’s you"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Use your biometric to continue"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Use your biometric or screen lock to continue"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometric hardware unavailable"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Authentication cancelled"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Not recognised"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Use fingerprint"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Use fingerprint or screen lock"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Use your fingerprint to continue"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Use your fingerprint or screen lock to continue"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Fingerprint icon"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Use face unlock"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Use face or screen lock"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Use face unlock to continue"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Use your face or screen lock to continue"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Face icon"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"You don\'t have permission to open this page."</string>
     <string name="text_copied" msgid="2531420577879738860">"Text copied to clipboard."</string>
     <string name="copied" msgid="4675902854553014676">"Copied"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> pasted from <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> pasted from clipboard"</string>
     <string name="more_item_label" msgid="7419249600215749115">"More"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Menu+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Turn off"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Checking <xliff:g id="NAME">%s</xliff:g>…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Reviewing current content"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Analysing media storage"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"New <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> isn’t working"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Tap to set up"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Select to set up"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"You may need to reformat the device. Tap to eject."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"For transferring photos and media"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Browse media files"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Issue with <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> isn’t working"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Tap to fix"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"Unsupported <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> isn’t working"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"This device doesn’t support this <xliff:g id="NAME">%s</xliff:g>. Tap to set up in a supported format."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"This device doesn’t support this <xliff:g id="NAME">%s</xliff:g>. Select to set up in a supported format."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Select to set up <xliff:g id="NAME">%s</xliff:g> in a supported format."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"You may need to reformat the device"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> unexpectedly removed"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Eject media before removing to avoid losing content"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Use Shortcut"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Colour Inversion"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Color correction"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Reduce brightness"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Extra dim"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned on."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned off."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Press and hold both volume keys for three seconds to use <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"On-screen accessibility shortcut"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"On-screen accessibility shortcut chooser"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Accessibility shortcut"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Dismiss notification shade"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Caption bar of <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> has been put into the RESTRICTED bucket"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"New: Window magnifier"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"You can now magnify some or all of your screen"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Magnify part of your screen"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"You can now magnify your full screen, a specific area, or switch between both options."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Turn on in settings"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Dismiss"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"To continue, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; needs access to your device microphone."</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Sensor privacy"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Application icon"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Application branding image"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Check access settings"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> can view and control your screen. Tap to review."</string>
 </resources>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index aef32a4d..a4bf0c3 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‎‏‎‎‏‏‎‏‏‎‏‏‏‎‏‎‎‎‏‏‎‎‏‎‎‎‏‎‏‎‎‏‎‎‎‏‎‏‏‎‏‎‏‎‎‏‎‎‏‏‎‎‎‎Twilight Service‎‏‎‎‏‎"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‎‎‎‏‏‎‏‏‏‎‎‏‎‎‏‏‎‏‏‎‏‎‏‎‎‏‎‏‏‏‏‏‎‏‏‏‎‏‎‏‎‎‏‎‎‎‏‏‏‎‏‏‏‎‎‎‎‎Time Zone Detector (No connectivity)‎‏‎‎‏‎"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‎‏‎‏‎‏‏‎‏‏‏‏‏‎‎‏‏‎‏‏‎‏‎‏‎‏‎‎‎‏‏‎‎‏‎‎‏‏‎‏‎‎‏‏‏‎‏‏‏‏‏‎GNSS Time Update Service‎‏‎‎‏‎"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‎‏‎‏‎‏‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‎‎‎‎‏‏‎‏‏‎‎‎‏‏‏‎‏‏‎‎‎‎‎‏‏‎‎‎‎‎‏‏‏‎Music Recognition Manager Service‎‏‎‎‏‎"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‎‏‏‏‏‎‎‎‎‎‏‎‎‎‏‎‏‎‏‏‎‏‎‏‎‏‎‏‏‎‏‏‎‏‎‎‏‎‎‏‎‎‏‎‎‎‏‎‎‎‎‎‏‎Your device will be erased‎‏‎‎‏‎"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‏‏‎‏‏‏‏‏‏‎‏‏‏‏‎‎‏‎‎‎‎‏‏‏‎‏‏‏‎‏‎‏‏‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‎‎‏‎‏‎‏‎The admin app can\'t be used. Your device will now be erased.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎If you have questions, contact your organization\'s admin.‎‏‎‎‏‎"</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‏‏‎‏‎‎‎‎‏‎‏‎‏‎‏‏‎‏‏‏‎‎‎‎‎‎‎‎‎‎‎‏‏‎‏‎‏‎‎‎‏‎‎‎‎‎‎‏‎‏‏‏‏‎‎‏‎Printing disabled by ‎‏‎‎‏‏‎<xliff:g id="OWNER_APP">%s</xliff:g>‎‏‎‎‏‏‏‎.‎‏‎‎‏‎"</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‎‏‏‎‏‏‏‏‏‎‎‎‎‎‎‎‏‏‏‏‏‎‏‎‏‏‎‎‎‎‎‏‎‏‏‎‎‎‎‏‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎App running‎‏‎‎‏‎"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‎‎‏‎‎‎‎‎‎‎‎‏‏‎‎‎‎‏‎‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‏‏‏‎‎‎‎‏‏‏‏‎‏‎‎‏‏‏‎‏‎‎Apps consuming battery‎‏‎‎‏‎"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‏‎‏‏‎‎‏‏‏‎‏‏‏‎‏‎‏‎‎‏‏‏‏‎‎‎‏‎‏‏‎‎‏‎‎‏‏‏‏‏‎‏‏‏‏‎‏‎‎‏‎‏‎‎‏‎‎Magnification‎‏‎‎‏‎"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‎‎‏‏‏‏‏‏‏‎‎‏‎‏‎‏‎‏‏‏‏‏‎‏‏‎‎‏‎‏‎‏‎‎‎‎‎‏‏‎‏‏‎‎‎‎‎‎‎‏‏‎‎‏‏‏‎‎Accessibility security policy‎‏‎‎‏‎"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‏‏‏‏‏‏‎‎‏‎‏‏‎‎‎‏‎‎‏‎‏‏‎‏‏‎‎‏‎‏‏‎‏‏‏‎‎‏‎‎‎‏‏‏‏‎‎‎‎‎‏‎‏‎‎‏‏‎‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ is using battery‎‏‎‎‏‎"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‏‏‏‎‏‎‎‎‎‏‏‎‎‏‏‏‎‏‏‎‎‎‎‏‏‏‎‏‎‎‎‏‏‏‎‎‎‏‎‏‏‏‎‏‎‎‎‎‏‎‏‏‏‎‎‏‎‎‏‏‎<xliff:g id="NUMBER">%1$d</xliff:g>‎‏‎‎‏‏‏‎ apps are using battery‎‏‎‎‏‎"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‎‏‎‏‎‏‎‏‏‏‎‎‎‎‎‎‏‏‏‎‏‏‏‏‎‏‎‏‏‏‏‎‎‏‏‎‏‏‏‏‏‏‎Tap for details on battery and data usage‎‏‎‎‏‎"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‏‎‏‎‎‏‏‏‏‏‎‏‎‎‏‎‎‏‎‎‎‎‎‎‎‏‏‎‏‎‎‏‎‎‎‎‏‎‏‎‎‎‎‎‏‎‎‏‎‏‎‏‏‎‏‎Allows the app to be the status bar.‎‏‎‎‏‎"</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‎‎‏‏‎‏‏‏‏‎‎‏‏‏‏‎‏‎‏‏‏‎‎‏‏‏‏‎‏‏‎‎‎‎‏‎‏‏‎‏‏‏‎‎‎‏‏‎‏‎‎‎‎‎‎‏‎‎expand/collapse status bar‎‏‎‎‏‎"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‏‎‎‏‏‏‎‎‏‎‏‏‎‎‎‏‎‏‏‎‏‏‎‎‎‎‏‏‎‏‏‎‏‎‏‎‏‎‏‏‏‏‎‎‏‏‎‏‏‎‏‎‎‎‎Allows the app to expand or collapse the status bar.‎‏‎‎‏‎"</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‏‏‎‏‎‎‏‏‎‏‎‏‏‎‎‏‏‏‏‏‏‎‏‎‎‎‏‏‎‏‎‏‏‏‎‎‎‏‎‏‎‎‏‏‎‏‎‎‎‎‏‏‎‎‎‎‎display notifications as full screen activities on a locked device‎‏‎‎‏‎"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‎‏‎‎‎‏‏‎‏‎‎‎‏‏‎‎‎‏‎‎‏‏‎‎‏‎‎‏‎‎‎‎‎‏‏‎‎‏‎‏‏‎‎‏‎‎‏‏‎‎‎‏‏‏‎‏‎Allows the app to display notifications as full screen activities on a locked device‎‏‎‎‏‎"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‏‏‎‏‎‎‏‎‎‏‏‏‏‎‏‎‎‏‎‏‎‎‏‏‎‏‎‎‎‏‏‎‎‏‏‎‏‎‎‎‎‏‏‎‎‎‎‎‏‎‏‏‏‎‏‎install shortcuts‎‏‎‎‏‎"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‎‎‎‏‏‏‏‏‎‎‎‏‏‏‎‏‎‎‎‎‎‏‏‎‎‎‏‏‏‎‏‏‏‏‎‏‎‎‏‎‎‏‎‏‏‎‎‎‎‎‎‏‎‏‏‏‎Allows an application to add Homescreen shortcuts without user intervention.‎‏‎‎‏‎"</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‎‎‎‎‏‏‎‎‎‏‏‏‏‏‏‎‎‏‎‏‏‏‎‏‎‏‏‎‎‏‎‏‎‎‏‎‏‏‎‏‏‏‏‎‏‎‏‏‎‎‏‏‎‎‏‏‎‎uninstall shortcuts‎‏‎‎‏‎"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‎‏‏‏‎‎‏‏‎‎‎‏‏‏‎‎‎‏‏‏‏‎‎‎‎‏‏‎‏‏‏‎‏‏‎‏‏‎‏‎‎‏‎‏‎‏‎‎‏‎‏‏‎‎‎‎Use biometrics or screen lock‎‏‎‎‏‎"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‎‏‏‎‎‎‎‏‏‎‏‏‏‏‏‏‎‏‎‎‏‎‏‎‏‎‎‎‏‎‎‎‏‏‏‎‏‏‎‎‎‏‎‎‎‏‎‎‎‏‎‎‏‎‎‏‎‎Verify it’s you‎‏‎‎‏‎"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‏‏‏‏‎‎‎‏‎‎‎‎‎‎‎‎‎‎‎‎‏‎‎‎‏‎‏‏‎‏‏‎‏‎‏‏‎‎‏‎‏‎‏‏‎‏‏‎‏‏‎‎‎‎Use your biometric to continue‎‏‎‎‏‎"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‎‎‎‏‏‎‏‏‎‏‏‎‎‏‏‎‎‎‏‏‏‏‏‏‎‎‎‎‎‎‎‎‎‏‏‏‎‏‎‏‎‏‎‎‏‏‎‏‏‎‎‎‎‏‎‎‏‎Use your biometric or screen lock to continue‎‏‎‎‏‎"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‎‏‎‎‏‏‏‎‎‏‎‏‏‏‏‏‎‎‎‏‎‏‎‎‏‏‏‎‏‎‏‎‏‎‏‏‏‎‏‎‏‏‏‎‎‏‎‏‎‎‎‏‏‎‎‎‎‎Biometric hardware unavailable‎‏‎‎‏‎"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‏‏‎‏‏‎‏‏‏‏‏‎‎‏‎‏‏‎‎‎‏‎‏‏‏‏‎‎‎‎‏‏‎‎‎‏‏‎‎‎‎‎‏‏‎‎‏‎‎‏‎‎‎‏‎‎Authentication canceled‎‏‎‎‏‎"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‎‏‏‎‏‏‏‏‎‏‎‎‏‏‎‎‏‎‏‎‏‏‎‏‎‏‏‎‎‏‎‎‏‏‎‏‏‎‎‎‎‏‏‎‏‎‎‎‏‎‏‏‏‎‎‎‎‎Not recognized‎‏‎‎‏‎"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‎‎‎‎‏‎‎‎‎‏‏‎‏‎‏‏‎‏‎‏‏‎‎‎‏‏‎‎‎‏‏‏‎‎‏‏‏‏‏‎‏‎‎‏‏‎‎‎‏‎‏‎‎‏‎‎‎Use fingerprint‎‏‎‎‏‎"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‏‎‎‏‏‎‎‎‏‎‏‏‎‎‎‏‎‎‏‎‏‏‏‎‎‏‏‏‏‏‎‎‎‎‎‎‎‎‎‏‎‏‏‏‏‏‎‎‏‏‏‎‏‎‏‏‎Use fingerprint or screen lock‎‏‎‎‏‎"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‏‏‏‎‏‎‏‏‏‏‏‏‎‏‏‏‏‎‏‏‎‏‎‏‎‏‎‏‎‏‏‏‏‎‎‏‎‎‎‏‎‏‏‎‎‏‎‎‎‏‏‎‎‎‎‎‏‎Use your fingerprint to continue‎‏‎‎‏‎"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‎‎‏‏‎‏‏‎‎‏‏‏‎‎‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‎‏‎‎‎‏‎‎‏‏‎‎‏‎‎‎‎‏‎‎‎‎Use your fingerprint or screen lock to continue‎‏‎‎‏‎"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‎‎‏‎‏‏‏‎‏‎‏‎‎‎‏‎‏‎‎‏‎‏‏‏‏‎‎‎‏‏‎‏‏‎‎‎‎‎‎‏‎‎‏‏‏‎‏‎‎‏‎‎‎‏‎Fingerprint icon‎‏‎‎‏‎"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‏‎‏‎‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‎‏‏‏‎‎‎‎‎‎‏‎‏‏‏‎‎‏‎‎‎‎‏‎‏‏‎‏‎‏‎‏‏‎Use face unlock‎‏‎‎‏‎"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‎‎‏‏‏‏‏‏‏‎‎‎‎‏‏‏‏‎‎‏‎‏‏‏‎‎‏‎‎‏‎‏‎‏‏‏‏‎‎‏‎‏‏‎‎‎‎‏‎‎‏‏‎‎‏‎‎Use face or screen lock‎‏‎‎‏‎"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‏‎‎‎‏‏‎‎‏‏‎‏‏‎‎‎‏‎‎‏‏‏‏‎‏‎‎‏‏‎‎‎‏‏‎‏‎‎‎‎‏‎‎‏‏‏‎‎‎‏‏‏‏‏‎‎‎‎Use face unlock to continue‎‏‎‎‏‎"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‏‎‏‏‏‏‎‏‎‎‎‏‏‏‏‎‏‎‏‏‏‏‎‏‎‎‏‎‎‎‏‏‎‏‏‎‎‎‏‎‎‏‏‏‎‏‎‎‎‏‏‎‏‎‏‎‎‎Use your face or screen lock to continue‎‏‎‎‏‎"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‎‎‏‏‏‎‏‎‎‎‎‎‏‏‏‏‎‏‏‎‏‎‎‎‏‏‎‏‏‎‎‎‎‎‎‎‎‎‎‎‏‏‏‏‎‎‏‎‏‏‏‏‏‏‎‎‎‎Face icon‎‏‎‎‏‎"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‏‎‎‏‎‎‏‏‎‎‎‏‏‏‎‏‏‎‏‎‏‏‏‎‏‎‎‏‎‏‎‎‎‏‏‎‏‏‎‏‏‏‎‏‎‏‎‏‏‏‏‎‎‏‏‎You don\'t have permission to open this page.‎‏‎‎‏‎"</string>
     <string name="text_copied" msgid="2531420577879738860">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‏‎‎‏‎‎‎‎‏‎‏‏‎‏‎‎‏‏‎‎‏‏‎‏‎‏‎‎‎‎‎‎‏‏‎‏‎‎‎‏‎‏‏‎‎‏‎‎‏‏‏‏‎‏‏‎‎‎Text copied to clipboard.‎‏‎‎‏‎"</string>
     <string name="copied" msgid="4675902854553014676">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‏‏‎‎‏‎‎‎‎‏‎‎‏‎‎‏‏‎‏‏‏‏‏‎‏‎‎‏‎‎‏‏‏‎‏‏‏‏‎‎‎‎‏‎‎‎‏‏‎‎‏‎‏‎‎‎Copied‎‏‎‎‏‎"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‎‎‏‏‎‎‏‏‎‎‏‏‎‎‏‏‏‏‎‏‏‎‎‏‎‎‏‎‏‏‏‎‏‏‏‎‎‎‏‎‎‏‏‏‎‎‎‎‎‏‎‎‎‎‏‎‎‏‎‎‏‏‎<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ pasted from ‎‏‎‎‏‏‎<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‏‎‏‏‏‏‎‎‏‎‎‏‏‏‏‎‏‏‏‏‏‎‎‏‎‏‎‎‎‏‏‎‏‎‎‎‏‏‏‎‎‏‎‏‏‎‎‏‎‏‏‎‏‎‎‎‎‏‎‎‏‏‎<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ pasted from clipboard‎‏‎‎‏‎"</string>
     <string name="more_item_label" msgid="7419249600215749115">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‏‏‎‏‏‎‎‏‏‏‏‎‎‎‎‎‏‏‎‎‏‏‏‏‎‏‏‎‎‎‏‏‎‏‎‎‎‏‏‎‎‏‎‎‎‏‏‏‏‏‏‎‏‏‎More‎‏‎‎‏‎"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‎‎‏‏‎‎‏‎‏‏‏‎‏‏‎‏‎‎‏‎‎‎‏‎‎‏‎‏‎‏‏‏‏‏‎‎‎‎‏‎‏‏‏‏‎‎‎‏‏‏‏‎‏‏‏‏‎Menu+‎‏‎‎‏‎"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‏‎‎‎‎‏‏‏‎‏‏‏‎‎‎‎‏‏‎‎‎‎‎‎‏‎‏‏‎‏‎‏‏‎‏‏‎‎‏‎‏‎‎‎‏‏‎‎‏‏‏‎‏‏‏‎‎Meta+‎‏‎‎‏‎"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‎‏‎‎‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‏‎‎‎‏‎‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‎‏‎‎‎‏‎‎‎Turn off‎‏‎‎‏‎"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‏‎‏‏‎‎‏‎‏‎‏‏‏‎‎‏‏‎‏‏‎‎‏‎‏‏‏‏‏‎‏‎‏‏‏‎‎‏‎‏‏‏‏‏‏‎‏‎‎‎‏‏‏‎‎Checking ‎‏‎‎‏‏‎<xliff:g id="NAME">%s</xliff:g>‎‏‎‎‏‏‏‎…‎‏‎‎‏‎"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‏‏‏‏‏‎‎‎‎‎‎‏‏‏‏‎‎‏‎‏‎‏‏‎‎‏‎‏‎‎‎‎‎‏‎‎‏‏‎‏‏‏‎‎‎‏‎‏‎‎‏‏‎‏‏‎‎Reviewing current content‎‏‎‎‏‎"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‏‎‏‎‏‎‎‏‎‎‎‎‏‎‏‎‎‏‎‎‏‎‏‎‏‏‎‏‎‎‎‎‏‎‏‏‏‏‎‎‎‏‏‏‎‎‎‎‎‏‎‎‏‏‏‎Analyzing media storage‎‏‎‎‏‎"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‏‏‎‏‎‎‎‎‎‏‎‏‎‏‏‏‏‎‎‎‏‏‎‎‏‏‎‏‏‎‎‎‎‎‎‎‎‏‏‎‎‏‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎New ‎‏‎‎‏‏‎<xliff:g id="NAME">%s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‎‏‏‎‏‎‎‏‎‏‎‏‎‎‎‏‏‎‎‏‏‎‎‎‎‏‎‎‎‏‎‎‏‎‏‎‎‎‏‎‏‏‎‏‎‎‎‏‏‏‎‎‏‎‎‏‏‎<xliff:g id="NAME">%s</xliff:g>‎‏‎‎‏‏‏‎ isn’t working‎‏‎‎‏‎"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‎‎‏‎‏‏‏‎‎‏‏‏‎‎‎‏‏‎‏‏‎‎‎‎‎‏‏‏‎‎‏‎‎‎‏‎‎‎‏‎‏‎‏‏‏‏‏‏‎‏‎‏‎‏‎‎Tap to set up‎‏‎‎‏‎"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‎‎‎‎‎‎‏‎‎‏‏‏‎‏‎‎‎‎‎‏‎‎‎‏‏‏‎‏‏‎‏‎‏‎‏‏‏‏‎‎‏‎‎‏‎‏‏‎‏‏‏‏‎‏‎‎‎Select to set up‎‏‎‎‏‎"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‏‎‏‎‏‎‏‎‏‏‎‎‏‏‏‎‎‎‏‎‎‏‏‎‎‏‎‎‎‏‏‏‎‏‎‎‎‏‏‎‎‏‏‎‏‎‎‏‎‎‏‏‎‏‎‎You may need to reformat the device. Tap to eject.‎‏‎‎‏‎"</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‎‏‏‎‎‏‎‎‏‎‏‏‎‎‎‎‎‎‎‏‎‏‎‎‏‏‏‎‎‏‎‎‏‎‏‎‎‎‏‏‎‏‏‏‏‏‎‏‏‏‏‎‏‏‏‎‏‎For transferring photos and media‎‏‎‎‏‎"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‎‎‏‏‏‎‏‎‏‎‏‏‎‎‎‏‏‏‏‎‎‏‎‎‏‎‎‏‏‎‏‎‏‏‏‏‏‏‎‎‎‎‏‎‎‏‏‏‎‏‏‏‏‎Browse media files‎‏‎‎‏‎"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‏‏‏‎‎‎‎‎‎‎‏‏‏‎‎‏‏‏‏‏‏‎‎‏‏‎‏‏‎‏‎‏‎‏‏‏‏‏‎‎‏‏‏‎‎‏‏‎‏‎‎‎‏‏‎‎Issue with ‎‏‎‎‏‏‎<xliff:g id="NAME">%s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‏‎‎‏‏‏‎‏‎‎‏‏‎‎‏‎‏‎‎‏‏‎‏‏‏‎‎‏‏‏‏‏‎‏‎‏‎‏‏‎‎‎‏‏‏‏‏‎‎‎‏‏‎‎‎‎‎‎‏‎‎‏‏‎<xliff:g id="NAME">%s</xliff:g>‎‏‎‎‏‏‏‎ isn’t working‎‏‎‎‏‎"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‏‎‎‏‏‎‎‎‎‏‎‏‎‏‎‏‎‏‎‎‏‏‎‏‏‎‎‏‎‏‏‏‎‎‏‎‏‏‎‎‏‎‏‎‎‏‏‏‎‏‎‏‏‏‏‎‏‎Tap to fix‎‏‎‎‏‎"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‎‎‏‏‏‏‎‏‏‏‎‏‏‏‎‎‏‎‎‏‏‎‏‎‎‏‎‏‏‏‎‏‎‏‏‏‏‎‎‏‏‎‏‎‎‎‏‏‎‏‎‏‏‏‏‎‏‎Unsupported ‎‏‎‎‏‏‎<xliff:g id="NAME">%s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‏‎‏‎‎‏‏‎‎‏‎‏‏‎‏‏‏‏‎‎‎‎‏‎‎‎‎‎‎‏‏‎‎‏‎‎‏‏‎‎‎‎‏‎‏‏‎‎‏‎‎‏‏‎‏‎‎‏‎‎‏‏‎<xliff:g id="NAME">%s</xliff:g>‎‏‎‎‏‏‏‎ isn’t working‎‏‎‎‏‎"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‎‏‎‏‏‏‏‎‎‎‏‏‏‎‏‏‎‎‏‎‏‎‎‏‏‎‏‏‏‎‏‎‎‏‎‏‎‏‎‎‏‏‎‎‎‎‎‎‏‏‏‎‎‏‎‎‎‎This device doesn’t support this ‎‏‎‎‏‏‎<xliff:g id="NAME">%s</xliff:g>‎‏‎‎‏‏‏‎. Tap to set up in a supported format.‎‏‎‎‏‎"</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‏‏‏‎‏‏‏‎‎‏‎‎‏‏‎‏‎‏‎‏‏‏‎‏‏‎‎‏‎‏‏‏‏‏‎‏‎‎‎‏‎‎‎‏‏‏‏‏‏‏‎‏‎‏‎This device doesn’t support this ‎‏‎‎‏‏‎<xliff:g id="NAME">%s</xliff:g>‎‏‎‎‏‏‏‎. Select to set up in a supported format.‎‏‎‎‏‎"</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‎‎‏‎‎‏‎‎‎‏‎‎‏‎‏‏‎‎‏‎‎‏‏‏‏‏‎‎‎‏‎‏‏‎‎‏‏‎‏‎‎‏‏‎‎‏‏‏‎‏‏‏‎‏‎‎‎Select to set up ‎‏‎‎‏‏‎<xliff:g id="NAME">%s</xliff:g>‎‏‎‎‏‏‏‎ in a supported format.‎‏‎‎‏‎"</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‏‎‏‎‏‏‎‏‏‏‎‎‏‏‏‎‏‏‏‏‎‎‎‎‏‎‎‎‏‎‏‏‎‏‎‏‎‎‏‎‎‎‎‎‏‎‎‎‏‏‏‎‎‏‎‏‎‎You may need to reformat the device‎‏‎‎‏‎"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‎‎‎‏‏‎‏‎‎‎‎‏‎‏‏‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‏‏‎‏‏‏‏‎‏‎‏‏‎‏‏‎‎‎‏‎‎‎‎‎‏‎‎‏‏‎<xliff:g id="NAME">%s</xliff:g>‎‏‎‎‏‏‏‎ unexpectedly removed‎‏‎‎‏‎"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‏‏‎‎‏‎‎‎‏‏‎‎‎‎‏‎‎‏‎‎‏‏‎‎‏‎‏‎‎‎‏‏‎‏‏‎‎‏‏‎‏‎‎‎‏‏‎‏‏‏‏‎‏‏‏‎‎‎Eject media before removing to avoid losing content‎‏‎‎‏‎"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‏‎‎‏‏‏‎‏‎‏‏‎‎‎‏‎‎‏‎‎‎‎‎‏‎‏‎‎‎‏‎‎‏‎‏‏‏‎‏‎‎‎‏‏‏‏‎‎‏‎‏‏‏‏‎‎Use Shortcut‎‏‎‎‏‎"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‎‏‎‎‎‎‏‏‎‎‏‎‏‏‏‎‎‏‏‎‎‏‎‏‎‏‏‎‎‎‎‎‏‎‏‎‏‎‏‏‎‏‏‏‎‏‏‏‏‏‏‎‏‎‏‎‎‎Color Inversion‎‏‎‎‏‎"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‎‏‎‏‏‏‎‎‏‎‏‏‏‎‎‎‏‎‏‏‎‎‎‎‏‏‏‏‎‎‎‏‎‎‎‎‎‎‎‏‎‎‎‎‏‏‎‎‎‎‎‎‎‎‏‎‏‎Color Correction‎‏‎‎‏‎"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‎‎‏‎‎‏‎‏‎‏‏‏‎‏‎‎‏‎‏‏‏‏‏‏‎‏‏‎‏‏‎‏‎‏‎‏‏‏‎‎‏‎‏‎‏‏‎‎‏‏‎‎Reduce brightness‎‏‎‎‏‎"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‏‎‏‏‏‎‏‎‎‏‏‎‎‎‎‎‎‏‏‏‏‎‎‎‎‏‎‎‏‏‏‎‏‏‏‏‏‏‎‏‏‎‏‏‏‎‎‏‎‏‏‎‎‏‎‎‎Extra dim‎‏‎‎‏‎"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‏‏‏‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‎‎‎‏‏‎‏‎‏‎‎‏‏‏‏‏‎‏‎‎‎‏‏‏‏‏‎‎‏‎‎‎‎‎‏‏‏‎Held volume keys. ‎‏‎‎‏‏‎<xliff:g id="SERVICE_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ turned on.‎‏‎‎‏‎"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‎‏‎‎‏‎‏‎‏‎‎‎‏‎‎‏‏‎‏‎‏‏‎‎‏‏‏‎‎‏‎‏‎‏‏‏‏‎‏‎‏‏‏‎‎‏‎‎‏‎‏‏‎Held volume keys. ‎‏‎‎‏‏‎<xliff:g id="SERVICE_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ turned off.‎‏‎‎‏‎"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‎‏‎‏‏‎‎‎‎‎‏‏‎‏‎‏‎‎‏‏‎‎‏‏‏‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‏‎‏‎‎‏‎‏‏‏‏‎‎‏‎‎Press and hold both volume keys for three seconds to use ‎‏‎‎‏‏‎<xliff:g id="SERVICE_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‎‏‏‎‏‏‏‏‎‏‏‎‏‎‎‎‎‎‎‏‎‏‏‏‎‏‎‏‏‎‏‏‏‎‎‏‏‏‏‏‎‎‎‎‎‎‏‎‎‎‏‎‏‎On-screen Accessibility Shortcut‎‏‎‎‏‎"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‏‎‏‎‏‏‏‎‎‏‎‏‎‏‏‏‎‎‎‏‎‎‎‎‎‏‎‏‏‎‎‏‎‏‏‎‏‎‎‏‎‏‏‎‎‏‎‏‎‎‎‏‏‏‏‎‎On-screen Accessibility Shortcut Chooser‎‏‎‎‏‎"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‎‎‎‎‎‎‎‎‎‏‎‎‎‎‏‎‏‎‏‏‎‎‎‏‎‏‎‏‎‎‏‎‏‎‎‏‎‎‏‏‎‏‏‏‎‏‏‎‏‎‎‎‎‏‏‎Accessibility Shortcut‎‏‎‎‏‎"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‎‎‏‏‏‎‎‎‏‏‎‎‏‏‏‏‏‎‏‎‏‏‏‏‎‏‏‏‏‏‎‏‏‎‎‏‏‎‎‏‎‏‏‎‎‏‏‏‎‎‎‎‎Dismiss Notification Shade‎‏‎‎‏‎"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‎‎‎‎‏‎‏‏‏‎‏‏‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‎‏‎‏‏‏‎‏‎‎‏‎‏‎‎Caption bar of ‎‏‎‎‏‏‎<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>‎‏‎‎‏‏‏‎ has been put into the RESTRICTED bucket‎‏‎‎‏‎"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‎‏‎‎‏‎‎‏‎‏‎‎‎‎‎‎‎‏‏‎‎‎‏‎‏‎‎‎‎‏‏‎‎‏‏‎‎‎‏‎‎‎‏‎‏‎‏‏‏‏‏‏‎‎‏‎‎‏‏‎<xliff:g id="SENDER_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎:‎‏‎‎‏‎"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‎‎‎‏‏‎‏‏‏‏‎‎‎‏‎‏‎‎‏‎‏‏‎‏‎‏‏‎‎‎‏‎‎‎‏‎‎‎‏‏‎‏‎‎‏‏‏‎‎‎‎‎‎‎New: Window Magnifier‎‏‎‎‏‎"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‏‏‎‏‎‎‏‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‎‏‎‏‎‎‏‎‎‎‎‏‏‎‎‎‏‏‎‏‏‏‎‎‏‏‏‏‏‏‏‏‏‎‎You can now magnify some or all of your screen‎‏‎‎‏‎"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‎‏‎‎‎‎‏‎‎‏‎‎‎‎‏‏‎‏‎‎‎‎‏‏‎‏‏‎‎‏‏‎‎‎‏‎‏‏‎‏‎‏‏‎‎‎‏‎‏‏‏‏‎‎‎‎Magnify part of your screen‎‏‎‎‏‎"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‏‎‏‎‎‎‎‎‏‎‏‏‎‎‏‏‎‎‎‏‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‎‏‎You can now magnify your full screen, a specific area, or switch between both options.‎‏‎‎‏‎"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‎‎‎‏‎‎‎‏‏‎‏‏‎‎‏‏‏‏‎‏‎‏‏‏‏‎‏‏‎‎‏‎‏‎‎‎‏‏‎‎‎‎‏‏‎‎‏‎‏‎‏‎‎‎Turn on in Settings‎‏‎‎‏‎"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‎‎‎‎‎‏‎‎‏‎‏‎‎‎‎‎‏‏‎‎‏‏‎‎‎‎‏‎‎‎‎‎Dismiss‎‏‎‎‏‎"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‎‏‏‎‏‏‎‎‏‎‏‏‎‏‏‎‏‏‏‏‎‎‏‎‎‏‏‏‏‎‎‎‎‎‏‎‎‎‏‏‏‎‎‎‎‎‎‎‎‏‏‏‎To continue, &lt;b&gt;‎‏‎‎‏‏‎‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>‎‏‎‎‏‏‏‎&lt;/b&gt; needs access to your device microphone.‎‏‎‎‏‎"</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‎‏‏‏‏‏‏‎‏‎‏‏‏‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‏‎‎‏‎‏‎‏‎‏‏‎‎‏‎‏‏‏‏‏‎‏‎‎‏‎‏‎Sensor Privacy‎‏‎‎‏‎"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‎‏‎‎‎‎‎‎‏‏‏‎‎‎‎‎‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‎‏‏‎‎‎‏‏‏‎‏‏‎‏‏‏‏‏‏‎‏‎‏‎‏‏‎Application icon‎‏‎‎‏‎"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‎‎‏‎‎‏‏‏‏‏‏‎‏‎‎‎‏‏‏‎‎‏‏‏‏‏‏‏‎‎‎‎‎‏‏‎‏‏‏‎‎‎‎‎‏‏‎‎‎‏‏‎‎‎‎Application branding image‎‏‎‎‏‎"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‏‎‏‎‏‏‏‏‎‏‏‎‎‎‏‏‎‏‎‏‏‎‎‎‎‎‎‏‏‎‏‎‎‎‏‏‎‎‏‎‏‎‏‎‎‏‏‏‏‎‏‏‎‎‎‎‎Check access settings‎‏‎‎‏‎"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‎‎‏‎‎‏‏‎‎‎‏‎‏‏‏‎‎‏‏‏‎‎‏‏‎‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‎‎‎‎‎‎‎‎‏‎‎‎‏‎‎‏‏‎<xliff:g id="SERVICE_NAME">%s</xliff:g>‎‏‎‎‏‏‏‎ can view and control your screen. Tap to review.‎‏‎‎‏‎"</string>
 </resources>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 6125c16..da9292a 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Servicio de Twilight"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Detector de zona horaria (sin conexión)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"Servicio de actualización de tiempo GNSS"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Servicio de administrador de reconocimiento de música"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Se borrarán los datos del dispositivo"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"No se puede usar la app de administrador. Ahora se borrará tu dispositivo.\n\nSi tienes preguntas, comunícate con el administrador de tu organización."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> inhabilitó la impresión."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"App en ejecución"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Apps que consumen batería"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Ampliación"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Política de seguridad de accesibilidad"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> está consumiendo batería"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> apps están consumiendo batería"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Presiona para obtener información sobre el uso de datos y de la batería"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Permite que la aplicación sea la barra de estado."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"expandir o reducir la barra de estado"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Permite que la aplicación muestre y oculte la barra de estado."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"mostrar notificaciones como actividades de pantalla completa en un dispositivo bloqueado"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Permite que la app muestre notificaciones como actividades de pantalla completa en un dispositivo bloqueado"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"instalar accesos directos"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Permite que una aplicación agregue accesos directos a la pantalla principal sin que el usuario intervenga."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"desinstalar accesos directos"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Usar datos biométricos o bloqueo de pantalla"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Comprueba que eres tú"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Usa tus datos biométricos para continuar"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Usa tus datos biométricos o bloqueo de pantalla para continuar"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"No hay hardware biométrico disponible"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Se canceló la autenticación"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"No se reconoció"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Usar huella digital"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Usar bloqueo de huella dactilar o pantalla"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Utiliza tu huella dactilar para continuar"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Usa tu huella dactilar o bloqueo de pantalla para continuar"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ícono de huella dactilar"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Usar desbloqueo facial"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Usar bloqueo facial o de pantalla"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Usa el desbloqueo facial para continuar"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Usa tu rostro o bloqueo de pantalla para continuar"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Ícono cara"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"No tienes permiso para abrir esta página."</string>
     <string name="text_copied" msgid="2531420577879738860">"Texto copiado en el portapapeles."</string>
     <string name="copied" msgid="4675902854553014676">"Copiado"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> pegó contenido de <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> pegó contenido del portapapeles"</string>
     <string name="more_item_label" msgid="7419249600215749115">"Más"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Menú+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Desactivar"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Revisando <xliff:g id="NAME">%s</xliff:g>…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Revisando el contenido actual"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Analizando el almacenamiento de contenido multimedia"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Nuevo dispositivo: <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g>: no funciona"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Presiona para configurar"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Selecciona para configurar"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Es posible que debas reformatear el dispositivo. Presiona para expulsar."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"Para transferir fotos y contenido multimedia"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Explora archivos multimedia"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Problema con <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g>: no funciona"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Presiona para solucionar el problema"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"<xliff:g id="NAME">%s</xliff:g> no es compatible"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g>: no funciona"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"El dispositivo no es compatible con <xliff:g id="NAME">%s</xliff:g>. Presiona la pantalla para configurarlo en un formato compatible."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"Este dispositivo no es compatible con: <xliff:g id="NAME">%s</xliff:g>. Selecciona para configurar el medio en un formato compatible."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Selecciona para configurar <xliff:g id="NAME">%s</xliff:g> en un formato compatible."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Es posible que debas reformatear el dispositivo"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"Se extrajo <xliff:g id="NAME">%s</xliff:g> de forma inesperada."</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Expulsa los dispositivos multimedia antes de extraerlos para evitar la pérdida de contenido"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Usar acceso directo"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversión de color"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Corrección de color"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Reducir el brillo"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Atenuación extra"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Como mantuviste presionadas las teclas de volumen, se activó <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Se presionaron las teclas de volumen. Se desactivó <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Mantén presionadas ambas teclas de volumen durante tres segundos para usar <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Acceso directo de accesibilidad en pantalla"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Selector del acceso directo de accesibilidad en pantalla"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Acceso directo de accesibilidad"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Descartar panel de notificaciones"</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">"Se colocó <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> en el bucket RESTRICTED"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Nueva: Ampliación de ventanas"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Puedes ampliar toda tu pantalla o parte de ella"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Cómo ampliar una parte de la pantalla"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Ahora puedes ampliar toda la pantalla o parte de ella, o bien alternar entre ambas opciones."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Activar en Configuración"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Descartar"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Para continuar, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&amp;gt necesita acceso al micrófono del dispositivo."</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privacidad del sensor"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Ícono de la aplicación"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Imagen de marca de la aplicación"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Verifica la configuración de acceso"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> puede ver y controlar tu pantalla. Presiona para revisar esta opción."</string>
 </resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 0e163d2..ce2ee37 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Servicio de Twilight"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Detector de zona horaria (sin conexión)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"Servicio de actualización de tiempo GNSS"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Servicio de gestión de reconocimiento de música"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Tu dispositivo se borrará"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"No se puede utilizar la aplicación de administración. Se borrarán todos los datos del dispositivo.\n\nSi tienes alguna pregunta, ponte en contacto con el administrador de tu organización."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> ha inhabilitado la impresión."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Aplicación en ejecución"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Aplicaciones que consumen batería"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Ampliación"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Política de seguridad de accesibilidad"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> está usando la batería"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> aplicaciones están usando la batería"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Toca para ver información detallada sobre el uso de datos y de la batería"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Permite que la aplicación aparezca en la barra de estado."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"expandir/contraer la barra de estado"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Permite que la aplicación expanda o contraiga la barra de estado."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"Mostrar notificaciones como actividades de pantalla completa en un dispositivo bloqueado"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Permite que la aplicación muestre las notificaciones como actividades de pantalla completa en un dispositivo bloqueado"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"instalar accesos directos"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Permite que una aplicación añada accesos directos a la pantalla de inicio sin intervención del usuario."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"desinstalar accesos directos"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Usar biometría o bloqueo de pantalla"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Verifica que eres tú"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Usa tu biometría para continuar"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Usa la biometría o tu bloqueo de pantalla para continuar"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Hardware biométrico no disponible"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Autenticación cancelada"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"No se reconoce"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Usar huella digital"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Usar huella digital o bloqueo de pantalla"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Usa tu huella digital para continuar"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Usa tu huella digital o tu bloqueo de pantalla para continuar"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Icono de huella digital"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Usar desbloqueo facial"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Usar desbloqueo facial o bloqueo de pantalla"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Usa el desbloqueo facial para continuar"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Usa tu cara o tu bloqueo de pantalla para continuar"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Icono cara"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"No tienes permiso para abrir esta página."</string>
     <string name="text_copied" msgid="2531420577879738860">"Texto copiado al portapapeles."</string>
     <string name="copied" msgid="4675902854553014676">"Copiado"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ha pegado contenido de <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ha pegado contenido del portapapeles"</string>
     <string name="more_item_label" msgid="7419249600215749115">"Más"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"MENU+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta +"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Desactivar"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Comprobando <xliff:g id="NAME">%s</xliff:g>…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Revisando el contenido actual"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Analizando almacenamiento del dispositivo"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Nueva unidad: <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> no funciona"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Toca para configurar"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Selecciona para configurar"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Es posible que tengas que reformatear el dispositivo. Toca para expulsar."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"Para transferir fotos y multimedia"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Consulta los archivos del dispositivo"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Problema con <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> no funciona"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Toca para solucionar el problema"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"Medio externo (<xliff:g id="NAME">%s</xliff:g>) no admitido"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> no funciona"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"El dispositivo no admite este medio externo (<xliff:g id="NAME">%s</xliff:g>). Toca para configurarlo con un formato admitido."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"El dispositivo no admite esta <xliff:g id="NAME">%s</xliff:g>. Selecciónala para configurarla en un formato admitido."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Selecciona para configurar <xliff:g id="NAME">%s</xliff:g> en un formato compatible."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Es posible que tengas que reformatear el dispositivo"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"Extracción inesperada de <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Extrae el dispositivo de forma segura antes de sacarlo para evitar perder contenido"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Utilizar acceso directo"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversión de color"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Corrección de color"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Reducir brillo"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Atenuación extra"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Al mantener pulsadas las teclas de volumen, se ha activado <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Se han mantenido pulsadas las teclas de volumen. Se ha desactivado <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Para utilizar <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, mantén pulsadas ambas teclas de volumen durante 3 segundos"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Acceso directo de accesibilidad en pantalla"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Menú de acceso directo de accesibilidad en pantalla"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Acceso directo de accesibilidad"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Cerrar pantalla de notificaciones"</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> se ha incluido en el grupo de restringidos"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Nuevo: Lupa de ventanas"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Ahora puedes ampliar toda la pantalla o una parte"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Ampliar parte de la pantalla"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Ahora puedes ampliar toda la pantalla o una parte concreta, o cambiar entre ambas opciones."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Activar en Ajustes"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Cerrar"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Para continuar, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; necesita tener acceso al micrófono del dispositivo."</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privacidad del sensor"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Icono de aplicación"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Imagen de marca de aplicación"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Comprueba los ajustes de acceso"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> puede ver y controlar tu pantalla. Toca para revisarlo."</string>
 </resources>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 9f6df6e..04ab1f3 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Teenus Twilight"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Ajavööndi tuvastaja (ühenduvus puudub)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS-i aja värskendamise teenus"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Muusikatuvastuse halduri teenus"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Seade kustutatakse"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Administraatori rakendust ei saa kasutada. Teie seade tühjendatakse nüüd.\n\nKui teil on küsimusi, võtke ühendust organisatsiooni administraatoriga."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Rakendus <xliff:g id="OWNER_APP">%s</xliff:g> on printimise keelanud."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Rakendus töötab"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Rakendused kasutavad akutoidet"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Suurendus"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Juurdepääsufunktsioonide turvaeeskirjad"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> kasutab akutoidet"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> rakendust kasutab akutoidet"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Aku ja andmekasutuse üksikasjade nägemiseks puudutage"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Võimaldab rakendusel olla olekuriba."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"laienda/ahenda olekuriba"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Võimaldab rakendusel laiendada või ahendada olekuriba."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"Kuva märguanded lukustatud seadmes täisekraantegevustena"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Lubab rakendusel märguandeid lukustatud seadmes täisekraantegevustena kuvada"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"otseteede installimine"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Lubab rakendusel lisada avakuva otseteid ilma kasutaja sekkumiseta."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"otseteede desinstallimine"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Biomeetria või ekraaniluku kasutamine"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Kinnitage oma isik"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Jätkamiseks kasutage biomeetriat"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Jätkamiseks kasutage oma biomeetrilisi andmeid või ekraanilukku"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biomeetriline riistvara ei ole saadaval"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Autentimine tühistati"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Ei tuvastatud"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Sõrmejälje kasutamine"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Sõrmejälje või ekraaniluku kasutamine"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Jätkamiseks kasutage sõrmejälge"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Jätkamiseks kasutage oma sõrmejälge või ekraanilukku"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Sõrmejälje ikoon"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Face Unlocki kasutamine"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Face Unlocki või ekraaniluku kasutamine"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Jätkamiseks kasutage Face Unlocki"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Jätkamiseks kasutage oma nägu või ekraanilukku"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Näoikoon"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"Teil pole luba selle lehe avamiseks."</string>
     <string name="text_copied" msgid="2531420577879738860">"Lõikelauale kopeeritud tekst."</string>
     <string name="copied" msgid="4675902854553014676">"Kopeeritud"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> kleepis rakendusest <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> kleepis lõikelaualt"</string>
     <string name="more_item_label" msgid="7419249600215749115">"Rohkem"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Menüü+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta +"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Lülita välja"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Üksuse <xliff:g id="NAME">%s</xliff:g> kontrollimine …"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Kontrollitakse praegust sisu"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Meedia salvestusruumi analüüsimine"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Uus üksus <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> ei tööta"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Puudutage seadistamiseks"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Valige seadistamiseks"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Peate võib-olla seadme uuesti vormindama. Puudutage väljutamiseks."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"Fotode ja meedia ülekandmiseks"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Sirvige meediafaile"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Probleem üksusega <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> ei tööta"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Puudutage parandamiseks"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"Toetamata <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> ei tööta"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"See seade ei toeta üksust <xliff:g id="NAME">%s</xliff:g>. Puudutage toetatud vormingus seadistamiseks."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"See seade ei toeta kaarti <xliff:g id="NAME">%s</xliff:g>. Valige toetatud vormingus seadistamiseks."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Valige üksuse <xliff:g id="NAME">%s</xliff:g> seadistamiseks toetatud vormingus."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Peate võib-olla seadme uuesti vormindama"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"Üksus <xliff:g id="NAME">%s</xliff:g> eemaldati ootamatult"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Enne eemaldamist väljutage meedia, et vältida sisu kaotsiminekut"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Kasuta otseteed"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Värvide ümberpööramine"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Värvide korrigeerimine"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Ereduse vähendamine"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Eriti tume"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Helitugevuse klahve hoiti all. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> lülitati sisse."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Helitugevuse klahve hoiti all. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> lülitati välja."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Teenuse <xliff:g id="SERVICE_NAME">%1$s</xliff:g> kasutamiseks hoidke kolm sekundit all mõlemat helitugevuse klahvi"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Ekraanil kuvatav juurdepääsetavuse otsetee"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Ekraanil kuvatav juurdepääsetavuse otsetee valija"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Juurdepääsetavuse otsetee"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Loobu märguandealast"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Rakenduse <xliff:g id="APP_NAME">%1$s</xliff:g> pealkirjariba."</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> on lisatud salve PIIRANGUTEGA"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Uus: akna suurendaja"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Nüüd saab suurendada kogu ekraanikuva või osa sellest"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Ekraanikuva teatud osa suurendamine"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Nüüd on teil võimalik suurendada täisekraani, konkreetset ala või mõlema võimaluse vahel vahetada."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Lülitage sisse menüüs Seaded"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Loobu"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Jätkamiseks vajab rakendus &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; juurdepääsu teie seadme mikrofonile."</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Anduri privaatsus"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Rakenduse ikoon"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Rakenduse brändi kujutis"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Kontrollige juurdepääsuseadeid"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> saab vaadata ja hallata teie ekraanikuva. Puudutage ülevaatamiseks."</string>
 </resources>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 72d0833..2677dfd 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -195,7 +195,7 @@
     <string name="network_logging_notification_title" msgid="554983187553845004">"Jabeak kudeatzen du gailua"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Erakundeak kudeatzen du gailua eta baliteke sareko trafikoa gainbegiratzea. Sakatu hau xehetasunak ikusteko."</string>
     <string name="location_changed_notification_title" msgid="3620158742816699316">"Aplikazioek zure kokapena atzi dezakete"</string>
-    <string name="location_changed_notification_text" msgid="7158423339982706912">"Informazio gehiago lortzeko, jo IKT sailaren administratzailearengana"</string>
+    <string name="location_changed_notification_text" msgid="7158423339982706912">"Informazio gehiago lortzeko, jo IKT saileko administratzailearengana"</string>
     <string name="geofencing_service" msgid="3826902410740315456">"Muga geografikoen zerbitzua"</string>
     <string name="country_detector" msgid="7023275114706088854">"Herrialde-hautemailea"</string>
     <string name="location_service" msgid="2439187616018455546">"Kokapen-zerbitzua"</string>
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Ilunabarreko zerbitzua"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Ordu-zonaren hautemailea (ez zaude konektatuta sarera)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS ordua eguneratzeko zerbitzua"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Musika hautemateko kudeaketa-zerbitzua"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Gailuko datuak ezabatu egingo dira"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Ezin da erabili administratzeko aplikazioa. Ezabatu egingo da gailuko eduki guztia.\n\nZalantzarik baduzu, jarri erakundeko administratzailearekin harremanetan."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> aplikazioak desgaitu egin du inprimatzeko aukera."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Aplikazio bat abian da"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Bateria kontsumitzen ari diren aplikazioak"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Lupa"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Irisgarritasunari buruzko segurtasun-gidalerroak"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> ari da bateria erabiltzen"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> aplikazio ari dira bateria erabiltzen"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Sakatu bateria eta datuen erabilerari buruzko xehetasunak ikusteko"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Egoera-barra izatea baimentzen die aplikazioei."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"zabaldu/tolestu egoera-barra"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Egoera-barra zabaltzeko edo tolesteko aukera ematen die aplikazioei."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"blokeatutako gailu batean jakinarazpenak pantaila osoko jarduera gisa bistaratzea"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Blokeatutako gailu batean jakinarazpenak pantaila osoko jarduera gisa bistaratzeko baimena ematen dio aplikazioari"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"instalatu lasterbideak"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Erabiltzaileak ezer egin gabe hasierako pantailan lasterbideak gehitzeko aukera ematen die aplikazioei."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"desinstalatu lasterbideak"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Erabili sistema biometrikoak edo pantailaren blokeoa"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Egiaztatu zeu zarela"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Aurrera egiteko, erabili sistema biometrikoak"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Aurrera egiteko, erabili sistema biometrikoak edo pantailaren blokeoa"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Hardware biometrikoa ez dago erabilgarri"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Utzi da autentifikazioa"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Ez da ezagutu"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Erabili hatz-marka"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Erabili hatz-marka edo pantailaren blokeoa"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Aurrera egiteko, erabili hatz-marka"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Aurrera egiteko, erabili hatz-marka edo pantailaren blokeoa"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Hatz-markaren ikonoa"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Erabili aurpegiaren bidez desblokeatzeko eginbidea"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Erabili aurpegia edo pantailaren blokeoa"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Aurrera egiteko, erabili aurpegiaren bidez desblokeatzeko eginbidea"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Aurrera egiteko, erabili aurpegia edo pantailaren blokeoa"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Aurpegiaren ikonoa"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"Ez duzu orri hau irekitzeko baimenik."</string>
     <string name="text_copied" msgid="2531420577879738860">"Testua arbelean kopiatu da."</string>
     <string name="copied" msgid="4675902854553014676">"Kopiatu da"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> aplikaziotik itsatsi da <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"Arbeletik itsatsi da <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>"</string>
     <string name="more_item_label" msgid="7419249600215749115">"Gehiago"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Menua+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta +"</string>
@@ -1213,7 +1222,7 @@
     <string name="unsupported_display_size_show" msgid="980129850974919375">"Erakutsi beti"</string>
     <string name="unsupported_compile_sdk_message" msgid="7326293500707890537">"Android sistema eragilearen bertsio bateraezin baterako dago egina <xliff:g id="APP_NAME">%1$s</xliff:g>; beraz, espero ez bezala funtziona lezake. Baliteke aplikazioaren bertsio eguneratuago bat eskuragarri egotea."</string>
     <string name="unsupported_compile_sdk_show" msgid="1601210057960312248">"Erakutsi beti"</string>
-    <string name="unsupported_compile_sdk_check_update" msgid="1103639989147664456">"Bilatu eguneratzea"</string>
+    <string name="unsupported_compile_sdk_check_update" msgid="1103639989147664456">"Bilatu eguneratzeak"</string>
     <string name="smv_application" msgid="3775183542777792638">"<xliff:g id="APPLICATION">%1$s</xliff:g> aplikazioak (<xliff:g id="PROCESS">%2$s</xliff:g> prozesua) berak aplikatutako StrictMode gidalerroa urratu du."</string>
     <string name="smv_process" msgid="1398801497130695446">"<xliff:g id="PROCESS">%1$s</xliff:g> prozesuak bere kabuz ezarritako StrictMode gidalerroak urratu ditu."</string>
     <string name="android_upgrading_title" product="default" msgid="7279077384220829683">"Telefonoa eguneratzen ari da…"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Desaktibatu"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"<xliff:g id="NAME">%s</xliff:g> egiaztatzen…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Edukia berrikusten"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Multimedia-edukiaren memoria-unitatea aztertzen"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Euskarri berria: <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> ez da funtzionatzen ari"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Sakatu konfiguratzeko"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Hauta ezazu konfiguratzeko"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Gailua formateatu beharko duzu, agian. Saka ezazu kanporatzeko."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"Argazkiak eta multimedia-fitxategiak transferitzeko"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Arakatu multimedia-fitxategiak"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Arazo bat dago honekin: <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> ez da funtzionatzen ari"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Sakatu konpontzeko"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"Ez da onartzen <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> ez da funtzionatzen ari"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"Gailuak ez du <xliff:g id="NAME">%s</xliff:g> onartzen. Sakatu onartzen den formatu batean konfiguratzeko."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"Gailuak ez du <xliff:g id="NAME">%s</xliff:g> onartzen. Hauta ezazu onartzen den formatu batean konfiguratzeko."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Hauta ezazu onartzen den formatu batean <xliff:g id="NAME">%s</xliff:g> konfiguratzeko."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Gailua formateatu beharko duzu, agian"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> ustekabean kendu da"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Kendu aurretik, kanporatu euskarria edukirik ez galtzeko"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Erabili lasterbidea"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Koloreen alderantzikatzea"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Koloreen zuzenketa"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Murriztu distira"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Are ilunago"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Bolumen-botoiak sakatuta eduki direnez, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> aktibatu egin da."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Bolumen-botoiak sakatuta eduki direnez, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> desaktibatu egin da."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> erabiltzeko, eduki sakatuta bi bolumen-botoiak hiru segundoz"</string>
@@ -1689,7 +1701,7 @@
     <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Eginbide batetik bestera aldatzeko, pasatu hiru hatz pantailaren behealdetik gora eta eduki sakatuta une batez."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Lupa"</string>
     <string name="user_switched" msgid="7249833311585228097">"Erabiltzailea: <xliff:g id="NAME">%1$s</xliff:g>."</string>
-    <string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> erabiltzailera aldatzen…"</string>
+    <string name="user_switching_message" msgid="1912993630661332336">"\"<xliff:g id="NAME">%1$s</xliff:g>\" erabiltzailera aldatzen…"</string>
     <string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> erabiltzailearen saioa amaitzen…"</string>
     <string name="owner_name" msgid="8713560351570795743">"Jabea"</string>
     <string name="error_message_title" msgid="4082495589294631966">"Errorea"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Pantailako erabilerraztasun-lasterbidea"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Pantailako erabilerraztasun-lasterbideen hautatzailea"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Erabilerraztasun-lasterbidea"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Baztertu jakinarazpenen panela"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioko azpitituluen barra."</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Murriztuen edukiontzian ezarri da <xliff:g id="PACKAGE_NAME">%1$s</xliff:g>"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Berria: leihoen lupa"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Orain, pantaila osoa edo haren zati bat handi dezakezu"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Handitu pantailaren zati bat"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Orain, pantaila osoa edo eremu zehatz bat handi dezakezu, edo bi aukeren artean aldatu."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Aktibatu ezarpenetan"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Baztertu"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Aurrera egiteko, gailuaren mikrofonoa atzitzeko baimena behar du &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; aplikazioak."</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Sentsoreen pribatutasuna"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Aplikazioaren ikonoa"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Aplikazioaren marka-irudia"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Begiratu sarbide-ezarpenak"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> zerbitzuak pantaila ikusi eta kontrola dezake. Sakatu berrikusteko."</string>
 </resources>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 76d0c1e..19d6256 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"‏سرویس Twilight"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"شناساگر منطقه زمانی (بدون اتصال)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"‏سرویس به‌روزرسانی زمان GNSS"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"سرویس مدیر تشخیص موسیقی"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"دستگاهتان پاک خواهد شد"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"برنامه سرپرست سیستم را نمی‌توان استفاده کرد. دستگاه شما در این لحظه پاک می‌شود.\n\nاگر سؤالی دارید، با سرپرست سیستم سازمانتان تماس بگیرید."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> چاپ کردن را غیرفعال کرده است."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"برنامه درحال اجرا"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"برنامه‌های مصرف‌کننده باتری"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"درشت‌نمایی"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"خط‌مشی امنیتی دسترس‌پذیری"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> درحال استفاده کردن از باتری است"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> برنامه درحال استفاده کردن از باتری هستند"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"برای جزئیات مربوط به مصرف باتری و داده، ضربه بزنید"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"‏به برنامه اجازه می‎دهد که تبدیل به نوار وضعیت شود."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"گسترش دادن/جمع کردن نوار وضعیت"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"‏به برنامه اجازه می‎دهد تا نوار ابزار را جمع کند یا باز کند."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"نمایش اعلان‌ها به‌صورت فعالیت‌های تمام‌صفحه در دستگاه قفل"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"به برنامه امکان می‌دهد اعلان‌ها را به‌صورت فعالیت‌های تمام‌صفحه در دستگاه قفل نمایش دهد"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"نصب میان‌برها"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"به برنامه اجازه می‌دهد میان‌برهای صفحه اصلی را بدون دخالت کاربر اضافه کند."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"حذف نصب میان‌برها"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"استفاده از زیست‌سنجشی یا قفل صفحه"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"تأیید کنید این شما هستید"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"برای ادامه، از زیست‌سنجشی استفاده کنید"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"برای ادامه، از زیست‌سنجشی یا قفل صفحه استفاده کنید"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"سخت‌افزار زیست‌سنجی دردسترس نیست"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"اصالت‌سنجی لغو شد"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"شناسایی نشد"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"استفاده از اثر انگشت"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"استفاده از اثر انگشت یا قفل صفحه"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"برای ادامه، از اثر انگشتتان استفاده کنید"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"برای ادامه، از اثر انگشت یا قفل صفحه استفاده کنید"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"نماد اثر انگشت"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"استفاده از «بازگشایی با چهره»"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"استفاده از قفل صفحه یا چهره"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"برای ادامه، از «بازگشایی با چهره» استفاده کنید"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"برای ادامه، از تشخیص چهره یا قفل صفحه استفاده کنید"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"نماد چهره"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"شما اجازه بازکردن این صفحه را ندارید."</string>
     <string name="text_copied" msgid="2531420577879738860">"متن در بریده‌دان کپی شد."</string>
     <string name="copied" msgid="4675902854553014676">"کپی شد"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> از <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> جای‌گذاری کرد"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> از بریده‌دان جای‌گذاری کرد"</string>
     <string name="more_item_label" msgid="7419249600215749115">"بیشتر"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"منو+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"‎Meta+‎"</string>
@@ -1025,7 +1034,7 @@
       <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> روز قبل</item>
     </plurals>
     <string name="last_month" msgid="1528906781083518683">"ماه گذشته"</string>
-    <string name="older" msgid="1645159827884647400">"قدیمی تر"</string>
+    <string name="older" msgid="1645159827884647400">"قدیمی‌تر"</string>
     <string name="preposition_for_date" msgid="2780767868832729599">"در <xliff:g id="DATE">%s</xliff:g>"</string>
     <string name="preposition_for_time" msgid="4336835286453822053">"در <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="preposition_for_year" msgid="3149809685340130039">"در <xliff:g id="YEAR">%s</xliff:g>"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"خاموش کردن"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"درحال بررسی <xliff:g id="NAME">%s</xliff:g>…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"درحال مرور محتوای کنونی"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"درحال تجزیه‌وتحلیل فضای ذخیره‌سازی رسانه"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"<xliff:g id="NAME">%s</xliff:g> جدید"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> کار نمی‌کند"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"برای راه‌اندازی ضربه بزنید"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"برای راه‌اندازی، انتخاب کنید"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"شاید لازم باشد دستگاه را دوباره قالب‌بندی کنید. برای خارج کردن، ضربه بزنید."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"برای انتقال عکس‌ها و رسانه"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"فایل‌های رسانه‌ای را مرور کنید"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"مشکل مرتبط با <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> کار نمی‌کند"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"برای برطرف کردن مشکل، ضربه بزنید"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"<xliff:g id="NAME">%s</xliff:g> پشتیبانی نشده"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> کار نمی‌کند"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"این دستگاه از این <xliff:g id="NAME">%s</xliff:g> پشتیبانی نمی‌کند. برای نصب آن در قالب پشتیبانی‌شده ضربه بزنید."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"این دستگاه از این <xliff:g id="NAME">%s</xliff:g> پشتیبانی نمی‌کند. برای تنظیم در یک قالب پشتیبانی‌شده، آن را انتخاب کنید."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"برای راه‌اندازی <xliff:g id="NAME">%s</xliff:g> در قالب پشتیبانی‌شده، انتخاب کنید."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"شاید لازم باشد دستگاه را دوباره قالب‌بندی کنید"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> به‌طور غیرمنتظره جدا شد"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"برای جلوگیری از از دست رفتن محتوا، رسانه را قبل از برداشتن بیرون برانید"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"استفاده از میان‌بر"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"وارونگی رنگ"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"تصحیح رنگ"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"کاهش روشنایی"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"بسیار کم‌نور"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"کلیدهای میزان صدا پایین نگه داشته شد. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> روشن شد."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"کلیدهای میزان صدا پایین نگه داشته شد. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> خاموش شد."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"برای استفاده از <xliff:g id="SERVICE_NAME">%1$s</xliff:g>، هر دو کلید صدا را فشار دهید و سه ثانیه نگه دارید"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"میان‌بر دسترس‌پذیری روی صفحه"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"انتخاب‌گر میان‌بر دسترس‌پذیری روی صفحه"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"میان‌بر دسترسی‌پذیری"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"رد کردن کشوی اعلانات"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"نوار شرح <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> در سطل «محدودشده» قرار گرفت"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"‏جدید: Window Magnifier"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"اکنون می‌توانید بخشی از صفحه یا کل آن را درشت کنید"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"درشت‌نمایی بخشی از صفحه‌نمایش"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"اکنون می‌توانید بخش مشخصی صفحه یا کل آن را درشت‌نمایی کنید، یا بیت دو گزینه جابه‌جا شوید."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"روشن کردن در «تنظیمات»"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"رد شدن"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"‏برای ادامه دادن، &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; باید به میکروفون دستگاه دسترسی داشته باشد."</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"حریم‌خصوصی حسگر"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"نماد برنامه"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"تصویر نمانام‌سازی برنامه"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"بررسی تنظیمات دسترسی"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> می‌تواند صفحه‌نمایش شما را مشاهده و کنترل کند. برای مرور، ضربه بزنید."</string>
 </resources>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 2e0d6cd..d78dffc 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Twilight-palvelu"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Aikavyöhykkeen tunnistin (ei yhteyttä)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS-ajanpäivityspalvelu"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Musiikintunnistuksen ylläpitopalvelu"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Laitteen tiedot poistetaan"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Hallintasovellusta ei voi käyttää. Laitteen tiedot pyyhitään.\n\nPyydä ohjeita järjestelmänvalvojaltasi."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> on poistanut tulostuksen käytöstä."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Sovellus käynnissä"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Akkua kuluttavat sovellukset"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Suurennus"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Esteettömyyden tietoturvakäytäntö"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> käyttää akkua."</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> sovellusta käyttää akkua."</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Katso lisätietoja akun ja datan käytöstä napauttamalla."</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Antaa sovelluksen sijaita tilapalkissa."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"laajentaa/tiivistää tilarivin"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Antaa sovelluksen laajentaa tai tiivistää tilarivin."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"näyttää ilmoituksia koko näytön tapahtumina lukitulla laitteella"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Sallii sovelluksen näyttää ilmoituksia koko näytön tapahtumina lukitulla laitteella"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"asentaa pikakuvakkeita"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Antaa sovelluksen lisätä aloitusruudun pikakuvakkeita ilman käyttäjän toimia."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"poista pikakuvakkeita"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Käytä biometriikkaa tai näytön lukitusta"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Vahvista henkilöllisyytesi"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Jatka käyttämällä biometriikkaa"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Jatka biometriikan tai näytön lukituksen avulla"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrinen laitteisto ei käytettävissä"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Todennus peruutettu"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Ei tunnistettu"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Käytä sormenjälkeä"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Käytä sormenjälkeä tai näytön lukitusta"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Jatka sormenjäljen avulla"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Jatka sormenjäljen tai näytön lukituksen avulla"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Sormenjälkikuvake"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Käytä Face Unlockia"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Käytä Face Unlockia tai näytön lukitusta"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Jatka käyttämällä Face Unlockia"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Jatka kasvojentunnistuksen tai näytön lukituksen avulla"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Kasvokuvake"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"Ei lupaa avata tätä sivua."</string>
     <string name="text_copied" msgid="2531420577879738860">"Teksti kopioitu leikepöydälle."</string>
     <string name="copied" msgid="4675902854553014676">"Kopioitu"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> liitetty täältä: <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> liitetty leikepöydältä"</string>
     <string name="more_item_label" msgid="7419249600215749115">"Lisää"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Valikko+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Poista käytöstä"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"<xliff:g id="NAME">%s</xliff:g> tarkastetaan…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Tarkastetaan nykyistä sisältöä"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Analysoidaan median tallennustilaa"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Uusi <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> ei toimi"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Määritä koskettamalla."</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Valitse käyttöönottoa varten"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Sinun on ehkä alustettava laite uudelleen. Poista napauttamalla."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"Kuvien ja median siirtämiseen"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Selaa mediatiedostoja"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Ongelma: <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> ei toimi"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Korjaa napauttamalla."</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"Epäyhteensopiva <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> ei toimi"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"<xliff:g id="NAME">%s</xliff:g> ei ole yhteensopiva tämän laitteen kanssa. Ota se käyttöön tuetussa tilassa napauttamalla."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"Tämä laite ei tue laitetta <xliff:g id="NAME">%s</xliff:g>. Valitse laite, niin voit suorittaa määrityksen tuetussa muodossa."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Valitse tämä, jos haluat, että <xliff:g id="NAME">%s</xliff:g> otetaan käyttöön tuetussa muodossa."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Sinun on ehkä alustettava laite uudelleen"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> poistettiin yllättäen"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Poista media ennen sen irrottamista, niin et menetä sisältöä."</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Käytä pikanäppäintä"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Käänteiset värit"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Värinkorjaus"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Vähennä kirkkautta"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Erittäin himmeä"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Äänenvoimakkuuspainikkeita painettiin pitkään. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> laitettiin päälle."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Äänenvoimakkuuspainikkeita painettiin pitkään. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> laitettiin pois päältä."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Voit käyttää palvelua <xliff:g id="SERVICE_NAME">%1$s</xliff:g> painamalla molempia äänenvoimakkuuspainikkeita kolmen sekunnin ajan"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Näytöllä näkyvä esteettömyyspainike"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Näytöllä näkyvän esteettömyyspainikkeen valitsin"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Esteettömyyspainike"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Sulje ilmoitusalue"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Tekstityspalkki: <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> on nyt rajoitettujen ryhmässä"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Uutta: ikkunan suurennus"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Voit nyt suurentaa näytön osittain tai kokonaan"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Suurenna näytön osa"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Voit nyt suurentaa koko näytön tai tietyn alueen tai vaihtaa yhdestä näistä vaihtoehdoista toiseen."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Laita päälle asetuksista"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Hylkää"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Jotta voit jatkaa, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; tarvitsee pääsyn laitteesi mikrofoniin."</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Anturin tietosuoja"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Sovelluskuvake"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Sovelluksen tuotemerkkikuva"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Tarkista pääsyasetukset"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> voi nähdä ja ohjata näyttöäsi. Tarkista napauttamalla."</string>
 </resources>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 1ebc604..3f18daf 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -57,7 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"Code IIEM"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"Numéro de l\'appelant (entrant)"</string>
-    <string name="ClirMmi" msgid="6752346475055446417">"Masquer l\'identifiant de l\'appelant sortant"</string>
+    <string name="ClirMmi" msgid="6752346475055446417">"Masquer l\'identifiant de l\'appelant (appels sortants)"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"Identifiant de la ligne connectée"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"Restriction d\'identifiant de la ligne connectée"</string>
     <string name="CfMmi" msgid="8390012691099787178">"Transfert d\'appel"</string>
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Service de crépuscule"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Détecteur de fuseau horaire (aucune connectivité)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"Service d\'actualisation de l\'heure GNSS"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Service de gestion de la reconnaissance musicale"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Le contenu de votre appareil sera effacé"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Impossible d\'utiliser l\'application d\'administration. Les données de votre appareil vont maintenant être effacées.\n\nSi vous avez des questions, communiquez avec l\'administrateur de votre organisation."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Impression désactivée par <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Application en cours d\'exécution"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Applications qui sollicitent la pile"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Agrandissement"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Politique de sécurité relative aux fonctionnalités d\'accessibilité"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> sollicite la pile"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> applications sollicitent la pile"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Touchez pour afficher des détails sur l\'utilisation de la pile et des données"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Permet à l\'application de faire office de barre d\'état."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"agrandir ou réduire la barre d\'état"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Permet à l\'application de réduire ou de développer la barre d\'état."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"afficher les notifications en mode plein écran sur un appareil verrouillé"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Permet à l\'application d\'afficher les notifications en mode plein écran sur un appareil verrouillé."</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"installer des raccourcis"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Permet à une application d\'ajouter des raccourcis sans l\'intervention de l\'utilisateur."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"désinstaller des raccourcis"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Utiliser les données biométriques ou le verrouillage de l\'écran"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Confirmez que c\'est vous"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Utilisez votre méthode d\'authentification biométrique pour continuer"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Utilisez vos données biométriques ou le verrouillage de l\'écran pour continuer"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Matériel biométrique indisponible"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Authentification annulée"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Données biométriques non reconnues"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Utiliser l\'empreinte digitale"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Utiliser l\'empreinte digitale ou le verrouillage de l\'écran"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Utilisez votre empreinte digitale pour continuer"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Utilisez votre empreinte digitale ou le verrouillage de l\'écran pour continuer"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Icône d\'empreinte digitale"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Utiliser le déverrouillage par reconnaissance faciale"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Utiliser la reconnaissance faciale ou le verrouillage de l\'écran"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Utilisez le déverrouillage par reconnaissance faciale pour continuer"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Utilisez votre visage ou le verrouillage de l\'écran pour continuer"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Icône visage"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"Vous n\'êtes pas autorisé à ouvrir cette page."</string>
     <string name="text_copied" msgid="2531420577879738860">"Le texte a été copié dans le presse-papiers."</string>
     <string name="copied" msgid="4675902854553014676">"Copié"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> collé à partir de <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> collé à partir du presse-papiers"</string>
     <string name="more_item_label" msgid="7419249600215749115">"Plus"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Menu+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Méta+"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Désactiver"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Vérification de <xliff:g id="NAME">%s</xliff:g> en cours…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Vérification du contenu actuel"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Analyse de l\'espace de stockage sur le support en cours…"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Nouveau périphérique <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> ne fonctionne pas"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Toucher pour configurer"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Sélectionnez pour configurer"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Vous devrez peut-être reformater l\'appareil. Touchez pour l\'éjecter."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"Pour transférer des photos et d\'autres fichiers"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Parcourir les fichiers multimédias"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Il y a un problème avec <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> ne fonctionne pas"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Touchez la notification pour corriger la situation"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"<xliff:g id="NAME">%s</xliff:g> non compatible"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> ne fonctionne pas"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"Cet appareil n\'est pas compatible avec la mémoire de stockage « <xliff:g id="NAME">%s</xliff:g> ». Touchez pour la configurer dans un format compatible."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"Cet appareil ne prend pas en charge ce média « <xliff:g id="NAME">%s</xliff:g> ». Sélectionnez-le pour le configurer dans un format compatible."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Sélectionner pour configurer <xliff:g id="NAME">%s</xliff:g> dans un format pris en charge."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Vous devrez peut-être reformater l\'appareil"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"Retrait inattendu de la mémoire « <xliff:g id="NAME">%s</xliff:g> »"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Éjectez les périphériques avant de les retirer pour éviter toute perte de données."</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Utiliser le raccourci"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversion des couleurs"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Correction des couleurs"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Réduire la luminosité"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Réduction supplémentaire de la luminosité"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Touches de volume maintenues enfoncées. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> activé."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Touches de volume maintenues enfoncées. Service <xliff:g id="SERVICE_NAME">%1$s</xliff:g> désactivé."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Maintenez enfoncées les deux touches de volume pendant trois secondes pour utiliser <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -1689,7 +1701,7 @@
     <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Pour basculer entre les fonctionnalités, balayez l\'écran vers le haut avec trois doigts et maintenez-les-y."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Zoom"</string>
     <string name="user_switched" msgid="7249833311585228097">"Utilisateur actuel : <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="user_switching_message" msgid="1912993630661332336">"Changement d\'utilisateur (<xliff:g id="NAME">%1$s</xliff:g>) en cours…"</string>
+    <string name="user_switching_message" msgid="1912993630661332336">"Passage au profil : <xliff:g id="NAME">%1$s</xliff:g>…"</string>
     <string name="user_logging_out_message" msgid="7216437629179710359">"Déconnexion de <xliff:g id="NAME">%1$s</xliff:g> en cours..."</string>
     <string name="owner_name" msgid="8713560351570795743">"Propriétaire"</string>
     <string name="error_message_title" msgid="4082495589294631966">"Erreur"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Raccourci d\'accessibilité à l\'écran"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Sélecteur de raccourci d\'accessibilité à l\'écran"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Raccourci d\'accessibilité"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Ignorer le volet de notification"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Barre de légende de l\'application <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> a été placé dans le compartiment RESTREINT"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g> :"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Nouveauté : Loupe de fenêtre"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Vous pouvez agrandir une partie ou la totalité de votre écran"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Agrandir une partie de votre écran"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Vous pouvez maintenant agrandir la totalité de votre écran, une région précise ou passer d\'une option à l\'autre."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Activer dans les paramètres"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Fermer"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Pour continuer, vous devez accorder l\'accès au microphone de votre appareil à l\'application &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt;."</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Confidentialité des capteurs"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Icône de l\'application"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Image de marque de l\'application"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Vérifiez les paramètres d\'accès"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> peut voir et contrôler votre écran. Touchez pour examiner."</string>
 </resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index ce36dbc..10a3bad 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Service Twilight"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Outil de détection du fuseau horaire (aucune connectivité)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"Service de mise à jour de l\'heure GNSS"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Service du gestionnaire de reconnaissance musicale"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Les données de votre appareil vont être effacées"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Impossible d\'utiliser l\'application d\'administration. Les données de votre appareil vont maintenant être effacées.\n\nSi vous avez des questions, contactez l\'administrateur de votre organisation."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Impression désactivée par <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Application en cours d\'exécution"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Applications utilisant la batterie"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Agrandissement"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Règlement sur la sécurité de l\'accessibilité"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> utilise la batterie"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> applications utilisent la batterie"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Appuyer pour obtenir des informations sur l\'utilisation de la batterie et des données"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Permet à l\'application de faire office de barre d\'état."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"Agrandir/réduire la barre d\'état"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Permet à l\'application de réduire ou de développer la barre d\'état."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"Afficher les notifications en plein écran sur un appareil verrouillé"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Autorise l\'appli à afficher les notifications en plein écran sur un appareil verrouillé"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"Installer des raccourcis"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Permettre à une application d\'ajouter des raccourcis à l\'écran d\'accueil sans l\'intervention de l\'utilisateur"</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"désinstaller des raccourcis"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Utiliser la biométrie ou le verrouillage de l\'écran"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Confirmez votre identité"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Utilisez la biométrie pour continuer"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Utilisez la biométrie ou le verrouillage de l\'écran pour continuer"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Matériel biométrique indisponible"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Authentification annulée"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Non reconnu"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Utiliser l\'empreinte digitale"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Utiliser votre empreinte digitale ou le verrouillage de l\'écran"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Utilisez votre empreinte digitale pour continuer"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Utilisez votre empreinte digitale ou le verrouillage de l\'écran pour continuer"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Icône d\'empreinte digitale"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Utiliser Face Unlock"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Utiliser Face Lock ou le verrouillage de l\'écran"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Utilisez Face Unlock pour continuer"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Utilisez la reconnaissance faciale ou le verrouillage de l\'écran pour continuer"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Icône visage"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"Vous n\'êtes pas autorisé à ouvrir cette page."</string>
     <string name="text_copied" msgid="2531420577879738860">"Le texte a été copié dans le presse-papier."</string>
     <string name="copied" msgid="4675902854553014676">"Copie effectuée"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> collé depuis <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> collé depuis le presse-papiers"</string>
     <string name="more_item_label" msgid="7419249600215749115">"Plus"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Menu+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Méta+"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Désactiver"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Vérification de \"<xliff:g id="NAME">%s</xliff:g>\"…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Vérification du contenu actuel"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Analyse de l\'espace de stockage…"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Nouveau périphérique : <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> ne fonctionne pas"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Appuyer pour configurer"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Sélectionnez pour configurer"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Vous devez peut-être reformater le périphérique. Appuyez pour l\'éjecter."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"Pour transférer photos et fichiers"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Parcourez les fichiers multimédias"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Problème avec : <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> ne fonctionne pas"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Appuyez sur la notification pour résoudre le problème"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"<xliff:g id="NAME">%s</xliff:g> non compatible"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> ne fonctionne pas"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"Cet appareil n\'est pas compatible avec le support \"<xliff:g id="NAME">%s</xliff:g>\". Appuyez ici pour le configurer dans un format accepté."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"Cet appareil n\'est pas compatible avec cette <xliff:g id="NAME">%s</xliff:g>. Sélectionnez cette option pour la configurer dans un format accepté."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Sélectionnez pour configurer <xliff:g id="NAME">%s</xliff:g> dans un format accepté."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Vous devez peut-être reformater le périphérique"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"Retrait inattendu de mémoire \"<xliff:g id="NAME">%s</xliff:g>\""</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Éjectez le périphérique externe avant de le retirer pour éviter toute perte de contenu"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Utiliser le raccourci"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversion des couleurs"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Correction des couleurs"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Réduire la luminosité"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Encore moins lumineux"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Touches de volume appuyées de manière prolongée. Service <xliff:g id="SERVICE_NAME">%1$s</xliff:g> activé."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Touches de volume appuyées de manière prolongée. Service <xliff:g id="SERVICE_NAME">%1$s</xliff:g> désactivé."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Appuyez de manière prolongée sur les deux touches de volume pendant trois secondes pour utiliser <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -1689,7 +1701,7 @@
     <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Pour changer de fonctionnalité, balayez l\'écran vers le haut avec trois doigts et appuyez de manière prolongée."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Agrandissement"</string>
     <string name="user_switched" msgid="7249833311585228097">"Utilisateur actuel : <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="user_switching_message" msgid="1912993630661332336">"Chargement du profil de <xliff:g id="NAME">%1$s</xliff:g>..."</string>
+    <string name="user_switching_message" msgid="1912993630661332336">"Passage au profil : <xliff:g id="NAME">%1$s</xliff:g>..."</string>
     <string name="user_logging_out_message" msgid="7216437629179710359">"Déconnexion de <xliff:g id="NAME">%1$s</xliff:g>…"</string>
     <string name="owner_name" msgid="8713560351570795743">"Propriétaire"</string>
     <string name="error_message_title" msgid="4082495589294631966">"Erreur"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Raccourci d\'accessibilité à l\'écran"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Outil de sélection des raccourcis d\'accessibilité à l\'écran"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Raccourci d\'accessibilité"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Fermer le volet des notifications"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Barre de légende de l\'application <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> a été placé dans le bucket RESTRICTED"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g> :"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Nouveau : agrandissement de la fenêtre"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Vous pouvez agrandir tout ou partie de l\'écran"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Agrandissez une partie de l\'écran"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Vous pouvez agrandir tout ou partie de l\'écran, ou basculer entre ces deux options."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Activer dans les paramètres"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Fermer"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Pour continuer, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; a besoin d\'accéder au micro de votre appareil."</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Confidentialité du capteur"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Icône de l\'application"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Image de branding de l\'application"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Vérifiez les paramètres d\'accès"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> peut afficher et contrôler votre écran. Appuyez ici pour en savoir plus."</string>
 </resources>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 9d95af8..0aac641 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Servizo Twilight"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Detector de fuso horario (non require conexión)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"Servizo de actualización horaria mediante o GNSS"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Servizo de xestión de recoñecemento musical"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Borrarase o teu dispositivo"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Non se pode utilizar a aplicación de administración. Borrarase o teu dispositivo.\n\nSe tes preguntas, contacta co administrador da organización."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> desactivou a impresión."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Estase executando a aplicación"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Aplicacións que consomen batería"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Ampliación"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Política de seguranza relativa á accesibilidade"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"A aplicación <xliff:g id="APP_NAME">%1$s</xliff:g> está consumindo batería"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> aplicacións están consumindo batería"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Toca para obter información sobre o uso de datos e a batería"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Permite á aplicación ser a barra de estado."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"ampliar/contraer a barra de estado"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Permite á aplicación ampliar ou contraer a barra de estado."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"mostrar notificacións como actividades a pantalla completa nun dispositivo bloqueado"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Permite que a aplicación mostre notificacións como actividades a pantalla completa nun dispositivo bloqueado"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"instalar atallos"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Permite a unha aplicación engadir atallos na pantalla de inicio sen intervención do usuario."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"desinstalar atallos"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Utilizar desbloqueo biométrico ou credencial do dispositivo"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Verifica que es ti"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Para continuar, utiliza o desbloqueo biométrico"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Para continuar, utiliza o desbloqueo biométrico ou o bloqueo de pantalla"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"O hardware biométrico non está dispoñible"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Cancelouse a autenticación"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Non se recoñeceu"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Utilizar impresión dixital"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Utilizar impresión dixital ou credencial do dispositivo"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Utiliza a túa impresión dixital para continuar"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Para continuar, utiliza a impresión dixital ou o bloqueo de pantalla"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Icona de impresión dixital"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Utilizar desbloqueo facial"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Utilizar desbloqueo facial ou credencial do dispositivo"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Para continuar, utiliza o desbloqueo facial"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Para continuar, utiliza o desbloqueo facial ou a credencial do dispositivo"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Icona cara"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"Non tes permiso para abrir esta páxina."</string>
     <string name="text_copied" msgid="2531420577879738860">"O texto copiouse no portapapeis."</string>
     <string name="copied" msgid="4675902854553014676">"Copiuse"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> pegou contido procedente de <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> pegou contido procedente do portapapeis"</string>
     <string name="more_item_label" msgid="7419249600215749115">"Máis"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Menú+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta +"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Desactivar"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Comprobando <xliff:g id="NAME">%s</xliff:g>…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Revisando contido actual"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Analizando almacenamento do soporte"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Nova <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"O dispositivo (<xliff:g id="NAME">%s</xliff:g>) non funciona"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Toca para configurar"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Selecciona o soporte para configuralo"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Pode ser necesario que formates de novo o dispositivo. Toca para expulsalo."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"Para transferir fotos e contidos multimedia"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Explora os ficheiros do soporte"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Produciuse un problema coa <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"O dispositivo (<xliff:g id="NAME">%s</xliff:g>) non funciona"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Toca para solucionalo"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"<xliff:g id="NAME">%s</xliff:g> incompatible"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"O dispositivo (<xliff:g id="NAME">%s</xliff:g>) non funciona"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"Este dispositivo non é compatible con esta <xliff:g id="NAME">%s</xliff:g>. Toca para configurala nun formato compatible."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"Este dispositivo non é compatible con esta <xliff:g id="NAME">%s</xliff:g>. Selecciona para configurala nun formato compatible."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Selecciona <xliff:g id="NAME">%s</xliff:g> para configurar o soporte cun formato compatible."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Pode ser necesario que formates de novo o dispositivo"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"Retirouse a <xliff:g id="NAME">%s</xliff:g> de forma inesperada"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Para evitar perder contido, expulsa os dispositivos multimedia antes de quitalos"</string>
@@ -1677,7 +1689,8 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Utilizar atallo"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversión de cor"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Corrección de cor"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Reducir brillo"</string>
+    <!-- no translation found for reduce_bright_colors_feature_name (3222994553174604132) -->
+    <skip />
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Teclas de volume premidas. Activouse o servizo <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Teclas de volume premidas. Desactivouse <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Mantén premidas as teclas do volume durante tres segudos para usar <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -2086,6 +2099,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Atallo de accesibilidade en pantalla"</string>
     <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_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>
@@ -2223,8 +2237,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Nova función: Lupa de ventá"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Agora podes ampliar toda a pantalla ou parte dela"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Amplía parte da pantalla"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Xa podes ampliar a pantalla completa ou unha área específica, ou ben alternar entre ambas as dúas opcións."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Activar en Configuración"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Ignorar"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Para continuar, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; precisa acceder ao micrófono do dispositivo."</string>
@@ -2233,4 +2247,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privacidade do sensor"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Icona de aplicación"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Imaxe de marca da aplicación"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Comproba a configuración do acceso"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"Agora <xliff:g id="SERVICE_NAME">%s</xliff:g> pode ver e controlar a túa pantalla. Toca para revisalo."</string>
 </resources>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 334ba2d..40af808 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"ટ્વાઇલાઇટ સેવા"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"સમય ઝોન શોધવાની સુવિધા (કનેક્ટિવિટી જરૂરી નથી)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS સમય અપડેટ કરવાની સેવા"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"મ્યુઝિકની ઓળખ માટે મેનેજમેન્ટ સેવા"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"તમારું ઉપકરણ કાઢી નાખવામાં આવશે"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"વ્યવસ્થાપક ઍપનો ઉપયોગ કરી શકાશે નહીં. તમારું ઉપકરણ હવે કાઢી નાખવામાં આવશે.\n\nજો તમને પ્રશ્નો હોય, તો તમારી સંસ્થાના વ્યવસ્થાપકનો સંપર્ક કરો."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> દ્વારા પ્રિન્ટ કરવાનું બંધ કરાયું છે."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"ઍપ ચાલી રહ્યું છે"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"ઍપ બૅટરીનો વપરાશ કરી રહ્યાં છે"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"મોટું કરવાની સુવિધા"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"ઍક્સેસિબિલિટી સુરક્ષા પૉલિસી"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> બૅટરીનો ઉપયોગ કરી રહ્યું છે"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> ઍપ બૅટરીનો ઉપયોગ કરી રહ્યાં છે"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"બૅટરી અને ડેટા વપરાશ વિશેની વિગતો માટે ટૅપ કરો"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"ઍપ્લિકેશનને સ્ટેટસ બારમાં બતાવવાની મંજૂરી આપે છે."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"સ્ટેટસ બાર વિસ્તૃત કરો/સંકુકિત કરો"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"ઍપ્લિકેશનને સ્ટેટસ બાર વિસ્તૃત કરવાની અને સંકુચિત કરવાની મંજૂરી આપે છે."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"લૉક કરેલા ડિવાઇસ પર પૂર્ણ સ્ક્રીન પરની પ્રવૃતિઓની જેમ નોટિફિકેશન બતાવો"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"ઍપને લૉક કરેલા ડિવાઇસ પર પૂર્ણ સ્ક્રીન પરની પ્રવૃતિઓની જેમ નોટિફિકેશન બતાવવાની મંજૂરી આપે છે"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"શોર્ટકટ્સ ઇન્સ્ટોલ કરો"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"એપ્લિકેશનને વપરાશકર્તા હસ્તક્ષેપ વગર હોમસ્ક્રીન શોર્ટકટ્સ ઉમેરવાની મંજૂરી આપે છે."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"શોર્ટકટ્સ અનઇન્સ્ટોલ કરો"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"બાયોમેટ્રિક્સ અથવા સ્ક્રીન લૉકનો ઉપયોગ કરો"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"તે તમે જ છો એ ચકાસો"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"આગળ વધવા માટે બાયોમેટ્રિકનો ઉપયોગ કરો"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"ચાલુ રાખવા માટે તમારા બાયોમેટ્રિક ડેટા અથવા સ્ક્રીન લૉક સુવિધાનો ઉપયોગ કરો"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"બાયોમેટ્રિક હાર્ડવેર ઉપલબ્ધ નથી"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"પ્રમાણીકરણ રદ કર્યું"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"ઓળખાયેલ નથી"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ફિંગરપ્રિન્ટનો ઉપયોગ કરો"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ફિંગરપ્રિન્ટ અથવા સ્ક્રીન લૉકનો ઉપયોગ કરો"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"ચાલુ રાખવા માટે તમારી ફિંગરપ્રિન્ટનો ઉપયોગ કરો"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"ચાલુ રાખવા માટે તમારા ફિંગરપ્રિન્ટ અથવા સ્ક્રીન લૉકનો ઉપયોગ કરો"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"ફિંગરપ્રિન્ટ આયકન"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"ફેસ અનલૉકનો ઉપયોગ કરો"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"ફેસ લૉક અથવા સ્ક્રીન લૉકનો ઉપયોગ કરો"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"આગળ વધવા માટે ફેસ અનલૉકનો ઉપયોગ કરો"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"ચાલુ રાખવા માટે તમારા ફેસ લૉક અથવા સ્ક્રીન લૉકનો ઉપયોગ કરો"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"ચહેરા આઇકન"</string>
@@ -663,7 +670,7 @@
     <string name="permdesc_control_incall_experience" msgid="5896723643771737534">"એપ્લિકેશનને કૉલમાં વપરાશકર્તા અનુભવ પ્રદાન કરવાની મંજૂરી આપે છે."</string>
     <string name="permlab_readNetworkUsageHistory" msgid="8470402862501573795">"ઐતિહાસિક નેટવર્ક ઉપયોગ વાંચો"</string>
     <string name="permdesc_readNetworkUsageHistory" msgid="1112962304941637102">"એપ્લિકેશનને ચોક્કસ નેટવર્ક્સ અને ઍપ્લિકેશનો માટે ઐતિહાસિક નેટવર્ક વપરાશ વાંચવાની મંજૂરી આપે છે."</string>
-    <string name="permlab_manageNetworkPolicy" msgid="6872549423152175378">"નેટવર્ક નીતિ મેનેજ કરો"</string>
+    <string name="permlab_manageNetworkPolicy" msgid="6872549423152175378">"નેટવર્ક પૉલિસી મેનેજ કરો"</string>
     <string name="permdesc_manageNetworkPolicy" msgid="1865663268764673296">"ઍપને નેટવર્ક નીતિઓ મેનેજ કરવાની અને ઍપ-વિશિષ્ટ નિયમો નિર્ધારિત કરવાની મંજૂરી આપે છે."</string>
     <string name="permlab_modifyNetworkAccounting" msgid="7448790834938749041">"નેટવર્ક વપરાશ એકાઉન્ટિંગ સંશોધિત કરો"</string>
     <string name="permdesc_modifyNetworkAccounting" msgid="5076042642247205390">"એપ્લિકેશનને કેવી રીતે ઍપ્લિકેશનો સામે નેટવર્ક વપરાશ ગણવામાં આવે છે તે સંશોધિત કરવાની મંજૂરી આપે છે. સામાન્ય ઍપ્લિકેશનો દ્વારા ઉપયોગમાં લેવા માટે નથી."</string>
@@ -719,7 +726,7 @@
     <string name="policydesc_wipeData_secondaryUser" product="tv" msgid="2293713284515865200">"ચેતવણી વિના આ Android TV ડિવાઇસ પર રહેલો આ વપરાશકર્તાનો ડેટા કાઢી નાખો."</string>
     <string name="policydesc_wipeData_secondaryUser" product="default" msgid="2788325512167208654">"ચેતવણી વિના આ ફોન પરનો આ વપરાશકર્તાનો ડેટા કાઢી નાખો."</string>
     <string name="policylab_setGlobalProxy" msgid="215332221188670221">"ઉપકરણ વૈશ્વિક પ્રોક્સી સેટ કરો"</string>
-    <string name="policydesc_setGlobalProxy" msgid="7149665222705519604">"નીતિ સક્ષમ હોય તે વખતે ઉપયોગ કરવા માટેના ઉપકરણ વૈશ્વિક પ્રોક્સીને સેટ કરો. ફક્ત ઉપકરણના માલિક વૈશ્વિક પ્રોક્સી સેટ કરી શકે છે."</string>
+    <string name="policydesc_setGlobalProxy" msgid="7149665222705519604">"પૉલિસી સક્ષમ હોય તે વખતે ઉપયોગ કરવા માટેના ડિવાઇસ વૈશ્વિક પ્રોક્સીને સેટ કરો. ફક્ત ડિવાઇસના માલિક વૈશ્વિક પ્રોક્સી સેટ કરી શકે છે."</string>
     <string name="policylab_expirePassword" msgid="6015404400532459169">"સ્ક્રીન લૉક પાસવર્ડ સમાપ્તિ સેટ કરો"</string>
     <string name="policydesc_expirePassword" msgid="9136524319325960675">"કેટલા સમયાંતરે સ્ક્રીન લૉક પાસવર્ડ, પિન અથવા પૅટર્ન બદલવો આવશ્યક છે, તેને બદલો."</string>
     <string name="policylab_encryptedStorage" msgid="9012936958126670110">"સંગ્રહ એન્ક્રિપ્શન સેટ કરો"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"તમને આ પૃષ્ઠને ખોલવાની પરવાનગી નથી."</string>
     <string name="text_copied" msgid="2531420577879738860">"ક્લિપબોર્ડ પર ટેક્સ્ટ કૉપિ કરી."</string>
     <string name="copied" msgid="4675902854553014676">"કૉપિ કરેલ"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>માંથી કૉપિ કરાયેલો ડેટા <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>માં પેસ્ટ કરવામાં આવ્યો"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"ક્લિપબોર્ડ ડેટાને <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>માં પેસ્ટ કર્યો"</string>
     <string name="more_item_label" msgid="7419249600215749115">"વધુ"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"મેનૂ+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"બંધ કરો"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"<xliff:g id="NAME">%s</xliff:g> તપાસી રહ્યાં છીએ…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"હાલના કન્ટેન્ટને રિવ્યૂ કરવું"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"મીડિયા સ્ટોરેજનું વિશ્લેષણ કરી રહ્યાં છીએ"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"નવું <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> કામ કરી રહ્યું નથી"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"સેટ કરવા માટે ટૅપ કરો"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"સેટઅપ કરવા માટે પસંદ કરો"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"તમને કદાચ ડિવાઇસને ફરીથી ફૉર્મેટ કરવાની જરૂર પડી શકે છે. બહાર કાઢવા માટે ટૅપ કરો."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"ફોટો અને મીડિયા ટ્રાન્સફર કરવા માટે"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"મીડિયા ફાઇલો બ્રાઉઝ કરો"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"<xliff:g id="NAME">%s</xliff:g>ની સમસ્યા"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> કામ કરી રહ્યું નથી"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"ઠીક કરવા માટે ટૅપ કરો"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"અસમર્થિત <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> કામ કરી રહ્યું નથી"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"આ ઉપકરણ આ <xliff:g id="NAME">%s</xliff:g> નું સમર્થન કરતું નથી. સમર્થિત ફોર્મેટમાં સેટ કરવા માટે ટૅપ કરો."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"આ ઉપકરણ આ <xliff:g id="NAME">%s</xliff:g> નું સમર્થન કરતું નથી. સમર્થિત ફૉર્મેટમાં સેટ કરવા માટે પસંદ કરો."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"સપોર્ટ કરતા હોય એવા ફૉર્મેટમાં <xliff:g id="NAME">%s</xliff:g>નું સેટઅપ કરવા માટે પસંદ કરો."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"તમને કદાચ ડિવાઇસને ફરીથી ફૉર્મેટ કરવાની જરૂર પડી શકે છે"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> અનપેક્ષિત રીતે દૂર કર્યું"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"કન્ટેન્ટ ગુમાવવાનું ટાળવા માટે મીડિયાને દૂર કરતા પહેલાં બહાર કાઢો"</string>
@@ -1677,7 +1689,8 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"શૉર્ટકટનો ઉપયોગ કરો"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"વિપરીત રંગમાં બદલવું"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"રંગ સુધારણા"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"બ્રાઇટનેસ ઘટાડો"</string>
+    <!-- no translation found for reduce_bright_colors_feature_name (3222994553174604132) -->
+    <skip />
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"વૉલ્યૂમ કી દબાવી રાખો. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ચાલુ કરી."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"વૉલ્યૂમ કી દબાવી રાખો. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> બંધ કરી."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>નો ઉપયોગ કરવા માટે બન્ને વૉલ્યૂમ કીને ત્રણ સેકન્ડ સુધી દબાવી રાખો"</string>
@@ -2086,6 +2099,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"સ્ક્રીન પરના ઍક્સેસિબિલિટી શૉર્ટકટ"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"સ્ક્રીન પરના ઍક્સેસિબિલિટી શૉર્ટકટના પસંદકર્તા"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"ઍક્સેસિબિલિટી શૉર્ટકટ"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"નોટિફિકેશન શેડ છોડી દો"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<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>ને પ્રતિબંધિત સમૂહમાં મૂકવામાં આવ્યું છે"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2237,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"નવી: વિંડો મોટી કરવાની સુવિધા"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"હવે તમે તમારી કેટલીક કે આખી સ્ક્રીનને મોટી કરી શકો છો"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"તમારી સ્ક્રીનનો અમુક ભાગ મોટો કરો"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"હવે તમે તમારી પૂર્ણ સ્ક્રીનને કે સ્ક્રીનના અમુક ચોક્કસ ભાગને મોટો કરી શકો છો અથવા બંને વિકલ્પો વચ્ચે સ્વિચ કરી શકો છો."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"સેટિંગમાં ચાલુ કરો"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"છોડી દો"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"ચાલુ રાખવા માટે, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt;ને તમારા ડિવાઇસના માઇક્રોફોનના ઍક્સેસની જરૂર છે."</string>
@@ -2233,4 +2247,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"સેન્સર પ્રાઇવસી સંબંધિત નોટિફિકેશન"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"ઍપ્લિકેશનનું આઇકન"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"ઍપ્લિકેશનની બ્રાંડિંગ છબી"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"ઍક્સેસના સેટિંગ ચેક કરો"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> તમારી સ્ક્રીન જોઈ અને નિયંત્રિત કરી શકે છે. રિવ્યૂ કરવા માટે ટૅપ કરો."</string>
 </resources>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 16e848f..20f703a 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"ट्वाइलाइट समय बताने वाली सेवा"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"समय क्षेत्र का पता लगाने वाली सुविधा (ऑफ़लाइन होने पर)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS समय अपडेट सेवा"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Music Recognition Manager Service"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"आपके डिवाइस को मिटा दिया जाएगा"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"एडमिन ऐप्लिकेशन का इस्तेमाल नहीं किया जा सकता. आपके डिवाइस पर मौजूद डेटा अब मिटा दिया जाएगा.\n\nअगर आप कुछ पूछना चाहते हैं तो, अपने संगठन के एडमिन से संपर्क करें."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> ने प्रिंटिंग सुविधा बंद कर दी है."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"ऐप अभी इस्तेमाल हो रहा है"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"बैटरी की खपत करने वाले ऐप"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"ज़ूम करने की सुविधा"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"सुलभता सुविधाओं से जुड़ी सुरक्षा नीति"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> बैटरी का इस्तेमाल कर रहा है"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> ऐप बैटरी का इस्तेमाल कर रहे हैं"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"बैटरी और डेटा खर्च की जानकारी के लिए छूएं"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"ऐप को स्टेटस बार बने रहने की अनुमति देता है."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"स्टेटस बार खोलकर बड़ा करें/छोटा करें"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"ऐप को, स्टेटस बार खोलकर बड़ा करने या उसे छोटा करने की अनुमति देता है."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"लॉक किए गए किसी डिवाइस पर सूचनाओं को फ़ुल स्क्रीन पर दिखाता है"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"यह अनुमति मिलने के बाद ऐप्लिकेशन, लॉक किए गए डिवाइस में सूचनाओं को फ़ुल स्क्रीन मोड में दिखाता है"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"शॉर्टकट इंस्‍टॉल करें"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"ऐप्‍लिकेशन को उपयोगकर्ता की रोक के बिना होमस्‍क्रीन शॉर्टकट जोड़ने की अनुमति देता है."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"शॉर्टकट अनइंस्टॉल करें"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"बायोमेट्रिक्स या स्क्रीन लॉक का क्रेडेंशियल इस्तेमाल करें"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"अपनी पहचान की पुष्टि करें"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"जारी रखने के लिए, बायोमेट्रिक्स इस्तेमाल करें"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"जारी रखने के लिए, बायोमेट्रिक या स्क्रीन लॉक क्रेडेंशियल डालकर पुष्टि करें"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"बायोमेट्रिक हार्डवेयर उपलब्ध नहीं है"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"प्रमाणीकरण रद्द किया गया"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"पहचान नहीं हो पाई"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"फ़िंगरप्रिंट इस्तेमाल करें"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"फ़िंगरप्रिंट या स्क्रीन लॉक का क्रेडेंशियल इस्तेमाल करें"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"जारी रखने के लिए फ़िंगरप्रिंट का इस्तेमाल करें"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"जारी रखने के लिए, फ़िंगरप्रिंट या स्क्रीन लॉक क्रेडेंशियल डालकर पुष्टि करें"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"फ़िंगरप्रिंट आइकॉन"</string>
@@ -632,8 +638,9 @@
     <string name="face_error_security_update_required" msgid="5076017208528750161">"सेंसर कुछ समय के लिए बंद कर दिया गया है."</string>
     <string name="face_name_template" msgid="3877037340223318119">"चेहरा <xliff:g id="FACEID">%d</xliff:g>"</string>
     <string name="face_app_setting_name" msgid="8130135875458467243">"\'फ़ेस अनलॉक\' इस्तेमाल करें"</string>
-    <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"चेहरा पहचानने की सुविधा या स्क्रीन लॉक का क्रेडेंशियल इस्तेमाल करें"</string>
+    <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"\'फ़ेस अनलॉक\' या स्क्रीन लॉक का क्रेडेंशियल इस्तेमाल करें"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"जारी रखने के लिए, \'फ़ेस अनलॉक\' इस्तेमाल करें"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"जारी रखने के लिए, अपना चेहरा दिखाकर या स्क्रीन लॉक क्रेडेंशियल डालकर पुष्टि करें"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"चेहरे का आइकॉन"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"आपके पास इस पेज को खोलने की अनुमति नहीं है."</string>
     <string name="text_copied" msgid="2531420577879738860">"लेख को क्‍लिपबोर्ड पर कॉपी किया गया."</string>
     <string name="copied" msgid="4675902854553014676">"कॉपी किया गया"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> से कॉपी किए गए डेटा को <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> में चिपकाया गया है"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"क्लिपबोर्ड के डेटा को <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> में चिपकाया गया है"</string>
     <string name="more_item_label" msgid="7419249600215749115">"और"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"मेन्यू+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"बंद करें"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"<xliff:g id="NAME">%s</xliff:g> ढूंढा जा रहा है…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"मौजूदा सामग्री की जाँच की जा रही है"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"मीडिया स्टोरेज की जांच हो रही है"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"नया <xliff:g id="NAME">%s</xliff:g> लगाया गया"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> काम नहीं कर रहा है"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"सेटअप करने के लिए टैप करें"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"सेट अप करने के लिए चुनें"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"आपको डिवाइस फिर से फ़ॉर्मैट करना पड़ सकता है. निकालने के लिए टैप करें."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"फ़ोटो और मीडिया ट्रांसफर करने के लिए"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"मीडिया फ़ाइलों को ब्राउज़ करें"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"<xliff:g id="NAME">%s</xliff:g> में गड़बड़ी है"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> काम नहीं कर रहा है"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"समस्या ठीक करने के लिए टैप करें"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"असमर्थित <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> काम नहीं कर रहा है"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"यह डिवाइस इस <xliff:g id="NAME">%s</xliff:g> का समर्थन नहीं करता है. समर्थित प्रारूप में सेट करने के लिए टैप करें."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"इस डिवाइस पर <xliff:g id="NAME">%s</xliff:g> काम नहीं करता है. काम करने वाले प्रारूप में सेट अप करने के लिए चुनें."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"<xliff:g id="NAME">%s</xliff:g> को काम करने वाले फ़ॉर्मैट में सेट अप करने के लिए चुनें."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"आपको डिवाइस फिर से फ़ॉर्मैट करना पड़ सकता है"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> अप्रत्याशित रूप से निकाला गया"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"पहले मीडिया डिवाइस निकालने का विकल्प चुनें, फिर उसे निकालें ताकि आपकी सामग्री सुरक्षित रहे"</string>
@@ -1645,7 +1657,7 @@
     <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4670840383567106114">"आपने अपना लॉक खोलने का पैटर्न <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत तरीके से बनाया है. <xliff:g id="NUMBER_1">%2$d</xliff:g> और गलत प्रयासों के बाद, आपसे अपने Android TV डिवाइस को अपने ईमेल खाते का इस्तेमाल करके अनलॉक करने के लिए कहा जाएगा.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकंड बाद प्रयास करें."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"आपने अपने अनलॉक आकार को <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत तरीके से आरेखित किया है. <xliff:g id="NUMBER_1">%2$d</xliff:g> और असफल प्रयासों के बाद, आपसे अपने फ़ोन को किसी ईमेल खाते का उपयोग करके अनलॉक करने के लिए कहा जाएगा.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकंड में फिर से प्रयास करें."</string>
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
-    <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"निकालें"</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"हटाएं"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"वॉल्यूम को सुझाए गए स्तर से ऊपर बढ़ाएं?\n\nअत्यधिक वॉल्यूम पर ज़्यादा समय तक सुनने से आपकी सुनने की क्षमता को नुकसान हो सकता है."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"सुलभता शॉर्टकट का इस्तेमाल करना चाहते हैं?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"शॉर्टकट के चालू होने पर, दाेनाें वॉल्यूम बटन (आवाज़ कम या ज़्यादा करने वाले बटन) को तीन सेकंड तक दबाने से, सुलभता सुविधा शुरू हाे जाएगी."</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"शॉर्टकट का उपयोग करें"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"रंग बदलने की सुविधा"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"रंग में सुधार करने की सुविधा"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"स्क्रीन की चमक कम करें"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"स्क्रीन की रोशनी को सामान्य लेवल से और कम करने की सुविधा"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"आवाज़ कम-ज़्यादा करने वाले दोनों बटन दबाकर रखें. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> को चालू कर दिया गया."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"आवाज़ कम-ज़्यादा करने वाले दोनों बटन दबाकर रखें. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> को बंद कर दिया गया."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> इस्तेमाल करने के लिए आवाज़ वाले दोनों बटन तीन सेकंड तक दबाकर रखें"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"स्क्रीन पर दिखने वाला सुलभता का शॉर्टकट"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"स्क्रीन पर दिखने वाले सुलभता के शॉर्टकट को चुनने का मेन्यू"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"सुलभता का शॉर्टकट"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"नोटिफ़िकेशन शेड खारिज करें"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<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> को प्रतिबंधित बकेट में रखा गया है"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"नई सुविधा: विंडो को ज़ूम करके देखने की सुविधा"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"अब अपनी पूरी स्क्रीन या कुछ हिस्से को ज़ूम करके देख सकते हैं"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"अपनी स्क्रीन के कुछ हिस्से को ज़ूम करें"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"अब आप अपनी फ़ुल स्क्रीन या स्क्रीन के किसी खास हिस्से को ज़ूम करके देख सकते हैं. इसके अलावा, आप इन दोनों विकल्पों के बीच स्विच भी कर सकते हैं."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"सेटिंग में जाकर, इस सुविधा को चालू करें"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"खारिज करें"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"जारी रखने के लिए, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; को आपके डिवाइस का माइक्रोफ़ोन ऐक्सेस करने की ज़रूरत है."</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"सेंसर से जुड़ी निजता के बारे में सूचना"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"ऐप्लिकेशन का आइकॉन"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"ऐप्लिकेशन की ब्रैंड इमेज"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"ऐक्सेस से जुड़ी सेटिंग देखें"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> आपकी स्क्रीन को देख सकता है और कंट्रोल कर सकता है. ऐक्सेस की समीक्षा करने के लिए टैप करें."</string>
 </resources>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 15c36c9..25db5e6 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -206,6 +206,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Usluga Sumrak"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Detektor vremenske zone (nije povezan)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS – usluga ažuriranja vremena"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Usluga upravitelja prepoznavanja glazbe"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Uređaj će se izbrisati"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Administratorska aplikacija ne može se upotrebljavati. Uređaj će se izbrisati.\n\nAko imate pitanja, obratite se administratoru organizacije."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Ispis je onemogućila aplikacija <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -296,6 +297,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Izvodi se aplikacija"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Aplikacije troše bateriju"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Povećavanje"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Pravila o sigurnosti za pristupačnost"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> koristi bateriju"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"Broj aplikacija koje koriste bateriju: <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Dodirnite da biste vidjeli pojedinosti o potrošnji baterije i podatkovnom prometu"</string>
@@ -346,6 +348,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Aplikaciji omogućuje da bude traka statusa."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"proširivanje/sažimanje trake statusa"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Omogućuje aplikaciji proširivanje ili sažimanje trake statusa."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"prikazivati obavijesti kao aktivnosti na cijelom zaslonu na zaključanom uređaju"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Omogućuje aplikaciji da na zaključanom uređaju prikazuje obavijesti kao aktivnosti na cijelom zaslonu"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"instaliranje prečaca"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Aplikaciji omogućuje dodavanje prečaca početnog zaslona bez intervencije korisnika."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"deinstaliranje prečaca"</string>
@@ -557,6 +561,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Upotreba biometrijske autentifikacije ili zaključavanja zaslona"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Potvrdite da ste to vi"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Upotrijebite svoju biometrijsku autentifikaciju da biste nastavili"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Za nastavak se identificirajte biometrijski ili vjerodajnicom zaključavanja zaslona"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrijski hardver nije dostupan"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Autentifikacija otkazana"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Nije prepoznato"</string>
@@ -590,6 +595,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Upotreba otiska prsta"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Upotreba otiska prsta ili zaključavanja zaslona"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Nastavite pomoću otiska prsta"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Za nastavak se identificirajte otiskom prsta ili vjerodajnicom zaključavanja zaslona"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikona otiska prsta"</string>
@@ -637,6 +643,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Upotreba otključavanja licem"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Upotreba lica ili zaključavanja zaslona"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Upotrijebite otključavanje licem da biste nastavili"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Za nastavak se identificirajte licem ili vjerodajnicom zaključavanja zaslona"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Ikona lica"</string>
@@ -1000,6 +1007,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"Nemate dozvolu za otvaranje te stranice."</string>
     <string name="text_copied" msgid="2531420577879738860">"Tekst kopiran u međuspremnik."</string>
     <string name="copied" msgid="4675902854553014676">"Kopirano"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"U aplikaciji <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> zalijepljen je sadržaj aplikacije <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"U aplikaciji <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> zalijepljen je sadržaj međuspremnika"</string>
     <string name="more_item_label" msgid="7419249600215749115">"Više"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Izbornik+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1390,11 +1399,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Isključi"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Provjeravanje medija <xliff:g id="NAME">%s</xliff:g>…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Pregled trenutačnog sadržaja"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Analiza pohrane na medijima"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Novi medij <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> ne radi"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Dodirnite za postavljanje"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Odaberite da biste postavili"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Možda ćete morati ponovo formatirati uređaj. Dodirnite za izbacivanje."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"Za prijenos fotografija i medija"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Pregledajte datoteke na medijima"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Poteškoća s medijem <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> ne radi"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Dodirnite za popravak"</string>
@@ -1403,7 +1415,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"Nepodržani medij za pohranu <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> ne radi"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"Uređaj ne podržava ovaj medij (<xliff:g id="NAME">%s</xliff:g>). Dodirnite da biste ga postavili u podržanom formatu."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"Ovaj uređaj ne podržava taj medij (<xliff:g id="NAME">%s</xliff:g>). Odaberite da biste postavili u podržanom formatu."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Odaberite da biste postavili medij <xliff:g id="NAME">%s</xliff:g> u podržanom formatu."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Možda ćete morati ponovo formatirati uređaj"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"Uređaj <xliff:g id="NAME">%s</xliff:g> iznenada je uklonjen"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Izbacite medij prije uklanjanja kako ne biste izgubili sadržaj"</string>
@@ -1699,7 +1711,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Upotrijebi prečac"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Inverzija boja"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Korekcija boje"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Smanjenje svjetline"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Dodatno tamno"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Držali ste tipke za glasnoću. Uključila se usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Držali ste tipke za glasnoću. Isključila se usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Pritisnite i zadržite tipke za glasnoću na tri sekunde da biste koristili uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -2120,6 +2132,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Prečac pristupačnosti na zaslonu"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Alat za odabir prečaca pristupačnosti na zaslonu"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Prečac pristupačnosti"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Odbacivanje zaslona obavijesti"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Traka naslova aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Paket <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> premješten je u spremnik OGRANIČENO"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2257,8 +2270,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Novo: alat za povećanje prozora"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Sad možete povećati dio zaslona ili cijeli zaslon"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Povećavanje dijela zaslona"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Sad možete povećati cijeli zaslon ili određeno područje ili izmjenjivati obje opcije."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Uključite u Postavkama"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Odbaci"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Da bi nastavila s radom, aplikacija &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; treba pristupiti mikrofonu vašeg uređaja."</string>
@@ -2267,4 +2280,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privatnost senzora"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Ikona aplikacije"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Imidž robne marke aplikacije"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Provjerite postavke pristupa"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> može pregledavati i kontrolirati vaš zaslon. Dodirnite za pregled."</string>
 </resources>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index f28f1b6..c25e691 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Twilight szolgáltatás"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Időzóna-felismerő (Offline)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS időfrissítési szolgáltatás"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Zenefelismerést kezelő szolgáltatás"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"A rendszer törölni fogja eszközét"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"A rendszergazdai alkalmazás nem használható. A rendszer most törli az eszközt.\n\nKérdéseivel forduljon szervezete rendszergazdájához."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"A(z) <xliff:g id="OWNER_APP">%s</xliff:g> letiltotta a nyomtatást."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Jelenleg futó alkalmazás"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Akkumulátort használó alkalmazások"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Nagyítás"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Kisegítő lehetőségek biztonsági házirendje"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> alkalmazás használja az akkumulátort"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> alkalmazás használja az akkumulátort"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Koppintson az akkumulátor- és adathasználat részleteinek megtekintéséhez"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Lehetővé teszi az alkalmazás számára, hogy az állapotsoron legyen."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"állapotsáv részletes- és listanézete"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Lehetővé teszi az alkalmazás számára, hogy váltson az állapotsor részletes és listanézete között."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"Értesítések megjelenítése teljes képernyős tevékenységként zárolt eszközön"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Lehetővé teszi az alkalmazás számára, hogy értesítéseket jelenítsen meg teljes képernyős tevékenységként zárolt eszközön."</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"parancsikonok telepítése"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Lehetővé teszi egy alkalmazás számára, hogy felhasználói beavatkozás nélkül adjon hozzá parancsikonokat a kezdőképernyőhöz."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"parancsikonok eltávolítása"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"A folytatás biometriai feloldással vagy képernyőzárral lehetséges"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Igazolja, hogy Ön az"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"A folytatás biometriai feloldással lehetséges"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"A folytatás biometriai feloldással vagy a képernyőzár feloldásával lehetséges"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrikus hardver nem áll rendelkezésre"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Hitelesítés megszakítva"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Nem ismerhető fel"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Ujjlenyomat használata"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"A folytatás ujjlenyomattal vagy képernyőzárral lehetséges"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"A folytatáshoz használja ujjlenyomatát"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"A folytatás ujjlenyomattal vagy a képernyőzár feloldásával lehetséges"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ujjlenyomat ikon"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Arcalapú feloldás használata"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"A folytatás arcalapú feloldással vagy képernyőzárral lehetséges"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"A folytatás arcalapú feloldással lehetséges"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"A folytatás arcalapú feloldással vagy a képernyőzár feloldásával lehetséges"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Arcikon"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"Nincs engedélye ennek az oldalnak a megnyitására."</string>
     <string name="text_copied" msgid="2531420577879738860">"A szöveg bemásolva a vágólapra."</string>
     <string name="copied" msgid="4675902854553014676">"Átmásolva"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"A(z) <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> tartalmat másolt vágólapra a(z) <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> appból"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"A(z) <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> beillesztette a vágólapon lévő tartalmat"</string>
     <string name="more_item_label" msgid="7419249600215749115">"Egyebek"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Menü+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Kikapcsolás"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"<xliff:g id="NAME">%s</xliff:g> ellenőrzése…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Az aktuális tartalom ellenőrzése"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Médiatárhely elemzése…"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Új <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"A(z) <xliff:g id="NAME">%s</xliff:g> nem működik"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Koppintson ide a beállításhoz"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Válassza ki a beállításhoz"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Előfordulhat, hogy újra kell formáznia az eszközt. Koppintson az eltávolításhoz."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"Fotók és más tartalmak átviteléhez"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Médiafájlok böngészése"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Probléma a következővel: <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"A(z) <xliff:g id="NAME">%s</xliff:g> nem működik"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Koppintson a javításhoz"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"Nem támogatott <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"A(z) <xliff:g id="NAME">%s</xliff:g> nem működik"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"Ez az eszköz nem támogatja ezt a(z) <xliff:g id="NAME">%s</xliff:g> eszközt. Koppintson rá a támogatott formátumban való beállításhoz."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"Ez az eszköz nem támogatja a(z) <xliff:g id="NAME">%s</xliff:g> nevű alkalmazást. Válassza ki a támogatott formátumú beállításhoz."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Válassza ki a(z) <xliff:g id="NAME">%s</xliff:g> támogatott formátumban történő beállításához."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Előfordulhat, hogy újra kell formáznia az eszközt"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"A(z) <xliff:g id="NAME">%s</xliff:g> váratlanul eltávolítva"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"A tartalomvesztés elkerülése érdekében az eltávolítás előtt előbb hajtsa végre az eszköz kiadását"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Billentyűparancs használata"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Színek invertálása"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Színkorrekció"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Fényerő csökkentése"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Extrasötét"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Nyomva tartotta a hangerőgombokat. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> bekapcsolva."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Nyomva tartotta a hangerőgombokat. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> kikapcsolva."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"A(z) <xliff:g id="SERVICE_NAME">%1$s</xliff:g> használatához tartsa lenyomva három másodpercig a két hangerőgombot"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Képernyőn megjelenő kisegítő lehetőségekre vonatkozó parancs"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Képernyőn megjelenő kisegítő lehetőségekre vonatkozó parancsválasztó"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Kisegítő lehetőségek gyorsparancsa"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Értesítési felület bezárása"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> alkalmazás címsora."</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"A következő csomag a KORLÁTOZOTT csoportba került: <xliff:g id="PACKAGE_NAME">%1$s</xliff:g>"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Újdonság: Ablaknagyító"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Ezután nagyíthatja a képernyőt vagy egy részét"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"A képernyő egy részének felnagyítása"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Mostantól felnagyíthatja a teljes képernyőt vagy a kívánt területet, valamint válthat a két lehetőség között."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Bekapcsolás a Beállításokban"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Elvetés"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"A folytatáshoz a(z) &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; alkalmazásnak hozzáférésre van szüksége az eszköze mikrofonjához."</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Érzékelőkkel kapcsolatos adatvédelem"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Alkalmazás ikonja"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Alkalmazás márkaképe"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Ellenőrizze a hozzáférési beállításokat"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"A(z) <xliff:g id="SERVICE_NAME">%s</xliff:g> megtekintheti és irányíthatja képernyőjét. Koppintson az áttekintéshez."</string>
 </resources>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index 959cb57..594b029 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Մթնշաղի սկիզբը որոշող ծառայություն"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Ժամային գոտու դետեկտոր (աշխատում է առանց ինտերնետի)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"Ժամանակի թարմացման GNSS ծառայություն"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Երաժշտության ճանաչումը կառավարող ծառայություն"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Ձեր սարքը ջնջվելու է"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Հնարավոր չէ օգտագործել ադմինիստրատորի հավելվածը։ Ձեր սարքից բոլոր տվյալները կջնջվեն։\n\nՀարցեր ունենալու դեպքում դիմեք ձեր կազմակերպության ադմինիստրատորին։"</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Տպումն անջատված է <xliff:g id="OWNER_APP">%s</xliff:g> հավելվածի կողմից։"</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Հավելվածն աշխատում է"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Մարտկոցի լիցքը ծախսող հավելվածներ"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Խոշորացում"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Հատուկ գործառույթների անվտանգության քաղաքականություն"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"«<xliff:g id="APP_NAME">%1$s</xliff:g>» հավելվածը ծախսում է մարտկոցի լիցքը"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> հավելված ծախսում է մարտկոցի լիցքը"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Հպեք՝ մարտկոցի և թրաֆիկի մանրամասները տեսնելու համար"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Թույլ է տալիս հավելվածին կարգավիճակի գոտին լինել:"</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"ընդլայնել կամ հետ ծալել կարգավիճակի գոտին"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Թույլ է տալիս ծրագրին ընդլայնել կամ հետ ծալել կարգավիճակի գոտին:"</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"ցուցադրել ծանուցումներ կողպված սարքի էկրանին լիաէկրան ռեժիմում"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Թույլ է տալիս հավելվածին ծանուցումներ ցուցադրել կողպված սարքի էկրանին լիաէկրան ռեժիմում"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"տեղադրել դյուրանցումներ"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Հավելվածին թույլ է տալիս ավելացնել գլխավոր էկրանի դյուրանցումներ՝ առանց օգտագործողի միջամտության:"</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"ապատեղադրել դյուրանցումները"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Օգտագործել կենսաչափական համակարգեր կամ էկրանի կողպում"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Հաստատեք ձեր ինքնությունը"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Շարունակելու համար օգտագործեք կենսաչափական համակարգեր"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Շարունակելու համար օգտագործեք ձեր կենսաչափական տվյալները կամ էկրանի կողպումը"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Կենսաչափական սարքը հասանելի չէ"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Նույնականացումը չեղարկվեց"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Չհաջողվեց ճանաչել"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Օգտագործել մատնահետք"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Օգտագործել մատնահետք կամ էկրանի կողպում"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Շարունակելու համար անհրաժեշտ է ձեր մատնահետքը"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Շարունակելու համար օգտագործեք ձեր մատնահետքը կամ էկրանի կողպումը"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Մատնահետքի պատկերակ"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Օգտագործել դեմքով ապակողպում"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Օգտագործել դեմքով ապակողպում կամ էկրանի կողպում"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Շարունակելու համար օգտագործեք դեմքով ապակողպում"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Շարունակելու համար օգտագործեք ձեր դեմքը կամ էկրանի կողպումը"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Դեմքի պատկերակ"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"Դուք չունեք այս էջը բացելու թույլտվություն:"</string>
     <string name="text_copied" msgid="2531420577879738860">"Տեքստը պատճենված է սեղմատախտակին:"</string>
     <string name="copied" msgid="4675902854553014676">"Պատճենվեց"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> հավելվածը տվյալներ տեղադրեց <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> հավելվածից"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> հավելվածը տվյալներ տեղադրեց սեղմատախտակից"</string>
     <string name="more_item_label" msgid="7419249600215749115">"Ավելին"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Ցանկ+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Անջատել"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"<xliff:g id="NAME">%s</xliff:g> հիշասարքի ստուգում…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Բովանդակության ստուգում"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Արտաքին կրիչի ստուգում"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Նոր հիշասարք (<xliff:g id="NAME">%s</xliff:g>)"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g>ը չի աշխատում"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Հպեք՝ կարգավորելու համար"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Ընտրեք՝ կարգավորելու համար"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Կարող է պահանջվել, որ նորից ֆորմատավորեք սարքը։ Հպեք՝ հեռացնելու համար։"</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"Լուսանկարներ և մեդիա ֆայլեր տեղափոխելու համար"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Մեդիա ֆայլերի դիտում"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"<xliff:g id="NAME">%s</xliff:g> հիշասարքի հետ կապված խնդիր կա"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g>ը չի աշխատում"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Հպեք՝ շտկելու համար"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"Չապահովվող <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g>ը չի աշխատում"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"Այս սարքը չի աջակցում այս <xliff:g id="NAME">%s</xliff:g>-ը: Հպեք՝ աջակցվող ձևաչափով կարգավորելու համար:"</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"Այս սարքը չի աջակցում այս <xliff:g id="NAME">%s</xliff:g>-ը: Ընտրեք՝ աջակցվող ձևաչափով կարգավորելու համար:"</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Ընտրեք՝ կրիչը (<xliff:g id="NAME">%s</xliff:g>) աջակցվող ձևաչափով կարգավորելու համար։"</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Կարող է պահանջվել, որ նորից ֆորմատավորեք սարքը"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g>-ը հեռացվել է առանց անջատելու"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Տվյալներ չկորցնելու համար կրիչը հեռացնելուց առաջ անջատեք այն"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Օգտագործել դյուրանցումը"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Գունաշրջում"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Գունաշտկում"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Պայծառության նվազեցում"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Հավելյալ խամրեցում"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Ձայնի կարգավորման կոճակները սեղմվեցին։ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ծառայությունը միացավ։"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Ձայնի կարգավորման կոճակները սեղմվեցին։ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ծառայությունն անջատվեց։"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"«<xliff:g id="SERVICE_NAME">%1$s</xliff:g>» ծառայությունն օգտագործելու համար սեղմեք և 3 վայրկյան պահեք ձայնի ուժգնության երկու կոճակները"</string>
@@ -1689,7 +1701,7 @@
     <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Մի գործառույթից մյուսին անցնելու համար երեք մատը սահեցրեք վերև և պահեք։"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Խոշորացում"</string>
     <string name="user_switched" msgid="7249833311585228097">"Ներկայիս օգտատերը <xliff:g id="NAME">%1$s</xliff:g>:"</string>
-    <string name="user_switching_message" msgid="1912993630661332336">"Փոխարկվում է <xliff:g id="NAME">%1$s</xliff:g>-ին..."</string>
+    <string name="user_switching_message" msgid="1912993630661332336">"Անցում հետևյալ պրոֆիլին՝ <xliff:g id="NAME">%1$s</xliff:g>..."</string>
     <string name="user_logging_out_message" msgid="7216437629179710359">"Ելք <xliff:g id="NAME">%1$s</xliff:g>-ից…"</string>
     <string name="owner_name" msgid="8713560351570795743">"Սեփականատեր"</string>
     <string name="error_message_title" msgid="4082495589294631966">"Սխալ"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Հատուկ գործառույթների դյուրանցում"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Հատուկ գործառույթների դյուրանցման ընտրիչ"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Հատուկ գործառույթների դյուրանցում"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Փակել ծանուցումների վահանակը"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<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> փաթեթը գցվեց ՍԱՀՄԱՆԱՓԱԿՎԱԾ զամբյուղի մեջ"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>՝"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Նոր գործառույթ. Պատուհանի խոշորացույց"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Այժմ կարող եք խոշորացնել ամբողջ էկրանը կամ դրա մի մասը"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Խոշորացրեք էկրանի մի հատվածը"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Այժմ կարող եք խոշորացնել ամբողջ էկրանը կամ էկրանի որոշակի հատված, ինչպես նաև փոխել ռեժիմները։"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Միացնել կարգավորումներում"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Փակել"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Շարունակելու համար &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; հավելվածին անհրաժեշտ է սարքի խոսափողի օգտագործման թույլտվություն։"</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Տվիչների գաղտնիություն"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Հավելվածի պատկերակ"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Հավելվածի բրենդային պատկեր"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Ստուգեք մուտքի կարգավորումները"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> ծառայությունը կարող է դիտել և կառավարել ձեր էկրանի բովանդակությունը։ Հպեք՝ մանրամասներն իմանալու համար։"</string>
 </resources>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 9f69209..00c8b5b 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Layanan Twilight"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Pendeteksi Zona Waktu (Tidak ada konektivitas)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"Layanan Pembaruan Waktu GNSS"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Layanan Pengelola Pengenalan Musik"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Perangkat akan dihapus"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Aplikasi admin tidak dapat digunakan. Perangkat Anda kini akan dihapus.\n\nJika ada pertanyaan, hubungi admin organisasi."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Fitur pencetakan dinonaktifkan oleh <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Aplikasi berjalan"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Aplikasi yang menggunakan baterai"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Pembesaran"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Kebijakan keamanan aksesibilitas"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> sedang menggunakan baterai"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> aplikasi sedang meggunakan baterai"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Ketuk untuk melihat detail penggunaan baterai dan data"</string>
@@ -326,7 +328,7 @@
     <string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Mengambil konten jendela"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Memeriksa konten jendela tempat Anda berinteraksi."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Mengaktifkan Jelajahi dengan Sentuhan"</string>
-    <string name="capability_desc_canRequestTouchExploration" msgid="4394677060796752976">"Item yang diketuk akan diucapkan dengan jelas dan layar dapat dijelajahi menggunakan isyarat."</string>
+    <string name="capability_desc_canRequestTouchExploration" msgid="4394677060796752976">"Item yang diketuk akan diucapkan dengan jelas dan layar dapat dijelajahi menggunakan gestur."</string>
     <string name="capability_title_canRequestFilterKeyEvents" msgid="2772371671541753254">"Mengamati teks yang Anda ketik"</string>
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="2381315802405773092">"Meliputi data pribadi seperti nomor kartu kredit dan sandi."</string>
     <string name="capability_title_canControlMagnification" msgid="7701572187333415795">"Mengontrol perbesaran layar"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Mengizinkan apl menjadi bilah status."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"luaskan/ciutkan bilah status"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Mengizinkan apl memperluas atau menciutkan bilah status."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"Tampilkan notifikasi sebagai aktivitas layar penuh di perangkat terkunci"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Mengizinkan aplikasi untuk menampilkan notifikasi sebagai aktivitas layar penuh di perangkat terkunci"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"memasang pintasan"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Mengizinkan aplikasi menambahkan pintasan Layar Utama tanpa tindakan dari pengguna."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"meng-uninstal pintasan"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Gunakan biometrik atau kunci layar"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Verifikasi bahwa ini memang Anda"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Gunakan biometrik untuk melanjutkan"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Gunakan biometrik atau kunci layar untuk melanjutkan"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Hardware biometrik tidak tersedia"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Autentikasi dibatalkan"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Tidak dikenali"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Gunakan sidik jari"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Gunakan sidik jari atau kunci layar"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Gunakan sidik jari untuk melanjutkan"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Gunakan sidik jari atau kunci layar untuk melanjutkan"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikon sidik jari"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Gunakan face unlock"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Gunakan face lock atau kunci layar"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Gunakan face unlock untuk melanjutkan"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Gunakan face lock atau kunci layar untuk melanjutkan"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Ikon wajah"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"Anda tidak memiliki izin untuk membuka halaman ini."</string>
     <string name="text_copied" msgid="2531420577879738860">"Teks disalin ke papan klip."</string>
     <string name="copied" msgid="4675902854553014676">"Disalin"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ditempelkan dari <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ditempelkan dari papan klip"</string>
     <string name="more_item_label" msgid="7419249600215749115">"Lainnya"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Menu+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Nonaktifkan"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Memeriksa <xliff:g id="NAME">%s</xliff:g>…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Meninjau konten saat ini"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Menganalisis penyimpanan media"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"<xliff:g id="NAME">%s</xliff:g> baru"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> tidak berfungsi"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Ketuk untuk menyiapkan"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Pilih untuk menyiapkan"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Anda mungkin perlu memformat ulang perangkat. Ketuk untuk mengeluarkan"</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"Untuk mentransfer foto dan media"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Jelajahi file media"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Masalah pada <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> tidak berfungsi"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Ketuk untuk memperbaiki"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"<xliff:g id="NAME">%s</xliff:g> tidak didukung"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> tidak berfungsi"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"Perangkat tidak mendukung <xliff:g id="NAME">%s</xliff:g> ini. Ketuk untuk menyiapkan dalam format yang didukung."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"Perangkat ini tidak mendukung <xliff:g id="NAME">%s</xliff:g> ini. Pilih untuk menyiapkan dalam format yang didukung."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Pilih untuk menyiapkan <xliff:g id="NAME">%s</xliff:g> dalam format yang didukung."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Anda mungkin perlu memformat ulang perangkat"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> tiba-tiba dicabut"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Keluarkan media sebelum mencabut agar konten tidak hilang"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Gunakan Pintasan"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversi Warna"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Koreksi Warna"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Kurangi kecerahan"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Ekstra redup"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tombol volume ditahan. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> diaktifkan."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tombol volume ditahan. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> dinonaktifkan."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Tekan dan tahan kedua tombol volume selama tiga detik untuk menggunakan <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Pintasan Aksesibilitas di layar"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Pemilih Pintasan Aksesibilitas di layar"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Pintasan Aksesibilitas"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Tutup Menu Notifikasi"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Kolom teks <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> telah dimasukkan ke dalam bucket DIBATASI"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Baru: Pembesar Jendela"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Anda bisa memperbesar sebagian atau seluruh layar"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Memperbesar tampilan sebagian layar"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Anda kini dapat memperbesar layar penuh, area tertentu, atau beralih antara kedua opsi tersebut."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Aktifkan di Setelan"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Tutup"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Untuk melanjutkan, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; memerlukan akses ke mikrofon perangkat."</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privasi Sensor"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Ikon aplikasi"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Brand image aplikasi"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Periksa setelan akses"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> dapat melihat dan mengontrol layar Anda. Ketuk untuk meninjau."</string>
 </resources>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index 0e11f03..1c5809f 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Ljósaskiptaþjónusta"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Tímabeltisgreinir (engin tenging)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"Tímastillingarþjónusta hnattræna gervihnattaleiðsögukerfisins (GNSS)"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Umsjónarþjónusta tónlistargreiningar"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Tækið verður hreinsað"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Ekki er hægt að nota stjórnunarforritið. Tækinu verður eytt.\n\nEf spurningar vakna skaltu hafa samband við kerfisstjóra fyrirtækisins."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> lokaði á prentun."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Forrit er í gangi"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Forrit sem nota rafhlöðuorku"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Stækkun"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Öryggisregla aðgengis"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> notar rafhlöðuorku"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> forrit nota rafhlöðuorku"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Ýttu til að fá upplýsingar um rafhlöðu- og gagnanotkun"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Leyfir forriti að vera stöðustikan."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"stækka/minnka stöðustiku"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Leyfir forriti að stækka og minnka stöðustikuna."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"birta tilkynningar sem aðgerðir á öllum skjánum á læstu tæki"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Gerir forritinu kleift að birta tilkynningar sem aðgerðir á öllum skjánum á læstu tæki"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"setja upp flýtileiðir"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Leyfir forriti að bæta flýtileiðum á heimaskjá án inngrips notanda."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"fjarlægja flýtileiðir"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Nota lífkenni eða skjálás"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Staðfestu hver þú ert"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Notaðu lífkenni til að halda áfram"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Notaðu lífkenni eða skjálás til að halda áfram"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Lífkennavélbúnaður ekki tiltækur"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Hætt við auðkenningu"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Þekktist ekki"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Nota fingrafar"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Nota fingrafar eða skjálás"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Notaðu fingrafarið þitt til að halda áfram"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Notaðu fingrafar eða skjálás til að halda áfram"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Fingrafaratákn"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Nota andlitsopnun"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Nota andlit eða skjálás"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Notaðu andlitsopnun til að halda áfram"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Notaðu andlitið eða skjálás til að halda áfram"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Andlitstákn"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"Þú hefur ekki heimild til að opna þessa síðu."</string>
     <string name="text_copied" msgid="2531420577879738860">"Texti afritaður á klippiborð."</string>
     <string name="copied" msgid="4675902854553014676">"Afritað"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> límt úr <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> límt af klippiborði."</string>
     <string name="more_item_label" msgid="7419249600215749115">"Meira"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Valmynd+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Slökkva"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Athugar <xliff:g id="NAME">%s</xliff:g>…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Fer yfir núverandi efni"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Greinir efnisgeymslu"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Nýtt <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> virkar ekki"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Ýttu til að setja upp"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Veldu til að setja upp"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Þú gætir þurft að endursníða tækið. Ýttu til að fjarlægja."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"Til að flytja myndir og aðrar skrár"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Skoða efnisskrár"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Vandamál með <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> virkar ekki"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Ýttu til að lagfæra"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"Óstutt <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> virkar ekki"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"Þetta tæki styður ekki <xliff:g id="NAME">%s</xliff:g>. Ýttu til að setja upp með studdu sniði."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"Þetta tæki styður ekki <xliff:g id="NAME">%s</xliff:g>. Veldu til að setja upp með studdu sniði."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Veldu til að setja <xliff:g id="NAME">%s</xliff:g> upp á studdu sniði."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Þú gætir þurft að endursníða tækið"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> fjarlægt án fyrirvara"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Aftengdu geymslumiðil áður en þú tekur hann úr sambandi til að koma í veg fyrir að þú glatir efni"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Nota flýtileið"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Umsnúningur lita"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Litaleiðrétting"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Minnka birtu"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Mjög dökkt"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Hljóðstyrkstökkum haldið inni. Kveikt á <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Hljóðstyrkstökkum haldið inni. Slökkt á <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Haltu báðum hljóðstyrkstökkunum inni í þrjár sekúndur til að nota <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Flýtileið í aðgengiseiginleika á skjánum"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Val um flýtileið í aðgengiseiginleika á skjánum"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Flýtileið aðgengisstillingar"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Loka tilkynningaglugga"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Skjátextastika <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> var sett í flokkinn TAKMARKAÐ"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Nýtt: Gluggastækkun"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Nú geturðu stækkað allan skjáinn eða hluta hans"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Stækka hluta af skjánum"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Nú geturðu stækkað allan skjáinn, tiltekið svæði eða skipt á milli þessara valkosta."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Kveikja á í stillingum"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Hunsa"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Til að halda áfram þarf &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; aðgang að hljóðnema tækisins."</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Persónuvernd skynjara"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Forritstákn"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Mynd af merki forrits"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Skoða aðgangsstillingar"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> getur skoðað og stjórnað skjánum hjá þér. Ýttu til að skoða."</string>
 </resources>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index b41996e..4e342b6 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Servizio Twilight"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Rilevatore di fuso orario (connessione a Internet non necessaria)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"Servizio di aggiornamento dell\'orario GNSS"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Servizio di gestione del riconoscimento della musica"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Il dispositivo verrà resettato"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Impossibile usare l\'app di amministrazione. Il dispositivo verrà resettato.\n\nPer eventuali domande, contatta l\'amministratore della tua organizzazione."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Stampa disattivata da <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"App in esecuzione"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"App che consumano la batteria"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Ingrandimento"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Criteri di sicurezza dell\'accessibilità"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"L\'app <xliff:g id="APP_NAME">%1$s</xliff:g> sta consumando la batteria"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> app stanno consumando la batteria"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Tocca per conoscere i dettagli sull\'utilizzo dei dati e della batteria"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Consente di visualizzare l\'applicazione nella barra di stato."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"espansione/compressione barra di stato"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Consente all\'applicazione di espandere o comprimere la barra di stato."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"Visualizzazione di notifiche sotto forma di attività in modalità a schermo intero su un dispositivo bloccato"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Consente all\'app di visualizzare le notifiche sotto forma di attività in modalità a schermo intero su un dispositivo bloccato"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"aggiunta di scorciatoie"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Consente a un\'applicazione di aggiungere scorciatoie alla schermata Home automaticamente."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"eliminazione di scorciatoie"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Usa la biometria o il blocco schermo"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Verifica la tua identità"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Usa la biometria per continuare"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Per continuare devi usare i tuoi dati biometrici o il tuo blocco schermo"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Hardware biometrico non disponibile"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Autenticazione annullata"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Non riconosciuto"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Usa l\'impronta"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Usa l\'impronta o il blocco schermo"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Utilizza la tua impronta per continuare"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Per continuare devi usare la tua impronta o il tuo blocco schermo"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Icona dell\'impronta"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Usa Sblocco con il volto"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Usa Sblocco con il volto o il blocco schermo"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Usa Sblocco con il volto per continuare"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Per continuare devi usare il tuo volto o il tuo blocco schermo"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Icona volto"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"Non sei autorizzato ad aprire questa pagina."</string>
     <string name="text_copied" msgid="2531420577879738860">"Testo copiato negli appunti."</string>
     <string name="copied" msgid="4675902854553014676">"Copia eseguita"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"Dati dell\'app <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> incollati dall\'app <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"Dati dell\'app <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> incollati dagli appunti"</string>
     <string name="more_item_label" msgid="7419249600215749115">"Altro"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Menu+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"META +"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Disattiva"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Controllo del dispositivo <xliff:g id="NAME">%s</xliff:g>…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Controllo dei contenuti correnti"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Analisi dello spazio di archiviazione multimediale in corso…"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Nuovo dispositivo <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> non funziona"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Tocca per configurare"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Seleziona per configurare"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Potresti dover riformattare il dispositivo. Tocca per espellere."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"Per trasferire foto e altri file"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Sfoglia i file multimediali"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Problema con <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> non funziona"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Tocca per risolvere il problema"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"<xliff:g id="NAME">%s</xliff:g> non supportata"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> non funziona"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"Il dispositivo non supporta il seguente elemento: <xliff:g id="NAME">%s</xliff:g>. Tocca per configurare un formato supportato."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"Il dispositivo non supporta questo tipo di <xliff:g id="NAME">%s</xliff:g>. Seleziona per eseguire la configurazione in un formato supportato."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Seleziona per configurare <xliff:g id="NAME">%s</xliff:g> in un formato supportato."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Potresti dover riformattare il dispositivo"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"Rimozione imprevista della <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Espelli il supporto prima di rimuoverlo per evitare di perdere contenuti"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Usa scorciatoia"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversione dei colori"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Correzione del colore"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Riduci la luminosità"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Attenuazione extra"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tieni premuti i tasti del volume. Servizio <xliff:g id="SERVICE_NAME">%1$s</xliff:g> attivato."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tieni premuti i tasti del volume. Servizio <xliff:g id="SERVICE_NAME">%1$s</xliff:g> disattivato."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Tieni premuti entrambi i tasti del volume per tre secondi per utilizzare <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Scorciatoia Accessibilità sullo schermo"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Selettore scorciatoia Accessibilità sullo schermo"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Scorciatoia Accessibilità"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Ignora area notifiche"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Barra del titolo di <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> è stato inserito nel bucket RESTRICTED"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Novità: Ingrandimento finestra"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Puoi ingrandire lo schermo in parte o per intero"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Ingrandisci parte dello schermo"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Ora puoi ingrandire l\'intero schermo, un\'area specifica o passare da un\'opzione all\'altra."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Attiva nelle Impostazioni"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Ignora"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Per continuare, l\'app &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; deve accedere al microfono del dispositivo."</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privacy relativa ai sensori"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Icona dell\'applicazione"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Immagine del branding dell\'applicazione"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Controlla le impostazioni di accesso"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> può visualizzare e controllare il tuo schermo. Tocca per esaminare."</string>
 </resources>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index be05cc0..f2f6138 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -34,7 +34,7 @@
     <string name="defaultMsisdnAlphaTag" msgid="2285034592902077488">"MSISDN1"</string>
     <string name="mmiError" msgid="2862759606579822246">"‏בעיה בחיבור או קוד MMI לא חוקי."</string>
     <string name="mmiFdnError" msgid="3975490266767565852">"הפעולה מוגבלת למספרי חיוג קבועים בלבד."</string>
-    <string name="mmiErrorWhileRoaming" msgid="1204173664713870114">"לא ניתן לשנות את הגדרות העברת השיחות מהטלפון שלך כשאתה במצב נדידה."</string>
+    <string name="mmiErrorWhileRoaming" msgid="1204173664713870114">"לא ניתן לשנות את הגדרות העברת השיחות מהטלפון במצב נדידה."</string>
     <string name="serviceEnabled" msgid="7549025003394765639">"השירות הופעל."</string>
     <string name="serviceEnabledFor" msgid="1463104778656711613">"השירות הופעל עבור:"</string>
     <string name="serviceDisabled" msgid="641878791205871379">"השירות הושבת."</string>
@@ -45,7 +45,7 @@
     <string name="badPin" msgid="888372071306274355">"קוד הגישה הישן שהקלדת שגוי."</string>
     <string name="badPuk" msgid="4232069163733147376">"‏ה-PUK שהקלדת שגוי."</string>
     <string name="mismatchPin" msgid="2929611853228707473">"קודי הגישה שהקלדת לא תואמים."</string>
-    <string name="invalidPin" msgid="7542498253319440408">"הקלד קוד גישה שאורכו 4 עד 8 ספרות."</string>
+    <string name="invalidPin" msgid="7542498253319440408">"יש להקליד קוד אימות שאורכו 4 עד 8 ספרות."</string>
     <string name="invalidPuk" msgid="8831151490931907083">"‏הקלד PUK באורך 8 מספרים או יותר."</string>
     <string name="needPuk" msgid="7321876090152422918">"‏כרטיס ה-SIM נעול באמצעות PUK. הקלד את קוד PUK כדי לבטל את נעילתו."</string>
     <string name="needPuk2" msgid="7032612093451537186">"‏הקלד PUK2 כדי לבטל את חסימת כרטיס ה-SIM."</string>
@@ -86,7 +86,7 @@
     <string name="RestrictedStateContent" msgid="7693575344608618926">"הושבת באופן זמני על ידי הספק"</string>
     <string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"‏הושבת באופן זמני על ידי הספק עבור SIM <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"לא ניתן להתחבר לרשת הסלולרית"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"יש לנסות לשנות את הרשת המועדפת. ניתן להקיש כדי לשנות."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"אפשר לנסות לשנות את הרשת המועדפת. יש להקיש כדי לשנות אותה."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"שיחות חירום לא זמינות"</string>
     <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"‏לא ניתן לבצע שיחות חירום דרך Wi-Fi"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"התראות"</string>
@@ -124,7 +124,7 @@
     <string name="roamingText11" msgid="5245687407203281407">"מודעת באנר נודדת מופעלת"</string>
     <string name="roamingText12" msgid="673537506362152640">"מודעת באנר נודדת כבויה"</string>
     <string name="roamingTextSearching" msgid="5323235489657753486">"מחפש שירות"</string>
-    <string name="wfcRegErrorTitle" msgid="3193072971584858020">"‏לא ניתן היה להגדיר שיחות Wi-Fi"</string>
+    <string name="wfcRegErrorTitle" msgid="3193072971584858020">"‏לא ניתן היה להגדיר את התכונה \'שיחות Wi-Fi\'"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
     <item msgid="468830943567116703">"‏כדי להתקשר ולשלוח הודעות ברשת Wi-Fi, תחילה יש לבקש מהספק להגדיר את השירות. לאחר מכן, יש להפעיל שוב שיחות Wi-Fi ב\'הגדרות\'. (קוד שגיאה: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
@@ -180,7 +180,7 @@
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="4562226280528716090">"נעשה ניסיון למחוק יותר מדי <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string>
     <string name="low_memory" product="tablet" msgid="5557552311566179924">"שטח האחסון של הטאבלט מלא. מחק קבצים כדי לפנות מקום."</string>
     <string name="low_memory" product="watch" msgid="3479447988234030194">"שטח האחסון של השעון מלא. מחק כמה קבצים כדי לפנות שטח."</string>
-    <string name="low_memory" product="tv" msgid="6663680413790323318">"‏האחסון של מכשיר ה-Android TV מלא. יש למחוק חלק מהקבצים כדי לפנות שטח."</string>
+    <string name="low_memory" product="tv" msgid="6663680413790323318">"‏האחסון של מכשיר ה-Android TV מלא. יש למחוק חלק מהקבצים כדי לפנות מקום."</string>
     <string name="low_memory" product="default" msgid="2539532364144025569">"שטח האחסון של הטלפון מלא. מחק חלק מהקבצים כדי לפנות שטח."</string>
     <plurals name="ssl_ca_cert_warning" formatted="false" msgid="2288194355006173029">
       <item quantity="two">רשויות אישורים הותקנו</item>
@@ -188,7 +188,7 @@
       <item quantity="other">רשויות אישורים הותקנו</item>
       <item quantity="one">רשות אישורים הותקנה</item>
     </plurals>
-    <string name="ssl_ca_cert_noti_by_unknown" msgid="4961102218216815242">"על ידי צד שלישי לא מוכר"</string>
+    <string name="ssl_ca_cert_noti_by_unknown" msgid="4961102218216815242">"על ידי צד שלישי לא ידוע"</string>
     <string name="ssl_ca_cert_noti_by_administrator" msgid="4564941950768783879">"על ידי המנהל של פרופיל העבודה שלך"</string>
     <string name="ssl_ca_cert_noti_managed" msgid="217337232273211674">"על ידי <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
     <string name="work_profile_deleted" msgid="5891181538182009328">"פרופיל העבודה נמחק"</string>
@@ -208,6 +208,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"שירות דמדומים"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"מזהה אזור זמן (ללא צורך בקישוריות)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"‏שירות עדכון הזמן של GNSS"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"השירות של מנהל זיהוי המוזיקה"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"תתבצע מחיקה של המכשיר"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"לא ניתן להשתמש באפליקציה של מנהל המערכת.\n\nאם יש לך שאלות, יש ליצור קשר עם מנהל המערכת של הארגון."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"ההדפסה הושבתה על ידי <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -255,7 +256,7 @@
     <string name="global_action_logout" msgid="6093581310002476511">"סיום הפעלה"</string>
     <string name="global_action_screenshot" msgid="2610053466156478564">"צילום מסך"</string>
     <string name="bugreport_title" msgid="8549990811777373050">"דיווח על באג"</string>
-    <string name="bugreport_message" msgid="5212529146119624326">"פעולה זו תאסוף מידע על מצב המכשיר הנוכחי שלך על מנת לשלוח אותו כהודעת אימייל. היא תימשך זמן קצר מרגע פתיחת דיווח הבאג ועד לשליחת ההודעה בפועל. אנא המתן בסבלנות."</string>
+    <string name="bugreport_message" msgid="5212529146119624326">"הפעולה הזו תאסוף מידע על מצב המכשיר הנוכחי שלך כדי לשלוח אותו כהודעת אימייל. היא תימשך זמן קצר מרגע פתיחת הדיווח על הבאג ועד לשליחת ההודעה בפועל. יש להמתין בסבלנות."</string>
     <string name="bugreport_option_interactive_title" msgid="7968287837902871289">"דוח אינטראקטיבי"</string>
     <string name="bugreport_option_interactive_summary" msgid="8493795476325339542">"השתמש באפשרות זו ברוב המקרים. היא מאפשרת לך לעקוב אחר התקדמות הדוח, להזין פרטים נוספים על הבעיה וליצור צילומי מסך. היא עשויה להשמיט כמה קטעים שנמצאים פחות בשימוש ואשר יצירת הדיווח עליהם נמשכת זמן רב."</string>
     <string name="bugreport_option_full_title" msgid="7681035745950045690">"דוח מלא"</string>
@@ -299,6 +300,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"אפליקציה פועלת"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"אפליקציות שמרוקנות את הסוללה"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"הגדלה"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"מדיניות בנושא אבטחת נגישות"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> משתמשת בסוללה"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> אפליקציות משתמשות בסוללה"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"הקש לקבלת פרטים על צריכה של נתונים וסוללה"</string>
@@ -341,7 +343,7 @@
     <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_title_canTakeScreenshot" msgid="3895812893130071930">"שמירת צילום המסך"</string>
+    <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"צילום המסך"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"ניתן לצלם צילום מסך של התצוגה."</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"השבת או שנה את שורת המצב"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"מאפשר לאפליקציה להשבית את שורת המצב או להוסיף ולהסיר סמלי מערכת."</string>
@@ -349,6 +351,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"מאפשר לאפליקציה להופיע בשורת המצב."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"הרחב/כווץ את שורת המצב"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"מאפשר לאפליקציה להרחיב או לכווץ את שורת המצב."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"הצגת התראות כפעילויות במסך מלא במכשיר נעול"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"מאפשרת לאפליקציה להציג התראות כפעילויות במסך מלא במכשיר נעול"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"התקן קיצורי דרך"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"מאפשר לאפליקציה להוסיף קיצורי דרך במסך דף הבית ללא התערבות המשתמש."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"להסרת התקנה של קיצורי דרך"</string>
@@ -360,25 +364,25 @@
     <string name="permlab_receiveSms" msgid="505961632050451881">"‏קבלת הודעות טקסט (SMS)"</string>
     <string name="permdesc_receiveSms" msgid="1797345626687832285">"‏מאפשר לאפליקציה לקבל ולעבד הודעות SMS. משמעות הדבר היא שהאפליקציה יכולה לעקוב אחר הודעות שנשלחו למכשיר או למחוק אותן מבלי להציג לך אותן."</string>
     <string name="permlab_receiveMms" msgid="4000650116674380275">"‏קבלת הודעות טקסט (MMS)"</string>
-    <string name="permdesc_receiveMms" msgid="958102423732219710">"‏מאפשר לאפליקציה לקבל ולעבד הודעות MMS. משמעות הדבר היא שהאפליקציה יכולה לעקוב אחר הודעות שנשלחו למכשיר או למחוק אותן מבלי להציג לך אותן."</string>
+    <string name="permdesc_receiveMms" msgid="958102423732219710">"‏מאפשרת לאפליקציה לקבל ולעבד הודעות MMS. משמעות הדבר היא שהאפליקציה יכולה לעקוב אחר הודעות שנשלחו למכשיר או למחוק אותן מבלי להציג לך אותן."</string>
     <string name="permlab_bindCellBroadcastService" msgid="586746677002040651">"העברת הודעות של שידור סלולרי"</string>
     <string name="permdesc_bindCellBroadcastService" msgid="6540910200973641606">"מאפשרת לאפליקציה להתחייב למודול של השידור הסלולרי כדי להעביר הודעות של שידור סלולרי כשהן מתקבלות. התראות שידור סלולרי נשלחות במקומות מסוימים כדי להזהיר אותך מפני מצבי חירום. אפליקציות זדוניות עשויות להפריע לביצועים או לפעולה של המכשיר כאשר מתקבל שידור חירום סלולרי."</string>
     <string name="permlab_manageOngoingCalls" msgid="281244770664231782">"ניהול שיחות שנערכות"</string>
     <string name="permdesc_manageOngoingCalls" msgid="7003138133829915265">"לאפליקציה תהיה אפשרות לראות פרטים על שיחות שנערכות במכשיר ולשלוט בשיחות האלה."</string>
     <string name="permlab_readCellBroadcasts" msgid="5869884450872137693">"קריאת הודעות שידור סלולרי"</string>
     <string name="permdesc_readCellBroadcasts" msgid="672513437331980168">"מאפשר לאפליקציה לקרוא הודעות שידור סלולרי שהתקבלו במכשיר שלך. התראות שידור סלולרי נשלחות במקומות מסוימים על מנת להזהיר אותך מפני מצבי חירום. אפליקציות זדוניות עשויות להפריע לביצועים או לפעולה של המכשיר שלך כאשר מתקבל שידור חירום סלולרי."</string>
-    <string name="permlab_subscribedFeedsRead" msgid="217624769238425461">"קרא עדכוני מנויים"</string>
+    <string name="permlab_subscribedFeedsRead" msgid="217624769238425461">"קריאת עדכוני מינויים"</string>
     <string name="permdesc_subscribedFeedsRead" msgid="6911349196661811865">"מאפשר לאפליקציה לקבל פרטים על ההזנות הנוכחיות שמסונכרנות."</string>
     <string name="permlab_sendSms" msgid="7757368721742014252">"‏שליחה והצגה של הודעות SMS"</string>
     <string name="permdesc_sendSms" msgid="6757089798435130769">"‏מאפשר לאפליקציה לשלוח הודעות SMS. הדבר עשוי לגרום לחיובים בלתי צפויים. אפליקציות זדוניות עלולות לגרום לעלויות על ידי שליחת הודעות ללא אישורך."</string>
     <string name="permlab_readSms" msgid="5164176626258800297">"‏קריאת הודעות הטקסט שלך (SMS או MMS)"</string>
     <string name="permdesc_readSms" product="tablet" msgid="7912990447198112829">"‏אפליקציה זו יכולה לקרוא את כל הודעות הטקסט (SMS) המאוחסנות בטאבלט."</string>
-    <string name="permdesc_readSms" product="tv" msgid="3054753345758011986">"‏אפליקציה זו יכולה לקרוא את כל הודעות הטקסט (SMS) המאוחסנות במכשיר ה-Android TV."</string>
+    <string name="permdesc_readSms" product="tv" msgid="3054753345758011986">"‏האפליקציה הזו יכולה לקרוא את כל הודעות הטקסט (SMS) המאוחסנות במכשיר ה-Android TV."</string>
     <string name="permdesc_readSms" product="default" msgid="774753371111699782">"‏אפליקציה זו יכולה לקרוא את כל הודעות הטקסט (SMS) המאוחסנות בטלפון."</string>
     <string name="permlab_receiveWapPush" msgid="4223747702856929056">"‏קבלת הודעות טקסט (WAP)"</string>
     <string name="permdesc_receiveWapPush" msgid="1638677888301778457">"‏מאפשר לאפליקציה לקבל ולעבד הודעות WAP. אישור זה כולל את היכולת לעקוב אחר הודעות שנשלחו אליך ולמחוק אותן מבלי להציג לך אותן."</string>
     <string name="permlab_getTasks" msgid="7460048811831750262">"אחזור אפליקציות פעילות"</string>
-    <string name="permdesc_getTasks" msgid="7388138607018233726">"מאפשר לאפליקציה לאחזר מידע לגבי משימות הפועלות כרגע ושפעלו לאחרונה. ייתכן שהדבר יתיר לאפליקציה לגלות מידע לגבי האפליקציות שבהן נעשה שימוש במכשיר."</string>
+    <string name="permdesc_getTasks" msgid="7388138607018233726">"מאפשרת לאפליקציה לאחזר מידע לגבי משימות הפועלות כרגע וכאלו שפעלו לאחרונה. ייתכן שההרשאה הזו תתיר לאפליקציה לגלות מידע לגבי האפליקציות שבהן נעשה שימוש במכשיר."</string>
     <string name="permlab_manageProfileAndDeviceOwners" msgid="639849495253987493">"ניהול בעלים של פרופיל ומכשיר"</string>
     <string name="permdesc_manageProfileAndDeviceOwners" msgid="7304240671781989283">"מאפשרת לאפליקציות להגדיר את הבעלים של הפרופיל ואת בעל המכשיר."</string>
     <string name="permlab_reorderTasks" msgid="7598562301992923804">"סידור מחדש של אפליקציות פעילות"</string>
@@ -398,7 +402,7 @@
     <string name="permdesc_persistentActivity" product="tv" msgid="6800526387664131321">"‏מאפשרת לאפליקציה לאחסן חלקים שלה בזיכרון באופן קבוע. פעולה זו עשויה להגביל את הזיכרון הזמין לאפליקציות אחרות ולהאט את הפעולה של מכשיר ה-Android TV."</string>
     <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"מאפשר לאפליקציה להפוך חלקים ממנו לקבועים בזיכרון. פעולה זו עשויה להגביל את הזיכרון הזמין לאפליקציות אחרים ולהאט את פעולת הטלפון."</string>
     <string name="permlab_foregroundService" msgid="1768855976818467491">"הרצת שירות קדמה"</string>
-    <string name="permdesc_foregroundService" msgid="8720071450020922795">"הרשאה זו מאפשרת לאפליקציה לעשות שימוש בשירותים בקדמה."</string>
+    <string name="permdesc_foregroundService" msgid="8720071450020922795">"ההרשאה הזו מאפשרת לאפליקציה להשתמש בשירותים שפועלים בחזית."</string>
     <string name="permlab_getPackageSize" msgid="375391550792886641">"מדידת נפח האחסון של אפליקציות"</string>
     <string name="permdesc_getPackageSize" msgid="742743530909966782">"מאפשר לאפליקציה לאחזר את הקוד, הנתונים, וגודלי קובצי המטמון שלו"</string>
     <string name="permlab_writeSettings" msgid="8057285063719277394">"שינוי הגדרות מערכת"</string>
@@ -417,7 +421,7 @@
     <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"מאפשרת לאפליקציה לקרוא נתונים על אנשי הקשר השמורים בטלפון שלך. לאפליקציות תהיה גם גישה לחשבונות בטלפון שיצרו אנשי קשר. פעולה זו עשויה לכלול חשבונות שנוצרו על ידי אפליקציות שהתקנת. הרשאה זו מאפשרת לאפליקציות לשמור נתונים של אנשי הקשר שלך, ואפליקציות זדוניות עלולות לשתף נתונים של אנשי קשר ללא ידיעתך."</string>
     <string name="permlab_writeContacts" msgid="8919430536404830430">"שינוי אנשי הקשר שלך"</string>
     <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"מאפשרת לאפליקציה לשנות את הנתונים לגבי אנשי הקשר המאוחסנים בטאבלט שלך. הרשאה זו מאפשרת לאפליקציות למחוק נתונים של אנשי קשר."</string>
-    <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"‏מאפשרת לאפליקציה לשנות את הנתונים לגבי אנשי הקשר המאוחסנים במכשיר ה-Android TV שלך. הרשאה זו מאפשרת לאפליקציות למחוק נתונים של אנשי קשר."</string>
+    <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"‏מאפשרת לאפליקציה לשנות את הנתונים לגבי אנשי הקשר המאוחסנים במכשיר ה-Android TV שלך. ההרשאה הזו מאפשרת לאפליקציות למחוק נתונים של אנשי קשר."</string>
     <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"מאפשרת לאפליקציה לשנות את הנתונים לגבי אנשי הקשר המאוחסנים בטלפון שלך. הרשאה זו מאפשרת לאפליקציות למחוק נתונים של אנשי קשר."</string>
     <string name="permlab_readCallLog" msgid="1739990210293505948">"קריאת יומן שיחות"</string>
     <string name="permdesc_readCallLog" msgid="8964770895425873433">"אפליקציה זו יכולה לקרוא את היסטוריית השיחות שלך."</string>
@@ -427,10 +431,10 @@
     <string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"מאפשר לאפליקציה לשנות את יומן השיחות של הטלפון, כולל נתונים על שיחות נכנסות ויוצאות. אפליקציות זדוניות עלולות לעשות בכך שימוש כדי למחוק או לשנות את יומן השיחות שלך."</string>
     <string name="permlab_bodySensors" msgid="3411035315357380862">"גישה אל חיישני גוף (כמו מוניטורים לקצב לב)"</string>
     <string name="permdesc_bodySensors" product="default" msgid="2365357960407973997">"מאפשר לאפליקציה לגשת אל נתוני חיישנים העוקבים אחר מצבך הגופני, כמו קצב הלב."</string>
-    <string name="permlab_readCalendar" msgid="6408654259475396200">"קריאה של אירועי יומן ופרטיהם"</string>
-    <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"אפליקציה זו יכולה לקרוא את כל אירועי היומן המאוחסנים בטאבלט, ולשתף או לשמור את נתוני היומן."</string>
+    <string name="permlab_readCalendar" msgid="6408654259475396200">"קריאה של אירועי יומן והפרטים שלהם"</string>
+    <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"האפליקציה הזו יכולה לקרוא את כל אירועי היומן המאוחסנים בטאבלט, ולשתף או לשמור את נתוני היומן."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"‏אפליקציה זו יכולה לקרוא את כל אירועי היומן המאוחסנים במכשיר ה-Android TV, ולשתף או לשמור את נתוני היומן."</string>
-    <string name="permdesc_readCalendar" product="default" msgid="9118823807655829957">"אפליקציה זו יכולה לקרוא את כל אירועי היומן המאוחסנים בטלפון, ולשתף או לשמור את נתוני היומן."</string>
+    <string name="permdesc_readCalendar" product="default" msgid="9118823807655829957">"האפליקציה הזו יכולה לקרוא את כל אירועי היומן המאוחסנים בטלפון, ולשתף או לשמור את נתוני היומן."</string>
     <string name="permlab_writeCalendar" msgid="6422137308329578076">"הוספה ושינוי של אירועי יומן ושליחת אימייל לאורחים ללא ידיעת הבעלים"</string>
     <string name="permdesc_writeCalendar" product="tablet" msgid="8722230940717092850">"אפליקציה זו יכולה להוסיף, להסיר ולשנות אירועי יומן בטאבלט. האפליקציה יכולה לשנות אירועים בלי להודיע לבעליהם ולשלוח הודעות שעשויות להיראות כאילו נשלחו מבעלי יומנים."</string>
     <string name="permdesc_writeCalendar" product="tv" msgid="951246749004952706">"‏אפליקציה זו יכולה להוסיף, להסיר ולשנות אירועי יומן במכשיר ה-Android TV. האפליקציה יכולה לשלוח הודעות שעשויות להיראות כאילו נשלחו מבעלי יומנים ולשנות אירועים בלי להודיע על כך לבעליהם."</string>
@@ -450,7 +454,7 @@
     <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"הקלטת אודיו ברקע"</string>
     <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="permdesc_sim_communication" msgid="4179799296415957960">"‏מאפשרת לאפליקציה לשלוח פקודות ל-SIM. זוהי הרשאה מסוכנת מאוד."</string>
     <string name="permlab_activityRecognition" msgid="1782303296053990884">"זיהוי הפעילות הגופנית"</string>
     <string name="permdesc_activityRecognition" msgid="8667484762991357519">"האפליקציה מזהה את הפעילות הגופנית שלך."</string>
     <string name="permlab_camera" msgid="6320282492904119413">"צלם תמונות וסרטונים"</string>
@@ -469,7 +473,7 @@
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"‏גישה אל שירות שיחות IMS"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"‏מאפשר לאפליקציה להשתמש בשירות ה-IMS לביצוע שיחות ללא התערבותך."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"קריאת הסטטוס והזהות של הטלפון"</string>
-    <string name="permdesc_readPhoneState" msgid="7229063553502788058">"מאפשר לאפליקציה לגשת לתכונות הטלפון של המכשיר. אישור זה מתיר לאפליקציה לגלות את מספר הטלפון ואת זיהויי המכשיר, האם שיחה פעילה ואת המספר המרוחק המחובר באמצעות שיחה."</string>
+    <string name="permdesc_readPhoneState" msgid="7229063553502788058">"מאפשרת לאפליקציה לגשת לתכונות הטלפון של המכשיר. ההרשאה הזו מתירה לאפליקציה לגלות את מספר הטלפון ואת מזהי המכשיר, אם השיחה פעילה ואת המספר המרוחק המחובר באמצעות שיחה."</string>
     <string name="permlab_manageOwnCalls" msgid="9033349060307561370">"ניתוב שיחות דרך המערכת"</string>
     <string name="permdesc_manageOwnCalls" msgid="4431178362202142574">"מאפשרת לאפליקציה לנתב את השיחות דרך המערכת כדי לשפר את חוויית השיחה."</string>
     <string name="permlab_callCompanionApp" msgid="3654373653014126884">"ניתן להציג שיחות ולשלוט בהן באמצעות המערכת."</string>
@@ -481,7 +485,7 @@
     <string name="permlab_readPhoneNumbers" msgid="5668704794723365628">"גישה למספרי הטלפון"</string>
     <string name="permdesc_readPhoneNumbers" msgid="7368652482818338871">"מתירה לאפליקציה גישה למספרי הטלפון במכשיר."</string>
     <string name="permlab_wakeLock" product="automotive" msgid="1904736682319375676">"מסך המכונית יישאר דלוק"</string>
-    <string name="permlab_wakeLock" product="tablet" msgid="1527660973931694000">"מנע מהטאבלט לעבור למצב שינה"</string>
+    <string name="permlab_wakeLock" product="tablet" msgid="1527660973931694000">"מניעה מהטאבלט לעבור למצב שינה"</string>
     <string name="permlab_wakeLock" product="tv" msgid="2856941418123343518">"‏מונעת ממכשיר ה-Android TV להיכנס למצב שינה"</string>
     <string name="permlab_wakeLock" product="default" msgid="569409726861695115">"מניעת מעבר הטלפון למצב שינה"</string>
     <string name="permdesc_wakeLock" product="automotive" msgid="5995045369683254571">"מסך המכונית יישאר דלוק כשהאפליקציה פועלת."</string>
@@ -496,7 +500,7 @@
     <string name="permdesc_setWallpaper" msgid="2973996714129021397">"מאפשר לאפליקציה להגדיר את טפט המערכת."</string>
     <string name="permlab_setWallpaperHints" msgid="1153485176642032714">"התאמת גודל הטפט שלך"</string>
     <string name="permdesc_setWallpaperHints" msgid="6257053376990044668">"מאפשר לאפליקציה להגדיר את סמני הגודל של טפט המערכת."</string>
-    <string name="permlab_setTimeZone" msgid="7922618798611542432">"הגדר אזור זמן"</string>
+    <string name="permlab_setTimeZone" msgid="7922618798611542432">"הגדרת אזור זמן"</string>
     <string name="permdesc_setTimeZone" product="tablet" msgid="1788868809638682503">"מאפשר לאפליקציה לשנות את אזור הזמן של הטאבלט."</string>
     <string name="permdesc_setTimeZone" product="tv" msgid="9069045914174455938">"‏מאפשרת לאפליקציה לשנות את אזור הזמן של מכשיר ה-Android TV."</string>
     <string name="permdesc_setTimeZone" product="default" msgid="4611828585759488256">"מאפשר לאפליקציה לשנות את אזור הזמן של הטלפון."</string>
@@ -504,8 +508,8 @@
     <string name="permdesc_getAccounts" product="tablet" msgid="1784452755887604512">"מאפשר לאפליקציה לקבל רשימה של חשבונות המוכרים לטאבלט. הדבר עשוי לכלול חשבונות שנוצרו על ידי אפליקציות שהתקנת."</string>
     <string name="permdesc_getAccounts" product="tv" msgid="437604680436540822">"‏מאפשרת לאפליקציה לקבל את רשימת החשבונות המוכרים למכשיר ה-Android TV. הפרטים עשויים לכלול חשבונות שנוצרו על ידי אפליקציות שהתקנת."</string>
     <string name="permdesc_getAccounts" product="default" msgid="2491273043569751867">"מאפשר לאפליקציה לקבל רשימה של חשבונות המוכרים לטלפון. הדבר עשוי לכלול חשבונות שנוצרו על ידי אפליקציות שהתקנת."</string>
-    <string name="permlab_accessNetworkState" msgid="2349126720783633918">"הצג חיבורי רשת"</string>
-    <string name="permdesc_accessNetworkState" msgid="4394564702881662849">"מאפשר לאפליקציה להציג מידע לגבי חיבורי רשת, למשל, אילו רשתות קיימות ומחוברות."</string>
+    <string name="permlab_accessNetworkState" msgid="2349126720783633918">"הצגת חיבורי רשת"</string>
+    <string name="permdesc_accessNetworkState" msgid="4394564702881662849">"מאפשרת לאפליקציה להציג מידע לגבי חיבורי רשת, למשל, אילו רשתות קיימות ומחוברות."</string>
     <string name="permlab_createNetworkSockets" msgid="3224420491603590541">"קבלת גישת רשת מלאה"</string>
     <string name="permdesc_createNetworkSockets" msgid="7722020828749535988">"‏מאפשר לאפליקציה ליצור Sockets ולהשתמש בפרוטוקולי רשת מותאמים אישית. הדפדפן, כמו אפליקציות  אחרות, מספק אמצעים לשליחת נתונים לאינטרנט, כך שאישור זה אינו נחוץ לשליחת נתונים לאינטרנט."</string>
     <string name="permlab_changeNetworkState" msgid="8945711637530425586">"שנה את קישוריות הרשת"</string>
@@ -546,7 +550,7 @@
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"מאפשרת לאפליקציה להשתמש בחומרה ביומטרית לצורך אימות"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"ניהול חומרה של טביעות אצבעות"</string>
     <string name="permdesc_manageFingerprint" msgid="2025616816437339865">"מאפשר לאפליקציה להפעיל שיטות להוספה ומחיקה של תבניות טביעות אצבעות שבהן ייעשה שימוש."</string>
-    <string name="permlab_useFingerprint" msgid="1001421069766751922">"חומרה של טביעות אצבעות"</string>
+    <string name="permlab_useFingerprint" msgid="1001421069766751922">"שימוש בחומרה של טביעות אצבעות"</string>
     <string name="permdesc_useFingerprint" msgid="412463055059323742">"מאפשר לאפליקציה להשתמש בחומרה של טביעות אצבעות לצורך אימות"</string>
     <string name="permlab_audioWrite" msgid="8501705294265669405">"לשנות את אוסף המוזיקה שלך"</string>
     <string name="permdesc_audioWrite" msgid="8057399517013412431">"מאפשרת לאפליקציה לשנות את אוסף המוזיקה שלך."</string>
@@ -560,11 +564,12 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"שימוש במידע ביומטרי בנעילת מסך"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"אימות זהותך"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"יש להשתמש במידע ביומטרי כדי להמשיך"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"יש להשתמש במידע הביומטרי או בנעילת המסך כדי להמשיך"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"חומרה ביומטרית לא זמינה"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"האימות בוטל"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"לא זוהתה"</string>
     <string name="biometric_error_canceled" msgid="8266582404844179778">"האימות בוטל"</string>
-    <string name="biometric_error_device_not_secured" msgid="3129845065043995924">"עוד לא הוגדרו קוד גישה, קו ביטול נעילה או סיסמה"</string>
+    <string name="biometric_error_device_not_secured" msgid="3129845065043995924">"עוד לא הוגדרו קוד אימות, קו ביטול נעילה או סיסמה"</string>
     <string name="biometric_error_generic" msgid="6784371929985434439">"שגיאה באימות"</string>
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"שימוש בנעילת מסך"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"יש להזין את פרטי הכניסה של המכשיר כדי להמשיך"</string>
@@ -580,10 +585,10 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"זיהוי הפנים בוצע. יש ללחוץ על אישור"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"החומרה בשביל טביעות אצבעות אינה זמינה."</string>
     <string name="fingerprint_error_no_space" msgid="6126456006769817485">"לא ניתן לאחסן טביעת אצבע. יש להסיר טביעת אצבע קיימת."</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"חלף הזמן הקצוב לטביעת אצבע. אפשר לנסות שוב."</string>
+    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"נגמר הזמן הקצוב לטביעת אצבע. אפשר לנסות שוב."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"פעולת טביעת האצבע בוטלה."</string>
-    <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"פעולת טביעת האצבע בוטלה בידי המשתמש."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"יותר מדי ניסיונות. נסה שוב מאוחר יותר."</string>
+    <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"פעולת טביעת האצבע בוטלה על ידי המשתמש."</string>
+    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"יותר מדי ניסיונות. יש לנסות שוב מאוחר יותר."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="3895478283943513746">"יותר מדי ניסיונות. חיישן טביעות האצבע הושבת."</string>
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"כדאי לנסות שוב."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"לא נרשמו טביעות אצבע."</string>
@@ -593,6 +598,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"שימוש בטביעת אצבע"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"שימוש בטביעת אצבע או בנעילת מסך"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"יש להשתמש בטביעת האצבע כדי להמשיך"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"יש להשתמש בטביעת האצבע או בנעילת המסך כדי להמשיך"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"סמל טביעת אצבע"</string>
@@ -600,7 +606,7 @@
     <string name="permdesc_manageFace" msgid="6204569688492710471">"מאפשרת לאפליקציה להפעיל שיטות להוספה ומחיקה של תבניות פנים שבהן ייעשה שימוש."</string>
     <string name="permlab_useFaceAuthentication" msgid="1011430526454859030">"שימוש בחומרה לשחרור נעילה על ידי זיהוי פנים"</string>
     <string name="permdesc_useFaceAuthentication" msgid="3115697017684668012">"מאפשרת לאפליקציה להשתמש בחומרה לשחרור נעילה על ידי זיהוי פנים לצורך אימות"</string>
-    <string name="face_recalibrate_notification_name" msgid="6006095897989257026">"שחרור נעילה בזיהוי פנים"</string>
+    <string name="face_recalibrate_notification_name" msgid="6006095897989257026">"שחרור נעילה על ידי זיהוי פנים"</string>
     <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"יש לבצע רישום מחדש של הפנים שלך"</string>
     <string name="face_recalibrate_notification_content" msgid="892757485125249962">"לשיפור הזיהוי יש לבצע רישום מחדש של הפנים שלך"</string>
     <string name="face_acquired_insufficient" msgid="2150805835949162453">"לא ניתן היה לקלוט את הפנים במדויק. יש לנסות שוב."</string>
@@ -608,7 +614,7 @@
     <string name="face_acquired_too_dark" msgid="252573548464426546">"התמונה חשוכה מדי. צריך תאורה חזקה יותר."</string>
     <string name="face_acquired_too_close" msgid="1628767882971469833">"יש להרחיק את הטלפון."</string>
     <string name="face_acquired_too_far" msgid="5098567726427173896">"צריך לקרב את הטלפון."</string>
-    <string name="face_acquired_too_high" msgid="4868033653626081839">"צריך להגביה את הטלפון."</string>
+    <string name="face_acquired_too_high" msgid="4868033653626081839">"צריך להרים את הטלפון גבוה יותר."</string>
     <string name="face_acquired_too_low" msgid="1512237819632165945">"צריך להוריד את הטלפון."</string>
     <string name="face_acquired_too_right" msgid="2513391513020932655">"צריך להזיז את הטלפון שמאלה."</string>
     <string name="face_acquired_too_left" msgid="8882499346502714350">"צריך להזיז את הטלפון ימינה."</string>
@@ -640,6 +646,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"שחרור נעילה על ידי זיהוי פנים"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"שימוש בזיהוי פנים או בנעילת מסך"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"יש להשתמש בשחרור נעילה על ידי זיהוי פנים כדי להמשיך"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"יש להשתמש בזיהוי הפנים או בנעילת המסך כדי להמשיך"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"סמל הפנים"</string>
@@ -647,7 +654,7 @@
     <string name="permdesc_readSyncSettings" msgid="1325658466358779298">"מאפשר לאפליקציה לקרוא את הגדרות הסנכרון של חשבון. לדוגמה, ניתן לגלות כך האם האפליקציה \'אנשים\' מסונכרן עם חשבון כלשהו."</string>
     <string name="permlab_writeSyncSettings" msgid="6583154300780427399">"הפעלת וכיבוי סנכרון"</string>
     <string name="permdesc_writeSyncSettings" msgid="6029151549667182687">"מאפשר לאפליקציה לשנות את הגדרות הסנכרון של חשבון. לדוגמה, ניתן להשתמש בכך על מנת להפעיל סנכרון של האפליקציה \'אנשים\' עם חשבון כלשהו."</string>
-    <string name="permlab_readSyncStats" msgid="3747407238320105332">"קרא את הנתונים הסטטיסטיים של הסינכרון"</string>
+    <string name="permlab_readSyncStats" msgid="3747407238320105332">"קריאת הנתונים הסטטיסטיים של הסנכרון"</string>
     <string name="permdesc_readSyncStats" msgid="3867809926567379434">"מאפשר לאפליקציה לקרוא את סטטיסטיקת הסנכרון של חשבון, כולל היסטוריית אירועי הסנכרון וכמות הנתונים שסונכרנה."</string>
     <string name="permlab_sdcardRead" msgid="5791467020950064920">"קריאת התוכן של האחסון המשותף שלך"</string>
     <string name="permdesc_sdcardRead" msgid="6872973242228240382">"מאפשר לאפליקציה לקרוא את התוכן של האחסון המשותף."</string>
@@ -655,7 +662,7 @@
     <string name="permdesc_sdcardWrite" msgid="8376047679331387102">"מאפשר לאפליקציה לכתוב את התוכן של האחסון המשותף."</string>
     <string name="permlab_use_sip" msgid="8250774565189337477">"‏ביצוע/קבלה של שיחות SIP"</string>
     <string name="permdesc_use_sip" msgid="3590270893253204451">"‏אפשר לאפליקציה לבצע ולקבל שיחות SIP."</string>
-    <string name="permlab_register_sim_subscription" msgid="1653054249287576161">"‏רשום חיבורי Telecom SIM חדשים"</string>
+    <string name="permlab_register_sim_subscription" msgid="1653054249287576161">"‏רישום חיבורי Telecom SIM חדשים"</string>
     <string name="permdesc_register_sim_subscription" msgid="4183858662792232464">"‏מאפשר לאפליקציה לרשום חיבורי Telecom SIM חדשים."</string>
     <string name="permlab_register_call_provider" msgid="6135073566140050702">"‏רשום חיבורי Telecom חדשים"</string>
     <string name="permdesc_register_call_provider" msgid="4201429251459068613">"מאפשר לאפליקציה לרשום חיבורי תקשורת חדשים."</string>
@@ -676,9 +683,9 @@
     <string name="permlab_accessNotifications" msgid="7130360248191984741">"גישה להתראות"</string>
     <string name="permdesc_accessNotifications" msgid="761730149268789668">"מאפשר לאפליקציה לאחזר, לבדוק ולמחוק התראות, כולל כאלה שפורסמו על ידי אפליקציות אחרות."</string>
     <string name="permlab_bindNotificationListenerService" msgid="5848096702733262458">"איגוד לשירות של מאזין להתראות"</string>
-    <string name="permdesc_bindNotificationListenerService" msgid="4970553694467137126">"הרשאה זו מאפשרת למשתמש לבצע איגוד לממשק הרמה העליונה של שירות מאזין להתראות. הרשאה זו אף פעם אינה נחוצה לאפליקציות רגילים."</string>
+    <string name="permdesc_bindNotificationListenerService" msgid="4970553694467137126">"מאפשרת למשתמש לבצע איגוד לממשק הרמה העליונה של שירות האזנה להתראות. ההרשאה הזו אינה נחוצה לאפליקציות רגילות."</string>
     <string name="permlab_bindConditionProviderService" msgid="5245421224814878483">"איגוד לשירות ספק תנאי"</string>
-    <string name="permdesc_bindConditionProviderService" msgid="6106018791256120258">"מאפשרת לבעלים לאגד לממשק ברמה העליונה של שירות ספק תנאי. לעולם לא אמורה להיות נחוצה עבור אפליקציות רגילות."</string>
+    <string name="permdesc_bindConditionProviderService" msgid="6106018791256120258">"מאפשרת לבעלים לאגד לממשק ברמה העליונה של שירות ספק תנאי. לא אמורה להיות נחוצה עבור אפליקציות רגילות."</string>
     <string name="permlab_bindDreamService" msgid="4776175992848982706">"איגוד לשירות ׳חלום בהקיץ׳"</string>
     <string name="permdesc_bindDreamService" msgid="9129615743300572973">"מאפשרת לבעלים לבצע איגוד לממשק הרמה העליונה של שירות ׳חלום בהקיץ׳. הרשאה זו אף פעם אינה נחוצה לאפליקציות רגילות."</string>
     <string name="permlab_invokeCarrierSetup" msgid="5098810760209818140">"הפעלה של אפליקציית תצורה שסופקה על ידי ספק"</string>
@@ -696,7 +703,7 @@
     <string name="permlab_bindCarrierMessagingService" msgid="3363450860593096967">"איגוד לשירות העברת הודעות של ספק"</string>
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"מאפשרת לבעלים לאגד לממשק ברמה העליונה של שירות העברת הודעות של ספק. לעולם לא אמורה להיות נחוצה עבור אפליקציות רגילות."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"איגוד לשירותי ספק"</string>
-    <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"מאפשר לבעלים לאגד לשירות ספק. לעולם לא אמור להיות נחוץ לאפליקציות רגילות."</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>
@@ -704,7 +711,7 @@
     <string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"גישה לנתוני חיישנים בתדירות דגימה גבוהה"</string>
     <string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"האפליקציה תוכל לדגום נתוני חיישנים בתדירות של מעל 200 הרץ"</string>
     <string name="policylab_limitPassword" msgid="4851829918814422199">"הגדר כללי סיסמה"</string>
-    <string name="policydesc_limitPassword" msgid="4105491021115793793">"קביעת האורך הנדרש והתווים המותרים בסיסמאות ובקודי הגישה של מסך הנעילה."</string>
+    <string name="policydesc_limitPassword" msgid="4105491021115793793">"קביעת האורך הנדרש והתווים המותרים בסיסמאות ובקודי האימות של מסך הנעילה."</string>
     <string name="policylab_watchLogin" msgid="7599669460083719504">"מעקב אחר ניסיונות לביטול של נעילת המסך"</string>
     <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"ניהול מעקב אחר מספר הסיסמאות השגויות שמוקלדות בעת ביטול נעילת המסך, וביצוע נעילה של הטאבלט, או מחיקה של כל נתוני הטאבלט, אם מוקלדות יותר מדי סיסמאות שגויות."</string>
     <string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"‏מעקב אחר מספר הסיסמאות השגויות שהוזנו בעת ביטול נעילת המסך, כמו גם נעילה של מכשיר ה-Android TV או מחיקה של כל נתוני מכשיר ה-Android TV אם הוזנו יותר מדי סיסמאות שגויות."</string>
@@ -717,7 +724,7 @@
     <string name="policylab_forceLock" msgid="7360335502968476434">"נעילת המסך"</string>
     <string name="policydesc_forceLock" msgid="1008844760853899693">"שליטה באופן ובתזמון של נעילת המסך."</string>
     <string name="policylab_wipeData" msgid="1359485247727537311">"מחיקת כל הנתונים"</string>
-    <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"מחק את נתוני הטאבלט ללא אזהרה על ידי ביצוע איפוס נתוני יצרן."</string>
+    <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"מחיקה של נתוני הטאבלט ללא אזהרה, באמצעות איפוס לנתוני היצרן."</string>
     <string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"‏מחיקה ללא אזהרה של נתוני מכשיר ה-Android TV באמצעות איפוס לנתוני היצרן."</string>
     <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"מחיקה של נתוני הטלפון, ללא אזהרה, על ידי ביצוע איפוס נתוני יצרן."</string>
     <string name="policylab_wipeData_secondaryUser" msgid="413813645323433166">"מחיקת נתוני משתמש"</string>
@@ -730,10 +737,10 @@
     <string name="policydesc_expirePassword" msgid="9136524319325960675">"שינוי התדירות לדרישת השינוי של הסיסמה, קוד הגישה או קו ביטול הנעילה של מסך הנעילה."</string>
     <string name="policylab_encryptedStorage" msgid="9012936958126670110">"הגדר הצפנת אחסון"</string>
     <string name="policydesc_encryptedStorage" msgid="1102516950740375617">"דרוש שנתוני אפליקציות מאוחסנות יהיו מוצפנים."</string>
-    <string name="policylab_disableCamera" msgid="5749486347810162018">"השבת מצלמות"</string>
+    <string name="policylab_disableCamera" msgid="5749486347810162018">"השבתת מצלמות"</string>
     <string name="policydesc_disableCamera" msgid="3204405908799676104">"מנע שימוש בכל המצלמות שבמכשיר."</string>
     <string name="policylab_disableKeyguardFeatures" msgid="5071855750149949741">"השבת חלק מהתכונות של נעילת המסך"</string>
-    <string name="policydesc_disableKeyguardFeatures" msgid="6641673177041195957">"מנע שימוש בחלק מהתכונות של נעילת המסך."</string>
+    <string name="policydesc_disableKeyguardFeatures" msgid="6641673177041195957">"מניעת שימוש בחלק מהתכונות של נעילת המסך."</string>
   <string-array name="phoneTypes">
     <item msgid="8996339953292723951">"בית"</item>
     <item msgid="7740243458912727194">"נייד"</item>
@@ -836,7 +843,7 @@
     <string name="relationTypeFather" msgid="3856225062864790596">"אב"</string>
     <string name="relationTypeFriend" msgid="3192092625893980574">"חבר"</string>
     <string name="relationTypeManager" msgid="2272860813153171857">"מנהל"</string>
-    <string name="relationTypeMother" msgid="2331762740982699460">"אם"</string>
+    <string name="relationTypeMother" msgid="2331762740982699460">"אמא"</string>
     <string name="relationTypeParent" msgid="4177920938333039882">"הורה"</string>
     <string name="relationTypePartner" msgid="4018017075116766194">"שותף"</string>
     <string name="relationTypeReferredBy" msgid="5285082289602849400">"הופנה על ידי"</string>
@@ -848,14 +855,14 @@
     <string name="sipAddressTypeWork" msgid="7873967986701216770">"עבודה"</string>
     <string name="sipAddressTypeOther" msgid="6317012577345187275">"אחר"</string>
     <string name="quick_contacts_not_available" msgid="1262709196045052223">"לא נמצאה אפליקציה להצגת התוכן הזה."</string>
-    <string name="keyguard_password_enter_pin_code" msgid="6401406801060956153">"הקלד קוד גישה"</string>
-    <string name="keyguard_password_enter_puk_code" msgid="3112256684547584093">"‏הקלד את קוד ה-PUK וקוד  הגישה החדש"</string>
+    <string name="keyguard_password_enter_pin_code" msgid="6401406801060956153">"יש להקליד קוד אימות"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="3112256684547584093">"‏יש להקליד את קוד ה-PUK ואת קוד האימות החדש"</string>
     <string name="keyguard_password_enter_puk_prompt" msgid="2825313071899938305">"‏קוד PUK"</string>
-    <string name="keyguard_password_enter_pin_prompt" msgid="5505434724229581207">"קוד גישה חדש"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="5505434724229581207">"קוד אימות חדש"</string>
     <string name="keyguard_password_entry_touch_hint" msgid="4032288032993261520"><font size="17">"הקש כדי להקליד את הסיסמה"</font></string>
     <string name="keyguard_password_enter_password_code" msgid="2751130557661643482">"הקלד סיסמה לביטול הנעילה"</string>
-    <string name="keyguard_password_enter_pin_password_code" msgid="7792964196473964340">"הקלד קוד גישה לביטול הנעילה"</string>
-    <string name="keyguard_password_wrong_pin_code" msgid="8583732939138432793">"קוד גישה שגוי"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="7792964196473964340">"יש להקליד קוד אימות לביטול הנעילה"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="8583732939138432793">"קוד אימות שגוי"</string>
     <string name="keyguard_label_text" msgid="3841953694564168384">"כדי לבטל את הנעילה, לחץ על \'תפריט\' ולאחר מכן על 0."</string>
     <string name="emergency_call_dialog_number_for_display" msgid="2978165477085612673">"מספר חירום"</string>
     <string name="lockscreen_carrier_default" msgid="6192313772955399160">"אין שירות"</string>
@@ -879,7 +886,7 @@
     <string name="lockscreen_permanent_disabled_sim_message_short" msgid="3812893366715730539">"‏לא ניתן להשתמש בכרטיס SIM זה."</string>
     <string name="lockscreen_permanent_disabled_sim_instructions" msgid="4358929052509450807">"‏כרטיס ה-SIM שלך הושבת לצמיתות.\nפנה לספק השירות האלחוטי שלך לקבלת כרטיס SIM אחר."</string>
     <string name="lockscreen_transport_prev_description" msgid="2879469521751181478">"הרצועה הקודמת"</string>
-    <string name="lockscreen_transport_next_description" msgid="2931509904881099919">"הרצועה הבאה"</string>
+    <string name="lockscreen_transport_next_description" msgid="2931509904881099919">"הטראק הבא"</string>
     <string name="lockscreen_transport_pause_description" msgid="6705284702135372494">"השהה"</string>
     <string name="lockscreen_transport_play_description" msgid="106868788691652733">"הפעלה"</string>
     <string name="lockscreen_transport_stop_description" msgid="1449552232598355348">"הפסק"</string>
@@ -904,10 +911,10 @@
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="2205435033340091883">"‏ניסית לבטל בצורה שגויה את הנעילה של מכשיר ה-Android TV <xliff:g id="NUMBER">%d</xliff:g> פעמים. מכשיר ה-Android TV יעבור כעת איפוס לברירת המחדל של היצרן."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="2203704707679895487">"ביצעת <xliff:g id="NUMBER">%d</xliff:g> ניסיונות שגויים לביטול נעילת הטלפון. הטלפון יעבור כעת איפוס לברירת המחדל של היצרן."</string>
     <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6807200118164539589">"נסה שוב בעוד <xliff:g id="NUMBER">%d</xliff:g> שניות."</string>
-    <string name="lockscreen_forgot_pattern_button_text" msgid="8362442730606839031">"שכחת את הקו?"</string>
+    <string name="lockscreen_forgot_pattern_button_text" msgid="8362442730606839031">"שכחת את קו ביטול הנעילה?"</string>
     <string name="lockscreen_glogin_forgot_pattern" msgid="9218940117797602518">"ביטול נעילת חשבון"</string>
     <string name="lockscreen_glogin_too_many_attempts" msgid="3775904917743034195">"בוצעו ניסיונות רבים מדי לשרטוט קו ביטול נעילה."</string>
-    <string name="lockscreen_glogin_instructions" msgid="4695162942525531700">"‏כדי לבטל את הנעילה, היכנס באמצעות חשבון Google שלך."</string>
+    <string name="lockscreen_glogin_instructions" msgid="4695162942525531700">"‏כדי לבטל את הנעילה, עליך להיכנס באמצעות חשבון Google שלך."</string>
     <string name="lockscreen_glogin_username_hint" msgid="6916101478673157045">"שם משתמש (אימייל)"</string>
     <string name="lockscreen_glogin_password_hint" msgid="3031027901286812848">"סיסמה"</string>
     <string name="lockscreen_glogin_submit_button" msgid="3590556636347843733">"כניסה"</string>
@@ -941,7 +948,7 @@
     <string name="keyguard_accessibility_pattern_unlock" msgid="8669128146589233293">"ביטול נעילה על ידי שרטוט קו."</string>
     <string name="keyguard_accessibility_face_unlock" msgid="632407612842329815">"ביטול נעילה באמצעות זיהוי פנים."</string>
     <string name="keyguard_accessibility_pin_unlock" msgid="4020864007967340068">"ביטול נעילה באמצעות קוד גישה."</string>
-    <string name="keyguard_accessibility_sim_pin_unlock" msgid="4895939120871890557">"‏ביטול נעילה של קוד הגישה ל-SIM."</string>
+    <string name="keyguard_accessibility_sim_pin_unlock" msgid="4895939120871890557">"‏ביטול הנעילה של קוד האימות ל-SIM."</string>
     <string name="keyguard_accessibility_sim_puk_unlock" msgid="3459003464041899101">"‏ביטול נעילה של PUK ל-SIM."</string>
     <string name="keyguard_accessibility_password_unlock" msgid="6130186108581153265">"ביטול נעילה באמצעות סיסמה."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="1419570880512350689">"אזור לשרטוט קו ביטול נעילה."</string>
@@ -997,12 +1004,14 @@
     <string name="permlab_writeGeolocationPermissions" msgid="8605631647492879449">"שינוי הרשאות המיקום הגיאוגרפי של הדפדפן"</string>
     <string name="permdesc_writeGeolocationPermissions" msgid="5817346421222227772">"מאפשר לאפליקציה לשנות את הרשאות המיקום הגיאוגרפי של הדפדפן. אפליקציות זדוניות עלולות להשתמש בכך כדי לאפשר משלוח של פרטי מיקום לאתרים זדוניים אחרים."</string>
     <string name="save_password_message" msgid="2146409467245462965">"האם ברצונך שהדפדפן יזכור סיסמה זו?"</string>
-    <string name="save_password_notnow" msgid="2878327088951240061">"לא כעת"</string>
+    <string name="save_password_notnow" msgid="2878327088951240061">"לא עכשיו"</string>
     <string name="save_password_remember" msgid="6490888932657708341">"זכור"</string>
     <string name="save_password_never" msgid="6776808375903410659">"אף פעם"</string>
     <string name="open_permission_deny" msgid="5136793905306987251">"אין לך הרשאה לפתוח דף זה."</string>
     <string name="text_copied" msgid="2531420577879738860">"הטקסט הועתק ללוח."</string>
     <string name="copied" msgid="4675902854553014676">"ההעתקה בוצעה"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"האפליקציה <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> הודבקה מ-<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"האפליקציה <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> הודבקה מהלוח"</string>
     <string name="more_item_label" msgid="7419249600215749115">"עוד"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"תפריט+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1018,10 +1027,10 @@
     <string name="search_hint" msgid="455364685740251925">"חיפוש…"</string>
     <string name="searchview_description_search" msgid="1045552007537359343">"חיפוש"</string>
     <string name="searchview_description_query" msgid="7430242366971716338">"שאילתת חיפוש"</string>
-    <string name="searchview_description_clear" msgid="1989371719192982900">"נקה שאילתה"</string>
-    <string name="searchview_description_submit" msgid="6771060386117334686">"שלח שאילתה"</string>
+    <string name="searchview_description_clear" msgid="1989371719192982900">"ניקוי שאילתה"</string>
+    <string name="searchview_description_submit" msgid="6771060386117334686">"שליחת שאילתה"</string>
     <string name="searchview_description_voice" msgid="42360159504884679">"חיפוש קולי"</string>
-    <string name="enable_explore_by_touch_warning_title" msgid="5095399706284943314">"האם להפעיל את התכונה \'חקור על ידי מגע\'?"</string>
+    <string name="enable_explore_by_touch_warning_title" msgid="5095399706284943314">"האם להפעיל את התכונה \'גילוי באמצעות מגע\'?"</string>
     <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="1037295476738940824">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> רוצה להפעיל את התכונה \'חקור על ידי מגע\'. כאשר התכונה \'חקור על ידי מגע\' מופעלת, אתה יכול לשמוע או לראות תיאורים של הפריטים שעליהם אצבעך  מונחת או לקיים אינטראקציה עם הטאבלט באמצעות תנועות אצבע."</string>
     <string name="enable_explore_by_touch_warning_message" product="default" msgid="4312979647356179250">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> רוצה להפעיל את התכונה \'חקור על ידי מגע\'. כאשר התכונה \'חקור על ידי מגע\' מופעלת, אתה יכול לשמוע או לראות תיאורים של הפריטים שעליהם אצבעך מונחת או לקיים אינטראקציה עם הטלפון באמצעות תנועות אצבע."</string>
     <string name="oneMonthDurationPast" msgid="4538030857114635777">"לפני חודש אחד"</string>
@@ -1158,8 +1167,8 @@
     <string name="elapsed_time_short_format_mm_ss" msgid="8689459651807876423">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
     <string name="elapsed_time_short_format_h_mm_ss" msgid="2302144714803345056">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
     <string name="selectAll" msgid="1532369154488982046">"בחר הכל"</string>
-    <string name="cut" msgid="2561199725874745819">"חתוך"</string>
-    <string name="copy" msgid="5472512047143665218">"העתק"</string>
+    <string name="cut" msgid="2561199725874745819">"חיתוך"</string>
+    <string name="copy" msgid="5472512047143665218">"העתקה"</string>
     <string name="failed_to_copy_to_clipboard" msgid="725919885138539875">"ההעתקה אל הלוח נכשלה"</string>
     <string name="paste" msgid="461843306215520225">"הדבק"</string>
     <string name="paste_as_plain_text" msgid="7664800665823182587">"הדבק כטקסט פשוט"</string>
@@ -1175,7 +1184,7 @@
     <string name="deleteText" msgid="4200807474529938112">"מחיקה"</string>
     <string name="inputMethod" msgid="1784759500516314751">"שיטת קלט"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"פעולות טקסט"</string>
-    <string name="low_internal_storage_view_title" msgid="9024241779284783414">"שטח האחסון אוזל"</string>
+    <string name="low_internal_storage_view_title" msgid="9024241779284783414">"מקום האחסון עומד להיגמר"</string>
     <string name="low_internal_storage_view_text" msgid="8172166728369697835">"ייתכן שפונקציות מערכת מסוימות לא יפעלו"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="7368968163411251788">"‏אין מספיק שטח אחסון עבור המערכת. ודא שיש לך שטח פנוי בגודל 250MB התחל שוב."</string>
     <string name="app_running_notification_title" msgid="8985999749231486569">"<xliff:g id="APP_NAME">%1$s</xliff:g> פועל"</string>
@@ -1204,10 +1213,10 @@
     <string name="whichOpenHostLinksWithApp" msgid="2401668560768463004">"פתיחת קישורים של <xliff:g id="HOST">%1$s</xliff:g> באמצעות <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="7805857277166106236">"הענקת גישה"</string>
     <string name="whichEditApplication" msgid="6191568491456092812">"ערוך באמצעות"</string>
-    <string name="whichEditApplicationNamed" msgid="8096494987978521514">"‏ערוך באמצעות %1$s"</string>
+    <string name="whichEditApplicationNamed" msgid="8096494987978521514">"‏עריכה באמצעות %1$s"</string>
     <string name="whichEditApplicationLabel" msgid="1463288652070140285">"עריכה"</string>
     <string name="whichSendApplication" msgid="4143847974460792029">"שיתוף"</string>
-    <string name="whichSendApplicationNamed" msgid="4470386782693183461">"‏שתף באמצעות %1$s"</string>
+    <string name="whichSendApplicationNamed" msgid="4470386782693183461">"‏שיתוף באמצעות %1$s"</string>
     <string name="whichSendApplicationLabel" msgid="7467813004769188515">"שתף"</string>
     <string name="whichSendToApplication" msgid="77101541959464018">"שליחה באמצעות"</string>
     <string name="whichSendToApplicationNamed" msgid="3385686512014670003">"‏שליחה באמצעות %1$s"</string>
@@ -1223,7 +1232,7 @@
     <string name="clearDefaultHintMsg" msgid="1325866337702524936">"‏נקה את הגדרת המחדל ב\'הגדרות מערכת\' &lt;‏ Google Apps‏ &lt; \'הורדות\'."</string>
     <string name="chooseActivity" msgid="8563390197659779956">"בחירת פעולה"</string>
     <string name="chooseUsbActivity" msgid="2096269989990986612">"‏בחר אפליקציה עבור התקן ה-USB"</string>
-    <string name="noApplications" msgid="1186909265235544019">"אין אפליקציות שיכולות לבצע פעולה זו."</string>
+    <string name="noApplications" msgid="1186909265235544019">"אין אפליקציות שיכולות לבצע את הפעולה הזו."</string>
     <string name="aerr_application" msgid="4090916809370389109">"האפליקציה <xliff:g id="APPLICATION">%1$s</xliff:g> הפסיקה"</string>
     <string name="aerr_process" msgid="4268018696970966407">"התהליך <xliff:g id="PROCESS">%1$s</xliff:g> הפסיק"</string>
     <string name="aerr_application_repeated" msgid="7804378743218496566">"האפליקציה <xliff:g id="APPLICATION">%1$s</xliff:g> נעצרת שוב ושוב"</string>
@@ -1245,9 +1254,9 @@
     <string name="webpage_unresponsive" msgid="7850879412195273433">"הדף אינו מגיב.\n\nהאם אתה רוצה לסגור אותו?"</string>
     <string name="launch_warning_title" msgid="6725456009564953595">"הפנייה מחדש של אפליקציה"</string>
     <string name="launch_warning_replace" msgid="3073392976283203402">"<xliff:g id="APP_NAME">%1$s</xliff:g> פועל כעת."</string>
-    <string name="launch_warning_original" msgid="3332206576800169626">"<xliff:g id="APP_NAME">%1$s</xliff:g> הופעל במקור."</string>
+    <string name="launch_warning_original" msgid="3332206576800169626">"אפליקציית <xliff:g id="APP_NAME">%1$s</xliff:g> הופעלה במקור."</string>
     <string name="screen_compat_mode_scale" msgid="8627359598437527726">"שינוי קנה-מידה"</string>
-    <string name="screen_compat_mode_show" msgid="5080361367584709857">"הצג תמיד"</string>
+    <string name="screen_compat_mode_show" msgid="5080361367584709857">"להציג תמיד"</string>
     <string name="screen_compat_mode_hint" msgid="4032272159093750908">"‏אפשר תכונה זו מחדש ב\'הגדרות מערכת\' &lt;‏ Google Apps‏ &lt; \'הורדות\'."</string>
     <string name="unsupported_display_size_message" msgid="7265211375269394699">"<xliff:g id="APP_NAME">%1$s</xliff:g> אינו תומך בהגדרת הגודל הנוכחית של התצוגה, והתנהגותו עשויה להיות בלתי צפויה."</string>
     <string name="unsupported_display_size_show" msgid="980129850974919375">"הצג תמיד"</string>
@@ -1276,8 +1285,8 @@
     <string name="heavy_weight_switcher_text" msgid="6814316627367160126">"לקבלת ביצועים טובים יותר, רק אחד מבין המשחקים האלה יכול להיות פתוח בכל פעם."</string>
     <string name="old_app_action" msgid="725331621042848590">"חזרה אל <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
     <string name="new_app_action" msgid="547772182913269801">"פתיחת <xliff:g id="NEW_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1958903080400806644">"<xliff:g id="OLD_APP">%1$s</xliff:g> האפליקציה תיסגר ללא שמירה"</string>
-    <string name="dump_heap_notification" msgid="5316644945404825032">"<xliff:g id="PROC">%1$s</xliff:g> חורג מהגבלת הזיכרון"</string>
+    <string name="new_app_description" msgid="1958903080400806644">"אפליקציית <xliff:g id="OLD_APP">%1$s</xliff:g> תיסגר ללא שמירה"</string>
+    <string name="dump_heap_notification" msgid="5316644945404825032">"<xliff:g id="PROC">%1$s</xliff:g> חורג ממגבלת הזיכרון"</string>
     <string name="dump_heap_ready_notification" msgid="2302452262927390268">"‏Dump של ערימה בשביל <xliff:g id="PROC">%1$s</xliff:g> מוכן"</string>
     <string name="dump_heap_notification_detail" msgid="8431586843001054050">"‏Dump של ערימה נאסף. יש להקיש כדי לשתף."</string>
     <string name="dump_heap_title" msgid="4367128917229233901">"‏האם לשתף את נתוני ה-Dump של הערימה?"</string>
@@ -1294,7 +1303,7 @@
     <string name="volume_alarm" msgid="4486241060751798448">"עוצמת קול של התראה"</string>
     <string name="volume_notification" msgid="6864412249031660057">"עוצמת הקול של ההתראות"</string>
     <string name="volume_unknown" msgid="4041914008166576293">"עוצמת קול"</string>
-    <string name="volume_icon_description_bluetooth" msgid="7540388479345558400">"‏עוצמת קול של Bluetooth"</string>
+    <string name="volume_icon_description_bluetooth" msgid="7540388479345558400">"‏עוצמת הקול של Bluetooth"</string>
     <string name="volume_icon_description_ringer" msgid="2187800636867423459">"עוצמת קול של רינגטון"</string>
     <string name="volume_icon_description_incall" msgid="4491255105381227919">"עוצמת קול של שיחות"</string>
     <string name="volume_icon_description_media" msgid="4997633254078171233">"עוצמת קול של מדיה"</string>
@@ -1359,7 +1368,7 @@
     <string name="time_picker_dialog_title" msgid="9053376764985220821">"הגדרת שעה"</string>
     <string name="date_picker_dialog_title" msgid="5030520449243071926">"הגדרת תאריך"</string>
     <string name="date_time_set" msgid="4603445265164486816">"הגדרה"</string>
-    <string name="date_time_done" msgid="8363155889402873463">"בוצע"</string>
+    <string name="date_time_done" msgid="8363155889402873463">"סיום"</string>
     <string name="perms_new_perm_prefix" msgid="6984556020395757087"><font size="12" fgcolor="#ff33b5e5">"חדש: "</font></string>
     <string name="perms_description_app" msgid="2747752389870161996">"מטעם <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
     <string name="no_permissions" msgid="5729199278862516390">"לא דרושים אישורים"</string>
@@ -1383,7 +1392,7 @@
     <string name="adbwifi_active_notification_message" msgid="930987922852867972">"יש להקיש כדי להשבית ניפוי באגים אלחוטי"</string>
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"יש לבחור כדי להשבית ניפוי באגים אלחוטי."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"מצב מסגרת בדיקה הופעל"</string>
-    <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"כדי להשבית את מצב מסגרת בדיקה צריך לאפס להגדרות היצרן."</string>
+    <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"כדי להשבית את מצב \'מסגרת בדיקה\' צריך לאפס להגדרות היצרן."</string>
     <string name="console_running_notification_title" msgid="6087888939261635904">"קונסולה סדרתית מופעלת"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"קיימת השפעה על הביצועים. כדי להשבית, יש לבדוק את תוכנת האתחול."</string>
     <string name="usb_contaminant_detected_title" msgid="4359048603069159678">"‏יש נוזלים או חלקיקים ביציאת ה-USB"</string>
@@ -1410,11 +1419,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"כיבוי"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"בתהליך בדיקה של <xliff:g id="NAME">%s</xliff:g>…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"מתבצעת בדיקה של התוכן הנוכחי"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"אחסון המדיה בתהליך ניתוח"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"<xliff:g id="NAME">%s</xliff:g> חדש"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"המדיה <xliff:g id="NAME">%s</xliff:g> לא פועלת"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"צריך להקיש כדי להגדיר"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"יש לבחור כדי להגדיר"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"ייתכן שיהיה צורך לפרמט מחדש את המכשיר. יש להקיש כדי להוציא את המדיה."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"להעברת תמונות ומדיה"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"עיון בקובצי המדיה"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"בעיה עם <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"המדיה <xliff:g id="NAME">%s</xliff:g> לא פועלת"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"יש להקיש כדי לתקן את הבעיה"</string>
@@ -1423,7 +1435,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"<xliff:g id="NAME">%s</xliff:g> לא נתמך"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"המדיה <xliff:g id="NAME">%s</xliff:g> לא פועלת"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"מכשיר זה אינו תומך ב-<xliff:g id="NAME">%s</xliff:g> זה. הקש כדי להגדיר בפורמט נתמך."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"<xliff:g id="NAME">%s</xliff:g> לא נתמך במכשיר הזה. בחר כדי להגדיר בפורמט שנתמך."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"יש לבחור כדי להגדיר את <xliff:g id="NAME">%s</xliff:g> בפורמט נתמך."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"ייתכן שיהיה צורך לפרמט מחדש את המכשיר"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> הוסר באופן בלתי צפוי"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"יש לבחור באפשרות להוצאת מדיה לפני ההסרה, כדי לא לאבד תוכן"</string>
@@ -1474,10 +1486,10 @@
     <string name="ime_action_done" msgid="6299921014822891569">"סיום"</string>
     <string name="ime_action_previous" msgid="6548799326860401611">"הקודם"</string>
     <string name="ime_action_default" msgid="8265027027659800121">"בצע"</string>
-    <string name="dial_number_using" msgid="6060769078933953531">"חייג למספר\nבאמצעות <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="dial_number_using" msgid="6060769078933953531">"חיוג למספר\nבאמצעות <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="create_contact_using" msgid="6200708808003692594">"צור איש קשר\nבאמצעות <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="grant_credentials_permission_message_header" msgid="5365733888842570481">"האפליקציות הבאות מבקשות אישור לגשת לחשבונך, כעת ובעתיד."</string>
-    <string name="grant_credentials_permission_message_footer" msgid="1886710210516246461">"האם ברצונך לאפשר בקשה זו?"</string>
+    <string name="grant_credentials_permission_message_footer" msgid="1886710210516246461">"לאפשר את הבקשה הזו?"</string>
     <string name="grant_permissions_header_text" msgid="3420736827804657201">"בקשת גישה"</string>
     <string name="allow" msgid="6195617008611933762">"כן, זה בסדר"</string>
     <string name="deny" msgid="6632259981847676572">"עדיף שלא"</string>
@@ -1526,10 +1538,10 @@
     <string name="find" msgid="5015737188624767706">"מצא"</string>
     <string name="websearch" msgid="5624340204512793290">"חיפוש באינטרנט"</string>
     <string name="find_next" msgid="5341217051549648153">"חפש את הבא"</string>
-    <string name="find_previous" msgid="4405898398141275532">"חפש את הקודם"</string>
+    <string name="find_previous" msgid="4405898398141275532">"חיפוש של הקודם"</string>
     <string name="gpsNotifTicker" msgid="3207361857637620780">"בקשת מיקום מאת <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="gpsNotifTitle" msgid="1590033371665669570">"בקשת מיקום"</string>
-    <string name="gpsNotifMessage" msgid="7346649122793758032">"מבוקש על ידי <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+    <string name="gpsNotifMessage" msgid="7346649122793758032">"הבקשה נשלחה על ידי <xliff:g id="NAME">%1$s</xliff:g>‏ (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
     <string name="gpsVerifYes" msgid="3719843080744112940">"כן"</string>
     <string name="gpsVerifNo" msgid="1671201856091564741">"לא"</string>
     <string name="sync_too_many_deletes" msgid="6999440774578705300">"חרגת ממגבלת המחיקה"</string>
@@ -1543,7 +1555,7 @@
     <string name="number_picker_increment_button" msgid="7621013714795186298">"הוסף"</string>
     <string name="number_picker_decrement_button" msgid="5116948444762708204">"הפחת"</string>
     <string name="number_picker_increment_scroll_mode" msgid="8403893549806805985">"<xliff:g id="VALUE">%s</xliff:g> לחיצה ארוכה."</string>
-    <string name="number_picker_increment_scroll_action" msgid="8310191318914268271">"הסט למעלה כדי להוסיף ולמטה כדי להפחית."</string>
+    <string name="number_picker_increment_scroll_action" msgid="8310191318914268271">"צריך להסיט למעלה כדי להוסיף ולמטה כדי להפחית."</string>
     <string name="time_picker_increment_minute_button" msgid="7195870222945784300">"הוספת דקה"</string>
     <string name="time_picker_decrement_minute_button" msgid="230925389943411490">"הפחת דקה"</string>
     <string name="time_picker_increment_hour_button" msgid="3063572723197178242">"הוסף שעה"</string>
@@ -1551,7 +1563,7 @@
     <string name="time_picker_increment_set_pm_button" msgid="5889149366900376419">"‏הגדר PM"</string>
     <string name="time_picker_decrement_set_am_button" msgid="1422608001541064087">"‏הגדר AM"</string>
     <string name="date_picker_increment_month_button" msgid="3447263316096060309">"הוסף חודש"</string>
-    <string name="date_picker_decrement_month_button" msgid="6531888937036883014">"הפחת חודש"</string>
+    <string name="date_picker_decrement_month_button" msgid="6531888937036883014">"הפחתת חודש"</string>
     <string name="date_picker_increment_day_button" msgid="4349336637188534259">"הוסף יום"</string>
     <string name="date_picker_decrement_day_button" msgid="6840253837656637248">"הפחת יום"</string>
     <string name="date_picker_increment_year_button" msgid="7608128783435372594">"הוסף שנה"</string>
@@ -1569,10 +1581,10 @@
     <string name="activitychooserview_choose_application_error" msgid="6937782107559241734">"לא ניתן היה להפעיל את <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="shareactionprovider_share_with" msgid="2753089758467748982">"שתף עם"</string>
     <string name="shareactionprovider_share_with_application" msgid="4902832247173666973">"שתף עם <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
-    <string name="content_description_sliding_handle" msgid="982510275422590757">"ידית להחלקה. לחיצה ארוכה."</string>
+    <string name="content_description_sliding_handle" msgid="982510275422590757">"נקודת אחיזה להחלקה. לחיצה ארוכה."</string>
     <string name="description_target_unlock_tablet" msgid="7431571180065859551">"החלק לביטול נעילה."</string>
     <string name="action_bar_home_description" msgid="1501655419158631974">"נווט לדף הבית"</string>
-    <string name="action_bar_up_description" msgid="6611579697195026932">"נווט למעלה"</string>
+    <string name="action_bar_up_description" msgid="6611579697195026932">"ניווט למעלה"</string>
     <string name="action_menu_overflow_description" msgid="4579536843510088170">"אפשרויות נוספות"</string>
     <string name="action_bar_home_description_format" msgid="5087107531331621803">"‏%1$s‏, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="4346835454749569826">"‏%1$s‏, %2$s‏, %3$s"</string>
@@ -1588,7 +1600,7 @@
     <string name="data_usage_mobile_limit_title" msgid="3911447354393775241">"הגעת למגבלה של חבילת הגלישה"</string>
     <string name="data_usage_wifi_limit_title" msgid="2069698056520812232">"‏הגעת למגבלת נתוני Wi-Fi"</string>
     <string name="data_usage_limit_body" msgid="3567699582000085710">"הנתונים הושהו להמשך המחזור"</string>
-    <string name="data_usage_mobile_limit_snoozed_title" msgid="101888478915677895">"חריגה מהמגבלה של חבילת הגלישה"</string>
+    <string name="data_usage_mobile_limit_snoozed_title" msgid="101888478915677895">"חרגת מהמגבלה של חבילת הגלישה"</string>
     <string name="data_usage_wifi_limit_snoozed_title" msgid="1622359254521960508">"‏חריגה ממגבלת נתוני ה-Wi-Fi"</string>
     <string name="data_usage_limit_snoozed_body" msgid="545146591766765678">"חרגת ב-<xliff:g id="SIZE">%s</xliff:g> מעבר למגבלה המוגדרת"</string>
     <string name="data_usage_restricted_title" msgid="126711424380051268">"נתוני הרקע מוגבלים"</string>
@@ -1611,7 +1623,7 @@
     <string name="sha256_fingerprint" msgid="7103976380961964600">"‏טביעת אצבע SHA-256:"</string>
     <string name="sha1_fingerprint" msgid="2339915142825390774">"‏טביעת אצבע SHA-1:"</string>
     <string name="activity_chooser_view_see_all" msgid="3917045206812726099">"הצג הכל"</string>
-    <string name="activity_chooser_view_dialog_title_default" msgid="8880731437191978314">"בחר פעילות"</string>
+    <string name="activity_chooser_view_dialog_title_default" msgid="8880731437191978314">"בחירת פעילות"</string>
     <string name="share_action_provider_share_with" msgid="1904096863622941880">"שתף עם"</string>
     <string name="sending" msgid="206925243621664438">"שולח…"</string>
     <string name="launchBrowserDefault" msgid="6328349989932924119">"להפעיל את הדפדפן?"</string>
@@ -1669,7 +1681,7 @@
     <string name="kg_invalid_puk" msgid="4809502818518963344">"‏הזן מחדש את קוד PUK הנכון. ניסיונות חוזרים ישביתו לצמיתות את כרטיס ה-SIM."</string>
     <string name="kg_invalid_confirm_pin_hint" product="default" msgid="4705368340409816254">"קודי הגישה אינם תואמים"</string>
     <string name="kg_login_too_many_attempts" msgid="699292728290654121">"ניסיונות רבים מדי לשרטוט קו ביטול נעילה."</string>
-    <string name="kg_login_instructions" msgid="3619844310339066827">"‏כדי לבטל את הנעילה, היכנס באמצעות חשבון Google שלך."</string>
+    <string name="kg_login_instructions" msgid="3619844310339066827">"‏כדי לבטל את הנעילה, עליך להיכנס באמצעות חשבון Google שלך."</string>
     <string name="kg_login_username_hint" msgid="1765453775467133251">"שם משתמש (אימייל)"</string>
     <string name="kg_login_password_hint" msgid="3330530727273164402">"סיסמה"</string>
     <string name="kg_login_submit_button" msgid="893611277617096870">"כניסה"</string>
@@ -1686,10 +1698,10 @@
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="5045460916106267585">"‏ניסית לבטל בצורה שגויה את הנעילה של מכשיר ה-Android TV <xliff:g id="NUMBER">%d</xliff:g> פעמים. מכשיר ה-Android TV יעבור כעת איפוס לברירת המחדל של היצרן."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="5043730590446071189">"ביצעת <xliff:g id="NUMBER">%d</xliff:g> ניסיונות שגויים לביטול נעילת הטלפון. הטלפון יעבור כעת איפוס לברירת המחדל של היצרן."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="7086799295109717623">"שרטטת את קו ביטול הנעילה באופן שגוי <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%2$d</xliff:g> ניסיונות כושלים נוספים, תתבקש לבטל את נעילת הטאבלט באמצעות חשבון אימייל‏.\n\nנסה שוב בעוד <xliff:g id="NUMBER_2">%3$d</xliff:g> שניות."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4670840383567106114">"‏שרטטת קו ביטול נעילה שגוי <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%2$d</xliff:g> ניסיונות כושלים נוספים, תתבקש לבטל את הנעילה של מכשיר ה-Android TV באמצעות חשבון אימייל.\n\n נסה שוב בעוד <xliff:g id="NUMBER_2">%3$d</xliff:g> שניות."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4670840383567106114">"‏שרטטת קו ביטול נעילה שגוי <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%2$d</xliff:g> ניסיונות כושלים נוספים, יהיה צורך לבטל את הנעילה של מכשיר ה-Android TV באמצעות חשבון אימייל.\n\n יש לנסות שוב בעוד <xliff:g id="NUMBER_2">%3$d</xliff:g> שניות."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"שרטטת את קו ביטול הנעילה באופן שגוי <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%2$d</xliff:g> ניסיונות כושלים נוספים, תתבקש לבטל את נעילת הטלפון באמצעות חשבון אימייל‏.\n\nנסה שוב בעוד <xliff:g id="NUMBER_2">%3$d</xliff:g> שניות."</string>
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
-    <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"הסר"</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"הסרה"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"האם להעלות את עוצמת הקול מעל לרמה המומלצת?\n\nהאזנה בעוצמת קול גבוהה למשכי זמן ממושכים עלולה לפגוע בשמיעה."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"להשתמש בקיצור הדרך לתכונת הנגישות?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"כשקיצור הדרך מופעל, לחיצה על שני לחצני עוצמת הקול למשך שלוש שניות מפעילה את תכונת הנגישות."</string>
@@ -1718,10 +1730,10 @@
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"עריכת קיצורי הדרך"</string>
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"סיום"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"כבה את קיצור הדרך"</string>
-    <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"השתמש בקיצור הדרך"</string>
+    <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"שימוש בקיצור הדרך"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"היפוך צבעים"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"תיקון צבעים"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"הפחתה של עוצמת הבהירות"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"מעומעם במיוחד"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"לחצני עוצמת הקול נלחצו בלחיצה ארוכה. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> הופעל."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"לחצני עוצמת הקול נלחצו בלחיצה ארוכה. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> הושבת."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"יש ללחוץ לחיצה ארוכה על שני לחצני עוצמת הקול למשך שלוש שניות כדי להשתמש בשירות <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -1733,12 +1745,12 @@
     <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"כדי לעבור בין תכונות, יש להחליק כלפי מעלה בעזרת שלוש אצבעות ולהחזיק."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"הגדלה"</string>
     <string name="user_switched" msgid="7249833311585228097">"המשתמש הנוכחי <xliff:g id="NAME">%1$s</xliff:g>."</string>
-    <string name="user_switching_message" msgid="1912993630661332336">"עובר אל <xliff:g id="NAME">%1$s</xliff:g>…"</string>
+    <string name="user_switching_message" msgid="1912993630661332336">"מעבר אל <xliff:g id="NAME">%1$s</xliff:g>…"</string>
     <string name="user_logging_out_message" msgid="7216437629179710359">"מתבצע ניתוק של <xliff:g id="NAME">%1$s</xliff:g>…"</string>
     <string name="owner_name" msgid="8713560351570795743">"בעלים"</string>
     <string name="error_message_title" msgid="4082495589294631966">"שגיאה"</string>
     <string name="error_message_change_not_allowed" msgid="843159705042381454">"מנהל המערכת שלך אינו מתיר שינוי זה"</string>
-    <string name="app_not_found" msgid="3429506115332341800">"לא נמצאה אפליקציה שתומכת בפעולה זו"</string>
+    <string name="app_not_found" msgid="3429506115332341800">"לא נמצאה אפליקציה שתומכת בפעולה הזו"</string>
     <string name="revoke" msgid="5526857743819590458">"ביטול"</string>
     <string name="mediasize_iso_a0" msgid="7039061159929977973">"ISO A0"</string>
     <string name="mediasize_iso_a1" msgid="4063589931031977223">"ISO A1"</string>
@@ -1828,15 +1840,15 @@
     <string name="reason_unknown" msgid="5599739807581133337">"לא ידוע"</string>
     <string name="reason_service_unavailable" msgid="5288405248063804713">"שירות ההדפסה לא הופעל"</string>
     <string name="print_service_installed_title" msgid="6134880817336942482">"שירות <xliff:g id="NAME">%s</xliff:g> מותקן"</string>
-    <string name="print_service_installed_message" msgid="7005672469916968131">"הקש כדי להפעיל"</string>
-    <string name="restr_pin_enter_admin_pin" msgid="1199419462726962697">"הזן את קוד הגישה של מנהל המכשיר"</string>
+    <string name="print_service_installed_message" msgid="7005672469916968131">"יש להקיש כדי להפעיל את השירות"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="1199419462726962697">"יש להזין את קוד האימות של מנהל המכשיר"</string>
     <string name="restr_pin_enter_pin" msgid="373139384161304555">"הזן קוד גישה"</string>
     <string name="restr_pin_incorrect" msgid="3861383632940852496">"שגוי"</string>
     <string name="restr_pin_enter_old_pin" msgid="7537079094090650967">"קוד גישה נוכחי"</string>
-    <string name="restr_pin_enter_new_pin" msgid="3267614461844565431">"קוד גישה חדש"</string>
+    <string name="restr_pin_enter_new_pin" msgid="3267614461844565431">"קוד אימות חדש"</string>
     <string name="restr_pin_confirm_pin" msgid="7143161971614944989">"אשר את קוד הגישה החדש"</string>
     <string name="restr_pin_create_pin" msgid="917067613896366033">"צור קוד גישה לשינוי הגבלות"</string>
-    <string name="restr_pin_error_doesnt_match" msgid="7063392698489280556">"קודי הגישה לא תואמים. נסה שוב."</string>
+    <string name="restr_pin_error_doesnt_match" msgid="7063392698489280556">"קודי האימות לא תואמים. יש לנסות שוב."</string>
     <string name="restr_pin_error_too_short" msgid="1547007808237941065">"קוד הגישה קצר מדי. חייב להיות באורך 4 ספרות לפחות."</string>
     <plurals name="restr_pin_countdown" formatted="false" msgid="4427486903285216153">
       <item quantity="two">נסה שוב בעוד <xliff:g id="COUNT">%d</xliff:g> שניות</item>
@@ -1844,17 +1856,17 @@
       <item quantity="other">נסה שוב בעוד <xliff:g id="COUNT">%d</xliff:g> שניות</item>
       <item quantity="one">נסה שוב בעוד שנייה אחת</item>
     </plurals>
-    <string name="restr_pin_try_later" msgid="5897719962541636727">"נסה שוב מאוחר יותר"</string>
+    <string name="restr_pin_try_later" msgid="5897719962541636727">"יש לנסות שוב מאוחר יותר"</string>
     <string name="immersive_cling_title" msgid="2307034298721541791">"צפייה במסך מלא"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"כדי לצאת, פשוט מחליקים אצבע מלמעלה למטה."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"הבנתי"</string>
-    <string name="done_label" msgid="7283767013231718521">"בוצע"</string>
+    <string name="done_label" msgid="7283767013231718521">"סיום"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"מחוון שעות מעגלי"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"מחוון דקות מעגלי"</string>
     <string name="select_hours" msgid="5982889657313147347">"בחר שעות"</string>
-    <string name="select_minutes" msgid="9157401137441014032">"בחר דקות"</string>
+    <string name="select_minutes" msgid="9157401137441014032">"בחירת דקות"</string>
     <string name="select_day" msgid="2060371240117403147">"בחר חודש ויום"</string>
-    <string name="select_year" msgid="1868350712095595393">"בחר שנה"</string>
+    <string name="select_year" msgid="1868350712095595393">"בחירת שנה"</string>
     <string name="deleted_key" msgid="9130083334943364001">"<xliff:g id="KEY">%1$s</xliff:g> נמחק"</string>
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"עבודה <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"<xliff:g id="LABEL">%1$s</xliff:g> שני בעבודה"</string>
@@ -2001,7 +2013,7 @@
     <string name="profile_encrypted_message" msgid="1128512616293157802">"הקש לביטול נעילת פרופיל העבודה"</string>
     <string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"מחובר אל <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"הקש כדי להציג קבצים"</string>
-    <string name="pin_target" msgid="8036028973110156895">"הצמד"</string>
+    <string name="pin_target" msgid="8036028973110156895">"הצמדה"</string>
     <string name="pin_specific_target" msgid="7824671240625957415">"הצמדה של‏ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="unpin_target" msgid="3963318576590204447">"בטל הצמדה"</string>
     <string name="unpin_specific_target" msgid="3859828252160908146">"ביטול ההצמדה של <xliff:g id="LABEL">%1$s</xliff:g>"</string>
@@ -2021,12 +2033,12 @@
     <string name="app_category_maps" msgid="6395725487922533156">"מפות וניווט"</string>
     <string name="app_category_productivity" msgid="1844422703029557883">"פרודוקטיביות"</string>
     <string name="app_category_accessibility" msgid="6643521607848547683">"נגישות"</string>
-    <string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"שטח האחסון במכשיר"</string>
+    <string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"נפח האחסון במכשיר"</string>
     <string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"‏ניקוי באגים ב-USB"</string>
     <string name="time_picker_hour_label" msgid="4208590187662336864">"שעה"</string>
     <string name="time_picker_minute_label" msgid="8307452311269824553">"דקה"</string>
     <string name="time_picker_header_text" msgid="9073802285051516688">"הגדרת שעה"</string>
-    <string name="time_picker_input_error" msgid="8386271930742451034">"הזן שעה חוקית"</string>
+    <string name="time_picker_input_error" msgid="8386271930742451034">"יש להזין שעה חוקית"</string>
     <string name="time_picker_prompt_label" msgid="303588544656363889">"מהי השעה הנכונה"</string>
     <string name="time_picker_text_input_mode_description" msgid="4761160667516611576">"העבר למצב קלט טקסט לצורך הזנת השעה"</string>
     <string name="time_picker_radial_mode_description" msgid="1222342577115016953">"העבר למצב שעון לצורך הזנת השעה"</string>
@@ -2066,7 +2078,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="5828171463387976279">"יש להתפנות מיידית מאזורים הסמוכים לחופים ולנהרות למקום בטוח יותר, כגון שטח גבוה יותר."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="4888224011071875068">"הישאר רגוע וחפש מחסה בקרבת מקום."</string>
     <string name="etws_primary_default_message_test" msgid="4583367373909549421">"בדיקה של הודעות חירום"</string>
-    <string name="notification_reply_button_accessibility" msgid="5235776156579456126">"השב"</string>
+    <string name="notification_reply_button_accessibility" msgid="5235776156579456126">"תשובה"</string>
     <string name="etws_primary_default_message_others" msgid="7958161706019130739"></string>
     <string name="mmcc_authentication_reject" msgid="4891965994643876369">"‏כרטיס ה-SIM לא מורשה לזיהוי קולי"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="227760698553988751">"‏ניהול התצורה של כרטיס ה-SIM לא מתאים לזיהוי קולי"</string>
@@ -2154,6 +2166,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"קיצור דרך לנגישות במסך"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"בורר קיצורי דרך לנגישות במסך"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"קיצור דרך לנגישות"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"סגירת לוח ההתראות"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"סרגל כיתוב של <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> התווספה לקטגוריה \'מוגבל\'"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2291,8 +2304,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"‏חדש: Window Magnifier"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"עכשיו אפשר להגדיל את המסך או חלקים ממנו"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"הגדלה של חלק מהמסך"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"עכשיו אפשר להגדיל את המסך המלא או אזור ספציפי במסך, או לעבור בין שתי האפשרויות."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"הפעלה בהגדרות"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"סגירה"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"‏כדי להמשיך, האפליקציה &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; צריכה גישה למיקרופון של המכשיר שלך."</string>
@@ -2301,4 +2314,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"פרטיות חיישנים"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"סמל האפליקציה"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"תדמית המותג של האפליקציה"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"בדיקה של הגדרות הגישה"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"לשירות <xliff:g id="SERVICE_NAME">%s</xliff:g> יהיו הרשאות לצפייה ולשליטה במסך. יש להקיש כדי לבדוק."</string>
 </resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index e7c3438..95a0f86 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"トワイライト サービス"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Time Zone Detector(未接続)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS 時間アップデートサービス"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"楽曲認識マネージャー サービス"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"デバイスのデータが消去されます"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"管理アプリを使用できません。デバイスのデータはこれから消去されます。\n\nご不明な点がある場合は、組織の管理者にお問い合わせください。"</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"「<xliff:g id="OWNER_APP">%s</xliff:g>」により印刷は無効にされています。"</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"実行中のアプリ"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"電池を消費しているアプリ"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"拡大"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"ユーザー補助機能に関するセキュリティ ポリシー"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」が電池を使用しています"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> 個のアプリが電池を使用しています"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"タップして電池やデータの使用量を確認"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"ステータスバーへの表示をアプリに許可します。"</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"ステータスバーの拡大/縮小"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"ステータスバーの展開/折りたたみをアプリに許可します。"</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"ロックされているデバイスにおける通知の全画面表示アクティビティとしての表示"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"ロックされているデバイスに通知を全画面表示のアクティビティとして表示することをアプリに許可します"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"ショートカットのインストール"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"ユーザー操作なしでホーム画面にショートカットを追加することをアプリに許可します。"</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"ショートカットのアンインストール"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"生体認証または画面ロックの使用"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"本人確認"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"続行するには生体認証を使用してください"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"続行するには、生体認証または画面ロックを使用してください"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"生体認証ハードウェアが利用できません"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"認証をキャンセルしました"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"認識されませんでした"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"指紋の使用"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"指紋または画面ロックの使用"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"続行するには指紋認証を使用してください"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"続行するには、指紋認証または画面ロックを使用してください"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"指紋アイコン"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"顔認証の使用"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"顔認証または画面ロックの使用"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"続行するには顔認証を使用してください"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"続行するには、顔認証または画面ロックを使用してください"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"顔アイコン"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"このページへのアクセスは許可されていません。"</string>
     <string name="text_copied" msgid="2531420577879738860">"テキストをクリップボードにコピーしました。"</string>
     <string name="copied" msgid="4675902854553014676">"コピーしました"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> から <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> に貼り付けました"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"クリップボードから <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> に貼り付けました"</string>
     <string name="more_item_label" msgid="7419249600215749115">"その他"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"MENU+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"OFF にする"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"<xliff:g id="NAME">%s</xliff:g>を確認しています…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"現在のコンテンツを確認しています"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"メディア ストレージを分析しています"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"新しい <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g>は動作していません"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"タップして設定してください"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"選択してセットアップしてください"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"デバイスの再フォーマットが必要になる場合があります。取り出すにはタップしてください。"</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"写真などのメディア転送用"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"メディア ファイルをブラウジングできます"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"<xliff:g id="NAME">%s</xliff:g>に関する問題"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g>は動作していません"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"タップして修正してください"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"対応していない<xliff:g id="NAME">%s</xliff:g>です"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g>は動作していません"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"このデバイスはこの <xliff:g id="NAME">%s</xliff:g>に対応していません。タップして、対応している形式でセットアップしてください。"</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"このデバイスはこの <xliff:g id="NAME">%s</xliff:g>に対応していません。サポートされるフォーマットで設定するには選択してください。"</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"<xliff:g id="NAME">%s</xliff:g>を選択して、対応している形式でセットアップしてください。"</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"デバイスの再フォーマットが必要になる場合があります"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g>が不適切に取り外されました"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"コンテンツの喪失を防ぐため、メディアを取り出してから取り外してください"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ショートカットを使用"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"色反転"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"色補正"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"明るさを下げる"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"さらに輝度を下げる"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"音量ボタンを長押ししました。<xliff:g id="SERVICE_NAME">%1$s</xliff:g> が ON になりました。"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"音量ボタンを長押ししました。<xliff:g id="SERVICE_NAME">%1$s</xliff:g> が OFF になりました。"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> を使用するには、音量大と音量小の両方のボタンを 3 秒間長押ししてください"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"画面上のユーザー補助機能のショートカット"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"画面上のユーザー補助機能のショートカットの選択メニュー"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"ユーザー補助機能のショートカット"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"通知シェードを閉じる"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<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> は RESTRICTED バケットに移動しました。"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"新機能: Window Magnifier"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"画面の一部または全体を拡大できるようになりました"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"画面の一部を拡大できます"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"画面全体または一部を拡大したり、画面全体と一部の拡大を切り替えたりできるようになりました。"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"[設定] で ON にする"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"閉じる"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"続行するには、&lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; にデバイスのマイクへのアクセスを許可する必要があります。"</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"センサー プライバシー"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"アプリのアイコン"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"アプリのブランド イメージ"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"アクセス設定の確認"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> は画面を参照、操作できます。タップしてご確認ください。"</string>
 </resources>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 3fb6c69..4f27b37 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Twilight სერვისი"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"სასაათო სარტყლის დეტექტორი (კავშირის გარეშე)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS დროის განახლების სერვისი"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"მუსიკის ამოცნობის მმართველის სერვისი"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"თქვენი მოწყობილობა წაიშლება"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"ადმინისტრატორის აპის გამოყენება ვერ მოხერხდება. თქვენი მოწყობილობა ახლა ამოიშლება.\n\nთუ შეკითხვები გაქვთ, დაუკავშირდით თქვენი ორგანიზაციის ადმინისტრატორს."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"ბეჭდვა გათიშულია <xliff:g id="OWNER_APP">%s</xliff:g>-ის მიერ."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"აპი გაშვებულია"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"ბატარეის მხარჯავი აპები"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"გადიდება"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"მარტივი წვდომის უსაფრთხოების წესები"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> იყენებს ბატარეას"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"ბატარეას <xliff:g id="NUMBER">%1$d</xliff:g> აპი იყენებს"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"შეეხეთ ბატარეისა და მონაცემების მოხმარების შესახებ დეტალური ინფორმაციისთვის"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"აპს შეეძლება სტატუსის ზოლის ჩანაცვლება."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"სტატუსების ზოლის გაფართოება/აკეცვა"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"აპს შეეძლება სტატუსის ზოლის გახსნა-დახურვა."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"შეტყობინებების ჩვენება სრული ეკრანის აქტივობების სახით ჩაკეტილ მოწყობილობაზე"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"ნებას რთავს აპს, აჩვენოს შეტყობინებები სრული ეკრანის აქტივობების სახით ჩაკეტილ მოწყობილობაზე"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"მალსახმობების დაყენება"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"მთავარ ეკრანზე აპლიკაციისთვის მალსახმობების დამოუკიდებლად დამატების უფლების მიცემა."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"მალსახმობების წაშლა"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"გამოიყენეთ ბიომეტრიული სისტემა ან ეკრანის დაბლოკვა"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"დაადასტურეთ ვინაობა"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"გასაგრძელებლად გამოიყენეთ თქვენი ბიომეტრიული მონაცემები"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"გასაგრძელებლად გამოიყენეთ თქვენი ბიომეტრიული მონაცემები ან ეკრანის განბლოკვის ნიმუში"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"ბიომეტრიული აპარატურა მიუწვდომელია"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"ავტორიზაცია გაუქმდა"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"არ არის ამოცნობილი"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"გამოიყენეთ თითის ანაბეჭდი"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"გამოიყენეთ თითის ანაბეჭდი ან ეკრანის დაბლოკვა"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"გასაგრძელებლად გამოიყენეთ თქვენი თითის ანაბეჭდი"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"გასაგრძელებლად გამოიყენეთ თქვენი თითის ანაბეჭდი ან ეკრანის განბლოკვის ნიმუში"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"თითის ანაბეჭდის ხატულა"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"გამოიყენეთ სახით განბლოკვა"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"გამოიყენეთ სახე ან ეკრანის დაბლოკვა"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"გასაგრძელებლად გამოიყენეთ სახით განბლოკვა"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"გასაგრძელებლად გამოიყენეთ თქვენი სახე ან ეკრანის განბლოკვის ნიმუში"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"სახის ხატულა"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"ამ გვერდის გახსნის უფლება არ გაქვთ."</string>
     <string name="text_copied" msgid="2531420577879738860">"ტექსტი დაკოპირებულია გაცვლის ბუფერში."</string>
     <string name="copied" msgid="4675902854553014676">"დაკოპირდა"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>-დან <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>-ში ჩასმული"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>-მა ჩასვა გაცვლის ბუფერიდან"</string>
     <string name="more_item_label" msgid="7419249600215749115">"დამატებით"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"მენიუ+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"გამორთვა"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"მიმდინარეობს <xliff:g id="NAME">%s</xliff:g>-ის შემოწმება…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"მიმდინარეობს ამჟამინდელი კონტენტის შემოწმება"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"მიმდინარეობს მედიასაცავის ანალიზი"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"ახალი <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> არ მუშაობს"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"შეეხეთ დასაყენებლად"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"დასაყენებლად აირჩიეთ"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"შეიძლება მოწყობილობის რეფორმატირება დაგჭირდეთ. შეეხეთ ამოსაღებად."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"ფოტოებისა და მედიის გადასატანად"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"მედიაფაილების დათვალიერება"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"პრობლემა <xliff:g id="NAME">%s</xliff:g>-თან მიმართებით"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> არ მუშაობს"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"შეეხეთ გამოსასწორებლად"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"მხარდაუჭერელი <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> არ მუშაობს"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"ეს <xliff:g id="NAME">%s</xliff:g> მხარდაუჭერელია არ მოწყობილობაზე. შეეხეთ მხარდაჭერილ ფორმატში დასაყენებლად."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"ეს <xliff:g id="NAME">%s</xliff:g> მხარდაუჭერელია ამ მოწყობილობაზე. შეეხეთ მხარდაჭერილ ფორმატში დასაყენებლად."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"აირჩიეთ, რათა დააყენოთ <xliff:g id="NAME">%s</xliff:g> მხარდაჭერილ ფორმატში."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"შეიძლება მოწყობილობის რეფორმატირება დაგჭირდეთ"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"მოულოდნელად მოხდა <xliff:g id="NAME">%s</xliff:g>-ის ამოღება"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"გაწყვიტეთ მედია-მოწყობილობასთან კავშირი მის ამოშლამდე, კონტენტის დაკარგვის ასაცილებლად"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"მალსახმობის გამოყენება"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"ფერთა ინვერსია"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"ფერთა კორექცია"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"სიკაშკაშის შემცირება"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"დამატებითი დაბნელება"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ხანგრძლივად დააჭირეთ ხმის ღილაკებს. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ჩართულია."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ხანგრძლივად დააჭირეთ ხმის ღილაკებს. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> გამორთულია."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> რომ გამოიყენოთ, დააჭირეთ ხმის ორივე ღილაკზე 3 წამის განმავლობაში"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"მისაწვდომობის ეკრანული მალსახმობი"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"მისაწვდომობის ეკრანული მალსახმობის ამომრჩევი"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"მისაწვდომობის მალსახმობი"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"შეტყობინებების ფარდის დახურვა"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<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> მოთავსდა კალათაში „შეზღუდული“"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"სიახლე: ფანჯრის გამადიდებელი"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"ახლა შეგიძლიათ, გაადიდოთ ეკრანი ან მისი ნაწილი"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"გაადიდეთ თქვენი ეკრანის ნაწილი"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"თქვენ უკვე შეგიძლიათ გაადიდოთ სრული ეკრანი, მისი გარკვეული ნაწილი, ან მონაცვლეობით გადართოთ ამ ორ ვარიანტს შორის."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"ჩართვა პარამეტრებში"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"უარყოფა"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"გასაგრძელებლად &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt;-ს თქვენი მოწყობილობის მიკროფონზე წვდომა სჭირდება."</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"სენსორის კონფიდენციალურობა"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"აპლიკაციის ხატულა"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"აპლიკაციის ბრენდის სურათი"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"სწრაფი წვდომის პარამეტრები"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g>-ს შეუძლია თქვენი ეკრანის ნახვა და მართვა. შეეხეთ გადასახედად."</string>
 </resources>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 4404603..df1bbeb 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Twilight қызметі"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Уақыт белдеуін анықтағыш (қосылу мүмкіндігі жоқ)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS уақыт жаңарту жүйесі"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Музыканы анықтау менеджері қызметі"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Құрылғыңыздағы деректер өшіріледі"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Әкімші қолданбасын пайдалану мүмкін емес. Қазір құрылғыдағы деректер өшіріледі\n\nСұрақтарыңыз болса, ұйым әкімшісіне хабарласыңыз."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Басып шығаруды <xliff:g id="OWNER_APP">%s</xliff:g> өшірді."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Қолданба қосулы"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Батареяны пайдаланып жатқан қолданбалар"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Ұлғайту"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Арнайы мүмкіндіктер қауіпсіздігі саясаты"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> батареяны пайдалануда"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> қолданба батареяны пайдалануда"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Батарея мен деректер трафигі туралы білу үшін түртіңіз"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Қолданбаға күй жолағы болуға рұқсат береді."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"күйі жолағын кеңейту/жиыру"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Қолданбаға статус жолағын жаюға емесе тасалауға рұқсат береді."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"құлыпталған құрылғыда хабарландыруларды толық экрандағы әрекеттер түрінде көрсету"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Қолданбаның құлыпталған құрылғыда хабарландыруларды толық экрандағы әрекеттер түрінде көрсетуіне рұқсат береді."</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"төте пернелерді орнату"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Қолданбаға Негізгі экранның төте пернелерін пайдаланушының қатысуынсыз қосу мүмкіндігін береді."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"төте пернелерді алып тастау"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Биометриканы немесе экран құлпын пайдалану"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Бұл сіз екеніңізді растаңыз"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Жалғастыру үшін биометрикаңызды пайдаланыңыз."</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Жалғастыру үшін биометриканы немесе экран құлпын пайдаланыңыз."</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Биометрикалық жабдық жоқ"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Аутентификациядан бас тартылды."</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Танылмады"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Саусақ ізін пайдалану"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Саусақ ізін немесе экран құлпын пайдалану"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Жалғастыру үшін саусақ ізін пайдаланыңыз."</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Жалғастыру үшін саусақ ізін немесе экран құлпын пайдаланыңыз."</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Саусақ ізі белгішесі"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Face Unlock функциясын пайдалану"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Face Lock функциясын немесе экран құлпын пайдалану"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Жалғастыру үшін Face Unlock функциясын пайдаланыңыз."</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Жалғастыру үшін бетті анықтау функциясын немесе экран құлпын пайдаланыңыз."</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Бет белгішесі"</string>
@@ -691,7 +698,7 @@
     <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="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>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"Сізде осы бетті ашуға рұқсат жоқ."</string>
     <string name="text_copied" msgid="2531420577879738860">"Мәтін ақпарат алмастыру қорына сақталды."</string>
     <string name="copied" msgid="4675902854553014676">"Көшірілді"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> қолданбасынан <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> қолданбасына қойылды."</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"Буферден <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> қолданбасына қойылды."</string>
     <string name="more_item_label" msgid="7419249600215749115">"Көбірек"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Mәзір+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Өшіру"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"<xliff:g id="NAME">%s</xliff:g> тексеріліп жатыр…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Ағымдағы мазмұн тексерілуде"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Мультимедиа жады талдануда"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Жаңа <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> жұмыс істемейді"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Реттеу үшін түртіңіз"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Реттеу үшін таңдаңыз."</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Құрылғыны қайта форматтау қажет болуы мүмкін. Шығару үшін түртіңіз."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"Фотосуреттер мен медиа файлдарын тасымалдау үшін"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Медиа файлдарды таңдаңыз."</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"<xliff:g id="NAME">%s</xliff:g> ақаулы"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> жұмыс істемейді"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Түзету үшін түртіңіз"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"Қолданылмайтын <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> жұмыс істемейді"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"Бұл құрылғы <xliff:g id="NAME">%s</xliff:g> картасына қолдау көрсетеді. Қолдау көрсетілетін пішімде орнату үшін түртіңіз."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"Бұл құрылғыда <xliff:g id="NAME">%s</xliff:g> картасына қолдау көрсетілмейді. Қолдау көрсетілетін форматта реттеуді таңдаңыз."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"<xliff:g id="NAME">%s</xliff:g> құрылғысын қолдау көрсетілетін форматта реттеу үшін таңдаңыз."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Құрылғыны қайта форматтау қажет болуы мүмкін."</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> кенеттен шығарылды"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Мазмұнды жоғалтып алмау үшін ақпарат тасығышты алдымен ажыратыңыз, содан кейін барып шығарыңыз."</string>
@@ -1645,7 +1657,7 @@
     <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4670840383567106114">"Құлыпты ашу өрнегін <xliff:g id="NUMBER_0">%1$d</xliff:g> рет дұрыс сызбадыңыз. Енді тағы <xliff:g id="NUMBER_1">%2$d</xliff:g> рет қателессеңіз, Android TV құрылғыңыздың құлпын ашу үшін есептік жазбаңызға кіру керек болады.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секундтан кейін қайталап көріңіз."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Бекітпені ашу кескінін <xliff:g id="NUMBER_0">%1$d</xliff:g> рет қате сыздыңыз. <xliff:g id="NUMBER_1">%2$d</xliff:g> сәтсіз әрекеттен кейін телефоныңызды есептік жазба арқылы ашу өтінішін аласыз. \n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секундтан кейін қайта әрекеттеніңіз."</string>
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
-    <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Алып тастау"</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Жою"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Дыбыс деңгейін ұсынылған деңгейден көтеру керек пе?\n\nЖоғары дыбыс деңгейінде ұзақ кезеңдер бойы тыңдау есту қабілетіңізге зиян тигізуі мүмкін."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Арнайы мүмкіндік төте жолын пайдалану керек пе?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Түймелер тіркесімі қосулы кезде, екі дыбыс түймесін 3 секунд басып тұрсаңыз, \"Арнайы мүмкіндіктер\" функциясы іске қосылады."</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Төте жолды пайдалану"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Түстер инверсиясы"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Түсті түзету"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Жарықтығын азайту"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Аса күңгірт"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Пайдаланушы дыбыс деңгейі пернелерін басып ұстап тұрды. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> қосулы."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Дыбыс деңгейі пернелерін басып тұрған соң, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> өшірілді."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> қызметін пайдалану үшін дыбыс деңгейін реттейтін екі түймені де 3 секунд басып тұрыңыз"</string>
@@ -1689,7 +1701,7 @@
     <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Бір функциядан екінші функцияға ауысу үшін үш саусақпен жоғары қарай сырғытып, ұстап тұрыңыз."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ұлғайту"</string>
     <string name="user_switched" msgid="7249833311585228097">"Ағымдағы пайдаланушы <xliff:g id="NAME">%1$s</xliff:g>."</string>
-    <string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> ауысу орындалуда…"</string>
+    <string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> профиліне ауысу…"</string>
     <string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> ішінен шығу…"</string>
     <string name="owner_name" msgid="8713560351570795743">"Құрылғы иесі"</string>
     <string name="error_message_title" msgid="4082495589294631966">"Қателік"</string>
@@ -1861,7 +1873,7 @@
     <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_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>
@@ -2025,10 +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="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_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>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Экрандағы арнайы мүмкіндіктерді жылдам қосу"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Экрандағы арнайы мүмкіндіктерді жылдам қосу әрекетін таңдау"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Арнайы мүмкіндіктерді жылдам қосу"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Хабарландыру тақтасын жабу"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<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> ШЕКТЕЛГЕН себетке салынды."</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Жаңа: Window Magnifier"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Енді экранның бір бөлігін не барлығын ұлғайта аласыз."</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Экран бөлігін ұлғайтыңыз"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Енді толық экранды не оның бір бөлігін ұлғайтуға немесе осы опцияларды алма-кезек қолдануға болады."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Параметрлер бөлімінен қосу"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Қабылдамау"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Жалғастыру үшін &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; қолданбасы құрылғыңыздың микрофонына рұқсат алу керек."</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Датчикке қатысты құпиялылық"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Қолданба белгішесі"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Қолданба брендін ілгері жылжыту кескіні"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Пайдалану параметрлерін тексеріңіз"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> қызметі экраныңызды көріп, бақылай алады. Көру үшін түртіңіз."</string>
 </resources>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index fb11553..e8f45bc 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"សេវាកម្ម​ព្រលប់"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"ឧបករណ៍សម្គាល់​ល្វែងម៉ោង (គ្មានការតភ្ជាប់ទេ)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"សេវាកម្ម​ធ្វើបច្ចុប្បន្នភាព​ពេលវេលា GNSS"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"សេវាកម្មគ្រប់គ្រងការសម្គាល់តន្ត្រី"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"ឧបករណ៍របស់អ្នកនឹងត្រូវបានលុប"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"មិនអាច​ប្រើ​កម្មវិធី​អ្នកគ្រប់គ្រង​បានទេ។ ឧបករណ៍​របស់អ្នក​នឹងលុប​ឥឡូវនេះ។\n\nប្រសិនបើ​អ្នកមាន​សំណួរផ្សេងៗ​ សូមទាក់ទង​ទៅអ្នក​គ្រប់គ្រង​ស្ថាប័ន​របស់​អ្នក។"</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"ការបោះពុម្ព​ត្រូវបាន​បិទ​ដោយ <xliff:g id="OWNER_APP">%s</xliff:g> ។"</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"កម្មវិធី​ដែល​កំពុង​ដំណើរការ"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"កម្មវិធីដែល​កំពុងប្រើថ្ម"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"ការពង្រីក"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"គោលការណ៍​ស្ដីពី​សុវត្ថិភាព​នៃភាពងាយស្រួល"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> កំពុងប្រើថ្ម"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"កម្មវិធីចំនួន <xliff:g id="NUMBER">%1$d</xliff:g> កំពុងប្រើថ្ម"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"ចុចដើម្បីមើលព័ត៌មានលម្អិតអំពីការប្រើប្រាស់ទិន្នន័យ និងថ្ម"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"ឲ្យ​កម្មវិធី​ក្លាយ​ជា​របារ​ស្ថានភាព។"</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"ពង្រីក/បង្រួម​របារ​ស្ថាន​ភាព"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"ឲ្យ​កម្មវិធី​ពង្រីក ឬ​បង្រួម​របារ​ស្ថានភាព។"</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"បង្ហាញការជូនដំណឹងជាសកម្មភាព​អេក្រង់ពេញ​នៅលើឧបករណ៍ជាប់សោ"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"អនុញ្ញាតឱ្យ​កម្មវិធីបង្ហាញ​ការជូនដំណឹងជាសកម្មភាព​អេក្រង់ពេញ​នៅលើឧបករណ៍​ជាប់សោ"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"ដំឡើង​ផ្លូវកាត់"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"អនុញ្ញាត​ឲ្យ​កម្មវិធី​បន្ថែម​ផ្លូវកាត់​អេក្រង់​ដើម​ ដោយ​គ្មាន​​​អំពើ​ពី​អ្នក​ប្រើ។"</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"លុប​ផ្លូវកាត់"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"ប្រើជីវមាត្រ ឬ​ការចាក់សោអេក្រង់"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"ផ្ទៀងផ្ទាត់ថាជាអ្នក"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"ប្រើជីវមាត្រ​របស់អ្នក ដើម្បីបន្ត"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"ប្រើការចាក់សោអេក្រង់ ឬជីវមាត្ររបស់អ្នក ដើម្បីបន្ត"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"មិនអាច​ប្រើឧបករណ៍​ស្កេន​ស្នាមម្រាមដៃ​បានទេ"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"បាន​បោះបង់​ការ​ផ្ទៀងផ្ទាត់"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"មិនអាចសម្គាល់បានទេ"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ប្រើស្នាមម្រាមដៃ"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ប្រើស្នាមម្រាមដៃ ឬ​ការចាក់សោអេក្រង់"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"ប្រើ​ស្នាមម្រាមដៃ​របស់អ្នក ដើម្បីបន្ត"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"ប្រើការចាក់សោអេក្រង់ ឬស្នាមម្រាមដៃរបស់អ្នក ដើម្បីបន្ត"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"រូបស្នាមម្រាមដៃ"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"ប្រើការដោះសោ​តាមទម្រង់មុខ"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"ប្រើមុខ ឬ​ការចាក់សោអេក្រង់"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"ប្រើការដោះសោ​តាមទម្រង់មុខ ដើម្បីបន្ត"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"ប្រើការចាក់សោអេក្រង់ ឬមុខរបស់អ្នក ដើម្បីបន្ត"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"រូប​ផ្ទៃមុខ"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"អ្នក​មិន​មាន​សិទ្ធិ ដើម្បី​បើក​ទំព័រ​នេះ។"</string>
     <string name="text_copied" msgid="2531420577879738860">"បាន​ចម្លង​អត្ថបទ​ទៅ​ក្ដារ​តម្បៀត​ខ្ទាស់។"</string>
     <string name="copied" msgid="4675902854553014676">"បា​នចម្លង"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> បានដាក់ចូលពី <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> បានដាក់ចូលពីឃ្លីបបត"</string>
     <string name="more_item_label" msgid="7419249600215749115">"ច្រើន​ទៀត"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"ម៉ឺនុយ +"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"បិទ"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"កំពុង​ពិនិត្យ <xliff:g id="NAME">%s</xliff:g>…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"កំពុង​ពិនិត្យ​​មើលខ្លឹមសារ​បច្ចុប្បន្ន"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"កំពុងវិភាគទំហំ​ផ្ទុកមេឌៀ"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"<xliff:g id="NAME">%s</xliff:g> ថ្មី"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> មិនដំណើរការទេ"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"ចុច​ដើម្បី​រៀបចំ"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"ជ្រើសរើសដើម្បីរៀបចំ"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"អ្នកប្រហែលជាត្រូវសម្អាតឧបករណ៍ឡើងវិញ។ សូមចុច ដើម្បីដកចេញ។"</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"សម្រាប់ផ្ទេររូបភាព និងមេឌៀ"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"រុករក​ឯកសារមេឌៀ"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"មាន​បញ្ហា​ជាមួយ <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> មិនដំណើរការទេ"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"ចុចដើម្បីកែបញ្ហា"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"<xliff:g id="NAME">%s</xliff:g> មិនគាំទ្រ"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> មិនដំណើរការទេ"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"ឧបករណ៍នេះមិនគាំទ្រ <xliff:g id="NAME">%s</xliff:g> នេះទេ។ ប៉ះដើម្បីកំណត់ទម្រង់ដែលគាំទ្រ។"</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"ឧបករណ៍នេះ​មិន​ស្គាល់ <xliff:g id="NAME">%s</xliff:g> នេះ​ទេ។ សូម​ជ្រើសរើស​ដើម្បី​រៀបចំ​ក្នុង​ទម្រង់ដែលស្គាល់។"</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"ជ្រើសរើសដើម្បីរៀបចំ <xliff:g id="NAME">%s</xliff:g> ក្នុងទម្រង់ដែលអាចប្រើបាន។"</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"អ្នកប្រហែលជាត្រូវសម្អាតឧបករណ៍ឡើងវិញ"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"បានដក <xliff:g id="NAME">%s</xliff:g> ចេញដោយមិនបានរំពឹងទុក"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"ដក​មេឌៀ​មុន​ពេល​យក​វា​ចេញ ដើម្បី​ជៀសវាង​ការ​បាត់​បង់​ខ្លឹមសារ"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ប្រើប្រាស់​ផ្លូវកាត់"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"បញ្ច្រាស​ពណ៌"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"ការ​កែ​ពណ៌"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"បន្ថយ​ពន្លឺ"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"ពន្លឺតិចខ្លាំង"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"បានសង្កត់​គ្រាប់ចុច​កម្រិតសំឡេង​ជាប់។ បាន​បើក <xliff:g id="SERVICE_NAME">%1$s</xliff:g>។"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"បានសង្កត់​គ្រាប់ចុច​កម្រិតសំឡេង​ជាប់។ បាន​បិទ <xliff:g id="SERVICE_NAME">%1$s</xliff:g>។"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"ចុចគ្រាប់ចុច​កម្រិត​សំឡេងទាំងពីរ​ឱ្យជាប់រយៈពេលបីវិនាទី ដើម្បីប្រើ <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"ផ្លូវកាត់​ភាពងាយស្រួល​នៅលើអេក្រង់"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"ម៉ឺនុយជ្រើសរើស​ផ្លូវកាត់ភាពងាយស្រួល​នៅលើអេក្រង់"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"ផ្លូវកាត់​ភាពងាយស្រួល"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"ច្រានចោល​ផ្ទាំងជូនដំណឹង"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"របារពណ៌នា​អំពី <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> ត្រូវបានដាក់​ទៅក្នុងធុង​ដែលបានដាក់កំហិត"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>៖"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"ថ្មី៖ កម្មវិធីពង្រីក​វិនដូ"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"ឥឡូវនេះ អ្នកអាចពង្រីកផ្នែកខ្លះ ឬទាំងអស់នៃអេក្រង់របស់អ្នក"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"ពង្រីកផ្នែកនៃ​អេក្រង់របស់អ្នក"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"ឥឡូវនេះ អ្នកអាចពង្រីក​អេក្រង់ពេញរបស់អ្នក តំបន់ជាក់លាក់ ឬប្ដូររវាងជម្រើសទាំងពីរ។"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"បើកនៅក្នុងការកំណត់"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"ច្រានចោល"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"ដើម្បីបន្ត &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ត្រូវការសិទ្ធិចូលប្រើ​មីក្រូហ្វូន​របស់ឧបករណ៍អ្នក។"</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"ឯកជនភាព​ឧបករណ៍​ចាប់សញ្ញា"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"រូប​កម្មវិធី"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"រូបភាព​ផ្សព្វផ្សាយម៉ាក​កម្មវិធី"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"ពិនិត្យមើល​ការកំណត់​សិទ្ធិចូលប្រើ"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> អាច​មើល និង​គ្រប់គ្រង​អេក្រង់​របស់អ្នក​បាន។ សូមចុច ដើម្បី​ពិនិត្យមើល។"</string>
 </resources>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index f484344d..cfa6cf8 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"ಟ್ವಿಲೈಟ್ ಸೇವೆ"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"ಸಮಯವಲಯ  ಡಿಟೆಕ್ಟರ್ (ಯಾವುದೇ ಸಂಪರ್ಕ ಕಲ್ಪಿಸುವಿಕೆ ಇಲ್ಲ)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS ಸಮಯದ ಅಪ್‌ಡೇಟ್ ಸೇವೆ"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"ಸಂಗೀತ ಗುರುತಿಸುವಿಕೆ ನಿರ್ವಾಹಕ ಸೇವೆ"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"ನಿಮ್ಮ ಸಾಧನವನ್ನು ಅಳಿಸಲಾಗುತ್ತದೆ"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"ನಿರ್ವಹಣೆ ಅಪ್ಲಿಕೇಶನ್ ಬಳಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ನಿಮ್ಮ ಸಾಧನವನ್ನು ಇದೀಗ ಅಳಿಸಲಾಗುತ್ತದೆ.\n\nನಿಮ್ಮಲ್ಲಿ ಪ್ರಶ್ನೆಗಳಿದ್ದರೆ, ನಿಮ್ಮ ಸಂಸ್ಥೆಯ ನಿರ್ವಾಹಕರನ್ನು ಸಂಪರ್ಕಿಸಿ."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> ಮೂಲಕ ಪ್ರಿಂಟಿಂಗ್ ಅನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"App ರನ್ ಆಗುತ್ತಿದೆ"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ಬ್ಯಾಟರಿಯನ್ನು ಉಪಯೋಗಿಸುತ್ತಿವೆ"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"ಹಿಗ್ಗಿಸುವಿಕೆ"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"ಪ್ರವೇಶಿಸುವಿಕೆ ಭದ್ರತಾ ನೀತಿ"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಆ್ಯಪ್, ಬ್ಯಾಟರಿಯನ್ನು ಬಳಸುತ್ತಿದೆ"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ಬ್ಯಾಟರಿ ಬಳಸುತ್ತಿವೆ"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"ಬ್ಯಾಟರಿ,ಡೇಟಾ ಬಳಕೆಯ ವಿವರಗಳಿಗಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ಸ್ಥಿತಿ ಪಟ್ಟಿಯಾಗಿ ಅನುಮತಿಸುತ್ತದೆ."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"ಸ್ಥಿತಿ ಪಟ್ಟಿಯನ್ನು ವಿಸ್ತರಿಸಿ/ಸಂಕುಚಿಸಿ"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"ಸ್ಥಿತಿ ಪಟ್ಟಿಯನ್ನು ವಿಸ್ತರಿಸಲು ಅಥವಾ ಸಂಕುಚಿಸಲು ಅಪ್ಲಿಕೇಶನ್‌‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"ಲಾಕ್ ಮಾಡಲಾದ ಸಾಧನದಲ್ಲಿ ಅಧಿಸೂಚನೆಗಳನ್ನು ಪೂರ್ಣ-ಸ್ಕ್ರೀನ್ ಚಟುವಟಿಕೆ ರೀತಿಯಲ್ಲಿ ಡಿಸ್‌ಪ್ಲೇ ಮಾಡಿ"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"ಲಾಕ್ ಮಾಡಲಾದ ಸಾಧನದಲ್ಲಿ ಅಧಿಸೂಚನೆಗಳನ್ನು ಪೂರ್ಣ-ಸ್ಕ್ರೀನ್ ಚಟುವಟಿಕೆ ರೀತಿಯಲ್ಲಿ ಡಿಸ್‌ಪ್ಲೇ ಮಾಡಲು ಆ್ಯಪ್‌ಗೆ ಅನುಮತಿಸಿ"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"ಶಾರ್ಟ್‌ಕಟ್‌ಗಳನ್ನು ಸ್ಥಾಪಿಸಿ"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"ಬಳಕೆದಾರರ ಮಧ್ಯಸ್ಥಿಕೆ ಇಲ್ಲದೆಯೇ ಹೋಮ್‌ಸ್ಕ್ರೀನ್ ಶಾರ್ಟ್‌ಕಟ್‌ಗಳನ್ನು ಸೇರಿಸಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅವಕಾಶ ಮಾಡಿಕೊಡುತ್ತದೆ."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"ಶಾರ್ಟ್‌ಕಟ್‌ಗಳನ್ನು ಅನ್‌ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಿ"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"ಬಯೋಮೆಟ್ರಿಕ್ಸ್ ಅಥವಾ ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಅನ್ನು ಬಳಸಿ"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"ಇದು ನೀವೇ ಎಂದು ಪರಿಶೀಲಿಸಿ"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"ಮುಂದುವರಿಸಲು ನಿಮ್ಮ ಬಯೋಮೆಟ್ರಿಕ್ ಬಳಸಿ"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"ಮುಂದುವರಿಸಲು ನಿಮ್ಮ ಬಯೋಮೆಟ್ರಿಕ್ ಅಥವಾ ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಅನ್ನು ಬಳಸಿ"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"ಬಯೋಮೆಟ್ರಿಕ್ ಹಾರ್ಡ್‌ವೇರ್‌ ಲಭ್ಯವಿಲ್ಲ"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"ಪ್ರಮಾಣೀಕರಣವನ್ನು ರದ್ದುಗೊಳಿಸಲಾಗಿದೆ"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"ಗುರುತಿಸಲಾಗಿಲ್ಲ"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ಫಿಂಗರ್ ಪ್ರಿಂಟ್ ಬಳಸಿ"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ಫಿಂಗರ್‌ ಪ್ರಿಂಟ್ ಅಥವಾ ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಬಳಸಿ"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"ಮುಂದುವರಿಸಲು ನಿಮ್ಮ ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಬಳಸಿ"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"ಮುಂದುವರಿಸಲು ಫಿಂಗರ್ ಪ್ರಿಂಟ್ ಅಥವಾ ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಅನ್ನು ಬಳಸಿ"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಐಕಾನ್"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"ಫೇಸ್ ಅನ್‌ಲಾಕ್ ಅನ್ನು ಬಳಸಿ‌‌"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"ಫೇಸ್ ಅಥವಾ ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಅನ್ನು ಬಳಸಿ"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"ಮುಂದುವರಿಸಲು ಫೇಸ್ ಅನ್‌ಲಾಕ್ ಅನ್ನು ಬಳಸಿ"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"ಮುಂದುವರಿಸಲು ನಿಮ್ಮ ಮುಖ ಅಥವಾ ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಅನ್ನು ಬಳಸಿ"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"ಮುಖದ ಐಕಾನ್‌"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"ಈ ಪುಟವನ್ನು ತೆರೆಯಲು ನೀವು ಅನುಮತಿಯನ್ನು ಹೊಂದಿಲ್ಲ."</string>
     <string name="text_copied" msgid="2531420577879738860">"ಪಠ್ಯವನ್ನು ಕ್ಲಿಪ್‌ಬೋರ್ಡ್‌ಗೆ ನಕಲಿಸಲಾಗಿದೆ."</string>
     <string name="copied" msgid="4675902854553014676">"ನಕಲಿಸಲಾಗಿದೆ"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ಅನ್ನು <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> ನಿಂದ ಅಂಟಿಸಲಾಗಿದೆ"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ಅನ್ನು ಕ್ಲಿಪ್‌ಬೋರ್ಡ್‌ನಿಂದ ಅಂಟಿಸಲಾಗಿದೆ"</string>
     <string name="more_item_label" msgid="7419249600215749115">"ಇನ್ನಷ್ಟು"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"ಮೆನು+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"ಆಫ್ ಮಾಡಿ"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"<xliff:g id="NAME">%s</xliff:g> ಅನ್ನು ಪರಿಶೀಲಿಸಲಾಗುತ್ತಿದೆ…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"ಪ್ರಸ್ತುತ ವಿಷಯವನ್ನು ಪರಿಶೀಲಿಸಲಾಗುತ್ತಿದೆ"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"ಮೀಡಿಯಾ ಸಂಗ್ರಹಣೆಯನ್ನು ವಿಶ್ಲೇಷಿಸಲಾಗುತ್ತಿದೆ"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"ಹೊಸ <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತಿಲ್ಲ"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"ಹೊಂದಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"ಸೆಟಪ್ ಮಾಡಲು ಆಯ್ಕೆಮಾಡಿ"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"ನೀವು ಸಾಧನವನ್ನು ಮರು ಫಾರ್ಮ್ಯಾಟ್ ಮಾಡಬೇಕಾಗಬಹುದು. ಎಜೆಕ್ಟ್ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"ಫೋಟೋಗಳು ಮತ್ತು ಮಾಧ್ಯಮವನ್ನು ವರ್ಗಾಯಿಸಲು"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"ಮೀಡಿಯಾ ಫೈಲ್‌ಗಳನ್ನು ಬ್ರೌಸ್ ಮಾಡಿ"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"<xliff:g id="NAME">%s</xliff:g> ನೊಂದಿಗೆ ಸಮಸ್ಯೆ"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತಿಲ್ಲ"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"ಸರಿಪಡಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"ಬೆಂಬಲಿಸದಿರುವ <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತಿಲ್ಲ"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"ಈ ಸಾಧನವು <xliff:g id="NAME">%s</xliff:g> ಅನ್ನು ಬೆಂಬಲಿಸುವುದಿಲ್ಲ. ಬೆಂಬಲಿತ ಫಾರ್ಮ್ಯಾಟ್‌‌ನಲ್ಲಿ ಹೊಂದಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"ಈ ಸಾಧನವು ಈ <xliff:g id="NAME">%s</xliff:g> ಅನ್ನು ಬೆಂಬಲಿಸುವುದಿಲ್ಲ. ಬೆಂಬಲಿತ ಫಾರ್ಮ್ಯಾಟ್‌‌ನಲ್ಲಿ ಹೊಂದಿಸಲು ಆಯ್ಕೆ ಮಾಡಿ."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"ಬೆಂಬಲಿಸಲಾಗುವ ಫಾರ್ಮ್ಯಾಟ್‌ನಲ್ಲಿ <xliff:g id="NAME">%s</xliff:g> ಅನ್ನು ಸೆಟಪ್ ಮಾಡಲು ಆಯ್ಕೆಮಾಡಿ."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"ನೀವು ಸಾಧನವನ್ನು ಮರು ಫಾರ್ಮ್ಯಾಟ್ ಮಾಡಬೇಕಾಗಬಹುದು"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> ಅನಿರೀಕ್ಷಿತವಾಗಿ ತೆಗೆದುಹಾಕಲಾಗಿದೆ"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"ವಿಷಯ ನಷ್ಟವನ್ನು ತಪ್ಪಿಸಲು ತೆಗೆದುಹಾಕುವುದಕ್ಕೂ ಮುನ್ನ ಮಾಧ್ಯಮವನ್ನು ಎಜೆಕ್ಟ್ ಮಾಡಿ"</string>
@@ -1677,7 +1689,8 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ಶಾರ್ಟ್‌ಕಟ್ ಬಳಸಿ"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"ಬಣ್ಣ ವಿಲೋಮ"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"ಬಣ್ಣ ತಿದ್ದುಪಡಿ"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"ಪ್ರಖರತೆಯನ್ನು ಕಡಿಮೆ ಮಾಡಿ"</string>
+    <!-- no translation found for reduce_bright_colors_feature_name (3222994553174604132) -->
+    <skip />
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ವಾಲ್ಯೂಮ್ ಕೀಗಳನ್ನು ಹಿಡಿದುಕೊಳ್ಳಿ. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ಅನ್ನು ಆನ್ ಮಾಡಲಾಗಿದೆ."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ವಾಲ್ಯೂಮ್ ಕೀಗಳನ್ನು ಹಿಡಿದಿಟ್ಟುಕೊಳ್ಳಲಾಗಿದೆ. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, ಆಫ್ ಮಾಡಲಾಗಿದೆ."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ಅನ್ನು ಬಳಸಲು ಎರಡೂ ಧ್ವನಿ ಕೀಗಳನ್ನು ಮೂರು ಸೆಕೆಂಡ್‌ಗಳ ಕಾಲ ಒತ್ತಿ ಹಿಡಿದುಕೊಳ್ಳಿ"</string>
@@ -1689,7 +1702,7 @@
     <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"ವೈಶಿಷ್ಟ್ಯಗಳ ನಡುವೆ ಬದಲಿಸಲು, ಮೂರು ಬೆರಳುಗಳನ್ನು ಬಳಸಿ ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ ಮತ್ತು ಒತ್ತಿ ಹಿಡಿಯಿರಿ."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"ಹಿಗ್ಗಿಸುವಿಕೆ"</string>
     <string name="user_switched" msgid="7249833311585228097">"ಪ್ರಸ್ತುತ ಬಳಕೆದಾರರು <xliff:g id="NAME">%1$s</xliff:g>."</string>
-    <string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> ಗೆ ಬದಲಾಯಿಸಲಾಗುತ್ತಿದೆ…"</string>
+    <string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g>ಗೆ ಬದಲಾಯಿಸಲಾಗುತ್ತಿದೆ…"</string>
     <string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> ಅವರನ್ನು ಲಾಗ್‌ ಔಟ್‌ ಮಾಡಲಾಗುತ್ತಿದೆ…"</string>
     <string name="owner_name" msgid="8713560351570795743">"ಮಾಲೀಕರು"</string>
     <string name="error_message_title" msgid="4082495589294631966">"ದೋಷ"</string>
@@ -2086,6 +2099,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"ಸ್ಕ್ರೀನ್‌ನಲ್ಲಿನ ಪ್ರವೇಶಿಸುವಿಕೆ ಶಾರ್ಟ್‌ಕಟ್"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"ಸ್ಕ್ರೀನ್‌ನಲ್ಲಿನ ಪ್ರವೇಶಿಸುವಿಕೆ ಶಾರ್ಟ್‌ಕಟ್ ಆಯ್ಕೆ"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"ಪ್ರವೇಶಿಸುವಿಕೆ ಶಾರ್ಟ್‌ಕಟ್"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"ಅಧಿಸೂಚನೆಯ ಪರದೆಯನ್ನು ವಜಾಗೊಳಿಸಿ"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<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> ಅನ್ನು ನಿರ್ಬಂಧಿತ ಬಕೆಟ್‌ಗೆ ಹಾಕಲಾಗಿದೆ"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2237,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"ಹೊಸದು: ವಿಂಡೋ ಮ್ಯಾಗ್ನಿಫೈಯರ್"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"ಈಗ ಕೆಲವು ಅಥವಾ ಎಲ್ಲಾ ಸ್ಕ್ರೀನ್ ಅನ್ನು ಹಿಗ್ಗಿಸಬಹುದು"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"ನಿಮ್ಮ ಸ್ಕ್ರೀನ್‌ನ ಭಾಗವನ್ನು ಹಿಗ್ಗಿಸಿ"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"ಈಗ ನಿಮ್ಮ ಪೂರ್ಣ ಸ್ಕ್ರೀನ್‌ನಲ್ಲಿ ಅಥವಾ ನಿರ್ದಿಷ್ಟ ಪ್ರದೇಶದಲ್ಲಿ ನೀವು ಹಿಗ್ಗಿಸುವಿಕೆ ಮಾಡಬಹುದು ಅಥವಾ ಈ ಎರಡು ಆಯ್ಕೆಗಳ ನಡುವೆ ಬದಲಾಯಿಸಬಹುದು."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"ಸೆಟ್ಟಿಂಗ್‌ಗಳಲ್ಲಿ ಆನ್ ಮಾಡಿ"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"ವಜಾಗೊಳಿಸಿ"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"ಮುಂದುವರಿಯಲು, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ಗೆ ನಿಮ್ಮ ಸಾಧನದ ಮೈಕ್ರೋಫೋನ್‌ನ ಪ್ರವೇಶದ ಅಗತ್ಯವಿದೆ."</string>
@@ -2233,4 +2247,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"ಸೆನ್ಸರ್ ಗೌಪ್ಯತೆ"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"ಅಪ್ಲಿಕೇಶನ್‌ ಐಕಾನ್‌"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"ಅಪ್ಲಿಕೇಶನ್ ಬ್ರ್ಯಾಂಡಿಂಗ್ ಚಿತ್ರ"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"ಪ್ರವೇಶ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಪರಿಶೀಲಿಸಿ"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> ನಿಮ್ಮ ಸ್ಕ್ರೀನ್ ಅನ್ನು ವೀಕ್ಷಿಸಬಹುದು ಮತ್ತು ನಿಯಂತ್ರಿಸಬಹುದು. ಪರಿಶೀಲಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
 </resources>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 78cc1b5..08ceb30 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"새벽 서비스"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"시간대 감지(연결되지 않음)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS 시간 업데이트 서비스"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"음악 인식 관리자 서비스"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"기기가 삭제됩니다."</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"관리자 앱을 사용할 수 없습니다. 곧 기기가 삭제됩니다.\n\n궁금한 점이 있으면 조직의 관리자에게 문의하세요."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g>에 의해 사용 중지되었습니다."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"실행 중인 앱"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"배터리를 소모하는 앱"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"확대"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"접근성 보안 정책"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g>에서 배터리 사용 중"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"앱 <xliff:g id="NUMBER">%1$d</xliff:g>개에서 배터리 사용 중"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"탭하여 배터리 및 데이터 사용량 확인"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"앱이 상태 표시줄이 되도록 허용합니다."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"상태 표시줄 확장/축소"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"앱이 상태 표시줄을 확장하거나 축소할 수 있도록 허용합니다."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"잠긴 기기에 알림을 전체 화면 활동으로 표시"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"앱에서 잠긴 기기에 알림을 전체 화면 활동으로 표시하도록 허용합니다."</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"바로가기 설치"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"애플리케이션이 사용자의 작업 없이 홈 화면 바로가기를 추가할 수 있도록 허용합니다."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"바로가기 제거"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"생체 인식 또는 화면 잠금을 사용"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"본인 확인"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"생체 인식을 사용하여 계속하세요"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"계속하려면 생체 인식이나 화면 잠금을 사용하세요"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"생체 인식 하드웨어를 사용할 수 없음"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"인증이 취소되었습니다."</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"인식할 수 없음"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"지문 사용"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"지문 또는 화면 잠금 사용"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"계속하려면 지문을 사용하세요."</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"계속하려면 지문이나 화면 잠금을 사용하세요"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"지문 아이콘"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"얼굴인식 잠금해제 사용"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"얼굴 또는 화면 잠금 사용"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"얼굴인식 잠금해제를 사용하여 계속하세요"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"계속하려면 얼굴 또는 화면 잠금을 사용하세요"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"얼굴 아이콘"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"페이지를 열 수 있는 권한이 없습니다."</string>
     <string name="text_copied" msgid="2531420577879738860">"텍스트가 클립보드에 복사되었습니다."</string>
     <string name="copied" msgid="4675902854553014676">"복사 완료"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> 앱이 <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> 앱에서 복사하여 붙여넣음"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> 앱이 클립보드에서 복사하여 붙여넣음"</string>
     <string name="more_item_label" msgid="7419249600215749115">"더보기"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Menu+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"사용 중지"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"<xliff:g id="NAME">%s</xliff:g> 확인 중…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"현재 콘텐츠 검토 중"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"미디어 저장소를 분석하는 중입니다."</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"새로운 <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g>이(가) 작동하지 않음"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"설정하려면 탭하세요."</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"설정하려면 선택하세요."</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"기기를 다시 포맷해야 할 수 있습니다. 꺼내려면 탭하세요."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"사진 및 미디어를 전송하는 데 사용합니다."</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"미디어 파일을 둘러보세요."</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"<xliff:g id="NAME">%s</xliff:g>에 문제 발생"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g>이(가) 작동하지 않음"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"문제를 해결하려면 탭하세요."</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"지원되지 않는 <xliff:g id="NAME">%s</xliff:g>입니다."</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g>이(가) 작동하지 않음"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"이 기기는 <xliff:g id="NAME">%s</xliff:g>을(를) 지원하지 않습니다. 지원하는 형식으로 설정하려면 탭하세요."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"이 기기는 이 <xliff:g id="NAME">%s</xliff:g>을(를) 지원하지 않습니다. 선택하여 지원되는 형식으로 설정하세요."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"<xliff:g id="NAME">%s</xliff:g>을(를) 지원되는 형식으로 설정하려면 선택하세요."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"기기를 다시 포맷해야 할 수 있습니다."</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g>이(가) 예기치 않게 삭제됨"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"콘텐츠 손실을 피하려면 미디어를 제거하기 전에 마운트 해제하세요."</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"단축키 사용"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"색상 반전"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"색상 보정"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"밝기 낮추기"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"더 어둡게"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"볼륨 키를 길게 눌렀습니다. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>이(가) 사용 설정되었습니다."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"볼륨 키를 길게 눌렀습니다. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>이(가) 사용 중지되었습니다."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> 서비스를 사용하려면 두 볼륨 키를 3초 동안 길게 누르세요"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"화면상의 접근성 바로가기"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"화면상의 접근성 바로가기 선택 도구"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"접근성 단축키"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"알림 창 닫기"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<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> 항목이 RESTRICTED 버킷으로 이동함"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"새로운 기능: 창 돋보기"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"이제 화면 일부 또는 전체를 확대할 수 있습니다."</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"일부 화면 확대"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"이제 전체 화면, 특정 영역을 확대하거나 두 가지 옵션 간에 전환할 수 있습니다."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"설정에서 사용 설정"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"닫기"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"계속하려면 &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt;에서 기기 마이크에 액세스해야 합니다."</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"센서 개인정보 보호"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"애플리케이션 아이콘"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"애플리케이션 브랜드 이미지"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"접근성 설정 확인"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> 서비스가 내 화면을 보고 제어할 수 있습니다. 검토하려면 탭하세요."</string>
 </resources>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index 5d8b898..034d94e 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Twilight кызматы"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Убакыт алкагын аныктагыч (байланыш жок)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS Убакытты жаңыртуу кызматы"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Музыканы таануу кызматы"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Түзмөгүңүз тазаланат"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Түзмөктү башкаруучу колдонмо жараксыз. Түзмөгүңүз азыр тазаланат.\n\nСуроолоруңуз болсо, ишканаңыздын администраторуна кайрылыңыз."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Басып чыгаруу <xliff:g id="OWNER_APP">%s</xliff:g> тарабынан өчүрүлдү."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Колдонмо иштеп жатат"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Колдонмолор батареяңызды коротууда"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Чоңойтуу"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Атайын мүмкүнчүлүктөрдүн коопсуздугун коргоо саясаты"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосу батареяны пайдаланып жатат"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> колдонмо батареяны пайдаланып жатат"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Батареянын кубаты жана трафиктин көлөмү жөнүндө билүү үчүн таптап коюңуз"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Колдонмого абал тилкеси болуу мүмкүнчүлүгүн берет."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"абал тилкесин жайып көрсөтүү/жыйнап коюу"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Колдонмого абал тилкесин жайып көрсөтүү же жыйнап коюу мүмкүнчүлүгүн берет."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"билдирмелерди кулпуланган түзмөктүн толук экранында көрсөтүү"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Колдонмого билдирмелерди кулпуланган түзмөктүн толук экранында көрсөтүүгө уруксат берет"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"тез чакырма орнотуу"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Колдонмого үй экранга колдонуучунун катышуусусуз тез чакырма кошууга мүмкүнчүлүк берет."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"тез чакыргычтарды жок кылуу"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Биометрикалык жөндөөнү же экрандын кулпусун колдонуу"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Өзүңүздү ырастаңыз"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Улантуу үчүн биометрикалык жөндөөнү колдонуу"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Улантуу үчүн биометрикалык маалыматты же экрандын кулпусун колдонуңуз"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Биометрикалык аппарат жеткиликсиз"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Аныктыгын текшерүү жокко чыгарылды"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Таанылган жок"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Манжа изин колдонуу"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Манжа изин же экрандын кулпусун колдонуу"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Улантуу үчүн манжаңыздын изин колдонуңуз"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Улантуу үчүн манжа изин же экрандын кулпусун колдонуңуз"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Манжа изинин сүрөтчөсү"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Жүзүнөн таанып ачууну колдонуу"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Жүзүнөн таанып ачууну же экрандын кулпусун колдонуу"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Улантуу үчүн жүзүнөн таанып ачууну колдонуу"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Улантуу үчүн жүзүңүздү же экрандын кулпусун колдонуңуз"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Жүздүн сүрөтчөсү"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"Бул бетти ачууга уруксат берилген эмес."</string>
     <string name="text_copied" msgid="2531420577879738860">"Текст алмашуу буферине көчүрүлдү."</string>
     <string name="copied" msgid="4675902854553014676">"Көчүрүлдү"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> колдонмосунан чапталды"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> алмашуу буферинен чапталды"</string>
     <string name="more_item_label" msgid="7419249600215749115">"Дагы"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Меню+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1207,12 +1216,12 @@
     <string name="launch_warning_replace" msgid="3073392976283203402">"<xliff:g id="APP_NAME">%1$s</xliff:g> азыр иштеп жатат."</string>
     <string name="launch_warning_original" msgid="3332206576800169626">"Башында <xliff:g id="APP_NAME">%1$s</xliff:g> жүргүзүлгөн."</string>
     <string name="screen_compat_mode_scale" msgid="8627359598437527726">"Шкала"</string>
-    <string name="screen_compat_mode_show" msgid="5080361367584709857">"Ар дайым көрсөтүлсүн"</string>
+    <string name="screen_compat_mode_show" msgid="5080361367584709857">"Ар дайым көрүнсүн"</string>
     <string name="screen_compat_mode_hint" msgid="4032272159093750908">"Муну тутум жөндөөлөрүнөн кайра иштетүү &gt; Колдонмолор &gt; Жүктөлүп алынган."</string>
     <string name="unsupported_display_size_message" msgid="7265211375269394699">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосу көрүнүштүн тандалган өлчөмүн экранда көрсөтө албайт жана туура эмес иштеши мүмкүн."</string>
-    <string name="unsupported_display_size_show" msgid="980129850974919375">"Ар дайым көрсөтүлсүн"</string>
+    <string name="unsupported_display_size_show" msgid="980129850974919375">"Ар дайым көрүнсүн"</string>
     <string name="unsupported_compile_sdk_message" msgid="7326293500707890537">"<xliff:g id="APP_NAME">%1$s</xliff:g> Android OS тутуму менен иштеген түзмөктүн шайкеш келбеген версиясы үчүн орнотулган колдонмо жана туура эмес иштеши мүмкүн. Колдонмонун жаңыртылган версиясы жеткиликтүү болушу мүмкүн."</string>
-    <string name="unsupported_compile_sdk_show" msgid="1601210057960312248">"Ар дайым көрсөтүлсүн"</string>
+    <string name="unsupported_compile_sdk_show" msgid="1601210057960312248">"Ар дайым көрүнсүн"</string>
     <string name="unsupported_compile_sdk_check_update" msgid="1103639989147664456">"Жаңыртууну издөө"</string>
     <string name="smv_application" msgid="3775183542777792638">"<xliff:g id="APPLICATION">%1$s</xliff:g> колдонмосу (<xliff:g id="PROCESS">%2$s</xliff:g> процесси) өз алдынча иштеткен StrictMode саясатын бузду."</string>
     <string name="smv_process" msgid="1398801497130695446">"<xliff:g id="PROCESS">%1$s</xliff:g> процесси өзүнүн мажбурланган StrictMode саясатын бузуп койду."</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Өчүрүү"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"<xliff:g id="NAME">%s</xliff:g> текшерилүүдө…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Учурдагы мазмун каралып жатат"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Медиа сактагычты талдоо"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Жаңы <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> иштебей жатат"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Жөндөө үчүн таптаңыз"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Жөндөө үчүн тандаңыз"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Түзмөктү форматташыңыз керек болушу мүмкүн. Чыгаруу үчүн таптап коюңуз."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"Сүрөттөрдү жана медиа өткөрүү үчүн"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Медиа файлдарды серептөө"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"<xliff:g id="NAME">%s</xliff:g> түзмөгүндө бир маселе бар"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> иштебей жатат"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Оңдоо үчүн таптап коюңуз"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"<xliff:g id="NAME">%s</xliff:g> колдоого алынбайт"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> иштебей жатат"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"Бул түзмөктө <xliff:g id="NAME">%s</xliff:g> колдоого алынбайт. Колдоого алынуучу форматта орнотуу үчүн таптап коюңуз."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"Бул түзмөктө <xliff:g id="NAME">%s</xliff:g> колдоого алынбайт. Колдоого алынуучу форматта орнотуу үчүн тандаңыз."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Колдоого алынуучу форматта орнотуу үчүн <xliff:g id="NAME">%s</xliff:g> тандаңыз."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Түзмөктү форматташыңыз керек болушу мүмкүн"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> күтүүсүздөн өчүрүлдү"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Мазмунду жоготуп албаш үчүн алып салуудан мурда медианы өчүрүңүз"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Кыска жолду колдонуу"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Түстү инверсиялоо"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Түсүн тууралоо"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Экрандын жарыктыгын төмөндөтүү"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Кошумча караңгылатуу"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Үндү катуулатуу/акырындатуу баскычтары басылып, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> күйгүзүлдү."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Үндү катуулатуу/акырындатуу баскычтары басылып, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> өчүрүлдү."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> кызматын колдонуу үчүн үнүн чоңойтуп/кичирейтүү баскычтарын үч секунд коё бербей басып туруңуз"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Ыкчам иштетүү"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Ыкчам иштетүү менюсу"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Ыкчам иштетүү"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Билдирмелер тактасын жабуу"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<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> ЧЕКТЕЛГЕН чакага коюлган"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Жаңы функция: Терезе чоңойткуч"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Эми толук экранды же анын бөлүгүн чоңойто аласыз"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Экрандын бир бөлүгүн чоңойтуу"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Эми толук экранды же анын бөлүгүн чоңойтуп, же болбосо, эки параметрди которуштуруп колдоно аласыз."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Жөндөөлөрдөн күйгүзүү"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Жабуу"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Улантуу үчүн &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; колдонмосуна түзмөгүңүздүн микрофонун пайдаланууга уруксат беришиңиз керек."</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Сенсордун купуялыгы"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Колдонмонун сүрөтчөсү"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Колдонмонун брендинин сүрөтү"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Кирүү мүмкүнчүлүгүнүн жөндөөлөрүн текшериңиз"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> экраныңызды көрүп, көзөмөлдөй алат. Көрүү үчүн таптап коюңуз."</string>
 </resources>
diff --git a/core/res/res/values-land/dimens.xml b/core/res/res/values-land/dimens.xml
index 42c2c69..ca549ae 100644
--- a/core/res/res/values-land/dimens.xml
+++ b/core/res/res/values-land/dimens.xml
@@ -30,9 +30,7 @@
     <!-- Height of the status bar -->
     <dimen name="status_bar_height">@dimen/status_bar_height_landscape</dimen>
     <!-- Height of area above QQS where battery/time go -->
-    <dimen name="quick_qs_offset_height">@dimen/status_bar_height_landscape</dimen>
-    <!-- Total height of QQS in landscape, this is effectively status_bar_height_landscape + 128 -->
-    <dimen name="quick_qs_total_height">152dp</dimen>
+    <dimen name="quick_qs_offset_height">48dp</dimen>
     <!-- Default height of an action bar. -->
     <dimen name="action_bar_default_height">40dip</dimen>
     <!-- Vertical padding around action bar icons. -->
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index fcf47ed..ad56f88 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"ບໍລິການ Twilight"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"ຕົວກວດຫາເຂດເວລາ (ບໍ່ມີການເຊື່ອມຕໍ່)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"ບໍລິການອັບເດດເວລາ GNSS"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"ບໍລິການຕົວຈັດການການຈຳແນກເພງ"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"ອຸ​ປະ​ກອນ​ຂອງ​ທ່ານ​ຈະ​ຖືກ​ລຶບ"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"ບໍ່ສາມາດໃຊ້ແອັບຜູ້ເບິ່ງແຍງລະບົບໄດ້. ອຸປະກອນຂອງທ່ານຈະຖືກລຶບຂໍ້ມູນໃນຕອນນີ້.\n\nຫາກທ່ານມີຄຳຖາມ, ໃຫ້ຕິດຕໍ່ຜູ້ເບິ່ງແຍງລະບົບອົງກອນຂອງທ່ານ."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"ການພິມຖືກປິດໄວ້ໂດຍ <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"ແອັບກຳລັງເຮັດວຽກ"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"ແອັບທີ່ກຳລັງໃຊ້ແບັດເຕີຣີ"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"ການຂະຫຍາຍ"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"ນະໂຍບາຍຄວາມປອດໄພການຊ່ວຍເຂົ້າເຖິງ"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> ກຳລັງໃຊ້ແບັດເຕີຣີຢູ່"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> ແອັບກຳລັງໃຊ້ແບັດເຕີຣີຢູ່"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"ແຕະເພື່ອເບິ່ງລາຍລະອຽດການນຳໃຊ້ແບັດເຕີຣີ ແລະ ອິນເຕີເນັດ"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"ອະນຸຍາດໃຫ້ແອັບຯເປັນແຖບສະຖານະ."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"ຫຍໍ້/ຂະຫຍາຍ ແຖບສະຖານະ"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"ອະນຸຍາດໃຫ້ແອັບຯ ຂະຫຍາຍ ຫຼືຫຍໍ້ແຖບສະຖານະ."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"ສະແດງການແຈ້ງເຕືອນເປັນການເຄື່ອນໄຫວແບບເຕັມຈໍຢູ່ອຸປະກອນທີ່ລັອກໄວ້"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"ອະນຸຍາດໃຫ້ແອັບສະແດງການແຈ້ງເຕືອນເປັນການເຄື່ອນໄຫວແບບເຕັມຈໍຢູ່ອຸປະກອນທີ່ລັອກໄວ້"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"ຕິດຕັ້ງທາງລັດ"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນເພີ່ມທາງລັດໄດ້ ໂດຍບໍ່ຕ້ອງຮັບການຢືນຢັນຈາກຜູ່ໃຊ້."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"ຖອນທາງລັດ"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"ໃຊ້ລະບົບຊີວະມິຕິ ຫຼື ການລັອກໜ້າຈໍ"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"ຢັ້ງຢືນວ່າແມ່ນທ່ານ"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"ໃຊ້ລະບົບຊີວະມິຕິຂອງທ່ານເພື່ອດຳເນີນການຕໍ່"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"ໃຊ້ລະບົບຊີວະມິຕິ ຫຼື ການລັອກໜ້າຈໍຂອງທ່ານເພື່ອດຳເນີນການຕໍ່"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"ຮາດແວຊີວະມິຕິບໍ່ສາມາດໃຊ້ໄດ້"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"ຍົກເລີກການຮັບຮອງຄວາມຖືກຕ້ອງແລ້ວ"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"ບໍ່ຮັບຮູ້"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ໃຊ້ລາຍນິ້ວມື"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ໃຊ້ລາຍນິ້ວມື ຫຼື ການລັອກໜ້າຈໍ"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"ໃຊ້​ລາຍ​ນີ້ວ​ມື​ຂອງ​ທ່ານ​ເພື່ອ​ສືບ​ຕໍ່"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"ໃຊ້ລາຍນິ້ວມື ຫຼື ການລັອກໜ້າຈໍຂອງທ່ານເພື່ອດຳເນີນການຕໍ່"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"ໄອຄອນລາຍນິ້ວມື"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"ໃຊ້ການປົດລັອກດ້ວຍໜ້າ"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"ໃຊ້ໃບໜ້າ ຫຼື ການລັອກໜ້າຈໍ"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"ໃຊ້ການປົດລັອກດ້ວຍໜ້າເພື່ອດຳເນີນການຕໍ່"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"ໃຊ້ໃບໜ້າ ຫຼື ການລັອກໜ້າຈໍຂອງທ່ານເພື່ອດຳເນີນການຕໍ່"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"ໄອຄອນໃບໜ້າ"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"ທ່ານບໍ່ໄດ້ຮັບອະນຸຍາດໃຫ້ເປີດໜ້ານີ້."</string>
     <string name="text_copied" msgid="2531420577879738860">"ສຳເນົາຂໍ້ຄວາມໃສ່ຄລິບບອດແລ້ວ."</string>
     <string name="copied" msgid="4675902854553014676">"ສຳເນົາແລ້ວ"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"ວາງ <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ຈາກ <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> ແລ້ວ"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"ວາງ <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ຈາກຄລິບບອດແລ້ວ"</string>
     <string name="more_item_label" msgid="7419249600215749115">"ເພີ່ມເຕີມ"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"ເມນູ+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"ປິດ"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"ກຳລັງກວດສອບ <xliff:g id="NAME">%s</xliff:g>…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"ກຳລັງຕໍ່ອາຍຸເນື້ອຫາປັດຈຸບັນ"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"ກຳລັງວິເຄາະບ່ອນຈັດເກັບຂໍ້ມູນມີເດຍ"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"<xliff:g id="NAME">%s</xliff:g> ໃໝ່"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> ບໍ່ເຮັດວຽກ"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"ແຕະເພື່ອຕັ້ງຄ່າ"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"ເລືອກເພື່ອຕັ້ງຄ່າ"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"ທ່ານຈະຕ້ອງຟໍແມັດອຸປະກອນຄືນໃໝ່. ແຕະເພື່ອຖອດອອກ."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"ສຳ​ລັບ​ການ​ໂອນ​ຮູບຖ່າຍ ແລະ​ມີ​ເດຍ"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"ເລືອກໄຟລ໌ມີເດຍ"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"ເກີດບັນຫາກັບ <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> ບໍ່ເຮັດວຽກ"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"ແຕະເພື່ອແກ້ໄຂ"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"ບໍ່​ຮອງ​ຮັບ <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> ບໍ່ເຮັດວຽກ"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"ອຸປະກອນນີ້ບໍ່ຮອງຮັບ <xliff:g id="NAME">%s</xliff:g> ນີ້. ແຕະເພື່ອຕັ້ງຄ່າໃນຮູບແບບທີ່ຮອງຮັບ."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"ອຸປະກອນນີ້ບໍ່ຮອງຮັບ <xliff:g id="NAME">%s</xliff:g> ນີ້. ແຕະເພື່ອຕັ້ງຄ່າໃນຮູບແບບທີ່ຮອງຮັບ."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"ເລືອກເພື່ອຕັ້ງຄ່າ <xliff:g id="NAME">%s</xliff:g> ໃນຮູບແບບທີ່ຮອງຮັບ."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"ທ່ານຈະຕ້ອງຟໍແມັດອຸປະກອນຄືນໃໝ່"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> ຖືກ​ຖອດ​ອອກ​ໄປ​ແບບ​ບໍ່​ຄາດ​ຄິດ"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"ກະລຸນາດີດມີເດຍອອກກ່ອນການຖອດເພື່ອຫຼີກເວັ້ນການສູນເສຍຂໍ້ມູນ"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ໃຊ້ປຸ່ມລັດ"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"ການປີ້ນສີ"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"ການແກ້ໄຂຄ່າສີ"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"ຫຼຸດຄວາມສະຫວ່າງລົງ"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"ຫຼຸດແສງເປັນພິເສດ"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ກົດປຸ່ມລະດັບສຽງຄ້າງໄວ້. ເປີດໃຊ້ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ແລ້ວ."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ກົດປຸ່ມລະດັບສຽງຄ້າງໄວ້. ປິດ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ໄວ້ແລ້ວ."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"ກົດປຸ່ມສຽງທັງສອງພ້ອມກັນຄ້າງໄວ້ສາມວິນາທີເພື່ອໃຊ້ <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -1689,7 +1701,7 @@
     <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"ເພື່ອສະຫຼັບລະຫວ່າງຄຸນສົມບັດຕ່າງໆ, ໃຫ້ປັດຂຶ້ນດ້ວຍສາມນິ້ວຄ້າງໄວ້."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"ການຂະຫຍາຍ"</string>
     <string name="user_switched" msgid="7249833311585228097">"ຜູ່ໃຊ້ປັດຈຸບັນ <xliff:g id="NAME">%1$s</xliff:g> ."</string>
-    <string name="user_switching_message" msgid="1912993630661332336">"ກຳ​ລັງ​ສະ​ລັບ​​ໄປ​ຫາ <xliff:g id="NAME">%1$s</xliff:g>…"</string>
+    <string name="user_switching_message" msgid="1912993630661332336">"ກຳລັງສະຫຼັບໄປຫາ<xliff:g id="NAME">%1$s</xliff:g>…"</string>
     <string name="user_logging_out_message" msgid="7216437629179710359">"ກຳລັງອອກຈາກລະບົບ <xliff:g id="NAME">%1$s</xliff:g>…"</string>
     <string name="owner_name" msgid="8713560351570795743">"ເຈົ້າຂອງ"</string>
     <string name="error_message_title" msgid="4082495589294631966">"ຜິດພາດ"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"ທາງລັດການຊ່ວຍເຂົ້າເຖິງຢູ່ໜ້າຈໍ"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"ຕົວເລືອກທາງລັດການຊ່ວຍເຂົ້າເຖິງຢູ່ໜ້າຈໍ"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"ທາງລັດການຊ່ວຍເຂົ້າເຖິງ"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"ປິດເງົາການແຈ້ງເຕືອນໄວ້"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"ແຖບຄຳບັນຍາຍຂອງ <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> ຖືກວາງໄວ້ໃນກະຕ່າ \"ຈຳກັດ\" ແລ້ວ"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"ໃໝ່: ຕົວຂະຫຍາຍໜ້າຈໍ"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"ຕອນນີ້ທ່ານສາມາດຂະຫຍາຍບາງສ່ວນ ຫຼື ທັງໝົດຂອງໜ້າຈໍໄດ້"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"ຂະຫຍາຍບາງສ່ວນຂອງໜ້າຈໍທ່ານ"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"ຕອນນີ້ທ່ານສາມາດຂະຫຍາຍເນື້ອຫາແບບເຕັມຈໍຂອງທ່ານ, ພື້ນທີ່ສະເພາະ ຫຼື ສະຫຼັບລະຫວ່າງຕົວເລືອກທັງສອງໄດ້ແລ້ວ."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"ເປີດໃຊ້ໃນການຕັ້ງຄ່າ"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"ປິດໄວ້"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"ເພື່ອດຳເນີນການຕໍ່, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ຕ້ອງການສິດເຂົ້າເຖິງໄມໂຄຣໂຟນອຸປະກອນທ່ານ."</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"ຄວາມເປັນສ່ວນຕົວເຊັນເຊີ"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"ໄອຄອນແອັບພລິເຄຊັນ"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"ຮູບແບຣນແອັບພລິເຄຊັນ"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"ກວດສອບການຕັ້ງຄ່າການເຂົ້າເຖິງ"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> ສາມາດເບິ່ງ ແລະ ຄວບຄຸມໜ້າຈໍຂອງທ່ານໄດ້. ແຕະເພື່ອກວດສອບ."</string>
 </resources>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 4afef3b..1ae2996 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -208,6 +208,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Paslauga „Twilight“"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Laiko juostos aptikimo priemonė (nėra ryšio)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS laiko atnaujinimo paslauga"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Muzikos atpažinimo tvarkyklės paslauga"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Įrenginys bus ištrintas"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Administratoriaus programos negalima naudoti. Dabar įrenginio duomenys bus ištrinti.\n\nJei turite klausimų, susisiekite su organizacijos administratoriumi."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Neleidžiama spausdinti (<xliff:g id="OWNER_APP">%s</xliff:g>)."</string>
@@ -299,6 +300,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Programa paleista"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Programos, naudojančios akumuliatoriaus energiją"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Didinimas"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Pritaikomumo saugos politika"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"„<xliff:g id="APP_NAME">%1$s</xliff:g>“ naudoja akumuliatoriaus energiją"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"Programų, naudojančių akumuliatoriaus energiją: <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Palieskite ir sužinokite išsamios informacijos apie akumuliatoriaus bei duomenų naudojimą"</string>
@@ -349,6 +351,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Leidžiama programai būti būsenos juosta."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"išskleisti / sutraukti būsenos juostą"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Leidžiama programai išskleisti arba sutraukti būsenos juostą."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"pateikti pranešimus kaip veiklą viso ekrano režimu užrakintame įrenginyje"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Leidžiama programai pateikti pranešimus kaip veiklą viso ekrano režimu užrakintame įrenginyje"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"įdiegti sparčiuosius klavišus"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Programai leidžiama pridėti sparčiuosius klavišus prie pagrindinio ekrano be naudotojo įsikišimo."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"pašalinti sparčiuosius klavišus"</string>
@@ -560,6 +564,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Naudoti biometrinius duomenis arba ekrano užraktą"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Patvirtinkite, kad tai jūs"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Norėdami tęsti, naudokite biometrinius duomenis"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Jei norite tęsti, naudokite biometrinius duomenis arba ekrano užraktą"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrinė aparatinė įranga nepasiekiama"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Autentifikavimas atšauktas"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Neatpažinta"</string>
@@ -593,6 +598,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Naudoti kontrolinį kodą"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Naudoti kontrolinį kodą arba ekrano užraktą"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Naudokite kontrolinį kodą, kad galėtumėte tęsti"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Jei norite tęsti, naudokite kontrolinį kodą arba ekrano užraktą"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Piršto antspaudo piktograma"</string>
@@ -640,6 +646,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Naudoti atrakinimą pagal veidą"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Naudoti atrakinimą pagal veidą arba ekrano užraktą"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Norėdami tęsti, naudokite atrakinimą pagal veidą"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Jei norite tęsti, naudokite veido atpažinimo funkciją arba ekrano užraktą"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Veido pkt."</string>
@@ -1003,6 +1010,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"Neturite leidimo atidaryti šį puslapį."</string>
     <string name="text_copied" msgid="2531420577879738860">"Tekstas nukopijuotas į iškarpinę."</string>
     <string name="copied" msgid="4675902854553014676">"Nukopijuota"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"„<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>“ įklijuota iš „<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>“"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"„<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>“ įklijuota iš iškarpinės"</string>
     <string name="more_item_label" msgid="7419249600215749115">"Daugiau"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Meniu+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"„Meta“ +"</string>
@@ -1410,11 +1419,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Išjungti"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Tikrinama išorinė laikmena (<xliff:g id="NAME">%s</xliff:g>)…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Peržiūrimas dabartinis turinys"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Analizuojama medijos saugykla"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Nauja laikmena (<xliff:g id="NAME">%s</xliff:g>)"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> neveikia"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Palieskite, kad nustatytumėte"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Pasirinkite, kad nustatytumėte"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Jums gali reikėti suformatuoti įrenginį iš naujo. Palieskite, kad pašalintumėte."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"Norint perkelti nuotraukas ir mediją"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Naršykite medijos failus"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Kilo problema dėl laikmenos (<xliff:g id="NAME">%s</xliff:g>)"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> neveikia"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Palieskite ir ištaisykite tai"</string>
@@ -1423,7 +1435,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"Nepalaikoma saugykla (<xliff:g id="NAME">%s</xliff:g>)"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> neveikia"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"Šis įrenginys nepalaiko šios <xliff:g id="NAME">%s</xliff:g>. Palieskite, kad nustatytumėte palaikomu formatu."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"Šis įrenginys nepalaiko šios <xliff:g id="NAME">%s</xliff:g>. Pasirinkite ir nustatykite palaikomu formatu."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Pasirinkite, kad nustatytumėte <xliff:g id="NAME">%s</xliff:g> palaikomu formatu."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Jums gali reikėti suformatuoti įrenginį iš naujo"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> netikėtai pašalinta"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Prieš šalindami išimkite laikmeną, kad neprarastumėte turinio"</string>
@@ -1721,7 +1733,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Naudoti spartųjį klavišą"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Spalvų inversija"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Spalvų taisymas"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Šviesumo mažinimas"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Itin blanku"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Laikomi garsumo klavišai. „<xliff:g id="SERVICE_NAME">%1$s</xliff:g>“ įjungta."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Laikomi garsumo klavišai. „<xliff:g id="SERVICE_NAME">%1$s</xliff:g>“ išjungta."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Jei norite naudoti „<xliff:g id="SERVICE_NAME">%1$s</xliff:g>“, paspauskite abu garsumo klavišus ir palaikykite tris sekundes"</string>
@@ -2154,6 +2166,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Ekrano pritaikomumo šaukinys"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Ekrano pritaikomumo šaukinių parinkiklis"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Pritaikomumo šaukinys"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Atsisakyti pranešimų skydelio"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Programos „<xliff:g id="APP_NAME">%1$s</xliff:g>“ antraštės juosta."</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"„<xliff:g id="PACKAGE_NAME">%1$s</xliff:g>“ įkeltas į grupę APRIBOTA"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2291,8 +2304,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Nauja: „Window Magnifier“"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Dabar galite padidinti dalį ekrano ar jį visą"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Ekrano dalies didinimas"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Dabar galite padidinti visą ekraną, konkrečią sritį ar perjungti abi parinktis."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Įjungti nustatymuose"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Atmesti"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Kad būtų galima tęsti, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; reikalinga prieiga prie įrenginio mikrofono."</string>
@@ -2301,4 +2314,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Jutiklių privatumas"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Programos piktograma"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Programos prekės ženklo vaizdas"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Patikrinkite prieigos nustatymus"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"„<xliff:g id="SERVICE_NAME">%s</xliff:g>“ gali peržiūrėti ir valdyti jūsų ekraną. Palieskite ir peržiūrėkite."</string>
 </resources>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 8fbfb27..f011815 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -206,6 +206,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Krēslas noteikšanas pakalpojums"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Laika joslas noteikšanas rīks (nav savienojuma)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS laika atjaunināšanas pakalpojums"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Mūzikas atpazīšanas pārziņa pakalpojums"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Jūsu ierīces dati tiks dzēsti"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Administratora lietotni nevar izmantot. Ierīcē saglabātie dati tiks dzēsti.\n\nJa jums ir kādi jautājumi, sazinieties ar savas organizācijas administratoru."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Drukāšanu atspējoja <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -296,6 +297,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Lietotne darbojas"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Lietotnes, kas patērē akumulatora jaudu"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Palielinājums"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Pieejamības drošības politika"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"Lietotne <xliff:g id="APP_NAME">%1$s</xliff:g> izmanto akumulatoru"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> lietotne(-es) izmanto akumulatoru"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Pieskarieties, lai skatītu detalizētu informāciju par akumulatora un datu lietojumu"</string>
@@ -346,6 +348,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Ļauj lietotnei būt par statusa joslu."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"izvērst/sakļaut statusa joslu"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Ļauj lietotnei izvērst vai sakļaut statusa joslu."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"paziņojumu darbību rādīšana pilnekrāna režīmā, ja ierīce ir bloķēta"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Ļauj lietotnei rādīt paziņojumus kā pilnekrāna režīma darbības, ja ierīce ir bloķēta"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"instalēt saīsnes"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Ļauj lietojumprogrammai pievienot saīsnes sākuma ekrānam, nejautājot lietotājam."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"atinstalēt saīsnes"</string>
@@ -557,6 +561,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Biometrijas vai ekrāna bloķēšanas izmantošana"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Apstipriniet, ka tas esat jūs"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Lai turpinātu, izmantojiet biometriju"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Izmantojiet biometrijas datus vai ekrāna bloķēšanas opciju, lai turpinātu"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrisko datu aparatūra nav pieejama"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Autentifikācija ir atcelta"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Dati nav atpazīti"</string>
@@ -590,6 +595,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Pirksta nospieduma izmantošana"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Pirksta nospieduma vai ekrāna bloķēšanas metodes izmantošana"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Lai turpinātu, izmantojiet pirksta nospiedumu"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Izmantojiet pirksta nospiedumu vai ekrāna bloķēšanas opciju, lai turpinātu"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Pirksta nospieduma ikona"</string>
@@ -637,6 +643,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Autorizācija pēc sejas"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Autorizācijas pēc sejas vai ekrāna bloķēšanas metodes izmantošana"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Lai turpinātu, izmantojiet autorizāciju pēc sejas"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Izmantojiet autorizāciju pēc sejas vai ekrāna bloķēšanas opciju, lai turpinātu"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Sejas ikona"</string>
@@ -1000,6 +1007,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"Jums nav atļaujas atvērt šo lapu."</string>
     <string name="text_copied" msgid="2531420577879738860">"Teksts ir kopēts uz starpliktuvi."</string>
     <string name="copied" msgid="4675902854553014676">"Nokopēts"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"Lietotnē <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> tika ielīmēti dati no lietotnes <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>."</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"Lietotnē <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> tika ielīmēti dati no starpliktuves."</string>
     <string name="more_item_label" msgid="7419249600215749115">"Vairāk"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Izvēlne+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta taustiņš +"</string>
@@ -1390,11 +1399,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Izslēgt"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Notiek ierīces <xliff:g id="NAME">%s</xliff:g> pārbaude…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Notiek pašreizējā satura pārskatīšana."</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Notiek multivides krātuves analīze…"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Jauna ierīce: <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> nedarbojas."</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Pieskarieties, lai iestatītu."</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Atlasiet, lai iestatītu."</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Iespējams, jums būs atkārtoti jāformatē ierīce. Pieskarieties, lai izņemtu."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"Fotoattēlu un satura pārsūtīšanai."</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Pārlūkojiet multivides failus."</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Problēma saistībā ar <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> nedarbojas."</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Pieskarieties, lai novērstu problēmu."</string>
@@ -1403,7 +1415,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"Neatbalstīts datu nesējs (<xliff:g id="NAME">%s</xliff:g>)"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> nedarbojas."</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"Šī ierīce neatbalsta datu nesēju <xliff:g id="NAME">%s</xliff:g>. Pieskarieties, lai iestatītu to atbalstītā formātā."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"Šajā ierīcē netiek atbalstīta šī <xliff:g id="NAME">%s</xliff:g>. Atlasiet, lai iestatītu atbalstītu formātu."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Atlasiet, lai iestatītu atbalstītu formātu multivides krātuvei (<xliff:g id="NAME">%s</xliff:g>)."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Iespējams, jums būs atkārtoti jāformatē ierīce."</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> tika negaidīti izņemta"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Lai nezaudētu saturu, pirms izņemšanas izstumiet datu nesēju."</string>
@@ -1699,7 +1711,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Izmantot saīsni"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Krāsu inversija"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Krāsu korekcija"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Spilgtuma samazināšana"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Papildu aptumšošana"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Turējāt nospiestas skaļuma pogas. Pakalpojums <xliff:g id="SERVICE_NAME">%1$s</xliff:g> tika ieslēgts."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Turējāt nospiestas skaļuma pogas. Pakalpojums <xliff:g id="SERVICE_NAME">%1$s</xliff:g> tika izslēgts."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Lai izmantotu pakalpojumu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, nospiediet abus skaļuma taustiņus un turiet tos trīs sekundes."</string>
@@ -2120,6 +2132,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Ekrāna pieejamības saīsne"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Ekrāna pieejamības saīsnes atlasītājs"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Pieejamības saīsne"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Nerādīt paziņojumu paneli"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Lietotnes <xliff:g id="APP_NAME">%1$s</xliff:g> subtitru josla."</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Pakotne “<xliff:g id="PACKAGE_NAME">%1$s</xliff:g>” ir ievietota ierobežotā kopā."</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2257,8 +2270,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Jaunums: funkcija Window Magnifier"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Tagad varat palielināt ekrāna daļu vai visu ekrānu"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Ekrāna daļas palielināšana"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Tagad varat palielināt visu ekrānu vai noteiktu apgabalu vai pāriet starp abām iespējām."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Ieslēgt sadaļā Iestatījumi"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Nerādīt"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Lai turpinātu, lietotnei &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; nepieciešama piekļuve jūsu ierīces mikrofonam."</string>
@@ -2267,4 +2280,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Sensoru konfidencialitāte"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Lietojumprogrammas ikona"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Lietojumprogrammas zīmola attēls"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Pārbaudiet piekļuves iestatījumus"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"Pakalpojums <xliff:g id="SERVICE_NAME">%s</xliff:g> var skatīt un kontrolēt jūsu ekrānu. Pieskarieties, lai to pārskatītu."</string>
 </resources>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 9d07234..bbd9d9d 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Услуга за самрак"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Откривач на временска зона (не може да се поврзе)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"Услуга за ажурирање на времето на GNSS"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Услуга на управникот за препознавање музика"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Уредот ќе се избрише"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Апликацијата на администраторот не може да се користи. Уредот ќе се избрише сега.\n\nАко имате прашања, контактирајте со администраторот на организацијата."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Печатењето е оневозможено од <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Апликацијата работи"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Апликации што ја трошат батеријата"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Зголемување"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Политика за безбедност на „Пристапност“"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> користи батерија"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> апликации користат батерија"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Допрете за детали за батеријата и потрошениот сообраќај"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Дозволува апликацијата да биде статусната лента."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"прошири/собери статусна лента"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Дозволува апликацијата да ја прошири или собере статусната лента."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"да прикажува известувања како активности на цел екран на заклучен уред"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Дозволува апликацијата да прикажува известувања како активности на цел екран на заклучен уред"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"инсталирај кратенки"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Овозможува апликацијата да додава кратенки до почетниот екран без интервенција на корисникот."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"деинсталирај кратенки"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Користи биометрика или заклучен екран"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Потврдете дека сте вие"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Користете ја вашата биометрика за да продолжите"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Користете ја вашата биометрика или заклучување екран за да продолжите"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Биометрискиот хардвер е недостапен"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Проверката е откажана"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Непознат"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Користи отпечаток"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Користи отпечаток или заклучување екран"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Користете го отпечатокот за да продолжите"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Користете го вашиот отпечаток или заклучување екран за да продолжите"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Икона за отпечатоци"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Користи отклучување со лик"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Користи лик или заклучување екран"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Користете отклучување со лик за да продолжите"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Користете отклучување со лик или заклучување екран за да продолжите"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Икона"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"Немате дозвола да ја отворите страницава."</string>
     <string name="text_copied" msgid="2531420577879738860">"Текстот е копиран на таблата со исечоци."</string>
     <string name="copied" msgid="4675902854553014676">"Копирано"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> залепи од <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> залепи од привремената меморија"</string>
     <string name="more_item_label" msgid="7419249600215749115">"Повеќе"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Мени+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"копче Meta+"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Исклучи"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Проверка на <xliff:g id="NAME">%s</xliff:g>…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Се прегледуваат тековните содржини"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Се анализира капацитетот на надворешниот уред"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Нова <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> не работи"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Допрете за поставување"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Изберете за поставување"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Можеби ќе треба да го преформатирате уредот. Допрете за отстранување."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"За пренесување фотографии и аудио/видео содржини"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Прелистајте ги датотеките на надворешниот уред"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Проблем со <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> не работи"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Допрете за да го поправите ова"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"Неподдржана <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> не работи"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"Уредот не ја поддржува оваа <xliff:g id="NAME">%s</xliff:g>. Допрете за поставување во поддржан формат."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"Уредов не ја поддржува оваа <xliff:g id="NAME">%s</xliff:g>. Изберете за поставување во поддржан формат."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Допрете за поставување на <xliff:g id="NAME">%s</xliff:g> во поддржан формат."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Можеби ќе треба да го преформатирате уредот"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> неочекувано е отстранета"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Исклучете  ја надворешната меморија пред да ја отстраните за да избегнете губење содржини"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Користи кратенка"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Инверзија на бои"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Корекција на бои"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Намалување на осветленоста"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Дополнително затемнување"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Ги задржавте копчињата за јачина на звук. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> е вклучена."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Ги задржавте копчињата за јачина на звук. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> е исклучена."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Притиснете ги и задржете ги двете копчиња за јачина на звукот во траење од три секунди за да користите <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Кратенка за пристапност на екранот"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Избирач на кратенка за пристапност на екранот"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Кратенка за пристапност"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Отфрлете го панелот за известување"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Насловна лента на <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> е ставен во корпата ОГРАНИЧЕНИ"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Ново: „Лупа за прозорци“"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Сега може се зголеми целиот екран или само дел"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Зголемете дел од екранот"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Отсега може да го зголемувате вашиот цел екран, конкретна област или да се префрлате помеѓу двете опции."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Вклучи во „Поставки“"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Отфрли"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"За да продолжи, на &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ѝ е потребен пристап до микрофонот на уредот."</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Приватност на сензорот"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Икона за апликацијата"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Слика за брендирање на апликацијата"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Проверете ги поставките за пристап"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> може да го прегледува и контролира вашиот екран. Допрете за да прегледате."</string>
 </resources>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index 8d91c51..cfc112a 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"സന്ധ്യാസമയത്തെ സേവനം"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"സമയമേഖല കണ്ടെത്താനുള്ള സംവിധാനം (കണക്റ്റിവിറ്റി ഇല്ല)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS സമയ അപ്ഡേറ്റ് സേവനം"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"സംഗീതം തിരിച്ചറിയൽ മാനേജര്‍ സേവനം"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"നിങ്ങളുടെ ഉപകരണം മായ്‌ക്കും"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"അഡ്‌മിൻ ആപ്പ് ഉപയോഗിക്കാനാകില്ല. നിങ്ങളുടെ ഉപകരണം ഇപ്പോൾ മായ്ക്കപ്പെടും.\n\nനിങ്ങൾക്ക് ചോദ്യങ്ങൾ ഉണ്ടെങ്കിൽ, നിങ്ങളുടെ സ്ഥാപനത്തിന്റെ അഡ്‌മിനെ ബന്ധപ്പെടുക."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> പ്രിന്റിംഗ് പ്രവർത്തനരഹിതമാക്കി."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"ആപ്പ് പ്രവർത്തിക്കുന്നു"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"ആപ്പുകൾ ബാറ്ററി ഉപയോഗിക്കുന്നു"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"മാഗ്നിഫിക്കേഷൻ"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"ഉപയോഗസഹായി സുരക്ഷാ നയം"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> ബാറ്ററി ഉപയോഗിക്കുന്നു"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> ആപ്പുകൾ ബാറ്ററി ഉപയോഗിക്കുന്നു"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"ബാറ്ററി, ഡാറ്റ ഉപയോഗം എന്നിവയുടെ വിശദാംശങ്ങളറിയാൻ ടാപ്പുചെയ്യുക"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"അപ്ലിക്കേഷനെ നില ബാർ ആകാൻ അനുവദിക്കുന്നു."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"സ്റ്റാറ്റസ് വിപുലീകരിക്കുക/ചുരുക്കുക"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"നില ബാർ വിപുലീകരിക്കുന്നതിനോ ചുരുക്കുന്നതിനോ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"ലോക്ക് ചെയ്‌ത ഒരു ഉപകരണത്തിൽ പൂർണ്ണ സ്ക്രീൻ ആക്റ്റിവിറ്റികളായി അറിയിപ്പുകൾ പ്രദർശിപ്പിക്കുക"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"ലോക്ക് ചെയ്‌ത ഒരു ഉപകരണത്തിൽ പൂർണ്ണ സ്ക്രീൻ ആക്റ്റിവിറ്റികളായി അറിയിപ്പുകൾ പ്രദർശിപ്പിക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"കുറുക്കുവഴികൾ ഇൻസ്റ്റാളുചെയ്യുക"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"ഉപയോക്തൃ ഇടപെടലില്ലാതെ ഹോംസ്‌ക്രീൻ കുറുക്കുവഴികൾ ചേർക്കാൻ ഒരു അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"കുറുക്കുവഴികൾ അൺഇൻസ്റ്റാളുചെയ്യുക"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"ബയോമെട്രിക്‌സ് അല്ലെങ്കിൽ സ്‌ക്രീൻ ലോക്ക് ഉപയോഗിക്കുക"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"ഇത് നിങ്ങളാണെന്ന് പരിശോധിച്ചുറപ്പിക്കുക"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"തുടരാൻ ബയോമെട്രിക് ഉപയോഗിക്കുക"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"തുടരാൻ നിങ്ങളുടെ ബയോമെട്രിക്‌ അല്ലെങ്കിൽ സ്‌ക്രീൻ ലോക്ക് ഉപയോഗിക്കുക"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"ബയോമെട്രിക് ഹാർ‌ഡ്‌വെയർ ലഭ്യമല്ല"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"പരിശോധിച്ചുറപ്പിക്കൽ റദ്ദാക്കി"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"തിരിച്ചറിഞ്ഞില്ല"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ഫിംഗർപ്രിന്റ് ഉപയോഗിക്കുക"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ഫിംഗർപ്രിന്റ് അല്ലെങ്കിൽ സ്‌ക്രീൻ ലോക്ക് ഉപയോഗിക്കുക"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"തുടരുന്നതിന് നിങ്ങളുടെ ഫിംഗർപ്രിന്റ് ഉപയോഗിക്കുക"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"തുടരാൻ നിങ്ങളുടെ ഫിംഗർപ്രിന്റ്‌ അല്ലെങ്കിൽ സ്‌ക്രീൻ ലോക്ക് ഉപയോഗിക്കുക"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"ഫിംഗർപ്രിന്റ് ഐക്കൺ"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"മുഖം തിരിച്ചറിഞ്ഞുള്ള അൺലോക്ക് ഉപയോഗിക്കുക"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"മുഖം അല്ലെങ്കിൽ സ്‌ക്രീൻ ലോക്ക് ഉപയോഗിക്കുക"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"തുടരാൻ മുഖം തിരിച്ചറിഞ്ഞുള്ള അൺലോക്ക് ഉപയോഗിക്കുക"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"തുടരാൻ നിങ്ങളുടെ മുഖം‌ അല്ലെങ്കിൽ സ്‌ക്രീൻ ലോക്ക് ഉപയോഗിക്കുക"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"മുഖത്തിന്റെ ഐക്കൺ"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"ഈ പേജ് തുറക്കുന്നതിന് നിങ്ങൾക്ക് അനുമതിയില്ല."</string>
     <string name="text_copied" msgid="2531420577879738860">"ടെക്‌സ്റ്റ് ക്ലിപ്‍ബോർഡിലേക്ക് പകർത്തി."</string>
     <string name="copied" msgid="4675902854553014676">"പകർത്തി"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> എന്നതിൽ നിന്ന് <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ഒട്ടിച്ചു"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"ക്ലിപ്‌ബോർഡിൽ നിന്ന് <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ഒട്ടിച്ചു"</string>
     <string name="more_item_label" msgid="7419249600215749115">"കൂടുതൽ"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"മെനു+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"മെറ്റ+"</string>
@@ -1241,9 +1250,9 @@
     <string name="dump_heap_ready_notification" msgid="2302452262927390268">"<xliff:g id="PROC">%1$s</xliff:g> ഹീപ്പ് ഡംപ് തയ്യാറാണ്"</string>
     <string name="dump_heap_notification_detail" msgid="8431586843001054050">"ഹീപ്പ് ഡംപ് ശേഖരിച്ചു. പങ്കിടാൻ ടാപ്പ് ചെയ്യുക"</string>
     <string name="dump_heap_title" msgid="4367128917229233901">"ഹീപ്പ് ഡംപ് പങ്കിടണോ?"</string>
-    <string name="dump_heap_text" msgid="1692649033835719336">"<xliff:g id="PROC">%1$s</xliff:g> പ്രോസസിന്, മെമ്മറി പരിധിയായ <xliff:g id="SIZE">%2$s</xliff:g> കവിഞ്ഞു. അതിന്റെ ഡവലപ്പറുമായി പങ്കിടാൻ ഒരു ഹീപ്പ് ഡംപ് നിങ്ങൾക്ക് ലഭ്യമാണ്. ശ്രദ്ധിക്കുക: ഈ ഹീപ്പ് ഡംപിൽ ആപ്പിന് ആക്‌സസുള്ള ഏതെങ്കിലും വ്യക്തിഗത വിവരം അടങ്ങിയിരിക്കാം."</string>
-    <string name="dump_heap_system_text" msgid="6805155514925350849">"<xliff:g id="PROC">%1$s</xliff:g> പ്രോസസ് അതിൻ്റെ മെമ്മറി പരിധിയായ <xliff:g id="SIZE">%2$s</xliff:g> കവിഞ്ഞു. നിങ്ങൾക്ക് പങ്കിടാൻ ഒരു ഹീപ്പ് ഡംപ് ലഭ്യമാണ്. ശ്രദ്ധിക്കുക: പ്രോസസിന് ആക്‌സസ് ചെയ്യാനാകുന്ന, സൂക്ഷ്‌മമായി കൈകാര്യം ചെയ്യേണ്ട ഏതെങ്കിലും വ്യക്തിഗത വിവരം ഈ ഹീപ്പ് ഡംപിൽ അടങ്ങിയിരിക്കാം, നിങ്ങൾ ടൈപ്പ് ചെയ്‌തിട്ടുള്ള കാര്യങ്ങൾ ഇതിൽ ഉൾപ്പെട്ടിരിക്കാം."</string>
-    <string name="dump_heap_ready_text" msgid="5849618132123045516">"നിങ്ങൾക്ക് പങ്കിടാൻ <xliff:g id="PROC">%1$s</xliff:g> എന്നതിൻ്റെ പ്രോസസിൻ്റെ ഒരു ഹീപ്പ് ഡംപ് ലഭ്യമാണ്. ശ്രദ്ധിക്കുക: പ്രോസസിന് ആക്‌സസ് ചെയ്യാനാകുന്ന, സൂക്ഷ്‌മമായി കൈകാര്യം ചെയ്യേണ്ട ഏതെങ്കിലും വ്യക്തിഗത വിവരം ഈ ഹീപ്പ് ഡംപിൽ അടങ്ങിയിരിക്കാം, നിങ്ങൾ ടൈപ്പ് ചെയ്‌തിട്ടുള്ള കാര്യങ്ങൾ ഇതിൽ ഉൾപ്പെട്ടിരിക്കാം."</string>
+    <string name="dump_heap_text" msgid="1692649033835719336">"<xliff:g id="PROC">%1$s</xliff:g> പ്രോസസിന്, മെമ്മറി പരിധിയായ <xliff:g id="SIZE">%2$s</xliff:g> കവിഞ്ഞു. അതിന്റെ ഡവലപ്പറുമായി പങ്കിടാൻ ഒരു ഹീപ്പ് ഡംപ് നിങ്ങൾക്ക് ലഭ്യമാണ്. ശ്രദ്ധിക്കുക: ഈ ഹീപ്പ് ഡംപിൽ ആപ്പിന് ആക്‌സസുള്ള ഏതെങ്കിലും വ്യക്തിപരമായ വിവരങ്ങൾ അടങ്ങിയിരിക്കാം."</string>
+    <string name="dump_heap_system_text" msgid="6805155514925350849">"<xliff:g id="PROC">%1$s</xliff:g> പ്രോസസ് അതിൻ്റെ മെമ്മറി പരിധിയായ <xliff:g id="SIZE">%2$s</xliff:g> കവിഞ്ഞു. നിങ്ങൾക്ക് പങ്കിടാൻ ഒരു ഹീപ്പ് ഡംപ് ലഭ്യമാണ്. ശ്രദ്ധിക്കുക: പ്രോസസിന് ആക്‌സസ് ചെയ്യാനാകുന്ന, സൂക്ഷ്‌മമായി കൈകാര്യം ചെയ്യേണ്ട ഏതെങ്കിലും വ്യക്തിപരമായ വിവരങ്ങൾ ഈ ഹീപ്പ് ഡംപിൽ അടങ്ങിയിരിക്കാം, നിങ്ങൾ ടൈപ്പ് ചെയ്‌തിട്ടുള്ള കാര്യങ്ങൾ ഇതിൽ ഉൾപ്പെട്ടിരിക്കാം."</string>
+    <string name="dump_heap_ready_text" msgid="5849618132123045516">"നിങ്ങൾക്ക് പങ്കിടാൻ <xliff:g id="PROC">%1$s</xliff:g> എന്നതിൻ്റെ പ്രോസസിൻ്റെ ഒരു ഹീപ്പ് ഡംപ് ലഭ്യമാണ്. ശ്രദ്ധിക്കുക: പ്രോസസിന് ആക്‌സസ് ചെയ്യാനാകുന്ന, സൂക്ഷ്‌മമായി കൈകാര്യം ചെയ്യേണ്ട ഏതെങ്കിലും വ്യക്തിപരമായ വിവരങ്ങൾ ഈ ഹീപ്പ് ഡംപിൽ അടങ്ങിയിരിക്കാം, നിങ്ങൾ ടൈപ്പ് ചെയ്‌തിട്ടുള്ള കാര്യങ്ങൾ ഇതിൽ ഉൾപ്പെട്ടിരിക്കാം."</string>
     <string name="sendText" msgid="493003724401350724">"വാചകസന്ദേശത്തിനായി ഒരു പ്രവർത്തനം തിരഞ്ഞെടുക്കുക"</string>
     <string name="volume_ringtone" msgid="134784084629229029">"റിംഗർ വോളിയം"</string>
     <string name="volume_music" msgid="7727274216734955095">"മീഡിയ വോളിയം"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"ഓഫാക്കുക"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"<xliff:g id="NAME">%s</xliff:g> പരിശോധിക്കുന്നു…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"നിലവിലെ ഉള്ളടക്കം അവലോകനം ചെയ്യുന്നു"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"മീഡിയാ സ്റ്റോറേജ് വിശകലനം ചെയ്യുന്നു"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"പുതിയ <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> പ്രവർത്തിക്കുന്നില്ല"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"സജ്ജമാക്കാൻ ടാപ്പ് ചെയ്യുക"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"സജ്ജീകരിക്കാൻ തിരഞ്ഞെടുക്കുക"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"ഉപകരണം വീണ്ടും ഫോർമാറ്റ് ചെയ്യേണ്ടി വന്നേക്കാം. പുറത്തെടുക്കാൻ ടാപ്പ് ചെയ്യുക."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"ഫോട്ടോകളും മീഡിയയും ട്രാൻസ്‌ഫർ ചെയ്യാൻ"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"മീഡിയാ ഫയലുകൾ ബ്രൗസ് ചെയ്യുക"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"<xliff:g id="NAME">%s</xliff:g>-ൽ പ്രശ്‌നം"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> പ്രവർത്തിക്കുന്നില്ല"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"പരിഹരിക്കാൻ ടാപ്പ് ചെയ്യുക"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"പിന്തുണയില്ലാത്ത <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> പ്രവർത്തിക്കുന്നില്ല"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"ഈ ഉപകരണം <xliff:g id="NAME">%s</xliff:g> പിന്തുണയ്ക്കുന്നതല്ല. പിന്തുണയുള്ള ഫോർമാറ്റിൽ സജ്ജമാക്കുന്നതിന് ടാപ്പുചെയ്യുക."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"<xliff:g id="NAME">%s</xliff:g> ഈ ഉപകരണത്തിന് അനുയോജ്യമല്ല. അനുയോജ്യമായ ഒരു ഫോർമാറ്റിൽ സജ്ജമാക്കുന്നതിന് തിരഞ്ഞെടുക്കുക."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"പിന്തുണയ്‌ക്കുന്ന ഫോർമാറ്റിൽ <xliff:g id="NAME">%s</xliff:g> സജ്ജീകരിക്കാൻ തിരഞ്ഞെടുക്കുക."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"ഉപകരണം വീണ്ടും ഫോർമാറ്റ് ചെയ്യേണ്ടി വന്നേക്കാം"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> അപ്രതീക്ഷിതമായി നീക്കംചെയ്‌തു"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"ഉള്ളടക്കം നഷ്‌ടമാകുന്നത് തടയാൻ, നീക്കം ചെയ്യുന്നതിന് മുൻപ് മീഡിയ ഒഴിവാക്കുക"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"കുറുക്കുവഴി ഉപയോഗിക്കുക"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"വർണ്ണ വിപര്യയം"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"നിറം ക്രമീകരിക്കൽ"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"തെളിച്ചം കുറയ്ക്കുക"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"കൂടുതൽ ഡിം ചെയ്യൽ"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"വോളിയം കീകൾ പിടിച്ചു. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ഓണാക്കി."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"വോളിയം കീകൾ അമർത്തിപ്പിടിച്ചു. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ഓഫാക്കി."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ഉപയോഗിക്കാൻ, രണ്ട് വോളിയം കീകളും മൂന്ന് സെക്കൻഡ് അമർത്തിപ്പിടിക്കുക"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"സ്ക്രീനിലെ ഉപയോഗസഹായി കുറുക്കുവഴി"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"സ്ക്രീനിലെ ഉപയോഗസഹായി കുറുക്കുവഴി ചൂസർ"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"ഉപയോഗസഹായി കുറുക്കുവഴി"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"അറിയിപ്പ് ഷെയ്‌ഡ് ഡിസ്‌മിസ് ചെയ്യുക"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<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> നിയന്ത്രിത ബക്കറ്റിലേക്ക് നീക്കി"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"പുതിയത്: വിൻഡോ മാഗ്നിഫൈയർ"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"സ്ക്രീനിന്റെ ഭാഗങ്ങളോ മുഴുവനുമോ മാഗ്നിഫൈ ചെയ്യാം"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"നിങ്ങളുടെ സ്ക്രീനിന്റെ ഒരു ഭാഗം മാഗ്നിഫൈ ചെയ്യുക"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"നിങ്ങൾക്ക് സ്ക്രീൻ പൂർണ്ണമായോ, ഒരു പ്രത്യേക ഭാഗമോ മാഗ്നിഫൈ ചെയ്യാം അല്ലെങ്കിൽ ഈ രണ്ട് ഓപ്ഷനുകൾക്കിടയിൽ പരസ്‌പരം മാറുക."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"ക്രമീകരണത്തിൽ ഓണാക്കുക"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"ഡിസ്‌മിസ് ചെയ്യുക"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"തുടരാൻ, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ആപ്പിന് നിങ്ങളുടെ ഉപകരണത്തിന്റെ മൈക്രോഫോണിലേക്ക് ആക്‌സസ് നൽകേണ്ടതുണ്ട്."</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"സെൻസർ സ്വകാര്യത"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"ആപ്പ് ഐക്കൺ"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"അപ്ലിക്കേഷൻ ബ്രാൻഡിംഗ് ഇമേജ്"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"ആക്‌സസ് ക്രമീകരണം പരിശോധിക്കുക"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> എന്നതിന് നിങ്ങളുടെ സ്ക്രീൻ കാണാനും നിയന്ത്രിക്കാനും കഴിയും. അവലോകനം ചെയ്യുന്നതിന് ടാപ്പ് ചെയ്യുക."</string>
 </resources>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index faec2be..99c4628 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Twilight үйлчилгээ"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Цагийн бүс илрүүлэгч (Холболт байхгүй)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS Хугацаа шинэчлэлтийн үйлчилгээ"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Хөгжим танилтын менежерийн үйлчилгээ"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Таны төхөөрөмж устах болно."</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Админ аппыг ашиглах боломжгүй. Таны төхөөрөмжийг одоо устгана.\n\nХэрэв танд асуулт байгаа бол байгууллагынхаа админтай холбогдоно уу."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> хэвлэх үйлдлийг идэвхгүй болгосон."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Апп ажиллаж байна"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Апп батарей ашиглаж байна"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Томруулах"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Хандалтын аюулгүй байдлын бодлого"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> батерей ашиглаж байна"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> апп батерей ашиглаж байна"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Батерей, дата ашиглалтын талаар дэлгэрэнгүйг харахын тулд товшино уу"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Апп нь статус самбар болох боломжтой."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"статус самбарыг нээх/хаах"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Апп нь статус самбарыг дэлгэх болон хаах боломжтой."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"мэдэгдлийг түгжигдсэн төхөөрөмж дээр бүтэн дэлгэцийн үйл ажиллагаа байдлаар үзүүлэх"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Аппад мэдэгдлийг түгжигдсэн төхөөрөмж дээр бүтэн дэлгэцийн үйл ажиллагаа байдлаар үзүүлэхийг зөвшөөрдөг"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"товчлол суулгах"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Аппликейшн нь хэрэглэгчийн оролцоогүйгээр Нүүр дэлгэцний товчлолыг нэмж чадна."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"товчлолыг устгах"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Биометр эсвэл дэлгэцийн түгжээ ашиглах"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Өөрийгөө мөн гэдгийг баталгаажуулаарай"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Үргэлжлүүлэхийн тулд биометрээ ашиглана уу"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Үргэлжлүүлэхийн тулд биометр эсвэл дэлгэцийн түгжээгээ ашиглана уу"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Биометрийн техник хангамж боломжгүй байна"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Нотолгоог цуцаллаа"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Таниагүй"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Хурууны хээ ашиглах"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Хурууны хээ эсвэл дэлгэцийн түгжээ ашиглах"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Үргэлжлүүлэхийн тулд хурууны хээгээ ашиглаарай"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Үргэлжлүүлэхийн тулд хурууны хээ эсвэл дэлгэцийн түгжээгээ ашиглана уу"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Хурууны хээний дүрс"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Царайгаар тайлахыг ашиглах"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Царай эсвэл дэлгэцийн түгжээ ашиглах"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Үргэлжлүүлэхийн тулд царайгаар тайлахыг ашиглана уу"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Үргэлжлүүлэхийн тулд царай эсвэл дэлгэцийн түгжээгээ ашиглана уу"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Царайны дүрс тэмдэг"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"Танд энэ хуудсыг нээх зөвшөөрөл байхгүй."</string>
     <string name="text_copied" msgid="2531420577879738860">"Текст хуулагдав."</string>
     <string name="copied" msgid="4675902854553014676">"Хуулсан"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>-с буулгасан <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"Түр санах ойгоос буулгасан <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>"</string>
     <string name="more_item_label" msgid="7419249600215749115">"Илүү"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Цэс+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Мета+"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Унтраах"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"<xliff:g id="NAME">%s</xliff:g>-г шалгаж байна…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Одоогийн агуулгыг хянаж байна"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Медиагийн хадгалах санг задлан шинжилж байна"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Шинэ <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> ажиллахгүй байна"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Тохируулахын тулд товшино уу"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Тохируулахын тулд сонгоно уу"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Та төхөөрөмжийг дахин форматлах шаардлагатай байж болзошгүй. Салгахын тулд товшино уу."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"Зураг, медиа шилжүүлэхэд зориулсан"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Медиа файлуудыг үзэх"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"<xliff:g id="NAME">%s</xliff:g> алдаатай байна"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> ажиллахгүй байна"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Засахын тулд товшино уу"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"Дэмжээгүй <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> ажиллахгүй байна"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"Энэ төхөөрөмж нь <xliff:g id="NAME">%s</xliff:g>-г дэмждэггүй. Дэмжигдсэн хэлбэршүүлэлтэд тохируулахын тулд товшино уу."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"Энэ төхөөрөмж <xliff:g id="NAME">%s</xliff:g>-г дэмждэггүй. Дэмжсэн хэлбэршүүлэлтэд тохируулахын тулд сонгоно уу."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"<xliff:g id="NAME">%s</xliff:g>-г дэмжигдсэн форматаар тохируулахын тулд сонгоно уу."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Та төхөөрөмжийг дахин форматлах шаардлагатай байж болзошгүй"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g>-ыг гэнэт гаргасан байна"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Агуулга алдахаас сэргийлэхийн тулд медиаг төхөөрөмжөөс салгахаасаа өмнө холболтыг салгана уу"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Товчлол ашиглах"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Өнгө хувиргалт"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Өнгөний засвар"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Гэрэлтүүлгийг багасгах"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Хэт бүүдгэр"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Дууны түвшний түлхүүрийг удаан дарсан. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>-г асаалаа."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Дууны түвшний түлхүүрийг удаан дарсан. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>-г унтраалаа."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>-г ашиглахын тулд дууны түвшнийг ихэсгэх, багасгах түлхүүрийг 3 секундийн турш зэрэг дарна уу"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Дэлгэц дээрх хандалтын товчлол"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Дэлгэц дээрх хандалтын товчлол сонгогч"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Хандалтын товчлол"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Мэдэгдлийн хураангуй самбарыг хаах"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<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>-г ХЯЗГААРЛАСАН сагс руу орууллаа"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Шинэ: Цонх томруулагч"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Та одоо зарим эсвэл бүх дэлгэцээ томруулж болно"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Дэлгэцийнхээ хэсгийг томруулаарай"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Та одоо бүтэн дэлгэц, тодорхой хэсгээ томруулах эсвэл аль аль сонголтын хооронд сэлгэх боломжтой."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Тохиргоонд асаана уу"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Үл хэрэгсэх"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Үргэлжлүүлэхийн тулд, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; таны төхөөрөмжийн микрофонд хандах шаардлагатай."</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Мэдрэгчийн нууцлал"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Аппын дүрс тэмдэг"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Аппын брэнд зураг"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Хандалтын тохиргоог шалгана уу"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> таны дэлгэцийг харах болон хянах боломжтой. Хянахын тулд товшино уу."</string>
 </resources>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 102c469..adb86de 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"ट्वायलाइट सेवा"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"टाइम झोन डिटेक्टर (कनेक्टिव्हिटी नाही)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS ची वेळ अपडेट करणारी सेवा"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"संगीत ओळख व्यवस्थापक सेवा"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"तुमचे डिव्हाइस मिटविले जाईल"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"प्रशासक अ‍ॅप वापरता येणार नाही. तुमचे डिव्हाइस आता साफ केले जाईल.\n\nतुम्हाला कुठलेही प्रश्न असल्यास, तुमच्या संस्थेच्या प्रशासकाशी संपर्क साधा."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> नी प्रिंट करणे बंद केले आहे."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"APP चालत आहे"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"बॅटरी लवकर संपवणारी अ‍ॅप्स"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"मॅग्निफिकेशन"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"अ‍ॅक्सेसिबिलिटी सुरक्षा धोरण"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> बॅटरी वापरत आहे"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> अ‍ॅप्स बॅटरी वापरत आहेत"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"बॅटरी आणि डेटा वापराच्‍या तपशीलांसाठी टॅप करा"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"स्टेटस बार होण्यासाठी अ‍ॅप ला अनुमती देते."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"स्‍टेटस बार विस्तृत करा/संकुचित करा"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"स्टेटस बार विस्तृत करण्यासाठी किंवा संक्षिप्त करण्यासाठी अ‍ॅप ला अनुमती देते."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"लॉक केलेल्या डिव्हाइसवर फुल स्क्रीन अ‍ॅक्टिव्हिटी म्हणून सूचना प्रदर्शित करणे"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"लॉक केलेल्या डिव्हाइसवर फुल स्क्रीन अ‍ॅक्टिव्हिटी म्हणून सूचना प्रदर्शित करण्यासाठी ॲपला अनुमती द्या"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"शॉर्टकट स्‍थापित करा"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"अनुप्रयोगाला वापरकर्ता हस्‍तक्षेपाशिवाय मुख्‍यस्‍क्रीन शॉर्टकट जोडण्‍याची अनुमती देते."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"शॉर्टकट विस्‍थापित करा"</string>
@@ -550,23 +554,19 @@
     <string name="permdesc_imagesWrite" msgid="5195054463269193317">"ॲपला तुमच्या फोटो संग्रहामध्ये सुधारणा करण्याची अनुमती देते."</string>
     <string name="permlab_mediaLocation" msgid="7368098373378598066">"तुमच्या मीडिया संग्रहातून स्थाने वाचा"</string>
     <string name="permdesc_mediaLocation" msgid="597912899423578138">"ॲपला तुमच्या मीडिया संग्रहामध्येील स्थाने वाचण्यासाठी अनुमती देते."</string>
-    <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
-    <skip />
-    <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
-    <skip />
+    <string name="biometric_app_setting_name" msgid="3339209978734534457">"बायोमेट्रिक वापरा"</string>
+    <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"बायोमेट्रिक किंवा स्क्रीन लॉक वापरा"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"हे तुम्हीच आहात याची पडताळणी करा"</string>
-    <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
-    <skip />
+    <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"पुढे सुरू ठेवण्यासाठी तुमचे बायोमेट्रिक वापरा"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"पुढे सुरू ठेवण्यासाठी तुमचे बायोमेट्रिक किंवा स्क्रीन लॉक वापरा"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"बायोमेट्रिक हार्डवेअर उपलब्ध नाही"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"ऑथेंटिकेशन रद्द केले"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"ओळखले नाही"</string>
     <string name="biometric_error_canceled" msgid="8266582404844179778">"ऑथेंटिकेशन रद्द केले"</string>
     <string name="biometric_error_device_not_secured" msgid="3129845065043995924">"कोणताही पिन, पॅटर्न किंवा पासवर्ड सेट केलेला नाही"</string>
     <string name="biometric_error_generic" msgid="6784371929985434439">"एरर ऑथेंटिकेट करत आहे"</string>
-    <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
-    <skip />
-    <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
-    <skip />
+    <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"स्क्रीन लॉक वापरा"</string>
+    <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"पुढे सुरू ठेवण्यासाठी तुमच्या डिव्हाइसचे क्रेडेंशियल एंटर करा"</string>
     <string name="fingerprint_acquired_partial" msgid="8532380671091299342">"आंशिक फिंगरप्रिंट आढळली. कृपया पुन्हा प्रयत्न करा."</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"फिंगरप्रिंटवर प्रक्रिया करणे शक्य झाले नाही. कृपया पुन्हा प्रयत्न करा."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"फिंगरप्रिंट सेन्सर खराब आहे. कृपया साफ करा आणि पुन्हा प्रयत्न करा."</string>
@@ -589,11 +589,10 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"या डिव्हाइसमध्ये फिंगरप्रिंट सेन्सर नाही."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"सेन्सर तात्पुरता बंद केला आहे."</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g> बोट"</string>
-    <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
-    <skip />
-    <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
-    <skip />
+    <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"फिंगरप्रिंट वापरा"</string>
+    <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"फिंगरप्रिंट किंवा स्क्रीन लॉक वापरा"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"पुढे सुरू ठेवण्‍यासाठी तुमची फिंगरप्रिंट वापरा"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"पुढे सुरू ठेवण्यासाठी तुमचे फिंगरप्रिंट किंवा स्क्रीन लॉक वापरा"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"फिंगरप्रिंट आयकन"</string>
@@ -638,12 +637,10 @@
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"या डिव्हाइसवर फेस अनलॉकला सपोर्ट नाही."</string>
     <string name="face_error_security_update_required" msgid="5076017208528750161">"सेन्सर तात्पुरता बंद केला आहे."</string>
     <string name="face_name_template" msgid="3877037340223318119">"चेहरा <xliff:g id="FACEID">%d</xliff:g>"</string>
-    <!-- no translation found for face_app_setting_name (8130135875458467243) -->
-    <skip />
-    <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
-    <skip />
-    <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
-    <skip />
+    <string name="face_app_setting_name" msgid="8130135875458467243">"फेस अनलॉक वापरा"</string>
+    <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"फेस किंवा स्क्रीन लॉक वापरा"</string>
+    <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"पुढे सुरू ठेवण्यासाठी फेस अनलॉक वापरा"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"पुढे सुरू ठेवण्यासाठी तुमचा चेहरा किंवा स्क्रीन लॉक वापरा"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"चेहरा आयकन"</string>
@@ -1007,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"तुम्हाला हे पृष्ठ उघडण्याची परवानगी नाही."</string>
     <string name="text_copied" msgid="2531420577879738860">"मजकूर क्लिपबोर्डवर कॉपी केला."</string>
     <string name="copied" msgid="4675902854553014676">"कॉपी केले"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> वरून <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> पेस्ट केले"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"क्लिपबोर्डवरून <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> पेस्ट केले"</string>
     <string name="more_item_label" msgid="7419249600215749115">"अधिक"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"मेनू+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1380,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"बंद करा"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"<xliff:g id="NAME">%s</xliff:g> तपासत आहे…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"सध्याच्या आशयाचे पुनरावलोकन करत आहे"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"मीडिया स्टोरेजचे विश्लेषण करत आहे"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"नवीन <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> काम करत नाही"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"सेट करण्यासाठी टॅप करा"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"सेट अप करण्यासाठी निवडा"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"तुम्हाला डिव्हाइस पुन्हा फॉरमॅट करावे लागू शकते. बाहेर काढण्यासाठी टॅप करा."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"फोटो आणि मीडिया स्थानांतरित करण्‍यासाठी"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"मीडिया फाइल ब्राउझ करा"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"<xliff:g id="NAME">%s</xliff:g> सह समस्या"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> काम करत नाही"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"दुरुस्त करण्‍यासाठी टॅप करा"</string>
@@ -1393,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"<xliff:g id="NAME">%s</xliff:g> असमर्थित"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> काम करत नाही"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"हे डिव्हाइस <xliff:g id="NAME">%s</xliff:g> ला सपोर्ट करत नाही. सपोर्ट असलेल्या फॉरमॅटमध्ये सेट करण्यासाठी टॅप करा."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"हे डिव्हाइस <xliff:g id="NAME">%s</xliff:g> ला सपोर्ट करत नाही. सपोर्ट असलेल्या फॉरमॅटमध्ये सेट करण्यासाठी निवडा."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"सपोर्ट असलेल्या फॉरमॅटमध्ये <xliff:g id="NAME">%s</xliff:g> सेट करण्यासाठी निवडा."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"तुम्हाला डिव्हाइस पुन्हा फॉरमॅट करावे लागू शकते"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> अनपेक्षितरित्या काढले"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"आशय गमावणे टाळण्यासाठी काढून टाकण्यापूर्वी मीडिया इजेक्ट करा"</string>
@@ -1687,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"शॉर्टकट वापरा"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"रंगांची उलटापालट"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"रंग सुधारणा"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"ब्राइटनेस कमी करा"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"आणखी डिम"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"धरून ठेवलेल्या व्हॉल्यूम की. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> सुरू केला आहे."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"धरून ठेवलेल्या व्हॉल्यूम की. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> बंद केले आहे."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> वापरण्यासाठी दोन्ही व्हॉल्युम की तीन सेकंद दाबा आणि धरून ठेवा"</string>
@@ -1966,8 +1968,7 @@
     <string name="app_category_news" msgid="1172762719574964544">"बातम्‍या आणि मासिके"</string>
     <string name="app_category_maps" msgid="6395725487922533156">"नकाशे आणि नेव्हिगेशन"</string>
     <string name="app_category_productivity" msgid="1844422703029557883">"उत्पादनक्षमता"</string>
-    <!-- no translation found for app_category_accessibility (6643521607848547683) -->
-    <skip />
+    <string name="app_category_accessibility" msgid="6643521607848547683">"अ‍ॅक्सेसिबिलिटी"</string>
     <string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"डिव्हाइस स्टोरेज"</string>
     <string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB डीबगिंग"</string>
     <string name="time_picker_hour_label" msgid="4208590187662336864">"तास"</string>
@@ -2097,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"ऑन-स्क्रीन ॲक्सेसिबिलिटी शॉर्टकट"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"ऑन-स्क्रीन ॲक्सेसिबिलिटी शॉर्टकट निवडकर्ता"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"अ‍ॅक्सेसिबिलिटी शॉर्टकट"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"सूचना शेड डिसमिस करा"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<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> हे प्रतिबंधित बादलीमध्ये ठेवण्यात आले आहे"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2234,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"नवीन: विंडो मॅग्निफायर"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"आता स्क्रीन अंशतः किंवा पूर्ण मॅग्निफाय करू शकता"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"तुमच्या स्क्रीनचा काही भाग मॅग्निफाय करा"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"आता तुम्ही तुमची फुल स्क्रीन, विशिष्ट भाग मॅग्निफाय करू शकता किंवा दोन्ही पर्यायांमध्ये स्विच करू शकता."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"सेटिंग्ज मध्ये सुरू करा"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"डिसमिस करा"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"पुढे सुरू ठेवण्यासाठी, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ला तुमच्या डिव्हाइसचा मायक्रोफोन अ‍ॅक्सेस करण्याची आवश्यकता आहे."</string>
@@ -2244,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"सेन्सरशी संबंधित गोपनीयतेबाबत सूचना"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"ॲप्लिकेशन आयकन"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"अ‍ॅप्लिकेशन ब्रॅंडिंग इमेज"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"अ‍ॅक्सेसशी संबंधित सेटिंग्ज तपासा"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> हे तुमची स्क्रीन पाहू शकते आणि नियंत्रित करू शकते. परीक्षण करण्यासाठी टॅप करा."</string>
 </resources>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 3bf3063..9550abb 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Perkhidmatan Twilight"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Pengesan Zon Waktu (Tiada kesambungan)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"Perkhidmatan Kemaskinian Waktu GNSS"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Perkhidmatan Pengurus Pengecaman Muzik"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Peranti anda akan dipadam"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Apl pentadbir tidak dapat digunakan. Peranti anda akan dipadamkan sekarang.\n\nJika anda ingin mengemukakan soalan, hubungi pentadbir organisasi anda."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Pencetakan dilumpuhkan oleh <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Apl berjalan"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Apl yang menggunakan bateri"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Pembesaran"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Dasar keselamatan kebolehaksesan"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> sedang menggunakan bateri"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> apl sedang menggunakan bateri"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Ketik untuk mendapatkan butiran tentang penggunaan kuasa bateri dan data"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Membenarkan apl menjadi bar status."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"kembangkan/runtuhkan bar status"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Membenarkan apl mengembangkan atau meruntuhkan bar status."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"paparkan pemberitahuan sebagai aktiviti skrin penuh pada peranti yang dikunci"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Membolehkan apl memaparkan pemberitahuan sebagai aktiviti skrin penuh pada peranti yang dikunci"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"pasang pintasan"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Membenarkan aplikasi menambah pintasan Skrin Laman Utama tanpa campur tangan pengguna."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"nyahpasang pintasan"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Gunakan biometrik atau kunci skrin"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Sahkan itu anda"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Gunakan biometrik anda untuk meneruskan"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Gunakan biometrik atau kunci skrin anda untuk meneruskan pengesahan"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Perkakasan biometrik tidak tersedia"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Pengesahan dibatalkan"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Tidak dikenali"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Gunakan cap jari"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Gunakan cap jari atau kunci skrin"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Gunakan cap jari anda untuk teruskan"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Gunakan cap jari atau kunci skrin anda untuk meneruskan"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikon cap jari"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Gunakan wajah buka kunci"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Gunakan kunci wajah atau skrin"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Gunakan wajah buka kunci untuk meneruskan"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Gunakan wajah atau kunci skrin anda untuk meneruskan"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Ikon wajah"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"Anda tidak mempunyai kebenaran untuk membuka laman ini."</string>
     <string name="text_copied" msgid="2531420577879738860">"Teks disalin ke papan keratan"</string>
     <string name="copied" msgid="4675902854553014676">"Disalin"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ditampalkan daripada <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ditampalkan daripada papan keratan"</string>
     <string name="more_item_label" msgid="7419249600215749115">"Lagi"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Menu+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Matikan"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Menyemak <xliff:g id="NAME">%s</xliff:g>…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Menyemak kandungan semasa"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Menganalisis storan media"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"<xliff:g id="NAME">%s</xliff:g> baharu"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> tidak berfungsi"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Ketik untuk menyediakan"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Pilih untuk penyediaan"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Anda mungkin perlu memformatkan semula peranti. Ketik untuk mengeluarkan media."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"Untuk memindahkan foto dan media"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Semak imbas fail media"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Isu dengan <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> tidak berfungsi"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Ketik untuk menyelesaikan masalah"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"<xliff:g id="NAME">%s</xliff:g> tidak disokong"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> tidak berfungsi"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"Peranti ini tidak menyokong <xliff:g id="NAME">%s</xliff:g> ini. Ketik untuk menyediakannya dalam format yang disokong."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"Peranti ini tidak menyokong <xliff:g id="NAME">%s</xliff:g> ini. Pilih untuk menyediakan media dalam format yang disokong."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Pilih untuk menyediakan <xliff:g id="NAME">%s</xliff:g> dalam format yang disokong."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Anda mungkin perlu memformatkan semula peranti"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> ditanggalkan tanpa dijangka"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Keluarkan media sebelum menanggalkan media itu untuk mengelakkan kehilangan kandungan"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Gunakan Pintasan"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Penyongsangan Warna"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Pembetulan Warna"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Kurangkan kecerahan"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Amat malap"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Kekunci kelantangan ditahan. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> dihidupkan."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Kekunci kelantangan ditahan. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> dimatikan."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Tekan dan tahan kedua-dua kekunci kelantangan selama tiga saat untuk menggunakan <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Pintasan Kebolehaksesan Pada Skrin"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Pemilih Pintasan Kebolehaksesan Pada Skrin"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Pintasan Kebolehaksesan"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Ketepikan Bidai Pemberitahuan"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Bar kapsyen <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> telah diletakkan dalam baldi TERHAD"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Baharu: Pembesar Tetingkap"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Besarkan sebahagian atau keseluruhan skrin anda"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Besarkan sebahagian skrin anda"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Kini anda boleh membesarkan skrin penuh, kawasan tertentu atau beralih antara kedua-dua pilihan."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Hidupkan dalam Tetapan"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Tolak"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Untuk meneruskan proses, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; memerlukan akses kepada mikrofon peranti anda."</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privasi Penderia"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Ikon aplikasi"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Imej jenama aplikasi"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Semak tetapan akses"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> boleh melihat dan mengawal skrin anda. Ketik untuk menyemak."</string>
 </resources>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index f301483..165db32 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"နေဝင်ဆည်းဆာ ဝန်ဆောင်မှု"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"ဒေသစံတော်ချိန် ရှာဖွေစနစ် (ချိတ်ဆက်နိုင်မှု မလိုပါ)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS အချိန်အပ်ဒိတ် ဝန်ဆောင်မှု"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"တေးဂီတကို သိရှိမှတ်မိခြင်း စီမံခန့်ခွဲမှုစနစ် ဝန်ဆောင်မှု"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"သင့်ကိရိယာအား ပယ်ဖျက်လိမ့်မည်"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"စီမံခန့်ခွဲမှု အက်ပ်ကို သုံး၍မရပါ။ သင်၏ စက်ပစ္စည်းအတွင်းရှိ အရာများကို ဖျက်လိုက်ပါမည်\n\nမေးစရာများရှိပါက သင့်အဖွဲ့အစည်း၏ စီမံခန့်ခွဲသူကို ဆက်သွယ်ပါ။"</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> က ပုံနှိပ်ထုတ်ယူခြင်းကို ပိတ်ထားသည်။"</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"APP လုပ်ဆောင်နေသည်"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"အက်ပ်များက ဘက်ထရီကုန်စေသည်"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"ချဲ့ခြင်း"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"အများသုံးစွဲနိုင်မှုဆိုင်ရာ လုံခြုံရေးမူဝါဒ"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> က ဘက်ထရီကို အသုံးပြုနေသည်"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"အက်ပ် <xliff:g id="NUMBER">%1$d</xliff:g> ခုက ဘက်ထရီကို အသုံးပြုနေသည်"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"ဘက်ထရီနှင့် ဒေတာအသုံးပြုမှု အသေးစိတ်ကို ကြည့်ရန် တို့ပါ"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"အက်ပ်အား အခြေအနေပြ ဘားဖြစ်ခွင့် ပြုသည်။"</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"အခြေအနေပြဘားအား ချဲ့/ပြန့်ခြင်း"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"အက်ပ်အား အခြေအနေပြ ဘားကို ချဲ့ခွင့် သို့မဟုတ် ခေါက်သိမ်းခွင့် ပြုသည်။"</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"လော့ခ်ချထားသော စက်ပစ္စည်းပေါ်တွင် အကြောင်းကြားချက်များကို ဖန်သားပြင်အပြည့် လုပ်ဆောင်ချက်များအဖြစ် ပြခြင်း"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"လော့ခ်ချထားသော စက်ပစ္စည်းပေါ်တွင် အကြောင်းကြားချက်များကို ဖန်သားပြင်အပြည့် လုပ်ဆောင်ချက်များအဖြစ် ပြရန် အက်ပ်ကို ခွင့်ပြုသည်"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"အတိုကောက်များအား ထည့်သွင်းခြင်း"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"အပလီကေးရှင်းအား အသုံးပြုသူ လုပ်ဆောင်ခြင်း မပါပဲ ပင်မ မြင်ကွင်းအား ပြောင်းလဲခွင့် ပေးခြင်း"</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"အတိုကောက်များ ဖယ်ထုတ်ခြင်း"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"ဇီဝမက်ထရစ်အချက်အလက်များ (သို့) ဖန်သားပြင်လော့ခ်ချခြင်းကို သုံးခြင်း"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"သင်ဖြစ်ကြောင်း အတည်ပြုပါ"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"ရှေ့ဆက်ရန် သင်၏ ဇီဝမက်ထရစ်အချက်အလက်ကို သုံးပါ"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"ရှေ့ဆက်ရန် သင်၏ ဇီဝမက်ထရစ်အချက်အလက် (သို့) ဖန်သားပြင်လော့ခ်ကို သုံးပါ"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"ဇီဝအချက်အလက်သုံး ကွန်ပျူတာစက်ပစ္စည်း မရရှိနိုင်ပါ"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"အထောက်အထားစိစစ်ခြင်းကို ပယ်ဖျက်လိုက်သည်"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"မသိ"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"လက်ဗွေ သုံးခြင်း"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"လက်ဗွေ (သို့) ဖန်သားပြင်လော့ခ်ချခြင်းကို သုံးခြင်း"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"ရှေ့ဆက်ရန် သင့်လက်ဗွေကို သုံးပါ"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"ရှေ့ဆက်ရန် သင်၏ လက်ဗွေ (သို့) ဖန်သားပြင်လော့ခ်ကို သုံးပါ"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"လက်ဗွေ သင်္ကေတ"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"မျက်နှာမှတ်သော့ဖွင့်ခြင်းကို သုံးခြင်း"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"မျက်နှာမှတ်သော့ဖွင့်ခြင်း (သို့) ဖန်သားပြင်လော့ခ်ချခြင်းကို သုံးခြင်း"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"ရှေ့ဆက်ရန် မျက်နှာမှတ်သော့ဖွင့်ခြင်းကို သုံးပါ"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"ရှေ့ဆက်ရန် သင်၏ မျက်နှာ (သို့) ဖန်သားပြင်လော့ခ်ကို သုံးပါ"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"မျက်နှာသင်္ကေတ"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"သင့်ဆီမှာ ဒီစာမျက်နှာကို ဖွင့်ရန် ခွင့်ပြုချက် မရှိပါ။"</string>
     <string name="text_copied" msgid="2531420577879738860">"clipboardထံ စာသားအားကူးယူမည်"</string>
     <string name="copied" msgid="4675902854553014676">"မိတ္တူကူးပြီးပါပြီ"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> မှ <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> သို့ ကူးထည့်ထားသည်"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"ကလစ်ဘုတ်မှ <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> သို့ ကူးထည့်ထားသည်"</string>
     <string name="more_item_label" msgid="7419249600215749115">"နောက်ထပ်"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Menu+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"ပိတ်ရန်"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"<xliff:g id="NAME">%s</xliff:g> ကို စစ်နေသည်…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"လက်ရှိ အကြောင်းအရာကို ပြန်လည်သုံးသပ်နေသည်"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"မီဒီယာသိုလှောင်ခန်းကို ပိုင်းခြားစိတ်ဖြာနေသည်"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"<xliff:g id="NAME">%s</xliff:g> အသစ်"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> အလုပ်မလုပ်ပါ"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"စနစ်ထည့်သွင်းရန် တို့ပါ"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"စနစ်ထည့်သွင်းရန် ရွေးပါ"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"စက်ကို ပြန်လည်ဖော်မက်လုပ်ရန် လိုအပ်နိုင်သည်။ ပယ်ရန် တို့ပါ။"</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"ဓာတ်ပုံနှင့် မီဒီယာများ လွှဲပြောင်းရန်အတွက်"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"မီဒီယာဖိုင်များကို ရှာကြည့်ပါ"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"<xliff:g id="NAME">%s</xliff:g> တွင် ပြဿနာရှိနေသည်"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> အလုပ်မလုပ်ပါ"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"ပြင်ဆင်ရန်အတွက် ထိလိုက်ပါ"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"ပံ့ပိုးထားခြင်း မရှိသော <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> အလုပ်မလုပ်ပါ"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"ဤစက်ပစ္စည်းတွင် <xliff:g id="NAME">%s</xliff:g> ကိုအသုံးပြု၍မရပါ။ အသုံးပြု၍ရသော စနစ်ပုံစံသို့သတ်မှတ်ရန် တို့ပါ။"</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"ဤစက်ပစ္စည်းတွင် <xliff:g id="NAME">%s</xliff:g> ကို ပံ့ပိုးမထားပါ။ ပံ့ပိုးသည့်ပုံစံတစ်ခုအဖြစ် စနစ်ထည့်သွင်းရန် ရွေးချယ်ပါ။"</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"<xliff:g id="NAME">%s</xliff:g> ကို ပံ့ပိုးထားသောဖော်မက်ဖြင့် စနစ်ထည့်သွင်းရန် ရွေးပါ။"</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"စက်ကို ပြန်လည်ဖော်မက်လုပ်ရန် လိုအပ်နိုင်သည်"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> မမျှော်လင့်ဘဲ ဖယ်ရှားခဲ့သည်"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"အကြောင်းအရာ မဆုံးရှုံးစေရန် မီဒီယာကို မဖယ်ရှားမီ ဦးစွာထုတ်လိုက်ပါ"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ဖြတ်လမ်းလင့်ခ်ကို သုံးရန်"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"အရောင် ပြောင်းပြန်လှန်ခြင်း"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"အရောင်ပြင်ဆင်ခြင်း"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"တောက်ပမှုကို လျှော့ခြင်း"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"ပိုမှိန်ခြင်း"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"အသံခလုတ်များကို ဖိထားသည်။ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ဖွင့်လိုက်သည်။"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"အသံခလုတ်များကို ဖိထားသည်။ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ပိတ်လိုက်သည်။"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ကို သုံးရန် အသံအတိုးအလျှော့ ခလုတ်နှစ်ခုလုံးကို သုံးစက္ကန့်ကြာ ဖိထားပါ"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"ဖန်သားပြင်အတွက် အများသုံးစွဲနိုင်မှုဖြတ်လမ်းလင့်ခ်"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"ဖန်သားပြင်အတွက် အများသုံးစွဲနိုင်မှုဖြတ်လမ်းလင့်ခ် ရွေးချယ်စနစ်"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"အများသုံးစွဲနိုင်မှု ဖြတ်လမ်းလင့်ခ်"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"အကြောင်းကြားစာအကွက်ကို ပယ်ရန်"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<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> ကို တားမြစ်ထားသော သိမ်းဆည်းမှုအတွင်းသို့ ထည့်ပြီးပါပြီ"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>-"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"အသစ်- ဝင်းဒိုးမှန်ဘီလူး"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"ဖန်သားပြင် တစ်စိတ်တစ်ပိုင်း (သို့) တစ်ခုလုံး ချဲ့နိုင်ပါပြီ"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"သင့်ဖန်သားပြင်၏ တစ်စိတ်တစ်ပိုင်းကို ချဲ့ပါ"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"ဖန်သားပြင်အပြည့် ချဲ့ခြင်း၊ သတ်မှတ်ဧရိယာကို ချဲ့ခြင်း သို့မဟုတ် နည်းလမ်းနှစ်ခုလုံးကြား ပြောင်းခြင်းတို့ကို လုပ်နိုင်ပါပြီ။"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"\'ဆက်တင်များ\' တွင် ဖွင့်ရန်"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"ပယ်ရန်"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"ဆက်လက်လုပ်ဆောင်ရန် &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; က သင့်စက်၏ မိုက်ခရိုဖုန်းကို အသုံးပြုခွင့်ရရန် လိုအပ်သည်။"</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"အာရုံခံကိရိယာ လုံခြုံရေး"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"အပလီကေးရှင်း သင်္ကေတ"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"အပလီကေးရှင်း ကုန်အမှတ်တံဆိပ်ပုံ"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"အသုံးပြုခွင့် ဆက်တင်များကို စစ်ဆေးပါ"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> က သင့်ဖန်သားပြင်ကို ကြည့်ရှုပြီး ထိန်းချုပ်နိုင်သည်။ ပြန်ကြည့်ရန် တို့ပါ။"</string>
 </resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 07cf9c0..b2b4675 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Twilight Service"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Tidssoneoppdagelse (ingen tilkobling)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS-tjeneste for tidsoppdatering"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Administreringstjeneste for musikkgjenkjenning"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Enheten blir slettet"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Administratorappen kan ikke brukes. Enheten din blir nå tømt.\n\nTa kontakt med administratoren for organisasjonen din hvis du har spørsmål."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> har slått av utskrift."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"App kjører"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Apper bruker batteri"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Forstørring"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Sikkerhetsretningslinjer for tilgjengelighet"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> bruker batteri"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> apper bruker batteri"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Trykk for detaljer om batteri- og databruk"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Gir appen tillatelse til å vises i statusfeltet."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"utvide/slå sammen statusfeltet"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Lar appen utvide eller skjule statuslinjen."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"vis varsler som aktiviteter i fullskjerm på en låst enhet"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Gir appen tillatelse til å vise varsler som aktiviteter i fullskjerm på en låst enhet"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"installere snarveier"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Lar appen legge til snarveier på startsiden uten å involvere brukeren."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"avinstallere snarveier"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Bruk biometri eller skjermlås"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Bekreft at det er deg"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Bruk biometri for å fortsette"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Bruk biometri eller skjermlåsen for å fortsette"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrisk maskinvare er utilgjengelig"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Autentiseringen er avbrutt"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Ikke gjenkjent"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Bruk fingeravtrykk"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Bruk fingeravtrykk eller skjermlås"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Bruk fingeravtrykket ditt for å fortsette"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Bruk fingeravtrykket eller skjermlåsen for å fortsette"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikon for fingeravtrykk"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Bruk ansiktslås"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Bruk ansikts- eller skjermlås"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Bruk ansiktslås for å fortsette"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Bruk ansikts- eller skjermlåsen for å fortsette"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Ansiktikon"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"Du har ikke tillatelse til å åpne denne siden."</string>
     <string name="text_copied" msgid="2531420577879738860">"Kopierte tekst til utklippstavlen."</string>
     <string name="copied" msgid="4675902854553014676">"Kopiert"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> limte inn fra <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> limte inn fra utklippstavlen"</string>
     <string name="more_item_label" msgid="7419249600215749115">"Mer"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"menyknapp+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Slå av"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Sjekker <xliff:g id="NAME">%s</xliff:g> …"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Gjennomgår nåværende innhold"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Analyserer medielagring"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Ny <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> fungerer ikke"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Trykk for å konfigurere"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Velg for å konfigurere"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Du må muligens reformatere enheten. Trykk for å løse ut."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"For overføring av bilder og medier"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Bla gjennom mediefiler"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Problem med <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> fungerer ikke"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Trykk for å løse problemet"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"<xliff:g id="NAME">%s</xliff:g> som ikke støttes"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> fungerer ikke"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"Denne enheten støtter ikke <xliff:g id="NAME">%s</xliff:g>. Trykk for å konfigurere i et støttet format."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"Denne enheten støtter ikke dette <xliff:g id="NAME">%s</xliff:g>. Velg for å konfigurere i et støttet format."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Velg for å konfigurere <xliff:g id="NAME">%s</xliff:g> i et format som støttes."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Du må muligens reformatere enheten"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> ble uventet fjernet"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Løs ut media før det tas ut for å unngå tap av innhold"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Bruk snarveien"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Fargeinvertering"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Fargekorrigering"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Reduser lysstyrken"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Ekstra dempet belysning"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Volumtastene holdes inne. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> er slått på."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Volumtastene holdes inne. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> er slått av."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Trykk og hold inne begge volumtastene i tre sekunder for å bruke <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Tilgjengelighetssnarvei på skjermen"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Velger for tilgjengelighetssnarvei på skjermen"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Tilgjengelighetssnarvei"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Lukk varselpanelet"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Tekstingsfelt i <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> er blitt plassert i TILGANGSBEGRENSET-toppmappen"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Nytt: vindusforstørrer"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Nå kan du forstørre deler av eller hele skjermen"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Forstørr en del av skjermen"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Nå kan du forstørre fullskjermen eller et bestemt område eller bytte mellom de to alternativene."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Slå på i innstillingene"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Avvis"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"For å fortsette må &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ha tilgang til enhetsmikrofonen."</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Sensorpersonvern"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Appikon"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Merkevareprofilen til appen"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Sjekk tilgangsinnstillingene"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> kan se og kontrollere skjermen. Trykk for å gjennomgå."</string>
 </resources>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 6295d44..64d825c 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"ट्वाइलाइट सेवा"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"समय क्षेत्र पत्ता लगाउने सुविधा (नेटवर्क कनेक्सन नहुँदा)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS को समय अपडेट गर्ने सेवा"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"सङ्गीत पहिचान गर्ने सुविधा व्यवस्थापन गर्ने सेवा"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"तपाईंको यन्त्र मेटिनेछ"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"प्रशासकको एप प्रयोग गर्न मिल्दैन। तपाईंको यन्त्रको डेटा अब मेटाइने छ।\n\nतपाईंसँग प्रश्नहरू भएका खण्डमा आफ्नो संगठनका प्रशासकसँग सम्पर्क गर्नुहोस्।"</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> ले छाप्ने कार्यलाई असक्षम पार्यो।"</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"एप चलिरहेको छ"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"एपहरूले ब्याट्री खपत गर्दै छन्"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"जुम इन गर्ने सुविधा"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"सर्वसुलभताको सुरक्षासम्बन्धी नीति"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> ले ब्याट्री प्रयोग गर्दै छ"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> एपहरूले ब्याट्री प्रयोग गर्दै छन्"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"ब्याट्री र डेटाका प्रयोग सम्बन्धी विवरणहरूका लागि ट्याप गर्नुहोस्"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"एपलाई स्थिति पट्टि हुन अनुमति दिन्छ।"</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"स्थिति पट्टिलाई विस्तृत/सङ्कुचित गर्नुहोस्"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"एपलाई स्थिति पट्टि विस्तार वा संकुचन गर्न अनुमति दिन्छ।"</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"लक गरिएको यन्त्रमा स्क्रिनभरि देखिने सूचनाहरू देखाइयोस्"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"यो अनुमति दिइएमा एपले लक गरिएको यन्त्रमा स्क्रिनभरि देखिने सूचनाहरू देखाउन सक्छ"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"सर्टकट स्थापना गर्नुहोस्"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"प्रयोगकर्ताको हस्तक्षेप बिना एउटा एपलाई सर्टकटमा थप्नको लागि अनुमति दिन्छ।"</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"सर्टकटहरूको स्थापन रद्द गर्नुहोस्"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"बायोमेट्रिक्स वा स्क्रिन लक प्रयोग गर्नुहोस्"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"यो व्यक्ति तपाईं नै हो भन्ने प्रमाणित गर्नुहोस्"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"जारी राख्न आफ्नो बायोमेट्रिक प्रयोग गर्नुहोस्"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"जारी राख्न आफ्नो बायोमेट्रिक वा स्क्रिन लक प्रयोग गरी पुष्टि गर्नुहोस्"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"बायोमेट्रिक हार्डवेयर उपलब्ध छैन"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"प्रमाणीकरण रद्द गरियो"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"पहिचान भएन"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"फिंगरप्रिन्ट प्रयोग गर्नुहोस्"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"फिंगरप्रिन्ट वा स्क्रिन लक प्रयोग गर्नुहोस्"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"जारी राख्न आफ्नो फिंगरप्रिन्ट प्रयोग गर्नुहोस्"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"जारी राख्न आफ्नो फिंगरप्रिन्ट वा स्क्रिन लक प्रयोग गरी पुष्टि गर्नुहोस्"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"फिंगरप्रिन्ट आइकन"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"फेस अनलक प्रयोग गर्नुहोस्"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"फेस अनलक वा स्क्रिन लक प्रयोग गर्नुहोस्"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"जारी राख्न फेस अनलक प्रयोग गर्नुहोस्"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"जारी राख्न आफ्नो फेस वा स्क्रिन लक प्रयोग गरी पुष्टि गर्नुहोस्"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"अनुहारको आइकन"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"यो पृष्ठ खोल्न तपाईँलाई अनुमति छैन।"</string>
     <string name="text_copied" msgid="2531420577879738860">"क्लिपबोर्डमा प्रतिलिप गरिएको पाठ।"</string>
     <string name="copied" msgid="4675902854553014676">"प्रतिलिपि गरियो"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> मा रहेको डेटा कपी गरी <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> मा पेस्ट गरियो"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"क्लिपबोर्डमा रहेको डेटा कपी गरी <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> मा पेस्ट गरियो"</string>
     <string name="more_item_label" msgid="7419249600215749115">"बढी"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"मेनु+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1119,7 +1128,7 @@
     <string name="elapsed_time_short_format_h_mm_ss" msgid="2302144714803345056">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
     <string name="selectAll" msgid="1532369154488982046">"सबैलाई चयन गर्नुहोस्"</string>
     <string name="cut" msgid="2561199725874745819">"काट्नुहोस्"</string>
-    <string name="copy" msgid="5472512047143665218">"प्रतिलिपि बनाउनुहोस्"</string>
+    <string name="copy" msgid="5472512047143665218">"कपी गर्नुहोस्"</string>
     <string name="failed_to_copy_to_clipboard" msgid="725919885138539875">"क्लिपबोर्डमा प्रतिलिपि गर्न सकिएन"</string>
     <string name="paste" msgid="461843306215520225">"टाँस्नुहोस्"</string>
     <string name="paste_as_plain_text" msgid="7664800665823182587">"सामान्य पाठको रूपमा टाँस्नुहोस्"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"निष्क्रिय पार्नुहोस्"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"जाँच गर्दै <xliff:g id="NAME">%s</xliff:g>…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"हालको सामग्री समीक्षा गर्दै"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"मिडिया भण्डारणको जाँच गरिँदै छ"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"नयाँ <xliff:g id="NAME">%s</xliff:g> पत्ता लाग्यो"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> ले काम गरिरहेको छैन"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"सेटअप गर्न ट्याप गर्नुहोस्"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"सेटअप गर्न चयन गर्नुहोस्"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"तपाईंले यो यन्त्र पुनः फर्म्याट गर्नु पर्ने हुन सक्छ। यो यन्त्र हटाउन ट्याप गर्नुहोस्।"</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"फोटोहरू र मिडिया स्थानान्तरणका लागि"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"मिडिया फाइलहरू ब्राउज गर्नुहोस्"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"<xliff:g id="NAME">%s</xliff:g> मा समस्या देखियो"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> ले काम गरिरहेको छैन"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"समस्या समाधान गर्न ट्याप गर्नुहोस्"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"असमर्थित <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> ले काम गरिरहेको छैन"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"यस यन्त्रले यस <xliff:g id="NAME">%s</xliff:g> लाई समर्थन गर्दैन। एक समर्थित ढाँचामा सेटअप गर्न ट्याप गर्नुहोस्।"</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"यो यन्त्रले यस <xliff:g id="NAME">%s</xliff:g> लाई समर्थन गर्दैन। एक समर्थित ढाँचामा सेटअप गर्न चयन गर्नुहोस्।"</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"<xliff:g id="NAME">%s</xliff:g> प्रयोग गर्न मिल्ने फर्म्याटमा सेटअप गर्न चयन गर्नुहोस्।"</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"तपाईंले यो यन्त्र पुनः फर्म्याट गर्नु पर्ने हुन सक्छ"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> अप्रत्याशित रूपमा निकालियो"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"सामग्री गुम्न नदिनका लागि मिडिया हटाउनुअघि त्यसलाई इजेक्ट गर्नुहोस्"</string>
@@ -1677,7 +1689,8 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"सर्टकट प्रयोग गर्नुहोस्"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"रङ्ग उल्टाउने सुविधा"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"रङ्ग सच्याउने सुविधा"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"चमक घटाइयोस्"</string>
+    <!-- no translation found for reduce_bright_colors_feature_name (3222994553174604132) -->
+    <skip />
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"तपाईंले भोल्युम बटनहरू थिचिराख्नुभयो। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> अन भयो।"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"तपाईंले भोल्युम बटनहरू थिचिराख्नुभयो। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> अफ भयो।"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> प्रयोग गर्न दुवै भोल्युम कुञ्जीहरूलाई तीन सेकेन्डसम्म थिचिराख्नुहोस्"</string>
@@ -1689,7 +1702,7 @@
     <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"एउटा सुविधाबाट अर्को सुविधामा जान तीनवटा औँलाले माथितिर स्वाइप गरी स्क्रिनमा टच एण्ड होल्ड गर्नुहोस्।"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"म्याग्निफिकेसन"</string>
     <string name="user_switched" msgid="7249833311585228097">"अहिलेको प्रयोगकर्ता <xliff:g id="NAME">%1$s</xliff:g>।"</string>
-    <string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> मा स्विच गर्दै..."</string>
+    <string name="user_switching_message" msgid="1912993630661332336">"स्विच गरेर <xliff:g id="NAME">%1$s</xliff:g> बनाइँदै..."</string>
     <string name="user_logging_out_message" msgid="7216437629179710359">"लग आउट गर्दै <xliff:g id="NAME">%1$s</xliff:g>…"</string>
     <string name="owner_name" msgid="8713560351570795743">"मालिक"</string>
     <string name="error_message_title" msgid="4082495589294631966">"त्रुटि"</string>
@@ -2086,6 +2099,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"सहज पहुँचका लागि स्क्रिनमा राखिने सर्टकट"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"सहज पहुँचका लागि स्क्रिनमा राखिने सर्टकट छान्ने मेनु"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"पहुँचको सर्टकट"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"सूचना कक्ष खारेज गर्नुहोस्"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<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> लाई प्रतिबन्धित बाल्टीमा राखियो"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2237,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"नयाँ सुविधा: विन्डो म्याग्निफायर"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"तपाईं अब स्क्रिनको केही वा सबै भाग जुम इन गर्न सक्नुहुन्छ"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"आफ्नो स्क्रिनको केही भाग जुम इन गर्नुहोस्"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"तपाईं अब आफ्नो स्क्रिनको पूरै भाग वा केही भाग जुम इन गर्न सक्नुहुन्छ वा यी दुई विकल्प अदलबदल गर्न सक्नुहुन्छ।"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"सेटिङमा गई यो सुविधा अन गर्नुहोस्"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"हटाउनुहोस्"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"जारी राख्न &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; लाई तपाईंको यन्त्रको माइक्रोफोन प्रयोग गर्ने अनुमति दिनु पर्ने हुन्छ।"</string>
@@ -2233,4 +2247,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"सेन्सरसम्बन्धी गोपनीयता"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"एप जनाउने आइकन"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"एपको ब्रान्डिङ फोटो"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"हेर्ने तथा नियन्त्रण गर्ने अनुमतिसम्बन्धी सेटिङ जाँच्नु…"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> ले तपाईंको स्क्रिन हेर्न र नियन्त्रण गर्न सक्छ। समीक्षा गर्न ट्याप गर्नुहोस्।"</string>
 </resources>
diff --git a/core/res/res/values-night/colors.xml b/core/res/res/values-night/colors.xml
index 4410e94..baffa5a 100644
--- a/core/res/res/values-night/colors.xml
+++ b/core/res/res/values-night/colors.xml
@@ -36,7 +36,6 @@
 
     <color name="resolver_empty_state_text">#FFFFFF</color>
     <color name="resolver_empty_state_icon">#FFFFFF</color>
-    <color name="chooser_chip_icon">#8AB4F8</color> <!-- Blue 300 -->
 
     <color name="personal_apps_suspension_notification_color">#8AB4F8</color>
 </resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 46880ea..c0026b7 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Service voor schemering"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Tijdzonedetector (Geen verbinding)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"Updateservice voor GNSS-tijd"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Beheerservice voor muziekherkenning"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Je apparaat wordt gewist"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"De beheer-app kan niet worden gebruikt. Je apparaat wordt nu gewist.\n\nNeem contact op met de beheerder van je organisatie als je vragen hebt."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Afdrukken uitgeschakeld door <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"App actief"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Apps die de batterij gebruiken"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Vergroting"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Beveiligingsbeleid voor toegankelijkheid"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> gebruikt de batterij"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> apps gebruiken de batterij"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Tik voor batterij- en datagebruik"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Hiermee kan de app de statusbalk zijn."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"statusbalk uitvouwen/samenvouwen"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Hiermee kan de app de statusbalk uitvouwen of samenvouwen."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"meldingen als activiteiten op volledig scherm tonen op een vergrendeld apparaat"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Hiermee kan de app meldingen als activiteiten op volledig scherm tonen op een vergrendeld apparaat"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"Snelle links instellen"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Een app toestaan snelkoppelingen aan het startscherm toe te voegen zonder tussenkomst van de gebruiker."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"snelkoppelingen verwijderen"</string>
@@ -352,9 +356,9 @@
     <string name="permlab_answerPhoneCalls" msgid="4131324833663725855">"telefoonoproepen beantwoorden"</string>
     <string name="permdesc_answerPhoneCalls" msgid="894386681983116838">"Hiermee kan de app een inkomende telefoonoproep beantwoorden."</string>
     <string name="permlab_receiveSms" msgid="505961632050451881">"tekstberichten (SMS) ontvangen"</string>
-    <string name="permdesc_receiveSms" msgid="1797345626687832285">"Hiermee kan de app sms-berichten ontvangen en verwerken. Dit betekent dat de app berichten die naar je apparaat zijn verzonden, kan bijhouden of verwijderen zonder deze aan u weer te geven."</string>
+    <string name="permdesc_receiveSms" msgid="1797345626687832285">"Hiermee kan de app sms-berichten ontvangen en verwerken. Dit betekent dat de app berichten die naar je apparaat zijn verstuurd, kan bijhouden of verwijderen zonder deze te tonen."</string>
     <string name="permlab_receiveMms" msgid="4000650116674380275">"tekstberichten (MMS) ontvangen"</string>
-    <string name="permdesc_receiveMms" msgid="958102423732219710">"Hiermee kan de app MMS-berichten ontvangen en verwerken. Dit betekent dat de app berichten die naar je apparaat zijn verzonden, kan bijhouden of verwijderen zonder deze aan u weer te geven."</string>
+    <string name="permdesc_receiveMms" msgid="958102423732219710">"Hiermee kan de app mms-berichten ontvangen en verwerken. Dit betekent dat de app berichten die naar je apparaat zijn verstuurd, kan bijhouden of verwijderen zonder deze te tonen."</string>
     <string name="permlab_bindCellBroadcastService" msgid="586746677002040651">"Cell broadcast-berichten doorsturen"</string>
     <string name="permdesc_bindCellBroadcastService" msgid="6540910200973641606">"Hiermee kan de app de module voor cell broadcasts binden om cell broadcast-berichten door te sturen als die worden ontvangen. Cell broadcast-waarschuwingen worden op bepaalde locaties verzonden om je te waarschuwen voor noodsituaties. Schadelijke apps kunnen de prestaties of verwerking van je apparaat verstoren als een bericht met een noodmelding wordt ontvangen."</string>
     <string name="permlab_manageOngoingCalls" msgid="281244770664231782">"Actieve gesprekken beheren"</string>
@@ -370,7 +374,7 @@
     <string name="permdesc_readSms" product="tv" msgid="3054753345758011986">"Deze app kan alle sms-berichten lezen die zijn opgeslagen op je Android TV-apparaat."</string>
     <string name="permdesc_readSms" product="default" msgid="774753371111699782">"Deze app kan alle sms-berichten lezen die zijn opgeslagen op je telefoon."</string>
     <string name="permlab_receiveWapPush" msgid="4223747702856929056">"tekstberichten (WAP) ontvangen"</string>
-    <string name="permdesc_receiveWapPush" msgid="1638677888301778457">"Hiermee kan de app WAP-berichten ontvangen en verwerken. Dit betekent dat de app berichten die naar je apparaat zijn verzonden, kan bijhouden of verwijderen zonder deze aan u weer te geven."</string>
+    <string name="permdesc_receiveWapPush" msgid="1638677888301778457">"Hiermee kan de app WAP-berichten ontvangen en verwerken. Dit betekent dat de app berichten die naar je apparaat zijn verstuurd, kan bijhouden of verwijderen zonder deze te tonen."</string>
     <string name="permlab_getTasks" msgid="7460048811831750262">"actieve apps ophalen"</string>
     <string name="permdesc_getTasks" msgid="7388138607018233726">"Hiermee kan de app informatie ophalen over actieve en recent uitgevoerde taken. Zo kan de app informatie vinden over welke apps op het apparaat worden gebruikt."</string>
     <string name="permlab_manageProfileAndDeviceOwners" msgid="639849495253987493">"profiel- en apparaateigenaren beheren"</string>
@@ -498,7 +502,7 @@
     <string name="permdesc_getAccounts" product="tablet" msgid="1784452755887604512">"Hiermee krijgt de app toegang tot de lijst met accounts die op de tablet bekend zijn. Dit kunnen ook accounts zijn die zijn gemaakt door apps die je hebt geïnstalleerd."</string>
     <string name="permdesc_getAccounts" product="tv" msgid="437604680436540822">"Hiermee kan de app de lijst met accounts ophalen die op het Android TV-apparaat bekend zijn. Dit kunnen ook accounts zijn die zijn gemaakt door apps die je hebt geïnstalleerd."</string>
     <string name="permdesc_getAccounts" product="default" msgid="2491273043569751867">"Hiermee krijgt de app toegang tot de lijst met accounts die op de telefoon bekend zijn. Dit kunnen ook accounts zijn die zijn gemaakt door apps die je hebt geïnstalleerd."</string>
-    <string name="permlab_accessNetworkState" msgid="2349126720783633918">"netwerkverbindingen weergeven"</string>
+    <string name="permlab_accessNetworkState" msgid="2349126720783633918">"netwerkverbindingen bekijken"</string>
     <string name="permdesc_accessNetworkState" msgid="4394564702881662849">"Hiermee kan de app informatie bekijken over netwerkverbindingen, zoals welke netwerken er zijn en welke verbonden zijn."</string>
     <string name="permlab_createNetworkSockets" msgid="3224420491603590541">"volledige netwerktoegang"</string>
     <string name="permdesc_createNetworkSockets" msgid="7722020828749535988">"Hiermee kan de app netwerksockets maken en aangepaste netwerkprotocollen gebruiken. De browser en andere apps bieden mogelijkheden om gegevens via internet te verzenden, dus deze rechten zijn niet vereist om gegevens via internet te verzenden."</string>
@@ -506,8 +510,8 @@
     <string name="permdesc_changeNetworkState" msgid="649341947816898736">"Hiermee kan de app de status van de netwerkverbinding wijzigen."</string>
     <string name="permlab_changeTetherState" msgid="9079611809931863861">"getetherde verbinding wijzigen"</string>
     <string name="permdesc_changeTetherState" msgid="3025129606422533085">"Hiermee kan de app de status van de getetherde netwerkverbinding wijzigen."</string>
-    <string name="permlab_accessWifiState" msgid="5552488500317911052">"wifi-verbindingen weergeven"</string>
-    <string name="permdesc_accessWifiState" msgid="6913641669259483363">"Hiermee kan de app informatie over wifi-netwerken bekijken, zoals of wifi is ingeschakeld en de naam van apparaten waarmee via wifi verbinding is gemaakt."</string>
+    <string name="permlab_accessWifiState" msgid="5552488500317911052">"wifi-verbindingen bekijken"</string>
+    <string name="permdesc_accessWifiState" msgid="6913641669259483363">"Hiermee kan de app informatie over wifi-netwerken bekijken, zoals of wifi is aangezet en de naam van apparaten waarmee via wifi verbinding is gemaakt."</string>
     <string name="permlab_changeWifiState" msgid="7947824109713181554">"Wifi-verbinding maken en verbreken"</string>
     <string name="permdesc_changeWifiState" msgid="7170350070554505384">"Hiermee kan de app zich koppelen aan en ontkoppelen van wifi-toegangspunten en wijzigingen aanbrengen in de apparaatconfiguratie voor wifi-netwerken."</string>
     <string name="permlab_changeWifiMulticastState" msgid="285626875870754696">"Wifi Multicast-ontvangst toestaan"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Biometrische gegevens of schermvergrendeling gebruiken"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Je identiteit verifiëren"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Gebruik je biometrische gegevens om door te gaan"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Gebruik je biometrische gegevens of schermvergrendeling om door te gaan"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrische hardware niet beschikbaar"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Verificatie geannuleerd"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Niet herkend"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Vingerafdruk gebruiken"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Vingerafdruk of schermvergrendeling gebruiken"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Gebruik je vingerafdruk om door te gaan."</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Gebruik je vingerafdruk of schermvergrendeling om door te gaan"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Vingerafdruk-icoon"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Ontgrendelen via gezichtsherkenning gebruiken"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Gezicht of schermgrendeling gebruiken"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Gebruik ontgrendelen via gezichtsherkenning om door te gaan"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Gebruik je gezicht of schermvergrendeling om door te gaan"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Gezichtspictogram"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"Je hebt geen rechten om deze pagina te openen."</string>
     <string name="text_copied" msgid="2531420577879738860">"Tekst naar klembord gekopieerd."</string>
     <string name="copied" msgid="4675902854553014676">"Gekopieerd"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> geplakt vanuit <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> geplakt vanaf het klembord"</string>
     <string name="more_item_label" msgid="7419249600215749115">"Meer"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Menu+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta +"</string>
@@ -1207,12 +1216,12 @@
     <string name="launch_warning_replace" msgid="3073392976283203402">"<xliff:g id="APP_NAME">%1$s</xliff:g> is nu actief."</string>
     <string name="launch_warning_original" msgid="3332206576800169626">"<xliff:g id="APP_NAME">%1$s</xliff:g> was het eerst gestart."</string>
     <string name="screen_compat_mode_scale" msgid="8627359598437527726">"Schaal"</string>
-    <string name="screen_compat_mode_show" msgid="5080361367584709857">"Altijd weergeven"</string>
+    <string name="screen_compat_mode_show" msgid="5080361367584709857">"Altijd tonen"</string>
     <string name="screen_compat_mode_hint" msgid="4032272159093750908">"U kunt dit opnieuw inschakelen via Systeeminstellingen &gt; Apps &gt; Gedownload."</string>
     <string name="unsupported_display_size_message" msgid="7265211375269394699">"<xliff:g id="APP_NAME">%1$s</xliff:g> biedt geen ondersteuning voor de huidige instelling voor weergavegrootte en kan onverwacht gedrag vertonen."</string>
-    <string name="unsupported_display_size_show" msgid="980129850974919375">"Altijd weergeven"</string>
+    <string name="unsupported_display_size_show" msgid="980129850974919375">"Altijd tonen"</string>
     <string name="unsupported_compile_sdk_message" msgid="7326293500707890537">"<xliff:g id="APP_NAME">%1$s</xliff:g> is gemaakt voor een niet-geschikte versie van het Android-besturingssysteem en kan onverwacht gedrag vertonen. Mogelijk is er een geüpdatete versie van de app beschikbaar."</string>
-    <string name="unsupported_compile_sdk_show" msgid="1601210057960312248">"Altijd weergeven"</string>
+    <string name="unsupported_compile_sdk_show" msgid="1601210057960312248">"Altijd tonen"</string>
     <string name="unsupported_compile_sdk_check_update" msgid="1103639989147664456">"Controleren op update"</string>
     <string name="smv_application" msgid="3775183542777792638">"De app <xliff:g id="APPLICATION">%1$s</xliff:g> (proces <xliff:g id="PROCESS">%2$s</xliff:g>) heeft het zelf afgedwongen StrictMode-beleid geschonden."</string>
     <string name="smv_process" msgid="1398801497130695446">"Het proces <xliff:g id="PROCESS">%1$s</xliff:g> heeft het zelf afgedwongen StrictMode-beleid geschonden."</string>
@@ -1357,7 +1366,7 @@
     <string name="share_remote_bugreport_action" msgid="7630880678785123682">"DELEN"</string>
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"WEIGEREN"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Invoermethode selecteren"</string>
-    <string name="show_ime" msgid="6406112007347443383">"Dit op het scherm weergeven terwijl het fysieke toetsenbord actief is"</string>
+    <string name="show_ime" msgid="6406112007347443383">"Op het scherm tonen terwijl het fysieke toetsenbord actief is"</string>
     <string name="hardware" msgid="1800597768237606953">"Virtueel toetsenbord tonen"</string>
     <string name="select_keyboard_layout_notification_title" msgid="4427643867639774118">"Fysiek toetsenbord instellen"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Tik om een taal en indeling te selecteren"</string>
@@ -1365,16 +1374,19 @@
     <string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"Weergeven vóór andere apps"</string>
     <string name="alert_windows_notification_channel_name" msgid="3437528564303192620">"<xliff:g id="NAME">%s</xliff:g> wordt weergegeven over andere apps"</string>
-    <string name="alert_windows_notification_title" msgid="6331662751095228536">"<xliff:g id="NAME">%s</xliff:g> wordt weergegeven over apps"</string>
+    <string name="alert_windows_notification_title" msgid="6331662751095228536">"<xliff:g id="NAME">%s</xliff:g> wordt weergegeven vóór andere apps"</string>
     <string name="alert_windows_notification_message" msgid="6538171456970725333">"Als je niet wilt dat <xliff:g id="NAME">%s</xliff:g> deze functie gebruikt, tik je om de instellingen te openen en schakel je de functie uit."</string>
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Uitschakelen"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"<xliff:g id="NAME">%s</xliff:g> controleren…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Huidige content controleren"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Mediaopslag analyseren"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Nieuwe <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> werkt niet"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Tik om in te stellen"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Selecteer om in te stellen"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Je moet het apparaat misschien opnieuw formatteren. Tik om het uit te werpen."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"Voor overzetten van foto\'s en media"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Browsen door mediabestanden"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Probleem met <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> werkt niet"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Tik om het probleem op te lossen"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"<xliff:g id="NAME">%s</xliff:g> niet ondersteund"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> werkt niet"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"Dit apparaat biedt geen ondersteuning voor deze <xliff:g id="NAME">%s</xliff:g>. Tik om in te stellen in een ondersteunde indeling."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"Dit apparaat biedt geen ondersteuning voor deze <xliff:g id="NAME">%s</xliff:g>. Selecteer om in te stellen in een ondersteunde indeling."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Selecteer om <xliff:g id="NAME">%s</xliff:g> in te stellen in een ondersteunde indeling."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Je moet het apparaat misschien opnieuw formatteren"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> is onverwacht verwijderd"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Werp media uit voordat je deze verwijdert om te voorkomen dat je content kwijtraakt"</string>
@@ -1568,7 +1580,7 @@
     <string name="fingerprints" msgid="148690767172613723">"Vingerafdrukken:"</string>
     <string name="sha256_fingerprint" msgid="7103976380961964600">"SHA-256-vingerafdruk"</string>
     <string name="sha1_fingerprint" msgid="2339915142825390774">"SHA-1-vingerafdruk:"</string>
-    <string name="activity_chooser_view_see_all" msgid="3917045206812726099">"Alles weergeven"</string>
+    <string name="activity_chooser_view_see_all" msgid="3917045206812726099">"Alles tonen"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="8880731437191978314">"Een activiteit kiezen"</string>
     <string name="share_action_provider_share_with" msgid="1904096863622941880">"Delen met"</string>
     <string name="sending" msgid="206925243621664438">"Verzenden..."</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Sneltoets gebruiken"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Kleurinversie"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Kleurcorrectie"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Helderheid verlagen"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Extra gedimd"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Volumetoetsen ingedrukt gehouden. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> is ingeschakeld."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Volumetoetsen ingedrukt gehouden. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> uitgeschakeld."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Houd beide volumetoetsen drie seconden ingedrukt om <xliff:g id="SERVICE_NAME">%1$s</xliff:g> te gebruiken"</string>
@@ -1799,7 +1811,7 @@
       <item quantity="one">Probeer het over 1 seconde opnieuw</item>
     </plurals>
     <string name="restr_pin_try_later" msgid="5897719962541636727">"Probeer het later opnieuw"</string>
-    <string name="immersive_cling_title" msgid="2307034298721541791">"Volledig scherm wordt weergegeven"</string>
+    <string name="immersive_cling_title" msgid="2307034298721541791">"Volledig scherm wordt getoond"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Swipe omlaag vanaf de bovenkant van het scherm om af te sluiten."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"Ik snap het"</string>
     <string name="done_label" msgid="7283767013231718521">"Klaar"</string>
@@ -1822,7 +1834,7 @@
     <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
     <string name="battery_saver_description_with_learn_more" msgid="4424488535318105801">"Batterijbesparing doet het volgende om de batterijduur te verlengen:\n\n• Het donkere thema inschakelen\n• Achtergrondactiviteit, bepaalde visuele effecten en andere functies (zoals \'Hey Google\') uitschakelen of beperken\n\n"<annotation id="url">"Meer informatie"</annotation></string>
     <string name="battery_saver_description" msgid="6794188153647295212">"Batterijbesparing doet het volgende om de batterijduur te verlengen:\n\n• Het donkere thema inschakelen.\n• Achtergrondactiviteit, bepaalde visuele effecten en andere functies (zoals \'Hey Google\') uitschakelen of beperken."</string>
-    <string name="data_saver_description" msgid="4995164271550590517">"Databesparing beperkt het datagebruik door te voorkomen dat sommige apps gegevens verzenden of ontvangen op de achtergrond. De apps die je open hebt, kunnen nog steeds data verbruiken, maar doen dit minder vaak. Afbeeldingen worden dan bijvoorbeeld niet weergegeven totdat je erop tikt."</string>
+    <string name="data_saver_description" msgid="4995164271550590517">"Databesparing beperkt het datagebruik door te voorkomen dat sommige apps gegevens sturen of ontvangen op de achtergrond. De apps die je open hebt, kunnen nog steeds data verbruiken, maar doen dit minder vaak. Afbeeldingen worden dan bijvoorbeeld niet weergegeven totdat je erop tikt."</string>
     <string name="data_saver_enable_title" msgid="7080620065745260137">"Databesparing aanzetten?"</string>
     <string name="data_saver_enable_button" msgid="4399405762586419726">"Inschakelen"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="2877101784123058273">
@@ -2020,7 +2032,7 @@
     <string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"VERWIJDEREN"</string>
     <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"TOCH OPENEN"</string>
     <string name="harmful_app_warning_title" msgid="8794823880881113856">"Schadelijke app gevonden"</string>
-    <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> wil segmenten van <xliff:g id="APP_2">%2$s</xliff:g> weergeven"</string>
+    <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> wil segmenten van <xliff:g id="APP_2">%2$s</xliff:g> tonen"</string>
     <string name="screenshot_edit" msgid="7408934887203689207">"Bewerken"</string>
     <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>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Snelkoppeling voor toegankelijkheid op scherm"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Kiezer voor snelkoppeling voor toegankelijkheid op scherm"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Snelkoppeling voor toegankelijkheid"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Meldingenpaneel sluiten"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Ondertitelingsbalk van <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> is in de bucket RESTRICTED geplaatst"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Nieuw: Venstervergroting"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Je kunt je scherm nu (gedeeltelijk) vergroten"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Een gedeelte van het scherm vergroten"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Je kunt nu je volledige scherm of een specifiek gedeelte vergroten of schakelen tussen beide opties."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Inschakelen in Instellingen"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Sluiten"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"&lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; heeft toegang tot de microfoon van je apparaat nodig om door te gaan."</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Sensorprivacy"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"App-icoon"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Merkafbeelding voor app"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Toegangsinstellingen checken"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> kan je scherm bekijken en beheren. Tik om te bekijken."</string>
 </resources>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index 7d65cde..770e4f0 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"ଟ୍ୱିଲାଇଟ୍ ସର୍ଭିସ୍"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"ଟାଇମ୍‍ ଜୋନ୍‍ ଡିଟେକ୍ଟର୍‍ (କୌଣସି ସଂଯୋଗ ନାହିଁ)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS ସମୟ ଅପଡେଟ୍ ସେବା"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"ମ୍ୟୁଜିକ୍ ଚିହ୍ନଟକରଣ ପରିଚାଳକ ସେବା"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"ଆପଣଙ୍କ ଡିଭାଇସ୍‍ ବର୍ତ୍ତମାନ ଲିଭାଯିବ"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"ଆଡମିନ୍‍ ଆପ୍‍‍ ବ୍ୟବହାର କରାଯାଇପାରିବ ନାହିଁ। ଆପଣଙ୍କ ଡିଭାଇସ୍‍‌ର ସମସ୍ତ ଡାଟାକୁ ବର୍ତ୍ତମାନ ଲିଭାଇଦିଆଯିବ। \n\nଯଦି ଆପଣଙ୍କର କୌଣସି ପ୍ରଶ୍ନ ରହିଥାଏ, ଆପଣଙ୍କ ସଂସ୍ଥାର ଆଡମିନ୍‌ଙ୍କ ସହ ଯୋଗାଯୋଗ କରନ୍ତୁ।"</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> ଦ୍ଵାରା ପ୍ରିଣ୍ଟିଙ୍ଗ ଅକ୍ଷମ କରାଯାଇଛି"</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"ଆପ୍‍ ଚାଲୁଛି"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"ଆପ୍‍ଗୁଡ଼ିକ ବ୍ୟାଟେରୀ ଖର୍ଚ୍ଚ କରିଥା\'ନ୍ତି"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"ମ୍ୟାଗ୍ନିଫିକେସନ୍"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"ଆକ୍ସେସିବିଲିଟୀ ସୁରକ୍ଷା ନୀତି"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> ବ୍ୟାଟେରୀ ବ୍ୟବହାର କରୁଛି"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g>ଟି ଆପ୍‍ ବ୍ୟାଟେରୀ ବ୍ୟବହାର କରୁଛନ୍ତି"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"ବ୍ୟାଟେରୀ ଏବଂ ଡାଟା ବ୍ୟବହାର ଉପରେ ବିବରଣୀ ପାଇଁ ଟାପ୍‍ କରନ୍ତୁ"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"ଆପ୍‍ଟିକୁ ସ୍ଥିତି ବାର୍‍ ହେବାକୁ ଅନୁମତି ଦେଇଥାଏ।"</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"ସ୍ଥିତି ବାର୍‌କୁ ବଡ଼/ଛୋଟ କରନ୍ତୁ"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"ଷ୍ଟାଟସ୍‌ ବାର୍‍କୁ ବଡ଼ କିମ୍ବା ଛୋଟ କରିବା ପାଇଁ ଆପ୍‍କୁ ଅନୁମତି ଦେଇଥାଏ।"</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"ଏକ ଲକ୍ ହୋଇଥିବା ଡିଭାଇସରେ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ପୂର୍ଣ୍ଣ ସ୍କ୍ରିନ୍ କାର୍ଯ୍ୟକଳାପ ଭାବେ ଦେଖାନ୍ତୁ"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"ଏକ ଲକ୍ ହୋଇଥିବା ଡିଭାଇସରେ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ପୂର୍ଣ୍ଣ ସ୍କ୍ରିନ୍ କାର୍ଯ୍ୟକଳାପ ଭାବେ ଦେଖାଇବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦିଏ"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"ଶର୍ଟକଟ୍‍ ଇନଷ୍ଟଲ୍‍ କରନ୍ତୁ"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"ୟୁଜର୍‌ଙ୍କ ବିନା ବାଧାରେ ହୋମ୍‍ସ୍କ୍ରୀନ୍‍ ସର୍ଟକଟ୍‍ ଯୋଡ଼ିବାକୁ ଏକ ଆପ୍ଲିକେଶନ୍‍କୁ ଅନୁମତି ଦେଇଥାଏ।"</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"ଶର୍ଟକଟ୍‍ ଅନଇନଷ୍ଟଲ୍‍ କରନ୍ତୁ"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"ବାୟୋମେଟ୍ରିକ୍ସ ବା ସ୍କ୍ରିନ୍ ଲକ୍ ବ୍ୟବହାର କରନ୍ତୁ"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"ଏହା ଆପଣ ବୋଲି ଯାଞ୍ଚ କରନ୍ତୁ"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"ଜାରି ରଖିବାକୁ ଆପଣଙ୍କ ବାୟୋମେଟ୍ରିକ୍ସ ବ୍ୟବହାର କରନ୍ତୁ"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"ଜାରି ରଖିବାକୁ ଆପଣଙ୍କ ବାୟୋମେଟ୍ରିକ୍ କିମ୍ବା ସ୍କ୍ରିନ୍ ଲକ୍ ବ୍ୟବହାର କରନ୍ତୁ"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"ବାୟୋମେଟ୍ରିକ୍‌ ହାର୍ଡୱେର୍‌ ଉପଲବ୍ଧ ନାହିଁ"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"ପ୍ରାମାଣିକତାକୁ ବାତିଲ୍ କରାଯାଇଛି"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"ଚିହ୍ନଟ ହେଲାନାହିଁ"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ଟିପଚିହ୍ନ ବ୍ୟବହାର କରନ୍ତୁ"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ଟିପଚିହ୍ନ ବା ସ୍କ୍ରିନ୍ ଲକ୍ ବ୍ୟବହାର କରନ୍ତୁ"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"ଜାରି ରଖିବାକୁ ଆପଣଙ୍କ ଟିପଚିହ୍ନ ବ୍ୟବହାର କରନ୍ତୁ"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"ଜାରି ରଖିବାକୁ ଆପଣଙ୍କ ଟିପଚିହ୍ନ କିମ୍ବା ସ୍କ୍ରିନ୍ ଲକ୍ ବ୍ୟବହାର କରନ୍ତୁ"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"ଟିପଚିହ୍ନ ଆଇକନ୍"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"ଫେସ୍ ଅନଲକ୍ ବ୍ୟବହାର କରନ୍ତୁ"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"ଫେସ୍ ବା ସ୍କ୍ରିନ୍ ଲକ୍ ବ୍ୟବହାର କରନ୍ତୁ"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"ଜାରି ରଖିବାକୁ ଫେସ୍ ଅନଲକ୍ ବ୍ୟବହାର କରନ୍ତୁ"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"ଜାରି ରଖିବାକୁ ଆପଣଙ୍କ ଚେହେରା କିମ୍ବା ସ୍କ୍ରିନ୍ ଲକ୍ ବ୍ୟବହାର କରନ୍ତୁ"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"ଫେସ୍ ଆଇକନ୍"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"ଏହି ପୃଷ୍ଠା ଖୋଲିବାକୁ ଆପଣଙ୍କ ପାଖରେ ଅନୁମତି ନାହିଁ।"</string>
     <string name="text_copied" msgid="2531420577879738860">"ଟେକ୍ସଟ୍‍ କ୍ଲିପବୋର୍ଡକୁ କପୀ ହୋଇଯାଇଛି"</string>
     <string name="copied" msgid="4675902854553014676">"କପି କରାଗଲା"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>ରୁ ପେଷ୍ଟ କରିଛି"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> କ୍ଲିପବୋର୍ଡରୁ ପେଷ୍ଟ କରିଛି"</string>
     <string name="more_item_label" msgid="7419249600215749115">"ଅଧିକ"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"ମେନୁ"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"ବନ୍ଦ କରନ୍ତୁ"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"<xliff:g id="NAME">%s</xliff:g>ର ଯାଞ୍ଚ କରାଯାଉଛି…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"ସାମ୍ପ୍ରତିକ କଣ୍ଟେଣ୍ଟର ଯାଞ୍ଚ କରାଯାଉଛି"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"ମିଡିଆ ଷ୍ଟୋରେଜର ବିଶ୍ଳେଷଣ କରାଯାଉଛି"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"ନୂଆ <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> କାମ କରୁନାହିଁ"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"ସେଟଅପ୍‌ କରିବା ପାଇଁ ଟାପ୍‌ କରନ୍ତୁ"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"ସେଟ୍ ଅପ୍ କରିବାକୁ ଚୟନ କରନ୍ତୁ"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"ଆପଣଙ୍କୁ ପୁଣି ଡିଭାଇସ୍ ଫର୍ମାଟ୍ କରିବାକୁ ପଡ଼ିପାରେ। ବାହାର କରିବାକୁ ଟାପ୍ କରନ୍ତୁ।"</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"ଫଟୋ ଓ ମିଡିଆ ସ୍ଥାନାନ୍ତର କରାଯିବା ପାଇଁ"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"ମିଡିଆ ଫାଇଲଗୁଡ଼ିକୁ ବ୍ରାଉଜ୍ କରନ୍ତୁ"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"<xliff:g id="NAME">%s</xliff:g> ସହ ସମସ୍ୟା"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> କାମ କରୁନାହିଁ"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"ଠିକ୍‌ କରିବାକୁ ଟାପ୍‌ କରନ୍ତୁ"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"<xliff:g id="NAME">%s</xliff:g> ସପୋର୍ଟ କରୁନାହିଁ"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> କାମ କରୁନାହିଁ"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"ଏହି ଡିଭାଇସ୍ ଏହି <xliff:g id="NAME">%s</xliff:g>କୁ ସପୋର୍ଟ କରେନାହିଁ। ଗୋଟିଏ ସପୋର୍ଟ କରୁଥିବା ଫର୍ମାଟ୍‌ରେ ସେଟ୍‍ ଅପ୍‍ କରିବା ପାଇଁ ଟାପ୍‍ କରନ୍ତୁ।"</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"ଏହି ଡିଭାଇସ୍ ଏହି <xliff:g id="NAME">%s</xliff:g>କୁ ସପୋର୍ଟ କରେ ନାହିଁ। ଗୋଟିଏ ସପୋର୍ଟ କରୁଥିବା ଫର୍ମାଟରେ ସେଟ୍‍ ଅପ୍‍ କରିବାକୁ ଟାପ୍‍ କରନ୍ତୁ।"</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"<xliff:g id="NAME">%s</xliff:g>କୁ ଏକ ସମର୍ଥିତ ଫର୍ମାଟରେ ସେଟ୍ ଅପ୍ କରିବାକୁ ଚୟନ କରନ୍ତୁ।"</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"ଆପଣଙ୍କୁ ପୁଣି ଡିଭାଇସ୍ ଫର୍ମାଟ୍ କରିବାକୁ ପଡ଼ିପାରେ"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g>କୁ ହଠାତ୍‌ କାଢ଼ିଦିଆଗଲା"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"କଣ୍ଟେଣ୍ତ ହରାଇବାକୁ ଏଡ଼ାଇବା ପାଇଁ କାଢ଼ିବା ପୂର୍ବରୁ ମିଡିଆକୁ ଇଜେକ୍ଟ କରନ୍ତୁ"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ଶର୍ଟକଟ୍‍ ବ୍ୟବହାର କରନ୍ତୁ"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"ରଙ୍ଗ ବଦଳାଇବାର ସୁବିଧା"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"ରଙ୍ଗ ସଂଶୋଧନ"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"ଉଜ୍ଜ୍ୱଳତା କମ୍ କରନ୍ତୁ"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"ଅତିରିକ୍ତ ଡିମ୍"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ଭଲ୍ୟୁମ୍ କୀ\'ଗୁଡ଼ିକୁ ଧରି ରଖାଯାଇଛି। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ଚାଲୁ ହୋଇଛି।"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ଭଲ୍ୟୁମ୍ କୀ\'ଗୁଡ଼ିକୁ ଧରି ରଖାଯାଇଛି। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ବନ୍ଦ ହୋଇଛି।"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ବ୍ୟବହାର କରିବାକୁ ତିନି ସେକେଣ୍ଡ ପାଇଁ ଉଭୟ ଭଲ୍ୟୁମ୍‍ କୀ ଦବାଇ ଧରି ରଖନ୍ତୁ"</string>
@@ -1689,7 +1701,7 @@
     <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"ଫିଚରଗୁଡ଼ିକ ମଧ୍ୟରେ ସ୍ୱିଚ୍ କରିବାକୁ, ତିନୋଟି ଆଙ୍ଗୁଠିରେ ଉପରକୁ ସ୍ୱାଇପ୍ କରି ଧରି ରଖନ୍ତୁ।"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"ମ୍ୟାଗ୍ନିଫିକେସନ୍‍"</string>
     <string name="user_switched" msgid="7249833311585228097">"ବର୍ତ୍ତମାନର ୟୁଜର୍‌ ହେଉଛନ୍ତି <xliff:g id="NAME">%1$s</xliff:g>।"</string>
-    <string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> ରେ ସୁଇଚ୍ କରନ୍ତୁ…"</string>
+    <string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g>ରେ ସ୍ୱିଚ୍ କରନ୍ତୁ…"</string>
     <string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g>ଙ୍କୁ ଲଗଆଉଟ୍‍ କରାଯାଉଛି…"</string>
     <string name="owner_name" msgid="8713560351570795743">"ମାଲିକ"</string>
     <string name="error_message_title" msgid="4082495589294631966">"ତ୍ରୁଟି"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"ଅନ୍-ସ୍କ୍ରିନ୍ ଆକ୍ସେସିବିଲିଟୀ ସର୍ଟକଟ୍"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"ଅନ୍-ସ୍କ୍ରିନ୍ ଆକ୍ସେସିବିଲିଟୀ ସର୍ଟକଟ୍ ବାଛିବା ସୁବିଧା"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"ଆକ୍ସେସିବିଲିଟୀ ସର୍ଟକଟ୍"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"ବିଜ୍ଞପ୍ତି ସେଡକୁ ଖାରଜ କରନ୍ତୁ"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<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>କୁ ପ୍ରତିବନ୍ଧିତ ବକେଟରେ ରଖାଯାଇଛି"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"ନୂଆ: ୱିଣ୍ଡୋ ମ୍ୟାଗ୍ନିଫାୟର୍"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"ଆପଣ ଏବେ ଆଂଶିକ ବା ସମ୍ପୂର୍ଣ୍ଣ ସ୍କ୍ରିନ୍ ବଡ଼ କରିପାରିବେ"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"ଆପଣଙ୍କ ସ୍କ୍ରିନର ଏକ ଅଂଶକୁ ମ୍ୟାଗ୍ନିଫାଏ କରନ୍ତୁ"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"ଆପଣ ବର୍ତ୍ତମାନ ଆପଣଙ୍କ ସମ୍ପୂର୍ଣ୍ଣ ସ୍କ୍ରିନକୁ ବା ଏହାର ଏକ ନିର୍ଦ୍ଦିଷ୍ଟ ଅଞ୍ଚଳକୁ ମ୍ୟାଗ୍ନିଫାଏ କରିପାରିବେ କିମ୍ବା ଉଭୟ ବିକଳ୍ପ ମଧ୍ୟରେ ସ୍ୱିଚ୍ କରିପାରିବେ।"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"ସେଟିଂସରେ ଚାଲୁ କରନ୍ତୁ"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"ଖାରଜ କରନ୍ତୁ"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"ଜାରି ରଖିବାକୁ, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ଆପଣଙ୍କ ଡିଭାଇସର ମାଇକ୍ରୋଫୋନକୁ ଆକ୍ସେସ୍ ଆବଶ୍ୟକ କରେ।"</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"ସେନ୍ସର୍ ଗୋପନୀୟତା"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"ଆପ୍ଲିକେସନ୍ ଆଇକନ୍"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"ଆପ୍ଲିକେସନ୍ ବ୍ରାଣ୍ଡିଂ ଛବି"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"ଆକ୍ସେସ୍ ସେଟିଂସକୁ ଯାଞ୍ଚ କରନ୍ତୁ"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> ଆପଣଙ୍କ ସ୍କ୍ରିନକୁ ଦେଖିପାରିବ ଏବଂ ନିୟନ୍ତ୍ରଣ କରିପାରିବ। ସମୀକ୍ଷା କରିବାକୁ ଟାପ୍ କରନ୍ତୁ।"</string>
 </resources>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 26861dd..c9267e4 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"ਟਵੀਲਾਈਟ ਸੇਵਾ"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"ਸਮਾਂ ਖੇਤਰ ਦਾ ਪਤਾ ਲਗਾਉਣ ਦੀ ਸੁਵਿਧਾ (ਕੋਈ ਕਨੈਕਟੀਵਿਟੀ ਨਹੀਂ)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS ਸਮਾਂ ਅੱਪਡੇਟ ਸੇਵਾ"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"ਸੰਗੀਤ ਪਛਾਣ ਪ੍ਰਬੰਧਕ ਸੇਵਾ"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"ਤੁਹਾਡਾ ਡੀਵਾਈਸ ਮਿਟਾਇਆ ਜਾਏਗਾ"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"ਪ੍ਰਸ਼ਾਸਕ ਐਪ ਵਰਤੀ ਨਹੀਂ ਜਾ ਸਕਦੀ। ਹੁਣ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਦਾ ਡਾਟਾ ਮਿਟਾਇਆ ਜਾਵੇਗਾ।\n\nਜੇਕਰ ਤੁਹਾਡੇ ਕੋਲ ਕੋਈ ਸਵਾਲ ਹਨ, ਤਾਂ ਆਪਣੀ ਸੰਸਥਾ ਦੇ ਪ੍ਰਸ਼ਾਸਕ ਨੂੰ ਸੰਪਰਕ ਕਰੋ।"</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> ਵੱਲੋਂ ਪ੍ਰਿੰਟ ਕਰਨਾ ਬੰਦ ਕੀਤਾ ਗਿਆ।"</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"ਚੱਲ ਰਹੀ ਐਪ"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"ਬੈਟਰੀ ਦੀ ਖਪਤ ਕਰਨ ਵਾਲੀਆਂ ਐਪਾਂ"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"ਵੱਡਦਰਸ਼ੀਕਰਨ"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"ਪਹੁੰਚਯੋਗਤਾ ਸੁਰੱਖਿਆ ਨੀਤੀ"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਵੱਲੋਂ ਬੈਟਰੀ ਦੀ ਵਰਤੋਂ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> ਐਪਾਂ ਬੈਟਰੀ ਦੀ ਵਰਤੋਂ ਕਰ ਰਹੀਆਂ ਹਨ"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"ਬੈਟਰੀ ਅਤੇ ਡਾਟਾ ਵਰਤੋਂ ਸਬੰਧੀ ਵੇਰਵਿਆਂ ਲਈ ਟੈਪ ਕਰੋ"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"ਐਪ ਨੂੰ ਸਥਿਤੀ ਪੱਟੀ ਹੋਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"ਸਥਿਤੀ ਪੱਟੀ ਦਾ ਵਿਸਤਾਰ/ਨਸ਼ਟ ਕਰੋ"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"ਐਪ ਨੂੰ ਸਥਿਤੀ ਪੱਟੀ ਦਾ ਵਿਸਤਾਰ ਕਰਨ ਜਾਂ ਨਸ਼ਟ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"ਕਿਸੇ ਲਾਕ ਕੀਤੇ ਡੀਵਾਈਸ \'ਤੇ ਪੂਰੀ ਸਕ੍ਰੀਨ ਵਾਲੀਆਂ ਸਰਗਰਮੀਆਂ ਵਜੋਂ ਸੂਚਨਾਵਾਂ ਦਿਖਾਓ"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"ਐਪ ਨੂੰ ਕਿਸੇ ਲਾਕ ਕੀਤੇ ਡੀਵਾਈਸ \'ਤੇ ਪੂਰੀ ਸਕ੍ਰੀਨ ਵਾਲੀਆਂ ਸਰਗਰਮੀਆਂ ਵਜੋਂ ਸੂਚਨਾਵਾਂ ਦਿਖਾਉਣ ਦਿੰਦਾ ਹੈ"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"ਸ਼ਾਰਟਕੱਟ ਸਥਾਪਤ ਕਰੋ"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"ਇੱਕ ਐਪਲੀਕੇਸ਼ਨ ਨੂੰ ਵਰਤੋਂਕਾਰ ਦੇ ਦਖ਼ਲ ਤੋਂ ਬਿਨਾਂ ਹੋਮਸਕ੍ਰੀਨ ਸ਼ਾਰਟਕੱਟ ਸ਼ਾਮਲ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"ਸ਼ਾਰਟਕੱਟ ਅਣਸਥਾਪਤ ਕਰੋ"</string>
@@ -550,23 +554,19 @@
     <string name="permdesc_imagesWrite" msgid="5195054463269193317">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ ਫ਼ੋਟੋ ਸੰਗ੍ਰਹਿ ਨੂੰ ਸੋਧਣ ਦਿੰਦੀ ਹੈ।"</string>
     <string name="permlab_mediaLocation" msgid="7368098373378598066">"ਤੁਹਾਡੇ ਮੀਡੀਆ ਸੰਗ੍ਰਹਿ ਦੇ ਟਿਕਾਣਿਆਂ ਨੂੰ ਪੜ੍ਹਨਾ"</string>
     <string name="permdesc_mediaLocation" msgid="597912899423578138">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ ਮੀਡੀਆ ਸੰਗ੍ਰਹਿ ਦੇ ਟਿਕਾਣਿਆਂ ਨੂੰ ਪੜ੍ਹਨ ਦਿੰਦੀ ਹੈ।"</string>
-    <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
-    <skip />
-    <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
-    <skip />
+    <string name="biometric_app_setting_name" msgid="3339209978734534457">"ਬਾਇਓਮੈਟ੍ਰਿਕ ਦੀ ਵਰਤੋਂ ਕਰੋ"</string>
+    <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"ਬਾਇਓਮੈਟ੍ਰਿਕ ਜਾਂ ਸਕ੍ਰੀਨ ਲਾਕ ਦੀ ਵਰਤੋਂ ਕਰੋ"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"ਆਪਣੀ ਪਛਾਣ ਦੀ ਪੁਸ਼ਟੀ ਕਰੋ"</string>
-    <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
-    <skip />
+    <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"ਜਾਰੀ ਰੱਖਣ ਲਈ ਆਪਣੇ ਬਾਇਓਮੈਟ੍ਰਿਕ ਦੀ ਵਰਤੋਂ ਕਰੋ"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"ਜਾਰੀ ਰੱਖਣ ਲਈ ਆਪਣਾ ਬਾਇਓਮੈਟ੍ਰਿਕ ਜਾਂ ਸਕ੍ਰੀਨ ਲਾਕ ਵਰਤੋ"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"ਬਾਇਓਮੈਟ੍ਰਿਕ ਹਾਰਡਵੇਅਰ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"ਪ੍ਰਮਾਣੀਕਰਨ ਰੱਦ ਕੀਤਾ ਗਿਆ"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"ਪਛਾਣ ਨਹੀਂ ਹੋਈ"</string>
     <string name="biometric_error_canceled" msgid="8266582404844179778">"ਪ੍ਰਮਾਣੀਕਰਨ ਰੱਦ ਕੀਤਾ ਗਿਆ"</string>
     <string name="biometric_error_device_not_secured" msgid="3129845065043995924">"ਕੋਈ ਪਿੰਨ, ਪੈਟਰਨ ਜਾਂ ਪਾਸਵਰਡ ਸੈੱਟ ਨਹੀਂ ਕੀਤਾ ਗਿਆ"</string>
     <string name="biometric_error_generic" msgid="6784371929985434439">"ਗੜਬੜ ਨੂੰ ਪ੍ਰਮਾਣਿਤ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
-    <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
-    <skip />
-    <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
-    <skip />
+    <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"ਸਕ੍ਰੀਨ ਲਾਕ ਦੀ ਵਰਤੋਂ ਕਰੋ"</string>
+    <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"ਜਾਰੀ ਰੱਖਣ ਲਈ ਆਪਣੇ ਡੀਵਾਈਸ ਦੇ ਕ੍ਰੀਡੈਂਸ਼ੀਅਲ ਨੂੰ ਦਾਖਲ ਕਰੋ"</string>
     <string name="fingerprint_acquired_partial" msgid="8532380671091299342">"ਅਧੂਰਾ ਫਿੰਗਰਪ੍ਰਿਟ ਮਿਲਿਆ। ਕਿਰਪਾ ਕਰਕੇ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"ਫਿੰਗਰਪ੍ਰਿੰਟ \'ਤੇ ਪ੍ਰਕਿਰਿਆ ਨਹੀਂ ਹੋ ਸਕੀ। ਕਿਰਪਾ ਕਰਕੇ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਸੈਂਸਰ ਗੰਦਾ ਹੈ। ਕਿਰਪਾ ਕਰਕੇ ਇਸਨੂੰ ਸਾਫ਼ ਕਰੋ ਅਤੇ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
@@ -589,11 +589,10 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ਇਸ ਡੀਵਾਈਸ ਵਿੱਚ ਫਿੰਗਰਪ੍ਰਿੰਟ ਸੈਂਸਰ ਨਹੀਂ ਹੈ।"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ਸੈਂਸਰ ਅਸਥਾਈ ਤੌਰ \'ਤੇ ਬੰਦ ਕੀਤਾ ਗਿਆ।"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"ਉਂਗਲ <xliff:g id="FINGERID">%d</xliff:g>"</string>
-    <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
-    <skip />
-    <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
-    <skip />
+    <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਦੀ ਵਰਤੋਂ ਕਰੋ"</string>
+    <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਜਾਂ ਸਕ੍ਰੀਨ ਲਾਕ ਦੀ ਵਰਤੋਂ ਕਰੋ"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"ਜਾਰੀ ਰੱਖਣ ਲਈ ਆਪਣਾ ਫਿੰਗਰਪ੍ਰਿੰਟ ਵਰਤੋ"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"ਜਾਰੀ ਰੱਖਣ ਲਈ ਆਪਣਾ ਫਿੰਗਰਪ੍ਰਿੰਟ ਜਾਂ ਸਕ੍ਰੀਨ ਲਾਕ ਵਰਤੋ"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਪ੍ਰਤੀਕ"</string>
@@ -638,12 +637,10 @@
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"ਇਸ ਡੀਵਾਈਸ ਵਿੱਚ ਚਿਹਰਾ ਅਣਲਾਕ ਦੀ ਸੁਵਿਧਾ ਨਹੀਂ ਹੈ।"</string>
     <string name="face_error_security_update_required" msgid="5076017208528750161">"ਸੈਂਸਰ ਅਸਥਾਈ ਤੌਰ \'ਤੇ ਬੰਦ ਕੀਤਾ ਗਿਆ।"</string>
     <string name="face_name_template" msgid="3877037340223318119">"ਚਿਹਰਾ <xliff:g id="FACEID">%d</xliff:g>"</string>
-    <!-- no translation found for face_app_setting_name (8130135875458467243) -->
-    <skip />
-    <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
-    <skip />
-    <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
-    <skip />
+    <string name="face_app_setting_name" msgid="8130135875458467243">"ਚਿਹਰਾ ਅਣਲਾਕ ਦੀ ਵਰਤੋਂ ਕਰੋ"</string>
+    <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"ਚਿਹਰਾ ਜਾਂ ਸਕ੍ਰੀਨ ਲਾਕ ਦੀ ਵਰਤੋਂ ਕਰੋ"</string>
+    <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"ਜਾਰੀ ਰੱਖਣ ਲਈ ਚਿਹਰਾ ਅਣਲਾਕ ਦੀ ਵਰਤੋਂ ਕਰੋ"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"ਜਾਰੀ ਰੱਖਣ ਲਈ ਆਪਣਾ ਚਿਹਰਾ ਜਾਂ ਸਕ੍ਰੀਨ ਲਾਕ ਵਰਤੋ"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"ਚਿਹਰਾ ਪ੍ਰਤੀਕ"</string>
@@ -1007,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"ਤੁਹਾਨੂੰ ਇਸ ਸਫ਼ੇ ਨੂੰ ਖੋਲ੍ਹਣ ਦੀ ਅਨੁਮਤੀ ਨਹੀਂ ਹੈ।"</string>
     <string name="text_copied" msgid="2531420577879738860">"ਟੈਕਸਟ ਕਲਿਪਬੋਰਡ ਤੇ ਕਾਪੀ ਕੀਤਾ।"</string>
     <string name="copied" msgid="4675902854553014676">"ਕਾਪੀ ਕੀਤੀ ਗਈ"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> ਤੋਂ ਕਾਪੀ ਕੀਤੇ ਡਾਟੇ ਨੂੰ <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ਵਿੱਚ ਪੇਸਟ ਕੀਤਾ ਗਿਆ"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"ਕਲਿੱਪਬੋਰਡ ਦੇ ਡਾਟੇ ਨੂੰ <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ਵਿੱਚ ਪੇਸਟ ਕੀਤਾ ਗਿਆ"</string>
     <string name="more_item_label" msgid="7419249600215749115">"ਹੋਰ"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"ਮੀਨੂ+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1380,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"ਬੰਦ ਕਰੋ"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"<xliff:g id="NAME">%s</xliff:g> ਦੀ ਜਾਂਚ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"ਵਰਤਮਾਨ ਸਮੱਗਰੀ ਦੀ ਸਮੀਖਿਆ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"ਮੀਡੀਆ ਸਟੋਰੇਜ ਦਾ ਵਿਸ਼ਲੇਸ਼ਣ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"ਨਵਾਂ <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> ਕੰਮ ਨਹੀਂ ਕਰ ਰਿਹਾ ਹੈ"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"ਸੈੱਟਅੱਪ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"ਸੈੱਟਅੱਪ ਕਰਨ ਲਈ ਚੁਣੋ"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"ਤੁਹਾਨੂੰ ਡੀਵਾਈਸ ਨੂੰ ਮੁੜ-ਫਾਰਮੈਟ ਕਰਨ ਦੀ ਲੋੜ ਪੈ ਸਕਦੀ ਹੈ। ਕੱਢਣ ਲਈ ਟੈਪ ਕਰੋ।"</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"ਫ਼ੋਟੋਆਂ ਅਤੇ ਮੀਡੀਆ ਨੂੰ ਟ੍ਰਾਂਸਫ਼ਰ ਕਰਨ ਲਈ"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"ਮੀਡੀਆ ਫ਼ਾਈਲਾਂ ਨੂੰ ਬ੍ਰਾਊਜ਼ ਕਰੋ"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"<xliff:g id="NAME">%s</xliff:g> ਵਿੱਚ ਸਮੱਸਿਆ ਆਈ"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> ਕੰਮ ਨਹੀਂ ਕਰ ਰਿਹਾ ਹੈ"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"ਠੀਕ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
@@ -1393,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"ਅਸਮਰਥਿਤ <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> ਕੰਮ ਨਹੀਂ ਕਰ ਰਿਹਾ ਹੈ"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"ਇਹ ਡੀਵਾਈਸ ਇਸ <xliff:g id="NAME">%s</xliff:g> ਨੂੰ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦਾ ਹੈ। ਕਿਸੇ ਸਮਰਥਿਤ ਫਾਰਮੈਟ ਵਿੱਚ ਸਥਾਪਤ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"ਇਹ ਡੀਵਾਈਸ ਇਸ <xliff:g id="NAME">%s</xliff:g> ਦਾ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦਾ ਹੈ। ਕਿਸੇ ਸਮਰਥਿਤ ਫਾਰਮੈਟ ਵਿੱਚ ਸਥਾਪਤ ਕਰਨ ਲਈ ਚੁਣੋ।"</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"ਕਿਸੇ ਸਮਰਥਿਤ ਫਾਰਮੈਟ ਵਿੱਚ <xliff:g id="NAME">%s</xliff:g> ਦਾ ਸੈੱਟਅੱਪ ਕਰਨ ਲਈ ਚੁਣੋ।"</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"ਤੁਹਾਨੂੰ ਡੀਵਾਈਸ ਨੂੰ ਮੁੜ-ਫਾਰਮੈਟ ਕਰਨ ਦੀ ਲੋੜ ਪੈ ਸਕਦੀ ਹੈ"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> ਨੂੰ ਅਚਨਚੇਤ ਹਟਾਇਆ ਗਿਆ"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"ਸਮੱਗਰੀ ਗੁਆਉਣ ਤੋਂ ਬਚਣ ਲਈ ਹਟਾਉਣ ਤੋਂ ਪਹਿਲਾਂ ਮੀਡੀਆ ਕੱਢੋ"</string>
@@ -1687,7 +1689,8 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ਸ਼ਾਰਟਕੱਟ ਦੀ ਵਰਤੋਂ ਕਰੋ"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"ਰੰਗ ਪਲਟਨਾ"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"ਰੰਗ ਸੁਧਾਈ"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"ਚਮਕ ਘਟਾਓ"</string>
+    <!-- no translation found for reduce_bright_colors_feature_name (3222994553174604132) -->
+    <skip />
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ਅਵਾਜ਼ੀ ਕੁੰਜੀਆਂ ਦਬਾ ਕੇ ਰੱਖੀਆਂ ਗਈਆਂ। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ਨੂੰ ਚਾਲੂ ਕੀਤਾ ਗਿਆ।"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ਅਵਾਜ਼ੀ ਕੁੰਜੀਆਂ ਦਬਾ ਕੇ ਰੱਖੀਆਂ ਗਈਆਂ। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ਨੂੰ ਬੰਦ ਕੀਤਾ ਗਿਆ।"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ਦੀ ਵਰਤੋਂ ਕਰਨ ਲਈ ਦੋਵੇਂ ਅਵਾਜ਼ ਕੁੰਜੀਆਂ ਨੂੰ 3 ਸਕਿੰਟਾਂ ਲਈ ਦਬਾਈ ਰੱਖੋ"</string>
@@ -1699,7 +1702,7 @@
     <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਵਿਚਾਲੇ ਅਦਲਾ-ਬਦਲੀ ਕਰਨ ਲਈ, ਤਿੰਨ ਉਂਗਲਾਂ ਨਾਲ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰਕੇ ਦਬਾਈ ਰੱਖੋ।"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"ਵੱਡਦਰਸ਼ੀਕਰਨ"</string>
     <string name="user_switched" msgid="7249833311585228097">"ਮੌਜੂਦਾ ਉਪਭੋਗਤਾ <xliff:g id="NAME">%1$s</xliff:g>।"</string>
-    <string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> ਤੇ ਸਵਿਚ ਕਰ ਰਿਹਾ ਹੈ…"</string>
+    <string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> \'ਤੇ ਸਵਿਚ ਕਰ ਰਿਹਾ ਹੈ…"</string>
     <string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> ਨੂੰ ਲਾਗ-ਆਉਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ …"</string>
     <string name="owner_name" msgid="8713560351570795743">"ਮਾਲਕ"</string>
     <string name="error_message_title" msgid="4082495589294631966">"ਅਸ਼ੁੱਧੀ"</string>
@@ -1966,8 +1969,7 @@
     <string name="app_category_news" msgid="1172762719574964544">"ਖਬਰਾਂ ਅਤੇ ਰਸਾਲੇ"</string>
     <string name="app_category_maps" msgid="6395725487922533156">"ਨਕਸ਼ੇ ਅਤੇ ਆਵਾਗੌਣ"</string>
     <string name="app_category_productivity" msgid="1844422703029557883">"ਉਤਪਾਦਕਤਾ"</string>
-    <!-- no translation found for app_category_accessibility (6643521607848547683) -->
-    <skip />
+    <string name="app_category_accessibility" msgid="6643521607848547683">"ਪਹੁੰਚਯੋਗਤਾ"</string>
     <string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"ਡੀਵਾਈਸ ਸਟੋਰੇਜ"</string>
     <string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB ਡੀਬੱਗਿੰਗ"</string>
     <string name="time_picker_hour_label" msgid="4208590187662336864">"ਘੰਟਾ"</string>
@@ -2097,6 +2099,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"ਸਕ੍ਰੀਨ \'ਤੇ ਦਿਸਣ ਵਾਲਾ ਪਹੁੰਚਯੋਗਤਾ ਸ਼ਾਰਟਕੱਟ"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"ਸਕ੍ਰੀਨ \'ਤੇ ਦਿਸਣ ਵਾਲੇ ਪਹੁੰਚਯੋਗਤਾ ਸ਼ਾਰਟਕੱਟ ਦਾ ਚੋਣਕਾਰ"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"ਪਹੁੰਚਯੋਗਤਾ ਸ਼ਾਰਟਕੱਟ"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"ਸੂਚਨਾ ਸ਼ੇਡ ਖਾਰਜ ਕਰੋ"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<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> ਨੂੰ ਪ੍ਰਤਿਬੰਧਿਤ ਖਾਨੇ ਵਿੱਚ ਪਾਇਆ ਗਿਆ ਹੈ"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2234,8 +2237,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"ਨਵਾਂ: Window ਵੱਡਦਰਸ਼ੀ"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"ਹੁਣ ਤੁਸੀਂ ਕੁਝ ਜਾਂ ਪੂਰੀ ਸਕ੍ਰੀਨ ਵੱਡਦਰਸ਼ੀ ਕਰ ਸਕਦੇ ਹੋ"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"ਆਪਣੀ ਸਕ੍ਰੀਨ ਦੇ ਕਿਸੇ ਹਿੱਸੇ ਨੂੰ ਵੱਡਦਰਸ਼ੀ ਕਰੋ"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"ਤੁਸੀਂ ਹੁਣ ਆਪਣੀ ਪੂਰੀ ਸਕ੍ਰੀਨ ਜਾਂ ਸਕ੍ਰੀਨ ਦੇ ਕਿਸੇ ਖਾਸ ਹਿੱਸੇ ਨੂੰ ਵੱਡਦਰਸ਼ੀ ਕਰ ਸਕਦੇ ਹੋ, ਜਾਂ ਇਹਨਾਂ ਦੋਨਾਂ ਵਿਕਲਪਾਂ ਵਿਚਾਲੇ ਸਵਿੱਚ ਕਰ ਸਕਦੇ ਹੋ।"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਚਾਲੂ ਕਰੋ"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"ਖਾਰਜ ਕਰੋ"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"ਜਾਰੀ ਰੱਖਣ ਲਈ, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ਨੂੰ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਤੱਕ ਪਹੁੰਚ ਦੀ ਲੋੜ ਹੈ।"</string>
@@ -2244,4 +2247,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"ਸੈਂਸਰ ਪਰਦੇਦਾਰੀ"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"ਐਪਲੀਕੇਸ਼ਨ ਪ੍ਰਤੀਕ"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"ਐਪਲੀਕੇਸ਼ਨ ਦਾ ਬ੍ਰਾਂਡ ਵਾਲਾ ਚਿੱਤਰ"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"ਪਹੁੰਚ ਸੈਟਿੰਗਾਂ ਦੀ ਜਾਂਚ ਕਰੋ"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> ਸੇਵਾ ਤੁਹਾਡੀ ਸਕ੍ਰੀਨ ਨੂੰ ਦੇਖ ਅਤੇ ਕੰਟਰੋਲ ਕਰ ਸਕਦੀ ਹੈ। ਸਮੀਖਿਆ ਲਈ ਟੈਪ ਕਰੋ।"</string>
 </resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 4b18320..c78efd7 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -208,6 +208,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Usługa Zmierzch"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Wykrywanie strefy czasowej (brak połączenia)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"Usługa synchronizacji czasu na podstawie sygnału GNSS"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Usługa menedżera rozpoznawania muzyki"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Twoje urządzenie zostanie wyczyszczone"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Nie można użyć aplikacji administratora. Dane z urządzenia zostaną wykasowane.\n\nJeśli masz pytania, skontaktuj się z administratorem organizacji."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Drukowanie wyłączone przez: <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -299,6 +300,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Działa aplikacja"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Aplikacje zużywające baterię"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Powiększenie"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Zasady bezpieczeństwa związane z ułatwieniami dostępu"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> zużywa baterię"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"Liczba aplikacji zużywających baterię: <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Kliknij, by wyświetlić szczegóły wykorzystania baterii i użycia danych"</string>
@@ -349,6 +351,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Pozwala aplikacji na występowanie na pasku stanu."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"rozwijanie/zwijanie paska stanu"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Pozwala aplikacji na rozwijanie lub zwijanie paska stanu."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"wyświetlaj powiadomienia w trybie pełnoekranowym na zablokowanym urządzeniu"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Zezwala na wyświetlanie przez aplikacje powiadomień w trybie pełnoekranowym na zablokowanym urządzeniu"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"instalowanie skrótów"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Pozwala aplikacji dodawać skróty na ekranie głównym bez interwencji użytkownika."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"odinstalowywanie skrótów"</string>
@@ -558,8 +562,9 @@
     <string name="permdesc_mediaLocation" msgid="597912899423578138">"Zezwala aplikacji na odczytywanie lokalizacji z kolekcji multimediów."</string>
     <string name="biometric_app_setting_name" msgid="3339209978734534457">"Używaj biometrii"</string>
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Używaj biometrii lub blokady ekranu"</string>
-    <string name="biometric_dialog_default_title" msgid="55026799173208210">"Potwierdź swoją tożsamość"</string>
+    <string name="biometric_dialog_default_title" msgid="55026799173208210">"Potwierdź, że to Ty"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Użyj biometrii, by kontynuować"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Aby kontynuować, użyj biometrii lub blokady ekranu"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Sprzęt biometryczny niedostępny"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Anulowano uwierzytelnianie"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Nie rozpoznano"</string>
@@ -593,6 +598,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Używaj odcisku palca"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Używaj odcisku palca lub blokady ekranu"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Użyj odcisku palca, by kontynuować"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Aby kontynuować, użyj odcisku palca lub blokady ekranu"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikona odcisku palca"</string>
@@ -640,6 +646,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Używaj rozpoznawania twarzy"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Używaj rozpoznawania twarzy lub blokady ekranu"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Użyj rozpoznawania twarzy, aby kontynuować"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Aby kontynuować, użyj rozpoznawania twarzy lub blokady ekranu"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Ikona twarzy"</string>
@@ -1003,6 +1010,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"Nie masz pozwolenia na otwarcie tej strony."</string>
     <string name="text_copied" msgid="2531420577879738860">"Tekst został skopiowany do schowka."</string>
     <string name="copied" msgid="4675902854553014676">"Skopiowano"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"Aplikacja <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> wkleiła dane z aplikacji <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"Aplikacja <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> wkleiła dane ze schowka"</string>
     <string name="more_item_label" msgid="7419249600215749115">"Więcej"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Menu+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1410,11 +1419,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Wyłącz"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Sprawdzam: <xliff:g id="NAME">%s</xliff:g>…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Sprawdzam bieżącą zawartość"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Analizuję miejsce na multimedia"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Nowy nośnik: <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> nie działa"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Kliknij, by skonfigurować"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Wybierz, aby skonfigurować"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Może być konieczne ponowne sformatowanie urządzenia. Kliknij, by je odłączyć."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"Do przenoszenia zdjęć i multimediów"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Przeglądaj pliki multimediów"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Wystąpił problem z: <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> nie działa"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Kliknij, by naprawić"</string>
@@ -1423,7 +1435,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"Nośnik <xliff:g id="NAME">%s</xliff:g> nieobsługiwany"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> nie działa"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"To urządzenie nie obsługuje <xliff:g id="NAME">%s</xliff:g>. Kliknij, by użyć obsługiwanego formatu."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"To urządzenie nie obsługuje nośnika <xliff:g id="NAME">%s</xliff:g>. Wybierz, by skonfigurować obsługiwany format."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Wybierz, aby skonfigurować nośnik <xliff:g id="NAME">%s</xliff:g> w obsługiwanym formacie."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Może być konieczne ponowne sformatowanie urządzenia"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g>: nieoczekiwane wyjęcie"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Zanim wyjmiesz nośnik, odłącz go, by uniknąć utraty danych"</string>
@@ -1721,7 +1733,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Użyj skrótu"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Odwrócenie kolorów"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Korekcja kolorów"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Zmniejsz jasność"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Dodatkowe przyciemnienie"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Przytrzymano klawisze głośności. Usługa <xliff:g id="SERVICE_NAME">%1$s</xliff:g> została włączona."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Przytrzymano klawisze głośności. Usługa <xliff:g id="SERVICE_NAME">%1$s</xliff:g> została wyłączona."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Naciśnij i przytrzymaj oba przyciski głośności przez trzy sekundy, by użyć usługi <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -2154,6 +2166,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Ekranowy skrót ułatwień dostępu"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Wybierz ekranowy skrót ułatwień dostępu"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Skrót ułatwień dostępu"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Zamknij obszar powiadomień"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Pasek napisów w aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Umieszczono pakiet <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> w zasobniku danych RESTRICTED"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2291,8 +2304,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Nowość: powiększanie okna"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Możesz teraz powiększyć część lub całość ekranu"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Powiększ część ekranu"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Możesz powiększyć ekran lub konkretny obszar bądź przełączać się między tymi opcjami."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Włącz w Ustawieniach"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Odrzuć"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Aby kontynuować, musisz przyznać aplikacji „<xliff:g id="APP">%s</xliff:g>” dostęp do mikrofonu urządzenia."</string>
@@ -2301,4 +2314,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Poufność danych z czujników"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Ikona aplikacji"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Wizerunek marki aplikacji"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Sprawdź ustawienia dostępu"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"Usługa <xliff:g id="SERVICE_NAME">%s</xliff:g> może wyświetlać i kontrolować ekran. Kliknij, aby sprawdzić."</string>
 </resources>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 7d028f9..5962304 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Serviço de crepúsculo"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Detector de fuso horário (sem conectividade)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"Serviço de atualização de horário do Sistema Global de Navegação por Satélites (GNSS, na sigla em inglês)"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Serviço de gerenciamento do reconhecimento de música"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Seu dispositivo será limpo"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Não é possível usar o aplicativo para administrador. Seu dispositivo passará por uma limpeza agora.\n\nEm caso de dúvidas, entre em contato com o administrador da sua organização."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Impressão desativada por <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"App em execução"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Apps que estão consumindo a bateria"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Ampliação"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Política de segurança de acessibilidade"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está consumindo a bateria"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> apps estão consumindo a bateria"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Tocar para ver detalhes sobre a bateria e o uso de dados"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Permite que o app seja a barra de status."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"expandir/recolher barra de status"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Permite que o app expanda ou recolha a barra de status."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"exibir notificações como atividades em tela cheia em um dispositivo bloqueado"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Permite que o app exiba notificações como atividades em tela cheia em um dispositivo bloqueado"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"instalar atalhos"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Permite que um app adicione atalhos da tela inicial sem a intervenção do usuário."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"desinstalar atalhos"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Usar biometria ou bloqueio de tela"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Confirme que é você"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Use seus dados biométricos para continuar"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Use sua autenticação biométrica ou o bloqueio de tela para continuar"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Hardware biométrico indisponível"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Autenticação cancelada"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Não reconhecido"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Usar impressão digital"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Usar impressão digital ou bloqueio de tela"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Use sua impressão digital para continuar"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Use sua impressão digital ou o bloqueio de tela para continuar"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ícone de impressão digital"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Usar desbloqueio facial"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Usar reconhecimento facial ou bloqueio de tela"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Use o desbloqueio facial para continuar"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Use seu rosto ou o bloqueio de tela para continuar"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Ícone facial"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"Você não tem permissão para abrir esta página."</string>
     <string name="text_copied" msgid="2531420577879738860">"Texto copiado para a área de transferência."</string>
     <string name="copied" msgid="4675902854553014676">"Copiado"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"Dados do app <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> colados no app <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"Dados da área de transferência colados no app <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>"</string>
     <string name="more_item_label" msgid="7419249600215749115">"Mais"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Menu+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Desativar"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Verificando <xliff:g id="NAME">%s</xliff:g>…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Analisando conteúdo atual"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Analisando armazenamento de mídia"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Novo <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> não está funcionando"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Toque para configurar"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Selecione para configurar"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Pode ser necessário reformatar o dispositivo. Toque para ejetá-lo."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"Para transferir fotos e mídia"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Procure arquivos de mídia"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Ocorreu um problema com o <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> não está funcionando"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Toque para corrigir"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"<xliff:g id="NAME">%s</xliff:g> não compatível"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> não está funcionando"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"Este dispositivo não é compatível com esse <xliff:g id="NAME">%s</xliff:g>. Toque para configurar em um formato compatível."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"Este dispositivo não é compatível com este <xliff:g id="NAME">%s</xliff:g>. Selecione para configurar um formato compatível."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Selecione para configurar <xliff:g id="NAME">%s</xliff:g> em um formato compatível."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Pode ser necessário reformatar o dispositivo"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> foi removido inesperadamente"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Ejete a mídia antes da remoção para evitar a perda de conteúdo"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Usar atalho"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversão de cores"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Correção de cor"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Reduzir brilho"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Mais escuro"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Teclas de volume pressionadas. Serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ativado."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Teclas de volume pressionadas. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> desativado."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Toque nos dois botões de volume e os mantenha pressionados por três segundo para usar o <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Atalho de acessibilidade na tela"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Seletor de atalho de acessibilidade na tela"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Atalho de acessibilidade"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Dispensar aba de notificações"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Barra de legendas do app <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> foi colocado no intervalo \"RESTRITO\""</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Novo: Lupa de janela"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Agora você pode ampliar uma ou todas as suas telas"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Ampliar parte da tela"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Agora você pode ampliar toda a tela, uma área específica ou alternar entre as duas opções."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Ativar nas Configurações"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Dispensar"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Para continuar, o app &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; precisa acessar o microfone do dispositivo."</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privacidade do sensor"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Ícone do aplicativo"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Imagem da marca do aplicativo"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Confira as configurações de acesso"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"O serviço <xliff:g id="SERVICE_NAME">%s</xliff:g> pode ver e controlar sua tela. Toque para revisar."</string>
 </resources>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index a01db5e..54d0a2e 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Serviço de crepúsculo"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Detetor do fuso horário (sem conetividade)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"Serviço de atualização da hora GNSS"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Serviço do gestor de reconhecimento de música"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"O seu dispositivo será apagado"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Não é possível utilizar a app de administrador. O seu dispositivo será agora apagado.\n\nSe tiver questões, contacte o administrador da entidade."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Impressão desativada por <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Aplicação em execução"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Apps que estão a consumir bateria"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Ampliação"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Política de segurança de acessibilidade"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"A app <xliff:g id="APP_NAME">%1$s</xliff:g> está a consumir bateria."</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> aplicações estão a consumir bateria."</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Toque para obter detalhes acerca da utilização da bateria e dos dados"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Permite que a app seja apresentada na barra de estado."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"expandir/fechar barra de estado"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Permite à app expandir ou fechar a barra de estado."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"apresentar notificações como atividades em ecrã inteiro num dispositivo bloqueado"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Permite à app apresentar notificações como atividades em ecrã inteiro num dispositivo bloqueado"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"instalar atalhos"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Permite que uma app adicione atalhos ao Ecrã principal sem a intervenção do utilizador."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"desinstalar atalhos"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Utilizar a biometria ou o bloqueio de ecrã"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Confirme a sua identidade"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Utilize a biometria para continuar."</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Utilize a biometria ou o bloqueio de ecrã para continuar"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Hardware biométrico indisponível."</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Autenticação cancelada"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Não reconhecido."</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Utilizar a impressão digital"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Utilizar o bloqueio de ecrã ou a impressão digital"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Utilize a sua impressão digital para continuar."</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Utilize a impressão digital ou o bloqueio de ecrã para continuar"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ícone de impressão digital"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Utilizar o desbloqueio facial"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Utilizar o bloqueio através do rosto ou de ecrã"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Utilize o desbloqueio facial para continuar."</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Utilize o rosto ou o bloqueio de ecrã para continuar"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Ícone de rosto"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"Não tem autorização para abrir esta página."</string>
     <string name="text_copied" msgid="2531420577879738860">"Texto copiado para a área de transferência."</string>
     <string name="copied" msgid="4675902854553014676">"Copiado"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"A app <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> colou da app <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"A app <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> colou da área de transferência"</string>
     <string name="more_item_label" msgid="7419249600215749115">"Mais"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Menu+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta +"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Desligar"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"A verificar o <xliff:g id="NAME">%s</xliff:g>…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"A rever o conteúdo atual…"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"A analisar o armazenamento de multimédia"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Novo <xliff:g id="NAME">%s</xliff:g>."</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> não está a funcionar."</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Toque para configurar."</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Selecione para configurar"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Poderá ser necessário reformatar o dispositivo. Toque para o ejetar."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"Transf. fotos, conteúdos multimédia."</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Procure ficheiros multimédia"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Ocorreu um problema com o <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> não está a funcionar."</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Toque para corrigir."</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"<xliff:g id="NAME">%s</xliff:g> não suportado"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> não está a funcionar."</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"Este dispositivo não é compatível com este <xliff:g id="NAME">%s</xliff:g>. Toque para o configurar num formato compatível."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"Este dispositivo não é compatível com este(a) <xliff:g id="NAME">%s</xliff:g>. Selecione para configurar num formato compatível."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Selecione para configurar o(a) <xliff:g id="NAME">%s</xliff:g> num formato suportado."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Poderá ser necessário reformatar o dispositivo."</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> foi removido inesperadamente"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Ejete o armazenamento multimédia antes de o remover para evitar a perda de conteúdos."</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Utilizar atalho"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversão de cores"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Correção da cor"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Reduza o brilho"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Escurecimento extra"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Teclas do volume premidas. Serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ativado."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Teclas de volume premidas. Serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g> desativado."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Prima sem soltar as teclas de volume durante três segundos para utilizar o serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Atalho de acessibilidade no ecrã"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Selecionador de atalhos de acessibilidade no ecrã"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Atalho de acessibilidade"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Ignorar o painel de notificações"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Barra de legendas da app <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> foi colocado no contentor RESTRITO."</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Novidade: ampliador da janela"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Já pode ampliar o ecrã parcial ou totalmente."</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Amplie parte do ecrã"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Já pode ampliar o ecrã inteiro, uma área específica ou alternar entre as duas opções."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Ativar nas Definições"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Ignorar"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Para continuar, a app &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; precisa de acesso ao microfone do dispositivo."</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privacidade dos sensores"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Ícone de aplicação."</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Imagem de branding da aplicação."</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Verifique as definições de acesso"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"O serviço <xliff:g id="SERVICE_NAME">%s</xliff:g> pode ver e controlar o seu ecrã. Toque para rever."</string>
 </resources>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 7d028f9..5962304 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Serviço de crepúsculo"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Detector de fuso horário (sem conectividade)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"Serviço de atualização de horário do Sistema Global de Navegação por Satélites (GNSS, na sigla em inglês)"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Serviço de gerenciamento do reconhecimento de música"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Seu dispositivo será limpo"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Não é possível usar o aplicativo para administrador. Seu dispositivo passará por uma limpeza agora.\n\nEm caso de dúvidas, entre em contato com o administrador da sua organização."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Impressão desativada por <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"App em execução"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Apps que estão consumindo a bateria"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Ampliação"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Política de segurança de acessibilidade"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está consumindo a bateria"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> apps estão consumindo a bateria"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Tocar para ver detalhes sobre a bateria e o uso de dados"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Permite que o app seja a barra de status."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"expandir/recolher barra de status"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Permite que o app expanda ou recolha a barra de status."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"exibir notificações como atividades em tela cheia em um dispositivo bloqueado"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Permite que o app exiba notificações como atividades em tela cheia em um dispositivo bloqueado"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"instalar atalhos"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Permite que um app adicione atalhos da tela inicial sem a intervenção do usuário."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"desinstalar atalhos"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Usar biometria ou bloqueio de tela"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Confirme que é você"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Use seus dados biométricos para continuar"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Use sua autenticação biométrica ou o bloqueio de tela para continuar"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Hardware biométrico indisponível"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Autenticação cancelada"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Não reconhecido"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Usar impressão digital"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Usar impressão digital ou bloqueio de tela"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Use sua impressão digital para continuar"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Use sua impressão digital ou o bloqueio de tela para continuar"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ícone de impressão digital"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Usar desbloqueio facial"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Usar reconhecimento facial ou bloqueio de tela"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Use o desbloqueio facial para continuar"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Use seu rosto ou o bloqueio de tela para continuar"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Ícone facial"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"Você não tem permissão para abrir esta página."</string>
     <string name="text_copied" msgid="2531420577879738860">"Texto copiado para a área de transferência."</string>
     <string name="copied" msgid="4675902854553014676">"Copiado"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"Dados do app <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> colados no app <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"Dados da área de transferência colados no app <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>"</string>
     <string name="more_item_label" msgid="7419249600215749115">"Mais"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Menu+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Desativar"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Verificando <xliff:g id="NAME">%s</xliff:g>…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Analisando conteúdo atual"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Analisando armazenamento de mídia"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Novo <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> não está funcionando"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Toque para configurar"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Selecione para configurar"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Pode ser necessário reformatar o dispositivo. Toque para ejetá-lo."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"Para transferir fotos e mídia"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Procure arquivos de mídia"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Ocorreu um problema com o <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> não está funcionando"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Toque para corrigir"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"<xliff:g id="NAME">%s</xliff:g> não compatível"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> não está funcionando"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"Este dispositivo não é compatível com esse <xliff:g id="NAME">%s</xliff:g>. Toque para configurar em um formato compatível."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"Este dispositivo não é compatível com este <xliff:g id="NAME">%s</xliff:g>. Selecione para configurar um formato compatível."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Selecione para configurar <xliff:g id="NAME">%s</xliff:g> em um formato compatível."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Pode ser necessário reformatar o dispositivo"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> foi removido inesperadamente"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Ejete a mídia antes da remoção para evitar a perda de conteúdo"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Usar atalho"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversão de cores"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Correção de cor"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Reduzir brilho"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Mais escuro"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Teclas de volume pressionadas. Serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ativado."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Teclas de volume pressionadas. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> desativado."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Toque nos dois botões de volume e os mantenha pressionados por três segundo para usar o <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Atalho de acessibilidade na tela"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Seletor de atalho de acessibilidade na tela"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Atalho de acessibilidade"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Dispensar aba de notificações"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Barra de legendas do app <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> foi colocado no intervalo \"RESTRITO\""</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Novo: Lupa de janela"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Agora você pode ampliar uma ou todas as suas telas"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Ampliar parte da tela"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Agora você pode ampliar toda a tela, uma área específica ou alternar entre as duas opções."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Ativar nas Configurações"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Dispensar"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Para continuar, o app &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; precisa acessar o microfone do dispositivo."</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privacidade do sensor"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Ícone do aplicativo"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Imagem da marca do aplicativo"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Confira as configurações de acesso"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"O serviço <xliff:g id="SERVICE_NAME">%s</xliff:g> pode ver e controlar sua tela. Toque para revisar."</string>
 </resources>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index e8c5539..2d7d149 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -206,6 +206,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Serviciul Twilight"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Detector de fus orar (fără conexiune)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"Serviciul de actualizare a orei bazat pe GNSS"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Serviciu de gestionare a recunoașterii de melodii"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Datele de pe dispozitiv vor fi șterse"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Aplicația de administrare nu poate fi utilizată. Dispozitivul va fi șters.\n\nDacă aveți întrebări, contactați administratorul organizației dvs."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Printare dezactivată de <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -296,6 +297,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Aplicația rulează"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Aplicațiile consumă bateria"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Mărire"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Politica de securitate privind accesibilitatea"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> folosește bateria"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> aplicații folosesc bateria"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Atingeți pentru mai multe detalii privind bateria și utilizarea datelor"</string>
@@ -346,6 +348,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Permite aplicației să fie bară de stare."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"extindere/restrângere bară de stare"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Permite aplicației să extindă sau să restrângă bara de stare."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"să afișeze notificări ca activități pe ecran complet pe un dispozitiv blocat"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Permite aplicației să afișeze notificări ca activități pe ecran complet pe un dispozitiv blocat"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"instalează comenzi rapide"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Permite unei aplicații să adauge comenzi rapide pe ecranul de pornire, fără intervenția utilizatorului."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"dezinstalează comenzi rapide"</string>
@@ -557,6 +561,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Folosiți sistemele biometrice sau blocarea ecranului"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Confirmați-vă identitatea"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Folosiți sistemele biometrice pentru a continua"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Folosiți sistemele biometrice sau blocarea ecranului pentru a continua"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Hardware biometric indisponibil"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Autentificarea a fost anulată"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Nu este recunoscut"</string>
@@ -590,6 +595,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Folosiți amprenta"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Folosiți amprenta sau blocarea ecranului"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Folosiți amprenta pentru a continua"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Folosiți amprenta sau blocarea ecranului pentru a continua"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Pictograma amprentă"</string>
@@ -637,6 +643,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Folosiți deblocarea facială"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Folosiți blocarea ecranului sau blocarea facială"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Folosiți deblocarea facială pentru a continua"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Folosiți-vă chipul sau blocarea ecranului pentru a continua"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Pictograma chip"</string>
@@ -1000,6 +1007,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"Nu aveți permisiunea de a deschide această pagină."</string>
     <string name="text_copied" msgid="2531420577879738860">"Text copiat în clipboard."</string>
     <string name="copied" msgid="4675902854553014676">"Copiat"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> a inserat date din <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> a inserat date din clipboard"</string>
     <string name="more_item_label" msgid="7419249600215749115">"Mai multe"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Meniu+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1390,11 +1399,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Dezactivați"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Se verifică <xliff:g id="NAME">%s</xliff:g>…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Se examinează conținutul curent"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Se analizează spațiul de stocare media"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"<xliff:g id="NAME">%s</xliff:g> nou"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> nu funcționează"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Atingeți pentru a configura"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Selectați pentru a configura"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Poate fi nevoie să reformatați dispozitivul. Atingeți pentru a-l scoate."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"Pentru a transfera fotografii și fișiere media"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Răsfoiți fișierele media"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Problemă cu <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> nu funcționează"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Atingeți pentru a remedia"</string>
@@ -1403,7 +1415,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"<xliff:g id="NAME">%s</xliff:g> necompatibil"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> nu funcționează"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"Dispozitivul nu este compatibil cu acest <xliff:g id="NAME">%s</xliff:g>. Atingeți pentru configurare într-un format compatibil."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"Dispozitivul nu este compatibil cu acest <xliff:g id="NAME">%s</xliff:g>. Selectați pentru configurare într-un format compatibil."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Selectați pentru a configura <xliff:g id="NAME">%s</xliff:g> într-un format acceptat."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Poate fi nevoie să reformatați dispozitivul"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> scos pe neașteptate"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Deconectați din setări dispozitivele media înainte de a le îndepărta, pentru a evita pierderea conținutului"</string>
@@ -1699,7 +1711,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Utilizați comanda rapidă"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversarea culorilor"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Corecția culorii"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Reduceți luminozitatea"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Luminozitate redusă suplimentar"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"S-au apăsat lung tastele de volum. S-a activat <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"S-au apăsat lung tastele de volum. S-a dezactivat <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Apăsați ambele butoane de volum timp de trei secunde pentru a folosi <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -2120,6 +2132,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Comandă rapidă de accesibilitate de pe ecran"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Selector de comenzi rapide de accesibilitate de pe ecran"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Comandă rapidă de accesibilitate"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Închideți fereastra de notificări"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Bară cu legenda pentru <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> a fost adăugat la grupul RESTRICȚIONATE"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2257,8 +2270,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Nou: lupă fereastră"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Acum puteți mări o parte sau tot ecranul"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Măriți o parte a ecranului"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Acum puteți să măriți tot ecranul sau o anumită zonă ori să comutați între cele două opțiuni."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Activați din Setări"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Respingeți"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Pentru a continua, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; necesită acces la microfonul dispozitivului."</string>
@@ -2267,4 +2280,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Confidențialitatea privind senzorii"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Pictograma aplicației"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Imaginea de branding a aplicației"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Verificați setările pentru acces"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> poată să vadă și să vă controleze ecranul. Atingeți pentru a examina."</string>
 </resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 48f96ef..a980750 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -208,6 +208,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Сервис для определения наступления сумерек"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Определитель часового пояса (работает без Интернета)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"Синхронизация времени с помощью ГНСС"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Сервис управления распознаванием музыки"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Все данные с устройства будут удалены"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Невозможно использовать приложение для администрирования. С устройства будут удалены все данные.\n\nЕсли у вас возникли вопросы, обратитесь к администратору."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Функция печати отключена приложением \"<xliff:g id="OWNER_APP">%s</xliff:g>\""</string>
@@ -231,7 +232,7 @@
     <string name="reboot_to_update_prepare" msgid="6978842143587422365">"Подготовка обновлений…"</string>
     <string name="reboot_to_update_package" msgid="4644104795527534811">"Обработка обновлений…"</string>
     <string name="reboot_to_update_reboot" msgid="4474726009984452312">"Перезагрузка…"</string>
-    <string name="reboot_to_reset_title" msgid="2226229680017882787">"Сбросить к заводским настройкам"</string>
+    <string name="reboot_to_reset_title" msgid="2226229680017882787">"Сбросить настройки"</string>
     <string name="reboot_to_reset_message" msgid="3347690497972074356">"Перезагрузка…"</string>
     <string name="shutdown_progress" msgid="5017145516412657345">"Выключение..."</string>
     <string name="shutdown_confirm" product="tablet" msgid="2872769463279602432">"Планшетный ПК будет отключен."</string>
@@ -299,6 +300,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Приложение активно"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Приложения, расходующие заряд"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Увеличение"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Политика безопасности для специальных возможностей"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" расходует заряд"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"Несколько приложений (<xliff:g id="NUMBER">%1$d</xliff:g>) расходуют заряд"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Нажмите, чтобы проверить энергопотребление и трафик"</string>
@@ -349,6 +351,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Приложение сможет заменять собой строку состояния."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"Разворачивание/сворачивание строки состояния"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Приложение сможет разворачивать и сворачивать строку состояния."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"Показ уведомлений в полноэкранном режиме на заблокированном устройстве"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Приложение сможет показывать уведомления в полноэкранном режиме на заблокированном устройстве"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"Создание ярлыков"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Приложение сможет добавлять ярлыки на главный экран без вмешательства пользователя."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"Удаление ярлыков"</string>
@@ -559,7 +563,8 @@
     <string name="biometric_app_setting_name" msgid="3339209978734534457">"Использовать биометрию"</string>
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Использовать биометрию или блокировку экрана"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Подтвердите, что это вы"</string>
-    <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Чтобы продолжить, используйте биометрические данные"</string>
+    <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Чтобы продолжить, используйте биометрические данные."</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Чтобы продолжить, используйте биометрию или данные для разблокировки экрана."</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Биометрическое оборудование недоступно"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Аутентификация отменена"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Не распознано"</string>
@@ -567,7 +572,7 @@
     <string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Укажите PIN-код, пароль или графический ключ"</string>
     <string name="biometric_error_generic" msgid="6784371929985434439">"Ошибка аутентификации."</string>
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Использовать блокировку экрана"</string>
-    <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Чтобы продолжить, введите учетные данные устройства"</string>
+    <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Чтобы продолжить, введите учетные данные устройства."</string>
     <string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Отсканирована только часть отпечатка. Повторите попытку."</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Не удалось распознать отпечаток. Повторите попытку."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Очистите сканер и повторите попытку."</string>
@@ -593,6 +598,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Использовать отпечаток пальца"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Использовать отпечаток пальца или блокировку экрана"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Чтобы продолжить, используйте цифровой отпечаток"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Чтобы продолжить, используйте отпечаток пальца или данные для разблокировки экрана."</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Значок отпечатка пальца"</string>
@@ -639,7 +645,8 @@
     <string name="face_name_template" msgid="3877037340223318119">"Лицо <xliff:g id="FACEID">%d</xliff:g>"</string>
     <string name="face_app_setting_name" msgid="8130135875458467243">"Использовать фейсконтроль"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Использовать фейсконтроль или блокировку экрана"</string>
-    <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Чтобы продолжить, используйте фейсконтроль"</string>
+    <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Чтобы продолжить, используйте фейсконтроль."</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Чтобы продолжить, посмотрите на экран или используйте данные для разблокировки."</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Значок лица"</string>
@@ -1003,6 +1010,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"У вас нет доступа к этой странице."</string>
     <string name="text_copied" msgid="2531420577879738860">"Текст скопирован в буфер обмена."</string>
     <string name="copied" msgid="4675902854553014676">"Скопировано"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"Данные из приложения \"<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>\" вставлены в приложение \"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>\"."</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"Данные из буфера обмена вставлены в приложение \"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>\"."</string>
     <string name="more_item_label" msgid="7419249600215749115">"Ещё"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Меню+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta +"</string>
@@ -1410,11 +1419,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Отключить"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Проверка накопителя (<xliff:g id="NAME">%s</xliff:g>)…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Выполняем проверку контента."</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Анализ хранилища мультимедиа…"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Новый накопитель: <xliff:g id="NAME">%s</xliff:g>."</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> не работает"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Нажмите, чтобы настроить."</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Выберите, чтобы настроить."</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Возможно, потребуется отформатировать устройство. Нажмите, чтобы извлечь его."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"Для переноса фотографий и других файлов"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Посмотрите медиафайлы."</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Проблема с накопителем (<xliff:g id="NAME">%s</xliff:g>)"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> не работает"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Нажмите здесь, чтобы исправить."</string>
@@ -1423,7 +1435,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"<xliff:g id="NAME">%s</xliff:g> не поддерживается"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> не работает"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"Устройство не поддерживает этот носитель (<xliff:g id="NAME">%s</xliff:g>). Нажмите, чтобы настроить."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"Внешний носитель (<xliff:g id="NAME">%s</xliff:g>) не поддерживается на этом устройстве. Выберите, чтобы изменить формат."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Выберите, чтобы настроить носитель (<xliff:g id="NAME">%s</xliff:g>) в поддерживаемом формате."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Возможно, потребуется отформатировать устройство."</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"Карта \"<xliff:g id="NAME">%s</xliff:g>\" извлечена неправильно"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Перед тем как извлечь накопитель, отключите его, чтобы избежать потери данных."</string>
@@ -1721,7 +1733,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Использовать быстрое включение"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Инверсия цветов"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Коррекция цвета"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Уменьшение яркости"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Дополнительное уменьшение яркости"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Использован жест с кнопками регулировки громкости. Функция \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\" включена."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Использован жест с кнопками регулировки громкости. Функция \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\" отключена."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Чтобы использовать сервис \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\", нажмите и удерживайте обе клавиши громкости в течение трех секунд."</string>
@@ -1733,7 +1745,7 @@
     <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Для переключения между функциями проведите по экрану снизу вверх тремя пальцами и задержите их."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Увеличение"</string>
     <string name="user_switched" msgid="7249833311585228097">"Выбран аккаунт пользователя <xliff:g id="NAME">%1$s</xliff:g>."</string>
-    <string name="user_switching_message" msgid="1912993630661332336">"Смена профиля на <xliff:g id="NAME">%1$s</xliff:g>…"</string>
+    <string name="user_switching_message" msgid="1912993630661332336">"Смена профиля на \"<xliff:g id="NAME">%1$s</xliff:g>\"…"</string>
     <string name="user_logging_out_message" msgid="7216437629179710359">"Выход из аккаунта <xliff:g id="NAME">%1$s</xliff:g>…"</string>
     <string name="owner_name" msgid="8713560351570795743">"Владелец"</string>
     <string name="error_message_title" msgid="4082495589294631966">"Ошибка"</string>
@@ -2020,7 +2032,7 @@
     <string name="app_category_news" msgid="1172762719574964544">"Новости и журналы"</string>
     <string name="app_category_maps" msgid="6395725487922533156">"Карты и навигация"</string>
     <string name="app_category_productivity" msgid="1844422703029557883">"Работа"</string>
-    <string name="app_category_accessibility" msgid="6643521607848547683">"Доступность"</string>
+    <string name="app_category_accessibility" msgid="6643521607848547683">"Специальные возможности"</string>
     <string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Хранилище устройства"</string>
     <string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Отладка по USB"</string>
     <string name="time_picker_hour_label" msgid="4208590187662336864">"ч."</string>
@@ -2154,6 +2166,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Действие для быстрого включения"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Выбор действия для быстрого включения"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Быстрое включение"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Скрыть панель уведомлений"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Строка субтитров в приложении \"<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>\" помещено в категорию с ограниченным доступом."</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2291,8 +2304,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Новинка: экранная лупа"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Теперь можно увеличивать весь экран или его часть."</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Увеличьте часть экрана"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Теперь вы можете увеличить весь экран или его часть либо переключаться между этими вариантами."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Включить в настройках"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Закрыть"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Чтобы продолжить, предоставьте приложению &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; доступ к микрофону устройства."</string>
@@ -2301,4 +2314,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Конфиденциальность датчиков"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Значок приложения"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Образ бренда приложения"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Проверьте настройки доступа"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> может просматривать информацию на вашем экране и управлять им. Нажмите, чтобы узнать подробности."</string>
 </resources>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index e01a1c4..a1e3b4a 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"ඇඳිරි සේවාව"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"වේලා කලාප අනාවරකය (සම්බන්ධතාවක් නොමැත)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS වේලා යාවත්කාලීන සේවාව"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"සංගීත හැඳුනුම් කළමනාකරු සේවාව"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"ඔබගේ උපාංගය මකා දැමෙනු ඇත"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"පරිපාලක යෙදුම භාවිතා කළ නොහැකිය. ඔබේ උපාංගය දැන් මකා දමනු ඇත.\n\nඔබට ප්‍රශ්න තිබේ නම්, ඔබේ සංවිධානයේ පරිපාලකට අමතන්න."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> විසින් මුද්‍රණය කිරීම අබල කර ඇත."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"යෙදුම ධාවනය කරමින්"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"බැටරිය භාවිත කරන යෙදුම්"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"විශාලනය"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"ප්‍රවේශ්‍යතා ආරක්ෂක ප්‍රතිපත්තිය"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> බැටරිය භාවිත කරයි"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"යෙදුම් <xliff:g id="NUMBER">%1$d</xliff:g>ක් බැටරිය භාවිත කරයි"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"බැටරි හා දත්ත භාවිතය පිළිබඳව විස්තර සඳහා තට්ටු කරන්න"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"තත්ව තීරුව වීමට යෙදුමට අවසර දෙන්න."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"තත්ව තීරුව දිග හැරීම/හැකිලීම"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"තත්ව තීරුව දිග හැරීමට හෝ හැකිළීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"අගුලු දැමූ උපාංගයක සම්පූර්ණ තිර ක්‍රියාකාරකම් ලෙස දැනුම්දීම් සංදර්ශනය කරන්න"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"අගුලු දැමූ උපාංගයක පූර්ණ තිර ක්‍රියාකාරකම් ලෙස දැනුම්දීම් සංදර්ශනය කිරීමට යෙදුමට ඉඩ දෙයි"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"කෙටිමං ස්ථාපනය කරන්න"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"පරිශීලක මැදිහත්වීමෙන් තොරව කෙටිමං එක් කිරීමට යෙදුමට අවසර දෙන්න."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"කෙටිමං අස්ථාපනය කරන්න"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"ජෛවමිතික හෝ තිර අගුල භාවිත කරන්න"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"එය ඔබ බව තහවුරු කරන්න"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"ඉදිරියට යාමට ඔබගේ ජෛවමිතික භාවිත කරන්න"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"ඉදිරියට යාමට ඔබගේ ජෛවමිතික හෝ තිර අගුල භාවිත කරන්න"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"ජීවමිතික දෘඪාංග ලබා ගත නොහැකිය"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"සත්‍යාපනය අවලංගු කළා"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"හඳුනා නොගන්නා ලදී"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ඇඟිලි සලකුණ භාවිත කරන්න"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ඇඟිලි සලකුණ හෝ තිර අගුල භාවිත කරන්න"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"ඉදිරියට යාමට ඔබගේ ඇඟිලි සලකුණ භාවිත කරන්න"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"ඉදිරියට යාමට ඔබගේ ඇඟිලි සලකුණ හෝ තිර අගුල භාවිත කරන්න"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"ඇඟිලි සලකුණු නිරූපකය"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"මුහුණු අගුලු හැරීම භාවිත කරන්න"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"මුහුණු අගුලු හැරීම හෝ තිර අගුල භාවිත කරන්න"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"ඉදිරියට යාමට මුහුණු අගුලු හැරීම භාවිත කරන්න"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"ඉදිරියට යාමට ඔබගේ මුහුණු හෝ තිර අගුල භාවිත කරන්න"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"මුහුණ නිරූපකය"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"මෙම පිටුව විවෘත කිරීමට ඔබට අවසර නැත."</string>
     <string name="text_copied" msgid="2531420577879738860">"පෙළ පසුරු පුවරුවට පිටපත් කරන ලදි."</string>
     <string name="copied" msgid="4675902854553014676">"පිටපත් කළා"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> වෙතින් අලවන ලදි"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> පසුරු පුවරුව වෙතින් අලවන ලදි"</string>
     <string name="more_item_label" msgid="7419249600215749115">"තව"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"මෙනුව+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"ක්‍රියාවිරහිත කරන්න"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"<xliff:g id="NAME">%s</xliff:g> පරීක්ෂා කරමින්…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"වත්මන් අන්තර්ගතය සමාලෝචනය කරමින්"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"මාධ්‍ය ගබඩාව විශ්ලේෂණය කරමින්"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"අලුත් <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> ක්‍රියා නොකරයි"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"පිහිටුවීමට තට්ටු කරන්න"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"පිහිටුවීමට තෝරන්න"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"ඔබට උපාංගය නැවත හැඩගැන්වීමට අවශ්‍ය විය හැකිය. ඉවත් කිරීමට තට්ටු කරන්න."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"ඡායාරූප සහ මාධ්‍ය හුවමාරු කිරීම සඳහා"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"මාධ්‍ය ගොනු බ්‍රවුස් කරන්න"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"<xliff:g id="NAME">%s</xliff:g> සමගින් වන ගැටලුව"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> ක්‍රියා නොකරයි"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"විසඳීමට තට්ටු කරන්න"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"සහාය නොදක්වන <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> ක්‍රියා නොකරයි"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"මෙම උපාංගය මෙම <xliff:g id="NAME">%s</xliff:g> සඳහා සහාය නොදක්වයි. සහාය දක්වන ආකෘතියකින් පිහිටුවීමට තට්ටු කරන්න."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"මෙම උපාංගය මෙම <xliff:g id="NAME">%s</xliff:g> සඳහා සහාය නොදක්වයි. සහාය දක්වන ආකෘතියකින් පිහිටුවීමට තෝරන්න."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"සහාය දක්වන ආකෘතියකින් <xliff:g id="NAME">%s</xliff:g> පිහිටුවීමට තෝරන්න."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"ඔබට උපාංගය නැවත හැඩගැන්වීමට අවශ්‍ය විය හැකිය"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> අනපේක්ෂිතව ඉවත් කරන ලදි"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"අන්තර්ගතය නැති වීම වළක්වා ගැනීම සඳහා ඉවත් කිරීමට පෙර මාධ්‍යය ඉවත් කරන්න"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"කෙටිමඟ භාවිතා කරන්න"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"වර්ණ අපවර්තනය"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"වර්ණ නිවැරදි කිරීම"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"දීප්තිය අඩු කරන්න"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"තවත් අඳුරු"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"හඬ පරිමා යතුරු අල්ලා ගන්න <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ක්‍රියාත්මකයි."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"හඬ පරිමා යතුරු අල්ලා ගන්න <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ක්‍රියාවිරහිතයි."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> භාවිත කිරීමට හඬ පරිමා යතුරු දෙකම තත්පර තුනකට ඔබාගෙන සිටින්න"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"තිරය මත ප්‍රවේශ්‍යතා කෙටිමග"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"තිරය මත ප්‍රවේශ්‍යතා කෙටිමං තෝරනය"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"ප්‍රවේශ්‍යතා කෙටිමඟ"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"දැනුම්දීම් සෙවන ඉවත ලන්න"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<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> අවහිර කළ බාල්දියට දමා ඇත"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"නව: කවුළු විශාලකය"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"ඔබට දැන් තිරයේ සමහර හෝ සියලු දේ විශාලනය කළ හැකිය"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"ඔබගේ තිරයේ කොටසක් විශාලනය කරන්න"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"ඔබට දැන් ඔබගේ පූර්ණ තිරය, විශේෂිත ප්‍රදේශයක් විශාලනය කළ හැකිය, නැතහොත් විකල්ප දෙක අතර මාරු විය හැකිය."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"සැකසීම් තුළ ක්‍රියාත්මක කරන්න"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"ඉවත ලන්න"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"දිගටම කර ගෙන යාමට, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; හට ඔබගේ උපාංගයෙහි මයික්‍රෆෝනයට ප්‍රවේශය අවශ්‍යයි."</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"සංවේදක පෞද්ගලිකත්වය"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"යෙදුම් නිරූපකය"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"යෙදුම් සන්නම් කිරීමේ රූපය"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"ප්‍රවේශ සැකසීම් පරීක්ෂා කරන්න"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> හට ඔබගේ තිරය බැලීමට සහ පාලනය කිරීමට හැකිය. සමාලෝචනය කිරීමට තට්ටු කරන්න."</string>
 </resources>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index f645fe1..f22317e 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -208,6 +208,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Služba stmievania"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Detektor časového pásma (bez pripojenia)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"Služba na aktualizáciu času globálneho družicového polohového systému"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Služba správcu rozpoznávania hudby"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Vaše zariadenie bude vymazané"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Daná aplikácia na správu sa nedá použiť. Vaše zariadenie bude vymazané.\n\nV prípade otázok kontaktujte správcu organizácie."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Tlač zakázala aplikácia <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -299,6 +300,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Aplikácia je spustená"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Aplikácie spotrebúvajúce batériu"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Zväčšenie"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Pravidlá pre zabezpečenie dostupnosti"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> používa batériu"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"Aplikácie (<xliff:g id="NUMBER">%1$d</xliff:g>) používajú batériu"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Klepnutím zobrazíte podrobnosti o batérii a spotrebe dát"</string>
@@ -349,6 +351,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Umožňuje aplikácii fungovať ako stavový riadok."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"rozbalenie a zbalenie stavového riadka"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Umožňuje aplikácii rozbaliť alebo zbaliť stavový riadok."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"zobrazovanie upozornení ako aktivít na celej obrazovke v uzamknutom zariadení"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Táto možnosť umožňuje aplikácii zobrazovať upozornenia ako aktivity na celej obrazovke v uzamknutom zariadení"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"inštalovať odkazy"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Povoľuje aplikácii pridať odkazy na ploche bez zásahu používateľa."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"odinštalovať odkazy"</string>
@@ -560,6 +564,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Použiť biometrické údaje alebo zámku obrazovky"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Overenie, že ste to vy"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Ak chcete pokračovať, použite biometrický údaj"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Pokračujte použitím biometrických údajov alebo zámky obrazovky"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrický hardvér nie je k dispozícii"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Overenie bolo zrušené"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Nerozpoznané"</string>
@@ -593,6 +598,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Použiť odtlačok prsta"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Použiť odtlačok prsta alebo zámku obrazovky"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Pokračujte nasnímaním odtlačku prsta"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Pokračujte použitím odtlačku prsta alebo zámky obrazovky"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikona odtlačku prsta"</string>
@@ -640,6 +646,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Použiť odomknutie tvárou"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Použiť tvár alebo zámku obrazovky"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Ak chcete pokračovať, použite odomknutie tvárou"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Pokračujte použitím tváre alebo zámky obrazovky"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Ikona tváre"</string>
@@ -1003,6 +1010,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"Nemáte povolenie na otvorenie tejto stránky."</string>
     <string name="text_copied" msgid="2531420577879738860">"Text bol skopírovaný do schránky."</string>
     <string name="copied" msgid="4675902854553014676">"Skopírované"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"Aplikácia <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> prilepila údaje z aplikácie <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"Aplikácia <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> prilepila údaje zo schránky"</string>
     <string name="more_item_label" msgid="7419249600215749115">"Viac"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Menu+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1410,11 +1419,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Vypnúť"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Kontroluje sa <xliff:g id="NAME">%s</xliff:g>…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Kontrola aktuálneho obsahu"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Analyzuje sa priestor médií"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Nové médium <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> nefunguje"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Klepnutím médium nastavte"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Vyberte a nastavte"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Zariadenie možno bude potrebné preformátovať. Klepnutím ho vysuniete."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"Na prenos fotiek a médií"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Prehliadajte súbory médií"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Problém s médiom <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> nefunguje"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Problém odstránite klepnutím"</string>
@@ -1423,7 +1435,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"Nepodporované úložisko <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> nefunguje"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"Toto zariadenie nepodporuje úložisko <xliff:g id="NAME">%s</xliff:g>. Klepnutím ho nastavíte v podporovanom formáte."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"Toto zariadenie nepodporuje médium <xliff:g id="NAME">%s</xliff:g>. Vyberte ho a nastavte v podporovanom formáte."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Vyberte a vytvorte tak <xliff:g id="NAME">%s</xliff:g> v podporovanom formáte."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Zariadenie možno bude potrebné preformátovať"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"Úl. <xliff:g id="NAME">%s</xliff:g> bolo neočakávane odobraté"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Pred odobratím médium najskôr odpojte, aby ste zabránili strate obsahu"</string>
@@ -1721,7 +1733,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Použiť skratku"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Inverzia farieb"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Úprava farieb"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Zníženie jasu"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Mimoriadne stmavenie"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Pridržali ste tlačidlá hlasitosti. Služba <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je zapnutá."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Pridržali ste tlačidlá hlasitosti. Služba <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je vypnutá."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Ak chcete používať službu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, pridržte tri sekundy oba klávesy hlasitosti"</string>
@@ -2154,6 +2166,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Skratka dostupnosti na obrazovke"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Výber skratky dostupnosti na obrazovke"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Skratka dostupnosti"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Zavrieť panel upozornení"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Popis aplikácie <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Balík <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> bol vložený do kontajnera OBMEDZENÉ"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2291,8 +2304,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Novinka: Lupa pre okná"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Teraz môžete zväčšiť celú obrazovku alebo jej časť"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Zväčšite časť obrazovky"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Teraz môžete zväčšiť celú obrazovku, jej konkrétnu časť alebo prepínať medzi oboma možnosťami."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Zapnúť v Nastaveniach"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Zavrieť"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Ak chcete pokračovať, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; požaduje prístup k mikrofónu zariadenia."</string>
@@ -2301,4 +2314,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Ochrana súkromia senzorov"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Ikona aplikácie"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Imidž značky aplikácie"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Skontrolujte nastavenia prístupu"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> môže zobraziť a ovládať vašu obrazovku. Skontrolujte to klepnutím."</string>
 </resources>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 97de6a3..220d802 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -208,6 +208,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Storitev Somrak"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Zaznavanje časovnega pasu (brez povezave)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"Storitev posodobitve ure po sistemu GNSS"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Storitev upravljalnika za prepoznavanje glasbe"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Podatki v napravi bodo izbrisani"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Skrbniške aplikacije ni mogoče uporabljati. Podatki v napravi bodo izbrisani.\n\nČe imate vprašanja, se obrnite na skrbnika organizacije."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Tiskanje je onemogočil pravilnik <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -299,6 +300,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Aplikacija se izvaja"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Aplikacije, ki porabljajo energijo baterije"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Povečava"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Varnostni pravilnik o funkcijah za ljudi s posebnimi potrebami"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> porablja energijo baterije"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"Toliko aplikacij porablja energijo baterije: <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Dotaknite se za prikaz podrobnosti porabe baterije in prenosa podatkov"</string>
@@ -349,6 +351,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Aplikaciji omogoča, da postane vrstica stanja."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"razširjanje/strnjevanje vrstice stanja"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Aplikaciji omogoča razširjanje ali strnjevanje vrstice stanja."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"Prikaz obvestil kot celozaslonskih dejavnosti v zaklenjeni napravi"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Aplikaciji dovoli, da prikaže obvestila kot celozaslonske dejavnosti v zaklenjeni napravi."</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"nameščanje bližnjic"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Aplikaciji omogoča dodajanje bližnjic na začetni zaslon brez posredovanja uporabnika."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"odstranjevanje bližnjic"</string>
@@ -560,6 +564,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Uporaba biometrike ali odklepanja s poverilnico"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Preverite, da ste res vi"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Za nadaljevanje uporabite biometrični podatek."</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Za nadaljevanje uporabite biometrični podatek ali odklepanje s poverilnico."</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Strojna oprema za biometrične podatke ni na voljo"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Preverjanje pristnosti je preklicano"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Ni prepoznano"</string>
@@ -593,6 +598,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Uporaba prstnega odtisa"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Uporaba prstnega odtisa ali odklepanja s poverilnico"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Uporabite prstni odtis, če želite nadaljevati."</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Za nadaljevanje uporabite prstni odtis ali odklepanje s poverilnico."</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikona prstnih odtisov"</string>
@@ -640,6 +646,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Uporaba odklepanja z obrazom"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Uporaba odklepanja z obrazom ali s poverilnico"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Za nadaljevanje uporabite odklepanje z obrazom."</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Za nadaljevanje uporabite obraz ali odklepanje s poverilnico."</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Ikona obraza"</string>
@@ -1003,6 +1010,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"Nimate dovoljenja za odpiranje te strani."</string>
     <string name="text_copied" msgid="2531420577879738860">"Besedilo, kopirano v odložišče."</string>
     <string name="copied" msgid="4675902854553014676">"Kopirano"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"Aplikacija <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> je prilepila iz aplikacije <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>."</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"Aplikacija <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> je prilepila iz odložišča."</string>
     <string name="more_item_label" msgid="7419249600215749115">"Več"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Meni+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta +"</string>
@@ -1410,11 +1419,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Izklopi"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Preverjanje nosilca <xliff:g id="NAME">%s</xliff:g> …"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Pregledovanje trenutne vsebine"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Poteka analiziranje shrambe predstavnosti."</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Nova naprava za shranjevanje: <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"Naprava <xliff:g id="NAME">%s</xliff:g> ne deluje"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Dotaknite se, če želite nastaviti"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Izberite, če želite nastaviti."</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Napravo boste morda morali znova formatirati. Če jo želite izvreči, se dotaknite."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"Za prenos fotografij in predstavnosti"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Brskajte po predstavnostnih datotekah."</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Težava z nosilcem <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"Naprava <xliff:g id="NAME">%s</xliff:g> ne deluje"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Dotaknite se, da to popravite"</string>
@@ -1423,7 +1435,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"Nepodprta naprava za shran. <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"Naprava <xliff:g id="NAME">%s</xliff:g> ne deluje"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"Ta naprava ne podpira tega nosilca <xliff:g id="NAME">%s</xliff:g>. Dotaknite se, če želite nastaviti v podprti obliki."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"Naprava ne podpira nosilca <xliff:g id="NAME">%s</xliff:g>. Izberite, če ga želite nastaviti v podprti obliki."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Izberite, da nastavite »<xliff:g id="NAME">%s</xliff:g>« v podprti obliki."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Napravo boste morda morali znova formatirati"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"Shramba <xliff:g id="NAME">%s</xliff:g> nepričak. odstranjena"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Medij izvrzite, preden ga odstranite, da se izognete izgubi vsebine"</string>
@@ -1721,7 +1733,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Uporabi bližnjico"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Inverzija barv"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Popravljanje barv"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Zmanjšanje svetlosti"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Zelo zatemnjeno"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tipki za glasnost sta pridržani. Storitev <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je vklopljena."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tipki za glasnost sta pridržani. Storitev <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je izklopljena."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Za uporabo storitve <xliff:g id="SERVICE_NAME">%1$s</xliff:g> pritisnite obe tipki za glasnost in ju pridržite tri sekunde"</string>
@@ -2154,6 +2166,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Zaslonska bližnjica funkcij za ljudi s posebnimi potrebami"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Izbirnik zaslonske bližnjice funkcij za ljudi s posebnimi potrebami"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Bližnjica funkcij za ljudi s posebnimi potrebami"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Opusti zaslon z obvestili"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Vrstica s podnapisi aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Paket <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> je bil dodan v segment OMEJENO"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2291,8 +2304,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Novo: Lupa v oknu"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Zdaj lahko povečate del zaslona ali celotni zaslon"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Povečanje dela zaslona"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Zdaj lahko povečate celoten zaslon, določen del zaslona ali preklapljate med obema možnostma."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Vklopite v nastavitvah"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Opusti"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Za nadaljevanje potrebuje aplikacija &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; dostop do mikrofona v napravi."</string>
@@ -2301,4 +2314,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Zasebnost pri uporabi tipal"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Ikona aplikacije"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Podoba blagovne znamke aplikacije"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Preverite nastavitve dostopa"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"Storitev <xliff:g id="SERVICE_NAME">%s</xliff:g> si lahko ogleda in upravlja vaš zaslon. Dotaknite se za pregled."</string>
 </resources>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index a78ff77..c2c1bb4 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Shërbimi i muzgut"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Zbuluesi i brezit orar (nuk nevojitet lidhja)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"Shërbimi i përditësimit të kohës GNSS"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Shërbimi i menaxherit të njohjes së muzikës"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Pajisja do të spastrohet"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Aplikacioni i administratorit nuk mund të përdoret. Pajisja jote tani do të fshihet.\n\nNëse ke pyetje, kontakto me administratorin e organizatës."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Printimi është çaktivizuar nga <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Aplikacioni është në ekzekutim"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Aplikacionet që konsumojnë baterinë"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Zmadhimi"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Politika e sigurisë e qasshmërisë"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> po përdor baterinë"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> aplikacione po përdorin baterinë"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Trokit për detaje mbi baterinë dhe përdorimin e të dhënave"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Lejon aplikacionin të bëhet shiriti i statusit."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"zgjero ose shpalos shiritin e statusit"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Lejon aplikacionin të zgjerojë ose shpalosë shiritin e statusit."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"shfaq njoftimet si aktivitete në ekran të plotë në një pajisje të kyçur"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Lejon që aplikacioni t\'i shfaqë njoftimet si aktivitete në ekran të plotë në një pajisje të kyçur"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"instalo shkurtore"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Lejon një aplikacion për të shtuar shkurtore në ekranin bazë pa ndërhyrjen e përdoruesit."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"çinstalo shkurtore"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Përdor sistemet biometrike ose kyçjen e ekranit"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Verifiko që je ti"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Përdor sistemet e tua biometrike për të vazhduar"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Përdor sistemet e tua biometrike ose kyçjen e ekranit për të vazhduar"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Nuk ofrohet harduer biometrik"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Vërtetimi u anulua"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Nuk njihet"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Përdor gjurmën e gishtit"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Përdor gjurmën e gishtit ose kyçjen e ekranit"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Përdor gjurmën e gishtit për të vazhduar"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Përdor gjurmën tënde të gishtit ose kyçjen e ekranit për të vazhduar"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikona e gjurmës së gishtit"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Përdor shkyçjen me fytyrë"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Përdor kyçjen me fytyrë ose kyçjen e ekranit"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Përdor shkyçjen me fytyrë për të vazhduar"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Përdor fytyrën tënde ose kyçjen e ekranit për të vazhduar"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Ikona e fytyrës"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"Nuk ke leje për ta hapur këtë faqe."</string>
     <string name="text_copied" msgid="2531420577879738860">"Teksti u kopjua në kujtesën e fragmenteve."</string>
     <string name="copied" msgid="4675902854553014676">"U kopjua"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> u ngjit nga <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> u ngjit nga kujtesa e fragmenteve"</string>
     <string name="more_item_label" msgid="7419249600215749115">"Më shumë"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Menyja+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Çaktivizo"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"<xliff:g id="NAME">%s</xliff:g> po kontrollohet…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Përmbajtja aktuale po rishikohet"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Po analizon magazinën ruajtëse të medias"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"<xliff:g id="NAME">%s</xliff:g> e re"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> nuk punon"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Trokit për ta konfiguruar"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Zgjidhe për ta konfiguruar"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Mund të jetë nevoja ta riformatosh pajisjen. Trokit për ta nxjerrë."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"Për transferimin e fotografive dhe skedarëve të tjerë"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Shfleto skedarët e medias"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Problem me <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> nuk punon"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Trokit për ta rregulluar"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"<xliff:g id="NAME">%s</xliff:g> nuk mbështetet"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> nuk punon"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"Kjo pajisje nuk e mbështet këtë <xliff:g id="NAME">%s</xliff:g>. Trokit për ta konfiguruar në një format të mbështetur."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"Kjo pajisje nuk e mbështet këtë <xliff:g id="NAME">%s</xliff:g>. Përzgjidhe për ta konfiguruar në një format të mbështetur."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Zgjidh të konfigurosh <xliff:g id="NAME">%s</xliff:g> në një format të mbështetur."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Mund të jetë nevoja ta riformatosh pajisjen"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> u hoq papritur"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Nxirr median para se ta heqësh për të shmangur humbjen e përmbajtjes"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Përdor shkurtoren"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Kthimi i ngjyrës"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Korrigjimi i ngjyrës"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Redukto ndriçimin"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Tejet i errët"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tastet e volumit të mbajtura shtypur. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> i aktivizuar."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tastet e volumit të mbajtura shtypur. U çaktivizua \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\"."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Shtyp dhe mbaj shtypur të dy butonat e volumit për tre sekonda për të përdorur <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -1689,7 +1701,7 @@
     <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Për të kaluar mes veçorive, rrëshqit shpejt lart me tre gishta dhe mbaje prekur."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Zmadhimi"</string>
     <string name="user_switched" msgid="7249833311585228097">"Emri i përdoruesit aktual: <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="user_switching_message" msgid="1912993630661332336">"Po kalon në <xliff:g id="NAME">%1$s</xliff:g>…"</string>
+    <string name="user_switching_message" msgid="1912993630661332336">"Po kalon në \"<xliff:g id="NAME">%1$s</xliff:g>\"…"</string>
     <string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> po del…"</string>
     <string name="owner_name" msgid="8713560351570795743">"Zotëruesi"</string>
     <string name="error_message_title" msgid="4082495589294631966">"Gabim"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Shkurtorja e qasshmërisë në ekran"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Zgjedhësi i shkurtores së qasshmërisë në ekran"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Shkurtorja e qasshmërisë"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Hiq \"Strehën e njoftimeve\""</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Shiriti i nëntitullit të <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> është vendosur në grupin E KUFIZUAR"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Risi: Zmadhuesi i dritareve"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Tani mund t\'i zmadhosh një pjesë apo të gjithë ekranin tënd"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Zmadho pjesën e ekranit tënd"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Tani mund të zmadhosh ekranin tënd të plotë, një zonë specifike ose kalo mes dy opsioneve."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Aktivizo te \"Cilësimet\""</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Hiq"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Për të vazhduar, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ka nevojë të qaset në mikrofonin e pajisjes sate."</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privatësia e sensorit"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Ikona e aplikacionit"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Imazhi i vendosjes së aplikacionit të markës"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Kontrollo cilësimet e qasjes"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> mund ta shikojë dhe kontrollojë ekranin tënd. Trokit për ta rishikuar."</string>
 </resources>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 04bc35f..922c95ba 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -206,6 +206,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Услуга Сумрак"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Детектор временске зоне (нема интернет везе)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS услуга за ажурирање времена"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Услуга Менаџер препознавања музике"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Уређај ће бити обрисан"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Не можете да користите ову апликацију за администраторе. Уређај ће сада бити обрисан.\n\nАко имате питања, контактирајте администратора организације."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Штампање је онемогућила апликација <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -296,6 +297,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Активна апликација"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Апликације које троше батерију"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Увећање"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Безбедносне смернице за приступачност"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> користи батерију"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"Апликације (<xliff:g id="NUMBER">%1$d</xliff:g>) користе батерију"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Додирните за детаље о батерији и потрошњи података"</string>
@@ -346,6 +348,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Дозвољава апликацији да функционише као статусна трака."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"проширење/скупљање статусне траке"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Дозвољава апликацији да проширује или скупља статусну траку."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"приказује обавештења као активности преко целог екрана на закључаном уређају"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Омогућава апликацији да на закључаном уређају приказује обавештења као активности преко целог екрана."</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"инсталирање пречица"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Омогућава апликацији да додаје пречице на почетни екран без интервенције корисника."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"деинсталирање пречица"</string>
@@ -557,6 +561,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Користите биометрију или закључавање екрана"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Потврдите свој идентитет"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Користите биометријски податак да бисте наставили"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Користите биометријски податак или закључавање екрана да бисте наставили"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Биометријски хардвер није доступан"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Потврда идентитета је отказана"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Није препознато"</string>
@@ -590,6 +595,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Користите отисак прста"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Користите отисак прста или закључавање екрана"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Наставите помоћу отиска прста"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Користите отисак прста или закључавање екрана да бисте наставили"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Икона отиска прста"</string>
@@ -637,6 +643,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Користите откључавање лицем"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Користите закључавање лицем или закључавање екрана"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Користите откључавање лицем да бисте наставили"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Користите лице или закључавање екрана да бисте наставили"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Икона лица"</string>
@@ -1000,6 +1007,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"Немате дозволу да отворите ову страницу."</string>
     <string name="text_copied" msgid="2531420577879738860">"Текст је копиран у привремену меморију."</string>
     <string name="copied" msgid="4675902854553014676">"Копирано је"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"Апликација<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> је налепила податке из апликације <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"Апликација<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> налепила податке из привремене меморије"</string>
     <string name="more_item_label" msgid="7419249600215749115">"Још"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Мени+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1390,11 +1399,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Искључи"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Проверава се <xliff:g id="NAME">%s</xliff:g>…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Прегледа се актуелни садржај"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Анализира се меморијски простор за медије"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Нови/а <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> не ради"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Додирните да бисте подесили"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Изаберите да бисте подесили"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Можда морате да реформатирате уређај. Додирните да бисте избацили."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"За пренос слика и медија"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Прегледајте медијске фајлове"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Проблем са: <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> не ради"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Додирните да бисте исправили"</string>
@@ -1403,7 +1415,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"Уређај <xliff:g id="NAME">%s</xliff:g> није подржан"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> не ради"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"Овај уређај не подржава овај уређај <xliff:g id="NAME">%s</xliff:g>. Додирните да бисте подесили подржани формат."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"Овај уређај не подржава овај медиј (<xliff:g id="NAME">%s</xliff:g>). Изаберите да га подесите у подржаном формату."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Изаберите да бисте подесили уређај <xliff:g id="NAME">%s</xliff:g> у подржаном формату."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Можда морате да реформатирате уређај"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"Уређај <xliff:g id="NAME">%s</xliff:g> је неочекивано уклоњен"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Избаците медијум пре него што га уклоните да не бисте изгубили садржај"</string>
@@ -1699,7 +1711,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Користи пречицу"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Инверзија боја"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Корекција боја"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Смањите осветљеност"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Додатно затамњено"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Држали сте тастере за јачину звука. Услуга <xliff:g id="SERVICE_NAME">%1$s</xliff:g> је укључена."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Држали сте тастере за јачину звука. Услуга <xliff:g id="SERVICE_NAME">%1$s</xliff:g> је искључена."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Притисните и задржите оба тастера за јачину звука три секунде да бисте користили <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -2120,6 +2132,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Пречица за приступачност на екрану"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Алатка за бирање пречица за приступачност на екрану"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Пречица за приступачност"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Одбаци траку са обавештењима"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Трака са насловима апликације <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> је додат у сегмент ОГРАНИЧЕНО"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2257,8 +2270,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Ново: Лупа за прозор"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Можете да увећате део екрана или цео екран"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Увећајте приказ дела екрана"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Сада можете да увећате цео екран, одређену област или да прелазите са једне опције на другу."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Укључите у Подешавањима"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Одбаци"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"&lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; захтева приступ микрофону уређаја ради настављања."</string>
@@ -2267,4 +2280,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Приватност сензора"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Икона апликације"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Имиџ бренда апликације"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Проверите подешавања приступа"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> може да прегледа и контролише екран. Додирните да бисте прегледали."</string>
 </resources>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 5ab243a..cf44ee0 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Twilight Service"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Tidszondetektering (ingen anslutning)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"Tjänst för uppdatering av GNSS-tid"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Tjänst för hantering av musikidentifiering"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Enheten kommer att rensas"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Det går inte att använda administratörsappen. Enheten rensas.\n\nKontakta organisationens administratör om du har några frågor."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Utskrift har inaktiverats av <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"App körs"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Appar som drar batteri"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Förstoring"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Säkerhetspolicy för tillgänglighet"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> drar batteri"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> appar drar batteri"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Tryck för information om batteri- och dataanvändning"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Tillåter att appen visas i statusfältet."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"expandera/komprimera statusfält"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Tillåter att appen expanderar eller komprimerar statusfältet."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"visa aviseringar som aktiviteter i helskärm på en låst enhet"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Tillåter att appen visar aviseringar som aktiviteter i helskärm på en låst enhet"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"installera genvägar"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Tillåter att en app lägger till genvägar på startskärmen utan åtgärd från användaren."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"avinstallera genvägar"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Använd biometrisk data eller skärmlåset"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Verifiera din identitet"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Fortsätt med hjälp av din biometriska data"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Fortsätt med hjälp av din biometriska data eller skärmlåset"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrisk maskinvara är inte tillgänglig"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Autentiseringen avbröts"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Identifierades inte"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Använd ditt fingeravtryck"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Använd ditt fingeravtryck eller skärmlåset"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Fortsätt med hjälp av ditt fingeravtryck"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Fortsätt med hjälp av ditt fingeravtryck eller skärmlåset"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikon för fingeravtryck"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Använd ansiktslåset"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Använd ansiktslåset eller skärmlåset"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Fortsätt med hjälp av ansiktslåset"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Fortsätt med hjälp av ditt ansikte eller skärmlåset"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Ansikte"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"Du har inte behörighet att öppna den här sidan."</string>
     <string name="text_copied" msgid="2531420577879738860">"Text har kopierats till urklipp."</string>
     <string name="copied" msgid="4675902854553014676">"Kopierat"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> klistrade in från <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> klistrade in från urklipp"</string>
     <string name="more_item_label" msgid="7419249600215749115">"Mer"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Menu+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta + "</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Inaktivera"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"<xliff:g id="NAME">%s</xliff:g> kontrolleras …"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Granskar nuvarande innehåll"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Analyserar medialagring"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Nytt <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> fungerar inte"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Tryck för att konfigurera"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Välj för att konfigurera"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Du måste eventuellt formatera om enheten. Tryck för att mata ut."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"För överföring av foton och media"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Bläddra bland mediefiler"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Problem med <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> fungerar inte"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Tryck och åtgärda"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"<xliff:g id="NAME">%s</xliff:g> stöds inte"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> fungerar inte"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"Enheten har inte stöd för <xliff:g id="NAME">%s</xliff:g>. Tryck här om du vill konfigurera i ett format som stöds."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"Enheten stöder inte detta <xliff:g id="NAME">%s</xliff:g>. Välj för att konfigurera i ett format som stöds."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Välj för att konfigurera <xliff:g id="NAME">%s</xliff:g> i ett format som stöds."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Du måste eventuellt formatera om enheten"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> togs bort oväntat"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Mata ut media innan du tar bort den för att inte förlora innehåll"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Använd kortkommandot"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Inverterade färger"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Färgkorrigering"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Minska ljusstyrkan"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Extradimmat"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Volymknapparna har tryckts ned. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> har aktiverats."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Volymknapparna har tryckts ned. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> har inaktiverats."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Tryck och håll båda volymknapparna i tre sekunder för att använda <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Tillgänglighetsgenväg på skärmen"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Valfunktion för tillgänglighetsgenväg på skärmen"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Aktivera tillgänglighet snabbt"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Stäng meddelandepanelen"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Textningsfält för <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> har placerats i hinken RESTRICTED"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Nyhet: Fönsterförstoring"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Nu kan du förstora delar av eller hela skärmen"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Förstora en del av skärmen"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Nu kan du förstora hela skärmen, ett visst område eller växla mellan båda alternativen."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Aktivera i inställningarna"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Stäng"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"&lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; behöver behörighet till enhetens mikrofon för att fortsätta."</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Sensorintegritet"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Appikon"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Appens varumärkesbild"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Kontrollera åtkomstinställningar"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> kan visa och styra din skärm. Tryck för att granska."</string>
 </resources>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 00477d1..f715948 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Twilight Service"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Kitambua Saa za Eneo (Hakuna muunganisho)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"Huduma ya Kusasisha Saa za GNSS"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Huduma ya Kidhibiti cha Utambuzi wa Muziki"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Data iliyomo kwenye kifaa chako itafutwa"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Huwezi kutumia programu ya msimamizi. Sasa data iliyo kwenye kifaa chako itafutwa.\n\nIkiwa una maswali yoyote, wasiliana na msimamizi wa shirika lako."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Kipengele cha kuchapisha kimezimwa na <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Programu inaendelea kutekelezwa"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Programu zinazotumia betri"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Ukuzaji"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Sera ya usalama wa ufikivu"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> inatumia betri"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"Programu <xliff:g id="NUMBER">%1$d</xliff:g> zinatumia betri"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Gusa ili upate maelezo kuhusu betri na matumizi ya data"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Inaruhusu programu kuwa upau wa hali."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"panua/kunja mwambaa hali"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Inaruhusu programu kupanua au kukunja upau wa hali."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"onyesha arifa kama shughuli za skrini nzima kwenye kifaa kilichofungwa"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Huruhusu programu kuonyesha arifa kama shughuli za skrini nzima kwenye kifaa kilichofungwa"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"kuweka njia za mkato"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Huruhusu programu kuongeza njia za mkato za Skrini ya kwanza bila mtumiaji kuingilia."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"ondoa njia za mikato"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Tumia bayometriki au mbinu ya kufunga skrini"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Thibitisha kuwa ni wewe"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Tumia bayometriki yako ili uendelee"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Tumia bayometriki au mbinu yako ya kufunga skrini ili uendelee"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Maunzi ya bayometriki hayapatikani"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Imeghairi uthibitishaji"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Hayatambuliki"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Tumia alama ya kidole"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Tumia alama ya kidole au mbinu ya kufunga skrini"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Tumia alama ya kidole chako ili uendelee"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Tumia alama ya kidole au mbinu yako ya kufunga skrini ili uendelee"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Aikoni ya alama ya kidole"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Tumia kipengele cha kufungua kwa uso"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Tumia uso au mbinu ya kufunga skrini"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Tumia kipengele cha kufungua kwa uso ili uendelee"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Tumia uso au mbinu yako ya kufunga skrini ili uendelee"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Aikoni ya uso"</string>
@@ -996,7 +1003,9 @@
     <string name="save_password_never" msgid="6776808375903410659">"Katu"</string>
     <string name="open_permission_deny" msgid="5136793905306987251">"Hauna idhini ya kufungua ukurasa huu."</string>
     <string name="text_copied" msgid="2531420577879738860">"Maandishi yamenakiliwa kwenye ubao wa kunakili."</string>
-    <string name="copied" msgid="4675902854553014676">"Imenakiliwa"</string>
+    <string name="copied" msgid="4675902854553014676">"Umenakili"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> imebandika kutoka <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> imebandika kutoka ubao wa kunakili"</string>
     <string name="more_item_label" msgid="7419249600215749115">"Zaidi"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Menyu+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Zima"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Inakagua <xliff:g id="NAME">%s</xliff:g>…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Inakagua maudhui ya sasa"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Inachanganua hifadhi ya maudhui"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"<xliff:g id="NAME">%s</xliff:g> mpya"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> haifanyi kazi"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Gusa ili uweke mipangilio"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Chagua ili uweke mipangilio"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Huenda ukahitaji kubadilisha mipangilio ya kifaa. Gusa ili uondoe."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"Kwa ajili ya kuhamisha picha na maudhui"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Vinjari faili za maudhui"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Tatizo limetokea kwenye <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> haifanyi kazi"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Gusa ili urekebishe"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"<xliff:g id="NAME">%s</xliff:g> isiyotumika"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> haifanyi kazi"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"Kifaa hiki hakitumii <xliff:g id="NAME">%s</xliff:g>. Gusa ili uweke mipangilio ya muundo unaoweza kutumika."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"Kifaa hiki hakitumii <xliff:g id="NAME">%s</xliff:g> hii. Ichague ili uweke muundo unaotumika."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Chagua ili uweke mipangilio ya <xliff:g id="NAME">%s</xliff:g> katika muundo unaoweza kutumika."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Huenda ukahitaji kubadilisha mipangilio ya kifaa"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> imeondolewa bila kutarajiwa"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Ondoa kifaa cha maudhui kabla ya kukichomoa ili usipoteze maudhui"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Tumia Njia ya Mkato"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Ugeuzaji rangi"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Usahihishaji wa rangi"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Punguza ung\'aavu"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Kipunguza mwangaza zaidi"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Vitufe vya sauti vilivyoshikiliwa. Umewasha <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Vitufe vya sauti vimeshikiliwa. Umezima <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Bonyeza na ushikilie vitufe vyote viwili vya sauti kwa sekunde tatu ili utumie <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -1689,7 +1701,7 @@
     <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Ili ubadilishe kati ya vipengele, telezesha vidole vitatu juu na ushikilie."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ukuzaji"</string>
     <string name="user_switched" msgid="7249833311585228097">"Mtumiaji wa sasa <xliff:g id="NAME">%1$s</xliff:g>."</string>
-    <string name="user_switching_message" msgid="1912993630661332336">"Inabadili kwenda <xliff:g id="NAME">%1$s</xliff:g>…"</string>
+    <string name="user_switching_message" msgid="1912993630661332336">"Inaenda kwa <xliff:g id="NAME">%1$s</xliff:g>…"</string>
     <string name="user_logging_out_message" msgid="7216437629179710359">"Inamwondoa <xliff:g id="NAME">%1$s</xliff:g>…"</string>
     <string name="owner_name" msgid="8713560351570795743">"Mmiliki"</string>
     <string name="error_message_title" msgid="4082495589294631966">"Hitilafu"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Njia ya Mkato ya Ufikivu kwenye Skrini"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Kichagua Njia ya Mkato ya Ufikivu kwenye Skrini"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Njia ya Mkato ya Ufikivu"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Ondoa Sehemu ya Arifa"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Upau wa manukuu wa <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> kimewekwa katika kikundi KILICHODHIBITIWA"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Mpya: Kikuza Dirisha"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Sasa unaweza kukuza sehemu ya au skrini yako yote"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Kuza sehemu ya skrini yako"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Sasa unaweza kukuza skrini yako nzima, sehemu mahususi au ubadilishe kati ya chaguo zote mbili."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Washa katika Mipangilio"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Ondoa"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Ili uendelee, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; inahitaji ruhusa ya kufikia maikrofoni ya kifaa chako."</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Faragha ya Kitambuzi"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Aikoni ya programu"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Picha ya kuweka chapa kwenye programu"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Angalia mipangilio ya kufikia"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> inaweza kuangalia na kudhibiti skrini yako. Gusa ili ukague."</string>
 </resources>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 6325c19..0a5aca5 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Twilight சேவை"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"நேர மண்டல டிடெக்டர் (இணைப்பு இல்லை)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS நேரப் புதுப்பிப்புச் சேவை"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"இசை கண்டறிதலை நிர்வகிக்கும் சேவை"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"சாதனத் தரவு அழிக்கப்படும்"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"நிர்வாகி ஆப்ஸை உபயோகிக்க முடியாது. இப்போது, உங்கள் சாதனம் ஆரம்ப நிலைக்கு மீட்டமைக்கப்படும்.\n\nஏதேனும் கேள்விகள் இருப்பின், உங்கள் நிறுவனத்தின் நிர்வாகியைத் தொடர்புகொள்ளவும்."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"பிரிண்ட் செய்வதை <xliff:g id="OWNER_APP">%s</xliff:g> தடுத்துள்ளது."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"ஆப்ஸ் இயங்குகிறது"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"பேட்டரியைப் பயன்படுத்தும் ஆப்ஸ்"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"பெரிதாக்கல்"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"அணுகல்தன்மை பாதுகாப்புக் கொள்கை"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸ் பேட்டரியைப் பயன்படுத்துகிறது"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> ஆப்ஸ் பேட்டரியைப் பயன்படுத்துகின்றன"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"பேட்டரி மற்றும் டேட்டா உபயோக விவரங்களைக் காண, தட்டவும்"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"நிலைப் பட்டியில் இருக்க ஆப்ஸை அனுமதிக்கிறது."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"நிலைப் பட்டியை விரிவாக்குதல்/சுருக்குதல்"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"நிலைப் பட்டியை விரிவாக்க அல்லது சுருக்க, ஆப்ஸை அனுமதிக்கிறது."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"பூட்டப்பட்ட சாதனத்தில் முழுத்திரைச் செயல்பாடுகளாக அறிவிப்புகளைக் காட்டுதல்"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"பூட்டப்பட்ட சாதனத்தில் முழுத்திரைச் செயல்பாடுகளாக அறிவிப்புகளைக் காட்ட ஆப்ஸை அனுமதிக்கும்"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"குறுக்குவழிகளை நிறுவுதல்"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"பயனரின் அனுமதி இல்லாமல் முகப்புத்திரையின் குறுக்குவழிகளைச் சேர்க்கப் ஆப்ஸை அனுமதிக்கிறது."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"குறுக்குவழிகளை நிறுவல் நீக்குதல்"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"பயோமெட்ரிக்ஸையோ திரைப் பூட்டையோ பயன்படுத்து"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"நீங்கள்தான் என உறுதிசெய்க"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"தொடர உங்கள் பயோமெட்ரிக்கைப் பயன்படுத்துங்கள்"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"தொடர, உங்கள் பயோமெட்ரிக்கையோ திரைப் பூட்டையோ பயன்படுத்துங்கள்"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"பயோமெட்ரிக் வன்பொருள் இல்லை"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"அங்கீகரிப்பு ரத்தானது"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"அடையாளங்காணபடவில்லை"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"கைரேகையைப் பயன்படுத்து"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"கைரேகையையோ திரைப் பூட்டையோ பயன்படுத்து"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"தொடர்வதற்கு கைரேகையைப் பயன்படுத்துங்கள்"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"தொடர, உங்கள் கைரேகையையோ திரைப் பூட்டையோ பயன்படுத்துங்கள்"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"கைரேகை ஐகான்"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"முகம் காட்டித் திறத்தலை உபயோகி"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"முகத்தையோ திரைப் பூட்டையோ பயன்படுத்து"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"தொடர, \'முகம் காட்டித் திறத்தல்\' அம்சத்தை உபயோகியுங்கள்"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"தொடர, உங்கள் முகத்தையோ திரைப் பூட்டையோ பயன்படுத்துங்கள்"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"முக ஐகான்"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"இந்தப் பக்கத்தைத் திறக்க, உங்களிடம் அனுமதி இல்லை."</string>
     <string name="text_copied" msgid="2531420577879738860">"உரை கிளிப்போர்டிற்கு நகலெடுக்கப்பட்டது."</string>
     <string name="copied" msgid="4675902854553014676">"நகலெடுக்கப்பட்டது"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> ஆப்ஸிலிருந்து <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ஒட்டப்பட்டது"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"கிளிப்போர்டிலிருந்து <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ஒட்டப்பட்டது"</string>
     <string name="more_item_label" msgid="7419249600215749115">"மேலும்"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"மெனு+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"மெட்டா மற்றும்"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"ஆஃப் செய்"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"<xliff:g id="NAME">%s</xliff:g>ஐச் சரிபார்க்கிறது…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"தற்போதைய உள்ளடக்கத்தை மதிப்பாய்வு செய்கிறது"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"\'மீடியா சேமிப்பகம்\' பகுப்பாய்வு செய்யப்படுகிறது"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"புதிய <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> வேலை செய்யவில்லை"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"அமைக்க, தட்டவும்"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"அமைக்கத் தேர்ந்தெடுங்கள்"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"சாதனத்தை ரீஃபார்மேட் செய்ய வேண்டியிருக்கும். வெளியேற்ற தட்டவும்."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"படங்களையும் மீடியாவையும் மாற்றலாம்"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"மீடியா கோப்புகளை உலாவுக"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"<xliff:g id="NAME">%s</xliff:g> இல் சிக்கல்"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> வேலை செய்யவில்லை"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"சரிசெய்ய, தட்டவும்"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"ஆதரிக்கப்படாத <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> வேலை செய்யவில்லை"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"சாதனம் இந்த <xliff:g id="NAME">%s</xliff:g>ஐ ஆதரிக்கவில்லை. ஆதரிக்கப்படும் வடிவமைப்பில் அமைக்க, தட்டவும்."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"சாதனம் இந்த <xliff:g id="NAME">%s</xliff:g>ஐ ஆதரிக்கவில்லை. ஆதரிக்கப்படும் வடிவமைப்பில் அமைக்க, தேர்ந்தெடுக்கவும்."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"ஆதரிக்கப்படும் வடிவத்தில் <xliff:g id="NAME">%s</xliff:g> ஐ அமைக்கத் தேர்ந்தெடுங்கள்."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"சாதனத்தை ரீஃபார்மேட் செய்ய வேண்டியிருக்கும்"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> அகற்றப்பட்டது"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"உள்ளடக்கத்தை இழக்காமலிருக்க, அகற்றும் முன்பாக மீடியாவை வெளியேற்றவும்"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ஷார்ட்கட்டைப் பயன்படுத்து"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"கலர் இன்வெர்ஷன்"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"வண்ணத் திருத்தம்"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"ஒளிர்வைக் குறைத்தல்"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"மிகக் குறைவான வெளிச்சம்"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ஒலியளவுக்கான விசைகளைப் பிடித்திருந்தீர்கள். <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ஆன் செய்யப்பட்டது."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ஒலியளவுக்கான விசைகளைப் பிடித்திருந்தீர்கள். <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ஆஃப் செய்யப்பட்டது."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>ஐப் பயன்படுத்த 3 விநாடிகளுக்கு இரண்டு ஒலியளவு பட்டன்களையும் அழுத்திப் பிடிக்கவும்"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"திரையிலுள்ள அணுகல்தன்மை ஷார்ட்கட்"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"திரையிலுள்ள அணுகல்தன்மை ஷார்ட்கட்டிற்கான தேர்வி"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"அணுகல்தன்மை ஷார்ட்கட்"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"அறிவிப்பு விவரத்தை நிராகரி"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<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> என்பதை வரம்பிடப்பட்ட பக்கெட்திற்குள் சேர்க்கப்பட்டது"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"புதிது: சாளரம் பெரிதாக்கும் கருவி"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"திரை முழுவதையுமோ ஒரு பகுதியையோ பெரிதாக்கலாம்"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"திரையின் ஒரு பகுதியைப் பெரிதாக்குதல்"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"முழுத்திரையையோ குறிப்பிட்ட பகுதியையோ இப்போது பெரிதாக்கலாம் அல்லது இந்த இரு விருப்பங்களுக்கிடையே மாறலாம்."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"அமைப்புகளில் ஆன் செய்க"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"மூடுக"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"தொடர, உங்கள் சாதனத்தின் மைக்ரோஃபோனை அணுகுவதற்கு &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ஆப்ஸுக்கு அனுமதி வேண்டும்."</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"சென்சார் தனியுரிமை"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"ஆப்ஸ் ஐகான்"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"ஆப்ஸ் பிராண்டிங் இமேஜ்"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"அணுகல் அமைப்புகளைச் சரிபாருங்கள்"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> சேவையால் உங்கள் திரையைப் பார்க்கவும் கட்டுப்படுத்தவும் முடியும். பார்க்கத் தட்டவும்."</string>
 </resources>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index c2a5d42..a354380 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"ట్విలైట్ సర్వీస్"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"టైమ్ జోన్ డిటెక్టర్ (కనెక్టివిటీ లేదు)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS సమయ అప్‌డేట్ సర్వీస్"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"మ్యూజిక్ గుర్తింపు మేనేజర్ సర్వీస్"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"మీ పరికరంలోని డేటా తొలగించబడుతుంది"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"నిర్వాహక యాప్‌ ఉపయోగించడం సాధ్యపడదు. మీ పరికరంలోని డేటా ఇప్పుడు తొలగించబడుతుంది.\n\nమీకు ప్రశ్నలు ఉంటే, మీ సంస్థ యొక్క నిర్వాహకులను సంప్రదించండి."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"ముద్రణ <xliff:g id="OWNER_APP">%s</xliff:g> ద్వారా నిలిపివేయబడింది."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"యాప్ అమలవుతోంది"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"బ్యాటరీని ఉపయోగిస్తున్న యాప్‌లు"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"మాగ్నిఫికేషన్"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"యాక్సెసిబిలిటీ సెక్యూరిటీ పాలసీ"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> బ్యాటరీని ఉపయోగిస్తోంది"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> యాప్‌లు బ్యాటరీని ఉపయోగిస్తున్నాయి"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"బ్యాటరీ మరియు డేటా వినియోగ వివరాల కోసం నొక్కండి"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"స్థితి బార్‌ ఉండేలా చేయడానికి యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"స్థితి పట్టీని విస్తరింపజేయడం/కుదించడం"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"స్థితి బార్‌ను విస్తరింపజేయడానికి లేదా కుదించడానికి యాప్‌ను అనుమతిస్తుంది."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"లాక్ చేసి ఉన్న పరికరంలో నోటిఫికేషన్‌లను ఫుల్ స్క్రీన్ యాక్టివిటీలుగా డిస్‌ప్లే చేస్తుంది"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"లాక్ చేసి ఉన్న పరికరంలో నోటిఫికేషన్‌లను ఫుల్ స్క్రీన్ యాక్టివిటీలుగా డిస్‌ప్లే చేయడానికి యాప్‌ను అనుమతిస్తుంది"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"షార్ట్‌కట్‌లను ఇన్‌స్టాల్ చేయడం"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"వినియోగదారు ప్రమేయం లేకుండానే హోమ్‌స్క్రీన్ సత్వరమార్గాలను జోడించడానికి యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"సత్వరమార్గాలను అన్ఇన్‌స్టాల్ చేయడం"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"బయోమెట్రిక్స్‌ను లేదా స్క్రీన్ లాక్‌ను ఉపయోగించండి"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"ఇది మీరేనని వెరిఫై చేసుకోండి"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"కొనసాగించడానికి, మీ బయోమెట్రిక్‌ను ఉపయోగించండి"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"కొనసాగించడానికి మీ బయోమెట్రిక్ లేదా స్క్రీన్ లాక్‌ను ఉపయోగించండి"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"బయోమెట్రిక్ హార్డ్‌వేర్‌ అందుబాటులో లేదు"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"ప్రమాణీకరణ రద్దు చేయబడింది"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"గుర్తించలేదు"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"వేలిముద్రను ఉపయోగించండి"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"వేలిముద్ర లేదా స్క్రీన్ లాక్‌ను ఉపయోగించండి"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"కొనసాగించడానికి మీ వేలిముద్రను ఉపయోగించండి"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"కొనసాగించడానికి మీ వేలిముద్ర లేదా స్క్రీన్ లాక్‌ను ఉపయోగించండి"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"వేలిముద్ర చిహ్నం"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"ఫేస్ అన్‌లాక్‌ను ఉపయోగించండి"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"ముఖం లేదా స్క్రీన్ లాక్‌ను ఉపయోగించండి"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"కొనసాగించడానికి, మీ ఫేస్ అన్‌లాక్‌ను ఉపయోగించండి"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"కొనసాగించడానికి మీ ముఖం లేదా స్క్రీన్ లాక్‌ను ఉపయోగించండి"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"ముఖ చిహ్నం"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"ఈ పేజీని తెరవడానికి మీకు అనుమతి లేదు."</string>
     <string name="text_copied" msgid="2531420577879738860">"వచనం క్లిప్‌బోర్డ్‌కు కాపీ చేయబడింది."</string>
     <string name="copied" msgid="4675902854553014676">"కాపీ చేయబడింది"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> నుండి పేస్ట్ చేయబడింది"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> క్లిప్‌బోర్డ్ నుండి పేస్ట్ చేయబడింది"</string>
     <string name="more_item_label" msgid="7419249600215749115">"ఎక్కువ"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"మెనూ+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"ఆఫ్ చేయి"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"<xliff:g id="NAME">%s</xliff:g>ని తనిఖీ చేస్తోంది…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"ప్రస్తుత కంటెంట్ సమీక్షించబడుతోంది"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"మీడియా స్టోరేజ్‌ను విశ్లేషిస్తోంది"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"కొత్త <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> పని చేయటం లేదు"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"సెటప్ చేయడానికి నొక్కండి"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"సెటప్ చేయడానికి ఎంచుకోండి"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"మీరు పరికరాన్ని తిరిగి ఫార్మాట్ చేయాల్సి ఉంటుంది. తొలగించడానికి ట్యాప్ చేయండి"</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"ఫోటోలు మరియు మీడియాను బదిలీ చేయడానికి"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"మీడియా ఫైల్స్‌ను బ్రౌజ్ చేయండి"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"<xliff:g id="NAME">%s</xliff:g>తో సమస్య ఉంది"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> పని చేయటం లేదు"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"పరిష్కరించడానికి నొక్కండి"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"<xliff:g id="NAME">%s</xliff:g>కి మద్దతు లేదు"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> పని చేయటం లేదు"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"ఈ పరికరం ఈ <xliff:g id="NAME">%s</xliff:g>కి మద్దతు ఇవ్వదు. మద్దతు కలిగిన ఆకృతిలో సెటప్ చేయడానికి నొక్కండి."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"ఈ పరికరం ఈ <xliff:g id="NAME">%s</xliff:g>కి మద్దతు ఇవ్వదు. మద్దతు కలిగిన ఆకృతిలో సెటప్ చేయడానికి ఎంచుకోండి."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"సపోర్ట్ చేసే ఫార్మాట్‌లో <xliff:g id="NAME">%s</xliff:g>ను సెటప్ చేయడానికి ఎంచుకోండి."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"మీరు పరికరాన్ని తిరిగి ఫార్మాట్ చేయాల్సి ఉంటుంది"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> ఊహించని విధంగా తీసివేయబడింది"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"కంటెంట్‌ని కోల్పోవడాన్ని నివారించాలంటే తీసివేయబోయే ముందు మీడియాని తొలగించండి"</string>
@@ -1677,7 +1689,8 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"సత్వరమార్గాన్ని ఉపయోగించు"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"కలర్ మార్పిడి"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"కలర్ సరిచేయడం"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"ప్రకాశాన్ని తగ్గించండి"</string>
+    <!-- no translation found for reduce_bright_colors_feature_name (3222994553174604132) -->
+    <skip />
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"వాల్యూమ్ కీలు నొక్కి ఉంచబడ్డాయి. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ఆన్ చేయబడింది"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"వాల్యూమ్ కీలు నొక్కి ఉంచబడ్డాయి. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ఆఫ్ చేయబడింది"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>ని ఉపయోగించడానికి వాల్యూమ్ కీలు రెండింటినీ 3 సెకన్లు నొక్కి ఉంచండి"</string>
@@ -1689,9 +1702,9 @@
     <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"ఫీచర్ల మధ్య మారడానికి, మూడు చేతి వేళ్ళతో పైకి స్వైప్ చేసి పట్టుకోండి."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"మాగ్నిఫికేషన్"</string>
     <string name="user_switched" msgid="7249833311585228097">"ప్రస్తుత వినియోగదారు <xliff:g id="NAME">%1$s</xliff:g>."</string>
-    <string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g>కి మారుస్తోంది…"</string>
+    <string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> యూజర్‌కు స్విచ్ అవుతోంది…"</string>
     <string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g>ని లాగ్ అవుట్ చేస్తోంది…"</string>
-    <string name="owner_name" msgid="8713560351570795743">"యజమాని"</string>
+    <string name="owner_name" msgid="8713560351570795743">"ఓనర్"</string>
     <string name="error_message_title" msgid="4082495589294631966">"ఎర్రర్"</string>
     <string name="error_message_change_not_allowed" msgid="843159705042381454">"ఈ మార్పును మీ నిర్వాహకులు అనుమతించలేదు"</string>
     <string name="app_not_found" msgid="3429506115332341800">"ఈ చర్యను నిర్వహించడానికి యాప్ ఏదీ కనుగొనబడలేదు"</string>
@@ -2086,6 +2099,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"స్క్రీన్‌పై ఉండే యాక్సెసిబిలిటీ షార్ట్‌కట్"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"స్క్రీన్‌పై ఉండే యాక్సెసిబిలిటీ షార్ట్‌కట్‌ల ఎంపిక సాధనం"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"యాక్సెసిబిలిటీ షార్ట్‌కట్"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"నోటిఫికేషన్ తెరను తీసివేయండి"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<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> పరిమితం చేయబడిన బకెట్‌లో ఉంచబడింది"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2237,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"కొత్తది: విండో మాగ్నిఫయర్"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"స్క్రీన్ మొత్తం లేదా కొంత భాగాన్ని జూమ్ చేయవచ్చు"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"మీ స్క్రీన్‌లో కొంత భాగాన్ని మ్యాగ్నిఫై చేయండి"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"ఇప్పుడు మీరు మీ ఫుల్ స్క్రీన్‌ను, నిర్దిష్ట ఏరియాను మ్యాగ్నిఫై చేయగలరు లేదా రెండు ఆప్షన్‌ల మధ్య స్విచ్ చేయగలరు."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"సెట్టింగ్‌లలో ఆన్ చేయండి"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"విస్మరించు"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"కొనసాగించడానికి, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt;కు మీ పరికరం యొక్క మైక్రోఫోన్ యాక్సెస్ అవసరం."</string>
@@ -2233,4 +2247,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"సెన్సార్ గోప్యత"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"యాప్ చిహ్నం"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"యాప్ బ్రాండింగ్ ఇమేజ్"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"యాక్సెస్ సెట్టింగ్‌లను చెక్ చేయండి"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> మీ స్క్రీన్‌ను చూడవచ్చు, నియంత్రించవచ్చు. రివ్యూ చేయడానికి ట్యాప్ చేయండి."</string>
 </resources>
diff --git a/core/res/res/values-television/themes.xml b/core/res/res/values-television/themes.xml
index 176e89e..b023c75 100644
--- a/core/res/res/values-television/themes.xml
+++ b/core/res/res/values-television/themes.xml
@@ -14,14 +14,14 @@
      limitations under the License.
 -->
 <resources>
-    <style name="Theme.Dialog.Alert" parent="Theme.Leanback.Light.Dialog.Alert" />
+    <style name="Theme.Dialog.Alert" parent="Theme.Leanback.Dialog.Alert" />
     <style name="Theme.Dialog.Confirmation" parent="Theme.Leanback.Dialog.Confirmation" />
     <style name="Theme.Holo.Dialog.Alert" parent="Theme.Leanback.Dialog.Alert" />
-    <style name="Theme.Holo.Light.Dialog.Alert" parent="Theme.Leanback.Light.Dialog.Alert" />
+    <style name="Theme.Holo.Light.Dialog.Alert" parent="Theme.Leanback.Dialog.Alert" />
     <style name="Theme.Material.Dialog.Alert" parent="Theme.Leanback.Dialog.Alert" />
-    <style name="Theme.Material.Light.Dialog.Alert" parent="Theme.Leanback.Light.Dialog.Alert" />
+    <style name="Theme.Material.Light.Dialog.Alert" parent="Theme.Leanback.Dialog.Alert" />
     <style name="Theme.Material.Settings.Dialog.Alert" parent="Theme.Leanback.Settings.Dialog.Alert" />
     <style name="Theme.Material.Dialog" parent="Theme.Leanback.Dialog" />
-    <style name="Theme.Material.Light.Dialog" parent="Theme.Leanback.Light.Dialog" />
+    <style name="Theme.Material.Light.Dialog" parent="Theme.Leanback.Dialog" />
     <style name="Theme.Material.Settings.Dialog" parent="Theme.Leanback.Settings.Dialog" />
 </resources>
diff --git a/core/res/res/values-television/themes_device_defaults.xml b/core/res/res/values-television/themes_device_defaults.xml
index d6bdeee..9d0e522 100644
--- a/core/res/res/values-television/themes_device_defaults.xml
+++ b/core/res/res/values-television/themes_device_defaults.xml
@@ -16,7 +16,7 @@
 <resources>
     <style name="Theme.DeviceDefault.Dialog.Alert" parent="Theme.Leanback.Dialog.Alert" />
     <style name="Theme.DeviceDefault.Dialog.AppError" parent="Theme.Leanback.Dialog.AppError" />
-    <style name="Theme.DeviceDefault.Light.Dialog.Alert" parent="Theme.Leanback.Light.Dialog.Alert" />
+    <style name="Theme.DeviceDefault.Light.Dialog.Alert" parent="Theme.Leanback.Dialog.Alert" />
 
     <!-- TODO(b/116457731): remove colorBackground from colors_material.xml if not used anymore -->
     <style name="Theme.DeviceDefault.Autofill" parent="Theme.Material">
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index a5cfe40..a2bdfa7 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Twilight Service"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"ตัวตรวจจับเขตเวลา (ไม่มีการเชื่อมต่อ)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"บริการอัปเดตเวลาของ GNSS"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"บริการโปรแกรมจัดการการหาเพลง"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"ระบบจะลบข้อมูลในอุปกรณ์ของคุณ"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"ใช้แอปผู้ดูแลระบบนี้ไม่ได้ ขณะนี้ระบบจะลบข้อมูลในอุปกรณ์ของคุณ\n\nโปรดติดต่อผู้ดูแลระบบขององค์กรหากมีคำถาม"</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> ปิดใช้การพิมพ์แล้ว"</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"แอปที่ทำงานอยู่"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"แอปหลายแอปกำลังใช้แบตเตอรี่"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"การขยาย"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"นโยบายความปลอดภัยสำหรับการช่วยเหลือพิเศษ"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> กำลังใช้แบตเตอรี่"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"แอป <xliff:g id="NUMBER">%1$d</xliff:g> แอปกำลังใช้แบตเตอรี่"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"แตะเพื่อดูรายละเอียดเกี่ยวกับแบตเตอรี่และปริมาณการใช้อินเทอร์เน็ต"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"อนุญาตให้แอปพลิเคชันเป็นแถบสถานะ"</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"ขยาย/ยุบแถบสถานะ"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"อนุญาตให้แอปพลิเคชันขยายหรือยุบแถบสถานะ"</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"แสดงการแจ้งเตือนเป็นกิจกรรมแบบเต็มหน้าจอในอุปกรณ์ที่ล็อกอยู่"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"อนุญาตให้แอปแสดงการแจ้งเตือนเป็นกิจกรรมแบบเต็มหน้าจอในอุปกรณ์ที่ล็อกอยู่"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"ติดตั้งทางลัด"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"อนุญาตให้แอปพลิเคชันเพิ่มทางลัดหน้าจอหลักโดยไม่ต้องให้ผู้ใช้จัดการ"</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"ถอนการติดตั้งทางลัด"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"ใช้ข้อมูลไบโอเมตริกหรือการล็อกหน้าจอ"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"ยืนยันว่าเป็นตัวคุณ"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"ใช้ข้อมูลไบโอเมตริกเพื่อดำเนินการต่อ"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"ใช้ข้อมูลไบโอเมตริกหรือการล็อกหน้าจอเพื่อดำเนินการต่อ"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"ฮาร์ดแวร์ไบโอเมตริกไม่พร้อมใช้งาน"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"ยกเลิกการตรวจสอบสิทธิ์แล้ว"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"ไม่รู้จัก"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ใช้ลายนิ้วมือ"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ใช้ลายนิ้วมือหรือการล็อกหน้าจอ"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"ใช้ลายนิ้วมือของคุณเพื่อดำเนินการต่อ"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"ใช้ลายนิ้วมือหรือการล็อกหน้าจอเพื่อดำเนินการต่อ"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"ไอคอนลายนิ้วมือ"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"ใช้การปลดล็อกด้วยใบหน้า"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"ใช้การล็อกด้วยใบหน้าหรือการล็อกหน้าจอ"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"ใช้การปลดล็อกด้วยใบหน้าเพื่อดำเนินการต่อ"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"ใช้ใบหน้าหรือการล็อกหน้าจอเพื่อดำเนินการต่อ"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"ไอคอนใบหน้า"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"คุณไม่ได้รับอนุญาตให้เปิดหน้าเว็บนี้"</string>
     <string name="text_copied" msgid="2531420577879738860">"คัดลอกข้อความไปยังคลิปบอร์ด"</string>
     <string name="copied" msgid="4675902854553014676">"คัดลอกแล้ว"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"วาง <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> จาก <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> แล้ว"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"วาง <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> จากคลิปบอร์ดแล้ว"</string>
     <string name="more_item_label" msgid="7419249600215749115">"เพิ่มเติม"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"เมนู+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"ปิด"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"กำลังตรวจสอบ <xliff:g id="NAME">%s</xliff:g>…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"กำลังตรวจสอบเนื้อหาปัจจุบัน"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"กำลังวิเคราะห์พื้นที่เก็บข้อมูลสื่อ"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"<xliff:g id="NAME">%s</xliff:g> ใหม่"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> ใช้งานไม่ได้"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"แตะเพื่อตั้งค่า"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"เลือกเพื่อตั้งค่า"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"คุณอาจต้องฟอร์แมตอุปกรณ์นี้ใหม่ แตะเพื่อนำอุปกรณ์ออก"</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"สำหรับการโอนรูปภาพและสื่อ"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"เรียกดูไฟล์สื่อ"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"ปัญหาเกี่ยวกับ <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> ใช้งานไม่ได้"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"แตะเพื่อแก้ไข"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"ไม่สนับสนุน <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> ใช้งานไม่ได้"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"อุปกรณ์นี้ไม่สนับสนุน <xliff:g id="NAME">%s</xliff:g> นี้ แตะเพื่อตั้งค่าในรูปแบบที่สนับสนุน"</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"อุปกรณ์นี้ไม่รองรับ <xliff:g id="NAME">%s</xliff:g> นี้ เลือกเพื่อตั้งค่าในรูปแบบที่รองรับ"</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"เลือกเพื่อตั้งค่า<xliff:g id="NAME">%s</xliff:g> ในรูปแบบที่รองรับ"</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"คุณอาจต้องฟอร์แมตอุปกรณ์นี้ใหม่"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> ถูกนำออกไปโดยไม่คาดคิด"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"ยกเลิกการต่อเชื่อมสื่อก่อนที่จะนำออกเพื่อหลีกเลี่ยงไม่ให้เนื้อหาสูญหาย"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ใช้ทางลัด"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"การกลับสี"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"การแก้สี"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"ลดความสว่าง"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"หรี่แสงเพิ่มเติม"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"กดปุ่มปรับระดับเสียงค้างไว้แล้ว เปิด <xliff:g id="SERVICE_NAME">%1$s</xliff:g> แล้ว"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"กดปุ่มปรับระดับเสียงค้างไว้แล้ว ปิด <xliff:g id="SERVICE_NAME">%1$s</xliff:g> แล้ว"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"กดปุ่มปรับระดับเสียงทั้ง 2 ปุ่มค้างไว้ 3 วินาทีเพื่อใช้ <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"ทางลัดการช่วยเหลือพิเศษบนหน้าจอ"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"ตัวเลือกทางลัดการช่วยเหลือพิเศษบนหน้าจอ"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"ทางลัดการช่วยเหลือพิเศษ"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"ปิดหน้าต่างแจ้งเตือน"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"แถบคำบรรยาย <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> ในที่เก็บข้อมูลที่ถูกจำกัดแล้ว"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"ใหม่: แว่นขยายหน้าต่าง"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"คุณสามารถขยายหน้าจอบางส่วนหรือทั้งหมดได้แล้วตอนนี้"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"ขยายบางส่วนของหน้าจอ"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"ตอนนี้คุณสามารถขยายเป็นเต็มหน้าจอ ขยายพื้นที่ที่เจาะจง หรือจะสลับไปมาระหว่างตัวเลือกทั้ง 2 อย่างก็ได้"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"เปิดในการตั้งค่า"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"ปิด"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"&lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ต้องได้รับสิทธิ์เข้าถึงไมโครโฟนของอุปกรณ์เพื่อดำเนินการต่อ"</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"ความเป็นส่วนตัวสำหรับเซ็นเซอร์"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"ไอคอนแอปพลิเคชัน"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"ภาพลักษณ์ของแบรนด์แอปพลิเคชัน"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"ตรวจสอบการตั้งค่าการเข้าถึง"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> จะดูและควบคุมหน้าจอของคุณได้ แตะเพื่อตรวจสอบ"</string>
 </resources>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 4829cef..030a3e5 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Serbisyo ng Twilight"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Detector ng Time Zone (Walang koneksyon)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"Serbisyo sa Pag-update ng Oras ng GNSS"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Serbisyo ng Music Recognition Manager"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Buburahin ang iyong device"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Hindi magamit ang admin app. Mabubura na ang iyong device.\n\nKung mayroon kang mga tanong, makipag-ugnayan sa admin ng iyong organisasyon."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Na-disable ng <xliff:g id="OWNER_APP">%s</xliff:g> ang pag-print."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Tumatakbo ang app"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Mga app na kumokonsumo ng baterya"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Pag-magnify"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Patakaran sa seguridad ng accessibility"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"Gumagamit ng baterya ang <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"Gumagamit ng baterya ang <xliff:g id="NUMBER">%1$d</xliff:g> (na) app"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"I-tap para sa mga detalye tungkol sa paggamit ng baterya at data"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Pinapayagan ang app na maging status bar."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"palawakin/tiklupin ang status bar"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Pinapayagan ang app na palawakin o tiklupin ang status bar."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"ipakita ang mga notification bilang mga full screen na aktibidad sa naka-lock na device"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Nagbibigay-daan sa app na magpakita ng mga notification bilang mga full screen na aktibidad sa naka-lock na device"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"i-install ang mga shortcut"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Pinapayagan ang isang application na magdagdag ng mga shortcut ng Homescreen nang walang panghihimasok ng user."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"i-uninstall ang mga shortcut"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Gumamit ng biometrics o lock ng screen"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"I-verify na ikaw ito"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Gamitin ang iyong biometric para magpatuloy"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Gamitin ang iyong biometric o lock ng screen para magpatuloy"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Walang biometric hardware"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Nakansela ang pag-authenticate"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Hindi nakilala"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Gumamit ng fingerprint"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Gumamit ng fingerprint o lock ng screen"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Gamitin ang iyong fingerprint para magpatuloy"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Gamitin ang iyong fingerprint o lock ng screen para magpatuloy"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Icon ng fingerprint"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Gumamit ng face unlock"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Gumamit ng mukha o lock ng screen"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Gumamit ng face unlock para magpatuloy"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Gamitin ang iyong mukha o lock ng screen para magpatuloy"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Face icon"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"Wala kang pahintulot na buksan ang pahinang ito."</string>
     <string name="text_copied" msgid="2531420577879738860">"Nakopya ang teksto sa clipboard."</string>
     <string name="copied" msgid="4675902854553014676">"Nakopya"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"Na-paste ang <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> mula sa <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"Na-paste ang <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> mula sa clipboard"</string>
     <string name="more_item_label" msgid="7419249600215749115">"Higit pa"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Menu+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"I-off"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Sinusuri ang <xliff:g id="NAME">%s</xliff:g>…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Sinusuri ang kasalukuyang content"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Sinusuri ang storage ng media"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Bagong <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"Hindi gumagana ang <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Mag-tap para i-set up"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Piliin para i-set up"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Baka kailanganin mong i-reformat ang device. I-tap para i-eject."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"Para sa paglilipat ng mga larawan at media"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Mag-browse ng mga media file"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Isyu sa <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"Hindi gumagana ang <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Mag-tap para ayusin"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"Hindi sinusuportahang <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"Hindi gumagana ang <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"Hindi sinusuportahan ng device na ito ang <xliff:g id="NAME">%s</xliff:g> na ito. I-tap upang i-set up sa isang sinusuportahang format."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"Hindi sinusuportahan ng device na ito ang <xliff:g id="NAME">%s</xliff:g> na ito. Piliin upang i-set up sa isang sinusuportahang format."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Piliin para i-set up ang <xliff:g id="NAME">%s</xliff:g> sa isang sinusuportahang format."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Baka kailanganin mong i-reformat ang device"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"Hindi inaasahang naalis ang <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"I-eject ang media bago tanggalin para maiwasan ang pagkawala ng content"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Gamitin ang Shortcut"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Pag-invert ng Kulay"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Pagwawasto ng Kulay"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Bawasan ang liwanag"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Extra dim"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Pinindot nang matagal ang volume keys. Na-on ang <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Pinindot nang matagal ang volume keys. Na-off ang <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Pindutin nang matagal ang parehong volume key sa loob ng tatlong segundo para magamit ang <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Shortcut ng Accessibility sa Screen"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Tagapili ng Shortcut ng Accessibility sa Screen"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Shortcut ng Accessibility"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"I-dismiss ang Notification Shade"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Caption bar ng <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Inilagay ang <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> sa PINAGHIHIGPITANG bucket"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Bago: Magnifier ng Window"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Mama-magnify na ang bahagi o kabuuan ng screen mo"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"I-magnify ang isang bahagi ng iyong screen"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Puwede ka na ngayong mag-magnify ng iyong buong screen o ng partikular na bahagi, o magpalipat-lipat sa dalawang opsyon."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"I-on sa Mga Setting"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"I-dismiss"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Para magpatuloy, kailangan ng &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ng access sa mikropono ng iyong device."</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privacy ng Sensor"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Icon ng application"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Representasyon ng brand ng application"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Tingnan ang mga setting ng pag-access"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"Makikita at makokontrol ng <xliff:g id="SERVICE_NAME">%s</xliff:g> ang iyong screen. I-tap para suriin."</string>
 </resources>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 186ffa7..30bf808 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Alacakaranlık Hizmeti"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Zaman Dilimi Algılayıcı (Bağlantı yok)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS Zaman Güncelleme Hizmeti"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Müzik Tanıma Yöneticisi Hizmeti"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Cihazınız silinecek"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Yönetim uygulaması kullanılamıyor. Cihazınız şimdi silinecek.\n\nSorularınız varsa kuruluşunuzun yöneticisine başvurun."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Yazdırma işlemi <xliff:g id="OWNER_APP">%s</xliff:g> tarafından devre dışı bırakıldı."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Uygulama çalışıyor"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Pil kullanan uygulamalar"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Büyütme"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Erişilebilirlik güvenlik politikası"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> pil kullanıyor"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> uygulama pil kullanıyor"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Pil ve veri kullanımı ile ilgili ayrıntılar için dokunun"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Uygulamaya, durum çubuğu olma izni verir."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"durum çubuğunu genişlet/daralt"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Uygulamaya, durum çubuğunu genişletip daraltma izni verir."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"kilitli cihazda tam ekran etkinlik biçiminde bildirim göster"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Uygulamanın kilitli cihazda tam ekran etkinlik biçiminde bildirim göstermesine izin verilir"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"kısayolları yükleme"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Uygulamaya, kullanıcı müdahalesi olmadan kısayolları Ana Ekrana ekleme izni verir."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"kısayolların yüklemesini kaldırma"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Biyometri veya ekran kilidi kullan"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Siz olduğunuzu doğrulayın"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Devam etmek için biyometri kullanın"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Devam etmek için biyometrik kimlik bilginizi veya ekran kilidinizi kullanın"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biyometrik donanım kullanılamıyor"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Kimlik doğrulama iptal edildi"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Tanınmadı"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Parmak izi kullan"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Parmak izi veya ekran kilidi kullan"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Devam etmek için parmak izinizi kullanın"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Devam etmek için parmak izi veya ekran kilidinizi kullanın"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Parmak izi simgesi"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Yüz tanıma kilidi kullan"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Yüz tanıma veya ekran kilidi kullan"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Devam etmek için yüz tanıma kilidini kullanın"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Devam etmek için yüz veya ekran kilidinizi kullanın"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Yüz simgesi"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"Bu sayfayı açma izniniz yok."</string>
     <string name="text_copied" msgid="2531420577879738860">"Metin panoya kopyalandı."</string>
     <string name="copied" msgid="4675902854553014676">"Kopyalandı"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> uygulaması <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> kaynağından yapıştırdı"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>, panodan yapıştırıldı."</string>
     <string name="more_item_label" msgid="7419249600215749115">"Diğer"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Menü+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Kapat"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"<xliff:g id="NAME">%s</xliff:g> kontrol ediliyor…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Geçerli içerik inceleniyor"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Medya deposu analiz ediliyor"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Yeni <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> çalışmıyor"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Ayarlamak için dokunun"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Kurmak için harici medyayı seçin"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Cihazı yeniden biçimlendirmeniz gerekebilir. Çıkarmak için dokunun."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"Fotoğraf ve medya aktarmak için"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Medya dosyalarına göz atın"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"<xliff:g id="NAME">%s</xliff:g> medyasında sorun oluştu"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> çalışmıyor"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Düzeltmek için dokunun"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"Desteklenmeyen <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> çalışmıyor"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"Bu cihaz, bu <xliff:g id="NAME">%s</xliff:g> ortamını desteklemiyor. Desteklenen bir biçimde kurmak için dokunun."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"Bu cihaz, bu <xliff:g id="NAME">%s</xliff:g> medyasını desteklemiyor. Desteklenen bir biçimde ayarlamak için seçin."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"<xliff:g id="NAME">%s</xliff:g> kurulumunu desteklenen biçimde yapmak için seçin."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Cihazı yeniden biçimlendirmeniz gerekebilir"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> beklenmedik şekilde çıkarıldı"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"İçerik kaybı olmaması için medyayı çıkarmadan önce kaldırın"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Kısayolu Kullan"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Rengi Ters Çevirme"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Renk Düzeltme"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Parlaklığı azalt"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Ekstra loş"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Ses tuşlarını basılı tuttunuz. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> açıldı."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Ses tuşlarını basılı tuttunuz. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> kapatıldı."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> hizmetini kullanmak için her iki ses tuşunu basılı tutun"</string>
@@ -1691,7 +1703,7 @@
     <string name="user_switched" msgid="7249833311585228097">"Geçerli kullanıcı: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> adlı kullanıcıya geçiliyor…"</string>
     <string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> hesabından çıkış yapılıyor…"</string>
-    <string name="owner_name" msgid="8713560351570795743">"Sahibi"</string>
+    <string name="owner_name" msgid="8713560351570795743">"Sahip"</string>
     <string name="error_message_title" msgid="4082495589294631966">"Hata"</string>
     <string name="error_message_change_not_allowed" msgid="843159705042381454">"Yöneticiniz bu değişikliğe izin vermiyor"</string>
     <string name="app_not_found" msgid="3429506115332341800">"Bu eylemi gerçekleştirecek bir uygulama bulunamadı"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Ekran Erişilebilirlik Kısayolu"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Ekran Erişilebilirlik Kısayol Seçici"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Erişilebilirlik Kısayolu"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Bildirim Gölgesini Kapat"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g> uygulamasının başlık çubuğu."</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> KISITLANMIŞ gruba yerleştirildi"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Yeni: Pencere Büyüteci"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Artık ekranınızın bir kısmını veya tamamını büyütebilirsiniz"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Ekranınızın bir bölümünü büyütün"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Artık ekranınızın tamamını veya belirli bir bölümünü büyütebilir veya bu iki seçenek arasında geçiş yapabilirsiniz."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Ayarlar\'da aç"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Kapat"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Devam etmek için &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; uygulamasının cihazınızın mikrofonuna erişmesi gerekiyor."</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Sensör Gizliliği"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Uygulama simgesi"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Uygulama marka imajı"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Erişim ayarlarını kontrol edin"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g>, ekranınızı görüntüleyip kontrol edebilir. İncelemek için dokunun."</string>
 </resources>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 7049a2e..30a829a 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -208,6 +208,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Сервіс \"Сутінки\""</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Визначення часового поясу (без Інтернету)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"Сервіс оновлення часу GNSS"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Сервіс Music Recognition Manager"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"З вашого пристрою буде стерто всі дані"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Не можна запускати додаток для адміністраторів. Буде відновлено заводські налаштування пристрою.\n\nЯкщо у вас є запитання, зв’яжіться з адміністратором своєї організації."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Додаток <xliff:g id="OWNER_APP">%s</xliff:g> вимкнув друк."</string>
@@ -299,6 +300,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Працює додаток"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Додатки, що використовують заряд акумулятора"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Збільшення"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Правила щодо безпеки спеціальних можливостей"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"Додаток <xliff:g id="APP_NAME">%1$s</xliff:g> використовує заряд акумулятора"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"Додатків, що використовують заряд акумулятора: <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Торкніться, щоб перевірити використання акумулятора й трафік"</string>
@@ -349,6 +351,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Дозволяє програмі бути рядком стану."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"розгорнути/згорн. рядок стану"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Дозволяє програмі розгортати чи згортати рядок стану."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"Показувати сповіщення як активності на весь екран заблокованого пристрою"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Додаток зможе показувати сповіщення як активності на весь екран заблокованого пристрою"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"створення ярликів"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Дозволяє програмі самостійно додавати ярлики на головний екран."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"видаляти ярлики"</string>
@@ -556,18 +560,19 @@
     <string name="permdesc_imagesWrite" msgid="5195054463269193317">"Додаток зможе змінювати вашу колекцію фотографій."</string>
     <string name="permlab_mediaLocation" msgid="7368098373378598066">"розпізнавати геодані з колекції медіа-вмісту"</string>
     <string name="permdesc_mediaLocation" msgid="597912899423578138">"Додаток зможе розпізнавати геодані з вашої колекції медіа-вмісту."</string>
-    <string name="biometric_app_setting_name" msgid="3339209978734534457">"Використовувати біометрію"</string>
-    <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Використовувати біометрію або блокування екрана"</string>
+    <string name="biometric_app_setting_name" msgid="3339209978734534457">"Доступ через біометрію"</string>
+    <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Використовувати біометрію або дані для розблокування екрана"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Підтвердьте, що це ви"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Щоб продовжити, скористайтеся біометрією"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Щоб продовжити, скористайтеся біометрією або даними для розблокування екрана"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Біометричне апаратне забезпечення недоступне"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Автентифікацію скасовано"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Не розпізнано"</string>
     <string name="biometric_error_canceled" msgid="8266582404844179778">"Автентифікацію скасовано"</string>
     <string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Не вказано PIN-код, ключ або пароль"</string>
     <string name="biometric_error_generic" msgid="6784371929985434439">"Помилка автентифікації"</string>
-    <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Використовувати блокування екрана"</string>
-    <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Щоб продовжити, введіть облікові дані пристрою"</string>
+    <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Доступ розблокуванням екрана"</string>
+    <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Щоб продовжити, введіть дані для розблокування екрана пристрою"</string>
     <string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Відбиток пальця розпізнано частково. Повторіть спробу."</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Не вдалось обробити відбиток пальця. Повторіть спробу."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Датчик відбитків пальців забруднився. Очистьте його та повторіть спробу."</string>
@@ -590,9 +595,10 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"На цьому пристрої немає сканера відбитків пальців."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Датчик тимчасово вимкнено."</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Відбиток пальця <xliff:g id="FINGERID">%d</xliff:g>"</string>
-    <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Використовувати відбиток пальця"</string>
-    <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Використовувати відбиток пальця або блокування екрана"</string>
+    <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Доступ за відбитком пальця"</string>
+    <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Використовувати відбиток пальця або дані для розблокування екрана"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Щоб продовжити, скористайтеся своїм відбитком пальця"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Щоб продовжити, скористайтеся відбитком пальця або даними для розблокування екрана"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Значок відбитка пальця"</string>
@@ -637,9 +643,10 @@
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"На цьому пристрої не підтримується Фейсконтроль."</string>
     <string name="face_error_security_update_required" msgid="5076017208528750161">"Датчик тимчасово вимкнено."</string>
     <string name="face_name_template" msgid="3877037340223318119">"Обличчя <xliff:g id="FACEID">%d</xliff:g>"</string>
-    <string name="face_app_setting_name" msgid="8130135875458467243">"Використовувати фейсконтроль"</string>
-    <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Використовувати фейсконтроль або блокування екрана"</string>
+    <string name="face_app_setting_name" msgid="8130135875458467243">"Доступ через фейсконтроль"</string>
+    <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Використовувати фейсконтроль або дані для розблокування екрана"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Щоб продовжити, скористайтеся фейсконтролем"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Щоб продовжити, скористайтеся фейсконтролем або даними для розблокування екрана"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Значок обличчя"</string>
@@ -1003,6 +1010,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"У вас немає дозволу на відкривання цієї сторінки."</string>
     <string name="text_copied" msgid="2531420577879738860">"Текст скопійов. в буф. обм."</string>
     <string name="copied" msgid="4675902854553014676">"Скопійовано"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"Дані з додатка <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> вставлено в <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"Дані з буфера обміну вставлено в <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>"</string>
     <string name="more_item_label" msgid="7419249600215749115">"Більше"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Меню+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1410,11 +1419,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Вимкнути"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Перевіряється <xliff:g id="NAME">%s</xliff:g>…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Перевірка поточного вмісту"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Триває перевірка пам\'яті носія"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Новий пристрій пам’яті (<xliff:g id="NAME">%s</xliff:g>)"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> не працює"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Торкніться, щоб налаштувати"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Виберіть, щоб налаштувати"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Можливо, пристрій доведеться відформатувати. Натисніть, щоб вилучити."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"Для перенесення фотографій і медіафайлів"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Перегляньте файли на носії"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Проблема з носієм (<xliff:g id="NAME">%s</xliff:g>)"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> не працює"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Торкніться, щоб виправити"</string>
@@ -1423,7 +1435,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"<xliff:g id="NAME">%s</xliff:g> не підтримується"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> не працює"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"<xliff:g id="NAME">%s</xliff:g> не підтримується цим пристроєм. Торкніться, щоб налаштувати підтримуваний формат."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"<xliff:g id="NAME">%s</xliff:g> не підтримується на цьому пристрої. Виберіть, щоб налаштувати в підтримуваному форматі."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Виберіть, щоб налаштувати носій (<xliff:g id="NAME">%s</xliff:g>) у підтримуваному форматі."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Можливо, пристрій доведеться відформатувати"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> несподівано вийнято"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Перш ніж виймати носій, відключіть його, щоб не втратити вміст"</string>
@@ -1721,7 +1733,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Використовувати ярлик"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Інверсія кольорів"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Корекція кольорів"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Зменшення яскравості"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Додаткове зменшення яскравості"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Утримано клавіші гучності. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> увімкнено."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Утримано клавіші гучності. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> вимкнено."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Щоб скористатися службою <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, утримуйте обидві клавіші гучності впродовж трьох секунд"</string>
@@ -1733,7 +1745,7 @@
     <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Щоб переключитися між функціями, проведіть по екрану знизу вгору трьома пальцями й утримуйте їх."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Збільшення"</string>
     <string name="user_switched" msgid="7249833311585228097">"Поточний користувач: <xliff:g id="NAME">%1$s</xliff:g>."</string>
-    <string name="user_switching_message" msgid="1912993630661332336">"Перехід в обліковий запис \"<xliff:g id="NAME">%1$s</xliff:g>\"…"</string>
+    <string name="user_switching_message" msgid="1912993630661332336">"Перехід у режим \"<xliff:g id="NAME">%1$s</xliff:g>\"…"</string>
     <string name="user_logging_out_message" msgid="7216437629179710359">"Вихід з облікового запису користувача <xliff:g id="NAME">%1$s</xliff:g>…"</string>
     <string name="owner_name" msgid="8713560351570795743">"Власник"</string>
     <string name="error_message_title" msgid="4082495589294631966">"Помилка"</string>
@@ -2154,6 +2166,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Екранний засіб спеціальних можливостей"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Вибір екранного засобу спеціальних можливостей"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Засіб спеціальних можливостей"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Закрити панель сповіщень"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Смуга із субтитрами для додатка <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>\" додано в сегмент з обмеженнями"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2291,8 +2304,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Нове: збільшення вікон"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Тепер можна збільшити весь екран або його частину"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Збільшення частини екрана"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Тепер ви можете збільшувати весь екран чи певну область, а також переходити між цими режимами."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Увімкнути в налаштуваннях"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Закрити"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Щоб продовжити, надайте додатку &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; доступ до мікрофона пристрою."</string>
@@ -2301,4 +2314,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Конфіденційність датчиків"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Значок додатка"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Зображення фірмової символіки додатка"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Перевірте налаштування доступу"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> може переглядати екран вашого пристрою та керувати ним. Натисніть, щоб переглянути."</string>
 </resources>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 615e2fa4..c17309b 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"شفقی سروس"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"ٹائم زون ڈیٹیکٹر (کوئی کنیکٹوٹی نہیں ہے)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"‏GNSS کی ٹائم اپ ڈیٹ سروس"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"میوزک ریکگنیشن مینیجر سروس"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"آپ کا آلہ صاف کر دیا جائے گا"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"منتظم کی ایپ استعمال نہیں کی جا سکتی۔ آپ کا آلہ اب مٹا دیا جائے گا۔\n\nاگر آپ کے سوالات ہیں تو اپنی تنظیم کے منتظم سے رابطہ کریں۔"</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> نے پرنٹنگ کو غیر فعال کر دیا ہے۔"</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"ایپ چل رہی ہے"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"ایپس بیٹری خرچ کر رہی ہیں"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"میگنیفکیشن"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"ایکسیسبیلٹی سیکیورٹی کی پالیسی"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> بیٹری کا استعمال کر رہی ہے"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> ایپس بیٹری کا استعمال کر رہی ہیں"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"بیٹری اور ڈیٹا استعمال کے بارے میں تفصیلات کے لیے تھپتھپائیں"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"ایپ کو اسٹیٹس بار بننے کی اجازت دیتا ہے۔"</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"حیثیت بار پھیلائیں/سکیڑیں"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"ایپ کو اسٹیٹس بار پھیلانے یا سکیڑنے کی اجازت دیتا ہے۔"</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"مقفل آلے پر فُل اسکرین سرگرمیوں کے بطور اطلاعات کو ڈسپلے کریں"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"ایپ کو مقفل آلے پر فُل اسکرین سرگرمیوں کے بطور اطلاعات کو ڈسپلے کرنے کی اجازت دیتا ہے"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"شارٹ کٹس انسٹال کریں"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"کسی ایپلیکیشن کو صارف کی مداخلت کے بغیر ہوم اسکرین شارٹ کٹس شامل کرنے کی اجازت دیتا ہے۔"</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"شارٹ کٹس کو اَن انسٹال کریں"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"بایو میٹرکس یا اسکرین لاک استعمال کریں"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"توثیق کریں کہ یہ آپ ہیں"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"جاری رکھنے کیلئے اپنا بایو میٹرک استعمال کریں"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"جاری رکھنے کے لیے اپنے بایو میٹرک اور اسکرین لاک کا استعمال کریں"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"بایومیٹرک ہارڈ ویئر دستیاب نہیں ہے"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"تصدیق کا عمل منسوخ ہو گیا"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"تسلیم شدہ نہیں ہے"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"فنگر پرنٹ استعمال کریں"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"فنگر پرنٹ یا اسکرین لاک استعمال کریں"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"جاری رکھنے کیلئے اپنا فنگر پرنٹ استعمال کریں"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"جاری رکھنے کے لیے اپنے فنگر پرنٹ یا اسکرین لاک کا استعمال کریں"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"فنگر پرنٹ آئیکن"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"چہرے کے ذریعے غیر مقفل کرنا استعمال کریں"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"چہرہ یا اسکرین لاک استعمال کریں"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"جاری رکھنے کیلئے چہرے کے ذریعے غیر مقفل کرنا استعمال کریں"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"جاری رکھنے کے لیے اپنے چہرے یا اسکرین لاک کا استعمال کریں"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"چہرے کا آئیکن"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"آپ کے پاس یہ صفحہ کھولنے کی اجازت نہیں ہے۔"</string>
     <string name="text_copied" msgid="2531420577879738860">"متن کو کلپ بورڈ پر کاپی کیا گیا۔"</string>
     <string name="copied" msgid="4675902854553014676">"کاپی ہو گیا"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> سے <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> میں پیسٹ کیا گیا"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"کلپ بورڈ سے <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> میں پیسٹ کیا گیا"</string>
     <string name="more_item_label" msgid="7419249600215749115">"مزید"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"مینو+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+‎"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"آف کریں"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"<xliff:g id="NAME">%s</xliff:g> کو چیک کیا جا رہا ہے…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"موجودہ مواد کا جائزہ لیا جا رہا ہے"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"میڈیا اسٹوریج کا تجزیہ کیا جا رہا ہے"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"نیا <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> کام نہیں کر رہا ہے"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"سیٹ اپ کرنے کیلئے تھپتھپائیں"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"سیٹ اپ کرنے کے لیے منتخب کریں"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"آپ کو آلے کو پھر سے فارمیٹ کرنے کی ضرورت پیش آ سکتی ہے۔ خارج کرنے کے لیے تھپتھپائیں۔"</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"تصاویر اور میڈیا منتقل کرنے کیلئے"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"میڈیا فائلز کو براؤز کریں"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"<xliff:g id="NAME">%s</xliff:g> کے ساتھ مسئلہ"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> کام نہیں کر رہا ہے"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"درست کرنے کیلئے تھپتھپائیں"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"غیر تعاون یافتہ <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> کام نہیں کر رہا ہے"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"یہ آلہ <xliff:g id="NAME">%s</xliff:g> کو سپورٹ نہیں کرتا۔ ایک سپورٹ یافتہ فارمیٹ میں سیٹ اپ کرنے کیلئے تھپتھپائیں۔"</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"یہ آلہ اس <xliff:g id="NAME">%s</xliff:g> کو سپورٹ نہیں کرتا ہے۔ ایک سپورٹ یافتہ فارمیٹ میں سیٹ اپ کرنے کیلئے منتخب کریں۔"</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"سپورٹ یافتہ فارمیٹ میں <xliff:g id="NAME">%s</xliff:g> سیٹ اپ کرنے کے لیے منتخب کریں۔"</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"آپ کو آلے کو پھر سے فارمیٹ کرنے کی ضرورت پیش آ سکتی ہے"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> غیر متوقع طور پر ہٹا دیا گیا"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"مواد کھونے سے بچنے کے لئے ہٹانے سے پہلے میڈیا خارج کریں"</string>
@@ -1677,7 +1689,8 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"شارٹ کٹ استعمال کریں"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"رنگوں کی تقلیب"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"رنگ کی تصحیح"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"چمک کم کریں"</string>
+    <!-- no translation found for reduce_bright_colors_feature_name (3222994553174604132) -->
+    <skip />
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"والیوم کی کلیدوں کو دبائے رکھا گیا۔ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> آن ہے۔"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"والیوم کی کلیدوں کو دبائے رکھا گیا۔ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> آف ہے۔"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> کا استعمال کرنے کے لیے 3 سیکنڈ تک والیوم کی دونوں کلیدوں کو چھوئیں اور دبائے رکھیں"</string>
@@ -2086,6 +2099,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"آن اسکرین ایکسیسبیلٹی شارٹ کٹ"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"آن اسکرین ایکسیسبیلٹی شارٹ کٹ منتخب کنندہ"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"ایکسیسبیلٹی کا شارٹ کٹ"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"اطلاعاتی شیڈ برخاست کریں"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<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> کو پابند کردہ بکٹ میں رکھ دیا گیا ہے"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2237,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"نیا: ونڈو میگنیفائر"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"اب آپ اپنی تمام یا کچھ اسکرین کو بڑا کر سکتے ہیں"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"اپنی اسکرین کے کسی حصے کو بڑا کریں"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"آپ اپنی فُل اسکرین، کسی مخصوص حصے کو بڑا کر سکتے ہیں یا دونوں اختیارات کے درمیان سوئچ کر سکتے ہیں۔"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"ترتیبات میں آن کریں"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"برخاست کریں"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"‏جاری رکھنے کیلئے ‎<xliff:g id="APP">%s</xliff:g>&lt;b&gt;‎‏‎‎‏‏‎&lt;b&gt;‎ کو آپ کے آلے کے مائیکروفون تک رسائی درکار ہے۔"</string>
@@ -2233,4 +2247,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"سینسر کی رازداری"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"ایپلیکیشن کا آئیکن"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"ایپلیکیشن کی برانڈنگ تصویر"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"رسائی کی ترتیبات چیک کریں"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> آپ کی اسکرین کو دیکھ اور کنٹرول کر سکتی ہیں۔ جائزے کے لیے تھپتھپائیں۔"</string>
 </resources>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 0bcba06..f302d33 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Twilight xizmati"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Vaqt mintaqasini aniqlagich (Oflayn)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS yordamida vaqtni yangilash xizmati"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Musiqani aniqlash menejeri xizmati"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Qurilmangizdagi ma’lumotlar o‘chirib tashlanadi"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Administrator ilovasini ishlatib bo‘lmaydi. Qurilmada barcha ma’lumotlar o‘chirib tashlanadi.\n\nSavollaringiz bo‘lsa, administrator bilan bog‘laning."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Chop etish funksiyasi <xliff:g id="OWNER_APP">%s</xliff:g> tomonidan faolsizlantirilgan."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Ilova faol"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Batareya quvvatini sarflayotgan ilovalar"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Kattalashtirish"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Maxsus imkoniyatlar xavfsizlik siyosati"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> ilovasi batareya quvvatini sarflamoqda"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> ta ilova batareya quvvatini sarflamoqda"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Batareya va trafik sarfi tafsilotlari uchun ustiga bosing"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Ilova holat qatorining o‘rnini egallashi mumkin."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"holat panelini yoyish/yig‘ish"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Ilova holat panelini yoyishi va yig‘ishi mumkin."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"Barcha bildirishnomalarni qulflangan qurilmada butun ekranda koʻrsatish"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Ilova qulflangan qurilmada toʻliq ekranda bildirishnomalarni koʻrsata oladi"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"yorliqlar yaratish"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Dasturga foydalanuvchini aralashtirmasdan, Uy ekraniga yorliqlar qo‘shish imkonini beradi."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"yorliqlarni o‘chirish"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Biometrika yoki ekran qulfi"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Oʻzingizni taniting"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Davom etish uchun biometrik tasdiqlang"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Davom etish uchun biometrika yoki ekran qulfidan foydalaning"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrik sensor ishlamayapti"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Autentifikatsiya bekor qilindi"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Aniqlanmadi"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Barmoq izi ishlatish"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Barmoq izi yoki ekran qulfi"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Davom etish uchun barmoq izingizdan foydalaning"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Davom etish uchun barmoq izi yoki ekran qulfidan foydalaning"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Barmoq izi belgisi"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Yuz bilan ochish"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Yuz bilan ochish yoki ekran qulfi"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Davom etish uchun yuz bilan oching"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Davom etish uchun yuz tekshiruvi yoki ekran qulfidan foydalaning"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Yuz belgisi"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"Sizda ushbu sahifani ochish uchun vakolat yo‘q."</string>
     <string name="text_copied" msgid="2531420577879738860">"Matn klipboardga nusxa olindi."</string>
     <string name="copied" msgid="4675902854553014676">"Nusxalandi"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> ilovasidan <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> joylandi"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"Vaqtincha xotiradan <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> joylandi"</string>
     <string name="more_item_label" msgid="7419249600215749115">"Yana"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Menyu+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Faolsizlantirish"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"<xliff:g id="NAME">%s</xliff:g> tekshirilmoqda…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Joriy kontent tekshirilmoqda"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Media xotira tekshirilmoqda"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Yangi <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> ishlamayapti"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Sozlash uchun bosing"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Sozlash uchun tanlang"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Qurilmani qayta formatlashingiz lozim. Chiqarib tashlash uchun bosing."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"Rasm va boshqa fayllarni o‘tkazish"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Media fayl tanlash"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"<xliff:g id="NAME">%s</xliff:g> bilan muammo"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> ishlamayapti"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Tuzatish uchun bosing"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"<xliff:g id="NAME">%s</xliff:g> qo‘llab-quvvatlanmaydi"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> ishlamayapti"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"Bu xotira qurilmasi (<xliff:g id="NAME">%s</xliff:g>) qo‘llab-quvvatlanmaydi. Uni mos keladigan formatda sozlash uchun bu yerga bosing."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"Bu xotira qurilmasi (<xliff:g id="NAME">%s</xliff:g>) qo‘llab-quvvatlanmaydi. Mos formatda sozlash uchun uni tanlang."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Xotira qurilmasini (<xliff:g id="NAME">%s</xliff:g>) mos formatda sozlash uchun buni tanlang."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Qurilmani qayta formatlashingiz lozim"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> kutilmaganda chiqarib olindi"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Xotira qurilmasini olib tashlashdan oldin, uni o‘chiring, shuda ma’lumotlar o‘chib ketmaydi."</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Tezkor ishga tushirishdan foydalanish"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Ranglarni akslantirish"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Rangni tuzatish"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Yorqinlikni pasaytirish"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Juda xira"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tovush tugmalari bosib turildi. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> yoqildi."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tovush tugmalari bosib turildi. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> faolsizlantirildi."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> xizmatidan foydalanish uchun ikkala ovoz balandligi tugmalarini uzoq bosib turing"</string>
@@ -1689,7 +1701,7 @@
     <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Funksiyalarni almashtirish uchun uchta barmoq bilan tepaga suring va ushlab turing."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Kattalashtirish"</string>
     <string name="user_switched" msgid="7249833311585228097">"Joriy foydalanuvchi <xliff:g id="NAME">%1$s</xliff:g>."</string>
-    <string name="user_switching_message" msgid="1912993630661332336">"Quyidagi foydalanuvchiga o‘tilmoqda: <xliff:g id="NAME">%1$s</xliff:g>…"</string>
+    <string name="user_switching_message" msgid="1912993630661332336">"Bunga almashilmoqda: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> hisobidan chiqilmoqda…"</string>
     <string name="owner_name" msgid="8713560351570795743">"Egasi"</string>
     <string name="error_message_title" msgid="4082495589294631966">"Xato"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Ekranda tezkor ishga tushirish"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Ekranda tezkor ishga tushirishni tanlagich"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Tezkor ishga tushirish"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Eslatma soyasini yopish"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g> taglavhalar paneli."</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> cheklangan turkumga joylandi"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Yangi: Ekran lupasi"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Ekranni toʻliq yoki qisman kattalashtirish mumkin"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Ekranning bir qismini kattalashtirish"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Endi siz ekranni toʻliq yoki bir qismini kattalashtirishingiz yoki bu parametrlar orasida almashtirishingiz mumkin."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Sozlamalar orqali yoqish"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Yopish"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Davom etish uchun &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; mikrofoningizdan foydalanishi kerak."</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Sensorlar maxfiyligi"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Ilova belgisi"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Ilova brendining rasmi"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Kirish sozlamalarini tekshiring"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> ekraningizni koʻrishi va boshqarishi mumkin. Tekshirish uchun bosing."</string>
 </resources>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 11644d6..421e1e7 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Dịch vụ Twilight"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Trình phát hiện múi giờ (Không có kết nối)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"Dịch vụ cập nhật thời gian GNSS"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Dịch vụ quản lý tính năng nhận dạng nhạc"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Thiết bị của bạn sẽ bị xóa"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Không thể sử dụng ứng dụng quản trị. Thiết bị của bạn sẽ bị xóa ngay bây giờ.\n\nHãy liên hệ với quản trị viên của tổ chức nếu bạn có thắc mắc."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> đã tắt tính năng in."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Ứng dụng đang chạy"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Các ứng dụng tiêu thụ pin"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Phóng to"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Chính sách bảo mật của tính năng Hỗ trợ tiếp cận"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> đang sử dụng pin"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> ứng dụng đang sử dụng pin"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Nhấn để biết chi tiết về mức sử dụng dữ liệu và pin"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Cho phép ứng dụng trở thành thanh trạng thái."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"mở rộng/thu gọn thanh trạng thái"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Cho phép ứng dụng mở rộng hoặc thu gọn thanh trạng thái."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"hiển thị thông báo dưới dạng các hoạt động ở chế độ toàn màn hình trên thiết bị ở trạng thái khóa"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Cho phép ứng dụng hiển thị thông báo dưới dạng các hoạt động ở chế độ toàn màn hình trên thiết bị ở trạng thái khóa"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"cài đặt lối tắt"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Cho phép ứng dụng thêm lối tắt trên Màn hình chính mà không cần sự can thiệp của người dùng."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"gỡ cài đặt lối tắt"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Dùng dữ liệu sinh trắc học hoặc phương thức khóa màn hình"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Xác minh danh tính của bạn"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Dùng dữ liệu sinh trắc học của bạn để tiếp tục"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Dùng dữ liệu sinh trắc học của bạn hoặc phương thức khóa màn hình để tiếp tục"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Không có phần cứng sinh trắc học"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Đã hủy xác thực"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Không nhận dạng được"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Dùng vân tay"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Dùng vân tay hoặc phương thức khóa màn hình"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Sử dụng dấu vân tay của bạn để tiếp tục"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Dùng vân tay của bạn hoặc phương thức khóa màn hình để tiếp tục"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Biểu tượng vân tay"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Dùng tính năng mở khóa bằng khuôn mặt"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Dùng khuôn mặt hoặc phương thức khóa màn hình"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Dùng tính năng mở khóa bằng khuôn mặt để tiếp tục"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Dùng khuôn mặt của bạn hoặc phương thức khóa màn hình để tiếp tục"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Biểu tượng khuôn mặt"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"Bạn không được phép mở trang này."</string>
     <string name="text_copied" msgid="2531420577879738860">"Đã sao chép văn bản vào bảng nhớ tạm thời."</string>
     <string name="copied" msgid="4675902854553014676">"Đã sao chép"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> đã dán dữ liệu từ <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> đã dán dữ liệu từ bảng nhớ tạm"</string>
     <string name="more_item_label" msgid="7419249600215749115">"Thêm"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Trình đơn+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Tắt"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Đang kiểm tra <xliff:g id="NAME">%s</xliff:g>…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Đang xem lại nội dung hiện tại"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Đang phân tích dung lượng nội dung nghe nhìn"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"<xliff:g id="NAME">%s</xliff:g> mới"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> không hoạt động"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Hãy nhấn để thiết lập"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Chọn để thiết lập"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Bạn có thể phải định dạng lại thiết bị. Nhấn để ngắt kết nối."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"Để chuyển ảnh và phương tiện"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Duyệt xem các tệp nội dung nghe nhìn"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Vấn đề với <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> không hoạt động"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Hãy nhấn để sửa"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"<xliff:g id="NAME">%s</xliff:g> không được hỗ trợ"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> không hoạt động"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"Thiết bị này không hỗ trợ <xliff:g id="NAME">%s</xliff:g> này. Nhấn để thiết lập ở định dạng được hỗ trợ."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"Thiết bị này không hỗ trợ <xliff:g id="NAME">%s</xliff:g> này. Chọn để thiết lập ở định dạng được hỗ trợ."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Chọn để thiết lập <xliff:g id="NAME">%s</xliff:g> ở một định dạng được hỗ trợ."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Bạn có thể phải định dạng lại thiết bị"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"Đã tháo đột ngột <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Hãy ngắt kết nối phương tiện trước khi tháo để tránh mất nội dung"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Sử dụng phím tắt"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Đảo màu"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Chỉnh màu"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Giảm độ sáng"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Giảm độ sáng hơn nữa"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Bạn đã giữ các phím âm lượng. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> đã bật."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Bạn đã giữ các phím âm lượng. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> đã tắt."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Nhấn và giữ đồng thời cả hai phím âm lượng trong 3 giây để sử dụng <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -2072,7 +2084,7 @@
       <item quantity="other"><xliff:g id="FILE_NAME_2">%s</xliff:g> + <xliff:g id="COUNT_3">%d</xliff:g> tệp</item>
       <item quantity="one"><xliff:g id="FILE_NAME_0">%s</xliff:g> + <xliff:g id="COUNT_1">%d</xliff:g> tệp</item>
     </plurals>
-    <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Không có gợi ý về người để chia sẻ"</string>
+    <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Không có gợi ý nào về người mà bạn có thể chia sẻ"</string>
     <string name="chooser_all_apps_button_label" msgid="3230427756238666328">"Danh sách ứng dụng"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"Ứng dụng này chưa được cấp quyền ghi âm nhưng vẫn có thể ghi âm thông qua thiết bị USB này."</string>
     <string name="accessibility_system_action_home_label" msgid="3234748160850301870">"Màn hình chính"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Phím tắt hỗ trợ tiếp cận trên màn hình"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Bộ chọn phím tắt hỗ trợ tiếp cận trên màn hình"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Phím tắt hỗ trợ tiếp cận"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Đóng Ngăn thông báo"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Thanh phụ đề của <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Đã đưa <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> vào bộ chứa BỊ HẠN CHẾ"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Tính năng mới: Phóng to cửa sổ"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Giờ đây, bạn có thể phóng to một phần hoặc toàn màn hình"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Phóng to một phần màn hình"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Giờ đây, bạn có thể phóng to toàn màn hình, một vùng cụ thể hoặc chuyển đổi giữa hai tùy chọn."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Bật trong phần Cài đặt"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Đóng"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Để tiếp tục, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; cần quyền truy cập vào micrô trên thiết bị của bạn."</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Quyền riêng tư khi sử dụng cảm biến"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Biểu tượng ứng dụng"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Hình ảnh thương hiệu của ứng dụng"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Kiểm tra chế độ cài đặt quyền truy cập"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> có thể xem và điều khiển màn hình của bạn. Nhấn để xem lại."</string>
 </resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index ec455bc..d7c64e2 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Twilight 服务"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"时区检测器(无网络连接)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS 时间更新服务"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"音乐识别管理器服务"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"系统将清空您的设备"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"无法使用管理应用,系统现在将清空您的设备。\n\n如有疑问,请与您所在单位的管理员联系。"</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"“<xliff:g id="OWNER_APP">%s</xliff:g>”已停用打印功能。"</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"应用正在运行中"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"消耗电量的应用"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"放大功能"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"无障碍服务安全政策"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g>正在消耗电量"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> 个应用正在消耗电量"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"点按即可详细了解电量和流量消耗情况"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"允许以状态栏形式显示应用。"</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"展开/收拢状态栏"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"允许应用展开或收起状态栏。"</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"在锁定的设备上以全屏活动的形式显示通知"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"允许该应用在锁定的设备上以全屏活动的形式显示通知"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"安装快捷方式"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"允许应用自行添加主屏幕快捷方式。"</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"卸载快捷方式"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"使用生物识别或屏幕锁定凭据"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"验证是您本人在操作"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"使用生物识别验证身份才能继续"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"使用生物识别或屏幕锁定凭据验证身份,才能继续操作"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"生物识别硬件无法使用"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"身份验证已取消"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"无法识别"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"使用指纹"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"使用指纹或屏幕锁定凭据"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"使用指纹完成验证才能继续"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"使用指纹解锁或屏幕锁定凭据验证身份,才能继续操作"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"指纹图标"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"使用人脸解锁"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"使用人脸解锁或屏幕锁定凭据"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"使用人脸解锁验证身份才能继续"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"使用人脸解锁或屏幕锁定凭据验证身份,才能继续操作"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"面孔图标"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"您无权打开此网页。"</string>
     <string name="text_copied" msgid="2531420577879738860">"文本已复制到剪贴板。"</string>
     <string name="copied" msgid="4675902854553014676">"已复制"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>已粘贴从<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>复制的内容"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>已粘贴剪贴板中的内容"</string>
     <string name="more_item_label" msgid="7419249600215749115">"更多"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"MENU+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"关闭"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"正在检查<xliff:g id="NAME">%s</xliff:g>…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"正在检查当前内容"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"正在分析媒体存储空间"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"新的<xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g>无法使用"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"点按即可进行设置"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"选择即可设置"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"您可能需要重新格式化设备。点按即可弹出。"</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"可用于传输照片和媒体文件"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"浏览媒体文件"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"<xliff:g id="NAME">%s</xliff:g>出现问题"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g>无法使用"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"点按即可修正问题"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"<xliff:g id="NAME">%s</xliff:g>不受支持"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g>无法使用"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"该设备不支持此<xliff:g id="NAME">%s</xliff:g>。点按即可使用支持的格式进行设置。"</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"此设备不支持该<xliff:g id="NAME">%s</xliff:g>。选择即可使用支持的格式进行设置。"</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"选择即可使用支持的格式设置<xliff:g id="NAME">%s</xliff:g>。"</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"您可能需要重新格式化设备"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g>已意外移除"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"请先弹出媒体,再将其移除,以防内容丢失"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"使用快捷方式"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"颜色反转"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"色彩校正"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"调低亮度"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"超暗"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"已按住音量键。<xliff:g id="SERVICE_NAME">%1$s</xliff:g>已开启。"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"已按住音量键。<xliff:g id="SERVICE_NAME">%1$s</xliff:g>已关闭。"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"同时按住两个音量键 3 秒钟即可使用 <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"屏幕上的无障碍功能快捷方式"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"屏幕上的无障碍功能快捷方式选择器"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"无障碍功能快捷方式"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"关闭通知栏"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<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> 已被放入受限存储分区"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"新功能:窗口放大镜"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"您现在可以放大屏幕上的部分或所有内容"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"放大局部屏幕"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"现在,您可以放大整个屏幕或特定区域,也可以在这两个选项之间切换。"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"在“设置”中开启"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"关闭"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"如要继续操作,请向&lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt;授予设备的麦克风使用权。"</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"传感器隐私权"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"应用图标"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"应用品牌图片"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"查看权限设置"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g>可以查看和控制您的屏幕。点按即可查看。"</string>
 </resources>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 16b9b0f..bc89bed 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"暮光服務"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"時區偵測器 (沒有連線)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS 時間更新服務"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"音樂識別管理員服務"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"您的裝置將被清除"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"無法使用管理員應用程式。系統會現在清除您的裝置。\n\n如有任何疑問,請聯絡您的機構管理員。"</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"「<xliff:g id="OWNER_APP">%s</xliff:g>」暫停了列印。"</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"應用程式正在執行"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"耗用電量的應用程式"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"放大"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"無障礙工具安全性政策"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在使用電量"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> 個應用程式正在使用電量"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"輕按即可查看電池和數據用量詳情"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"允許應用程式以狀態列顯示。"</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"展開/收合狀態列"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"允許應用程式展開或收合狀態列。"</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"在已上鎖的裝置上以全螢幕活動形式顯示通知"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"允許應用程式在已上鎖的裝置上以全螢幕活動形式顯示通知"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"安裝捷徑"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"允許應用程式繞過使用者授權直接新增主畫面捷徑。"</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"解除安裝捷徑"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"使用生物識別或螢幕鎖定"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"驗證是你本人"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"如要繼續操作,請使用使用生物識別驗證身分"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"請使用生物識別或螢幕鎖定功能驗證身分,才能繼續操作"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"無法使用生物識別硬件"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"已取消驗證"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"未能識別"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"使用指紋鎖定"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"使用指紋或螢幕鎖定"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"請使用您的指紋繼續"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"請使用指紋解鎖或螢幕鎖定功能驗證身分,才能繼續操作"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"指紋圖示"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"使用臉孔解鎖"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"使用臉孔或螢幕鎖定"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"如要繼續操作,請使用臉孔解鎖驗證身分"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"請使用臉孔解鎖或螢幕鎖定功能驗證身分,才能繼續操作"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"臉孔圖示"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"您沒有開啟這個頁面的權限。"</string>
     <string name="text_copied" msgid="2531420577879738860">"文字已複製到剪貼簿。"</string>
     <string name="copied" msgid="4675902854553014676">"已複製"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> 已貼上從 <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> 複製的資料"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> 已貼上剪貼簿中的資料"</string>
     <string name="more_item_label" msgid="7419249600215749115">"更多"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"選單鍵 +"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta +"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"關閉"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"正在檢查 <xliff:g id="NAME">%s</xliff:g>…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"正在檢查目前的內容"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"正在分析媒體儲存空間"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"新 <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"「<xliff:g id="NAME">%s</xliff:g>」無法運作"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"輕按即可設定"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"選取即可設定"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"您可能需要將裝置重新格式化。輕按即可退出。"</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"用於轉移相片和媒體"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"瀏覽媒體檔案"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"<xliff:g id="NAME">%s</xliff:g>發生問題"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"「<xliff:g id="NAME">%s</xliff:g>」無法運作"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"輕按即可修正問題"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"不支援的 <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"「<xliff:g id="NAME">%s</xliff:g>」無法運作"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"此裝置並不支援此 <xliff:g id="NAME">%s</xliff:g>。輕按即可在支援的格式設定。"</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"這部裝置不支援此 <xliff:g id="NAME">%s</xliff:g>。選取即可使用支援的格式設定。"</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"選取即可使用支援的格式設定 <xliff:g id="NAME">%s</xliff:g>。"</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"您可能需要將裝置重新格式化"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g>被意外移除"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"請先退出媒體,再將其移除,以免內容遺失。"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"使用快速鍵"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"色彩反轉"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"色彩校正"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"調低亮度"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"超暗"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"已按住音量鍵。<xliff:g id="SERVICE_NAME">%1$s</xliff:g> 已開啟。"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"已按住音量鍵。<xliff:g id="SERVICE_NAME">%1$s</xliff:g> 已關閉。"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"㩒住兩個音量鍵 3 秒就可以用 <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"螢幕無障礙功能捷徑"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"螢幕無障礙功能捷徑選擇器"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"無障礙功能捷徑"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"關閉通知欄"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"「<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> 已納入受限制的儲存區"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"新功能:視窗放大鏡"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"您現在可以放大部分或整個畫面"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"放大部分畫面"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"您現在可放大整個或局部畫面,亦可切換這兩種模式。"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"在「設定」中開啟"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"關閉"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"如要繼續,&lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; 需要裝置的麥克風存取權。"</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"感應器私隱"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"應用程式圖示"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"應用程式品牌形象"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"檢查存取權設定"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> 可以查看及控制您的螢幕。輕按即可查看。"</string>
 </resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 90fe15d..f728be8 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Twilight 服務"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"時區偵測器 (不必連上網路)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS 時間更新服務"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"音樂辨識管理員服務"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"你的裝置資料將遭到清除"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"無法使用管理應用程式,系統現在將清除你裝置中的資料。\n\n如有任何問題,請與貴機構的管理員聯絡。"</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"「<xliff:g id="OWNER_APP">%s</xliff:g>」已停用列印功能。"</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"應用程式執行中"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"正在耗用電量的應用程式"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"放大"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"無障礙工具安全性政策"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在耗用電量"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> 個應用程式正在耗用電量"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"輕觸即可查看電池和數據用量詳情"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"允許應用程式以狀態列顯示。"</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"展開/收攏狀態列"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"允許應用程式展開或收合狀態列。"</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"在已鎖定的裝置上以全螢幕活動的形式顯示通知"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"允許應用程式在已鎖定的裝置上以全螢幕活動的形式顯示通知"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"安裝捷徑"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"允許應用程式自動新增主螢幕捷徑。"</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"解除安裝捷徑"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"使用生物特徵辨識或螢幕鎖定功能"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"驗證你的身分"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"如要繼續操作,請使用生物特徵辨識功能驗證身分"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"請使用生物特徵辨識或螢幕鎖定功能驗證身分,才能繼續操作"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"無法使用生物特徵辨識硬體"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"已取消驗證"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"無法辨識"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"使用指紋"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"使用指紋或螢幕鎖定功能"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"使用指紋完成驗證才能繼續操作"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"請使用指紋解鎖或螢幕鎖定功能驗證身分,才能繼續操作"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"指紋圖示"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"使用人臉解鎖功能"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"使用人臉解鎖或螢幕鎖定功能"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"如要繼續操作,請使用人臉解鎖功能驗證身分"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"請使用人臉解鎖或螢幕鎖定功能驗證身分,才能繼續操作"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"臉孔圖示"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"你沒有開啟這個頁面的權限。"</string>
     <string name="text_copied" msgid="2531420577879738860">"文字已複製到剪貼簿。"</string>
     <string name="copied" msgid="4675902854553014676">"已複製"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"「<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>」已貼上從「<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>」複製的資料"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"「<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>」已貼上剪貼簿中的資料"</string>
     <string name="more_item_label" msgid="7419249600215749115">"更多"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"[Menu] +"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta +"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"關閉"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"正在檢查 <xliff:g id="NAME">%s</xliff:g>…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"正在檢查目前的內容"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"正在分析媒體儲存空間"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"新的 <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"「<xliff:g id="NAME">%s</xliff:g>」無法運作"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"輕觸即可進行設定"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"選取即可設定"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"你可能要將裝置重新格式化。輕觸即可退出裝置。"</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"可用於傳輸相片和媒體"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"瀏覽媒體檔案"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"<xliff:g id="NAME">%s</xliff:g>發生問題"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"「<xliff:g id="NAME">%s</xliff:g>」無法運作"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"輕觸即可修正問題"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"不支援的「<xliff:g id="NAME">%s</xliff:g>」"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"「<xliff:g id="NAME">%s</xliff:g>」無法運作"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"此裝置不支援這個 <xliff:g id="NAME">%s</xliff:g>。輕觸即可使用支援的格式進行設定。"</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"此裝置不支援這個 <xliff:g id="NAME">%s</xliff:g>。選取即可使用支援的格式進行設定。"</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"選取即可使用支援的格式設定「<xliff:g id="NAME">%s</xliff:g>」。"</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"你可能要將裝置重新格式化"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"意外移除「<xliff:g id="NAME">%s</xliff:g>」"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"請先退出媒體,再將其移除,以免內容遺失"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"使用捷徑"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"色彩反轉"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"色彩校正"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"調低亮度"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"超暗"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"已按住音量鍵。「<xliff:g id="SERVICE_NAME">%1$s</xliff:g>」已開啟。"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"已按住音量鍵。「<xliff:g id="SERVICE_NAME">%1$s</xliff:g>」已關閉。"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"同時按住調低及調高音量鍵三秒即可使用「<xliff:g id="SERVICE_NAME">%1$s</xliff:g>」"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"螢幕上的無障礙捷徑"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"螢幕上的無障礙捷徑選擇器"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"無障礙捷徑"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"關閉通知欄"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"「<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>」移入受限制的值區"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"新功能:視窗放大鏡"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"你可以放大局部或整個畫面"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"放大局部螢幕畫面"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"你現在可以放大整個或局部螢幕畫面,也可以隨時切換這兩種模式。"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"在「設定」中開啟"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"關閉"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"如要繼續操作,請將裝置的麥克風存取權授予「<xliff:g id="APP">%s</xliff:g>」&lt;b&gt;&lt;/b&gt;。"</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"感應器隱私權"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"應用程式圖示"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"應用程式品牌圖片"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"查看存取權設定"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"「<xliff:g id="SERVICE_NAME">%s</xliff:g>」可以查看及控管你的螢幕。輕觸即可查看。"</string>
 </resources>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 1089f1e..dc15edc 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -204,6 +204,7 @@
     <string name="twilight_service" msgid="8964898045693187224">"Isevisi Yangovivi"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Isitholi Sezoni Yesikhathi (Akukho ukuxhumana)"</string>
     <string name="gnss_time_update_service" msgid="9039489496037616095">"Isevisi Ebuyekeziwe Yesikhathi se-GNSS"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Isevisi Yomphathi Wokuthola Umculo"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Idivayisi yakho izosulwa"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Uhlelo lokusebenza lomlawuli alikwazi ukusetshenziswa. Idivayisi yakho manje izosuswa.\n\nUma unemibuzo, xhumana nomlawuli wezinhlangano zakho."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Ukuphrinta kukhutshazwe nge-<xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -293,6 +294,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Uhlelo loksuebenza olusebenzayo"</string>
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Izinhlelo zokusebenza ezidla ibhethri"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Ukukhuliswa"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="3350443906017624270">"Inqubomgomo yokuvikeleka kokufinyeleleka"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> isebenzisa ibhethri"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> izinhlelo zokusebenza zisebenzisa ibhethri"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Thepha ngemininingwane ekusetshenzisweni kwebhethri nedatha"</string>
@@ -343,6 +345,8 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Ivumela uhlelo lokusebenza ukuthi lube umudwa ochaza ngesimo."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"khulisa/nciphisa ibha yomumo"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Ivumela uhlelo lokusebenza ukuthi ikhulise noma inciphise umudwa ochza ngesimo."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"bonisa izaziso njengemisebenzi yesikrini esigcwele kudivayisi evaliwe"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Kuvumela i-app ukuthi ibonise izaziso njengemisebenzi yesikrini esigcwele kudivayisi evaliwe"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"faka izinqamuleli"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Ivumela uhlelo lokusebenza ukwengeza izinqamuleli ngaphandle kokungenela komsebenzisi."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"khipha izinqamuleli"</string>
@@ -554,6 +558,7 @@
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Sebenzisa i-biometrics noma ukukhiya isikrini"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Qinisekisa ukuthi nguwe"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Sebenzisa i-biometric yakho ukuze uqhubeke"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Sebenzisa i-biometric noma ukukhiya isikrini ukuze uqhubeke"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"I-Biometric hardware ayitholakali"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Ukufakazela ubuqiniso kukhanseliwe"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Akwaziwa"</string>
@@ -587,6 +592,7 @@
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Sebenzisa izigxivizo zeminwe"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Sebenzisa izigxivizo zeminwe noma ukukhiya isikrini"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Sebenzisa izigxivizo zakho zeminwe ukuze uqhubeke"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Sebenzisa izigxivizo zakho zomunwe noma ukukhiya isikrini ukuze uqhubeke"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Isithonjana sezigxivizo zeminwe"</string>
@@ -634,6 +640,7 @@
     <string name="face_app_setting_name" msgid="8130135875458467243">"Sebenzisa i-face unlock"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Sebenzisa i-face lock noma ukukhiya isikrini"</string>
     <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Sebenzisa i-face unlock ukuze uqhubeke"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Sebenzisa ubuso bakho noma ukukhiya isikrini ukuze uqhubeke"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="465030547475916280">"Isithonjana sobuso"</string>
@@ -997,6 +1004,8 @@
     <string name="open_permission_deny" msgid="5136793905306987251">"Awunayo imvume yokuvula leli khasi."</string>
     <string name="text_copied" msgid="2531420577879738860">"Umbhalo ukopishwe ebhodini lokunamathisela."</string>
     <string name="copied" msgid="4675902854553014676">"Kukopishiwe"</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"I-<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> inamathiselwe kusuka ku-<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
+    <string name="pasted_from_clipboard" msgid="6295556725844421812">"I-<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> inamathiselwe kusuka ebhodini yokunamathisela"</string>
     <string name="more_item_label" msgid="7419249600215749115">"Okuningi"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Imenyu+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1370,11 +1379,14 @@
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Vala"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Iyahlola <xliff:g id="NAME">%s</xliff:g>…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Ukubuyekeza okuqukethwe kwamanje"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Ihlaziya isitoreji semidiya"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Okusha <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"I-<xliff:g id="NAME">%s</xliff:g> ayisebenzi"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Thepha ukuze usethe"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Khetha ukuze usethe"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Kungase kudingeke ukuthi ufomethe kabusha idivayisi. Thepha ukuze ukhiphe."</string>
     <string name="ext_media_ready_notification_message" msgid="777258143284919261">"Ukuze kudluliselwe izithombe nemidiya"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Phequlula amafayela wemidiya"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Inkinga ngo-<xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"I-<xliff:g id="NAME">%s</xliff:g> ayisebenzi"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Thepha ukuze ulungise"</string>
@@ -1383,7 +1395,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"Akusekelwe <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"I-<xliff:g id="NAME">%s</xliff:g> ayisebenzi"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"Le divayisi ayisekeli le <xliff:g id="NAME">%s</xliff:g>. Thepha ukuze usethe ngefomethi esekelwayo."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"Le divayisi ayisekeli le <xliff:g id="NAME">%s</xliff:g>. Khetha ukuze usethe ngefomethi esekelwayo."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Khetha ukusetha i-<xliff:g id="NAME">%s</xliff:g> ngefomethi esekelwayo."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Kungase kudingeke ukuthi ufomethe kabusha idivayisi"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"I-<xliff:g id="NAME">%s</xliff:g> isuswe ngokungalindelekile"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Khipha imidiya ngaphambi kokususa ukuze ugweme ukulahlekelwa okuqukethwe"</string>
@@ -1677,7 +1689,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Sebenzisa isinqamuleli"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Ukuguqulwa kombala"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Ukulungiswa kombala"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Nciphisa ukukhanya"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Ukufiphaza okwengeziwe"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Ubambe okhiye bevolumu. I-<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ivuliwe."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Ubambe okhiye bevolumu. I-<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ivaliwe."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Cindezela uphinde ubambe bobabili okhiye bevolumu ngamasekhondi amathathu ukuze usebenzise i-<xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -2086,6 +2098,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Isinqamuleli sokufinyeleleka kusikrini"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Isikhethi sesinqamuleli sokufinyeleleka kusikrini"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Isinqamuleli sokufinyeleleka"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Cashisa Umthunzi Wesaziso"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Ibha yamazwibela we-<xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"I-<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> ifakwe kubhakede LOKUKHAWULELWE"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2223,8 +2236,8 @@
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="8197528399699536320">"Okusha: Isikhulisi sewindi"</string>
-    <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Manje usungakwazi ukukhulisa esinye noma sonke isikrini sakho"</string>
+    <string name="window_magnification_prompt_title" msgid="4657040468055863672">"Khulisa ingxenye yesikrini sakho"</string>
+    <string name="window_magnification_prompt_content" msgid="3549230303326142349">"Manje usungakwazi ukukhulisa isikrini sakho esigcwele, indawo ethile, noma ushintshe phakathi kwazo zombili izinketho."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Vula Kumasethingi"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Cashisa"</string>
     <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Ukuze uqhubeke, &lt;b&gt;‎‏‎‎‏‏‎i-<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; idinga ukufinyelela imakrofoni yedivayisi yakho."</string>
@@ -2233,4 +2246,6 @@
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Ubumfihlo Benzwa"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Isithonjana sohlelo lokusebenza"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Isithombe sokubhrenda i-application"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Hlola amasethingi wokufinyelela"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"I-<xliff:g id="SERVICE_NAME">%s</xliff:g> ingakwazi ukubuka nokulawula isikrini sakho. Thepha ukuze ubuyekeze."</string>
 </resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 5e95f94..eea3799 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -1125,6 +1125,15 @@
              to framework controls (via colorControlActivated). -->
         <attr name="colorAccent" format="color" />
 
+        <!-- Light accent color used on Material NEXT buttons. @hide -->
+        <attr name="colorAccentPrimary" format="color" />
+
+        <!-- Secondary accent color used on Material NEXT buttons. @hide -->
+        <attr name="colorAccentSecondary" format="color" />
+
+        <!-- Tertiary accent color used on Material NEXT buttons. @hide -->
+        <attr name="colorAccentTertiary" format="color" />
+
         <!-- The color applied to framework controls in their normal state. -->
         <attr name="colorControlNormal" format="color" />
 
@@ -6061,6 +6070,8 @@
         <attr name="color" />
         <!-- Alpha multiplier applied to the base color. -->
         <attr name="alpha" />
+        <!-- Perceptual luminance applied to the base color. From 0 to 100. -->
+        <attr name="lStar" format="float" />
     </declare-styleable>
 
     <!-- Drawable used to render according to the animation scale. Esp. when it is 0 due to battery
@@ -9526,4 +9537,12 @@
 
     <attr name="iconfactoryIconSize" format="dimension"/>
     <attr name="iconfactoryBadgeSize" format="dimension"/>
+    <!-- Perceptual luminance of a color, in accessibility friendly color space. From 0 to 100. -->
+    <attr name="lStar" format="float"/>
+
+    <declare-styleable name="DisplayHasherService">
+        <!-- The throttle duration for display hash requests
+             @hide @SystemApi -->
+        <attr name="throttleDurationMillis" format="integer" />
+    </declare-styleable>
 </resources>
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 0318be7..986bb82 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -1595,6 +1595,20 @@
        <enum name="always" value="1" />
     </attr>
 
+    <!-- Enable hardware memory tagging (ARM MTE) in this process.
+         When enabled, heap memory bugs like use-after-free and buffer overlow
+         are detected and result in an immediate ("sync" mode) or delayed ("async"
+         mode) crash instead of a silent memory corruption. Sync mode, while slower,
+         provides enhanced bug reports including stack traces at the time of allocation
+         and deallocation of memory, similar to AddressSanitizer.
+
+         See the <a href="https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/enhancing-memory-safety">ARM announcement</a>
+         for more details.
+
+         <p>This attribute can be applied to a
+         {@link android.R.styleable#AndroidManifestProcess process} tag, or to an
+         {@link android.R.styleable#AndroidManifestApplication application} tag (to supply
+         a default setting for all application components). -->
     <attr name="memtagMode">
        <enum name="default" value="-1" />
        <enum name="off" value="0" />
@@ -1853,6 +1867,25 @@
              -->
         <attr name="preserveLegacyExternalStorage" format="boolean" />
 
+        <!-- If {@code true} this app would like optimized external storage access.
+
+        <p> This flag can only be used by apps holding
+        <ul>
+        <li>{@link android.Manifest.permission#MANAGE_EXTERNAL_STORAGE} permission or
+        <li>{@link android.app.role}#SYSTEM_GALLERY role.
+        </ul>
+        When the flag is set, bulk file path operations will be optimized.
+
+        The default value is {@code true} if
+        <ul>
+        <li>app has {@link android.Manifest.permission#MANAGE_EXTERNAL_STORAGE} permission and
+        targets targetSDK<=30.
+        <li>app has {@link android.app.role}#SYSTEM_GALLERY role and targetSDK<=29
+        </ul>
+        {@code false} otherwise.
+        -->
+        <attr name="requestOptimizedExternalStorageAccess" format="boolean" />
+
         <!-- If {@code true} this app declares that it should be visible to all other apps on
              device, regardless of what they declare via the {@code queries} tags in their
              manifest.
@@ -1879,7 +1912,9 @@
 
         <attr name="memtagMode" />
 
-        <attr name="nativeHeapZeroInit" format="boolean" />
+        <!-- If {@code true} enables automatic zero initialization of all native heap
+             allocations. -->
+        <attr name="nativeHeapZeroInitialized" format="boolean" />
 
         <!-- @hide no longer used, kept to preserve padding -->
         <attr name="allowAutoRevokePermissionsExemption" format="boolean" />
@@ -2063,13 +2098,14 @@
         requested.  If it does support the feature, it will be as if the manifest didn't
         request it at all. -->
         <attr name="requiredNotFeature" format="string" />
-        <!-- Optional: set of flags that should apply to this permission request. -->
+        <!-- Optional: set of flags that should apply to this permission request. Note that
+             these flags start at 0x4 to match PackageInfo.requestedPermissionsFlags. -->
         <attr name="usesPermissionFlags">
             <!-- Strong assertion by a developer that they will never use this
                  permission to derive the physical location of the device, even
                  when the app has been granted the ACCESS_FINE_LOCATION and/or
                  ACCESS_COARSE_LOCATION permissions. -->
-            <flag name="neverForLocation" value="0x1" />
+            <flag name="neverForLocation" value="0x00010000" />
         </attr>
     </declare-styleable>
 
@@ -2466,7 +2502,7 @@
         <attr name="process" />
         <attr name="gwpAsanMode" />
         <attr name="memtagMode" />
-        <attr name="nativeHeapZeroInit" />
+        <attr name="nativeHeapZeroInitialized" />
     </declare-styleable>
 
     <!-- The <code>deny-permission</code> tag specifies that a permission is to be denied
@@ -2842,6 +2878,13 @@
             {@link android.content.Context#sendBroadcast(Intent, String)} being used.
             Multiple tags can be specified separated by '|'. -->
         <attr name="attributionTags"/>
+        <!-- Specifies whether a home sound effect should be played if the home app moves to
+             front after an activity with this flag set to <code>true</code>.
+             <p>The default value of this attribute is <code>true</code>.
+             <p>Also note that home sounds are only played if the device supports home sounds,
+             usually TVs.
+             <p>Requires permission {@code android.permission.DISABLE_SYSTEM_SOUND_EFFECTS}. -->
+        <attr name="playHomeTransitionSound" format="boolean"/>
     </declare-styleable>
 
     <!-- The <code>activity-alias</code> tag declares a new
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index 22467e4..0213c60 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -237,121 +237,194 @@
     <color name="resolver_text_color_secondary_dark">#ffC4C6C6</color>
     <color name="resolver_empty_state_text">#FF202124</color>
     <color name="resolver_empty_state_icon">#FF5F6368</color>
-    <color name="chooser_chip_icon">#FF1A73E8</color> <!-- Blue 600 -->
 
     <!-- Color for personal app suspension notification button text and icon tint. -->
     <color name="personal_apps_suspension_notification_color">#1A73E8</color>
 
     <color name="conversation_important_highlight">#F9AB00</color>
 
-    <!-- Lightest shade of the primary color used by the system. White.
+    <!-- Lightest shade of the accent color used by the system. White.
      This value can be overlaid at runtime by OverlayManager RROs. -->
-    <color name="system_primary_0">#ffffff</color>
-    <!-- Shade of the primary system color at 95% lightness.
+    <color name="system_accent1_0">#ffffff</color>
+    <!-- Shade of the accent system color at 95% lightness.
      This value can be overlaid at runtime by OverlayManager RROs. -->
-    <color name="system_primary_50">#f2f2f2</color>
-    <!-- Shade of the primary system color at 90% lightness.
+    <color name="system_accent1_50">#9CFFF2</color>
+    <!-- Shade of the accent system color at 90% lightness.
      This value can be overlaid at runtime by OverlayManager RROs. -->
-    <color name="system_primary_100">#e3e3e3</color>
-    <!-- Shade of the primary system color at 80% lightness.
+    <color name="system_accent1_100">#8DF5E3</color>
+    <!-- Shade of the accent system color at 80% lightness.
      This value can be overlaid at runtime by OverlayManager RROs. -->
-    <color name="system_primary_200">#c7c7c7</color>
-    <!-- Shade of the primary system color at 70% lightness.
+    <color name="system_accent1_200">#71D8C7</color>
+    <!-- Shade of the accent system color at 70% lightness.
      This value can be overlaid at runtime by OverlayManager RROs. -->
-    <color name="system_primary_300">#ababab</color>
-    <!-- Shade of the primary system color at 60% lightness.
+    <color name="system_accent1_300">#53BCAC</color>
+    <!-- Shade of the accent system color at 60% lightness.
      This value can be overlaid at runtime by OverlayManager RROs. -->
-    <color name="system_primary_400">#8f8f8f</color>
-    <!-- Shade of the primary system color at 50% lightness.
+    <color name="system_accent1_400">#34A192</color>
+    <!-- Shade of the accent system color at 49% lightness.
      This value can be overlaid at runtime by OverlayManager RROs. -->
-    <color name="system_primary_500">#757575</color>
-    <!-- Shade of the primary system color at 40% lightness.
+    <color name="system_accent1_500">#008375</color>
+    <!-- Shade of the accent system color at 40% lightness.
      This value can be overlaid at runtime by OverlayManager RROs. -->
-    <color name="system_primary_600">#5e5e5e</color>
-    <!-- Shade of the primary system color at 30% lightness.
+    <color name="system_accent1_600">#006C5F</color>
+    <!-- Shade of the accent system color at 30% lightness.
      This value can be overlaid at runtime by OverlayManager RROs. -->
-    <color name="system_primary_700">#474747</color>
-    <!-- Shade of the primary system color at 20% lightness.
+    <color name="system_accent1_700">#005747</color>
+    <!-- Shade of the accent system color at 20% lightness.
      This value can be overlaid at runtime by OverlayManager RROs. -->
-    <color name="system_primary_800">#303030</color>
-    <!-- Shade of the primary system color at 10% lightness.
+    <color name="system_accent1_800">#003E31</color>
+    <!-- Shade of the accent system color at 10% lightness.
      This value can be overlaid at runtime by OverlayManager RROs. -->
-    <color name="system_primary_900">#1f1f1f</color>
-    <!-- Darkest shade of the primary color used by the system. Black.
+    <color name="system_accent1_900">#002214</color>
+    <!-- Darkest shade of the accent color used by the system. Black.
      This value can be overlaid at runtime by OverlayManager RROs. -->
-    <color name="system_primary_1000">#000000</color>
+    <color name="system_accent1_1000">#000000</color>
 
-    <!-- Lightest shade of the secondary color used by the system. White.
+    <!-- Lightest shade of the secondary accent color used by the system. White.
      This value can be overlaid at runtime by OverlayManager RROs. -->
-    <color name="system_secondary_0">#ffffff</color>
-    <!-- Shade of the secondary system color at 95% lightness.
+    <color name="system_accent2_0">#ffffff</color>
+    <!-- Shade of the secondary accent system color at 95% lightness.
      This value can be overlaid at runtime by OverlayManager RROs. -->
-    <color name="system_secondary_50">#91fff4</color>
-    <!-- Shade of the secondary system color at 90% lightness.
+    <color name="system_accent2_50">#CDFAF1</color>
+    <!-- Shade of the secondary accent system color at 90% lightness.
      This value can be overlaid at runtime by OverlayManager RROs. -->
-    <color name="system_secondary_100">#83f6e5</color>
-    <!-- Shade of the secondary system color at 80% lightness.
+    <color name="system_accent2_100">#BFEBE3</color>
+    <!-- Shade of the secondary accent system color at 80% lightness.
      This value can be overlaid at runtime by OverlayManager RROs. -->
-    <color name="system_secondary_200">#65d9c9</color>
-    <!-- Shade of the secondary system color at 70% lightness.
+    <color name="system_accent2_200">#A4CFC7</color>
+    <!-- Shade of the secondary accent system color at 70% lightness.
      This value can be overlaid at runtime by OverlayManager RROs. -->
-    <color name="system_secondary_300">#45bdae</color>
-    <!-- Shade of the secondary system color at 60% lightness.
+    <color name="system_accent2_300">#89B4AC</color>
+    <!-- Shade of the secondary accent system color at 60% lightness.
      This value can be overlaid at runtime by OverlayManager RROs. -->
-    <color name="system_secondary_400">#1fa293</color>
-    <!-- Shade of the secondary system color at 50% lightness.
+    <color name="system_accent2_400">#6F9991</color>
+    <!-- Shade of the secondary accent system color at 49% lightness.
      This value can be overlaid at runtime by OverlayManager RROs. -->
-    <color name="system_secondary_500">#008377</color>
-    <!-- Shade of the secondary system color at 40% lightness.
+    <color name="system_accent2_500">#537C75</color>
+    <!-- Shade of the secondary accent system color at 40% lightness.
      This value can be overlaid at runtime by OverlayManager RROs. -->
-    <color name="system_secondary_600">#006d61</color>
-    <!-- Shade of the secondary system color at 30% lightness.
+    <color name="system_accent2_600">#3D665F</color>
+    <!-- Shade of the secondary accent system color at 30% lightness.
      This value can be overlaid at runtime by OverlayManager RROs. -->
-    <color name="system_secondary_700">#005449</color>
-    <!-- Shade of the secondary system color at 20% lightness.
+    <color name="system_accent2_700">#254E47</color>
+    <!-- Shade of the secondary accent system color at 20% lightness.
      This value can be overlaid at runtime by OverlayManager RROs. -->
-    <color name="system_secondary_800">#003c33</color>
-    <!-- Shade of the secondary system color at 10% lightness.
+    <color name="system_accent2_800">#0C3731</color>
+    <!-- Shade of the secondary accent system color at 10% lightness.
      This value can be overlaid at runtime by OverlayManager RROs. -->
-    <color name="system_secondary_900">#00271e</color>
-    <!-- Darkest shade of the secondary color used by the system. Black.
+    <color name="system_accent2_900">#00211C</color>
+    <!-- Darkest shade of the secondary accent color used by the system. Black.
      This value can be overlaid at runtime by OverlayManager RROs. -->
-    <color name="system_secondary_1000">#000000</color>
+    <color name="system_accent2_1000">#000000</color>
+
+    <!-- Lightest shade of the tertiary accent color used by the system. White.
+     This value can be overlaid at runtime by OverlayManager RROs. -->
+    <color name="system_accent3_0">#ffffff</color>
+    <!-- Shade of the tertiary accent system color at 95% lightness.
+     This value can be overlaid at runtime by OverlayManager RROs. -->
+    <color name="system_accent3_50">#F9EAFF</color>
+    <!-- Shade of the tertiary accent system color at 90% lightness.
+     This value can be overlaid at runtime by OverlayManager RROs. -->
+    <color name="system_accent3_100">#ECDBFF</color>
+    <!-- Shade of the tertiary accent system color at 80% lightness.
+     This value can be overlaid at runtime by OverlayManager RROs. -->
+    <color name="system_accent3_200">#CFBFEB</color>
+    <!-- Shade of the tertiary accent system color at 70% lightness.
+     This value can be overlaid at runtime by OverlayManager RROs. -->
+    <color name="system_accent3_300">#B3A4CF</color>
+    <!-- Shade of the tertiary accent system color at 60% lightness.
+     This value can be overlaid at runtime by OverlayManager RROs. -->
+    <color name="system_accent3_400">#988AB3</color>
+    <!-- Shade of the tertiary accent system color at 49% lightness.
+     This value can be overlaid at runtime by OverlayManager RROs. -->
+    <color name="system_accent3_500">#7B6E96</color>
+    <!-- Shade of the tertiary accent system color at 40% lightness.
+     This value can be overlaid at runtime by OverlayManager RROs. -->
+    <color name="system_accent3_600">#64587F</color>
+    <!-- Shade of the tertiary accent system color at 30% lightness.
+     This value can be overlaid at runtime by OverlayManager RROs. -->
+    <color name="system_accent3_700">#4C4165</color>
+    <!-- Shade of the tertiary accent system color at 20% lightness.
+     This value can be overlaid at runtime by OverlayManager RROs. -->
+    <color name="system_accent3_800">#352B4D</color>
+    <!-- Shade of the tertiary accent system color at 10% lightness.
+     This value can be overlaid at runtime by OverlayManager RROs. -->
+    <color name="system_accent3_900">#1E1636</color>
+    <!-- Darkest shade of the tertiary accent color used by the system. Black.
+     This value can be overlaid at runtime by OverlayManager RROs. -->
+    <color name="system_accent3_1000">#000000</color>
 
     <!-- Lightest shade of the neutral color used by the system. White.
      This value can be overlaid at runtime by OverlayManager RROs. -->
-    <color name="system_neutral_0">#ffffff</color>
+    <color name="system_neutral1_0">#ffffff</color>
     <!-- Shade of the neutral system color at 95% lightness.
      This value can be overlaid at runtime by OverlayManager RROs. -->
-    <color name="system_neutral_50">#f0f0f0</color>
+    <color name="system_neutral1_50">#f0f0f0</color>
     <!-- Shade of the neutral system color at 90% lightness.
      This value can be overlaid at runtime by OverlayManager RROs. -->
-    <color name="system_neutral_100">#e2e2e2</color>
+    <color name="system_neutral1_100">#e2e2e2</color>
     <!-- Shade of the neutral system color at 80% lightness.
      This value can be overlaid at runtime by OverlayManager RROs. -->
-    <color name="system_neutral_200">#c6c6c6</color>
+    <color name="system_neutral1_200">#c6c6c6</color>
     <!-- Shade of the neutral system color at 70% lightness.
      This value can be overlaid at runtime by OverlayManager RROs. -->
-    <color name="system_neutral_300">#ababab</color>
+    <color name="system_neutral1_300">#ababab</color>
     <!-- Shade of the neutral system color at 60% lightness.
      This value can be overlaid at runtime by OverlayManager RROs. -->
-    <color name="system_neutral_400">#909090</color>
-    <!-- Shade of the neutral system color at 50% lightness.
+    <color name="system_neutral1_400">#909090</color>
+    <!-- Shade of the neutral system color at 49% lightness.
      This value can be overlaid at runtime by OverlayManager RROs. -->
-    <color name="system_neutral_500">#757575</color>
+    <color name="system_neutral1_500">#757575</color>
     <!-- Shade of the neutral system color at 40% lightness.
      This value can be overlaid at runtime by OverlayManager RROs. -->
-    <color name="system_neutral_600">#5e5e5e</color>
+    <color name="system_neutral1_600">#5e5e5e</color>
     <!-- Shade of the neutral system color at 30% lightness.
      This value can be overlaid at runtime by OverlayManager RROs. -->
-    <color name="system_neutral_700">#464646</color>
+    <color name="system_neutral1_700">#464646</color>
     <!-- Shade of the neutral system color at 20% lightness.
      This value can be overlaid at runtime by OverlayManager RROs. -->
-    <color name="system_neutral_800">#303030</color>
+    <color name="system_neutral1_800">#303030</color>
     <!-- Shade of the neutral system color at 10% lightness.
      This value can be overlaid at runtime by OverlayManager RROs. -->
-    <color name="system_neutral_900">#1b1b1b</color>
+    <color name="system_neutral1_900">#1b1b1b</color>
     <!-- Darkest shade of the neutral color used by the system. Black.
      This value can be overlaid at runtime by OverlayManager RROs. -->
-    <color name="system_neutral_1000">#000000</color>
+    <color name="system_neutral1_1000">#000000</color>
+
+    <!-- Lightest shade of the secondary neutral color used by the system. White.
+     This value can be overlaid at runtime by OverlayManager RROs. -->
+    <color name="system_neutral2_0">#ffffff</color>
+    <!-- Shade of the secondary neutral system color at 95% lightness.
+     This value can be overlaid at runtime by OverlayManager RROs. -->
+    <color name="system_neutral2_50">#f0f0f0</color>
+    <!-- Shade of the secondary neutral system color at 90% lightness.
+     This value can be overlaid at runtime by OverlayManager RROs. -->
+    <color name="system_neutral2_100">#e2e2e2</color>
+    <!-- Shade of the secondary neutral system color at 80% lightness.
+     This value can be overlaid at runtime by OverlayManager RROs. -->
+    <color name="system_neutral2_200">#c6c6c6</color>
+    <!-- Shade of the secondary neutral system color at 70% lightness.
+     This value can be overlaid at runtime by OverlayManager RROs. -->
+    <color name="system_neutral2_300">#ababab</color>
+    <!-- Shade of the secondary neutral system color at 60% lightness.
+     This value can be overlaid at runtime by OverlayManager RROs. -->
+    <color name="system_neutral2_400">#909090</color>
+    <!-- Shade of the secondary neutral system color at 49% lightness.
+     This value can be overlaid at runtime by OverlayManager RROs. -->
+    <color name="system_neutral2_500">#757575</color>
+    <!-- Shade of the secondary neutral system color at 40% lightness.
+     This value can be overlaid at runtime by OverlayManager RROs. -->
+    <color name="system_neutral2_600">#5e5e5e</color>
+    <!-- Shade of the secondary neutral system color at 30% lightness.
+     This value can be overlaid at runtime by OverlayManager RROs. -->
+    <color name="system_neutral2_700">#464646</color>
+    <!-- Shade of the secondary neutral system color at 20% lightness.
+     This value can be overlaid at runtime by OverlayManager RROs. -->
+    <color name="system_neutral2_800">#303030</color>
+    <!-- Shade of the secondary neutral system color at 10% lightness.
+     This value can be overlaid at runtime by OverlayManager RROs. -->
+    <color name="system_neutral2_900">#1b1b1b</color>
+    <!-- Darkest shade of the secondary neutral color used by the system. Black.
+     This value can be overlaid at runtime by OverlayManager RROs. -->
+    <color name="system_neutral2_1000">#000000</color>
 </resources>
diff --git a/core/res/res/values/colors_device_defaults.xml b/core/res/res/values/colors_device_defaults.xml
index 9b56321..0b41769 100644
--- a/core/res/res/values/colors_device_defaults.xml
+++ b/core/res/res/values/colors_device_defaults.xml
@@ -17,9 +17,9 @@
 <!-- Colors specific to DeviceDefault themes. These are mostly pass-throughs to enable
      overlaying new theme colors. -->
 <resources>
-    <color name="primary_device_default_dark">@color/system_primary_800</color>
-    <color name="primary_device_default_light">@color/system_primary_50</color>
-    <color name="primary_device_default_settings">@color/system_primary_800</color>
+    <color name="primary_device_default_dark">@color/system_neutral1_800</color>
+    <color name="primary_device_default_light">@color/system_neutral1_50</color>
+    <color name="primary_device_default_settings">@color/system_neutral1_800</color>
     <color name="primary_device_default_settings_light">@color/primary_device_default_light</color>
     <color name="primary_dark_device_default_dark">@color/primary_device_default_dark</color>
     <color name="primary_dark_device_default_light">@color/primary_device_default_light</color>
@@ -33,14 +33,17 @@
     <color name="tertiary_device_default_settings">@color/tertiary_material_settings</color>
     <color name="quaternary_device_default_settings">@color/quaternary_material_settings</color>
 
-    <color name="accent_device_default_light">@color/system_secondary_600</color>
-    <color name="accent_device_default_dark">@color/system_secondary_200</color>
+    <color name="accent_device_default_light">@color/system_accent1_600</color>
+    <color name="accent_device_default_dark">@color/system_accent1_200</color>
     <color name="accent_device_default">@color/accent_device_default_light</color>
+    <color name="accent_primary_device_default">@color/system_accent1_100</color>
+    <color name="accent_secondary_device_default">@color/system_accent2_100</color>
+    <color name="accent_tertiary_device_default">@color/system_accent3_100</color>
 
-    <color name="background_device_default_dark">@color/system_primary_800</color>
-    <color name="background_device_default_light">@color/system_primary_50</color>
-    <color name="background_floating_device_default_dark">@color/system_primary_900</color>
-    <color name="background_floating_device_default_light">@color/system_primary_100</color>
+    <color name="background_device_default_dark">@color/system_neutral1_800</color>
+    <color name="background_device_default_light">@color/system_neutral1_50</color>
+    <color name="background_floating_device_default_dark">@color/system_neutral1_900</color>
+    <color name="background_floating_device_default_light">@color/system_neutral1_100</color>
 
     <!-- Please refer to text_color_[primary]_device_default_[light].xml for text colors-->
     <color name="foreground_device_default_light">@color/text_color_primary_device_default_light</color>
@@ -50,8 +53,8 @@
     <color name="error_color_device_default_dark">@color/error_color_material_dark</color>
     <color name="error_color_device_default_light">@color/error_color_material_light</color>
 
-    <color name="list_divider_color_light">@color/system_primary_500</color>
-    <color name="list_divider_color_dark">@color/system_primary_400</color>
+    <color name="list_divider_color_light">@color/system_neutral1_200</color>
+    <color name="list_divider_color_dark">@color/system_neutral1_700</color>
     <color name="list_divider_opacity_device_default_light">@android:color/white</color>
     <color name="list_divider_opacity_device_default_dark">@android:color/white</color>
 
diff --git a/core/res/res/values/colors_leanback.xml b/core/res/res/values/colors_leanback.xml
index df0be03..1b0fad8 100644
--- a/core/res/res/values/colors_leanback.xml
+++ b/core/res/res/values/colors_leanback.xml
@@ -16,15 +16,11 @@
 
 <!-- Colors specific to Leanback themes. -->
 <resources>
-    <color name="background_leanback_dark">#ff324248</color>
-    <color name="background_leanback_light">#ffeeeeee</color>
+    <color name="background_leanback_dark">#FF1F232B</color>
 
     <color name="primary_text_leanback_dark">#cceeeeee</color>
     <color name="secondary_text_leanback_dark">#99eeeeee</color>
 
-    <color name="primary_text_leanback_light">#cc222222</color>
-    <color name="secondary_text_leanback_light">#99222222</color>
-
     <color name="primary_text_leanback_formwizard_default_dark">#ffeeeeee</color>
 
     <color name="btn_leanback_focused">#E8EAED</color>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index b0327a5..842f12d 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -951,6 +951,11 @@
     -->
     <integer name="config_longPressOnPowerBehavior">1</integer>
 
+    <!-- Whether the setting to change long press on power behaviour from default to assistant (5)
+         is available in Settings.
+     -->
+    <bool name="config_longPressOnPowerForAssistantSettingAvailable">true</bool>
+
     <!-- Control the behavior when the user long presses the power button for a long time.
             0 - Nothing
             1 - Global actions menu
@@ -3556,10 +3561,6 @@
     <!-- True if assistant app should be pinned via Pinner Service -->
     <bool name="config_pinnerAssistantApp">false</bool>
 
-    <!-- List of files pinned by the Pinner Service with the JIT Zygote boot image b/119800099 -->
-    <string-array translatable="false" name="config_jitzygoteBootImagePinnerServiceFiles">
-    </string-array>
-
     <!-- Number of days preloaded file cache should be preserved on a device before it can be
          deleted -->
     <integer name="config_keepPreloadsMinDays">7</integer>
@@ -3727,6 +3728,13 @@
      -->
     <string name="config_defaultWellbeingPackage" translatable="false"></string>
 
+    <!-- The package name for the companion provider app.
+         This package must be trusted, as it has the permissions to associate apps with devices
+         without a UI prompt.
+         Example: "com.google.android.gms"
+     -->
+    <string name="config_companionProviderPackage" translatable="false"></string>
+
     <!-- The component name for the default system attention service.
          This service must be trusted, as it can be activated without explicit consent of the user.
          See android.attention.AttentionManagerService.
@@ -4575,6 +4583,11 @@
          check after reboot or airplane mode toggling -->
     <bool translatable="false" name="reset_geo_fencing_check_after_boot_or_apm">false</bool>
 
+    <!-- Boolean indicating whether all CB messages should be disabled on this device. This config
+         is intended to be used by OEMs who need to disable CB messages for regulatory requirements,
+         (e.g. the device is a tablet in a country where tablets should not receive CB messages) -->
+    <bool translatable="false" name="config_disable_all_cb_messages">false</bool>
+
     <!-- Screen Wake Keys
          Determines whether the specified key groups can be used to wake up the device. -->
     <bool name="config_wakeOnDpadKeyPress">true</bool>
@@ -4649,6 +4662,10 @@
     <!-- WindowsManager JetPack display features -->
     <string name="config_display_features" translatable="false" />
 
+    <!-- Map of System DeviceState supplied by DeviceStateManager to WM Jetpack posture. Must be in
+         the format [System DeviceState]:[WM Jetpack Posture], for example: "0:1". -->
+    <string-array name="config_device_state_postures" translatable="false" />
+
     <!-- Aspect ratio of letterboxing for fixed orientation. Values <= 1.0 will be ignored.
          Note: Activity min/max aspect ratio restrictions will still be respected.
          Therefore this override can control the maximum screen area that can be occupied by
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 43dbd38..cf5b4e1 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -47,10 +47,6 @@
     <dimen name="status_bar_height_landscape">@dimen/status_bar_height_portrait</dimen>
     <!-- Height of area above QQS where battery/time go -->
     <dimen name="quick_qs_offset_height">48dp</dimen>
-    <!-- Total height of QQS (quick_qs_offset_height + 128) -->
-    <dimen name="quick_qs_total_height">176dp</dimen>
-    <!-- Total height of QQS with two rows to fit media player (quick_qs_offset_height + 176) -->
-    <dimen name="quick_qs_total_height_with_media">224dp</dimen>
     <!-- Height of the bottom navigation / system bar. -->
     <dimen name="navigation_bar_height">48dp</dimen>
     <!-- Height of the bottom navigation bar in portrait; often the same as @dimen/navigation_bar_height -->
@@ -226,9 +222,6 @@
     <!-- The margin on the end of the top-line content views (accommodates the expander) -->
     <dimen name="notification_heading_margin_end">56dp</dimen>
 
-    <!-- The margin for text at the end of the image view for media notifications -->
-    <dimen name="notification_media_image_margin_end">72dp</dimen>
-
     <!-- The height of the notification action list -->
     <dimen name="notification_action_list_height">60dp</dimen>
 
@@ -345,6 +338,9 @@
     <!-- The minimum width of the app name in the header if it shrinks -->
     <dimen name="notification_header_shrink_min_width">72dp</dimen>
 
+    <!-- The minimum width of optional header fields below which the view is simply hidden -->
+    <dimen name="notification_header_shrink_hide_width">24sp</dimen>
+
     <!-- The size of the media actions in the media notification. -->
     <dimen name="media_notification_action_button_size">48dp</dimen>
 
@@ -360,9 +356,6 @@
     <!-- The absolute height for the header in a media notification. -->
     <dimen name="media_notification_header_height">@dimen/notification_header_height</dimen>
 
-    <!-- The margin of the content to an image-->
-    <dimen name="notification_content_image_margin_end">8dp</dimen>
-
     <!-- The padding at the end of actions when the snooze and bubble buttons are gone-->
     <dimen name="snooze_and_bubble_gone_padding_end">12dp</dimen>
 
@@ -483,9 +476,6 @@
     <!-- Top padding for notification when text is large and narrow (i.e. it has 3 lines -->
     <dimen name="notification_top_pad_large_text_narrow">-4dp</dimen>
 
-    <!-- Padding for notification icon when drawn with circle around it -->
-    <dimen name="notification_large_icon_circle_padding">11dp</dimen>
-
     <!-- The margin on top of the text of the notification -->
     <dimen name="notification_text_margin_top">6dp</dimen>
 
@@ -736,12 +726,10 @@
     <dimen name="notification_big_picture_max_height">284dp</dimen>
     <!-- The maximum width of a big picture in a notification. The images will be reduced to that width in case they are bigger. This value is determined by the standard panel size -->
     <dimen name="notification_big_picture_max_width">416dp</dimen>
-    <!-- The maximum height of a image in a media notification. The images will be reduced to that height in case they are bigger. This value is determined by the expanded media template-->
-    <dimen name="notification_media_image_max_height">140dp</dimen>
-    <!-- The maximum width of a image in a media notification. The images will be reduced to that width in case they are bigger.-->
-    <dimen name="notification_media_image_max_width">280dp</dimen>
     <!-- The size of the right icon -->
     <dimen name="notification_right_icon_size">48dp</dimen>
+    <!-- The margin between the right icon and the content. -->
+    <dimen name="notification_right_icon_content_margin">12dp</dimen>
     <!-- The top and bottom margin of the right icon in the normal notification states -->
     <dimen name="notification_right_icon_headerless_margin">20dp</dimen>
     <!-- The top margin of the right icon in the "big" notification states -->
@@ -762,10 +750,6 @@
     <dimen name="notification_big_picture_max_height_low_ram">208dp</dimen>
     <!-- The maximum width of a big picture in a notification. The images will be reduced to that width in case they are bigger. -->
     <dimen name="notification_big_picture_max_width_low_ram">294dp</dimen>
-    <!-- The maximum height of a image in a media notification. The images will be reduced to that height in case they are bigger. -->
-    <dimen name="notification_media_image_max_height_low_ram">100dp</dimen>
-    <!-- The maximum width of a image in a media notification. The images will be reduced to that width in case they are bigger.-->
-    <dimen name="notification_media_image_max_width_low_ram">100dp</dimen>
     <!-- The size of the right icon image when on low ram -->
     <dimen name="notification_right_icon_size_low_ram">@dimen/notification_right_icon_size</dimen>
     <!-- The maximum size of the grayscale icon -->
diff --git a/core/res/res/values/dimens_leanback.xml b/core/res/res/values/dimens_leanback.xml
index 3ab2196..ecda735 100644
--- a/core/res/res/values/dimens_leanback.xml
+++ b/core/res/res/values/dimens_leanback.xml
@@ -89,4 +89,6 @@
     <dimen name="leanback_button_radius">55dp</dimen>
     <dimen name="leanback_button_padding_horizontal">22dp</dimen>
     <dimen name="leanback_button_padding_vertical">11dp</dimen>
+
+    <dimen name="leanback_dialog_corner_radius">8dp</dimen>
 </resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 33cc89d..aea9d60 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -3059,7 +3059,7 @@
     <public name="fontProviderSystemFontFamily" />
     <public name="hand_second" />
     <public name="memtagMode" />
-    <public name="nativeHeapZeroInit" />
+    <public name="nativeHeapZeroInitialized" />
     <!-- @hide @SystemApi -->
     <public name="hotwordDetectionService" />
     <public name="previewLayout" />
@@ -3091,6 +3091,13 @@
     <public name="isAccessibilityTool"/>
     <public name="attributionTags"/>
     <public name="suppressesSpellChecker" />
+    <public name="usesPermissionFlags" />
+    <public name="requestOptimizedExternalStorageAccess" />
+    <!-- @hide @SystemApi -->
+    <public name="playHomeTransitionSound" />
+    <public name="lStar" />
+    <!-- @hide @SystemApi -->
+    <public name="throttleDurationMillis" />
   </public-group>
 
   <public-group type="drawable" first-id="0x010800b5">
@@ -3101,45 +3108,68 @@
     <!-- color definitions go here -->
 
     <!-- Material design dynamic system palette:-->
-    <!-- Primary color -->
-    <public name="system_primary_0" />
-    <public name="system_primary_50" />
-    <public name="system_primary_100" />
-    <public name="system_primary_200" />
-    <public name="system_primary_300" />
-    <public name="system_primary_400" />
-    <public name="system_primary_500" />
-    <public name="system_primary_600" />
-    <public name="system_primary_700" />
-    <public name="system_primary_800" />
-    <public name="system_primary_900" />
-    <public name="system_primary_1000" />
-    <!-- Secondary color -->
-    <public name="system_secondary_0" />
-    <public name="system_secondary_50" />
-    <public name="system_secondary_100" />
-    <public name="system_secondary_200" />
-    <public name="system_secondary_300" />
-    <public name="system_secondary_400" />
-    <public name="system_secondary_500" />
-    <public name="system_secondary_600" />
-    <public name="system_secondary_700" />
-    <public name="system_secondary_800" />
-    <public name="system_secondary_900" />
-    <public name="system_secondary_1000" />
-    <!-- Neutral color -->
-    <public name="system_neutral_0" />
-    <public name="system_neutral_50" />
-    <public name="system_neutral_100" />
-    <public name="system_neutral_200" />
-    <public name="system_neutral_300" />
-    <public name="system_neutral_400" />
-    <public name="system_neutral_500" />
-    <public name="system_neutral_600" />
-    <public name="system_neutral_700" />
-    <public name="system_neutral_800" />
-    <public name="system_neutral_900" />
-    <public name="system_neutral_1000" />
+    <!-- Neutral colors for background and text -->
+    <public name="system_neutral1_0" />
+    <public name="system_neutral1_50" />
+    <public name="system_neutral1_100" />
+    <public name="system_neutral1_200" />
+    <public name="system_neutral1_300" />
+    <public name="system_neutral1_400" />
+    <public name="system_neutral1_500" />
+    <public name="system_neutral1_600" />
+    <public name="system_neutral1_700" />
+    <public name="system_neutral1_800" />
+    <public name="system_neutral1_900" />
+    <public name="system_neutral1_1000" />
+    <public name="system_neutral2_0" />
+    <public name="system_neutral2_50" />
+    <public name="system_neutral2_100" />
+    <public name="system_neutral2_200" />
+    <public name="system_neutral2_300" />
+    <public name="system_neutral2_400" />
+    <public name="system_neutral2_500" />
+    <public name="system_neutral2_600" />
+    <public name="system_neutral2_700" />
+    <public name="system_neutral2_800" />
+    <public name="system_neutral2_900" />
+    <public name="system_neutral2_1000" />
+    <!-- Accent colors, for buttons and UI decorations -->
+    <public name="system_accent1_0" />
+    <public name="system_accent1_50" />
+    <public name="system_accent1_100" />
+    <public name="system_accent1_200" />
+    <public name="system_accent1_300" />
+    <public name="system_accent1_400" />
+    <public name="system_accent1_500" />
+    <public name="system_accent1_600" />
+    <public name="system_accent1_700" />
+    <public name="system_accent1_800" />
+    <public name="system_accent1_900" />
+    <public name="system_accent1_1000" />
+    <public name="system_accent2_0" />
+    <public name="system_accent2_50" />
+    <public name="system_accent2_100" />
+    <public name="system_accent2_200" />
+    <public name="system_accent2_300" />
+    <public name="system_accent2_400" />
+    <public name="system_accent2_500" />
+    <public name="system_accent2_600" />
+    <public name="system_accent2_700" />
+    <public name="system_accent2_800" />
+    <public name="system_accent2_900" />
+    <public name="system_accent2_1000" />
+    <public name="system_accent3_0" />
+    <public name="system_accent3_50" />
+    <public name="system_accent3_100" />
+    <public name="system_accent3_200" />
+    <public name="system_accent3_300" />
+    <public name="system_accent3_400" />
+    <public name="system_accent3_500" />
+    <public name="system_accent3_600" />
+    <public name="system_accent3_700" />
+    <public name="system_accent3_800" />
+    <public name="system_accent3_900" />
+    <public name="system_accent3_1000" />
   </public-group>
 
   <public-group type="dimen" first-id="0x01050008">
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 3412ef2..77ef15b 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -745,7 +745,7 @@
 
     <!-- Text shown when viewing channel settings for notifications related to accessibility
          security policy. [CHAR_LIMIT=NONE]-->
-    <string name="notification_channel_accessibility_security_policy">Accessibility security policy</string>
+    <string name="notification_channel_accessibility_security_policy">Accessibility usage</string>
 
     <!-- Label for foreground service notification when one app is running.
     [CHAR LIMIT=NONE BACKUP_MESSAGE_ID=6826789589341671842] -->
@@ -822,6 +822,11 @@
     <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permgroupdesc_camera">take pictures and record video</string>
 
+    <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=40]-->
+    <string name="permgrouplab_nearby_devices">Nearby Bluetooth Devices</string>
+    <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=NONE]-->
+    <string name="permgroupdesc_nearby_devices">discover and connect to nearby Bluetooth devices</string>
+
     <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permgrouplab_calllog">Call logs</string>
     <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
@@ -1471,6 +1476,14 @@
     <string name="permdesc_bluetooth" product="default">Allows the app to view the
       configuration of the Bluetooth on the phone, and to make and accept
       connections with paired devices.</string>
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=50]-->
+    <string name="permlab_bluetooth_scan">discover and pair nearby Bluetooth devices</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=120]-->
+    <string name="permdesc_bluetooth_scan" product="default">Allows the app to discover and pair nearby Bluetooth devices</string>
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=50]-->
+    <string name="permlab_bluetooth_connect">connect to paired Bluetooth devices</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=120]-->
+    <string name="permdesc_bluetooth_connect" product="default">Allows the app to connect to paired Bluetooth devices</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_preferredPaymentInfo">Preferred NFC Payment Service Information</string>
@@ -1649,6 +1662,14 @@
     <string name="face_recalibrate_notification_title">Re-enroll your face</string>
     <!-- Notification content shown when the system requires the user to re-enroll their face. [CHAR LIMIT=NONE] -->
     <string name="face_recalibrate_notification_content">To improve recognition, please re-enroll your face</string>
+    <!-- Title of a notification that directs the user to set up face unlock by enrolling their face. [CHAR LIMIT=NONE] -->
+    <string name="face_setup_notification_title">Set up face unlock</string>
+    <!-- Contents of a notification that directs the user to set up face unlock by enrolling their face. [CHAR LIMIT=NONE] -->
+    <string name="face_setup_notification_content">Unlock your phone by looking at it</string>
+    <!-- Title of a notification that directs the user to enroll a fingerprint. [CHAR LIMIT=NONE] -->
+    <string name="fingerprint_setup_notification_title">Set up more ways to unlock</string>
+    <!-- Contents of a notification that directs the user to enroll a fingerprint. [CHAR LIMIT=NONE] -->
+    <string name="fingerprint_setup_notification_content">Tap to add a fingerprint</string>
 
     <!-- Message shown during face acquisition when the face cannot be recognized [CHAR LIMIT=50] -->
     <string name="face_acquired_insufficient">Couldn\u2019t capture accurate face data. Try again.</string>
@@ -2808,6 +2829,15 @@
     <!-- Displayed to the user to inform them that an app has accessed clipboard data (pasted as in "copy and paste") [CHAR LIMIT=50] -->
     <string name="pasted_from_clipboard"><xliff:g id="pasting_app_name" example="Gmail">%1$s</xliff:g> pasted from clipboard</string>
 
+    <!-- Displayed to the user to inform them that an app has accessed text from clipboard (pasted as in "copy and paste") [CHAR LIMIT=50] -->
+    <string name="pasted_text"><xliff:g id="pasting_app_name" example="Gmail">%1$s</xliff:g> pasted text you copied</string>
+
+    <!-- Displayed to the user to inform them that an app has accessed an image from clipboard (pasted as in "copy and paste") [CHAR LIMIT=50] -->
+    <string name="pasted_image"><xliff:g id="pasting_app_name" example="Gmail">%1$s</xliff:g> pasted an image you copied</string>
+
+    <!-- Displayed to the user to inform them that an app has accessed content from clipboard (pasted as in "copy and paste") [CHAR LIMIT=50] -->
+    <string name="pasted_content"><xliff:g id="pasting_app_name" example="Gmail">%1$s</xliff:g> pasted content you copied</string>
+
     <!-- Menu item displayed at the end of a menu to allow users to see another page worth of menu items. This is shown on any app's menu as long as the app has too many items in the menu.-->
     <string name="more_item_label">More</string>
     <!-- Prepended to the shortcut for a menu item to indicate that the user should hold the MENU button together with the shortcut to invoke the item. For example, if the shortcut to open a new tab in browser is MENU and B together, then this would be prepended to the letter "B" -->
@@ -5619,40 +5649,39 @@
     <!-- Accessibility label for the work tab button. [CHAR LIMIT=NONE] -->
     <string name="resolver_work_tab_accessibility">Work view</string>
 
-    <!-- Title of a screen. This text lets the user know that their IT admin doesn't allow them to share this specific content with work apps. [CHAR LIMIT=NONE] -->
-    <string name="resolver_cant_share_with_work_apps">Can\u2019t share this with work apps</string>
+    <!-- Title of a screen. This text lets the user know that their IT admin doesn't allow them to share this content across profiles. [CHAR LIMIT=NONE] -->
+    <string name="resolver_cross_profile_blocked">Blocked by your IT admin</string>
     <!-- Error message. This text is explaining that the user's IT admin doesn't allow this specific content to be shared with apps in the work profile. [CHAR LIMIT=NONE] -->
-    <string name="resolver_cant_share_with_work_apps_explanation">Your IT admin doesn\u2019t allow you to share this content with apps in your work profile</string>
+    <string name="resolver_cant_share_with_work_apps_explanation">This content can\u2019t be shared with work apps</string>
 
-    <!-- Title of an error screen. This error message lets the user know that their IT admin doesn't allow them to open this specific content with a work app. [CHAR LIMIT=NONE] -->
-    <string name="resolver_cant_access_work_apps">Can\u2019t open this with work apps</string>
     <!-- Error message. This message lets the user know that their IT admin doesn't allow them to open this specific content with an app in their work profile. [CHAR LIMIT=NONE] -->
-    <string name="resolver_cant_access_work_apps_explanation">Your IT admin doesn\u2019t allow you to open this content with apps in your work profile</string>
+    <string name="resolver_cant_access_work_apps_explanation">This content can\u2019t be opened with work apps</string>
 
-    <!-- Title of a screen. This text lets the user know that their IT admin doesn't allow them to share this specific content with personal apps. [CHAR LIMIT=NONE] -->
-    <string name="resolver_cant_share_with_personal_apps">Can\u2019t share this with personal apps</string>
     <!-- Error message. This text is explaining that the user's IT admin doesn't allow them to share this specific content with apps in their personal profile. [CHAR LIMIT=NONE] -->
-    <string name="resolver_cant_share_with_personal_apps_explanation">Your IT admin doesn\u2019t allow you to share this content with apps in your personal profile</string>
+    <string name="resolver_cant_share_with_personal_apps_explanation">This content can\u2019t be shared with personal apps</string>
 
-    <!-- Title of an error screen. This error message lets the user know that their IT admin doesn't allow them to open this specific content with a personal app. [CHAR LIMIT=NONE] -->
-    <string name="resolver_cant_access_personal_apps">Can\u2019t open this with personal apps</string>
     <!-- Error message. This message lets the user know that their IT admin doesn't allow them to open this specific content with an app in their personal profile. [CHAR LIMIT=NONE] -->
-    <string name="resolver_cant_access_personal_apps_explanation">Your IT admin doesn\u2019t allow you to open this content with apps in your personal profile</string>
+    <string name="resolver_cant_access_personal_apps_explanation">This content can\u2019t be opened with personal apps</string>
 
     <!-- Error message. This text lets the user know that they need to turn on work apps in order to share or open content. There's also a button a user can tap to turn on the apps. [CHAR LIMIT=NONE] -->
     <string name="resolver_turn_on_work_apps">Work profile is paused</string>
     <!-- Button text. This button turns on a user's work profile so they can access their work apps and data. [CHAR LIMIT=NONE] -->
-    <string name="resolver_switch_on_work">Turn on</string>
+    <string name="resolver_switch_on_work">Tap to turn on</string>
 
-    <!-- Error message. This text lets the user know that their current work apps don't support the specific content that they're trying to share. [CHAR LIMIT=NONE] -->
-    <string name="resolver_no_work_apps_available_share">No work apps can support this content</string>
-    <!-- Error message. This text lets the user know that their current work apps can't open this specific content. [CHAR LIMIT=NONE] -->
-    <string name="resolver_no_work_apps_available_resolve">No work apps can open this content</string>
+    <!-- Error message. This text lets the user know that their current work apps don't support the specific content. [CHAR LIMIT=NONE] -->
+    <string name="resolver_no_work_apps_available">No work apps</string>
 
-    <!-- Error message. This text lets the user know that their current personal apps don't support the specific content that they're trying to share. [CHAR LIMIT=NONE] -->
-    <string name="resolver_no_personal_apps_available_share">No personal apps can support this content</string>
-    <!-- Error message. This text lets the user know that their current personal apps can't open this specific content. [CHAR LIMIT=NONE] -->
-    <string name="resolver_no_personal_apps_available_resolve">No personal apps can open this content</string>
+    <!-- Error message. This text lets the user know that their current personal apps don't support the specific content. [CHAR LIMIT=NONE] -->
+    <string name="resolver_no_personal_apps_available">No personal apps</string>
+
+    <!-- Dialog title. User must choose between opening content in a cross-profile app or same-profile browser. [CHAR LIMIT=NONE] -->
+    <string name="miniresolver_open_in_personal">Open in <xliff:g id="app" example="YouTube">%s</xliff:g> in personal profile?</string>
+    <!-- Dialog title. User must choose between opening content in a cross-profile app or same-profile browser. [CHAR LIMIT=NONE] -->
+    <string name="miniresolver_open_in_work">Open in <xliff:g id="app" example="YouTube">%s</xliff:g> in work profile?</string>
+    <!-- Button option. Open the link in the personal browser. [CHAR LIMIT=NONE] -->
+    <string name="miniresolver_use_personal_browser">Use personal browser</string>
+    <!-- Button option. Open the link in the work browser. [CHAR LIMIT=NONE] -->
+    <string name="miniresolver_use_work_browser">Use work browser</string>
 
     <!-- Icc depersonalization related strings -->
     <!-- Label text for PIN entry widget on SIM Network Depersonalization panel [CHAR LIMIT=none] -->
@@ -5899,9 +5928,9 @@
     <!-- Window magnification prompt related string. -->
 
     <!-- Notification title to prompt the user that new magnification feature is available. [CHAR LIMIT=50] -->
-    <string name="window_magnification_prompt_title">Magnify part of your screen</string>
+    <string name="window_magnification_prompt_title">New magnification settings</string>
     <!-- Notification content to prompt the user that new magnification feature is available. [CHAR LIMIT=NONE] -->
-    <string name="window_magnification_prompt_content">You can now magnify your full screen, a specific area, or switch between both options.</string>
+    <string name="window_magnification_prompt_content">You can now magnify part of your screen</string>
     <!-- Notification action to bring the user to magnification settings page. [CHAR LIMIT=50] -->
     <string name="turn_on_magnification_settings_action">Turn on in Settings</string>
     <!-- Notification action to dismiss. [CHAR LIMIT=50] -->
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index c7ded0c..fbf67e0 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -1481,17 +1481,6 @@
         <item name="android:windowExitAnimation">@anim/slide_out_down</item>
     </style>
 
-    <!-- The style for the container of media actions in a notification. -->
-    <!-- @hide -->
-    <style name="NotificationMediaActionContainer">
-        <item name="layout_width">wrap_content</item>
-        <item name="layout_height">wrap_content</item>
-        <item name="layout_marginTop">-21dp</item>
-        <item name="paddingStart">8dp</item>
-        <item name="paddingBottom">@dimen/media_notification_actions_padding_bottom</item>
-        <item name="gravity">top</item>
-    </style>
-
     <!-- The style for normal action button on notification -->
     <style name="NotificationAction" parent="Widget.Material.Light.Button.Borderless.Small">
       <item name="textColor">@color/notification_action_button_text_color</item>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index cdeb71c..beed9a3 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -200,12 +200,7 @@
   <java-symbol type="id" name="action2" />
   <java-symbol type="id" name="action3" />
   <java-symbol type="id" name="action4" />
-  <java-symbol type="id" name="notification_media_seekbar_container" />
   <java-symbol type="id" name="notification_media_content" />
-  <java-symbol type="id" name="notification_media_progress" />
-  <java-symbol type="id" name="notification_media_progress_bar" />
-  <java-symbol type="id" name="notification_media_elapsed_time" />
-  <java-symbol type="id" name="notification_media_total_time" />
   <java-symbol type="id" name="big_picture" />
   <java-symbol type="id" name="big_text" />
   <java-symbol type="id" name="chronometer" />
@@ -436,6 +431,7 @@
   <java-symbol type="integer" name="config_extraFreeKbytesAbsolute" />
   <java-symbol type="integer" name="config_immersive_mode_confirmation_panic" />
   <java-symbol type="integer" name="config_longPressOnPowerBehavior" />
+  <java-symbol type="bool" name="config_longPressOnPowerForAssistantSettingAvailable" />
   <java-symbol type="integer" name="config_veryLongPressOnPowerBehavior" />
   <java-symbol type="integer" name="config_veryLongPressTimeout" />
   <java-symbol type="integer" name="config_longPressOnBackBehavior" />
@@ -525,7 +521,6 @@
   <java-symbol type="dimen" name="notification_top_pad_narrow" />
   <java-symbol type="dimen" name="notification_top_pad_large_text" />
   <java-symbol type="dimen" name="notification_top_pad_large_text_narrow" />
-  <java-symbol type="dimen" name="notification_large_icon_circle_padding" />
   <java-symbol type="dimen" name="notification_badge_size" />
   <java-symbol type="dimen" name="immersive_mode_cling_width" />
   <java-symbol type="dimen" name="accessibility_magnification_indicator_width" />
@@ -560,6 +555,9 @@
   <java-symbol type="string" name="paste_as_plain_text" />
   <java-symbol type="string" name="pasted_from_app" />
   <java-symbol type="string" name="pasted_from_clipboard" />
+  <java-symbol type="string" name="pasted_text" />
+  <java-symbol type="string" name="pasted_image" />
+  <java-symbol type="string" name="pasted_content" />
   <java-symbol type="string" name="replace" />
   <java-symbol type="string" name="undo" />
   <java-symbol type="string" name="redo" />
@@ -1564,7 +1562,6 @@
   <java-symbol type="layout" name="immersive_mode_cling" />
   <java-symbol type="layout" name="user_switching_dialog" />
   <java-symbol type="layout" name="common_tab_settings" />
-  <java-symbol type="layout" name="notification_material_media_seekbar" />
   <java-symbol type="layout" name="resolver_list_per_profile" />
   <java-symbol type="layout" name="chooser_list_per_profile" />
   <java-symbol type="layout" name="resolver_empty_states" />
@@ -1719,8 +1716,6 @@
   <java-symbol type="dimen" name="status_bar_height" />
   <java-symbol type="dimen" name="display_cutout_touchable_region_size" />
   <java-symbol type="dimen" name="quick_qs_offset_height" />
-  <java-symbol type="dimen" name="quick_qs_total_height" />
-  <java-symbol type="dimen" name="quick_qs_total_height_with_media" />
   <java-symbol type="drawable" name="ic_jog_dial_sound_off" />
   <java-symbol type="drawable" name="ic_jog_dial_sound_on" />
   <java-symbol type="drawable" name="ic_jog_dial_unlock" />
@@ -2921,6 +2916,7 @@
   <java-symbol type="drawable" name="ic_expand_bundle" />
   <java-symbol type="drawable" name="ic_collapse_bundle" />
   <java-symbol type="dimen" name="notification_header_shrink_min_width" />
+  <java-symbol type="dimen" name="notification_header_shrink_hide_width" />
   <java-symbol type="dimen" name="notification_content_margin_start" />
   <java-symbol type="dimen" name="notification_content_margin_end" />
   <java-symbol type="dimen" name="notification_heading_margin_end" />
@@ -3010,7 +3006,6 @@
   <java-symbol type="string" name="new_sms_notification_content" />
 
   <java-symbol type="dimen" name="media_notification_expanded_image_margin_bottom" />
-  <java-symbol type="dimen" name="notification_content_image_margin_end" />
 
   <java-symbol type="bool" name="config_strongAuthRequiredOnBoot" />
 
@@ -3019,8 +3014,6 @@
 
   <java-symbol type="id" name="aerr_wait" />
 
-  <java-symbol type="id" name="notification_content_container" />
-
   <java-symbol type="plurals" name="duration_minutes_shortest" />
   <java-symbol type="plurals" name="duration_hours_shortest" />
   <java-symbol type="plurals" name="duration_days_shortest" />
@@ -3138,7 +3131,6 @@
 
   <java-symbol type="bool" name="config_supportPreRebootSecurityLogs" />
 
-  <java-symbol type="dimen" name="notification_media_image_margin_end" />
   <java-symbol type="id" name="notification_action_list_margin_target" />
   <java-symbol type="dimen" name="notification_action_disabled_alpha" />
   <java-symbol type="id" name="tag_margin_end_when_icon_visible" />
@@ -3154,7 +3146,6 @@
   <java-symbol type="bool" name="config_pinnerCameraApp" />
   <java-symbol type="bool" name="config_pinnerHomeApp" />
   <java-symbol type="bool" name="config_pinnerAssistantApp" />
-  <java-symbol type="array" name="config_jitzygoteBootImagePinnerServiceFiles" />
 
   <java-symbol type="string" name="config_doubleTouchGestureEnableFile" />
 
@@ -3461,17 +3452,14 @@
 
   <java-symbol type="dimen" name="notification_big_picture_max_height"/>
   <java-symbol type="dimen" name="notification_big_picture_max_width"/>
-  <java-symbol type="dimen" name="notification_media_image_max_width"/>
-  <java-symbol type="dimen" name="notification_media_image_max_height"/>
   <java-symbol type="dimen" name="notification_right_icon_size"/>
+  <java-symbol type="dimen" name="notification_right_icon_content_margin"/>
   <java-symbol type="dimen" name="notification_actions_icon_drawable_size"/>
   <java-symbol type="dimen" name="notification_custom_view_max_image_height"/>
   <java-symbol type="dimen" name="notification_custom_view_max_image_width"/>
 
   <java-symbol type="dimen" name="notification_big_picture_max_height_low_ram"/>
   <java-symbol type="dimen" name="notification_big_picture_max_width_low_ram"/>
-  <java-symbol type="dimen" name="notification_media_image_max_width_low_ram"/>
-  <java-symbol type="dimen" name="notification_media_image_max_height_low_ram"/>
   <java-symbol type="dimen" name="notification_right_icon_size_low_ram"/>
   <java-symbol type="dimen" name="notification_grayscale_icon_max_size"/>
   <java-symbol type="dimen" name="notification_custom_view_max_image_height_low_ram"/>
@@ -3545,6 +3533,7 @@
   <java-symbol type="string" name="notification_channel_do_not_disturb" />
   <java-symbol type="string" name="notification_channel_accessibility_magnification" />
   <java-symbol type="string" name="notification_channel_accessibility_security_policy" />
+  <java-symbol type="string" name="config_companionProviderPackage" />
   <java-symbol type="string" name="config_defaultAutofillService" />
   <java-symbol type="string" name="config_defaultOnDeviceSpeechRecognitionService" />
   <java-symbol type="string" name="config_defaultTextClassifierPackage" />
@@ -3967,6 +3956,7 @@
   <java-symbol type="layout" name="chooser_action_button" />
   <java-symbol type="dimen" name="chooser_action_button_icon_size" />
   <java-symbol type="string" name="config_defaultNearbySharingComponent" />
+  <java-symbol type="bool" name="config_disable_all_cb_messages" />
   <java-symbol type="drawable" name="ic_close" />
 
   <java-symbol type="bool" name="config_automotiveHideNavBarForKeyboard" />
@@ -4103,19 +4093,14 @@
   <java-symbol type="id" name="resolver_empty_state_container" />
   <java-symbol type="id" name="button_bar_container" />
   <java-symbol type="id" name="title_container" />
-  <java-symbol type="string" name="resolver_cant_share_with_work_apps" />
+  <java-symbol type="string" name="resolver_cross_profile_blocked" />
   <java-symbol type="string" name="resolver_cant_share_with_work_apps_explanation" />
-  <java-symbol type="string" name="resolver_cant_share_with_personal_apps" />
   <java-symbol type="string" name="resolver_cant_share_with_personal_apps_explanation" />
-  <java-symbol type="string" name="resolver_cant_access_work_apps" />
   <java-symbol type="string" name="resolver_cant_access_work_apps_explanation" />
-  <java-symbol type="string" name="resolver_cant_access_personal_apps" />
   <java-symbol type="string" name="resolver_cant_access_personal_apps_explanation" />
   <java-symbol type="string" name="resolver_turn_on_work_apps" />
-  <java-symbol type="string" name="resolver_no_work_apps_available_share" />
-  <java-symbol type="string" name="resolver_no_work_apps_available_resolve" />
-  <java-symbol type="string" name="resolver_no_personal_apps_available_share" />
-  <java-symbol type="string" name="resolver_no_personal_apps_available_resolve" />
+  <java-symbol type="string" name="resolver_no_work_apps_available" />
+  <java-symbol type="string" name="resolver_no_personal_apps_available" />
   <java-symbol type="string" name="resolver_switch_on_work" />
   <java-symbol type="drawable" name="ic_work_apps_off" />
   <java-symbol type="drawable" name="ic_sharing_disabled" />
@@ -4182,6 +4167,7 @@
   <java-symbol type="dimen" name="default_background_blur_radius" />
   <java-symbol type="array" name="config_keep_warming_services" />
   <java-symbol type="string" name="config_display_features" />
+  <java-symbol type="array" name="config_device_state_postures" />
 
   <java-symbol type="dimen" name="controls_thumbnail_image_max_height" />
   <java-symbol type="dimen" name="controls_thumbnail_image_max_width" />
@@ -4231,6 +4217,10 @@
 
   <java-symbol type="bool" name="config_enableOneHandedKeyguard" />
 
+  <java-symbol type="attr" name="colorAccentPrimary" />
+  <java-symbol type="attr" name="colorAccentSecondary" />
+  <java-symbol type="attr" name="colorAccentTertiary" />
+
   <!-- CEC Configuration -->
   <java-symbol type="bool" name="config_cecHdmiCecEnabled_userConfigurable" />
   <java-symbol type="bool" name="config_cecHdmiCecControlEnabled_allowed" />
diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml
index 16d720b..e40e31e 100644
--- a/core/res/res/values/themes_device_defaults.xml
+++ b/core/res/res/values/themes_device_defaults.xml
@@ -214,6 +214,9 @@
         <item name="colorPrimary">@color/primary_device_default_dark</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
         <item name="colorAccent">@color/accent_device_default_dark</item>
+        <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
+        <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
+        <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
         <item name="colorError">@color/error_color_device_default_dark</item>
         <item name="colorBackground">@color/background_device_default_dark</item>
         <item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
@@ -237,6 +240,9 @@
         <item name="colorPrimary">@color/primary_device_default_dark</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
         <item name="colorAccent">@color/accent_device_default_dark</item>
+        <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
+        <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
+        <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
         <item name="colorError">@color/error_color_device_default_dark</item>
         <item name="colorBackground">@color/background_device_default_dark</item>
         <item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
@@ -272,6 +278,9 @@
         <item name="colorPrimary">@color/primary_device_default_dark</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
         <item name="colorAccent">@color/accent_device_default_dark</item>
+        <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
+        <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
+        <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
         <item name="colorError">@color/error_color_device_default_dark</item>
         <item name="colorBackground">@color/background_device_default_dark</item>
         <item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
@@ -309,6 +318,9 @@
         <item name="colorPrimary">@color/primary_device_default_dark</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
         <item name="colorAccent">@color/accent_device_default_dark</item>
+        <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
+        <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
+        <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
         <item name="colorError">@color/error_color_device_default_dark</item>
         <item name="colorBackground">@color/background_device_default_dark</item>
         <item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
@@ -345,6 +357,9 @@
         <item name="colorPrimary">@color/primary_device_default_dark</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
         <item name="colorAccent">@color/accent_device_default_dark</item>
+        <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
+        <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
+        <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
         <item name="colorError">@color/error_color_device_default_dark</item>
         <item name="colorBackground">@color/background_device_default_dark</item>
         <item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
@@ -396,6 +411,9 @@
         <item name="colorPrimary">@color/primary_device_default_dark</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
         <item name="colorAccent">@color/accent_device_default_dark</item>
+        <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
+        <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
+        <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
         <item name="colorError">@color/error_color_device_default_dark</item>
         <item name="colorBackground">@color/background_device_default_dark</item>
         <item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
@@ -424,6 +442,9 @@
         <item name="colorPrimary">@color/primary_device_default_dark</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
         <item name="colorAccent">@color/accent_device_default_dark</item>
+        <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
+        <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
+        <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
         <item name="colorError">@color/error_color_device_default_dark</item>
         <item name="colorBackground">@color/background_device_default_dark</item>
         <item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
@@ -458,6 +479,9 @@
         <item name="colorPrimary">@color/primary_device_default_dark</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
         <item name="colorAccent">@color/accent_device_default_dark</item>
+        <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
+        <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
+        <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
         <item name="colorError">@color/error_color_device_default_dark</item>
         <item name="colorBackground">@color/background_device_default_dark</item>
         <item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
@@ -493,6 +517,9 @@
         <item name="colorPrimary">@color/primary_device_default_dark</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
         <item name="colorAccent">@color/accent_device_default_dark</item>
+        <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
+        <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
+        <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
         <item name="colorError">@color/error_color_device_default_dark</item>
         <item name="colorBackground">@color/background_device_default_dark</item>
         <item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
@@ -544,6 +571,9 @@
         <item name="colorPrimary">@color/primary_device_default_dark</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
         <item name="colorAccent">@color/accent_device_default_dark</item>
+        <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
+        <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
+        <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
         <item name="colorError">@color/error_color_device_default_dark</item>
         <item name="colorBackground">@color/background_device_default_dark</item>
         <item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
@@ -580,6 +610,9 @@
         <item name="colorPrimary">@color/primary_device_default_dark</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
         <item name="colorAccent">@color/accent_device_default_dark</item>
+        <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
+        <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
+        <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
         <item name="colorError">@color/error_color_device_default_dark</item>
         <item name="colorBackground">@color/background_device_default_dark</item>
         <item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
@@ -614,6 +647,9 @@
         <item name="colorPrimary">@color/primary_device_default_dark</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
         <item name="colorAccent">@color/accent_device_default_dark</item>
+        <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
+        <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
+        <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
         <item name="colorError">@color/error_color_device_default_dark</item>
         <item name="colorBackground">@color/background_device_default_dark</item>
         <item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
@@ -650,6 +686,9 @@
         <item name="colorPrimary">@color/primary_device_default_dark</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
         <item name="colorAccent">@color/accent_device_default_dark</item>
+        <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
+        <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
+        <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
         <item name="colorError">@color/error_color_device_default_dark</item>
         <item name="colorBackground">@color/background_device_default_dark</item>
         <item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
@@ -685,6 +724,9 @@
         <item name="colorPrimary">@color/primary_device_default_dark</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
         <item name="colorAccent">@color/accent_device_default_dark</item>
+        <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
+        <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
+        <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
         <item name="colorError">@color/error_color_device_default_dark</item>
         <item name="colorBackground">@color/background_device_default_dark</item>
         <item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
@@ -720,6 +762,9 @@
         <item name="colorPrimary">@color/primary_device_default_dark</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
         <item name="colorAccent">@color/accent_device_default_dark</item>
+        <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
+        <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
+        <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
         <item name="colorError">@color/error_color_device_default_dark</item>
         <item name="colorBackground">@color/background_device_default_dark</item>
         <item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
@@ -755,6 +800,9 @@
         <item name="colorPrimary">@color/primary_device_default_light</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
+        <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
+        <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
         <item name="colorError">@color/error_color_device_default_light</item>
         <item name="colorBackground">@color/background_device_default_light</item>
         <item name="colorBackgroundFloating">@color/background_floating_device_default_light</item>
@@ -790,6 +838,9 @@
         <item name="colorPrimary">@color/primary_device_default_light</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
+        <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
+        <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
         <item name="colorError">@color/error_color_device_default_light</item>
         <item name="colorBackground">@color/background_device_default_light</item>
         <item name="colorBackgroundFloating">@color/background_floating_device_default_light</item>
@@ -829,6 +880,9 @@
         <item name="colorPrimary">@color/primary_device_default_dark</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
         <item name="colorAccent">@color/accent_device_default_dark</item>
+        <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
+        <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
+        <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
         <item name="colorError">@color/error_color_device_default_dark</item>
         <item name="colorBackground">@color/background_device_default_dark</item>
         <item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
@@ -865,6 +919,9 @@
         <item name="colorPrimary">@color/primary_device_default_dark</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
         <item name="colorAccent">@color/accent_device_default_dark</item>
+        <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
+        <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
+        <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
         <item name="colorError">@color/error_color_device_default_dark</item>
         <item name="colorBackground">@color/background_device_default_dark</item>
         <item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
@@ -898,6 +955,9 @@
         <item name="colorPrimary">@color/primary_device_default_dark</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
         <item name="colorAccent">@color/accent_device_default_dark</item>
+        <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
+        <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
+        <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
         <item name="colorError">@color/error_color_device_default_dark</item>
         <item name="colorBackground">@color/background_device_default_dark</item>
         <item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
@@ -1085,6 +1145,9 @@
         <item name="colorPrimary">@color/primary_device_default_light</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
+        <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
+        <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
         <item name="colorError">@color/error_color_device_default_light</item>
         <item name="colorBackground">@color/background_device_default_light</item>
         <item name="colorBackgroundFloating">@color/background_floating_device_default_light</item>
@@ -1104,6 +1167,9 @@
         <item name="colorPrimary">@color/primary_device_default_dark</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
+        <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
+        <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
         <item name="colorError">@color/error_color_device_default_light</item>
         <item name="colorBackground">@color/background_device_default_light</item>
         <item name="colorBackgroundFloating">@color/background_floating_device_default_light</item>
@@ -1138,6 +1204,9 @@
         <item name="colorPrimary">@color/primary_device_default_light</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
+        <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
+        <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
         <item name="colorError">@color/error_color_device_default_light</item>
         <item name="colorBackground">@color/background_device_default_light</item>
         <item name="colorBackgroundFloating">@color/background_floating_device_default_light</item>
@@ -1173,6 +1242,9 @@
         <item name="colorPrimary">@color/primary_device_default_light</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
+        <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
+        <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
         <item name="colorError">@color/error_color_device_default_light</item>
         <item name="colorBackground">@color/background_device_default_light</item>
         <item name="colorBackgroundFloating">@color/background_floating_device_default_light</item>
@@ -1210,6 +1282,9 @@
         <item name="colorPrimary">@color/primary_device_default_light</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
+        <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
+        <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
         <item name="colorError">@color/error_color_device_default_light</item>
         <item name="colorBackground">@color/background_device_default_light</item>
         <item name="colorBackgroundFloating">@color/background_floating_device_default_light</item>
@@ -1246,6 +1321,9 @@
         <item name="colorPrimary">@color/primary_device_default_light</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
+        <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
+        <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
         <item name="colorError">@color/error_color_device_default_light</item>
         <item name="colorBackground">@color/background_device_default_light</item>
         <item name="colorBackgroundFloating">@color/background_floating_device_default_light</item>
@@ -1299,6 +1377,9 @@
         <item name="colorPrimary">@color/primary_device_default_light</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
+        <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
+        <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
         <item name="colorError">@color/error_color_device_default_light</item>
         <item name="colorBackground">@color/background_device_default_light</item>
         <item name="colorBackgroundFloating">@color/background_floating_device_default_light</item>
@@ -1326,6 +1407,9 @@
         <item name="colorPrimary">@color/primary_device_default_light</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
+        <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
+        <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
         <item name="colorError">@color/error_color_device_default_light</item>
         <item name="colorBackground">@color/background_device_default_light</item>
         <item name="colorBackgroundFloating">@color/background_floating_device_default_light</item>
@@ -1363,6 +1447,9 @@
         <item name="colorPrimary">@color/primary_device_default_light</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
+        <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
+        <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
         <item name="colorError">@color/error_color_device_default_light</item>
         <item name="colorBackground">@color/background_device_default_light</item>
         <item name="colorBackgroundFloating">@color/background_floating_device_default_light</item>
@@ -1401,6 +1488,9 @@
         <item name="colorPrimary">@color/primary_device_default_light</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
+        <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
+        <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
         <item name="colorError">@color/error_color_device_default_light</item>
         <item name="colorBackground">@color/background_device_default_light</item>
         <item name="colorBackgroundFloating">@color/background_floating_device_default_light</item>
@@ -1440,6 +1530,9 @@
         <item name="colorPrimary">@color/primary_device_default_light</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
+        <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
+        <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
         <item name="colorError">@color/error_color_device_default_light</item>
         <item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
         <item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
@@ -1459,6 +1552,9 @@
         <item name="colorPrimary">@color/primary_device_default_light</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
+        <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
+        <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
         <item name="colorError">@color/error_color_device_default_light</item>
         <item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
         <item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
@@ -1477,6 +1573,9 @@
         <item name="colorPrimary">@color/primary_device_default_light</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
+        <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
+        <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
         <item name="colorError">@color/error_color_device_default_light</item>
         <item name="colorBackground">@color/background_device_default_light</item>
         <item name="colorBackgroundFloating">@color/background_floating_device_default_light</item>
@@ -1516,6 +1615,9 @@
         <item name="colorPrimary">@color/primary_device_default_light</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
+        <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
+        <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
         <item name="colorError">@color/error_color_device_default_light</item>
         <item name="colorBackground">@color/background_device_default_light</item>
         <item name="colorBackgroundFloating">@color/background_floating_device_default_light</item>
@@ -1553,6 +1655,9 @@
         <item name="colorPrimary">@color/primary_device_default_light</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
+        <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
+        <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
         <item name="colorError">@color/error_color_device_default_light</item>
         <item name="colorBackground">@color/background_device_default_light</item>
         <item name="colorBackgroundFloating">@color/background_floating_device_default_light</item>
@@ -1589,6 +1694,9 @@
         <item name="colorPrimary">@color/primary_device_default_light</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
+        <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
+        <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
         <item name="colorError">@color/error_color_device_default_light</item>
         <item name="colorBackground">@color/background_device_default_light</item>
         <item name="colorBackgroundFloating">@color/background_floating_device_default_light</item>
@@ -1624,6 +1732,9 @@
         <item name="colorPrimary">@color/primary_device_default_light</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
+        <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
+        <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
         <item name="colorError">@color/error_color_device_default_light</item>
         <item name="colorBackground">@color/background_device_default_light</item>
         <item name="colorBackgroundFloating">@color/background_floating_device_default_light</item>
@@ -1659,6 +1770,9 @@
         <item name="colorPrimary">@color/primary_device_default_light</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
+        <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
+        <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
         <item name="colorError">@color/error_color_device_default_light</item>
         <item name="colorBackground">@color/background_device_default_light</item>
         <item name="colorBackgroundFloating">@color/background_floating_device_default_light</item>
@@ -1692,6 +1806,9 @@
         <item name="colorPrimary">@color/primary_device_default_light</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
+        <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
+        <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
         <item name="colorError">@color/error_color_device_default_light</item>
         <item name="colorBackground">@color/background_device_default_light</item>
         <item name="colorBackgroundFloating">@color/background_floating_device_default_light</item>
@@ -1742,6 +1859,9 @@
         <item name="colorPrimaryDark">@color/primary_dark_device_default_settings_light</item>
         <item name="colorSecondary">@color/secondary_device_default_settings_light</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
+        <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
+        <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
         <item name="colorError">@color/error_color_device_default_light</item>
         <item name="colorEdgeEffect">@color/edge_effect_device_default_light</item>
 
@@ -1772,6 +1892,9 @@
         <item name="colorPrimaryDark">@color/primary_dark_device_default_settings_light</item>
         <item name="colorSecondary">@color/secondary_device_default_settings_light</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
+        <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
+        <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
         <item name="colorError">@color/error_color_device_default_light</item>
         <item name="colorControlNormal">?attr/textColorPrimary</item>
         <item name="alertDialogTheme">@style/Theme.DeviceDefault.Light.Dialog.Alert</item>
@@ -1797,6 +1920,9 @@
         <item name="colorPrimaryDark">@color/primary_dark_device_default_settings_light</item>
         <item name="colorSecondary">@color/secondary_device_default_settings_light</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
+        <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
+        <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
         <item name="colorError">@color/error_color_device_default_light</item>
         <item name="alertDialogTheme">@style/Theme.DeviceDefault.Light.Dialog.Alert</item>
 
@@ -1815,6 +1941,9 @@
         <item name="colorPrimaryDark">@color/primary_dark_device_default_settings</item>
         <item name="colorSecondary">@color/secondary_device_default_settings</item>
         <item name="colorAccent">@color/accent_device_default_dark</item>
+        <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
+        <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
+        <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
         <item name="colorError">@color/error_color_device_default_dark</item>
         <item name="colorBackground">@color/background_device_default_dark</item>
         <item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
@@ -1849,6 +1978,9 @@
         <item name="colorPrimaryDark">@color/primary_dark_device_default_settings</item>
         <item name="colorSecondary">@color/secondary_device_default_settings</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
+        <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
+        <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
         <item name="colorError">@color/error_color_device_default_light</item>
         <item name="colorBackground">@color/background_device_default_light</item>
         <item name="colorBackgroundFloating">@color/background_floating_device_default_light</item>
@@ -1893,6 +2025,9 @@
         <item name="colorPrimaryDark">@color/primary_dark_device_default_settings</item>
         <item name="colorSecondary">@color/secondary_device_default_settings</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
+        <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
+        <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
         <item name="colorError">@color/error_color_device_default_light</item>
         <item name="colorBackground">@color/background_device_default_light</item>
         <item name="colorBackgroundFloating">@color/background_floating_device_default_light</item>
@@ -1930,6 +2065,9 @@
         <item name="colorPrimaryDark">@color/primary_dark_device_default_settings</item>
         <item name="colorSecondary">@color/secondary_device_default_settings</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
+        <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
+        <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
         <item name="colorError">@color/error_color_device_default_light</item>
         <item name="colorBackground">@color/background_device_default_light</item>
         <item name="colorBackgroundFloating">@color/background_floating_device_default_light</item>
@@ -2030,10 +2168,16 @@
 
     <style name="ThemeOverlay.DeviceDefault.Accent">
         <item name="colorAccent">@color/accent_device_default_dark</item>
+        <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
+        <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
+        <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
     </style>
 
     <style name="ThemeOverlay.DeviceDefault.Accent.Light">
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
+        <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
+        <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
     </style>
 
     <!-- Theme overlay that replaces colorAccent with the colorAccent from {@link #Theme_DeviceDefault_DayNight}. -->
@@ -2042,6 +2186,9 @@
 
     <style name="ThemeOverlay.DeviceDefault.Dark.ActionBar.Accent" parent="ThemeOverlay.Material.Dark.ActionBar">
         <item name="colorAccent">@color/accent_device_default_dark</item>
+        <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
+        <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
+        <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
     </style>
 
     <style name="Theme.DeviceDefault.Light.Dialog.Alert.UserSwitchingDialog" parent="Theme.DeviceDefault.NoActionBar.Fullscreen">
diff --git a/core/res/res/values/themes_leanback.xml b/core/res/res/values/themes_leanback.xml
index efe5826..0be9e9800 100644
--- a/core/res/res/values/themes_leanback.xml
+++ b/core/res/res/values/themes_leanback.xml
@@ -15,31 +15,21 @@
 -->
 <resources>
     <style name="Theme.Leanback.Dialog" parent="Theme.Material.BaseDialog">
-      <item name="colorBackground">@color/background_leanback_dark</item>
-      <item name="textColorPrimary">@color/primary_text_leanback_dark</item>
-      <item name="textColorSecondary">@color/secondary_text_leanback_dark</item>
-      <item name="alertDialogStyle">@style/AlertDialog.Leanback</item>
-      <item name="timePickerStyle">@style/Widget.Leanback.TimePicker</item>
-      <item name="datePickerStyle">@style/Widget.Leanback.DatePicker</item>
-      <item name="numberPickerStyle">@style/Widget.Leanback.NumberPicker</item>
-      <item name="buttonBarButtonStyle">@style/Widget.Leanback.Button.ButtonBarGravityStart</item>
-      <item name="buttonBarStyle">@style/Widget.Leanback.ButtonBar</item>
-    </style>
-
-    <style name="Theme.Leanback.Light.Dialog" parent="Theme.Material.Light.BaseDialog">
-      <item name="colorBackground">@color/background_leanback_dark</item>
-      <item name="textColorPrimary">@color/primary_text_leanback_dark</item>
-      <item name="textColorSecondary">@color/secondary_text_leanback_dark</item>
-      <item name="alertDialogStyle">@style/AlertDialog.Leanback</item>
-      <item name="timePickerStyle">@style/Widget.Leanback.TimePicker</item>
-      <item name="datePickerStyle">@style/Widget.Leanback.DatePicker</item>
-      <item name="numberPickerStyle">@style/Widget.Leanback.NumberPicker</item>
+        <item name="colorBackground">@color/background_leanback_dark</item>
+        <item name="dialogCornerRadius">@dimen/leanback_dialog_corner_radius</item>
+        <item name="textColorPrimary">@color/primary_text_leanback_dark</item>
+        <item name="textColorSecondary">@color/secondary_text_leanback_dark</item>
+        <item name="alertDialogStyle">@style/AlertDialog.Leanback</item>
+        <item name="timePickerStyle">@style/Widget.Leanback.TimePicker</item>
+        <item name="datePickerStyle">@style/Widget.Leanback.DatePicker</item>
+        <item name="numberPickerStyle">@style/Widget.Leanback.NumberPicker</item>
         <item name="buttonBarButtonStyle">@style/Widget.Leanback.Button.ButtonBarGravityStart</item>
-      <item name="buttonBarStyle">@style/Widget.Leanback.ButtonBar</item>
+        <item name="buttonBarStyle">@style/Widget.Leanback.ButtonBar</item>
     </style>
 
     <style name="Theme.Leanback.Settings.Dialog" parent="Theme.Material.Settings.BaseDialog">
         <item name="colorBackground">@color/background_leanback_dark</item>
+        <item name="dialogCornerRadius">@dimen/leanback_dialog_corner_radius</item>
         <item name="textColorPrimary">@color/primary_text_leanback_dark</item>
         <item name="textColorSecondary">@color/secondary_text_leanback_dark</item>
         <item name="alertDialogStyle">@style/AlertDialog.Leanback</item>
@@ -51,34 +41,25 @@
     </style>
 
     <style name="Theme.Leanback.Dialog.Alert" parent="Theme.Material.Dialog.BaseAlert">
-      <item name="colorBackground">@color/background_leanback_dark</item>
-      <item name="textColorPrimary">@color/primary_text_leanback_dark</item>
-      <item name="textColorSecondary">@color/secondary_text_leanback_dark</item>
-      <item name="alertDialogStyle">@style/AlertDialog.Leanback</item>
-      <item name="timePickerStyle">@style/Widget.Leanback.TimePicker</item>
-      <item name="datePickerStyle">@style/Widget.Leanback.DatePicker</item>
-      <item name="numberPickerStyle">@style/Widget.Leanback.NumberPicker</item>
-      <item name="buttonBarButtonStyle">@style/Widget.Leanback.Button.ButtonBarGravityStart</item>
-      <item name="buttonBarStyle">@style/Widget.Leanback.ButtonBar</item>
-    </style>
-
-    <style name="Theme.Leanback.Light.Dialog.Alert" parent="Theme.Material.Light.Dialog.BaseAlert">
-      <item name="colorBackground">@color/background_leanback_light</item>
-      <item name="textColorPrimary">@color/primary_text_leanback_light</item>
-      <item name="textColorSecondary">@color/secondary_text_leanback_light</item>
-      <item name="alertDialogStyle">@style/AlertDialog.Leanback.Light</item>
-      <item name="timePickerStyle">@style/Widget.Leanback.TimePicker</item>
-      <item name="datePickerStyle">@style/Widget.Leanback.DatePicker</item>
-      <item name="numberPickerStyle">@style/Widget.Leanback.NumberPicker</item>
+        <item name="colorBackground">@color/background_leanback_dark</item>
+        <item name="dialogCornerRadius">@dimen/leanback_dialog_corner_radius</item>
+        <item name="textColorPrimary">@color/primary_text_leanback_dark</item>
+        <item name="textColorSecondary">@color/secondary_text_leanback_dark</item>
+        <item name="alertDialogStyle">@style/AlertDialog.Leanback</item>
+        <item name="timePickerStyle">@style/Widget.Leanback.TimePicker</item>
+        <item name="datePickerStyle">@style/Widget.Leanback.DatePicker</item>
+        <item name="numberPickerStyle">@style/Widget.Leanback.NumberPicker</item>
         <item name="buttonBarButtonStyle">@style/Widget.Leanback.Button.ButtonBarGravityStart</item>
-      <item name="buttonBarStyle">@style/Widget.Leanback.ButtonBar</item>
+        <item name="buttonBarStyle">@style/Widget.Leanback.ButtonBar</item>
     </style>
 
-    <style name="Theme.Leanback.Settings.Dialog.Alert" parent="Theme.Material.Settings.Dialog.BaseAlert">
-        <item name="colorBackground">@color/background_leanback_light</item>
-        <item name="textColorPrimary">@color/primary_text_leanback_light</item>
-        <item name="textColorSecondary">@color/secondary_text_leanback_light</item>
-        <item name="alertDialogStyle">@style/AlertDialog.Leanback.Light</item>
+    <style name="Theme.Leanback.Settings.Dialog.Alert"
+           parent="Theme.Material.Settings.Dialog.BaseAlert">
+        <item name="colorBackground">@color/background_leanback_dark</item>
+        <item name="dialogCornerRadius">@dimen/leanback_dialog_corner_radius</item>
+        <item name="textColorPrimary">@color/primary_text_leanback_dark</item>
+        <item name="textColorSecondary">@color/secondary_text_leanback_dark</item>
+        <item name="alertDialogStyle">@style/AlertDialog.Leanback</item>
         <item name="timePickerStyle">@style/Widget.Leanback.TimePicker</item>
         <item name="datePickerStyle">@style/Widget.Leanback.DatePicker</item>
         <item name="numberPickerStyle">@style/Widget.Leanback.NumberPicker</item>
@@ -144,9 +125,9 @@
         <!-- Icon sizes -->
         <item name="iconfactoryIconSize">@dimen/resolver_icon_size</item>
         <item name="iconfactoryBadgeSize">@dimen/resolver_badge_size</item>
-      </style>
+    </style>
 
     <!-- @hide Special theme for the default system Activity-based Alert dialogs. -->
-    <style name="Theme.Leanback.Dialog.Confirmation" parent="Theme.DeviceDefault.Dialog.Alert" />
+    <style name="Theme.Leanback.Dialog.Confirmation" parent="Theme.DeviceDefault.Dialog.Alert"/>
 
 </resources>
diff --git a/core/tests/GameManagerTests/AndroidManifest.xml b/core/tests/GameManagerTests/AndroidManifest.xml
index 6c28607..6a01abe 100644
--- a/core/tests/GameManagerTests/AndroidManifest.xml
+++ b/core/tests/GameManagerTests/AndroidManifest.xml
@@ -19,7 +19,7 @@
           package="com.android.app.gamemanagertests"
           android:sharedUserId="android.uid.system" >
 
-    <application>
+    <application android:appCategory="game">
         <uses-library android:name="android.test.runner" />
     </application>
 
diff --git a/core/tests/GameManagerTests/src/android/app/GameManagerTests.java b/core/tests/GameManagerTests/src/android/app/GameManagerTests.java
index 0c96411..baecc8c 100644
--- a/core/tests/GameManagerTests/src/android/app/GameManagerTests.java
+++ b/core/tests/GameManagerTests/src/android/app/GameManagerTests.java
@@ -37,9 +37,6 @@
 @SmallTest
 @Presubmit
 public final class GameManagerTests {
-    private static final String PACKAGE_NAME_0 = "com.android.app0";
-    private static final String PACKAGE_NAME_1 = "com.android.app1";
-
     protected Context mContext;
     private GameManager mGameManager;
     private String mPackageName;
@@ -52,8 +49,6 @@
 
         // Reset the Game Mode for the test app, since it persists across invocations.
         mGameManager.setGameMode(mPackageName, GameManager.GAME_MODE_UNSUPPORTED);
-        mGameManager.setGameMode(PACKAGE_NAME_0, GameManager.GAME_MODE_UNSUPPORTED);
-        mGameManager.setGameMode(PACKAGE_NAME_1, GameManager.GAME_MODE_UNSUPPORTED);
     }
 
     @Test
@@ -73,14 +68,14 @@
     @Test
     public void testPrivilegedGameModeGetterSetter() {
         assertEquals(GameManager.GAME_MODE_UNSUPPORTED,
-                mGameManager.getGameMode(PACKAGE_NAME_0));
+                mGameManager.getGameMode(mPackageName));
 
-        mGameManager.setGameMode(PACKAGE_NAME_1, GameManager.GAME_MODE_STANDARD);
+        mGameManager.setGameMode(mPackageName, GameManager.GAME_MODE_STANDARD);
         assertEquals(GameManager.GAME_MODE_STANDARD,
-                mGameManager.getGameMode(PACKAGE_NAME_1));
+                mGameManager.getGameMode(mPackageName));
 
-        mGameManager.setGameMode(PACKAGE_NAME_1, GameManager.GAME_MODE_PERFORMANCE);
+        mGameManager.setGameMode(mPackageName, GameManager.GAME_MODE_PERFORMANCE);
         assertEquals(GameManager.GAME_MODE_PERFORMANCE,
-                mGameManager.getGameMode(PACKAGE_NAME_1));
+                mGameManager.getGameMode(mPackageName));
     }
 }
diff --git a/core/tests/bluetoothtests/AndroidManifest.xml b/core/tests/bluetoothtests/AndroidManifest.xml
index 6849a90..f8c69ac 100644
--- a/core/tests/bluetoothtests/AndroidManifest.xml
+++ b/core/tests/bluetoothtests/AndroidManifest.xml
@@ -20,6 +20,8 @@
 
     <uses-permission android:name="android.permission.BLUETOOTH" />
     <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
+    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
+    <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
     <uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" />
     <uses-permission android:name="android.permission.BROADCAST_STICKY" />
     <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml
index f31233b..408624a 100644
--- a/core/tests/coretests/AndroidManifest.xml
+++ b/core/tests/coretests/AndroidManifest.xml
@@ -44,6 +44,8 @@
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
     <uses-permission android:name="android.permission.BLUETOOTH" />
     <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
+    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
+    <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
     <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
     <uses-permission android:name="android.permission.BROADCAST_STICKY" />
     <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
diff --git a/core/tests/coretests/src/android/app/NotificationTest.java b/core/tests/coretests/src/android/app/NotificationTest.java
index 252938a..0ea6364 100644
--- a/core/tests/coretests/src/android/app/NotificationTest.java
+++ b/core/tests/coretests/src/android/app/NotificationTest.java
@@ -16,8 +16,6 @@
 
 package android.app;
 
-import static com.android.internal.util.ContrastColorUtil.satisfiesTextContrast;
-
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotSame;
@@ -99,23 +97,6 @@
     }
 
     @Test
-    public void testColorSatisfiedWhenBgDarkTextDarker() {
-        Notification.Builder builder = getMediaNotification();
-        Notification n = builder.build();
-
-        assertTrue(n.isColorized());
-
-        // An initial guess where the foreground color is actually darker than an already dark bg
-        int backgroundColor = 0xff585868;
-        int initialForegroundColor = 0xff505868;
-        builder.setColorPalette(backgroundColor, initialForegroundColor);
-        int primaryTextColor = builder.getPrimaryTextColor(builder.mParams);
-        assertTrue(satisfiesTextContrast(primaryTextColor, backgroundColor));
-        int secondaryTextColor = builder.getSecondaryTextColor(builder.mParams);
-        assertTrue(satisfiesTextContrast(secondaryTextColor, backgroundColor));
-    }
-
-    @Test
     public void testHasCompletedProgress_noProgress() {
         Notification n = new Notification.Builder(mContext).build();
 
diff --git a/core/tests/coretests/src/android/app/appsearch/AppSearchSessionUnitTest.java b/core/tests/coretests/src/android/app/appsearch/AppSearchSessionUnitTest.java
index 7ef1d5e..56c685a 100644
--- a/core/tests/coretests/src/android/app/appsearch/AppSearchSessionUnitTest.java
+++ b/core/tests/coretests/src/android/app/appsearch/AppSearchSessionUnitTest.java
@@ -42,8 +42,8 @@
     public void setUp() throws Exception {
         // Remove all documents from any instances that may have been created in the tests.
         Objects.requireNonNull(mAppSearch);
-        AppSearchManager.SearchContext searchContext = new AppSearchManager.SearchContext.Builder()
-                .setDatabaseName("testDb").build();
+        AppSearchManager.SearchContext searchContext =
+                new AppSearchManager.SearchContext.Builder("testDb").build();
         CompletableFuture<AppSearchResult<AppSearchSession>> future = new CompletableFuture<>();
         mAppSearch.createSearchSession(searchContext, mExecutor, future::complete);
         mSearchSession = future.get().getResultValue();
@@ -51,7 +51,7 @@
         CompletableFuture<AppSearchResult<SetSchemaResponse>> schemaFuture =
                 new CompletableFuture<>();
         mSearchSession.setSchema(
-                new SetSchemaRequest.Builder().setForceOverride(true).build(), mExecutor,
+                new SetSchemaRequest.Builder().setForceOverride(true).build(), mExecutor, mExecutor,
                 schemaFuture::complete);
 
         schemaFuture.get().getResultValue();
diff --git a/core/tests/coretests/src/android/app/people/PeopleSpaceTileTest.java b/core/tests/coretests/src/android/app/people/PeopleSpaceTileTest.java
index 7cb6804..36da927 100644
--- a/core/tests/coretests/src/android/app/people/PeopleSpaceTileTest.java
+++ b/core/tests/coretests/src/android/app/people/PeopleSpaceTileTest.java
@@ -235,6 +235,7 @@
                 .setStatuses(statusList).setNotificationKey("key")
                 .setNotificationContent("content")
                 .setNotificationDataUri(Uri.parse("data"))
+                .setMessagesCount(2)
                 .setIntent(new Intent())
                 .build();
 
@@ -256,6 +257,7 @@
         assertThat(readTile.getNotificationKey()).isEqualTo(tile.getNotificationKey());
         assertThat(readTile.getNotificationContent()).isEqualTo(tile.getNotificationContent());
         assertThat(readTile.getNotificationDataUri()).isEqualTo(tile.getNotificationDataUri());
+        assertThat(readTile.getMessagesCount()).isEqualTo(tile.getMessagesCount());
         assertThat(readTile.getIntent().toString()).isEqualTo(tile.getIntent().toString());
     }
 
@@ -291,6 +293,17 @@
     }
 
     @Test
+    public void testMessagesCount() {
+        PeopleSpaceTile tile =
+                new PeopleSpaceTile.Builder(new ShortcutInfo.Builder(mContext, "123").build(),
+                        mLauncherApps)
+                        .setMessagesCount(2)
+                        .build();
+
+        assertThat(tile.getMessagesCount()).isEqualTo(2);
+    }
+
+    @Test
     public void testIntent() {
         PeopleSpaceTile tile = new PeopleSpaceTile.Builder(
                 new ShortcutInfo.Builder(mContext, "123").build(), mLauncherApps).build();
diff --git a/core/tests/coretests/src/android/content/ComponentCallbacksControllerTest.java b/core/tests/coretests/src/android/content/ComponentCallbacksControllerTest.java
new file mode 100644
index 0000000..09985a8
--- /dev/null
+++ b/core/tests/coretests/src/android/content/ComponentCallbacksControllerTest.java
@@ -0,0 +1,140 @@
+/*
+ * 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 android.content;
+
+import static android.content.ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.app.WindowConfiguration;
+import android.content.res.Configuration;
+import android.graphics.Rect;
+
+import androidx.annotation.NonNull;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ *  Build/Install/Run:
+ *   atest FrameworksCoreTests:ComponentCallbacksControllerTest
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class ComponentCallbacksControllerTest {
+    private ComponentCallbacksController mController;
+
+    @Before
+    public void setUp() {
+        mController = new ComponentCallbacksController();
+    }
+
+    @Test
+    public void testUnregisterCallbackWithoutRegistrationNoCrash() {
+        mController.unregisterCallbacks(new FakeComponentCallbacks());
+    }
+
+    @Test
+    public void testDispatchWithEmptyCallbacksNoCrash() {
+        mController.dispatchConfigurationChanged(new Configuration());
+        mController.dispatchLowMemory();
+        mController.dispatchTrimMemory(TRIM_MEMORY_BACKGROUND);
+    }
+
+    @Test
+    public void testClearCallbacksNoCrash() {
+        mController.clearCallbacks();
+    }
+
+    @Test
+    public void testDispatchTrimMemoryWithoutComponentCallbacks2NoCrash() {
+        // Register a ComponentCallbacks instead of ComponentCallbacks2
+        mController.registerCallbacks(new FakeComponentCallbacks());
+
+        mController.dispatchTrimMemory(TRIM_MEMORY_BACKGROUND);
+    }
+
+    @Test
+    public void testDispatchConfigurationChanged() throws Exception {
+        final TestComponentCallbacks2 callback = new TestComponentCallbacks2();
+        mController.registerCallbacks(callback);
+
+        final Configuration config = new Configuration();
+        config.windowConfiguration.setWindowingMode(WindowConfiguration.WINDOWING_MODE_FREEFORM);
+        config.windowConfiguration.setBounds(new Rect(0, 0, 100, 100));
+
+        mController.dispatchConfigurationChanged(config);
+
+        assertThat(callback.mConfiguration).isEqualTo(config);
+
+        mController.dispatchConfigurationChanged(Configuration.EMPTY);
+
+        assertThat(callback.mConfiguration).isEqualTo(Configuration.EMPTY);
+    }
+
+    @Test
+    public void testDispatchLowMemory() {
+        final TestComponentCallbacks2 callback = new TestComponentCallbacks2();
+        mController.registerCallbacks(callback);
+
+        mController.dispatchLowMemory();
+
+        assertThat(callback.mLowMemoryCalled).isTrue();
+    }
+
+    @Test
+    public void testDispatchTrimMemory() {
+        final TestComponentCallbacks2 callback = new TestComponentCallbacks2();
+        mController.registerCallbacks(callback);
+
+        mController.dispatchTrimMemory(TRIM_MEMORY_BACKGROUND);
+
+        assertThat(callback.mLevel).isEqualTo(TRIM_MEMORY_BACKGROUND);
+    }
+
+    private static class FakeComponentCallbacks implements ComponentCallbacks {
+        @Override
+        public void onConfigurationChanged(@NonNull Configuration newConfig) {}
+
+        @Override
+        public void onLowMemory() {}
+    }
+
+    private static class TestComponentCallbacks2 implements ComponentCallbacks2 {
+        private Configuration mConfiguration;
+        private boolean mLowMemoryCalled;
+        private int mLevel;
+
+        @Override
+        public void onConfigurationChanged(@NonNull Configuration newConfig) {
+            mConfiguration = newConfig;
+        }
+
+        @Override
+        public void onLowMemory() {
+            mLowMemoryCalled = true;
+        }
+
+        @Override
+        public void onTrimMemory(int level) {
+            mLevel = level;
+        }
+    }
+}
diff --git a/core/tests/coretests/src/android/content/ContentResolverTest.java b/core/tests/coretests/src/android/content/ContentResolverTest.java
index b517428..01e240a 100644
--- a/core/tests/coretests/src/android/content/ContentResolverTest.java
+++ b/core/tests/coretests/src/android/content/ContentResolverTest.java
@@ -86,7 +86,7 @@
 
         final AssetFileDescriptor afd = new AssetFileDescriptor(
                 new ParcelFileDescriptor(mImage.getFileDescriptor()), 0, mSize, null);
-        when(mProvider.openTypedAssetFile(any(), any(), any(), any(), any(), any())).thenReturn(
+        when(mProvider.openTypedAssetFile(any(), any(), any(), any(), any())).thenReturn(
                 afd);
     }
 
diff --git a/core/tests/coretests/src/android/content/OWNERS b/core/tests/coretests/src/android/content/OWNERS
index c61a4b5..0b94589 100644
--- a/core/tests/coretests/src/android/content/OWNERS
+++ b/core/tests/coretests/src/android/content/OWNERS
@@ -2,3 +2,5 @@
 per-file ContextTest.java = file:/services/core/java/com/android/server/wm/OWNERS
 per-file *Launcher* = file:/core/java/android/content/pm/LAUNCHER_OWNERS
 per-file *Shortcut* = file:/core/java/android/content/pm/SHORTCUT_OWNERS
+per-file ComponentCallbacksControllerTest = file:/services/core/java/com/android/server/wm/OWNERS
+per-file ComponentCallbacksControllerTest = charlesccchen@google.com
diff --git a/core/tests/coretests/src/android/content/pm/AppSearchShortcutInfoTest.java b/core/tests/coretests/src/android/content/pm/AppSearchShortcutInfoTest.java
index ffe93bc..21eb44a 100644
--- a/core/tests/coretests/src/android/content/pm/AppSearchShortcutInfoTest.java
+++ b/core/tests/coretests/src/android/content/pm/AppSearchShortcutInfoTest.java
@@ -45,7 +45,7 @@
         final Set<String> categorySet = new ArraySet<>();
         categorySet.add(category);
         final Intent shortcutIntent = new Intent(Intent.ACTION_VIEW);
-        final ShortcutInfo shortcut = new AppSearchShortcutInfo.Builder(id)
+        final ShortcutInfo shortcut = new AppSearchShortcutInfo.Builder(/*packageName=*/"", id)
                 .setActivity(activity)
                 .setLongLabel(id)
                 .setIconResName(shortcutIconResName)
diff --git a/core/tests/coretests/src/android/os/CombinedVibrationEffectTest.java b/core/tests/coretests/src/android/os/CombinedVibrationEffectTest.java
index 11239db..30b2d8e 100644
--- a/core/tests/coretests/src/android/os/CombinedVibrationEffectTest.java
+++ b/core/tests/coretests/src/android/os/CombinedVibrationEffectTest.java
@@ -28,13 +28,15 @@
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 
 @Presubmit
 @RunWith(JUnit4.class)
 public class CombinedVibrationEffectTest {
     private static final VibrationEffect VALID_EFFECT = VibrationEffect.createOneShot(10, 255);
-    private static final VibrationEffect INVALID_EFFECT = new VibrationEffect.OneShot(-1, -1);
+    private static final VibrationEffect INVALID_EFFECT = new VibrationEffect.Composed(
+            new ArrayList<>(), 0);
 
     @Test
     public void testValidateMono() {
diff --git a/core/tests/coretests/src/android/os/VibrationEffectTest.java b/core/tests/coretests/src/android/os/VibrationEffectTest.java
index d555cd9..009665f 100644
--- a/core/tests/coretests/src/android/os/VibrationEffectTest.java
+++ b/core/tests/coretests/src/android/os/VibrationEffectTest.java
@@ -18,13 +18,9 @@
 
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertNotNull;
-import static junit.framework.Assert.assertNotSame;
 import static junit.framework.Assert.assertNull;
-import static junit.framework.Assert.assertSame;
 import static junit.framework.Assert.assertTrue;
-import static junit.framework.Assert.fail;
 
-import static org.junit.Assert.assertArrayEquals;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
@@ -35,11 +31,13 @@
 import android.content.Context;
 import android.content.res.Resources;
 import android.net.Uri;
+import android.os.vibrator.PrebakedSegment;
+import android.os.vibrator.PrimitiveSegment;
+import android.os.vibrator.StepSegment;
 import android.platform.test.annotations.Presubmit;
 
 import com.android.internal.R;
 
-import org.junit.Assert;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.junit.MockitoJUnitRunner;
@@ -53,9 +51,6 @@
     private static final String RINGTONE_URI_3 = "content://test/system/ringtone_3";
     private static final String UNKNOWN_URI = "content://test/system/other_audio";
 
-    private static final float INTENSITY_SCALE_TOLERANCE = 1e-2f;
-    private static final int AMPLITUDE_SCALE_TOLERANCE = 1;
-
     private static final long TEST_TIMING = 100;
     private static final int TEST_AMPLITUDE = 100;
     private static final long[] TEST_TIMINGS = new long[] { 100, 100, 200 };
@@ -68,12 +63,6 @@
             VibrationEffect.createOneShot(TEST_TIMING, VibrationEffect.DEFAULT_AMPLITUDE);
     private static final VibrationEffect TEST_WAVEFORM =
             VibrationEffect.createWaveform(TEST_TIMINGS, TEST_AMPLITUDES, -1);
-    private static final VibrationEffect TEST_COMPOSED =
-            VibrationEffect.startComposition()
-                    .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f, 1)
-                    .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 0.5f, 10)
-                    .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 0f, 100)
-                    .compose();
 
     @Test
     public void getRingtones_noPrebakedRingtones() {
@@ -129,7 +118,16 @@
     public void testValidateWaveform() {
         VibrationEffect.createWaveform(TEST_TIMINGS, TEST_AMPLITUDES, -1).validate();
         VibrationEffect.createWaveform(TEST_TIMINGS, TEST_AMPLITUDES, 0).validate();
+        VibrationEffect.startWaveform()
+                .addStep(/* amplitude= */ 1, /* duration= */ 10)
+                .addRamp(/* amplitude= */ 0, /* duration= */ 20)
+                .addStep(/* amplitude= */ 1, /* frequency*/ 1, /* duration= */ 100)
+                .addRamp(/* amplitude= */ 0.5f, /* frequency*/ -1, /* duration= */ 50)
+                .build()
+                .validate();
 
+        assertThrows(IllegalStateException.class,
+                () -> VibrationEffect.startWaveform().build().validate());
         assertThrows(IllegalArgumentException.class,
                 () -> VibrationEffect.createWaveform(new long[0], new int[0], -1).validate());
         assertThrows(IllegalArgumentException.class,
@@ -143,17 +141,31 @@
         assertThrows(IllegalArgumentException.class,
                 () -> VibrationEffect.createWaveform(
                         TEST_TIMINGS, TEST_AMPLITUDES, TEST_TIMINGS.length).validate());
+        assertThrows(IllegalArgumentException.class,
+                () -> VibrationEffect.startWaveform()
+                        .addStep(/* amplitude= */ -2, 10).build().validate());
+        assertThrows(IllegalArgumentException.class,
+                () -> VibrationEffect.startWaveform()
+                        .addStep(1, /* duration= */ -1).build().validate());
+        assertThrows(IllegalArgumentException.class,
+                () -> VibrationEffect.startWaveform()
+                        .addStep(1, 0, /* duration= */ -1).build().validate());
     }
 
     @Test
     public void testValidateComposed() {
         VibrationEffect.startComposition()
                 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK)
+                .addEffect(TEST_ONE_SHOT)
                 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f)
+                .addEffect(TEST_WAVEFORM, 100)
                 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 0.5f, 10)
+                .addEffect(VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
                 .compose()
                 .validate();
 
+        assertThrows(IllegalStateException.class,
+                () -> VibrationEffect.startComposition().compose().validate());
         assertThrows(IllegalArgumentException.class,
                 () -> VibrationEffect.startComposition().addPrimitive(-1).compose().validate());
         assertThrows(IllegalArgumentException.class,
@@ -163,256 +175,138 @@
                         .validate());
         assertThrows(IllegalArgumentException.class,
                 () -> VibrationEffect.startComposition()
+                        .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1, -10)
+                        .compose()
+                        .validate());
+        assertThrows(IllegalArgumentException.class,
+                () -> VibrationEffect.startComposition()
+                        .addEffect(TEST_ONE_SHOT, /* delay= */ -10)
+                        .compose()
+                        .validate());
+        assertThrows(IllegalArgumentException.class,
+                () -> VibrationEffect.startComposition()
                         .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f, -1)
                         .compose()
                         .validate());
     }
 
     @Test
-    public void testScalePrebaked_scalesFallbackEffect() {
-        VibrationEffect.Prebaked prebaked =
-                (VibrationEffect.Prebaked) VibrationEffect.get(VibrationEffect.RINGTONES[1]);
-        assertSame(prebaked, prebaked.scale(0.5f));
-
-        prebaked = new VibrationEffect.Prebaked(VibrationEffect.EFFECT_CLICK,
-                VibrationEffect.EFFECT_STRENGTH_MEDIUM, TEST_ONE_SHOT);
-        VibrationEffect.OneShot scaledFallback =
-                (VibrationEffect.OneShot) prebaked.scale(0.5f).getFallbackEffect();
-        assertEquals(34, scaledFallback.getAmplitude(), AMPLITUDE_SCALE_TOLERANCE);
-    }
-
-    @Test
-    public void testResolvePrebaked_resolvesFallbackEffectIfSet() {
-        VibrationEffect.Prebaked prebaked =
-                (VibrationEffect.Prebaked) VibrationEffect.get(VibrationEffect.RINGTONES[1]);
-        assertSame(prebaked, prebaked.resolve(1000));
-
-        prebaked = new VibrationEffect.Prebaked(VibrationEffect.EFFECT_CLICK,
-                VibrationEffect.EFFECT_STRENGTH_MEDIUM,
-                VibrationEffect.createOneShot(1, VibrationEffect.DEFAULT_AMPLITUDE));
-        VibrationEffect.OneShot resolvedFallback =
-                (VibrationEffect.OneShot) prebaked.resolve(10).getFallbackEffect();
-        assertEquals(10, resolvedFallback.getAmplitude());
-    }
-
-    @Test
-    public void testScaleOneShot() {
-        VibrationEffect.OneShot unset = new VibrationEffect.OneShot(
-                TEST_TIMING, VibrationEffect.DEFAULT_AMPLITUDE);
-        assertEquals(VibrationEffect.DEFAULT_AMPLITUDE, unset.scale(2).getAmplitude());
-
-        VibrationEffect.OneShot initial = (VibrationEffect.OneShot) TEST_ONE_SHOT;
-
-        VibrationEffect.OneShot halved = initial.scale(0.5f);
-        assertEquals(34, halved.getAmplitude(), AMPLITUDE_SCALE_TOLERANCE);
-
-        VibrationEffect.OneShot copied = initial.scale(1f);
-        assertEquals(TEST_AMPLITUDE, copied.getAmplitude());
-
-        VibrationEffect.OneShot scaledUp = initial.scale(1.5f);
-        assertTrue(scaledUp.getAmplitude() > initial.getAmplitude());
-        VibrationEffect.OneShot restored = scaledUp.scale(2 / 3f);
-        // Does not restore to the exact original value because scale up is a bit offset.
-        assertEquals(105, restored.getAmplitude(), AMPLITUDE_SCALE_TOLERANCE);
-
-        VibrationEffect.OneShot scaledDown = initial.scale(0.8f);
-        assertTrue(scaledDown.getAmplitude() < initial.getAmplitude());
-        restored = scaledDown.scale(1.25f);
-        // Does not restore to the exact original value because scale up is a bit offset.
-        assertEquals(101, restored.getAmplitude(), AMPLITUDE_SCALE_TOLERANCE);
-
-        // Does not go below min amplitude while scaling down.
-        VibrationEffect.OneShot minAmplitude = new VibrationEffect.OneShot(TEST_TIMING, 1);
-        assertEquals(1, minAmplitude.scale(0.5f).getAmplitude());
-    }
-
-    @Test
     public void testResolveOneShot() {
-        VibrationEffect.OneShot initial = (VibrationEffect.OneShot) DEFAULT_ONE_SHOT;
-        VibrationEffect.OneShot resolved = initial.resolve(239);
-        assertNotSame(initial, resolved);
-        assertEquals(239, resolved.getAmplitude());
+        VibrationEffect.Composed resolved = DEFAULT_ONE_SHOT.resolve(51);
+        assertEquals(0.2f, ((StepSegment) resolved.getSegments().get(0)).getAmplitude());
 
-        // Ignores input when amplitude already set.
-        VibrationEffect.OneShot resolved2 = resolved.resolve(10);
-        assertSame(resolved, resolved2);
-        assertEquals(239, resolved2.getAmplitude());
-    }
-
-    @Test
-    public void testResolveOneshotFailsWhenMaxAmplitudeAboveThreshold() {
-        try {
-            TEST_ONE_SHOT.resolve(1000);
-            fail("Max amplitude above threshold, should throw IllegalArgumentException");
-        } catch (IllegalArgumentException expected) {
-        }
-    }
-
-    @Test
-    public void testResolveOneshotFailsWhenAmplitudeNonPositive() {
-        try {
-            TEST_ONE_SHOT.resolve(0);
-            fail("Amplitude is set to zero, should throw IllegalArgumentException");
-        } catch (IllegalArgumentException expected) {
-        }
-    }
-
-    @Test
-    public void testScaleWaveform() {
-        VibrationEffect.Waveform initial = (VibrationEffect.Waveform) TEST_WAVEFORM;
-
-        VibrationEffect.Waveform copied = initial.scale(1f);
-        assertArrayEquals(TEST_AMPLITUDES, copied.getAmplitudes());
-
-        VibrationEffect.Waveform scaled = initial.scale(0.9f);
-        assertEquals(216, scaled.getAmplitudes()[0], AMPLITUDE_SCALE_TOLERANCE);
-        assertEquals(0, scaled.getAmplitudes()[1]);
-        assertEquals(-1, scaled.getAmplitudes()[2]);
-
-        VibrationEffect.Waveform minAmplitude = new VibrationEffect.Waveform(
-                new long[]{100}, new int[] {1}, -1);
-        assertArrayEquals(new int[]{1}, minAmplitude.scale(0.5f).getAmplitudes());
+        assertThrows(IllegalArgumentException.class, () -> DEFAULT_ONE_SHOT.resolve(1000));
     }
 
     @Test
     public void testResolveWaveform() {
-        VibrationEffect.Waveform initial = (VibrationEffect.Waveform) TEST_WAVEFORM;
-        VibrationEffect.Waveform resolved = initial.resolve(123);
-        assertNotSame(initial, resolved);
-        assertArrayEquals(new int[]{255, 0, 123}, resolved.getAmplitudes());
+        VibrationEffect.Composed resolved = TEST_WAVEFORM.resolve(102);
+        assertEquals(0.4f, ((StepSegment) resolved.getSegments().get(2)).getAmplitude());
 
-        // Ignores input when amplitude already set.
-        VibrationEffect.Waveform resolved2 = resolved.resolve(10);
-        assertSame(resolved, resolved2);
-        assertArrayEquals(new int[]{255, 0, 123}, resolved2.getAmplitudes());
+        assertThrows(IllegalArgumentException.class, () -> TEST_WAVEFORM.resolve(1000));
     }
 
     @Test
-    public void testResolveWaveformFailsWhenMaxAmplitudeAboveThreshold() {
-        try {
-            TEST_WAVEFORM.resolve(1000);
-            fail("Max amplitude above threshold, should throw IllegalArgumentException");
-        } catch (IllegalArgumentException expected) {
-        }
+    public void testResolvePrebaked() {
+        VibrationEffect effect = VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
+        assertEquals(effect, effect.resolve(51));
+    }
+
+    @Test
+    public void testResolveComposed() {
+        VibrationEffect effect = VibrationEffect.startComposition()
+                .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f, 1)
+                .compose();
+        assertEquals(effect, effect.resolve(51));
+
+        VibrationEffect.Composed resolved = VibrationEffect.startComposition()
+                .addEffect(DEFAULT_ONE_SHOT)
+                .compose()
+                .resolve(51);
+        assertEquals(0.2f, ((StepSegment) resolved.getSegments().get(0)).getAmplitude());
+    }
+
+    @Test
+    public void testApplyEffectStrengthOneShot() {
+        VibrationEffect.Composed applied = DEFAULT_ONE_SHOT.applyEffectStrength(
+                VibrationEffect.EFFECT_STRENGTH_LIGHT);
+        assertEquals(DEFAULT_ONE_SHOT, applied);
+    }
+
+    @Test
+    public void testApplyEffectStrengthWaveform() {
+        VibrationEffect.Composed applied = TEST_WAVEFORM.applyEffectStrength(
+                VibrationEffect.EFFECT_STRENGTH_LIGHT);
+        assertEquals(TEST_WAVEFORM, applied);
+    }
+
+    @Test
+    public void testApplyEffectStrengthPrebaked() {
+        VibrationEffect.Composed applied = VibrationEffect.get(VibrationEffect.EFFECT_CLICK)
+                .applyEffectStrength(VibrationEffect.EFFECT_STRENGTH_LIGHT);
+        assertEquals(VibrationEffect.EFFECT_STRENGTH_LIGHT,
+                ((PrebakedSegment) applied.getSegments().get(0)).getEffectStrength());
+    }
+
+    @Test
+    public void testApplyEffectStrengthComposed() {
+        VibrationEffect effect = VibrationEffect.startComposition()
+                .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 0.5f, 1)
+                .compose();
+        assertEquals(effect, effect.applyEffectStrength(VibrationEffect.EFFECT_STRENGTH_LIGHT));
+
+        VibrationEffect.Composed applied = VibrationEffect.startComposition()
+                .addEffect(VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
+                .compose()
+                .applyEffectStrength(VibrationEffect.EFFECT_STRENGTH_LIGHT);
+        assertEquals(VibrationEffect.EFFECT_STRENGTH_LIGHT,
+                ((PrebakedSegment) applied.getSegments().get(0)).getEffectStrength());
+    }
+
+    @Test
+    public void testScaleOneShot() {
+        VibrationEffect.Composed scaledUp = TEST_ONE_SHOT.scale(1.5f);
+        assertTrue(100 / 255f < ((StepSegment) scaledUp.getSegments().get(0)).getAmplitude());
+
+        VibrationEffect.Composed scaledDown = TEST_ONE_SHOT.scale(0.5f);
+        assertTrue(100 / 255f > ((StepSegment) scaledDown.getSegments().get(0)).getAmplitude());
+    }
+
+    @Test
+    public void testScaleWaveform() {
+        VibrationEffect.Composed scaledUp = TEST_WAVEFORM.scale(1.5f);
+        assertEquals(1f, ((StepSegment) scaledUp.getSegments().get(0)).getAmplitude(), 1e-5f);
+
+        VibrationEffect.Composed scaledDown = TEST_WAVEFORM.scale(0.5f);
+        assertTrue(1f > ((StepSegment) scaledDown.getSegments().get(0)).getAmplitude());
+    }
+
+    @Test
+    public void testScalePrebaked() {
+        VibrationEffect effect = VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
+
+        VibrationEffect.Composed scaledUp = effect.scale(1.5f);
+        assertEquals(effect, scaledUp);
+
+        VibrationEffect.Composed scaledDown = effect.scale(0.5f);
+        assertEquals(effect, scaledDown);
     }
 
     @Test
     public void testScaleComposed() {
-        VibrationEffect.Composed initial = (VibrationEffect.Composed) TEST_COMPOSED;
-
-        VibrationEffect.Composed copied = initial.scale(1);
-        assertEquals(1f, copied.getPrimitiveEffects().get(0).scale);
-        assertEquals(0.5f, copied.getPrimitiveEffects().get(1).scale);
-        assertEquals(0f, copied.getPrimitiveEffects().get(2).scale);
-
-        VibrationEffect.Composed halved = initial.scale(0.5f);
-        assertEquals(0.34f, halved.getPrimitiveEffects().get(0).scale, INTENSITY_SCALE_TOLERANCE);
-        assertEquals(0.17f, halved.getPrimitiveEffects().get(1).scale, INTENSITY_SCALE_TOLERANCE);
-        assertEquals(0f, halved.getPrimitiveEffects().get(2).scale);
-
-        VibrationEffect.Composed scaledUp = initial.scale(1.5f);
-        // Does not scale up from 1.
-        assertEquals(1f, scaledUp.getPrimitiveEffects().get(0).scale, INTENSITY_SCALE_TOLERANCE);
-        assertTrue(0.5f < scaledUp.getPrimitiveEffects().get(1).scale);
-        assertEquals(0f, scaledUp.getPrimitiveEffects().get(2).scale);
-
-        VibrationEffect.Composed restored = scaledUp.scale(2 / 3f);
-        // The original value was not scaled up, so this only scales it down.
-        assertEquals(0.53f, restored.getPrimitiveEffects().get(0).scale, INTENSITY_SCALE_TOLERANCE);
-        // Does not restore to the exact original value because scale up is a bit offset.
-        assertEquals(0.47f, restored.getPrimitiveEffects().get(1).scale, INTENSITY_SCALE_TOLERANCE);
-        assertEquals(0f, restored.getPrimitiveEffects().get(2).scale);
-
-        VibrationEffect.Composed scaledDown = initial.scale(0.8f);
-        assertTrue(1f > scaledDown.getPrimitiveEffects().get(0).scale);
-        assertTrue(0.5f > scaledDown.getPrimitiveEffects().get(1).scale);
-        assertEquals(0f, scaledDown.getPrimitiveEffects().get(2).scale);
-
-        restored = scaledDown.scale(1.25f);
-        // Does not restore to the exact original value because scale up is a bit offset.
-        assertEquals(0.84f, restored.getPrimitiveEffects().get(0).scale, INTENSITY_SCALE_TOLERANCE);
-        assertEquals(0.5f, restored.getPrimitiveEffects().get(1).scale, INTENSITY_SCALE_TOLERANCE);
-        assertEquals(0f, restored.getPrimitiveEffects().get(2).scale);
-    }
-
-    @Test
-    public void testResolveComposed_ignoresDefaultAmplitudeAndReturnsSameEffect() {
-        VibrationEffect initial = TEST_COMPOSED;
-        assertSame(initial, initial.resolve(1000));
-    }
-
-    @Test
-    public void testScaleAppliesSameAdjustmentsOnAllEffects() {
-        VibrationEffect.OneShot oneShot = new VibrationEffect.OneShot(TEST_TIMING, TEST_AMPLITUDE);
-        VibrationEffect.Waveform waveform = new VibrationEffect.Waveform(
-                new long[] { TEST_TIMING }, new int[]{ TEST_AMPLITUDE }, -1);
-        VibrationEffect.Composed composed =
+        VibrationEffect.Composed effect =
                 (VibrationEffect.Composed) VibrationEffect.startComposition()
-                        .addPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK,
-                                TEST_AMPLITUDE / 255f)
+                        .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 0.5f, 1)
+                        .addEffect(TEST_ONE_SHOT)
                         .compose();
 
-        assertEquals(oneShot.scale(0.8f).getAmplitude(),
-                waveform.scale(0.8f).getAmplitudes()[0],
-                AMPLITUDE_SCALE_TOLERANCE);
-        assertEquals(oneShot.scale(1.2f).getAmplitude() / 255f,
-                composed.scale(1.2f).getPrimitiveEffects().get(0).scale,
-                INTENSITY_SCALE_TOLERANCE);
-    }
+        VibrationEffect.Composed scaledUp = effect.scale(1.5f);
+        assertTrue(0.5f < ((PrimitiveSegment) scaledUp.getSegments().get(0)).getScale());
+        assertTrue(100 / 255f < ((StepSegment) scaledUp.getSegments().get(1)).getAmplitude());
 
-    @Test
-    public void testScaleOnMaxAmplitude() {
-        VibrationEffect.OneShot oneShot = new VibrationEffect.OneShot(
-                TEST_TIMING, VibrationEffect.MAX_AMPLITUDE);
-        VibrationEffect.Waveform waveform = new VibrationEffect.Waveform(
-                new long[]{TEST_TIMING}, new int[]{VibrationEffect.MAX_AMPLITUDE}, -1);
-        VibrationEffect.Composed composed =
-                (VibrationEffect.Composed) VibrationEffect.startComposition()
-                        .addPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK)
-                        .compose();
-
-        // Scale up does NOT scale MAX_AMPLITUDE
-        assertEquals(VibrationEffect.MAX_AMPLITUDE, oneShot.scale(1.1f).getAmplitude());
-        assertEquals(VibrationEffect.MAX_AMPLITUDE, waveform.scale(1.2f).getAmplitudes()[0]);
-        assertEquals(1f,
-                composed.scale(1.4f).getPrimitiveEffects().get(0).scale,
-                INTENSITY_SCALE_TOLERANCE); // This needs tolerance for float point comparison.
-
-        // Scale down does scale MAX_AMPLITUDE
-        assertEquals(216, oneShot.scale(0.9f).getAmplitude(), AMPLITUDE_SCALE_TOLERANCE);
-        assertEquals(180, waveform.scale(0.8f).getAmplitudes()[0], AMPLITUDE_SCALE_TOLERANCE);
-        assertEquals(0.57f, composed.scale(0.7f).getPrimitiveEffects().get(0).scale,
-                INTENSITY_SCALE_TOLERANCE);
-    }
-
-    @Test
-    public void getEffectStrength_returnsValueFromConstructor() {
-        VibrationEffect.Prebaked effect = new VibrationEffect.Prebaked(VibrationEffect.EFFECT_CLICK,
-                VibrationEffect.EFFECT_STRENGTH_LIGHT, null);
-        Assert.assertEquals(VibrationEffect.EFFECT_STRENGTH_LIGHT, effect.getEffectStrength());
-    }
-
-    @Test
-    public void getFallbackEffect_withFallbackDisabled_isNull() {
-        VibrationEffect fallback = VibrationEffect.createOneShot(100, 100);
-        VibrationEffect.Prebaked effect = new VibrationEffect.Prebaked(VibrationEffect.EFFECT_CLICK,
-                false, VibrationEffect.EFFECT_STRENGTH_LIGHT);
-        Assert.assertNull(effect.getFallbackEffect());
-    }
-
-    @Test
-    public void getFallbackEffect_withoutEffectSet_isNull() {
-        VibrationEffect.Prebaked effect = new VibrationEffect.Prebaked(VibrationEffect.EFFECT_CLICK,
-                true, VibrationEffect.EFFECT_STRENGTH_LIGHT);
-        Assert.assertNull(effect.getFallbackEffect());
-    }
-
-    @Test
-    public void getFallbackEffect_withFallback_returnsValueFromConstructor() {
-        VibrationEffect fallback = VibrationEffect.createOneShot(100, 100);
-        VibrationEffect.Prebaked effect = new VibrationEffect.Prebaked(VibrationEffect.EFFECT_CLICK,
-                VibrationEffect.EFFECT_STRENGTH_LIGHT, fallback);
-        Assert.assertEquals(fallback, effect.getFallbackEffect());
+        VibrationEffect.Composed scaledDown = effect.scale(0.5f);
+        assertTrue(0.5f > ((PrimitiveSegment) scaledDown.getSegments().get(0)).getScale());
+        assertTrue(100 / 255f > ((StepSegment) scaledDown.getSegments().get(1)).getAmplitude());
     }
 
     private Resources mockRingtoneResources() {
@@ -448,4 +342,4 @@
 
         return context;
     }
-}
\ No newline at end of file
+}
diff --git a/core/tests/coretests/src/android/os/VibratorInfoTest.java b/core/tests/coretests/src/android/os/VibratorInfoTest.java
index 09c36dd..2521f75 100644
--- a/core/tests/coretests/src/android/os/VibratorInfoTest.java
+++ b/core/tests/coretests/src/android/os/VibratorInfoTest.java
@@ -21,8 +21,10 @@
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertTrue;
 
+import android.hardware.vibrator.Braking;
 import android.hardware.vibrator.IVibrator;
 import android.platform.test.annotations.Presubmit;
+import android.util.Range;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -31,6 +33,20 @@
 @Presubmit
 @RunWith(JUnit4.class)
 public class VibratorInfoTest {
+    private static final float TEST_TOLERANCE = 1e-5f;
+
+    private static final float TEST_MIN_FREQUENCY = 50;
+    private static final float TEST_RESONANT_FREQUENCY = 150;
+    private static final float TEST_FREQUENCY_RESOLUTION = 25;
+    private static final float[] TEST_AMPLITUDE_MAP = new float[]{
+            /* 50Hz= */ 0.1f, 0.2f, 0.4f, 0.8f, /* 150Hz= */ 1f, 0.9f, /* 200Hz= */ 0.8f};
+
+    private static final VibratorInfo.FrequencyMapping EMPTY_FREQUENCY_MAPPING =
+            new VibratorInfo.FrequencyMapping(Float.NaN, Float.NaN, Float.NaN, Float.NaN, null);
+    private static final VibratorInfo.FrequencyMapping TEST_FREQUENCY_MAPPING =
+            new VibratorInfo.FrequencyMapping(TEST_MIN_FREQUENCY,
+                    TEST_RESONANT_FREQUENCY, TEST_FREQUENCY_RESOLUTION,
+                    /* suggestedSafeRangeHz= */ 50, TEST_AMPLITUDE_MAP);
 
     @Test
     public void testHasAmplitudeControl() {
@@ -83,6 +99,149 @@
     }
 
     @Test
+    public void testGetDefaultBraking_returnsFirstSupportedBraking() {
+        assertEquals(Braking.NONE, new InfoBuilder().build().getDefaultBraking());
+        assertEquals(Braking.CLAB,
+                new InfoBuilder()
+                        .setSupportedBraking(Braking.NONE, Braking.CLAB)
+                        .build()
+                        .getDefaultBraking());
+    }
+
+    @Test
+    public void testGetFrequencyRange_invalidFrequencyMappingReturnsEmptyRange() {
+        // Invalid, contains NaN values or empty array.
+        assertEquals(Range.create(0f, 0f), new InfoBuilder().build().getFrequencyRange());
+        assertEquals(Range.create(0f, 0f), new InfoBuilder()
+                .setFrequencyMapping(new VibratorInfo.FrequencyMapping(
+                        Float.NaN, 150, 25, 50, TEST_AMPLITUDE_MAP))
+                .build().getFrequencyRange());
+        assertEquals(Range.create(0f, 0f), new InfoBuilder()
+                .setFrequencyMapping(new VibratorInfo.FrequencyMapping(
+                        50, Float.NaN, 25, 50, TEST_AMPLITUDE_MAP))
+                .build().getFrequencyRange());
+        assertEquals(Range.create(0f, 0f), new InfoBuilder()
+                .setFrequencyMapping(new VibratorInfo.FrequencyMapping(
+                        50, 150, Float.NaN, 50, TEST_AMPLITUDE_MAP))
+                .build().getFrequencyRange());
+        assertEquals(Range.create(0f, 0f), new InfoBuilder()
+                .setFrequencyMapping(new VibratorInfo.FrequencyMapping(
+                        50, 150, 25, Float.NaN, TEST_AMPLITUDE_MAP))
+                .build().getFrequencyRange());
+        assertEquals(Range.create(0f, 0f), new InfoBuilder()
+                .setFrequencyMapping(new VibratorInfo.FrequencyMapping(50, 150, 25, 50, null))
+                .build().getFrequencyRange());
+        // Invalid, minFrequency > resonantFrequency
+        assertEquals(Range.create(0f, 0f), new InfoBuilder()
+                .setFrequencyMapping(new VibratorInfo.FrequencyMapping(
+                        /* minFrequencyHz= */ 250, /* resonantFrequency= */ 150, 25, 50, null))
+                .build().getFrequencyRange());
+        // Invalid, maxFrequency < resonantFrequency by changing resolution.
+        assertEquals(Range.create(0f, 0f), new InfoBuilder()
+                .setFrequencyMapping(new VibratorInfo.FrequencyMapping(
+                        50, 150, /* frequencyResolutionHz= */10, 50, null))
+                .build().getFrequencyRange());
+    }
+
+    @Test
+    public void testGetFrequencyRange_safeRangeLimitedByMaxFrequency() {
+        VibratorInfo info = new InfoBuilder()
+                .setFrequencyMapping(new VibratorInfo.FrequencyMapping(
+                        /* minFrequencyHz= */ 50, /* resonantFrequencyHz= */ 150,
+                        /* frequencyResolutionHz= */ 25, /* suggestedSafeRangeHz= */ 200,
+                        TEST_AMPLITUDE_MAP))
+                .build();
+
+        // Mapping should range from 50Hz = -2 to 200Hz = 1
+        // Safe range [-1, 1] = [100Hz, 200Hz] defined by max - resonant = 50Hz
+        assertEquals(Range.create(-2f, 1f), info.getFrequencyRange());
+    }
+
+    @Test
+    public void testGetFrequencyRange_safeRangeLimitedByMinFrequency() {
+        VibratorInfo info = new InfoBuilder()
+                .setFrequencyMapping(new VibratorInfo.FrequencyMapping(
+                        /* minFrequencyHz= */ 50, /* resonantFrequencyHz= */ 150,
+                        /* frequencyResolutionHz= */ 50, /* suggestedSafeRangeHz= */ 200,
+                        TEST_AMPLITUDE_MAP))
+                .build();
+
+        // Mapping should range from 50Hz = -1 to 350Hz = 2
+        // Safe range [-1, 1] = [50Hz, 250Hz] defined by resonant - min = 100Hz
+        assertEquals(Range.create(-1f, 2f), info.getFrequencyRange());
+    }
+
+    @Test
+    public void testGetFrequencyRange_validMappingReturnsFullRelativeRange() {
+        VibratorInfo info = new InfoBuilder()
+                .setFrequencyMapping(new VibratorInfo.FrequencyMapping(
+                        /* minFrequencyHz= */ 50, /* resonantFrequencyHz= */ 150,
+                        /* frequencyResolutionHz= */ 50, /* suggestedSafeRangeHz= */ 100,
+                        TEST_AMPLITUDE_MAP))
+                .build();
+
+        // Mapping should range from 50Hz = -2 to 350Hz = 4
+        // Safe range [-1, 1] = [100Hz, 200Hz] defined by suggested safe range 100Hz
+        assertEquals(Range.create(-2f, 4f), info.getFrequencyRange());
+    }
+
+    @Test
+    public void testAbsoluteFrequency_emptyMappingReturnsNaN() {
+        VibratorInfo info = new InfoBuilder().build();
+        assertTrue(Float.isNaN(info.getAbsoluteFrequency(-1)));
+        assertTrue(Float.isNaN(info.getAbsoluteFrequency(0)));
+        assertTrue(Float.isNaN(info.getAbsoluteFrequency(1)));
+    }
+
+    @Test
+    public void testAbsoluteFrequency_validRangeReturnsOriginalValue() {
+        VibratorInfo info = new InfoBuilder().setFrequencyMapping(TEST_FREQUENCY_MAPPING).build();
+        assertEquals(TEST_RESONANT_FREQUENCY, info.getAbsoluteFrequency(0), TEST_TOLERANCE);
+
+        // Safe range [-1, 1] = [125Hz, 175Hz] defined by suggested safe range 100Hz
+        assertEquals(125, info.getAbsoluteFrequency(-1), TEST_TOLERANCE);
+        assertEquals(175, info.getAbsoluteFrequency(1), TEST_TOLERANCE);
+        assertEquals(155, info.getAbsoluteFrequency(0.2f), TEST_TOLERANCE);
+        assertEquals(140, info.getAbsoluteFrequency(-0.4f), TEST_TOLERANCE);
+
+        // Full range [-4, 2] = [50Hz, 200Hz] defined by min frequency and amplitude mapping size
+        assertEquals(50, info.getAbsoluteFrequency(info.getFrequencyRange().getLower()),
+                TEST_TOLERANCE);
+        assertEquals(200, info.getAbsoluteFrequency(info.getFrequencyRange().getUpper()),
+                TEST_TOLERANCE);
+    }
+
+    @Test
+    public void testGetMaxAmplitude_emptyMappingReturnsOnlyResonantFrequency() {
+        VibratorInfo info = new InfoBuilder().build();
+        assertEquals(1f, info.getMaxAmplitude(0), TEST_TOLERANCE);
+        assertEquals(0f, info.getMaxAmplitude(0.1f), TEST_TOLERANCE);
+        assertEquals(0f, info.getMaxAmplitude(-1), TEST_TOLERANCE);
+    }
+
+    @Test
+    public void testGetMaxAmplitude_validMappingReturnsMappedValues() {
+        VibratorInfo info = new InfoBuilder()
+                .setFrequencyMapping(new VibratorInfo.FrequencyMapping(/* minFrequencyHz= */ 50,
+                        /* resonantFrequencyHz= */ 150, /* frequencyResolutionHz= */ 25,
+                        /* suggestedSafeRangeHz= */ 50, TEST_AMPLITUDE_MAP))
+                .build();
+
+        assertEquals(1f, info.getMaxAmplitude(0), TEST_TOLERANCE); // 150Hz
+        assertEquals(0.9f, info.getMaxAmplitude(1), TEST_TOLERANCE); // 175Hz
+        assertEquals(0.8f, info.getMaxAmplitude(-1), TEST_TOLERANCE); // 125Hz
+        assertEquals(0.8f, info.getMaxAmplitude(info.getFrequencyRange().getUpper()),
+                TEST_TOLERANCE); // 200Hz
+        assertEquals(0.1f, info.getMaxAmplitude(info.getFrequencyRange().getLower()),
+                TEST_TOLERANCE); // 50Hz
+
+        // Rounds 145Hz to the max amplitude for 125Hz, which is lower.
+        assertEquals(0.8f, info.getMaxAmplitude(-0.1f), TEST_TOLERANCE); // 145Hz
+        // Rounds 185Hz to the max amplitude for 200Hz, which is lower.
+        assertEquals(0.8f, info.getMaxAmplitude(1.2f), TEST_TOLERANCE); // 185Hz
+    }
+
+    @Test
     public void testEquals() {
         InfoBuilder completeBuilder = new InfoBuilder()
                 .setId(1)
@@ -90,7 +249,7 @@
                 .setSupportedEffects(VibrationEffect.EFFECT_CLICK)
                 .setSupportedPrimitives(VibrationEffect.Composition.PRIMITIVE_CLICK)
                 .setQFactor(2f)
-                .setResonantFrequency(150f);
+                .setFrequencyMapping(TEST_FREQUENCY_MAPPING);
         VibratorInfo complete = completeBuilder.build();
 
         assertEquals(complete, complete);
@@ -110,22 +269,24 @@
         VibratorInfo completeWithUnknownEffects = completeBuilder
                 .setSupportedEffects(null)
                 .build();
-        assertNotEquals(complete, completeWithNoEffects);
+        assertNotEquals(complete, completeWithUnknownEffects);
 
         VibratorInfo completeWithUnknownPrimitives = completeBuilder
                 .setSupportedPrimitives(null)
                 .build();
         assertNotEquals(complete, completeWithUnknownPrimitives);
 
-        VibratorInfo completeWithDifferentF0 = completeBuilder
-                .setResonantFrequency(complete.getResonantFrequency() + 3f)
+        VibratorInfo completeWithDifferentFrequencyMapping = completeBuilder
+                .setFrequencyMapping(new VibratorInfo.FrequencyMapping(TEST_MIN_FREQUENCY + 10,
+                        TEST_RESONANT_FREQUENCY + 20, TEST_FREQUENCY_RESOLUTION + 5,
+                        /* suggestedSafeRangeHz= */ 100, TEST_AMPLITUDE_MAP))
                 .build();
-        assertNotEquals(complete, completeWithDifferentF0);
+        assertNotEquals(complete, completeWithDifferentFrequencyMapping);
 
-        VibratorInfo completeWithUnknownF0 = completeBuilder
-                .setResonantFrequency(Float.NaN)
+        VibratorInfo completeWithEmptyFrequencyMapping = completeBuilder
+                .setFrequencyMapping(EMPTY_FREQUENCY_MAPPING)
                 .build();
-        assertNotEquals(complete, completeWithUnknownF0);
+        assertNotEquals(complete, completeWithEmptyFrequencyMapping);
 
         VibratorInfo completeWithUnknownQFactor = completeBuilder
                 .setQFactor(Float.NaN)
@@ -153,8 +314,8 @@
                 .setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS)
                 .setSupportedEffects(VibrationEffect.EFFECT_CLICK)
                 .setSupportedPrimitives(null)
-                .setResonantFrequency(1.3f)
                 .setQFactor(Float.NaN)
+                .setFrequencyMapping(TEST_FREQUENCY_MAPPING)
                 .build();
 
         Parcel parcel = Parcel.obtain();
@@ -168,9 +329,10 @@
         private int mId = 0;
         private int mCapabilities = 0;
         private int[] mSupportedEffects = null;
+        private int[] mSupportedBraking = null;
         private int[] mSupportedPrimitives = null;
-        private float mResonantFrequency = Float.NaN;
         private float mQFactor = Float.NaN;
+        private VibratorInfo.FrequencyMapping mFrequencyMapping = EMPTY_FREQUENCY_MAPPING;
 
         public InfoBuilder setId(int id) {
             mId = id;
@@ -187,13 +349,13 @@
             return this;
         }
 
-        public InfoBuilder setSupportedPrimitives(int... supportedPrimitives) {
-            mSupportedPrimitives = supportedPrimitives;
+        public InfoBuilder setSupportedBraking(int... supportedBraking) {
+            mSupportedBraking = supportedBraking;
             return this;
         }
 
-        public InfoBuilder setResonantFrequency(float resonantFrequency) {
-            mResonantFrequency = resonantFrequency;
+        public InfoBuilder setSupportedPrimitives(int... supportedPrimitives) {
+            mSupportedPrimitives = supportedPrimitives;
             return this;
         }
 
@@ -202,9 +364,14 @@
             return this;
         }
 
+        public InfoBuilder setFrequencyMapping(VibratorInfo.FrequencyMapping frequencyMapping) {
+            mFrequencyMapping = frequencyMapping;
+            return this;
+        }
+
         public VibratorInfo build() {
-            return new VibratorInfo(mId, mCapabilities, mSupportedEffects, mSupportedPrimitives,
-                    mResonantFrequency, mQFactor);
+            return new VibratorInfo(mId, mCapabilities, mSupportedEffects, mSupportedBraking,
+                    mSupportedPrimitives, mQFactor, mFrequencyMapping);
         }
     }
 }
diff --git a/core/tests/coretests/src/android/os/vibrator/PrebakedSegmentTest.java b/core/tests/coretests/src/android/os/vibrator/PrebakedSegmentTest.java
new file mode 100644
index 0000000..de80812
--- /dev/null
+++ b/core/tests/coretests/src/android/os/vibrator/PrebakedSegmentTest.java
@@ -0,0 +1,108 @@
+/*
+ * 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 android.os.vibrator;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertSame;
+import static junit.framework.Assert.assertTrue;
+
+import static org.testng.Assert.assertNotEquals;
+import static org.testng.Assert.assertThrows;
+
+import android.os.Parcel;
+import android.os.VibrationEffect;
+import android.platform.test.annotations.Presubmit;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.junit.MockitoJUnitRunner;
+
+@Presubmit
+@RunWith(MockitoJUnitRunner.class)
+public class PrebakedSegmentTest {
+
+    @Test
+    public void testCreation() {
+        PrebakedSegment prebaked = new PrebakedSegment(
+                VibrationEffect.EFFECT_CLICK, true, VibrationEffect.EFFECT_STRENGTH_MEDIUM);
+
+        assertEquals(-1, prebaked.getDuration());
+        assertTrue(prebaked.hasNonZeroAmplitude());
+        assertEquals(VibrationEffect.EFFECT_CLICK, prebaked.getEffectId());
+        assertEquals(VibrationEffect.EFFECT_STRENGTH_MEDIUM, prebaked.getEffectStrength());
+        assertTrue(prebaked.shouldFallback());
+    }
+
+    @Test
+    public void testSerialization() {
+        PrebakedSegment original = new PrebakedSegment(
+                VibrationEffect.EFFECT_CLICK, true, VibrationEffect.EFFECT_STRENGTH_MEDIUM);
+        Parcel parcel = Parcel.obtain();
+        original.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        assertEquals(original, PrebakedSegment.CREATOR.createFromParcel(parcel));
+    }
+
+    @Test
+    public void testValidate() {
+        new PrebakedSegment(VibrationEffect.EFFECT_CLICK, true,
+                VibrationEffect.EFFECT_STRENGTH_MEDIUM).validate();
+
+        assertThrows(IllegalArgumentException.class,
+                () -> new PrebakedSegment(1000, true, VibrationEffect.EFFECT_STRENGTH_MEDIUM)
+                        .validate());
+        assertThrows(IllegalArgumentException.class,
+                () -> new PrebakedSegment(VibrationEffect.EFFECT_TICK, false, 1000)
+                        .validate());
+    }
+
+    @Test
+    public void testResolve_ignoresAndReturnsSameEffect() {
+        PrebakedSegment prebaked = new PrebakedSegment(
+                VibrationEffect.EFFECT_CLICK, true, VibrationEffect.EFFECT_STRENGTH_MEDIUM);
+        assertSame(prebaked, prebaked.resolve(1000));
+    }
+
+    @Test
+    public void testApplyEffectStrength() {
+        PrebakedSegment medium = new PrebakedSegment(
+                VibrationEffect.EFFECT_THUD, true, VibrationEffect.EFFECT_STRENGTH_MEDIUM);
+
+        PrebakedSegment light = medium.applyEffectStrength(VibrationEffect.EFFECT_STRENGTH_LIGHT);
+        assertNotEquals(medium, light);
+        assertEquals(medium.getEffectId(), light.getEffectId());
+        assertEquals(medium.shouldFallback(), light.shouldFallback());
+        assertEquals(VibrationEffect.EFFECT_STRENGTH_LIGHT, light.getEffectStrength());
+
+        PrebakedSegment strong = medium.applyEffectStrength(VibrationEffect.EFFECT_STRENGTH_STRONG);
+        assertNotEquals(medium, strong);
+        assertEquals(medium.getEffectId(), strong.getEffectId());
+        assertEquals(medium.shouldFallback(), strong.shouldFallback());
+        assertEquals(VibrationEffect.EFFECT_STRENGTH_STRONG, strong.getEffectStrength());
+
+        assertSame(medium, medium.applyEffectStrength(VibrationEffect.EFFECT_STRENGTH_MEDIUM));
+        // Invalid vibration effect strength is ignored.
+        assertSame(medium, medium.applyEffectStrength(1000));
+    }
+
+    @Test
+    public void testScale_ignoresAndReturnsSameEffect() {
+        PrebakedSegment prebaked = new PrebakedSegment(
+                VibrationEffect.EFFECT_CLICK, true, VibrationEffect.EFFECT_STRENGTH_MEDIUM);
+        assertSame(prebaked, prebaked.scale(0.5f));
+    }
+}
diff --git a/core/tests/coretests/src/android/os/vibrator/PrimitiveSegmentTest.java b/core/tests/coretests/src/android/os/vibrator/PrimitiveSegmentTest.java
new file mode 100644
index 0000000..538655b
--- /dev/null
+++ b/core/tests/coretests/src/android/os/vibrator/PrimitiveSegmentTest.java
@@ -0,0 +1,130 @@
+/*
+ * 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 android.os.vibrator;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertSame;
+import static junit.framework.Assert.assertTrue;
+
+import static org.testng.Assert.assertThrows;
+
+import android.os.Parcel;
+import android.os.VibrationEffect;
+import android.platform.test.annotations.Presubmit;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.junit.MockitoJUnitRunner;
+
+@Presubmit
+@RunWith(MockitoJUnitRunner.class)
+public class PrimitiveSegmentTest {
+    private static final float TOLERANCE = 1e-2f;
+
+    @Test
+    public void testCreation() {
+        PrimitiveSegment primitive = new PrimitiveSegment(
+                VibrationEffect.Composition.PRIMITIVE_CLICK, 1, 10);
+
+        assertEquals(-1, primitive.getDuration());
+        assertTrue(primitive.hasNonZeroAmplitude());
+        assertEquals(VibrationEffect.Composition.PRIMITIVE_CLICK, primitive.getPrimitiveId());
+        assertEquals(10, primitive.getDelay());
+        assertEquals(1f, primitive.getScale(), TOLERANCE);
+    }
+
+    @Test
+    public void testSerialization() {
+        PrimitiveSegment original = new PrimitiveSegment(
+                VibrationEffect.Composition.PRIMITIVE_CLICK, 1, 10);
+        Parcel parcel = Parcel.obtain();
+        original.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        assertEquals(original, PrimitiveSegment.CREATOR.createFromParcel(parcel));
+    }
+
+    @Test
+    public void testValidate() {
+        new PrimitiveSegment(VibrationEffect.Composition.PRIMITIVE_CLICK, 1, 0).validate();
+
+        assertThrows(IllegalArgumentException.class,
+                () -> new PrimitiveSegment(1000, 0, 10).validate());
+        assertThrows(IllegalArgumentException.class,
+                () -> new PrimitiveSegment(VibrationEffect.Composition.PRIMITIVE_NOOP, -1, 0)
+                        .validate());
+        assertThrows(IllegalArgumentException.class,
+                () -> new PrimitiveSegment(VibrationEffect.Composition.PRIMITIVE_NOOP, 1, -1)
+                        .validate());
+    }
+
+    @Test
+    public void testResolve_ignoresAndReturnsSameEffect() {
+        PrimitiveSegment primitive = new PrimitiveSegment(
+                VibrationEffect.Composition.PRIMITIVE_CLICK, 1, 0);
+        assertSame(primitive, primitive.resolve(1000));
+    }
+
+    @Test
+    public void testApplyEffectStrength_ignoresAndReturnsSameEffect() {
+        PrimitiveSegment primitive = new PrimitiveSegment(
+                VibrationEffect.Composition.PRIMITIVE_CLICK, 1, 0);
+        assertSame(primitive,
+                primitive.applyEffectStrength(VibrationEffect.EFFECT_STRENGTH_STRONG));
+    }
+
+    @Test
+    public void testScale_fullPrimitiveScaleValue() {
+        PrimitiveSegment initial = new PrimitiveSegment(
+                VibrationEffect.Composition.PRIMITIVE_CLICK, 1, 0);
+
+        assertEquals(1f, initial.scale(1).getScale(), TOLERANCE);
+        assertEquals(0.34f, initial.scale(0.5f).getScale(), TOLERANCE);
+        // The original value was not scaled up, so this only scales it down.
+        assertEquals(1f, initial.scale(1.5f).getScale(), TOLERANCE);
+        assertEquals(0.53f, initial.scale(1.5f).scale(2 / 3f).getScale(), TOLERANCE);
+        // Does not restore to the exact original value because scale up is a bit offset.
+        assertEquals(0.71f, initial.scale(0.8f).getScale(), TOLERANCE);
+        assertEquals(0.84f, initial.scale(0.8f).scale(1.25f).getScale(), TOLERANCE);
+    }
+
+    @Test
+    public void testScale_halfPrimitiveScaleValue() {
+        PrimitiveSegment initial = new PrimitiveSegment(
+                VibrationEffect.Composition.PRIMITIVE_CLICK, 0.5f, 0);
+
+        assertEquals(0.5f, initial.scale(1).getScale(), TOLERANCE);
+        assertEquals(0.17f, initial.scale(0.5f).getScale(), TOLERANCE);
+        // The original value was not scaled up, so this only scales it down.
+        assertEquals(0.86f, initial.scale(1.5f).getScale(), TOLERANCE);
+        assertEquals(0.47f, initial.scale(1.5f).scale(2 / 3f).getScale(), TOLERANCE);
+        // Does not restore to the exact original value because scale up is a bit offset.
+        assertEquals(0.35f, initial.scale(0.8f).getScale(), TOLERANCE);
+        assertEquals(0.5f, initial.scale(0.8f).scale(1.25f).getScale(), TOLERANCE);
+    }
+
+    @Test
+    public void testScale_zeroPrimitiveScaleValue() {
+        PrimitiveSegment initial = new PrimitiveSegment(
+                VibrationEffect.Composition.PRIMITIVE_CLICK, 0, 0);
+
+        assertEquals(0f, initial.scale(1).getScale(), TOLERANCE);
+        assertEquals(0f, initial.scale(0.5f).getScale(), TOLERANCE);
+        assertEquals(0f, initial.scale(1.5f).getScale(), TOLERANCE);
+        assertEquals(0f, initial.scale(1.5f).scale(2 / 3f).getScale(), TOLERANCE);
+        assertEquals(0f, initial.scale(0.8f).scale(1.25f).getScale(), TOLERANCE);
+    }
+}
diff --git a/core/tests/coretests/src/android/os/vibrator/RampSegmentTest.java b/core/tests/coretests/src/android/os/vibrator/RampSegmentTest.java
new file mode 100644
index 0000000..174b4a7
--- /dev/null
+++ b/core/tests/coretests/src/android/os/vibrator/RampSegmentTest.java
@@ -0,0 +1,128 @@
+/*
+ * 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 android.os.vibrator;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertSame;
+import static junit.framework.Assert.assertTrue;
+
+import static org.testng.Assert.assertThrows;
+
+import android.os.Parcel;
+import android.os.VibrationEffect;
+import android.platform.test.annotations.Presubmit;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.junit.MockitoJUnitRunner;
+
+@Presubmit
+@RunWith(MockitoJUnitRunner.class)
+public class RampSegmentTest {
+    private static final float TOLERANCE = 1e-2f;
+
+    @Test
+    public void testCreation() {
+        RampSegment ramp = new RampSegment(/* startAmplitude= */ 1, /* endAmplitude= */ 0,
+                /* StartFrequency= */ -1, /* endFrequency= */ 1, /* duration= */ 100);
+
+        assertEquals(100L, ramp.getDuration());
+        assertTrue(ramp.hasNonZeroAmplitude());
+        assertEquals(1f, ramp.getStartAmplitude());
+        assertEquals(0f, ramp.getEndAmplitude());
+        assertEquals(-1f, ramp.getStartFrequency());
+        assertEquals(1f, ramp.getEndFrequency());
+    }
+
+    @Test
+    public void testSerialization() {
+        RampSegment original = new RampSegment(0, 1, 0, 0.5f, 10);
+        Parcel parcel = Parcel.obtain();
+        original.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        assertEquals(original, RampSegment.CREATOR.createFromParcel(parcel));
+    }
+
+    @Test
+    public void testValidate() {
+        new RampSegment(/* startAmplitude= */ 1, /* endAmplitude= */ 0,
+                /* StartFrequency= */ -1, /* endFrequency= */ 1, /* duration= */ 100).validate();
+
+        assertThrows(IllegalArgumentException.class,
+                () -> new RampSegment(VibrationEffect.DEFAULT_AMPLITUDE, 0, 0, 0, 0).validate());
+        assertThrows(IllegalArgumentException.class,
+                () -> new RampSegment(/* startAmplitude= */ -2, 0, 0, 0, 0).validate());
+        assertThrows(IllegalArgumentException.class,
+                () -> new RampSegment(0, /* endAmplitude= */ 2, 0, 0, 0).validate());
+        assertThrows(IllegalArgumentException.class,
+                () -> new RampSegment(0, 0, 0, 0, /* duration= */ -1).validate());
+    }
+
+    @Test
+    public void testHasNonZeroAmplitude() {
+        assertTrue(new RampSegment(0, 1, 0, 0, 0).hasNonZeroAmplitude());
+        assertTrue(new RampSegment(0.01f, 0, 0, 0, 0).hasNonZeroAmplitude());
+        assertFalse(new RampSegment(0, 0, 0, 0, 0).hasNonZeroAmplitude());
+    }
+
+    @Test
+    public void testResolve() {
+        RampSegment ramp = new RampSegment(0, 1, 0, 0, 0);
+        assertSame(ramp, ramp.resolve(100));
+    }
+
+    @Test
+    public void testApplyEffectStrength_ignoresAndReturnsSameEffect() {
+        RampSegment ramp = new RampSegment(1, 0, 1, 0, 0);
+        assertSame(ramp, ramp.applyEffectStrength(VibrationEffect.EFFECT_STRENGTH_STRONG));
+    }
+
+    @Test
+    public void testScale() {
+        RampSegment initial = new RampSegment(0, 1, 0, 0, 0);
+
+        assertEquals(0f, initial.scale(1).getStartAmplitude(), TOLERANCE);
+        assertEquals(0f, initial.scale(0.5f).getStartAmplitude(), TOLERANCE);
+        assertEquals(0f, initial.scale(1.5f).getStartAmplitude(), TOLERANCE);
+        assertEquals(0f, initial.scale(1.5f).scale(2 / 3f).getStartAmplitude(), TOLERANCE);
+        assertEquals(0f, initial.scale(0.8f).scale(1.25f).getStartAmplitude(), TOLERANCE);
+
+        assertEquals(1f, initial.scale(1).getEndAmplitude(), TOLERANCE);
+        assertEquals(0.34f, initial.scale(0.5f).getEndAmplitude(), TOLERANCE);
+        // The original value was not scaled up, so this only scales it down.
+        assertEquals(1f, initial.scale(1.5f).getEndAmplitude(), TOLERANCE);
+        assertEquals(0.53f, initial.scale(1.5f).scale(2 / 3f).getEndAmplitude(), TOLERANCE);
+        // Does not restore to the exact original value because scale up is a bit offset.
+        assertEquals(0.71f, initial.scale(0.8f).getEndAmplitude(), TOLERANCE);
+        assertEquals(0.84f, initial.scale(0.8f).scale(1.25f).getEndAmplitude(), TOLERANCE);
+    }
+
+    @Test
+    public void testScale_halfPrimitiveScaleValue() {
+        RampSegment initial = new RampSegment(0.5f, 1, 0, 0, 0);
+
+        assertEquals(0.5f, initial.scale(1).getStartAmplitude(), TOLERANCE);
+        assertEquals(0.17f, initial.scale(0.5f).getStartAmplitude(), TOLERANCE);
+        // Does not restore to the exact original value because scale up is a bit offset.
+        assertEquals(0.86f, initial.scale(1.5f).getStartAmplitude(), TOLERANCE);
+        assertEquals(0.47f, initial.scale(1.5f).scale(2 / 3f).getStartAmplitude(), TOLERANCE);
+        // Does not restore to the exact original value because scale up is a bit offset.
+        assertEquals(0.35f, initial.scale(0.8f).getStartAmplitude(), TOLERANCE);
+        assertEquals(0.5f, initial.scale(0.8f).scale(1.25f).getStartAmplitude(), TOLERANCE);
+    }
+}
diff --git a/core/tests/coretests/src/android/os/vibrator/StepSegmentTest.java b/core/tests/coretests/src/android/os/vibrator/StepSegmentTest.java
new file mode 100644
index 0000000..79529b8
--- /dev/null
+++ b/core/tests/coretests/src/android/os/vibrator/StepSegmentTest.java
@@ -0,0 +1,144 @@
+/*
+ * 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 android.os.vibrator;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertSame;
+import static junit.framework.Assert.assertTrue;
+
+import static org.testng.Assert.assertThrows;
+
+import android.os.Parcel;
+import android.os.VibrationEffect;
+import android.platform.test.annotations.Presubmit;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.junit.MockitoJUnitRunner;
+
+@Presubmit
+@RunWith(MockitoJUnitRunner.class)
+public class StepSegmentTest {
+    private static final float TOLERANCE = 1e-2f;
+
+    @Test
+    public void testCreation() {
+        StepSegment step = new StepSegment(/* amplitude= */ 1f, /* frequency= */ -1f,
+                /* duration= */ 100);
+
+        assertEquals(100, step.getDuration());
+        assertTrue(step.hasNonZeroAmplitude());
+        assertEquals(1f, step.getAmplitude());
+        assertEquals(-1f, step.getFrequency());
+    }
+
+    @Test
+    public void testSerialization() {
+        StepSegment original = new StepSegment(0.5f, 1f, 10);
+        Parcel parcel = Parcel.obtain();
+        original.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        assertEquals(original, StepSegment.CREATOR.createFromParcel(parcel));
+    }
+
+    @Test
+    public void testValidate() {
+        new StepSegment(/* amplitude= */ 0f, /* frequency= */ -1f, /* duration= */ 100).validate();
+
+        assertThrows(IllegalArgumentException.class,
+                () -> new StepSegment(/* amplitude= */ -2, 1f, 10).validate());
+        assertThrows(IllegalArgumentException.class,
+                () -> new StepSegment(/* amplitude= */ 2, 1f, 10).validate());
+        assertThrows(IllegalArgumentException.class,
+                () -> new StepSegment(2, 1f, /* duration= */ -1).validate());
+    }
+
+    @Test
+    public void testHasNonZeroAmplitude() {
+        assertTrue(new StepSegment(1f, 0, 0).hasNonZeroAmplitude());
+        assertTrue(new StepSegment(0.01f, 0, 0).hasNonZeroAmplitude());
+        assertTrue(new StepSegment(VibrationEffect.DEFAULT_AMPLITUDE, 0, 0).hasNonZeroAmplitude());
+        assertFalse(new StepSegment(0, 0, 0).hasNonZeroAmplitude());
+    }
+
+    @Test
+    public void testResolve() {
+        StepSegment original = new StepSegment(VibrationEffect.DEFAULT_AMPLITUDE, 0, 0);
+        assertEquals(1f, original.resolve(VibrationEffect.MAX_AMPLITUDE).getAmplitude());
+        assertEquals(0.2f, original.resolve(51).getAmplitude(), TOLERANCE);
+
+        StepSegment resolved = new StepSegment(0, 0, 0);
+        assertSame(resolved, resolved.resolve(100));
+
+        assertThrows(IllegalArgumentException.class, () -> resolved.resolve(1000));
+    }
+
+    @Test
+    public void testApplyEffectStrength_ignoresAndReturnsSameEffect() {
+        StepSegment step = new StepSegment(VibrationEffect.DEFAULT_AMPLITUDE, 0, 0);
+        assertSame(step, step.applyEffectStrength(VibrationEffect.EFFECT_STRENGTH_STRONG));
+    }
+
+    @Test
+    public void testScale_fullAmplitude() {
+        StepSegment initial = new StepSegment(1f, 0, 0);
+
+        assertEquals(1f, initial.scale(1).getAmplitude(), TOLERANCE);
+        assertEquals(0.34f, initial.scale(0.5f).getAmplitude(), TOLERANCE);
+        // The original value was not scaled up, so this only scales it down.
+        assertEquals(1f, initial.scale(1.5f).getAmplitude(), TOLERANCE);
+        assertEquals(0.53f, initial.scale(1.5f).scale(2 / 3f).getAmplitude(), TOLERANCE);
+        // Does not restore to the exact original value because scale up is a bit offset.
+        assertEquals(0.71f, initial.scale(0.8f).getAmplitude(), TOLERANCE);
+        assertEquals(0.84f, initial.scale(0.8f).scale(1.25f).getAmplitude(), TOLERANCE);
+    }
+
+    @Test
+    public void testScale_halfAmplitude() {
+        StepSegment initial = new StepSegment(0.5f, 0, 0);
+
+        assertEquals(0.5f, initial.scale(1).getAmplitude(), TOLERANCE);
+        assertEquals(0.17f, initial.scale(0.5f).getAmplitude(), TOLERANCE);
+        // The original value was not scaled up, so this only scales it down.
+        assertEquals(0.86f, initial.scale(1.5f).getAmplitude(), TOLERANCE);
+        assertEquals(0.47f, initial.scale(1.5f).scale(2 / 3f).getAmplitude(), TOLERANCE);
+        // Does not restore to the exact original value because scale up is a bit offset.
+        assertEquals(0.35f, initial.scale(0.8f).getAmplitude(), TOLERANCE);
+        assertEquals(0.5f, initial.scale(0.8f).scale(1.25f).getAmplitude(), TOLERANCE);
+    }
+
+    @Test
+    public void testScale_zeroAmplitude() {
+        StepSegment initial = new StepSegment(0, 0, 0);
+
+        assertEquals(0f, initial.scale(1).getAmplitude(), TOLERANCE);
+        assertEquals(0f, initial.scale(0.5f).getAmplitude(), TOLERANCE);
+        assertEquals(0f, initial.scale(1.5f).getAmplitude(), TOLERANCE);
+    }
+
+    @Test
+    public void testScale_defaultAmplitude() {
+        StepSegment initial = new StepSegment(VibrationEffect.DEFAULT_AMPLITUDE, 0, 0);
+
+        assertEquals(VibrationEffect.DEFAULT_AMPLITUDE, initial.scale(1).getAmplitude(), TOLERANCE);
+        assertEquals(VibrationEffect.DEFAULT_AMPLITUDE, initial.scale(0.5f).getAmplitude(),
+                TOLERANCE);
+        assertEquals(VibrationEffect.DEFAULT_AMPLITUDE, initial.scale(1.5f).getAmplitude(),
+                TOLERANCE);
+    }
+}
diff --git a/core/tests/coretests/src/android/provider/NameValueCacheTest.java b/core/tests/coretests/src/android/provider/NameValueCacheTest.java
index 4212ef2..97e66c4 100644
--- a/core/tests/coretests/src/android/provider/NameValueCacheTest.java
+++ b/core/tests/coretests/src/android/provider/NameValueCacheTest.java
@@ -33,6 +33,7 @@
 import android.util.MemoryIntArray;
 
 import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
@@ -73,7 +74,8 @@
         Settings.Config.clearProviderForTest();
         MockitoAnnotations.initMocks(this);
         when(mMockContentProvider.getIContentProvider()).thenReturn(mMockIContentProvider);
-        mMockContentResolver = new MockContentResolver();
+        mMockContentResolver = new MockContentResolver(InstrumentationRegistry
+                .getInstrumentation().getContext());
         mMockContentResolver.addProvider(DeviceConfig.CONTENT_URI.getAuthority(),
                 mMockContentProvider);
         mCacheGenerationStore = new MemoryIntArray(1);
@@ -82,10 +84,10 @@
         // Stores keyValues for a given prefix and increments the generation. (Note that this
         // increments the generation no matter what, it doesn't pay attention to if anything
         // actually changed).
-        when(mMockIContentProvider.call(any(), any(), eq(DeviceConfig.CONTENT_URI.getAuthority()),
+        when(mMockIContentProvider.call(any(), eq(DeviceConfig.CONTENT_URI.getAuthority()),
                 eq(Settings.CALL_METHOD_SET_ALL_CONFIG),
                 any(), any(Bundle.class))).thenAnswer(invocationOnMock -> {
-                    Bundle incomingBundle = invocationOnMock.getArgument(5);
+                    Bundle incomingBundle = invocationOnMock.getArgument(4);
                     HashMap<String, String> keyValues =
                             (HashMap<String, String>) incomingBundle.getSerializable(
                                     Settings.CALL_METHOD_FLAGS_KEY);
@@ -101,10 +103,10 @@
         // Returns the keyValues corresponding to a namespace, or an empty map if the namespace
         // doesn't have anything stored for it. Returns the generation key if the caller asked
         // for one.
-        when(mMockIContentProvider.call(any(), any(), eq(DeviceConfig.CONTENT_URI.getAuthority()),
+        when(mMockIContentProvider.call(any(), eq(DeviceConfig.CONTENT_URI.getAuthority()),
                 eq(Settings.CALL_METHOD_LIST_CONFIG),
                 any(), any(Bundle.class))).thenAnswer(invocationOnMock -> {
-                    Bundle incomingBundle = invocationOnMock.getArgument(5);
+                    Bundle incomingBundle = invocationOnMock.getArgument(4);
 
                     String prefix = incomingBundle.getString(Settings.CALL_METHOD_PREFIX_KEY);
 
@@ -132,14 +134,14 @@
         HashMap<String, String> keyValues = new HashMap<>();
         keyValues.put("a", "b");
         Settings.Config.setStrings(mMockContentResolver, NAMESPACE, keyValues);
-        verify(mMockIContentProvider).call(any(), any(), any(),
+        verify(mMockIContentProvider).call(any(), any(),
                 eq(Settings.CALL_METHOD_SET_ALL_CONFIG),
                 any(), any(Bundle.class));
 
         Map<String, String> returnedValues = Settings.Config.getStrings(mMockContentResolver,
                 NAMESPACE,
                 Collections.emptyList());
-        verify(mMockIContentProvider).call(any(), any(), any(),
+        verify(mMockIContentProvider).call(any(), any(),
                 eq(Settings.CALL_METHOD_LIST_CONFIG),
                 any(), any(Bundle.class));
         assertThat(returnedValues).containsExactlyEntriesIn(keyValues);
@@ -152,13 +154,13 @@
         // Modify the value to invalidate the cache.
         keyValues.put("a", "c");
         Settings.Config.setStrings(mMockContentResolver, NAMESPACE, keyValues);
-        verify(mMockIContentProvider, times(2)).call(any(), any(), any(),
+        verify(mMockIContentProvider, times(2)).call(any(), any(),
                 eq(Settings.CALL_METHOD_SET_ALL_CONFIG),
                 any(), any(Bundle.class));
 
         Map<String, String> returnedValues2 = Settings.Config.getStrings(mMockContentResolver,
                 NAMESPACE, Collections.emptyList());
-        verify(mMockIContentProvider, times(2)).call(any(), any(), any(),
+        verify(mMockIContentProvider, times(2)).call(any(), any(),
                 eq(Settings.CALL_METHOD_LIST_CONFIG),
                 any(), any(Bundle.class));
         assertThat(returnedValues2).containsExactlyEntriesIn(keyValues);
@@ -174,7 +176,7 @@
         HashMap<String, String> keyValues = new HashMap<>();
         keyValues.put("a", "b");
         Settings.Config.setStrings(mMockContentResolver, NAMESPACE, keyValues);
-        verify(mMockIContentProvider).call(any(), any(), any(),
+        verify(mMockIContentProvider).call(any(), any(),
                 eq(Settings.CALL_METHOD_SET_ALL_CONFIG),
                 any(), any(Bundle.class));
 
@@ -182,14 +184,14 @@
         keyValues2.put("c", "d");
         keyValues2.put("e", "f");
         Settings.Config.setStrings(mMockContentResolver, NAMESPACE2, keyValues2);
-        verify(mMockIContentProvider, times(2)).call(any(), any(), any(),
+        verify(mMockIContentProvider, times(2)).call(any(), any(),
                 eq(Settings.CALL_METHOD_SET_ALL_CONFIG),
                 any(), any(Bundle.class));
 
         Map<String, String> returnedValues = Settings.Config.getStrings(mMockContentResolver,
                 NAMESPACE,
                 Collections.emptyList());
-        verify(mMockIContentProvider).call(any(), any(), any(),
+        verify(mMockIContentProvider).call(any(), any(),
                 eq(Settings.CALL_METHOD_LIST_CONFIG),
                 any(), any(Bundle.class));
         assertThat(returnedValues).containsExactlyEntriesIn(keyValues);
@@ -197,7 +199,7 @@
         Map<String, String> returnedValues2 = Settings.Config.getStrings(mMockContentResolver,
                 NAMESPACE2,
                 Collections.emptyList());
-        verify(mMockIContentProvider, times(2)).call(any(), any(), any(),
+        verify(mMockIContentProvider, times(2)).call(any(), any(),
                 eq(Settings.CALL_METHOD_LIST_CONFIG),
                 any(), any(Bundle.class));
         assertThat(returnedValues2).containsExactlyEntriesIn(keyValues2);
@@ -218,7 +220,7 @@
         Map<String, String> returnedValues = Settings.Config.getStrings(mMockContentResolver,
                 NAMESPACE,
                 Collections.emptyList());
-        verify(mMockIContentProvider).call(any(), any(), any(),
+        verify(mMockIContentProvider).call(any(), any(),
                 eq(Settings.CALL_METHOD_LIST_CONFIG),
                 any(), any(Bundle.class));
         assertThat(returnedValues).isEmpty();
diff --git a/core/tests/coretests/src/android/provider/TestDocumentsProvider.java b/core/tests/coretests/src/android/provider/TestDocumentsProvider.java
index 5f640be..4496983 100644
--- a/core/tests/coretests/src/android/provider/TestDocumentsProvider.java
+++ b/core/tests/coretests/src/android/provider/TestDocumentsProvider.java
@@ -18,13 +18,13 @@
 
 import android.annotation.Nullable;
 import android.app.AppOpsManager;
+import android.content.AttributionSource;
 import android.content.Context;
 import android.content.ContextWrapper;
 import android.content.pm.ProviderInfo;
 import android.database.Cursor;
 import android.net.Uri;
 import android.os.CancellationSignal;
-import android.os.IBinder;
 import android.os.ParcelFileDescriptor;
 import android.provider.DocumentsContract.Path;
 
@@ -93,14 +93,12 @@
     }
 
     @Override
-    protected int enforceReadPermissionInner(Uri uri, String callingPkg,
-            @Nullable String callingFeatureId, IBinder callerToken) {
+    protected int enforceReadPermissionInner(Uri uri, AttributionSource attributionSource) {
         return AppOpsManager.MODE_ALLOWED;
     }
 
     @Override
-    protected int enforceWritePermissionInner(Uri uri, String callingPkg,
-            @Nullable String callingFeatureId, IBinder callerToken) {
+    protected int enforceWritePermissionInner(Uri uri, AttributionSource attributionSource) {
         return AppOpsManager.MODE_ALLOWED;
     }
 
diff --git a/core/tests/coretests/src/android/util/SparseDoubleArrayTest.java b/core/tests/coretests/src/android/util/SparseDoubleArrayTest.java
new file mode 100644
index 0000000..2dd3f69
--- /dev/null
+++ b/core/tests/coretests/src/android/util/SparseDoubleArrayTest.java
@@ -0,0 +1,108 @@
+/*
+ * 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 android.util;
+
+import static org.junit.Assert.assertEquals;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Arrays;
+
+/**
+ * Internal tests for {@link SparseDoubleArray}.
+ *
+ * Run using:
+ *  atest FrameworksCoreTests:android.util.SparseDoubleArrayTest
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class SparseDoubleArrayTest {
+    private static final double EXACT_PRECISION = 0;
+    private static final double PRECISION = 0.000000001;
+
+    @Test
+    public void testPutGet() {
+        final SparseDoubleArray sda = new SparseDoubleArray();
+        assertEquals("Array should be empty", 0, sda.size());
+
+        final int[] keys = {1, 6, -14, 53251, 5, -13412, 12, 0, 2};
+        final double[] values = {7, -12.4, 7, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY,
+                Double.NaN,
+                4311236312.0 / 3431470161413514334123.0,
+                431123636434132151313412.0 / 34323.0,
+                0};
+        for (int i = 0; i < keys.length; i++) {
+            sda.put(keys[i], values[i]);
+        }
+
+        assertEquals("Wrong size array", keys.length, sda.size());
+        // Due to the implementation, we actually expect EXACT double equality.
+        for (int i = 0; i < keys.length; i++) {
+            assertEquals("Wrong value at index " + i, values[i], sda.get(keys[i]), EXACT_PRECISION);
+        }
+
+        // Now check something that was never put in
+        assertEquals("Wrong value for absent index", 0, sda.get(100000), EXACT_PRECISION);
+    }
+
+    @Test
+    public void testAdd() {
+        final SparseDoubleArray sda = new SparseDoubleArray();
+
+        sda.put(4, 6.1);
+        sda.add(4, -1.2);
+        sda.add(2, -1.2);
+
+        assertEquals(6.1 - 1.2, sda.get(4), PRECISION);
+        assertEquals(-1.2, sda.get(2), PRECISION);
+    }
+
+    @Test
+    public void testKeyValueAt() {
+        final SparseDoubleArray sda = new SparseDoubleArray();
+
+        final int[] keys = {1, 6, -14, 53251, 5, -13412, 12, 0, 2};
+        final double[] values = {7, -12.4, 7, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY,
+                Double.NaN,
+                4311236312.0 / 3431470161413514334123.0,
+                431123636434132151313412.0 / 34323.0,
+                0};
+        for (int i = 0; i < keys.length; i++) {
+            sda.put(keys[i], values[i]);
+        }
+
+        // Sort the sample data.
+        final ArrayMap<Integer, Double> map = new ArrayMap<>(keys.length);
+        for (int i = 0; i < keys.length; i++) {
+            map.put(keys[i], values[i]);
+        }
+        final int[] sortedKeys = Arrays.copyOf(keys, keys.length);
+        Arrays.sort(sortedKeys);
+
+        for (int i = 0; i < sortedKeys.length; i++) {
+            final int expectedKey = sortedKeys[i];
+            final double expectedValue = map.get(expectedKey);
+
+            assertEquals("Wrong key at index " + i, expectedKey, sda.keyAt(i), PRECISION);
+            assertEquals("Wrong value at index " + i, expectedValue, sda.valueAt(i), PRECISION);
+        }
+    }
+}
diff --git a/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java b/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java
index 5de55d7..34a1fd8 100644
--- a/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java
+++ b/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java
@@ -97,13 +97,13 @@
 
         InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
             // test if setVisibility can show IME
-            mImeConsumer.onWindowFocusGained();
-            mImeConsumer.applyImeVisibility(true);
+            mImeConsumer.onWindowFocusGained(true);
+            mController.show(WindowInsets.Type.ime(), true /* fromIme */);
             mController.cancelExistingAnimations();
             assertTrue(mController.getSourceConsumer(ime.getType()).isRequestedVisible());
 
             // test if setVisibility can hide IME
-            mImeConsumer.applyImeVisibility(false);
+            mController.hide(WindowInsets.Type.ime(), true /* fromIme */);
             mController.cancelExistingAnimations();
             assertFalse(mController.getSourceConsumer(ime.getType()).isRequestedVisible());
         });
@@ -116,8 +116,8 @@
 
         InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
             // Request IME visible before control is available.
-            mImeConsumer.onWindowFocusGained();
-            mImeConsumer.applyImeVisibility(true /* setVisible */);
+            mImeConsumer.onWindowFocusGained(true);
+            mController.show(WindowInsets.Type.ime(), true /* fromIme */);
 
             // set control and verify visibility is applied.
             InsetsSourceControl control =
@@ -132,24 +132,58 @@
     }
 
     @Test
-    public void testImeGetAndClearSkipAnimationOnce() {
+    public void testImeGetAndClearSkipAnimationOnce_expectSkip() {
+        // Expect IME animation will skipped when the IME is visible at first place.
+        verifyImeGetAndClearSkipAnimationOnce(true /* hasWindowFocus */, true /* hasViewFocus */,
+                true /* expectSkipAnim */);
+    }
+
+    @Test
+    public void testImeGetAndClearSkipAnimationOnce_expectNoSkip() {
+        // Expect IME animation will not skipped if previously no view focused when gained the
+        // window focus and requesting the IME visible next time.
+        verifyImeGetAndClearSkipAnimationOnce(true /* hasWindowFocus */, false /* hasViewFocus */,
+                false /* expectSkipAnim */);
+    }
+
+    private void verifyImeGetAndClearSkipAnimationOnce(boolean hasWindowFocus, boolean hasViewFocus,
+            boolean expectSkipAnim) {
         InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
             // Request IME visible before control is available.
-            mImeConsumer.onWindowFocusGained();
-            mImeConsumer.applyImeVisibility(true /* setVisible */);
+            mImeConsumer.onWindowFocusGained(hasWindowFocus);
+            final boolean imeVisible = hasWindowFocus && hasViewFocus;
+            if (imeVisible) {
+                mController.show(WindowInsets.Type.ime(), true /* fromIme */);
+            }
 
             // set control and verify visibility is applied.
             InsetsSourceControl control = Mockito.spy(
                     new InsetsSourceControl(ITYPE_IME, mLeash, new Point(), Insets.NONE));
             // Simulate IME source control set this flag when the target has starting window.
             control.setSkipAnimationOnce(true);
-            mController.onControlsChanged(new InsetsSourceControl[] { control });
-            // Verify IME show animation should be triggered when control becomes available and
-            // the animation will be skipped by getAndClearSkipAnimationOnce invoked.
-            verify(control).getAndClearSkipAnimationOnce();
-            verify(mController).applyAnimation(
-                    eq(WindowInsets.Type.ime()), eq(true) /* show */, eq(false) /* fromIme */,
-                    eq(true) /* skipAnim */);
+
+            if (imeVisible) {
+                // Verify IME applyAnimation should be triggered when control becomes available,
+                // and expect skip animation state after getAndClearSkipAnimationOnce invoked.
+                mController.onControlsChanged(new InsetsSourceControl[]{ control });
+                verify(control).getAndClearSkipAnimationOnce();
+                verify(mController).applyAnimation(eq(WindowInsets.Type.ime()),
+                        eq(true) /* show */, eq(false) /* fromIme */,
+                        eq(expectSkipAnim) /* skipAnim */);
+            }
+
+            // If previously hasViewFocus is false, verify when requesting the IME visible next
+            // time will not skip animation.
+            if (!hasViewFocus) {
+                mController.show(WindowInsets.Type.ime(), true);
+                mController.onControlsChanged(new InsetsSourceControl[]{ control });
+                // Verify IME show animation should be triggered when control becomes available and
+                // the animation will be skipped by getAndClearSkipAnimationOnce invoked.
+                verify(control).getAndClearSkipAnimationOnce();
+                verify(mController).applyAnimation(eq(WindowInsets.Type.ime()),
+                        eq(true) /* show */, eq(true) /* fromIme */,
+                        eq(false) /* skipAnim */);
+            }
         });
     }
 }
diff --git a/core/tests/coretests/src/android/view/InsetsControllerTest.java b/core/tests/coretests/src/android/view/InsetsControllerTest.java
index ff505c4..6301f32 100644
--- a/core/tests/coretests/src/android/view/InsetsControllerTest.java
+++ b/core/tests/coretests/src/android/view/InsetsControllerTest.java
@@ -234,9 +234,9 @@
         InsetsSourceControl ime = controls[2];
 
         InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
-            mController.getSourceConsumer(ITYPE_IME).onWindowFocusGained();
+            mController.getSourceConsumer(ITYPE_IME).onWindowFocusGained(true);
             // since there is no focused view, forcefully make IME visible.
-            mController.applyImeVisibility(true /* setVisible */);
+            mController.show(Type.ime(), true /* fromIme */);
             mController.show(Type.all());
             // quickly jump to final state by cancelling it.
             mController.cancelExistingAnimations();
@@ -244,7 +244,7 @@
             assertTrue(mController.getSourceConsumer(statusBar.getType()).isRequestedVisible());
             assertTrue(mController.getSourceConsumer(ime.getType()).isRequestedVisible());
 
-            mController.applyImeVisibility(false /* setVisible */);
+            mController.hide(Type.ime(), true /* fromIme */);
             mController.hide(Type.all());
             mController.cancelExistingAnimations();
             assertFalse(mController.getSourceConsumer(navBar.getType()).isRequestedVisible());
@@ -260,11 +260,11 @@
         InsetsSourceControl ime = createControl(ITYPE_IME);
         mController.onControlsChanged(new InsetsSourceControl[] { ime });
         InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
-            mController.getSourceConsumer(ITYPE_IME).onWindowFocusGained();
-            mController.applyImeVisibility(true);
+            mController.getSourceConsumer(ITYPE_IME).onWindowFocusGained(true);
+            mController.show(Type.ime(), true /* fromIme */);
             mController.cancelExistingAnimations();
             assertTrue(mController.getSourceConsumer(ime.getType()).isRequestedVisible());
-            mController.applyImeVisibility(false);
+            mController.hide(Type.ime(), true /* fromIme */);
             mController.cancelExistingAnimations();
             assertFalse(mController.getSourceConsumer(ime.getType()).isRequestedVisible());
             mController.getSourceConsumer(ITYPE_IME).onWindowFocusLost();
diff --git a/core/tests/coretests/src/android/view/ScrollCaptureConnectionTest.java b/core/tests/coretests/src/android/view/ScrollCaptureConnectionTest.java
index f3a6f9e..22c71b52 100644
--- a/core/tests/coretests/src/android/view/ScrollCaptureConnectionTest.java
+++ b/core/tests/coretests/src/android/view/ScrollCaptureConnectionTest.java
@@ -32,7 +32,9 @@
 import android.graphics.Rect;
 import android.os.Handler;
 import android.os.ICancellationSignal;
+import android.platform.test.annotations.Presubmit;
 
+import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
@@ -45,6 +47,8 @@
  * Tests of {@link ScrollCaptureConnection}.
  */
 @SuppressWarnings("UnnecessaryLocalVariable")
+@Presubmit
+@SmallTest
 @RunWith(AndroidJUnit4.class)
 public class ScrollCaptureConnectionTest {
 
diff --git a/core/tests/coretests/src/android/view/ScrollCaptureSearchResultsTest.java b/core/tests/coretests/src/android/view/ScrollCaptureSearchResultsTest.java
index cc229e1..dc43204 100644
--- a/core/tests/coretests/src/android/view/ScrollCaptureSearchResultsTest.java
+++ b/core/tests/coretests/src/android/view/ScrollCaptureSearchResultsTest.java
@@ -32,8 +32,10 @@
 import android.graphics.Rect;
 import android.os.CancellationSignal;
 import android.os.SystemClock;
+import android.platform.test.annotations.Presubmit;
 
 import androidx.annotation.NonNull;
+import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
@@ -47,8 +49,10 @@
 import java.util.function.Consumer;
 
 /**
- * Tests of {@link ScrollCaptureTargetSelector}.
+ * Tests of {@link ScrollCaptureSearchResults}.
  */
+@Presubmit
+@SmallTest
 @RunWith(AndroidJUnit4.class)
 public class ScrollCaptureSearchResultsTest {
 
diff --git a/core/tests/coretests/src/android/view/ViewGroupScrollCaptureTest.java b/core/tests/coretests/src/android/view/ViewGroupScrollCaptureTest.java
index 41cd4c5..2833ea3 100644
--- a/core/tests/coretests/src/android/view/ViewGroupScrollCaptureTest.java
+++ b/core/tests/coretests/src/android/view/ViewGroupScrollCaptureTest.java
@@ -49,7 +49,6 @@
  */
 @Presubmit
 @SmallTest
-@FlakyTest(detail = "promote once confirmed flake-free")
 @RunWith(MockitoJUnitRunner.class)
 public class ViewGroupScrollCaptureTest {
 
diff --git a/core/tests/coretests/src/android/view/WindowMetricsTest.java b/core/tests/coretests/src/android/view/WindowMetricsTest.java
index 96df9dd..39ea8af 100644
--- a/core/tests/coretests/src/android/view/WindowMetricsTest.java
+++ b/core/tests/coretests/src/android/view/WindowMetricsTest.java
@@ -73,17 +73,17 @@
             // Check get metrics do not crash.
             WindowMetrics currentMetrics = mWm.getCurrentWindowMetrics();
             WindowMetrics maxMetrics = mWm.getMaximumWindowMetrics();
-            verifyMetricsSanity(currentMetrics, maxMetrics);
+            verifyMetricsValidity(currentMetrics, maxMetrics);
 
             mWm.removeViewImmediate(view);
             // Check get metrics do not crash.
             currentMetrics = mWm.getCurrentWindowMetrics();
             maxMetrics = mWm.getMaximumWindowMetrics();
-            verifyMetricsSanity(currentMetrics, maxMetrics);
+            verifyMetricsValidity(currentMetrics, maxMetrics);
         }, 0);
     }
 
-    private static void verifyMetricsSanity(WindowMetrics currentMetrics,
+    private static void verifyMetricsValidity(WindowMetrics currentMetrics,
             WindowMetrics maxMetrics) {
         Rect currentBounds = currentMetrics.getBounds();
         Rect maxBounds = maxMetrics.getBounds();
diff --git a/core/tests/coretests/src/android/view/contentcapture/ContentCaptureEventTest.java b/core/tests/coretests/src/android/view/contentcapture/ContentCaptureEventTest.java
index 67614bb..e6a25d0 100644
--- a/core/tests/coretests/src/android/view/contentcapture/ContentCaptureEventTest.java
+++ b/core/tests/coretests/src/android/view/contentcapture/ContentCaptureEventTest.java
@@ -236,12 +236,13 @@
     @Test
     public void testMergeEvent_typeViewTextChanged() {
         final ContentCaptureEvent event = new ContentCaptureEvent(42, TYPE_VIEW_TEXT_CHANGED)
-                .setText("test");
+                .setText("test", false);
         final ContentCaptureEvent event2 = new ContentCaptureEvent(43, TYPE_VIEW_TEXT_CHANGED)
-                .setText("empty");
+                .setText("empty", true);
 
         event.mergeEvent(event2);
         assertThat(event.getText()).isEqualTo(event2.getText());
+        assertThat(event.getTextHasComposingSpan()).isEqualTo(event2.getTextHasComposingSpan());
     }
 
     @Test
@@ -282,16 +283,18 @@
     @Test
     public void testMergeEvent_differentEventTypes() {
         final ContentCaptureEvent event = new ContentCaptureEvent(42, TYPE_VIEW_DISAPPEARED)
-                .setText("test").setAutofillId(new AutofillId(1));
+                .setText("test", false).setAutofillId(new AutofillId(1));
         final ContentCaptureEvent event2 = new ContentCaptureEvent(17, TYPE_VIEW_TEXT_CHANGED)
-                .setText("empty").setAutofillId(new AutofillId(2));
+                .setText("empty", true).setAutofillId(new AutofillId(2));
 
         event.mergeEvent(event2);
         assertThat(event.getText()).isEqualTo("test");
+        assertThat(event.getTextHasComposingSpan()).isFalse();
         assertThat(event.getId()).isEqualTo(new AutofillId(1));
 
         event2.mergeEvent(event);
         assertThat(event2.getText()).isEqualTo("empty");
+        assertThat(event2.getTextHasComposingSpan()).isTrue();
         assertThat(event2.getId()).isEqualTo(new AutofillId(2));
     }
 
diff --git a/core/tests/coretests/src/android/window/WindowContextControllerTest.java b/core/tests/coretests/src/android/window/WindowContextControllerTest.java
new file mode 100644
index 0000000..e4fc19c
--- /dev/null
+++ b/core/tests/coretests/src/android/window/WindowContextControllerTest.java
@@ -0,0 +1,93 @@
+/*
+ * 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 android.window;
+
+import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+
+import android.os.Binder;
+import android.platform.test.annotations.Presubmit;
+import android.view.IWindowManager;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests for {@link WindowContextController}
+ *
+ * <p>Build/Install/Run:
+ *  atest FrameworksCoreTests:WindowContextControllerTest
+ *
+ * <p>This test class is a part of Window Manager Service tests and specified in
+ * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+@Presubmit
+public class WindowContextControllerTest {
+    private WindowContextController mController;
+    private IWindowManager mMockWms;
+
+    @Before
+    public void setUp() throws Exception {
+        mMockWms = mock(IWindowManager.class);
+        mController = new WindowContextController(new Binder(), mMockWms);
+
+        doReturn(true).when(mMockWms).registerWindowContextListener(
+                any(), anyInt(), anyInt(), any());
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testRegisterListenerTwiceThrowException() {
+        mController.registerListener(TYPE_APPLICATION_OVERLAY, DEFAULT_DISPLAY,
+                null /* options */);
+        mController.registerListener(TYPE_APPLICATION_OVERLAY, DEFAULT_DISPLAY,
+                null /* options */);
+    }
+
+    @Test
+    public void testUnregisterListenerIfNeeded_NotRegisteredYet_DoNothing() throws Exception {
+        mController.unregisterListenerIfNeeded();
+
+        verify(mMockWms, never()).registerWindowContextListener(any(), anyInt(), anyInt(), any());
+    }
+
+    @Test
+    public void testRegisterAndUnRegisterListener() {
+        mController.registerListener(TYPE_APPLICATION_OVERLAY, DEFAULT_DISPLAY,
+                null /* options */);
+
+        assertThat(mController.mListenerRegistered).isTrue();
+
+        mController.unregisterListenerIfNeeded();
+
+        assertThat(mController.mListenerRegistered).isFalse();
+    }
+}
diff --git a/core/tests/coretests/src/android/app/WindowContextTest.java b/core/tests/coretests/src/android/window/WindowContextTest.java
similarity index 97%
rename from core/tests/coretests/src/android/app/WindowContextTest.java
rename to core/tests/coretests/src/android/window/WindowContextTest.java
index 48b58c6..614e7c1 100644
--- a/core/tests/coretests/src/android/app/WindowContextTest.java
+++ b/core/tests/coretests/src/android/window/WindowContextTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.app;
+package android.window;
 
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
@@ -24,6 +24,9 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
+import android.app.Activity;
+import android.app.EmptyActivity;
+import android.app.Instrumentation;
 import android.content.Context;
 import android.content.Intent;
 import android.hardware.display.DisplayManager;
@@ -142,8 +145,8 @@
      * {@link WindowManager.LayoutParams#token}.
      *
      * The window context token should be overridden to
-     * {@link android.view.WindowManager.LayoutParams} and the {@link Activity}'s token must
-     * not be removed regardless of the release of window context.
+     * {@link android.view.WindowManager.LayoutParams} and the {@link Activity}'s token must not be
+     * removed regardless of release of window context.
      */
     @Test
     public void testCreateWindowContext_AttachActivity_TokenNotRemovedAfterRelease()
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 d9012f64..1633d28 100644
--- a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
@@ -154,8 +154,8 @@
         sOverrides.reset();
         sOverrides.createPackageManager = mPackageManagerOverride;
         DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.APPEND_DIRECT_SHARE_ENABLED,
-                Boolean.toString(false),
+                SystemUiDeviceConfigFlags.APPLY_SHARING_APP_LIMITS_IN_SYSUI,
+                Boolean.toString(true),
                 true /* makeDefault*/);
     }
 
@@ -1017,7 +1017,7 @@
         assertThat(adapter.getBaseScore(testDri, TARGET_TYPE_DEFAULT), is(testBaseScore));
         assertThat(adapter.getBaseScore(testDri, TARGET_TYPE_CHOOSER_TARGET), is(testBaseScore));
         assertThat(adapter.getBaseScore(testDri, TARGET_TYPE_SHORTCUTS_FROM_PREDICTION_SERVICE),
-                is(SHORTCUT_TARGET_SCORE_BOOST));
+                is(testBaseScore * SHORTCUT_TARGET_SCORE_BOOST));
         assertThat(adapter.getBaseScore(testDri, TARGET_TYPE_SHORTCUTS_FROM_SHORTCUT_MANAGER),
                 is(testBaseScore * SHORTCUT_TARGET_SCORE_BOOST));
     }
@@ -1262,6 +1262,126 @@
                 .getAllValues().get(2).getTaggedData(MetricsEvent.FIELD_RANKED_POSITION), is(0));
     }
 
+    @Test
+    public void testShortcutTargetWithApplyAppLimits() throws InterruptedException {
+        // Set up resources
+        sOverrides.resources = Mockito.spy(
+                InstrumentationRegistry.getInstrumentation().getContext().getResources());
+        when(sOverrides.resources.getInteger(R.integer.config_maxShortcutTargetsPerApp))
+                .thenReturn(1);
+        Intent sendIntent = createSendTextIntent();
+        // We need app targets for direct targets to get displayed
+        List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
+        when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
+                Mockito.anyBoolean(),
+                Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
+        // Create direct share target
+        List<ChooserTarget> serviceTargets = createDirectShareTargets(2,
+                resolvedComponentInfos.get(0).getResolveInfoAt(0).activityInfo.packageName);
+        ResolveInfo ri = ResolverDataProvider.createResolveInfo(3, 0);
+
+        // Start activity
+        final ChooserWrapperActivity activity = mActivityRule
+                .launchActivity(Intent.createChooser(sendIntent, null));
+
+        // Insert the direct share target
+        Map<ChooserTarget, ShortcutInfo> directShareToShortcutInfos = new HashMap<>();
+        List<ShareShortcutInfo> shortcutInfos = createShortcuts(activity);
+        directShareToShortcutInfos.put(serviceTargets.get(0),
+                shortcutInfos.get(0).getShortcutInfo());
+        directShareToShortcutInfos.put(serviceTargets.get(1),
+                shortcutInfos.get(1).getShortcutInfo());
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                () -> activity.getAdapter().addServiceResults(
+                        activity.createTestDisplayResolveInfo(sendIntent,
+                                ri,
+                                "testLabel",
+                                "testInfo",
+                                sendIntent,
+                                /* resolveInfoPresentationGetter */ null),
+                        serviceTargets,
+                        TARGET_TYPE_SHORTCUTS_FROM_PREDICTION_SERVICE,
+                        directShareToShortcutInfos,
+                        List.of())
+        );
+        // Thread.sleep shouldn't be a thing in an integration test but it's
+        // necessary here because of the way the code is structured
+        // TODO: restructure the tests b/129870719
+        Thread.sleep(ChooserActivity.LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS);
+
+        assertThat("Chooser should have 3 targets (2 apps, 1 direct)",
+                activity.getAdapter().getCount(), is(3));
+        assertThat("Chooser should have exactly one selectable direct target",
+                activity.getAdapter().getSelectableServiceTargetCount(), is(1));
+        assertThat("The resolver info must match the resolver info used to create the target",
+                activity.getAdapter().getItem(0).getResolveInfo(), is(ri));
+        assertThat("The display label must match",
+                activity.getAdapter().getItem(0).getDisplayLabel(), is("testTitle0"));
+    }
+
+    @Test
+    public void testShortcutTargetWithoutApplyAppLimits() throws InterruptedException {
+        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
+                SystemUiDeviceConfigFlags.APPLY_SHARING_APP_LIMITS_IN_SYSUI,
+                Boolean.toString(false),
+                true /* makeDefault*/);
+        // Set up resources
+        sOverrides.resources = Mockito.spy(
+                InstrumentationRegistry.getInstrumentation().getContext().getResources());
+        when(sOverrides.resources.getInteger(R.integer.config_maxShortcutTargetsPerApp))
+                .thenReturn(1);
+        Intent sendIntent = createSendTextIntent();
+        // We need app targets for direct targets to get displayed
+        List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
+        when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
+                Mockito.anyBoolean(),
+                Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
+        // Create direct share target
+        List<ChooserTarget> serviceTargets = createDirectShareTargets(2,
+                resolvedComponentInfos.get(0).getResolveInfoAt(0).activityInfo.packageName);
+        ResolveInfo ri = ResolverDataProvider.createResolveInfo(3, 0);
+
+        // Start activity
+        final ChooserWrapperActivity activity = mActivityRule
+                .launchActivity(Intent.createChooser(sendIntent, null));
+
+        // Insert the direct share target
+        Map<ChooserTarget, ShortcutInfo> directShareToShortcutInfos = new HashMap<>();
+        List<ShareShortcutInfo> shortcutInfos = createShortcuts(activity);
+        directShareToShortcutInfos.put(serviceTargets.get(0),
+                shortcutInfos.get(0).getShortcutInfo());
+        directShareToShortcutInfos.put(serviceTargets.get(1),
+                shortcutInfos.get(1).getShortcutInfo());
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                () -> activity.getAdapter().addServiceResults(
+                        activity.createTestDisplayResolveInfo(sendIntent,
+                                ri,
+                                "testLabel",
+                                "testInfo",
+                                sendIntent,
+                                /* resolveInfoPresentationGetter */ null),
+                        serviceTargets,
+                        TARGET_TYPE_SHORTCUTS_FROM_PREDICTION_SERVICE,
+                        directShareToShortcutInfos,
+                        List.of())
+        );
+        // Thread.sleep shouldn't be a thing in an integration test but it's
+        // necessary here because of the way the code is structured
+        // TODO: restructure the tests b/129870719
+        Thread.sleep(ChooserActivity.LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS);
+
+        assertThat("Chooser should have 4 targets (2 apps, 2 direct)",
+                activity.getAdapter().getCount(), is(4));
+        assertThat("Chooser should have exactly two selectable direct target",
+                activity.getAdapter().getSelectableServiceTargetCount(), is(2));
+        assertThat("The resolver info must match the resolver info used to create the target",
+                activity.getAdapter().getItem(0).getResolveInfo(), is(ri));
+        assertThat("The display label must match",
+                activity.getAdapter().getItem(0).getDisplayLabel(), is("testTitle0"));
+        assertThat("The display label must match",
+                activity.getAdapter().getItem(1).getDisplayLabel(), is("testTitle1"));
+    }
+
     // This test is too long and too slow and should not be taken as an example for future tests.
     @Test
     public void testDirectTargetLoggingWithAppTargetNotRankedPortrait()
@@ -1488,14 +1608,13 @@
         onView(withId(R.id.contentPanel))
                 .perform(swipeUp());
 
-        onView(withText(R.string.resolver_cant_share_with_work_apps))
+        onView(withText(R.string.resolver_cross_profile_blocked))
                 .check(matches(isDisplayed()));
     }
 
     @Test
     public void testWorkTab_workProfileDisabled_emptyStateShown() {
         // enable the work tab feature flag
-        ResolverActivity.ENABLE_TABBED_VIEW = true;
         markWorkProfileUserAvailable();
         int workProfileTargets = 4;
         List<ResolvedComponentInfo> personalResolvedComponentInfos =
@@ -1507,6 +1626,7 @@
         Intent sendIntent = createSendTextIntent();
         sendIntent.setType("TestType");
 
+        ResolverActivity.ENABLE_TABBED_VIEW = true;
         final ChooserWrapperActivity activity =
                 mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test"));
         waitForIdle();
@@ -1540,7 +1660,7 @@
         onView(withText(R.string.resolver_work_tab)).perform(click());
         waitForIdle();
 
-        onView(withText(R.string.resolver_no_work_apps_available_share))
+        onView(withText(R.string.resolver_no_work_apps_available))
                 .check(matches(isDisplayed()));
     }
 
@@ -1566,7 +1686,7 @@
         onView(withText(R.string.resolver_work_tab)).perform(click());
         waitForIdle();
 
-        onView(withText(R.string.resolver_cant_share_with_work_apps))
+        onView(withText(R.string.resolver_cross_profile_blocked))
                 .check(matches(isDisplayed()));
     }
 
@@ -1591,7 +1711,7 @@
         onView(withText(R.string.resolver_work_tab)).perform(click());
         waitForIdle();
 
-        onView(withText(R.string.resolver_no_work_apps_available_share))
+        onView(withText(R.string.resolver_no_work_apps_available))
                 .check(matches(isDisplayed()));
     }
 
@@ -1996,7 +2116,7 @@
         onView(withId(R.id.contentPanel))
                 .perform(swipeUp());
 
-        onView(withText(R.string.resolver_cant_access_work_apps))
+        onView(withText(R.string.resolver_cross_profile_blocked))
                 .check(matches(isDisplayed()));
     }
 
@@ -2026,7 +2146,7 @@
         onView(withText(R.string.resolver_work_tab)).perform(click());
         waitForIdle();
 
-        onView(withText(R.string.resolver_no_work_apps_available_resolve))
+        onView(withText(R.string.resolver_no_work_apps_available))
                 .check(matches(isDisplayed()));
     }
 
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 7dc5a8b..97652a9 100644
--- a/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java
@@ -650,7 +650,7 @@
         onView(withId(R.id.contentPanel))
                 .perform(swipeUp());
 
-        onView(withText(R.string.resolver_cant_access_work_apps))
+        onView(withText(R.string.resolver_cross_profile_blocked))
                 .check(matches(isDisplayed()));
     }
 
@@ -700,7 +700,7 @@
         onView(withText(R.string.resolver_work_tab)).perform(click());
         waitForIdle();
 
-        onView(withText(R.string.resolver_no_work_apps_available_resolve))
+        onView(withText(R.string.resolver_no_work_apps_available))
                 .check(matches(isDisplayed()));
     }
 
@@ -726,7 +726,7 @@
         onView(withText(R.string.resolver_work_tab)).perform(click());
         waitForIdle();
 
-        onView(withText(R.string.resolver_cant_access_work_apps))
+        onView(withText(R.string.resolver_cross_profile_blocked))
                 .check(matches(isDisplayed()));
     }
 
@@ -751,7 +751,7 @@
         onView(withText(R.string.resolver_work_tab)).perform(click());
         waitForIdle();
 
-        onView(withText(R.string.resolver_no_work_apps_available_resolve))
+        onView(withText(R.string.resolver_no_work_apps_available))
                 .check(matches(isDisplayed()));
     }
 
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsProviderTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsProviderTest.java
index 0f59143..d36f06a 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsProviderTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsProviderTest.java
@@ -158,4 +158,22 @@
 
         assertThat(item.time).isEqualTo(elapsedTimeMs);
     }
+
+    @Test
+    public void shouldUpdateStats() {
+        Context context = InstrumentationRegistry.getContext();
+        BatteryUsageStatsProvider provider = new BatteryUsageStatsProvider(context,
+                mStatsRule.getBatteryStats());
+
+        final List<BatteryUsageStatsQuery> queries = List.of(
+                new BatteryUsageStatsQuery.Builder().setMaxStatsAgeMs(1000).build(),
+                new BatteryUsageStatsQuery.Builder().setMaxStatsAgeMs(2000).build()
+        );
+
+        mStatsRule.setTime(10500, 0);
+        assertThat(provider.shouldUpdateStats(queries, 10000)).isFalse();
+
+        mStatsRule.setTime(11500, 0);
+        assertThat(provider.shouldUpdateStats(queries, 10000)).isTrue();
+    }
 }
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsTest.java
index 33b8aed..a18a88c 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsTest.java
@@ -68,7 +68,8 @@
 
         final BatteryUsageStats.Builder builder = new BatteryUsageStats.Builder(1, 1)
                 .setDischargePercentage(20)
-                .setDischargedPowerRange(1000, 2000);
+                .setDischargedPowerRange(1000, 2000)
+                .setStatsStartTimestamp(1000);
 
         builder.getOrCreateUidBatteryConsumerBuilder(batteryStatsUid)
                 .setPackageWithHighestDrain("foo")
@@ -95,7 +96,8 @@
                 .setUsageDurationMillis(
                         BatteryConsumer.TIME_COMPONENT_CPU, 10300)
                 .setUsageDurationForCustomComponentMillis(
-                        BatteryConsumer.FIRST_CUSTOM_TIME_COMPONENT_ID, 10400);
+                        BatteryConsumer.FIRST_CUSTOM_TIME_COMPONENT_ID, 10400)
+                .setPowerConsumedByApps(20000);
 
         return builder.build();
     }
@@ -105,6 +107,7 @@
         assertThat(batteryUsageStats.getDischargePercentage()).isEqualTo(20);
         assertThat(batteryUsageStats.getDischargedPowerRange().getLower()).isEqualTo(1000);
         assertThat(batteryUsageStats.getDischargedPowerRange().getUpper()).isEqualTo(2000);
+        assertThat(batteryUsageStats.getStatsStartTimestamp()).isEqualTo(1000);
 
         final List<UidBatteryConsumer> uidBatteryConsumers =
                 batteryUsageStats.getUidBatteryConsumers();
@@ -146,6 +149,7 @@
                 assertThat(systemBatteryConsumer.getUsageDurationForCustomComponentMillis(
                         BatteryConsumer.FIRST_CUSTOM_TIME_COMPONENT_ID)).isEqualTo(10400);
                 assertThat(systemBatteryConsumer.getConsumedPower()).isEqualTo(20300);
+                assertThat(systemBatteryConsumer.getPowerConsumedByApps()).isEqualTo(20000);
             } else {
                 fail("Unexpected drain type " + systemBatteryConsumer.getDrainType());
             }
diff --git a/core/tests/coretests/src/com/android/internal/os/BluetoothPowerCalculatorTest.java b/core/tests/coretests/src/com/android/internal/os/BluetoothPowerCalculatorTest.java
index 71d7668..2769b16 100644
--- a/core/tests/coretests/src/com/android/internal/os/BluetoothPowerCalculatorTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BluetoothPowerCalculatorTest.java
@@ -69,7 +69,7 @@
                 0.24722, 15000);
         assertBluetoothPowerAndDuration(
                 mStatsRule.getSystemBatteryConsumer(SystemBatteryConsumer.DRAIN_TYPE_BLUETOOTH),
-                0.15833, 9000);
+                0.51944, 9000, 0.51944, 0.36111);
     }
 
     @Test
@@ -98,7 +98,7 @@
                 0.2, 15000);
         assertBluetoothPowerAndDuration(
                 mStatsRule.getSystemBatteryConsumer(SystemBatteryConsumer.DRAIN_TYPE_BLUETOOTH),
-                0.15, 9000);
+                0.45, 9000, 0.45, 0.3);
     }
 
     private void setDurationsAndPower(
@@ -123,4 +123,15 @@
 
         assertThat(usageDurationMillis).isEqualTo(durationMs);
     }
+
+    private void assertBluetoothPowerAndDuration(@Nullable SystemBatteryConsumer batteryConsumer,
+            double powerMah, int durationMs, double consumedPower, double attributedPower) {
+        assertBluetoothPowerAndDuration(batteryConsumer, powerMah, durationMs);
+
+        assertThat(batteryConsumer.getConsumedPower())
+                .isWithin(PRECISION).of(consumedPower);
+
+        assertThat(batteryConsumer.getPowerConsumedByApps())
+                .isWithin(PRECISION).of(attributedPower);
+    }
 }
diff --git a/core/tests/coretests/src/com/android/internal/os/GnssPowerCalculatorTest.java b/core/tests/coretests/src/com/android/internal/os/GnssPowerCalculatorTest.java
index bd7f1e2..eed61cb 100644
--- a/core/tests/coretests/src/com/android/internal/os/GnssPowerCalculatorTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/GnssPowerCalculatorTest.java
@@ -19,6 +19,7 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import android.os.BatteryConsumer;
+import android.os.BatteryUsageStatsQuery;
 import android.os.Process;
 import android.os.UidBatteryConsumer;
 
@@ -35,12 +36,14 @@
     private static final double PRECISION = 0.00001;
 
     private static final int APP_UID = Process.FIRST_APPLICATION_UID + 42;
+    private static final int APP_UID2 = Process.FIRST_APPLICATION_UID + 222;
 
     @Rule
     public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule()
             .setAveragePower(PowerProfile.POWER_GPS_ON, 360.0)
             .setAveragePower(PowerProfile.POWER_GPS_SIGNAL_QUALITY_BASED,
-                    new double[] {720.0, 1440.0, 1800.0});
+                    new double[] {720.0, 1440.0, 1800.0})
+            .initMeasuredEnergyStatsLocked(0);
 
     @Test
     public void testTimerBasedModel() {
@@ -51,7 +54,8 @@
         GnssPowerCalculator calculator =
                 new GnssPowerCalculator(mStatsRule.getPowerProfile());
 
-        mStatsRule.apply(calculator);
+        mStatsRule.apply(new BatteryUsageStatsQuery.Builder().powerProfileModeledOnly().build(),
+                calculator);
 
         UidBatteryConsumer consumer = mStatsRule.getUidBatteryConsumer(APP_UID);
         assertThat(consumer.getUsageDurationMillis(BatteryConsumer.TIME_COMPONENT_GNSS))
@@ -59,4 +63,35 @@
         assertThat(consumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_GNSS))
                 .isWithin(PRECISION).of(0.1);
     }
+
+    @Test
+    public void testMeasuredEnergyBasedModel() {
+        BatteryStatsImpl.Uid uidStats = mStatsRule.getUidStats(APP_UID);
+        uidStats.noteStartGps(1000);
+        uidStats.noteStopGps(2000);
+
+        BatteryStatsImpl.Uid uidStats2 = mStatsRule.getUidStats(APP_UID2);
+        uidStats2.noteStartGps(3000);
+        uidStats2.noteStopGps(5000);
+
+        BatteryStatsImpl stats = mStatsRule.getBatteryStats();
+        stats.updateGnssMeasuredEnergyStatsLocked(30_000_000, 6000);
+
+        GnssPowerCalculator calculator =
+                new GnssPowerCalculator(mStatsRule.getPowerProfile());
+
+        mStatsRule.apply(calculator);
+
+        UidBatteryConsumer consumer = mStatsRule.getUidBatteryConsumer(APP_UID);
+        assertThat(consumer.getUsageDurationMillis(BatteryConsumer.TIME_COMPONENT_GNSS))
+                .isEqualTo(1000);
+        assertThat(consumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_GNSS))
+                .isWithin(PRECISION).of(2.77777);
+
+        UidBatteryConsumer consumer2 = mStatsRule.getUidBatteryConsumer(APP_UID2);
+        assertThat(consumer2.getUsageDurationMillis(BatteryConsumer.TIME_COMPONENT_GNSS))
+                .isEqualTo(2000);
+        assertThat(consumer2.getConsumedPower(BatteryConsumer.POWER_COMPONENT_GNSS))
+                .isWithin(PRECISION).of(5.55555);
+    }
 }
diff --git a/core/tests/coretests/src/com/android/internal/os/MobileRadioPowerCalculatorTest.java b/core/tests/coretests/src/com/android/internal/os/MobileRadioPowerCalculatorTest.java
index 66a8379..813bc9f 100644
--- a/core/tests/coretests/src/com/android/internal/os/MobileRadioPowerCalculatorTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/MobileRadioPowerCalculatorTest.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.os;
 
+import static android.os.BatteryStats.POWER_DATA_UNAVAILABLE;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.Mockito.mock;
@@ -24,6 +26,7 @@
 import android.net.NetworkCapabilities;
 import android.net.NetworkStats;
 import android.os.BatteryConsumer;
+import android.os.BatteryUsageStatsQuery;
 import android.os.Process;
 import android.os.SystemBatteryConsumer;
 import android.os.UidBatteryConsumer;
@@ -54,7 +57,8 @@
             .setAveragePower(PowerProfile.POWER_RADIO_SCANNING, 720.0)
             .setAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_RX, 1440.0)
             .setAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_TX,
-                    new double[] {720.0, 1080.0, 1440.0, 1800.0, 2160.0});
+                    new double[] {720.0, 1080.0, 1440.0, 1800.0, 2160.0})
+            .initMeasuredEnergyStatsLocked(0);
 
     @Test
     public void testCounterBasedModel() {
@@ -88,7 +92,63 @@
 
         ModemActivityInfo mai = new ModemActivityInfo(10000, 2000, 3000,
                 new int[] {100, 200, 300, 400, 500}, 600);
-        stats.noteModemControllerActivity(mai, 10000, 10000);
+        stats.noteModemControllerActivity(mai, POWER_DATA_UNAVAILABLE, 10000, 10000);
+
+        mStatsRule.setTime(12_000_000, 12_000_000);
+
+        MobileRadioPowerCalculator calculator =
+                new MobileRadioPowerCalculator(mStatsRule.getPowerProfile());
+
+        mStatsRule.apply(new BatteryUsageStatsQuery.Builder().powerProfileModeledOnly().build(),
+                calculator);
+
+        SystemBatteryConsumer consumer =
+                mStatsRule.getSystemBatteryConsumer(SystemBatteryConsumer.DRAIN_TYPE_MOBILE_RADIO);
+        assertThat(consumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
+                .isWithin(PRECISION).of(2.2444);
+        assertThat(consumer.getConsumedPower())
+                .isWithin(PRECISION).of(2.2444);
+        assertThat(consumer.getPowerConsumedByApps())
+                .isWithin(PRECISION).of(0.8);
+
+        UidBatteryConsumer uidConsumer = mStatsRule.getUidBatteryConsumer(APP_UID);
+        assertThat(uidConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
+                .isWithin(PRECISION).of(0.8);
+    }
+
+    @Test
+    public void testMeasuredEnergyBasedModel() {
+        BatteryStatsImpl stats = mStatsRule.getBatteryStats();
+
+        // Scan for a cell
+        stats.notePhoneStateLocked(ServiceState.STATE_OUT_OF_SERVICE,
+                TelephonyManager.SIM_STATE_READY,
+                2000, 2000);
+
+        // Found a cell
+        stats.notePhoneStateLocked(ServiceState.STATE_IN_SERVICE, TelephonyManager.SIM_STATE_READY,
+                5000, 5000);
+
+        // Note cell signal strength
+        SignalStrength signalStrength = mock(SignalStrength.class);
+        when(signalStrength.getLevel()).thenReturn(SignalStrength.SIGNAL_STRENGTH_MODERATE);
+        stats.notePhoneSignalStrengthLocked(signalStrength, 5000, 5000);
+
+        stats.noteMobileRadioPowerStateLocked(DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH,
+                8_000_000_000L, APP_UID, 8000, 8000);
+
+        // Note established network
+        stats.noteNetworkInterfaceForTransports("cellular",
+                new int[] { NetworkCapabilities.TRANSPORT_CELLULAR });
+
+        // Note application network activity
+        NetworkStats networkStats = new NetworkStats(10000, 1)
+                .insertEntry("cellular", APP_UID, 0, 0, 1000, 100, 2000, 20, 100);
+        mStatsRule.setNetworkStats(networkStats);
+
+        ModemActivityInfo mai = new ModemActivityInfo(10000, 2000, 3000,
+                new int[] {100, 200, 300, 400, 500}, 600);
+        stats.noteModemControllerActivity(mai, 10_000_000, 10000, 10000);
 
         mStatsRule.setTime(12_000_000, 12_000_000);
 
@@ -99,11 +159,15 @@
 
         SystemBatteryConsumer consumer =
                 mStatsRule.getSystemBatteryConsumer(SystemBatteryConsumer.DRAIN_TYPE_MOBILE_RADIO);
+
+        // 100000000 uAs * (1 mA / 1000 uA) * (1 h / 3600 s) + 1.53934 (apps)= 4.31711 mAh
         assertThat(consumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
-                .isWithin(PRECISION).of(1.44440);
+                .isWithin(PRECISION).of(4.31711);
+        assertThat(consumer.getPowerConsumedByApps())
+                .isWithin(PRECISION).of(1.53934);
 
         UidBatteryConsumer uidConsumer = mStatsRule.getUidBatteryConsumer(APP_UID);
         assertThat(uidConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
-                .isWithin(PRECISION).of(0.8);
+                .isWithin(PRECISION).of(1.53934);
     }
 }
diff --git a/core/tests/coretests/src/com/android/internal/os/ScreenPowerCalculatorTest.java b/core/tests/coretests/src/com/android/internal/os/ScreenPowerCalculatorTest.java
index f3cf81c..d296afa 100644
--- a/core/tests/coretests/src/com/android/internal/os/ScreenPowerCalculatorTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/ScreenPowerCalculatorTest.java
@@ -52,17 +52,26 @@
         BatteryStatsImpl batteryStats = mStatsRule.getBatteryStats();
 
         batteryStats.noteScreenStateLocked(Display.STATE_ON, 0, 0, 0);
-        batteryStats.updateDisplayMeasuredEnergyStatsLocked(0, Display.STATE_ON, 2 * MINUTE_IN_MS);
+        batteryStats.updateDisplayMeasuredEnergyStatsLocked(0, Display.STATE_ON, 0);
+        setProcState(APP_UID1, ActivityManager.PROCESS_STATE_TOP, true,
+                0, 0);
 
-        setFgState(APP_UID1, true, 2 * MINUTE_IN_MS, 2 * MINUTE_IN_MS);
-        setFgState(APP_UID1, false, 20 * MINUTE_IN_MS, 20 * MINUTE_IN_MS);
-        setFgState(APP_UID2, true, 30 * MINUTE_IN_MS, 30 * MINUTE_IN_MS);
+        batteryStats.updateDisplayMeasuredEnergyStatsLocked(200_000_000, Display.STATE_ON,
+                15 * MINUTE_IN_MS);
+
+        setProcState(APP_UID1, ActivityManager.PROCESS_STATE_CACHED_EMPTY, false,
+                20 * MINUTE_IN_MS, 20 * MINUTE_IN_MS);
+
+        setProcState(APP_UID2, ActivityManager.PROCESS_STATE_TOP, true,
+                20 * MINUTE_IN_MS, 20 * MINUTE_IN_MS);
 
         batteryStats.updateDisplayMeasuredEnergyStatsLocked(300_000_000, Display.STATE_ON,
                 60 * MINUTE_IN_MS);
 
         batteryStats.noteScreenStateLocked(Display.STATE_OFF,
                 80 * MINUTE_IN_MS, 80 * MINUTE_IN_MS, 80 * MINUTE_IN_MS);
+        setProcState(APP_UID2, ActivityManager.PROCESS_STATE_TOP_SLEEPING, false,
+                80 * MINUTE_IN_MS, 80 * MINUTE_IN_MS);
 
         batteryStats.updateDisplayMeasuredEnergyStatsLocked(100_000_000, Display.STATE_DOZE,
                 120 * MINUTE_IN_MS);
@@ -79,28 +88,33 @@
         assertThat(consumer.getUsageDurationMillis(BatteryConsumer.TIME_COMPONENT_USAGE))
                 .isEqualTo(80 * MINUTE_IN_MS);
 
-        // 400000000 uAs * (1 mA / 1000 uA) * (1 h / 3600 s)  = 111.11111 mAh
+        // 600000000 uAs * (1 mA / 1000 uA) * (1 h / 3600 s)  = 166.66666 mAh
         assertThat(consumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_USAGE))
-                .isWithin(PRECISION).of(111.11111);
+                .isWithin(PRECISION).of(166.66666);
+        assertThat(consumer.getConsumedPower())
+                .isWithin(PRECISION).of(166.66666);
+        assertThat(consumer.getPowerConsumedByApps())
+                .isWithin(PRECISION).of(166.66666);
 
         UidBatteryConsumer uid1 = mStatsRule.getUidBatteryConsumer(APP_UID1);
         assertThat(uid1.getUsageDurationMillis(BatteryConsumer.TIME_COMPONENT_SCREEN))
-                .isEqualTo(18 * MINUTE_IN_MS);
+                .isEqualTo(20 * MINUTE_IN_MS);
 
-        // Uid1 ran for 18 minutes out of the total 48 min of foreground time during the first
-        // Display update. Uid1 charge = 18 / 48 * 300000000 uAs = 31.25 mAh
+        // Uid1 took all of the foreground time during the first Display update.
+        // It also ran for 5 out of 45 min during the second Display update:
+        // Uid1 charge = 200000000 + 5 / 45 * 300000000 mAs = 64.81 mAh
         assertThat(uid1.getConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN))
-                .isWithin(PRECISION).of(31.25);
+                .isWithin(PRECISION).of(64.81481);
 
         UidBatteryConsumer uid2 = mStatsRule.getUidBatteryConsumer(APP_UID2);
         assertThat(uid2.getUsageDurationMillis(BatteryConsumer.TIME_COMPONENT_SCREEN))
-                .isEqualTo(90 * MINUTE_IN_MS);
+                .isEqualTo(60 * MINUTE_IN_MS);
 
-        // Uid2 ran for 30 minutes out of the total 48 min of foreground time during the first
-        // Display update and then took all of the time during the second Display update.
-        // Uid1 charge = 30 / 48 * 300000000 + 100000000 mAs = 79.86111 mAh
+        // Uid2 ran for 40 minutes out of the total 45 min of foreground time during the second
+        // Display update and then took all of the time during the third Display update.
+        // Uid2 charge = 40 / 45 * 300000000 + 100000000 mAs = 101.85 mAh
         assertThat(uid2.getConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN))
-                .isWithin(PRECISION).of(79.86111);
+                .isWithin(PRECISION).of(101.85185);
     }
 
     @Test
@@ -108,18 +122,22 @@
         BatteryStatsImpl batteryStats = mStatsRule.getBatteryStats();
 
         batteryStats.noteScreenStateLocked(Display.STATE_ON, 0, 0, 0);
-
-        setFgState(APP_UID1, true, 2 * MINUTE_IN_MS, 2 * MINUTE_IN_MS);
+        batteryStats.noteScreenBrightnessLocked(255, 0, 0);
+        setProcState(APP_UID1, ActivityManager.PROCESS_STATE_TOP, true,
+                0, 0);
 
         batteryStats.noteScreenBrightnessLocked(100, 5 * MINUTE_IN_MS, 5 * MINUTE_IN_MS);
         batteryStats.noteScreenBrightnessLocked(200, 10 * MINUTE_IN_MS, 10 * MINUTE_IN_MS);
 
-        setFgState(APP_UID1, false, 20 * MINUTE_IN_MS, 20 * MINUTE_IN_MS);
-
-        setFgState(APP_UID2, true, 30 * MINUTE_IN_MS, 30 * MINUTE_IN_MS);
+        setProcState(APP_UID1, ActivityManager.PROCESS_STATE_CACHED_EMPTY, false,
+                20 * MINUTE_IN_MS, 20 * MINUTE_IN_MS);
+        setProcState(APP_UID2, ActivityManager.PROCESS_STATE_TOP, true,
+                20 * MINUTE_IN_MS, 20 * MINUTE_IN_MS);
 
         batteryStats.noteScreenStateLocked(Display.STATE_OFF,
                 80 * MINUTE_IN_MS, 80 * MINUTE_IN_MS, 80 * MINUTE_IN_MS);
+        setProcState(APP_UID2, ActivityManager.PROCESS_STATE_TOP_SLEEPING, false,
+                80 * MINUTE_IN_MS, 80 * MINUTE_IN_MS);
 
         mStatsRule.setTime(120 * MINUTE_IN_US, 120 * MINUTE_IN_US);
 
@@ -134,31 +152,39 @@
         assertThat(consumer.getUsageDurationMillis(BatteryConsumer.TIME_COMPONENT_USAGE))
                 .isEqualTo(80 * MINUTE_IN_MS);
         assertThat(consumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_USAGE))
-                .isWithin(PRECISION).of(88.4);
+                .isWithin(PRECISION).of(92.0);
+        assertThat(consumer.getConsumedPower())
+                .isWithin(PRECISION).of(92.0);
+        assertThat(consumer.getPowerConsumedByApps())
+                .isWithin(PRECISION).of(92.0);
 
         UidBatteryConsumer uid1 = mStatsRule.getUidBatteryConsumer(APP_UID1);
         assertThat(uid1.getUsageDurationMillis(BatteryConsumer.TIME_COMPONENT_SCREEN))
-                .isEqualTo(18 * MINUTE_IN_MS);
+                .isEqualTo(20 * MINUTE_IN_MS);
+
+        // Uid1 took 20 out of the total of 80 min of foreground activity
+        // Uid1 charge = 20 / 80 * 92.0 = 23.0 mAh
         assertThat(uid1.getConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN))
-                .isWithin(PRECISION).of(14.73333);
+                .isWithin(PRECISION).of(23.0);
 
         UidBatteryConsumer uid2 = mStatsRule.getUidBatteryConsumer(APP_UID2);
         assertThat(uid2.getUsageDurationMillis(BatteryConsumer.TIME_COMPONENT_SCREEN))
-                .isEqualTo(90 * MINUTE_IN_MS);
+                .isEqualTo(60 * MINUTE_IN_MS);
+
+        // Uid2 took 60 out of the total of 80 min of foreground activity
+        // Uid2 charge = 60 / 80 * 92.0 = 69.0 mAh
         assertThat(uid2.getConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN))
-                .isWithin(PRECISION).of(73.66666);
+                .isWithin(PRECISION).of(69.0);
     }
 
-    private void setFgState(int uid, boolean fgOn, long realtimeMs, long uptimeMs) {
+    private void setProcState(int uid, int procState, boolean resumed, long realtimeMs,
+            long uptimeMs) {
         BatteryStatsImpl batteryStats = mStatsRule.getBatteryStats();
-        if (fgOn) {
+        batteryStats.noteUidProcessStateLocked(uid, procState, realtimeMs, uptimeMs);
+        if (resumed) {
             batteryStats.noteActivityResumedLocked(uid, realtimeMs, uptimeMs);
-            batteryStats.noteUidProcessStateLocked(uid, ActivityManager.PROCESS_STATE_TOP,
-                    realtimeMs, uptimeMs);
         } else {
             batteryStats.noteActivityPausedLocked(uid, realtimeMs, uptimeMs);
-            batteryStats.noteUidProcessStateLocked(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY,
-                    realtimeMs, uptimeMs);
         }
     }
 }
diff --git a/core/tests/coretests/src/com/android/internal/os/WifiPowerCalculatorTest.java b/core/tests/coretests/src/com/android/internal/os/WifiPowerCalculatorTest.java
index 2e23dc8..5df91dd 100644
--- a/core/tests/coretests/src/com/android/internal/os/WifiPowerCalculatorTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/WifiPowerCalculatorTest.java
@@ -99,7 +99,9 @@
         assertThat(systemConsumer.getUsageDurationMillis(BatteryConsumer.TIME_COMPONENT_WIFI))
                 .isEqualTo(5577);
         assertThat(systemConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_WIFI))
-                .isWithin(PRECISION).of(0.645200);
+                .isWithin(PRECISION).of(1.11153);
+        assertThat(systemConsumer.getPowerConsumedByApps())
+                .isWithin(PRECISION).of(0.466333);
     }
 
     @Test
@@ -125,7 +127,9 @@
                 .isEqualTo(5577);
         /* Same ratio as in testPowerControllerBasedModel_nonMeasured but scaled by 1_000_000uC. */
         assertThat(systemConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_WIFI))
-                .isWithin(PRECISION).of(0.645200 / (0.2214666 + 0.645200) * 1_000_000 / 3600000);
+                .isWithin(PRECISION).of(1.11153 / (0.2214666 + 0.645200) * 1_000_000 / 3600000);
+        assertThat(systemConsumer.getPowerConsumedByApps())
+                .isWithin(PRECISION).of(0.14946);
     }
 
     /** Sets up batterystats object with prepopulated network & timer data for Timer-model tests. */
@@ -163,7 +167,9 @@
         assertThat(systemConsumer.getUsageDurationMillis(BatteryConsumer.TIME_COMPONENT_WIFI))
                 .isEqualTo(2222);
         assertThat(systemConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_WIFI))
-                .isWithin(PRECISION).of(0.8759216);
+                .isWithin(PRECISION).of(2.575000);
+        assertThat(systemConsumer.getPowerConsumedByApps())
+                .isWithin(PRECISION).of(1.69907);
     }
 
     @Test
@@ -190,6 +196,8 @@
                 .isEqualTo(2222);
         /* Same ratio as in testTimerBasedModel_nonMeasured but scaled by 1_000_000uC. */
         assertThat(systemConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_WIFI))
-                .isWithin(PRECISION).of(0.8759216 / (0.8231573 + 0.8759216) * 1_000_000 / 3600000);
+                .isWithin(PRECISION).of(2.575000 / (0.8231573 + 0.8759216) * 1_000_000 / 3600000);
+        assertThat(systemConsumer.getPowerConsumedByApps())
+                .isWithin(PRECISION).of(0.277777);
     }
 }
diff --git a/core/tests/hosttests/test-apps/ExternalLocAllPermsTestApp/AndroidManifest.xml b/core/tests/hosttests/test-apps/ExternalLocAllPermsTestApp/AndroidManifest.xml
index 0898fae..b3b34ef 100644
--- a/core/tests/hosttests/test-apps/ExternalLocAllPermsTestApp/AndroidManifest.xml
+++ b/core/tests/hosttests/test-apps/ExternalLocAllPermsTestApp/AndroidManifest.xml
@@ -32,6 +32,8 @@
     <uses-permission android:name="android.permission.BIND_INPUT_METHOD" />
     <uses-permission android:name="android.permission.BLUETOOTH" />
     <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
+    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
+    <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
     <uses-permission android:name="android.permission.BRICK" />
     <uses-permission android:name="android.permission.BROADCAST_PACKAGE_REMOVED" />
     <uses-permission android:name="android.permission.BROADCAST_SMS" />
diff --git a/core/tests/hosttests/test-apps/ExternalSharedPermsBT/AndroidManifest.xml b/core/tests/hosttests/test-apps/ExternalSharedPermsBT/AndroidManifest.xml
index 98f7177..42d9407 100644
--- a/core/tests/hosttests/test-apps/ExternalSharedPermsBT/AndroidManifest.xml
+++ b/core/tests/hosttests/test-apps/ExternalSharedPermsBT/AndroidManifest.xml
@@ -21,6 +21,9 @@
        android:sharedUserId="com.android.framework.externalsharedpermstestapp">
 
     <uses-permission android:name="android.permission.BLUETOOTH" />
+    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
+    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
+    <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
 
     <application>
         <uses-library android:name="android.test.runner" />
diff --git a/data/etc/OWNERS b/data/etc/OWNERS
index 549e074..5aacfdd 100644
--- a/data/etc/OWNERS
+++ b/data/etc/OWNERS
@@ -13,3 +13,4 @@
 yamasani@google.com
 
 per-file preinstalled-packages* = file:/MULTIUSER_OWNERS
+per-file services.core.protolog.json =  file:/services/core/java/com/android/server/wm/OWNERS
diff --git a/data/etc/car/com.android.car.carlauncher.xml b/data/etc/car/com.android.car.carlauncher.xml
index ac16af3..abde232 100644
--- a/data/etc/car/com.android.car.carlauncher.xml
+++ b/data/etc/car/com.android.car.carlauncher.xml
@@ -18,6 +18,7 @@
     <privapp-permissions package="com.android.car.carlauncher">
         <permission name="android.permission.ACTIVITY_EMBEDDING"/>
         <permission name="android.permission.CONTROL_INCALL_EXPERIENCE"/>
+        <permission name="android.permission.INTERACT_ACROSS_USERS"/>
         <permission name="android.permission.MANAGE_USERS"/>
         <permission name="android.permission.MEDIA_CONTENT_CONTROL"/>
         <permission name="android.permission.PACKAGE_USAGE_STATS"/>
diff --git a/data/etc/car/com.android.car.cluster.home.xml b/data/etc/car/com.android.car.cluster.home.xml
index 4c2d614..832e5a7 100644
--- a/data/etc/car/com.android.car.cluster.home.xml
+++ b/data/etc/car/com.android.car.cluster.home.xml
@@ -16,6 +16,8 @@
   -->
 <permissions>
     <privapp-permissions package="com.android.car.cluster.home">
+        <permission name="android.permission.INTERACT_ACROSS_USERS"/>
+        <permission name="android.car.permission.ACCESS_PRIVATE_DISPLAY_ID"/>
         <permission name="android.car.permission.CAR_INSTRUMENT_CLUSTER_CONTROL"/>
     </privapp-permissions>
 </permissions>
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index 27bf4ef..3213390 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -48,6 +48,10 @@
         <group gid="uhid" />
     </permission>
 
+    <permission name="android.permission.VIRTUAL_INPUT_DEVICE" >
+        <group gid="uhid" />
+    </permission>
+
     <permission name="android.permission.NET_TUNNELING" >
         <group gid="vpn" />
     </permission>
@@ -224,7 +228,22 @@
                       targetSdk="29">
         <new-permission name="android.permission.ACCESS_MEDIA_LOCATION" />
     </split-permission>
-
+    <split-permission name="android.permission.BLUETOOTH"
+                      targetSdk="31">
+        <new-permission name="android.permission.BLUETOOTH_SCAN" />
+    </split-permission>
+    <split-permission name="android.permission.BLUETOOTH"
+                      targetSdk="31">
+        <new-permission name="android.permission.BLUETOOTH_CONNECT" />
+    </split-permission>
+    <split-permission name="android.permission.BLUETOOTH_ADMIN"
+                      targetSdk="31">
+        <new-permission name="android.permission.BLUETOOTH_SCAN" />
+    </split-permission>
+    <split-permission name="android.permission.BLUETOOTH_ADMIN"
+                      targetSdk="31">
+        <new-permission name="android.permission.BLUETOOTH_CONNECT" />
+    </split-permission>
 
     <!-- This is a list of all the libraries available for application
          code to link against. -->
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index c70d6b0..d9c0db9 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -1219,12 +1219,6 @@
       "group": "WM_DEBUG_ORIENTATION",
       "at": "com\/android\/server\/wm\/DragState.java"
     },
-    "-681380736": {
-      "message": "Sandbox max bounds for uid %s to bounds %s due to letterboxing from mismatch with parent bounds? %s size compat mode %s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_CONFIGURATION",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
     "-677449371": {
       "message": "moveTaskToRootTask: moving task=%d to rootTaskId=%d toTop=%b",
       "level": "DEBUG",
@@ -2875,6 +2869,12 @@
       "group": "WM_DEBUG_BOOT",
       "at": "com\/android\/server\/wm\/WindowManagerService.java"
     },
+    "1237719089": {
+      "message": "Sandbox max bounds for uid %s to bounds %s. letterboxing from mismatch with parent bounds = %s, has mCompatDisplayInsets = %s, should create compatDisplayInsets = %s",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_CONFIGURATION",
+      "at": "com\/android\/server\/wm\/ActivityRecord.java"
+    },
     "1246035185": {
       "message": "stopFreezingDisplayLocked: Returning waitingForConfig=%b, waitingForRemoteRotation=%b, mAppsFreezingScreen=%d, mWindowsFreezingScreen=%d, mClientFreezingScreen=%b, mOpeningApps.size()=%d",
       "level": "DEBUG",
diff --git a/docs/html/reference/images/rounded_corner/rounded-corner-info.png b/docs/html/reference/images/rounded_corner/rounded-corner-info.png
new file mode 100644
index 0000000..312d935
--- /dev/null
+++ b/docs/html/reference/images/rounded_corner/rounded-corner-info.png
Binary files differ
diff --git a/graphics/java/android/graphics/BLASTBufferQueue.java b/graphics/java/android/graphics/BLASTBufferQueue.java
index 3aaf11c..4534d36 100644
--- a/graphics/java/android/graphics/BLASTBufferQueue.java
+++ b/graphics/java/android/graphics/BLASTBufferQueue.java
@@ -28,7 +28,7 @@
     public long mNativeObject; // BLASTBufferQueue*
 
     private static native long nativeCreate(String name, long surfaceControl, long width,
-            long height, int format, boolean tripleBufferingEnabled);
+            long height, int format);
     private static native void nativeDestroy(long ptr);
     private static native Surface nativeGetSurface(long ptr, boolean includeSurfaceControlHandle);
     private static native void nativeSetNextTransaction(long ptr, long transactionPtr);
@@ -53,9 +53,8 @@
 
     /** Create a new connection with the surface flinger. */
     public BLASTBufferQueue(String name, SurfaceControl sc, int width, int height,
-            @PixelFormat.Format int format, boolean tripleBufferingEnabled) {
-        mNativeObject = nativeCreate(name, sc.mNativeObject, width, height, format,
-                tripleBufferingEnabled);
+            @PixelFormat.Format int format) {
+        mNativeObject = nativeCreate(name, sc.mNativeObject, width, height, format);
     }
 
     public void destroy() {
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index 2a6bbf3..c48fd8b 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -34,9 +34,11 @@
 import android.graphics.fonts.FontStyle;
 import android.graphics.fonts.FontVariationAxis;
 import android.graphics.fonts.SystemFonts;
+import android.icu.util.ULocale;
 import android.os.Build;
 import android.os.ParcelFileDescriptor;
 import android.os.SharedMemory;
+import android.os.SystemProperties;
 import android.os.Trace;
 import android.provider.FontRequest;
 import android.provider.FontsContract;
@@ -45,6 +47,7 @@
 import android.text.FontConfig;
 import android.util.ArrayMap;
 import android.util.Base64;
+import android.util.Log;
 import android.util.LongSparseArray;
 import android.util.LruCache;
 import android.util.SparseArray;
@@ -1375,13 +1378,35 @@
 
     static {
         // Preload Roboto-Regular.ttf in Zygote for improving app launch performance.
-        // TODO: add new attribute to fonts.xml to preload fonts in Zygote.
         preloadFontFile("/system/fonts/Roboto-Regular.ttf");
+
+        String locale = SystemProperties.get("persist.sys.locale", "en-US");
+        String script = ULocale.addLikelySubtags(ULocale.forLanguageTag(locale)).getScript();
+
+        FontConfig config = SystemFonts.getSystemPreinstalledFontConfig();
+        for (int i = 0; i < config.getFontFamilies().size(); ++i) {
+            FontConfig.FontFamily family = config.getFontFamilies().get(i);
+            boolean loadFamily = false;
+            for (int j = 0; j < family.getLocaleList().size(); ++j) {
+                String fontScript = ULocale.addLikelySubtags(
+                        ULocale.forLocale(family.getLocaleList().get(j))).getScript();
+                loadFamily = fontScript.equals(script);
+                if (loadFamily) {
+                    break;
+                }
+            }
+            if (loadFamily) {
+                for (int j = 0; j < family.getFontList().size(); ++j) {
+                    preloadFontFile(family.getFontList().get(j).getFile().getAbsolutePath());
+                }
+            }
+        }
     }
 
     private static void preloadFontFile(String filePath) {
         File file = new File(filePath);
         if (file.exists()) {
+            Log.i(TAG, "Preloading " + file.getAbsolutePath());
             nativeWarmUpCache(filePath);
         }
     }
@@ -1441,13 +1466,11 @@
 
     /** @hide */
     public boolean isSupportedAxes(int axis) {
-        if (mSupportedAxes == null) {
-            synchronized (this) {
+        synchronized (this) {
+            if (mSupportedAxes == null) {
+                mSupportedAxes = nativeGetSupportedAxes(native_instance);
                 if (mSupportedAxes == null) {
-                    mSupportedAxes = nativeGetSupportedAxes(native_instance);
-                    if (mSupportedAxes == null) {
-                        mSupportedAxes = EMPTY_AXES;
-                    }
+                    mSupportedAxes = EMPTY_AXES;
                 }
             }
         }
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index 24d73ef..3616a4d 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -276,7 +276,11 @@
      */
     @Nullable
     public float[] getCornerRadii() {
-        return mGradientState.mRadiusArray.clone();
+        float[] radii = mGradientState.mRadiusArray;
+        if (radii == null) {
+            return null;
+        }
+        return radii.clone();
     }
 
     /**
diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java
index d5711c8..f28b66d 100644
--- a/graphics/java/android/graphics/drawable/RippleDrawable.java
+++ b/graphics/java/android/graphics/drawable/RippleDrawable.java
@@ -48,7 +48,6 @@
 import android.graphics.Rect;
 import android.graphics.Shader;
 import android.os.Build;
-import android.os.SystemProperties;
 import android.util.AttributeSet;
 import android.view.animation.LinearInterpolator;
 
@@ -152,8 +151,7 @@
     private static final int MAX_RIPPLES = 10;
     private static final LinearInterpolator LINEAR_INTERPOLATOR = new LinearInterpolator();
     /** Temporary flag for teamfood. **/
-    private static final boolean FORCE_PATTERNED_STYLE =
-            SystemProperties.getBoolean("persist.material.patternedripple", false);
+    private static final boolean FORCE_PATTERNED_STYLE = true;
 
     private final Rect mTempRect = new Rect();
 
@@ -319,7 +317,6 @@
                 hovered = true;
             }
         }
-
         setRippleActive(enabled && pressed);
         setBackgroundActive(hovered, focused, pressed);
 
@@ -819,18 +816,22 @@
         if (isBounded()) {
             canvas.clipRect(bounds);
         }
-        float x, y, w, h;
+        final float x, y, cx, cy, w, h;
         if (changedHotspotBounds) {
             x = mHotspotBounds.exactCenterX();
             y = mHotspotBounds.exactCenterY();
-            w = mHotspotBounds.width();
+            cx = x;
+            cy = y;
             h = mHotspotBounds.height();
+            w = mHotspotBounds.width();
             useCanvasProps = false;
         } else {
             x = mPendingX;
             y = mPendingY;
-            w = bounds.width();
+            cx = bounds.centerX();
+            cy = bounds.centerY();
             h = bounds.height();
+            w = bounds.width();
         }
         boolean shouldAnimate = mRippleActive;
         boolean shouldExit = mExitingAnimation;
@@ -838,10 +839,10 @@
         mExitingAnimation = false;
         getRipplePaint();
         drawContent(canvas);
-        drawPatternedBackground(canvas);
+        drawPatternedBackground(canvas, cx, cy);
         if (shouldAnimate && mRunningAnimations.size() <= MAX_RIPPLES) {
             RippleAnimationSession.AnimationProperties<Float, Paint> properties =
-                    createAnimationProperties(x, y, w, h);
+                    createAnimationProperties(x, y, cx, cy, w, h);
             mRunningAnimations.add(new RippleAnimationSession(properties, !useCanvasProps)
                     .setOnAnimationUpdated(() -> invalidateSelf(false))
                     .setOnSessionEnd(session -> {
@@ -863,19 +864,39 @@
                         CanvasProperty<Paint>>
                         p = s.getCanvasProperties();
                 RecordingCanvas can = (RecordingCanvas) canvas;
-                can.drawRipple(p.getX(), p.getY(), p.getMaxRadius(), p.getPaint(),
+                CanvasProperty<Float> xProp, yProp;
+                if (changedHotspotBounds) {
+                    xProp = CanvasProperty.createFloat(x);
+                    yProp = CanvasProperty.createFloat(y);
+                    p.getShader().setTouch(x, y);
+                    p.getShader().setOrigin(x, y);
+                } else {
+                    xProp = p.getX();
+                    yProp = p.getY();
+                }
+                can.drawRipple(xProp, yProp, p.getMaxRadius(), p.getPaint(),
                         p.getProgress(), p.getShader());
             } else {
                 RippleAnimationSession.AnimationProperties<Float, Paint> p =
                         s.getProperties();
+                float xProp, yProp;
+                if (changedHotspotBounds) {
+                    xProp = x;
+                    yProp = y;
+                    p.getShader().setTouch(x, y);
+                    p.getShader().setOrigin(x, y);
+                } else {
+                    xProp = p.getX();
+                    yProp = p.getY();
+                }
                 float radius = p.getMaxRadius();
-                canvas.drawCircle(p.getX(), p.getY(), radius, p.getPaint());
+                canvas.drawCircle(xProp, yProp, radius, p.getPaint());
             }
         }
         canvas.restoreToCount(saveCount);
     }
 
-    private void drawPatternedBackground(Canvas c) {
+    private void drawPatternedBackground(Canvas c, float cx, float cy) {
         if (mRunBackgroundAnimation) {
             startBackgroundAnimation();
         }
@@ -888,8 +909,7 @@
             ColorFilter origFilter = p.getColorFilter();
             p.setColorFilter(mMaskColorFilter);
             p.setAlpha(alpha);
-            Rect b = mHotspotBounds;
-            c.drawCircle(b.centerX(), b.centerY(), mState.mMaxRadius, p);
+            c.drawCircle(cx, cy, mState.mMaxRadius, p);
             p.setAlpha(origAlpha);
             p.setColorFilter(origFilter);
         }
@@ -903,7 +923,7 @@
 
     @NonNull
     private RippleAnimationSession.AnimationProperties<Float, Paint> createAnimationProperties(
-            float x, float y, float w, float h) {
+            float x, float y, float cx, float cy, float w, float h) {
         Paint p = new Paint(mRipplePaint);
         float radius = mState.mMaxRadius;
         RippleAnimationSession.AnimationProperties<Float, Paint> properties;
@@ -912,14 +932,14 @@
                 ? mState.mColor.getColorForState(getState(), Color.BLACK)
                 : mMaskColorFilter.getColor();
         shader.setColor(color);
-        shader.setOrigin(w / 2, y / 2);
+        shader.setOrigin(cx, cy);
         shader.setTouch(x, y);
         shader.setResolution(w, h, mState.mDensity);
         shader.setNoisePhase(0);
         shader.setRadius(radius);
         shader.setProgress(.0f);
         properties = new RippleAnimationSession.AnimationProperties<>(
-                w / 2, h / 2, radius, p, 0f, shader);
+                cx, cy, radius, p, 0f, shader);
         if (mMaskShader == null) {
             shader.setShader(null);
         } else {
diff --git a/graphics/java/android/graphics/drawable/RippleShader.java b/graphics/java/android/graphics/drawable/RippleShader.java
index 5dd250c..98b9584 100644
--- a/graphics/java/android/graphics/drawable/RippleShader.java
+++ b/graphics/java/android/graphics/drawable/RippleShader.java
@@ -60,17 +60,13 @@
             + "  float d = distance(uv, xy);\n"
             + "  return 1. - smoothstep(1. - blurHalf, 1. + blurHalf, d / radius);\n"
             + "}\n"
-            + "\n"
-            + "float getRingMask(vec2 frag, vec2 center, float r, float progress) {\n"
-            + "      float dist = distance(frag, center);\n"
-            + "      float expansion = r * .6;\n"
-            + "      r = r * min(1.,progress);\n"
-            + "      float minD = max(r - expansion, 0.);\n"
-            + "      float maxD = r + expansion;\n"
-            + "      if (dist > maxD || dist < minD) return .0;\n"
-            + "      return min(maxD - dist, dist - minD) / expansion;    \n"
+            + "float softRing(vec2 uv, vec2 xy, float radius, float progress, float blur) {\n"
+            + "  float thickness = 0.2 * radius;\n"
+            + "  float currentRadius = radius * progress;\n"
+            + "  float circle_outer = softCircle(uv, xy, currentRadius + thickness, blur);\n"
+            + "  float circle_inner = softCircle(uv, xy, currentRadius - thickness, blur);\n"
+            + "  return clamp(circle_outer - circle_inner, 0., 1.);\n"
             + "}\n"
-            + "\n"
             + "float subProgress(float start, float end, float progress) {\n"
             + "    float sub = clamp(progress, start, end);\n"
             + "    return (sub - start) / (end - start); \n"
@@ -80,8 +76,8 @@
             + "    float fadeOutNoise = subProgress(0.375, 1., in_progress);\n"
             + "    float fadeOutRipple = subProgress(0.375, 0.75, in_progress);\n"
             + "    vec2 center = mix(in_touch, in_origin, fadeIn);\n"
-            + "    float ring = getRingMask(p, center, in_maxRadius, fadeIn);\n"
-            + "    float alpha = min(fadeIn, 1. - fadeOutNoise);\n"
+            + "    float ring = softRing(p, center, in_maxRadius, fadeIn, 0.45);\n"
+            + "    float alpha = 1. - fadeOutNoise;\n"
             + "    vec2 uv = p * in_resolutionScale;\n"
             + "    vec2 densityUv = uv - mod(uv, in_noiseScale);\n"
             + "    float sparkle = sparkles(densityUv, in_noisePhase) * ring * alpha;\n"
@@ -137,8 +133,7 @@
     }
 
     public void setResolution(float w, float h, int density) {
-        float noiseScale = 0.8f;
-        float densityScale = density * DisplayMetrics.DENSITY_DEFAULT_SCALE * 0.5f * noiseScale;
+        float densityScale = density * DisplayMetrics.DENSITY_DEFAULT_SCALE * 0.5f;
         setUniform("in_resolutionScale", new float[] {1f / w, 1f / h});
         setUniform("in_noiseScale", new float[] {densityScale / w, densityScale / h});
     }
diff --git a/keystore/java/android/security/AndroidKeyStoreMaintenance.java b/keystore/java/android/security/AndroidKeyStoreMaintenance.java
index 35b1c16..72cea0c 100644
--- a/keystore/java/android/security/AndroidKeyStoreMaintenance.java
+++ b/keystore/java/android/security/AndroidKeyStoreMaintenance.java
@@ -139,4 +139,18 @@
             return SYSTEM_ERROR;
         }
     }
+
+    /**
+     * Informs Keystore 2.0 that an off body event was detected.
+     */
+    public static void onDeviceOffBody() {
+        if (!android.security.keystore2.AndroidKeyStoreProvider.isInstalled()) return;
+        try {
+            getService().onDeviceOffBody();
+        } catch (Exception e) {
+            // TODO This fails open. This is not a regression with respect to keystore1 but it
+            //      should get fixed.
+            Log.e(TAG, "Error while reporting device off body event.", e);
+        }
+    }
 }
diff --git a/keystore/java/android/security/GenerateRkpKey.java b/keystore/java/android/security/GenerateRkpKey.java
new file mode 100644
index 0000000..a1a7aa8
--- /dev/null
+++ b/keystore/java/android/security/GenerateRkpKey.java
@@ -0,0 +1,99 @@
+/*
+ * 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 android.security;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.IBinder;
+import android.os.RemoteException;
+
+/**
+ * GenerateKey is a helper class to handle interactions between Keystore and the RemoteProvisioner
+ * app. There are two cases where Keystore should use this class.
+ *
+ * (1) : An app generates a new attested key pair, so Keystore calls notifyKeyGenerated to let the
+ *       RemoteProvisioner app check if the state of the attestation key pool is getting low enough
+ *       to warrant provisioning more attestation certificates early.
+ *
+ * (2) : An app attempts to generate a new key pair, but the keystore service discovers it is out of
+ *       attestation key pairs and cannot provide one for the given application. Keystore can then
+ *       make a blocking call on notifyEmpty to allow the RemoteProvisioner app to get another
+ *       attestation certificate chain provisioned.
+ *
+ * In most cases, the proper usage of (1) should preclude the need for (2).
+ *
+ * @hide
+ */
+public class GenerateRkpKey {
+
+    private IGenerateRkpKeyService mBinder;
+    private Context mContext;
+
+    private ServiceConnection mConnection = new ServiceConnection() {
+        @Override
+        public void onServiceConnected(ComponentName className, IBinder service) {
+            mBinder = IGenerateRkpKeyService.Stub.asInterface(service);
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName className) {
+            mBinder = null;
+        }
+    };
+
+    /**
+     * Constructor which takes a Context object.
+     */
+    public GenerateRkpKey(Context context) {
+        mContext = context;
+    }
+
+    /**
+     * Fulfills the use case of (2) described in the class documentation. Blocks until the
+     * RemoteProvisioner application can get new attestation keys signed by the server.
+     */
+    public void notifyEmpty(int securityLevel) throws RemoteException {
+        Intent intent = new Intent(IGenerateRkpKeyService.class.getName());
+        ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
+        intent.setComponent(comp);
+        if (comp == null || !mContext.bindService(intent, mConnection, Context.BIND_AUTO_CREATE)) {
+            throw new RemoteException("Failed to bind to GenerateKeyService");
+        }
+        if (mBinder != null) {
+            mBinder.generateKey(securityLevel);
+        }
+        mContext.unbindService(mConnection);
+    }
+
+    /**
+     * FUlfills the use case of (1) described in the class documentation. Non blocking call.
+     */
+    public void notifyKeyGenerated(int securityLevel) throws RemoteException {
+        Intent intent = new Intent(IGenerateRkpKeyService.class.getName());
+        ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
+        intent.setComponent(comp);
+        if (comp == null || !mContext.bindService(intent, mConnection, Context.BIND_AUTO_CREATE)) {
+            throw new RemoteException("Failed to bind to GenerateKeyService");
+        }
+        if (mBinder != null) {
+            mBinder.notifyKeyGenerated(securityLevel);
+        }
+        mContext.unbindService(mConnection);
+    }
+}
diff --git a/services/core/java/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneIdValidator.java b/keystore/java/android/security/GenerateRkpKeyException.java
similarity index 62%
copy from services/core/java/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneIdValidator.java
copy to keystore/java/android/security/GenerateRkpKeyException.java
index cab5ad2..a2d65e4 100644
--- a/services/core/java/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneIdValidator.java
+++ b/keystore/java/android/security/GenerateRkpKeyException.java
@@ -14,17 +14,18 @@
  * limitations under the License.
  */
 
-package com.android.server.timezonedetector.location;
+package android.security;
 
-import android.annotation.NonNull;
+/**
+ * Thrown on problems in attempting to attest to a key using a remotely provisioned key.
+ *
+ * @hide
+ */
+public class GenerateRkpKeyException extends Exception {
 
-import com.android.i18n.timezone.ZoneInfoDb;
-
-class ZoneInfoDbTimeZoneIdValidator implements
-        LocationTimeZoneProvider.TimeZoneIdValidator {
-
-    @Override
-    public boolean isValid(@NonNull String timeZoneId) {
-        return ZoneInfoDb.getInstance().hasTimeZone(timeZoneId);
+    /**
+     * Constructs a new {@code GenerateRkpKeyException}.
+     */
+    public GenerateRkpKeyException() {
     }
 }
diff --git a/keystore/java/android/security/IGenerateRkpKeyService.aidl b/keystore/java/android/security/IGenerateRkpKeyService.aidl
new file mode 100644
index 0000000..5f1d669
--- /dev/null
+++ b/keystore/java/android/security/IGenerateRkpKeyService.aidl
@@ -0,0 +1,36 @@
+/**
+ * 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 android.security;
+
+/**
+ * Interface to allow the framework to notify the RemoteProvisioner app when keys are empty. This
+ * will be used if Keystore replies with an error code NO_KEYS_AVAILABLE in response to an
+ * attestation request. The framework can then synchronously call generateKey() to get more
+ * attestation keys generated and signed. Upon return, the caller can be certain an attestation key
+ * is available.
+ *
+ * @hide
+ */
+interface IGenerateRkpKeyService {
+    /**
+     * Ping the provisioner service to let it know an app generated a key. This may or may not have
+     * consumed a remotely provisioned attestation key, so the RemoteProvisioner app should check.
+     */
+    oneway void notifyKeyGenerated(in int securityLevel);
+    /** Ping the provisioner service to indicate there are no remaining attestation keys left. */
+    void generateKey(in int securityLevel);
+}
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index a08f390..b05149e 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -1204,6 +1204,7 @@
      * Notify keystore that the device went off-body.
      */
     public void onDeviceOffBody() {
+        AndroidKeyStoreMaintenance.onDeviceOffBody();
         try {
             mBinder.onDeviceOffBody();
         } catch (RemoteException e) {
diff --git a/keystore/java/android/security/KeyStore2.java b/keystore/java/android/security/KeyStore2.java
index 6ac3821..df579bb 100644
--- a/keystore/java/android/security/KeyStore2.java
+++ b/keystore/java/android/security/KeyStore2.java
@@ -18,8 +18,7 @@
 
 import android.annotation.NonNull;
 import android.compat.annotation.ChangeId;
-import android.compat.annotation.EnabledAfter;
-import android.os.Build;
+import android.compat.annotation.Disabled;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.ServiceSpecificException;
@@ -86,7 +85,7 @@
      * successfully conclude an operation.
      */
     @ChangeId
-    @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.R)
+    @Disabled // See b/180133780
     static final long KEYSTORE_OPERATION_CREATION_MAY_FAIL = 169897160L;
 
     // Never use mBinder directly, use KeyStore2.getService() instead or better yet
@@ -126,6 +125,8 @@
         }
     }
 
+    private static final String KEYSTORE2_SERVICE_NAME =
+            "android.system.keystore2.IKeystoreService/default";
 
     private KeyStore2() {
         mBinder = null;
@@ -138,7 +139,7 @@
     private synchronized IKeystoreService getService(boolean retryLookup) {
         if (mBinder == null || retryLookup) {
             mBinder = IKeystoreService.Stub.asInterface(ServiceManager
-                    .getService("android.system.keystore2"));
+                    .getService(KEYSTORE2_SERVICE_NAME));
         }
         return mBinder;
     }
diff --git a/keystore/java/android/security/keystore/AttestationUtils.java b/keystore/java/android/security/keystore/AttestationUtils.java
index cd77d9c..ec3b102 100644
--- a/keystore/java/android/security/keystore/AttestationUtils.java
+++ b/keystore/java/android/security/keystore/AttestationUtils.java
@@ -254,6 +254,8 @@
             keyStore.deleteEntry(keystoreAlias);
 
             return certificateChain;
+        } catch (SecurityException e) {
+            throw e;
         } catch (Exception e) {
             throw new DeviceIdAttestationException("Unable to perform attestation", e);
         }
diff --git a/keystore/java/android/security/keystore/KeyGenParameterSpec.java b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
index 5cb2c3b..9ca551b 100644
--- a/keystore/java/android/security/keystore/KeyGenParameterSpec.java
+++ b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
@@ -288,7 +288,7 @@
     private static final Date DEFAULT_CERT_NOT_AFTER = new Date(2461449600000L); // Jan 1 2048
 
     private final String mKeystoreAlias;
-    private final int mNamespace;
+    private final @KeyProperties.Namespace int mNamespace;
     private final int mKeySize;
     private final AlgorithmParameterSpec mSpec;
     private final X500Principal mCertificateSubject;
@@ -331,7 +331,7 @@
      */
     public KeyGenParameterSpec(
             String keyStoreAlias,
-            int namespace,
+            @KeyProperties.Namespace int namespace,
             int keySize,
             AlgorithmParameterSpec spec,
             X500Principal certificateSubject,
@@ -472,7 +472,7 @@
      * @hide
      */
     @SystemApi
-    public int getNamespace() {
+    public @KeyProperties.Namespace int getNamespace() {
         return mNamespace;
     }
 
@@ -896,7 +896,7 @@
         private final String mKeystoreAlias;
         private @KeyProperties.PurposeEnum int mPurposes;
 
-        private int mNamespace = KeyProperties.NAMESPACE_APPLICATION;
+        private @KeyProperties.Namespace int mNamespace = KeyProperties.NAMESPACE_APPLICATION;
         private int mKeySize = -1;
         private AlgorithmParameterSpec mSpec;
         private X500Principal mCertificateSubject;
@@ -1051,7 +1051,7 @@
          */
         @SystemApi
         @NonNull
-        public Builder setNamespace(int namespace) {
+        public Builder setNamespace(@KeyProperties.Namespace int namespace) {
             mNamespace = namespace;
             return this;
         }
diff --git a/keystore/java/android/security/keystore/KeyProperties.java b/keystore/java/android/security/keystore/KeyProperties.java
index 7b0fa91..682d12a 100644
--- a/keystore/java/android/security/keystore/KeyProperties.java
+++ b/keystore/java/android/security/keystore/KeyProperties.java
@@ -892,6 +892,22 @@
     }
 
     /**
+     * Namespaces provide system developers and vendors with a way to use keystore without
+     * requiring an applications uid. Namespaces can be configured using SEPolicy.
+     * See <a href="https://source.android.com/security/keystore#access-control">
+     *     Keystore 2.0 access-control</a>
+     * {@See KeyGenParameterSpec.Builder#setNamespace}
+     * {@See android.security.keystore2.AndroidKeyStoreLoadStoreParameter}
+     * @hide
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = { "NAMESPACE_" }, value = {
+            NAMESPACE_APPLICATION,
+            NAMESPACE_WIFI,
+    })
+    public @interface Namespace {}
+
+    /**
      * This value indicates the implicit keystore namespace of the calling application.
      * It is used by default. Only select system components can choose a different namespace
      * which it must be configured in SEPolicy.
@@ -912,14 +928,12 @@
      * For legacy support, translate namespaces into known UIDs.
      * @hide
      */
-    public static int namespaceToLegacyUid(int namespace) {
+    public static int namespaceToLegacyUid(@Namespace int namespace) {
         switch (namespace) {
             case NAMESPACE_APPLICATION:
                 return KeyStore.UID_SELF;
             case NAMESPACE_WIFI:
                 return Process.WIFI_UID;
-            // TODO Translate WIFI and VPN UIDs once the namespaces are defined.
-            //  b/171305388 and b/171305607
             default:
                 throw new IllegalArgumentException("No UID corresponding to namespace "
                         + namespace);
@@ -930,14 +944,12 @@
      * For legacy support, translate namespaces into known UIDs.
      * @hide
      */
-    public static int legacyUidToNamespace(int uid) {
+    public static @Namespace int legacyUidToNamespace(int uid) {
         switch (uid) {
             case KeyStore.UID_SELF:
                 return NAMESPACE_APPLICATION;
             case Process.WIFI_UID:
                 return NAMESPACE_WIFI;
-            // TODO Translate WIFI and VPN UIDs once the namespaces are defined.
-            //  b/171305388 and b/171305607
             default:
                 throw new IllegalArgumentException("No namespace corresponding to uid "
                         + uid);
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java
index e401add..2d8901a 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java
@@ -24,6 +24,9 @@
 import android.hardware.security.keymint.SecurityLevel;
 import android.hardware.security.keymint.Tag;
 import android.os.Build;
+import android.os.RemoteException;
+import android.security.GenerateRkpKey;
+import android.security.GenerateRkpKeyException;
 import android.security.KeyPairGeneratorSpec;
 import android.security.KeyStore;
 import android.security.KeyStore2;
@@ -520,6 +523,18 @@
 
     @Override
     public KeyPair generateKeyPair() {
+        try {
+            return generateKeyPairHelper();
+        } catch (GenerateRkpKeyException e) {
+            try {
+                return generateKeyPairHelper();
+            } catch (GenerateRkpKeyException f) {
+                throw new ProviderException("Failed to provision new attestation keys.");
+            }
+        }
+    }
+
+    private KeyPair generateKeyPairHelper() throws GenerateRkpKeyException {
         if (mKeyStore == null || mSpec == null) {
             throw new IllegalStateException("Not initialized");
         }
@@ -557,13 +572,30 @@
             AndroidKeyStorePublicKey publicKey =
                     AndroidKeyStoreProvider.makeAndroidKeyStorePublicKeyFromKeyEntryResponse(
                             descriptor, metadata, iSecurityLevel, mKeymasterAlgorithm);
-
+            GenerateRkpKey keyGen = new GenerateRkpKey(KeyStore.getApplicationContext());
+            try {
+                if (mSpec.getAttestationChallenge() != null) {
+                    keyGen.notifyKeyGenerated(securityLevel);
+                }
+            } catch (RemoteException e) {
+                // This is not really an error state, and necessarily does not apply to non RKP
+                // systems or hybrid systems where RKP is not currently turned on.
+                Log.d(TAG, "Couldn't connect to the RemoteProvisioner backend.");
+            }
             success = true;
             return new KeyPair(publicKey, publicKey.getPrivateKey());
         } catch (android.security.KeyStoreException e) {
             switch(e.getErrorCode()) {
                 case KeymasterDefs.KM_ERROR_HARDWARE_TYPE_UNAVAILABLE:
                     throw new StrongBoxUnavailableException("Failed to generated key pair.", e);
+                case ResponseCode.OUT_OF_KEYS:
+                    GenerateRkpKey keyGen = new GenerateRkpKey(KeyStore.getApplicationContext());
+                    try {
+                        keyGen.notifyEmpty(securityLevel);
+                    } catch (RemoteException f) {
+                        throw new ProviderException("Failed to talk to RemoteProvisioner", f);
+                    }
+                    throw new GenerateRkpKeyException();
                 default:
                     ProviderException p = new ProviderException("Failed to generate key pair.", e);
                     if ((mSpec.getPurposes() & KeyProperties.PURPOSE_WRAP_KEY) != 0) {
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreLoadStoreParameter.java b/keystore/java/android/security/keystore2/AndroidKeyStoreLoadStoreParameter.java
index 0c6744f..25b1c86 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreLoadStoreParameter.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreLoadStoreParameter.java
@@ -16,6 +16,8 @@
 
 package android.security.keystore2;
 
+import android.security.keystore.KeyProperties;
+
 import java.security.KeyStore;
 import java.security.KeyStore.ProtectionParameter;
 
@@ -24,9 +26,9 @@
  */
 public class AndroidKeyStoreLoadStoreParameter implements KeyStore.LoadStoreParameter {
 
-    private final int mNamespace;
+    private final @KeyProperties.Namespace int mNamespace;
 
-    public AndroidKeyStoreLoadStoreParameter(int namespace) {
+    public AndroidKeyStoreLoadStoreParameter(@KeyProperties.Namespace int namespace) {
         mNamespace = namespace;
     }
 
@@ -35,7 +37,7 @@
         return null;
     }
 
-    int getNamespace() {
+    @KeyProperties.Namespace int getNamespace() {
         return mNamespace;
     }
 }
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java
index 39607ae..32f98a2 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java
@@ -100,7 +100,7 @@
     public static final String NAME = "AndroidKeyStore";
 
     private KeyStore2 mKeyStore;
-    private int mNamespace = KeyProperties.NAMESPACE_APPLICATION;
+    private @KeyProperties.Namespace int mNamespace = KeyProperties.NAMESPACE_APPLICATION;
 
     @Override
     public Key engineGetKey(String alias, char[] password) throws NoSuchAlgorithmException,
@@ -1125,7 +1125,7 @@
     @Override
     public void engineLoad(LoadStoreParameter param) throws IOException,
             NoSuchAlgorithmException, CertificateException {
-        int namespace = KeyProperties.NAMESPACE_APPLICATION;
+        @KeyProperties.Namespace int namespace = KeyProperties.NAMESPACE_APPLICATION;
         if (param != null) {
             if (param instanceof AndroidKeyStoreLoadStoreParameter) {
                 namespace = ((AndroidKeyStoreLoadStoreParameter) param).getNamespace();
diff --git a/libs/WindowManager/Jetpack/Android.bp b/libs/WindowManager/Jetpack/Android.bp
index d8f00bb..dc4b563 100644
--- a/libs/WindowManager/Jetpack/Android.bp
+++ b/libs/WindowManager/Jetpack/Android.bp
@@ -30,13 +30,20 @@
 
 java_library {
     name: "androidx.window.sidecar",
-    srcs: ["src/androidx/window/sidecar/**/*.java", "src/androidx/window/util/**/*.java"],
+    srcs: [
+        "src/androidx/window/sidecar/**/*.java",
+        "src/androidx/window/util/**/*.java",
+        "src/androidx/window/common/**/*.java",
+    ],
     static_libs: ["window-sidecar"],
     installable: true,
     sdk_version: "core_platform",
     system_ext_specific: true,
-    libs: ["framework", "androidx.annotation_annotation",],
-    required: ["androidx.window.sidecar.xml",],
+    libs: [
+        "framework",
+        "androidx.annotation_annotation",
+    ],
+    required: ["androidx.window.sidecar.xml"],
 }
 
 prebuilt_etc {
@@ -58,13 +65,20 @@
 
 java_library {
     name: "androidx.window.extensions",
-    srcs: ["src/androidx/window/extensions/**/*.java", "src/androidx/window/util/**/*.java"],
+    srcs: [
+        "src/androidx/window/extensions/**/*.java",
+        "src/androidx/window/util/**/*.java",
+        "src/androidx/window/common/**/*.java",
+    ],
     static_libs: ["window-extensions"],
     installable: true,
     sdk_version: "core_platform",
     system_ext_specific: true,
-    libs: ["framework", "androidx.annotation_annotation",],
-    required: ["androidx.window.extensions.xml",],
+    libs: [
+        "framework",
+        "androidx.annotation_annotation",
+    ],
+    required: ["androidx.window.extensions.xml"],
 }
 
 prebuilt_etc {
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/CommonDisplayFeature.java b/libs/WindowManager/Jetpack/src/androidx/window/common/CommonDisplayFeature.java
new file mode 100644
index 0000000..e6ad011
--- /dev/null
+++ b/libs/WindowManager/Jetpack/src/androidx/window/common/CommonDisplayFeature.java
@@ -0,0 +1,128 @@
+/*
+ * 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+)]");
+
+    private static final String FEATURE_TYPE_FOLD = "fold";
+    private static final String FEATURE_TYPE_HINGE = "hinge";
+
+    // 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);
+            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);
+            }
+
+            return new CommonDisplayFeature(type, null, 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) {
+        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);
+    }
+}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerPostureProducer.java b/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerPostureProducer.java
new file mode 100644
index 0000000..fa9a5a8
--- /dev/null
+++ b/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerPostureProducer.java
@@ -0,0 +1,93 @@
+/*
+ * 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 android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE;
+
+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.util.Log;
+import android.util.SparseIntArray;
+
+import androidx.window.util.BaseDataProducer;
+
+import com.android.internal.R;
+
+import java.util.Optional;
+
+/**
+ * An implementation of {@link androidx.window.util.DataProducer} that returns the device's posture
+ * 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";
+    private static final boolean DEBUG = false;
+
+    private final SparseIntArray mDeviceStateToPostureMap = new SparseIntArray();
+
+    private int mCurrentDeviceState = INVALID_DEVICE_STATE;
+
+    private final DeviceStateCallback mDeviceStateCallback = (state) -> {
+        mCurrentDeviceState = state;
+        notifyDataChanged();
+    };
+
+    public DeviceStateManagerPostureProducer(@NonNull Context context) {
+        String[] deviceStatePosturePairs = context.getResources()
+                .getStringArray(R.array.config_device_state_postures);
+        for (String deviceStatePosturePair : deviceStatePosturePairs) {
+            String[] deviceStatePostureMapping = deviceStatePosturePair.split(":");
+            if (deviceStatePostureMapping.length != 2) {
+                if (DEBUG) {
+                    Log.e(TAG, "Malformed device state posture pair: " + deviceStatePosturePair);
+                }
+                continue;
+            }
+
+            int deviceState;
+            int posture;
+            try {
+                deviceState = Integer.parseInt(deviceStatePostureMapping[0]);
+                posture = Integer.parseInt(deviceStatePostureMapping[1]);
+            } catch (NumberFormatException e) {
+                if (DEBUG) {
+                    Log.e(TAG, "Failed to parse device state or posture: " + deviceStatePosturePair,
+                            e);
+                }
+                continue;
+            }
+
+            mDeviceStateToPostureMap.put(deviceState, posture);
+        }
+
+        if (mDeviceStateToPostureMap.size() > 0) {
+            context.getSystemService(DeviceStateManager.class)
+                    .registerCallback(context.getMainExecutor(), mDeviceStateCallback);
+        }
+    }
+
+    @Override
+    @Nullable
+    public Optional<Integer> getData() {
+        final int posture = mDeviceStateToPostureMap.get(mCurrentDeviceState, -1);
+        return posture != -1 ? Optional.of(posture) : Optional.empty();
+    }
+}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/DisplayFeature.java b/libs/WindowManager/Jetpack/src/androidx/window/common/DisplayFeature.java
new file mode 100644
index 0000000..b6c4c43
--- /dev/null
+++ b/libs/WindowManager/Jetpack/src/androidx/window/common/DisplayFeature.java
@@ -0,0 +1,36 @@
+/*
+ * 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.Nullable;
+import android.graphics.Rect;
+
+import androidx.annotation.NonNull;
+
+/** 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
+    Integer getState();
+
+    /** Returns the bounds of the feature. */
+    @NonNull
+    Rect getRect();
+}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/ResourceConfigDisplayFeatureProducer.java b/libs/WindowManager/Jetpack/src/androidx/window/common/ResourceConfigDisplayFeatureProducer.java
new file mode 100644
index 0000000..cd2cadc
--- /dev/null
+++ b/libs/WindowManager/Jetpack/src/androidx/window/common/ResourceConfigDisplayFeatureProducer.java
@@ -0,0 +1,74 @@
+/*
+ * 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
new file mode 100644
index 0000000..2026df3
--- /dev/null
+++ b/libs/WindowManager/Jetpack/src/androidx/window/common/SettingsDevicePostureProducer.java
@@ -0,0 +1,96 @@
+/*
+ * 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
new file mode 100644
index 0000000..0406626
--- /dev/null
+++ b/libs/WindowManager/Jetpack/src/androidx/window/common/SettingsDisplayFeatureProducer.java
@@ -0,0 +1,125 @@
+/*
+ * 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 android.text.TextUtils;
+import android.util.Log;
+
+import androidx.window.util.BaseDataProducer;
+
+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 {@link Settings}.
+ */
+public final class SettingsDisplayFeatureProducer
+        extends BaseDataProducer<List<DisplayFeature>> {
+    private static final boolean DEBUG = false;
+    private static final String TAG = "SettingsDisplayFeatureProducer";
+    private static final String DISPLAY_FEATURES = "display_features";
+
+    private final Uri mDisplayFeaturesUri =
+            Settings.Global.getUriFor(DISPLAY_FEATURES);
+
+    private final ContentResolver mResolver;
+    private final ContentObserver mObserver;
+    private boolean mRegisteredObservers;
+
+    public SettingsDisplayFeatureProducer(@NonNull Context context) {
+        mResolver = context.getContentResolver();
+        mObserver = new SettingsObserver();
+    }
+
+    @Override
+    @Nullable
+    public Optional<List<DisplayFeature>> 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);
+        }
+        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);
+    }
+
+    /**
+     * 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(mDisplayFeaturesUri, 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 (mDisplayFeaturesUri.equals(uri)) {
+                notifyDataChanged();
+            }
+        }
+    }
+}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/SampleExtensionImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/SampleExtensionImpl.java
index 5c91cf41..ce9be6a 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/SampleExtensionImpl.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/SampleExtensionImpl.java
@@ -27,11 +27,17 @@
 import android.util.Log;
 
 import androidx.annotation.NonNull;
-import androidx.window.util.BaseDisplayFeature;
-import androidx.window.util.SettingsConfigProvider;
+import androidx.window.common.DeviceStateManagerPostureProducer;
+import androidx.window.common.DisplayFeature;
+import androidx.window.common.ResourceConfigDisplayFeatureProducer;
+import androidx.window.common.SettingsDevicePostureProducer;
+import androidx.window.common.SettingsDisplayFeatureProducer;
+import androidx.window.util.DataProducer;
+import androidx.window.util.PriorityDataProducer;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Optional;
 
 /**
  * Reference implementation of androidx.window.extensions OEM interface for use with
@@ -41,23 +47,46 @@
  * production builds since the interface can still change before reaching stable version.
  * Please refer to {@link androidx.window.sidecar.SampleSidecarImpl} instead.
  */
-class SampleExtensionImpl extends StubExtension implements
-        SettingsConfigProvider.StateChangeCallback {
+class SampleExtensionImpl extends StubExtension {
     private static final String TAG = "SampleExtension";
 
-    private final SettingsConfigProvider mConfigProvider;
+    private final SettingsDevicePostureProducer mSettingsDevicePostureProducer;
+    private final DataProducer<Integer> mDevicePostureProducer;
+
+    private final SettingsDisplayFeatureProducer mSettingsDisplayFeatureProducer;
+    private final DataProducer<List<DisplayFeature>> mDisplayFeatureProducer;
 
     SampleExtensionImpl(Context context) {
-        mConfigProvider = new SettingsConfigProvider(context, this);
+        mSettingsDevicePostureProducer = new SettingsDevicePostureProducer(context);
+        mDevicePostureProducer = new PriorityDataProducer<>(List.of(
+                mSettingsDevicePostureProducer,
+                new DeviceStateManagerPostureProducer(context)
+        ));
+
+        mSettingsDisplayFeatureProducer = new SettingsDisplayFeatureProducer(context);
+        mDisplayFeatureProducer = new PriorityDataProducer<>(List.of(
+                mSettingsDisplayFeatureProducer,
+                new ResourceConfigDisplayFeatureProducer(context)
+        ));
+
+        mDevicePostureProducer.addDataChangedCallback(this::onDevicePostureChanged);
+        mDisplayFeatureProducer.addDataChangedCallback(this::onDisplayFeaturesChanged);
     }
 
-    @Override
-    public void onDevicePostureChanged() {
-        updateDeviceState(new ExtensionDeviceState(mConfigProvider.getDeviceState()));
+    private void onDevicePostureChanged() {
+        updateDeviceState(new ExtensionDeviceState(getDevicePosture()));
+
+        // Trigger a change in display features as the posture will be used in place of the feature
+        // state if the state is left unset by the producer.
+        onDisplayFeaturesChanged();
     }
 
-    @Override
-    public void onDisplayFeaturesChanged() {
+    private int getDevicePosture() {
+        Optional<Integer> posture = mDevicePostureProducer.getData();
+        return posture.orElse(ExtensionDeviceState.POSTURE_UNKNOWN);
+    }
+
+    private void onDisplayFeaturesChanged() {
         for (Activity activity : getActivitiesListeningForLayoutChanges()) {
             ExtensionWindowLayoutInfo newLayout = getWindowLayoutInfo(activity);
             updateWindowLayout(activity, newLayout);
@@ -84,13 +113,20 @@
             return features;
         }
 
-        List<BaseDisplayFeature> storedFeatures = mConfigProvider.getDisplayFeatures();
-        for (BaseDisplayFeature baseFeature : storedFeatures) {
-            Rect featureRect = baseFeature.getRect();
-            rotateRectToDisplayRotation(displayId, featureRect);
-            transformToWindowSpaceRect(activity, featureRect);
-            features.add(new ExtensionFoldingFeature(featureRect, baseFeature.getType(),
-                    baseFeature.getState()));
+        Optional<List<DisplayFeature>> storedFeatures = mDisplayFeatureProducer.getData();
+        if (storedFeatures.isPresent()) {
+            int posture = getDevicePosture();
+
+            for (DisplayFeature baseFeature : storedFeatures.get()) {
+                Rect featureRect = baseFeature.getRect();
+                rotateRectToDisplayRotation(displayId, featureRect);
+                transformToWindowSpaceRect(activity, featureRect);
+
+                Integer featureState = baseFeature.getState();
+
+                features.add(new ExtensionFoldingFeature(featureRect, baseFeature.getType(),
+                        featureState == null ? posture : featureState));
+            }
         }
         return features;
     }
@@ -98,9 +134,11 @@
     @Override
     protected void onListenersChanged() {
         if (hasListeners()) {
-            mConfigProvider.registerObserversIfNeeded();
+            mSettingsDevicePostureProducer.registerObserversIfNeeded();
+            mSettingsDisplayFeatureProducer.registerObserversIfNeeded();
         } else {
-            mConfigProvider.unregisterObserversIfNeeded();
+            mSettingsDevicePostureProducer.unregisterObserversIfNeeded();
+            mSettingsDisplayFeatureProducer.unregisterObserversIfNeeded();
         }
 
         onDevicePostureChanged();
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java
index d3700f8..ece198c 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java
@@ -29,33 +29,53 @@
 import android.util.Log;
 
 import androidx.annotation.NonNull;
-import androidx.window.util.BaseDisplayFeature;
-import androidx.window.util.SettingsConfigProvider;
+import androidx.window.common.DeviceStateManagerPostureProducer;
+import androidx.window.common.DisplayFeature;
+import androidx.window.common.ResourceConfigDisplayFeatureProducer;
+import androidx.window.common.SettingsDevicePostureProducer;
+import androidx.window.common.SettingsDisplayFeatureProducer;
+import androidx.window.util.DataProducer;
+import androidx.window.util.PriorityDataProducer;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Optional;
 
 /**
  * Reference implementation of androidx.window.sidecar OEM interface for use with
  * WindowManager Jetpack.
  */
-class SampleSidecarImpl extends StubSidecar implements
-        SettingsConfigProvider.StateChangeCallback {
+class SampleSidecarImpl extends StubSidecar {
     private static final String TAG = "SampleSidecar";
 
-    private final SettingsConfigProvider mConfigProvider;
+    private final SettingsDevicePostureProducer mSettingsDevicePostureProducer;
+    private final DataProducer<Integer> mDevicePostureProducer;
+
+    private final SettingsDisplayFeatureProducer mSettingsDisplayFeatureProducer;
+    private final DataProducer<List<DisplayFeature>> mDisplayFeatureProducer;
 
     SampleSidecarImpl(Context context) {
-        mConfigProvider = new SettingsConfigProvider(context, this);
+        mSettingsDevicePostureProducer = new SettingsDevicePostureProducer(context);
+        mDevicePostureProducer = new PriorityDataProducer<>(List.of(
+                mSettingsDevicePostureProducer,
+                new DeviceStateManagerPostureProducer(context)
+        ));
+
+        mSettingsDisplayFeatureProducer = new SettingsDisplayFeatureProducer(context);
+        mDisplayFeatureProducer = new PriorityDataProducer<>(List.of(
+                mSettingsDisplayFeatureProducer,
+                new ResourceConfigDisplayFeatureProducer(context)
+        ));
+
+        mDevicePostureProducer.addDataChangedCallback(this::onDevicePostureChanged);
+        mDisplayFeatureProducer.addDataChangedCallback(this::onDisplayFeaturesChanged);
     }
 
-    @Override
-    public void onDevicePostureChanged() {
+    private void onDevicePostureChanged() {
         updateDeviceState(getDeviceState());
     }
 
-    @Override
-    public void onDisplayFeaturesChanged() {
+    private void onDisplayFeaturesChanged() {
         for (IBinder windowToken : getWindowsListeningForLayoutChanges()) {
             SidecarWindowLayoutInfo newLayout = getWindowLayoutInfo(windowToken);
             updateWindowLayout(windowToken, newLayout);
@@ -65,8 +85,10 @@
     @NonNull
     @Override
     public SidecarDeviceState getDeviceState() {
+        Optional<Integer> posture = mDevicePostureProducer.getData();
+
         SidecarDeviceState deviceState = new SidecarDeviceState();
-        deviceState.posture = mConfigProvider.getDeviceState();
+        deviceState.posture = posture.orElse(SidecarDeviceState.POSTURE_UNKNOWN);
         return deviceState;
     }
 
@@ -96,15 +118,17 @@
             return features;
         }
 
-        List<BaseDisplayFeature> storedFeatures = mConfigProvider.getDisplayFeatures();
-        for (BaseDisplayFeature baseFeature : storedFeatures) {
-            SidecarDisplayFeature feature = new SidecarDisplayFeature();
-            Rect featureRect = baseFeature.getRect();
-            rotateRectToDisplayRotation(displayId, featureRect);
-            transformToWindowSpaceRect(activity, featureRect);
-            feature.setRect(featureRect);
-            feature.setType(baseFeature.getType());
-            features.add(feature);
+        Optional<List<DisplayFeature>> storedFeatures = mDisplayFeatureProducer.getData();
+        if (storedFeatures.isPresent()) {
+            for (DisplayFeature baseFeature : storedFeatures.get()) {
+                SidecarDisplayFeature feature = new SidecarDisplayFeature();
+                Rect featureRect = baseFeature.getRect();
+                rotateRectToDisplayRotation(displayId, featureRect);
+                transformToWindowSpaceRect(activity, featureRect);
+                feature.setRect(featureRect);
+                feature.setType(baseFeature.getType());
+                features.add(feature);
+            }
         }
         return features;
     }
@@ -112,9 +136,11 @@
     @Override
     protected void onListenersChanged() {
         if (hasListeners()) {
-            mConfigProvider.registerObserversIfNeeded();
+            mSettingsDevicePostureProducer.registerObserversIfNeeded();
+            mSettingsDisplayFeatureProducer.registerObserversIfNeeded();
         } else {
-            mConfigProvider.unregisterObserversIfNeeded();
+            mSettingsDevicePostureProducer.unregisterObserversIfNeeded();
+            mSettingsDisplayFeatureProducer.unregisterObserversIfNeeded();
         }
     }
 }
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/util/BaseDataProducer.java b/libs/WindowManager/Jetpack/src/androidx/window/util/BaseDataProducer.java
new file mode 100644
index 0000000..0a46703451
--- /dev/null
+++ b/libs/WindowManager/Jetpack/src/androidx/window/util/BaseDataProducer.java
@@ -0,0 +1,52 @@
+/*
+ * 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.util;
+
+import androidx.annotation.NonNull;
+
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+/**
+ * Base class that provides the implementation for the callback mechanism of the
+ * {@link DataProducer} API.
+ *
+ * @param <T> The type of data this producer returns through {@link #getData()}.
+ */
+public abstract class BaseDataProducer<T> implements DataProducer<T> {
+    private final Set<Runnable> mCallbacks = new LinkedHashSet<>();
+
+    @Override
+    public final void addDataChangedCallback(@NonNull Runnable callback) {
+        mCallbacks.add(callback);
+    }
+
+    @Override
+    public final void removeDataChangedCallback(@NonNull Runnable callback) {
+        mCallbacks.remove(callback);
+    }
+
+    /**
+     * Called to notify all registered callbacks that the data provided by {@link #getData()} has
+     * changed.
+     */
+    protected void notifyDataChanged() {
+        for (Runnable callback : mCallbacks) {
+            callback.run();
+        }
+    }
+}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/util/BaseDisplayFeature.java b/libs/WindowManager/Jetpack/src/androidx/window/util/BaseDisplayFeature.java
deleted file mode 100644
index b74a2a4..0000000
--- a/libs/WindowManager/Jetpack/src/androidx/window/util/BaseDisplayFeature.java
+++ /dev/null
@@ -1,52 +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.util;
-
-import android.graphics.Rect;
-
-import androidx.annotation.NonNull;
-
-/** Wrapper for both Extension and Sidecar versions of DisplayFeature. */
-public class BaseDisplayFeature {
-    private final int mType;
-    private final int mState;
-    @NonNull
-    public final Rect mRect;
-
-    public BaseDisplayFeature(int type, int state, @NonNull Rect rect) {
-        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;
-    }
-
-    public int getState() {
-        return mState;
-    }
-
-    @NonNull
-    public Rect getRect() {
-        return mRect;
-    }
-}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/util/DataProducer.java b/libs/WindowManager/Jetpack/src/androidx/window/util/DataProducer.java
new file mode 100644
index 0000000..d4d1a23
--- /dev/null
+++ b/libs/WindowManager/Jetpack/src/androidx/window/util/DataProducer.java
@@ -0,0 +1,43 @@
+/*
+ * 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.util;
+
+import android.annotation.NonNull;
+
+import java.util.Optional;
+
+/**
+ * Produces data through {@link #getData()} and provides a mechanism for receiving a callback when
+ * the data managed by the produces has changed.
+ *
+ * @param <T> The type of data this producer returns through {@link #getData()}.
+ */
+public interface DataProducer<T> {
+    /**
+     * Returns the data currently stored in the provider, or {@link Optional#empty()} if the
+     * provider has no data.
+     */
+    Optional<T> getData();
+
+    /**
+     * Adds a callback to be notified when the data returned from {@link #getData()} has changed.
+     */
+    void addDataChangedCallback(@NonNull Runnable callback);
+
+    /** Removes a callback previously added with {@link #addDataChangedCallback(Runnable)}.  */
+    void removeDataChangedCallback(@NonNull Runnable callback);
+}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/util/PriorityDataProducer.java b/libs/WindowManager/Jetpack/src/androidx/window/util/PriorityDataProducer.java
new file mode 100644
index 0000000..990ae20
--- /dev/null
+++ b/libs/WindowManager/Jetpack/src/androidx/window/util/PriorityDataProducer.java
@@ -0,0 +1,56 @@
+/*
+ * 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.util;
+
+import android.annotation.Nullable;
+
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * Implementation of {@link DataProducer} that delegates calls to {@link #getData()} to the list of
+ * provided child producers.
+ * <p>
+ * The value returned is based on the precedence of the supplied children where the producer with
+ * index 0 has a higher precedence than producers that come later in the list. When a producer with
+ * a higher precedence has a non-empty value returned from {@link #getData()}, its value will be
+ * returned from an instance of this class, ignoring all other producers with lower precedence.
+ *
+ * @param <T> The type of data this producer returns through {@link #getData()}.
+ */
+public final class PriorityDataProducer<T> extends BaseDataProducer<T> {
+    private final List<DataProducer<T>> mChildProducers;
+
+    public PriorityDataProducer(List<DataProducer<T>> childProducers) {
+        mChildProducers = childProducers;
+        for (DataProducer<T> childProducer : mChildProducers) {
+            childProducer.addDataChangedCallback(this::notifyDataChanged);
+        }
+    }
+
+    @Nullable
+    @Override
+    public Optional<T> getData() {
+        for (DataProducer<T> childProducer : mChildProducers) {
+            final Optional<T> data = childProducer.getData();
+            if (data.isPresent()) {
+                return data;
+            }
+        }
+        return Optional.empty();
+    }
+}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/util/SettingsConfigProvider.java b/libs/WindowManager/Jetpack/src/androidx/window/util/SettingsConfigProvider.java
deleted file mode 100644
index 6dd190c..0000000
--- a/libs/WindowManager/Jetpack/src/androidx/window/util/SettingsConfigProvider.java
+++ /dev/null
@@ -1,196 +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.util;
-
-import static androidx.window.util.ExtensionHelper.isZero;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.database.ContentObserver;
-import android.graphics.Rect;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.Looper;
-import android.provider.Settings;
-import android.text.TextUtils;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-
-import com.android.internal.R;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Device and display feature state provider that uses Settings as the source.
- */
-public final class SettingsConfigProvider extends ContentObserver {
-    private static final String TAG = "SettingsConfigProvider";
-    private static final String DEVICE_POSTURE = "device_posture";
-    private static final String DISPLAY_FEATURES = "display_features";
-
-    private static final Pattern FEATURE_PATTERN =
-            Pattern.compile("([a-z]+)-\\[(\\d+),(\\d+),(\\d+),(\\d+)]");
-
-    private static final String FEATURE_TYPE_FOLD = "fold";
-    private static final String FEATURE_TYPE_HINGE = "hinge";
-
-    private final Uri mDevicePostureUri =
-            Settings.Global.getUriFor(DEVICE_POSTURE);
-    private final Uri mDisplayFeaturesUri =
-            Settings.Global.getUriFor(DISPLAY_FEATURES);
-    private final Context mContext;
-    private final ContentResolver mResolver;
-    private final StateChangeCallback mCallback;
-    private boolean mRegisteredObservers;
-
-    public SettingsConfigProvider(@NonNull Context context, @NonNull StateChangeCallback callback) {
-        super(new Handler(Looper.getMainLooper()));
-        mContext = context;
-        mResolver = context.getContentResolver();
-        mCallback = callback;
-    }
-
-    /**
-     * Registers the content observers for Settings keys that store device state and display feature
-     * configurations.
-     */
-    public void registerObserversIfNeeded() {
-        if (mRegisteredObservers) {
-            return;
-        }
-        mRegisteredObservers = true;
-        mResolver.registerContentObserver(mDevicePostureUri, false /* notifyForDescendants */,
-                this /* ContentObserver */);
-        mResolver.registerContentObserver(mDisplayFeaturesUri, false /* notifyForDescendants */,
-                this /* ContentObserver */);
-    }
-
-    /**
-     * Unregisters the content observers that are tracking the state changes.
-     * @see #registerObserversIfNeeded()
-     */
-    public void unregisterObserversIfNeeded() {
-        if (!mRegisteredObservers) {
-            return;
-        }
-        mRegisteredObservers = false;
-        mResolver.unregisterContentObserver(this);
-    }
-
-    /**
-     * Gets the device posture int stored in Settings.
-     */
-    public int getDeviceState() {
-        return Settings.Global.getInt(mResolver, DEVICE_POSTURE,
-                0 /* POSTURE_UNKNOWN */);
-    }
-
-    /**
-     * Gets the list of all display feature configs stored in Settings. Uses a custom
-     * {@link BaseDisplayFeature} class to report the config to be translated for actual
-     * containers in Sidecar or Extensions.
-     */
-    public List<BaseDisplayFeature> getDisplayFeatures() {
-        List<BaseDisplayFeature> features = new ArrayList<>();
-        String displayFeaturesString = Settings.Global.getString(mResolver, DISPLAY_FEATURES);
-        if (TextUtils.isEmpty(displayFeaturesString)) {
-            displayFeaturesString = mContext.getResources().getString(
-                    R.string.config_display_features);
-        }
-        if (TextUtils.isEmpty(displayFeaturesString)) {
-            return features;
-        }
-        String[] featureStrings =  displayFeaturesString.split(";");
-
-        int deviceState = getDeviceState();
-
-        for (String featureString : featureStrings) {
-            Matcher featureMatcher = FEATURE_PATTERN.matcher(featureString);
-            if (!featureMatcher.matches()) {
-                Log.e(TAG, "Malformed feature description format: " + featureString);
-                continue;
-            }
-            try {
-                String featureType = featureMatcher.group(1);
-                int type;
-                switch (featureType) {
-                    case FEATURE_TYPE_FOLD:
-                        type = 1 /* TYPE_FOLD */;
-                        break;
-                    case FEATURE_TYPE_HINGE:
-                        type = 2 /* TYPE_HINGE */;
-                        break;
-                    default: {
-                        Log.e(TAG, "Malformed feature type: " + featureType);
-                        continue;
-                    }
-                }
-
-                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)) {
-                    BaseDisplayFeature feature = new BaseDisplayFeature(type, deviceState,
-                            featureRect);
-                    features.add(feature);
-                } else {
-                    Log.w(TAG, "Read empty feature");
-                }
-            } catch (NumberFormatException e) {
-                Log.e(TAG, "Malformed feature description: " + featureString);
-            }
-        }
-        return features;
-    }
-
-    @Override
-    public void onChange(boolean selfChange, Uri uri) {
-        if (uri == null) {
-            return;
-        }
-
-        if (mDevicePostureUri.equals(uri)) {
-            mCallback.onDevicePostureChanged();
-            mCallback.onDisplayFeaturesChanged();
-            return;
-        }
-        if (mDisplayFeaturesUri.equals(uri)) {
-            mCallback.onDisplayFeaturesChanged();
-        }
-    }
-
-    /**
-     * Callback that notifies about device or display feature state changes.
-     */
-    public interface StateChangeCallback {
-        /**
-         * Notifies about the device state update.
-         */
-        void onDevicePostureChanged();
-
-        /**
-         * Notifies about the display feature config update.
-         */
-        void onDisplayFeaturesChanged();
-    }
-}
diff --git a/libs/WindowManager/Shell/AndroidManifest.xml b/libs/WindowManager/Shell/AndroidManifest.xml
index d2b3cf6..6bd0e0a 100644
--- a/libs/WindowManager/Shell/AndroidManifest.xml
+++ b/libs/WindowManager/Shell/AndroidManifest.xml
@@ -17,6 +17,8 @@
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.android.wm.shell">
+    <!-- System permission required by WM Shell Task Organizer. -->
+    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
     <uses-permission android:name="android.permission.ROTATE_SURFACE_FLINGER" />
     <uses-permission android:name="android.permission.READ_FRAME_BUFFER" />
 </manifest>
diff --git a/libs/WindowManager/Shell/res/values-iw/strings.xml b/libs/WindowManager/Shell/res/values-iw/strings.xml
index b75ee45..cd63de8 100644
--- a/libs/WindowManager/Shell/res/values-iw/strings.xml
+++ b/libs/WindowManager/Shell/res/values-iw/strings.xml
@@ -22,9 +22,9 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"הגדרות"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"תפריט"</string>
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> במצב תמונה בתוך תמונה"</string>
-    <string name="pip_notification_message" msgid="8854051911700302620">"אם אינך רוצה שהתכונה הזו תשמש את <xliff:g id="NAME">%s</xliff:g>, יש להקיש כדי לפתוח את ההגדרות ולכבות את התכונה."</string>
+    <string name="pip_notification_message" msgid="8854051911700302620">"אם אינך רוצה שהתכונה הזו תשמש את <xliff:g id="NAME">%s</xliff:g>, יש להקיש כדי לפתוח את ההגדרות ולהשבית את התכונה."</string>
     <string name="pip_play" msgid="3496151081459417097">"הפעלה"</string>
-    <string name="pip_pause" msgid="690688849510295232">"השהה"</string>
+    <string name="pip_pause" msgid="690688849510295232">"השהיה"</string>
     <string name="pip_skip_to_next" msgid="8403429188794867653">"אפשר לדלג אל הבא"</string>
     <string name="pip_skip_to_prev" msgid="7172158111196394092">"אפשר לדלג אל הקודם"</string>
     <string name="accessibility_action_pip_resize" msgid="4623966104749543182">"שינוי גודל"</string>
diff --git a/libs/WindowManager/Shell/res/values-nl/strings.xml b/libs/WindowManager/Shell/res/values-nl/strings.xml
index 1527e89..fcd706f 100644
--- a/libs/WindowManager/Shell/res/values-nl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nl/strings.xml
@@ -58,14 +58,14 @@
     <string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Naar rechtsonder verplaatsen"</string>
     <string name="bubbles_app_settings" msgid="3617224938701566416">"Instellingen voor <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="bubble_dismiss_text" msgid="8816558050659478158">"Bubbel sluiten"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Gesprekken niet in bubbels weergeven"</string>
+    <string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Gesprekken niet in bubbels tonen"</string>
     <string name="bubbles_user_education_title" msgid="2112319053732691899">"Chatten met bubbels"</string>
-    <string name="bubbles_user_education_description" msgid="4215862563054175407">"Nieuwe gesprekken worden weergegeven als zwevende iconen of \'bubbels\'. Tik om een bubbel te openen. Sleep om de bubbel te verplaatsen."</string>
+    <string name="bubbles_user_education_description" msgid="4215862563054175407">"Nieuwe gesprekken worden als zwevende iconen of bubbels getoond. Tik om een bubbel te openen. Sleep om een bubbel te verplaatsen."</string>
     <string name="bubbles_user_education_manage_title" msgid="7042699946735628035">"Beheer bubbels wanneer je wilt"</string>
     <string name="bubbles_user_education_manage" msgid="3460756219946517198">"Tik op Beheren om bubbels van deze app uit te schakelen"</string>
     <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"OK"</string>
     <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Geen recente bubbels"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Recente bubbels en gesloten bubbels worden hier weergegeven"</string>
+    <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Recente bubbels en gesloten bubbels zie je hier"</string>
     <string name="notification_bubble_title" msgid="6082910224488253378">"Bubbel"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Beheren"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubbel gesloten."</string>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/RootTaskDisplayAreaOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/RootTaskDisplayAreaOrganizer.java
index 3708e15..34c66a4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/RootTaskDisplayAreaOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/RootTaskDisplayAreaOrganizer.java
@@ -16,6 +16,8 @@
 
 package com.android.wm.shell;
 
+import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_TASK_ORG;
+
 import android.annotation.UiContext;
 import android.app.ResourcesManager;
 import android.content.Context;
@@ -34,6 +36,8 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
+import com.android.internal.protolog.common.ProtoLog;
+
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
@@ -44,14 +48,14 @@
 
     private static final String TAG = RootTaskDisplayAreaOrganizer.class.getSimpleName();
 
-    // Display area info. mapped by displayIds.
+    /** {@link DisplayAreaInfo} list, which is mapped by display IDs. */
     private final SparseArray<DisplayAreaInfo> mDisplayAreasInfo = new SparseArray<>();
-    // Display area leashes. mapped by displayIds.
+    /** Display area leashes, which is mapped by display IDs. */
     private final SparseArray<SurfaceControl> mLeashes = new SparseArray<>();
 
     private final SparseArray<ArrayList<RootTaskDisplayAreaListener>> mListeners =
             new SparseArray<>();
-
+    /** {@link DisplayAreaContext} list, which is mapped by display IDs. */
     private final SparseArray<DisplayAreaContext> mDisplayAreaContexts = new SparseArray<>();
 
     private final Context mContext;
@@ -173,8 +177,9 @@
         final Display display = mContext.getSystemService(DisplayManager.class)
                 .getDisplay(displayId);
         if (display == null) {
-            throw new UnsupportedOperationException("The display #" + displayId + " is invalid."
-                    + "displayAreaInfo:" + displayAreaInfo);
+            ProtoLog.w(WM_SHELL_TASK_ORG, "The display#%d has been removed."
+                    + " Skip following steps", displayId);
+            return;
         }
         DisplayAreaContext daContext = mDisplayAreaContexts.get(displayId);
         if (daContext == null) {
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 bacff78..b64c796 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
@@ -27,9 +27,10 @@
 import android.animation.ValueAnimator;
 import android.content.Context;
 import android.content.res.Configuration;
-import android.content.res.Resources;
 import android.graphics.Rect;
 import android.view.SurfaceControl;
+import android.view.WindowInsets;
+import android.view.WindowManager;
 
 import androidx.annotation.Nullable;
 
@@ -75,7 +76,7 @@
         mDividerSize = mDividerWindowWidth - mDividerInsets * 2;
 
         mRootBounds.set(configuration.windowConfiguration.getBounds());
-        mDividerSnapAlgorithm = getSnapAlgorithm(context.getResources(), mRootBounds);
+        mDividerSnapAlgorithm = getSnapAlgorithm(mContext, mRootBounds);
         resetDividerPosition();
     }
 
@@ -114,7 +115,7 @@
         mContext = mContext.createConfigurationContext(configuration);
         mSplitWindowManager.setConfiguration(configuration);
         mRootBounds.set(rootBounds);
-        mDividerSnapAlgorithm = getSnapAlgorithm(mContext.getResources(), mRootBounds);
+        mDividerSnapAlgorithm = getSnapAlgorithm(mContext, mRootBounds);
         resetDividerPosition();
 
         // Don't inflate divider bar if it is not initialized.
@@ -217,15 +218,15 @@
         return mDividerSnapAlgorithm.calculateSnapTarget(position, velocity, hardDismiss);
     }
 
-    private DividerSnapAlgorithm getSnapAlgorithm(Resources resources, Rect rootBounds) {
+    private DividerSnapAlgorithm getSnapAlgorithm(Context context, Rect rootBounds) {
         final boolean isLandscape = isLandscape(rootBounds);
         return new DividerSnapAlgorithm(
-                resources,
+                context.getResources(),
                 rootBounds.width(),
                 rootBounds.height(),
                 mDividerSize,
                 !isLandscape,
-                new Rect() /* insets */,
+                getDisplayInsets(context),
                 isLandscape ? DOCKED_LEFT : DOCKED_TOP /* dockSide */);
     }
 
@@ -250,6 +251,15 @@
         animator.start();
     }
 
+    private static Rect getDisplayInsets(Context context) {
+        return context.getSystemService(WindowManager.class)
+                .getMaximumWindowMetrics()
+                .getWindowInsets()
+                .getInsets(WindowInsets.Type.navigationBars()
+                        | WindowInsets.Type.statusBars()
+                        | WindowInsets.Type.displayCutout()).toRect();
+    }
+
     private static boolean isLandscape(Rect bounds) {
         return bounds.width() > bounds.height();
     }
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 f4c0f93..cf35656 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
@@ -67,7 +67,7 @@
 
     final SurfaceSession mSurfaceSession = new SurfaceSession();
 
-    private final SplitScreenTransitions mSplitTransitions;
+    private final LegacySplitScreenTransitions mSplitTransitions;
 
     LegacySplitScreenTaskListener(LegacySplitScreenController splitScreenController,
                     ShellTaskOrganizer shellTaskOrganizer,
@@ -75,7 +75,7 @@
                     SyncTransactionQueue syncQueue) {
         mSplitScreenController = splitScreenController;
         mTaskOrganizer = shellTaskOrganizer;
-        mSplitTransitions = new SplitScreenTransitions(splitScreenController.mTransactionPool,
+        mSplitTransitions = new LegacySplitScreenTransitions(splitScreenController.mTransactionPool,
                 transitions, mSplitScreenController, this);
         transitions.addHandler(mSplitTransitions);
         mSyncQueue = syncQueue;
@@ -112,7 +112,7 @@
         return mTaskOrganizer;
     }
 
-    SplitScreenTransitions getSplitTransitions() {
+    LegacySplitScreenTransitions getSplitTransitions() {
         return mSplitTransitions;
     }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/SplitScreenTransitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTransitions.java
similarity index 98%
rename from libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/SplitScreenTransitions.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTransitions.java
index d06064a..27c56fd 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/SplitScreenTransitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTransitions.java
@@ -47,7 +47,7 @@
 import java.util.ArrayList;
 
 /** Plays transition animations for split-screen */
-public class SplitScreenTransitions implements Transitions.TransitionHandler {
+public class LegacySplitScreenTransitions implements Transitions.TransitionHandler {
     private static final String TAG = "SplitScreenTransitions";
 
     public static final int TRANSIT_SPLIT_DISMISS_SNAP = TRANSIT_FIRST_CUSTOM + 10;
@@ -68,7 +68,7 @@
     private Transitions.TransitionFinishCallback mFinishCallback = null;
     private SurfaceControl.Transaction mFinishTransaction;
 
-    SplitScreenTransitions(@NonNull TransactionPool pool, @NonNull Transitions transitions,
+    LegacySplitScreenTransitions(@NonNull TransactionPool pool, @NonNull Transitions transitions,
             @NonNull LegacySplitScreenController splitScreen,
             @NonNull LegacySplitScreenTaskListener listener) {
         mTransactionPool = pool;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizer.java
index d90cc47..c7dbe88 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizer.java
@@ -23,7 +23,6 @@
 import android.util.Log;
 import android.view.SurfaceControl;
 import android.view.SurfaceSession;
-import android.view.WindowManager;
 import android.window.DisplayAreaAppearedInfo;
 import android.window.DisplayAreaInfo;
 import android.window.DisplayAreaOrganizer;
@@ -34,8 +33,9 @@
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.wm.shell.R;
-import com.android.wm.shell.common.DisplayController;
+import com.android.wm.shell.common.DisplayLayout;
 
+import java.io.PrintWriter;
 import java.util.List;
 import java.util.concurrent.Executor;
 
@@ -52,12 +52,15 @@
     private final SurfaceSession mSurfaceSession = new SurfaceSession();
     private final float[] mColor;
     private final float mAlpha;
-    private final Rect mRect;
     private final Executor mMainExecutor;
-    private final Rect mDisplaySize;
     private final OneHandedSurfaceTransactionHelper.SurfaceControlTransactionFactory
             mSurfaceControlTransactionFactory;
 
+    /**
+     * The background to distinguish the boundary of translated windows and empty region when
+     * one handed mode triggered.
+     */
+    private Rect mBkgBounds;
     @VisibleForTesting
     @GuardedBy("mLock")
     boolean mIsShowing;
@@ -82,15 +85,19 @@
         mMainExecutor.execute(() -> removeBackgroundPanelLayer());
     }
 
-    public OneHandedBackgroundPanelOrganizer(Context context, WindowManager windowManager,
-            DisplayController displayController, Executor executor) {
+    public OneHandedBackgroundPanelOrganizer(Context context, DisplayLayout displayLayout,
+            Executor executor) {
         super(executor);
-        mDisplaySize = windowManager.getCurrentWindowMetrics().getBounds();
         final Resources res = context.getResources();
         final float defaultRGB = res.getFloat(R.dimen.config_one_handed_background_rgb);
         mColor = new float[]{defaultRGB, defaultRGB, defaultRGB};
         mAlpha = res.getFloat(R.dimen.config_one_handed_background_alpha);
-        mRect = new Rect(0, 0, mDisplaySize.width(), mDisplaySize.height());
+        // Ensure the mBkgBounds is portrait, due to OHM only support on portrait
+        if (displayLayout.height() > displayLayout.width()) {
+            mBkgBounds = new Rect(0, 0, displayLayout.width(), displayLayout.height());
+        } else {
+            mBkgBounds = new Rect(0, 0, displayLayout.height(), displayLayout.width());
+        }
         mMainExecutor = executor;
         mSurfaceControlTransactionFactory = SurfaceControl.Transaction::new;
     }
@@ -144,6 +151,7 @@
             if (mBackgroundSurface == null) {
                 mBackgroundSurface = new SurfaceControl.Builder(mSurfaceSession)
                         .setParent(mParentLeash)
+                        .setBufferSize(mBkgBounds.width(), mBkgBounds.height())
                         .setColorLayer()
                         .setFormat(PixelFormat.RGBA_8888)
                         .setOpaque(false)
@@ -188,11 +196,19 @@
 
             SurfaceControl.Transaction transaction =
                     mSurfaceControlTransactionFactory.getTransaction();
-            transaction.remove(mBackgroundSurface);
-            transaction.apply();
+            transaction.remove(mBackgroundSurface).apply();
             transaction.close();
             mBackgroundSurface = null;
             mIsShowing = false;
         }
     }
+
+    void dump(@NonNull PrintWriter pw) {
+        final String innerPrefix = "  ";
+        pw.println(TAG + "states: ");
+        pw.print(innerPrefix + "mIsShowing=");
+        pw.println(mIsShowing);
+        pw.print(innerPrefix + "mBkgBounds=");
+        pw.println(mBkgBounds);
+    }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java
index 25968eb..7965a80 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java
@@ -17,10 +17,10 @@
 package com.android.wm.shell.onehanded;
 
 import static android.os.UserHandle.USER_CURRENT;
+import static android.view.Display.DEFAULT_DISPLAY;
 
 import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
 
-import android.Manifest;
 import android.annotation.BinderThread;
 import android.content.ComponentName;
 import android.content.Context;
@@ -28,13 +28,13 @@
 import android.content.om.OverlayInfo;
 import android.content.res.Configuration;
 import android.database.ContentObserver;
-import android.graphics.Rect;
 import android.os.Handler;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SystemProperties;
 import android.provider.Settings;
 import android.util.Slog;
+import android.view.Surface;
 import android.view.ViewConfiguration;
 import android.view.WindowManager;
 import android.view.accessibility.AccessibilityManager;
@@ -47,7 +47,7 @@
 import com.android.wm.shell.R;
 import com.android.wm.shell.common.DisplayChangeController;
 import com.android.wm.shell.common.DisplayController;
-import com.android.wm.shell.common.ExecutorUtils;
+import com.android.wm.shell.common.DisplayLayout;
 import com.android.wm.shell.common.RemoteCallable;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.TaskStackListenerCallback;
@@ -76,9 +76,10 @@
     private boolean mLockedDisabled;
     private float mOffSetFraction;
 
-    private final Context mContext;
+    private Context mContext;
+
+    private final AccessibilityManager mAccessibilityManager;
     private final DisplayController mDisplayController;
-    private final OneHandedGestureHandler mGestureHandler;
     private final OneHandedSettingsUtil mOneHandedSettingsUtil;
     private final OneHandedTimeoutHandler mTimeoutHandler;
     private final OneHandedTouchHandler mTouchHandler;
@@ -89,10 +90,9 @@
     private final ShellExecutor mMainExecutor;
     private final Handler mMainHandler;
     private final OneHandedImpl mImpl = new OneHandedImpl();
-    private final WindowManager mWindowManager;
 
     private OneHandedDisplayAreaOrganizer mDisplayAreaOrganizer;
-    private final AccessibilityManager mAccessibilityManager;
+    private OneHandedGestureHandler mGestureHandler;
     private OneHandedBackgroundPanelOrganizer mBackgroundPanelOrganizer;
 
     /**
@@ -100,8 +100,29 @@
      */
     private final DisplayChangeController.OnDisplayChangingListener mRotationController =
             (display, fromRotation, toRotation, wct) -> {
-                if (mDisplayAreaOrganizer != null) {
-                    mDisplayAreaOrganizer.onRotateDisplay(fromRotation, toRotation, wct);
+                if (!isInitialized()) {
+                    return;
+                }
+                mDisplayAreaOrganizer.onRotateDisplay(mContext, toRotation, wct);
+                mGestureHandler.onRotateDisplay(mDisplayAreaOrganizer.getDisplayLayout());
+            };
+
+    private final DisplayController.OnDisplaysChangedListener mDisplaysChangedListener =
+            new DisplayController.OnDisplaysChangedListener() {
+                @Override
+                public void onDisplayConfigurationChanged(int displayId, Configuration newConfig) {
+                    if (displayId != DEFAULT_DISPLAY || !isInitialized()) {
+                        return;
+                    }
+                    updateDisplayLayout(displayId);
+                }
+
+                @Override
+                public void onDisplayAdded(int displayId) {
+                    if (displayId != DEFAULT_DISPLAY || !isInitialized()) {
+                        return;
+                    }
+                    updateDisplayLayout(displayId);
                 }
             };
 
@@ -115,8 +136,7 @@
             new AccessibilityManager.AccessibilityStateChangeListener() {
                 @Override
                 public void onAccessibilityStateChanged(boolean enabled) {
-                    if (mOneHandedSettingsUtil == null) {
-                        Slog.w(TAG, "mOneHandedSettingsUtil may not instantiate yet");
+                    if (!isInitialized()) {
                         return;
                     }
                     if (enabled) {
@@ -147,6 +167,14 @@
                 }
             };
 
+    private boolean isInitialized() {
+        if (mDisplayAreaOrganizer == null || mDisplayController == null
+                || mGestureHandler == null || mOneHandedSettingsUtil == null) {
+            Slog.w(TAG, "Components may not initialized yet!");
+            return false;
+        }
+        return true;
+    }
 
     /**
      * Creates {@link OneHandedController}, returns {@code null} if the feature is not supported.
@@ -154,8 +182,8 @@
     @Nullable
     public static OneHandedController create(
             Context context, WindowManager windowManager, DisplayController displayController,
-            TaskStackListenerImpl taskStackListener, UiEventLogger uiEventLogger,
-            ShellExecutor mainExecutor, Handler mainHandler) {
+            DisplayLayout displayLayout, TaskStackListenerImpl taskStackListener,
+            UiEventLogger uiEventLogger, ShellExecutor mainExecutor, Handler mainHandler) {
         if (!SystemProperties.getBoolean(SUPPORT_ONE_HANDED_MODE, false)) {
             Slog.w(TAG, "Device doesn't support OneHanded feature");
             return null;
@@ -169,19 +197,17 @@
         OneHandedTouchHandler touchHandler = new OneHandedTouchHandler(timeoutHandler,
                 mainExecutor);
         OneHandedGestureHandler gestureHandler = new OneHandedGestureHandler(
-                context, windowManager, displayController, ViewConfiguration.get(context),
-                mainExecutor);
+                context, displayLayout, ViewConfiguration.get(context), mainExecutor);
         OneHandedBackgroundPanelOrganizer oneHandedBackgroundPanelOrganizer =
-                new OneHandedBackgroundPanelOrganizer(context, windowManager, displayController,
-                        mainExecutor);
+                new OneHandedBackgroundPanelOrganizer(context, displayLayout, mainExecutor);
         OneHandedDisplayAreaOrganizer organizer = new OneHandedDisplayAreaOrganizer(
-                context, windowManager, animationController, tutorialHandler,
+                context, displayLayout, animationController, tutorialHandler,
                 oneHandedBackgroundPanelOrganizer, mainExecutor);
         OneHandedSettingsUtil settingsUtil = new OneHandedSettingsUtil();
         OneHandedUiEventLogger oneHandedUiEventsLogger = new OneHandedUiEventLogger(uiEventLogger);
         IOverlayManager overlayManager = IOverlayManager.Stub.asInterface(
                 ServiceManager.getService(Context.OVERLAY_SERVICE));
-        return new OneHandedController(context, windowManager, displayController,
+        return new OneHandedController(context, displayController,
                 oneHandedBackgroundPanelOrganizer, organizer, touchHandler, tutorialHandler,
                 gestureHandler, settingsUtil, timeoutHandler, oneHandedUiEventsLogger,
                 overlayManager, taskStackListener, mainExecutor, mainHandler);
@@ -189,7 +215,6 @@
 
     @VisibleForTesting
     OneHandedController(Context context,
-            WindowManager windowManager,
             DisplayController displayController,
             OneHandedBackgroundPanelOrganizer backgroundPanelOrganizer,
             OneHandedDisplayAreaOrganizer displayAreaOrganizer,
@@ -205,7 +230,6 @@
             Handler mainHandler) {
         mContext = context;
         mOneHandedSettingsUtil = settingsUtil;
-        mWindowManager = windowManager;
         mBackgroundPanelOrganizer = backgroundPanelOrganizer;
         mDisplayAreaOrganizer = displayAreaOrganizer;
         mDisplayController = displayController;
@@ -218,6 +242,7 @@
         mOneHandedUiEventLogger = uiEventsLogger;
         mTaskStackListener = taskStackListener;
 
+        mDisplayController.addDisplayWindowListener(mDisplaysChangedListener);
         final float offsetPercentageConfig = context.getResources().getFraction(
                 R.fraction.config_one_handed_offset, 1, 1);
         final int sysPropPercentageConfig = SystemProperties.getInt(
@@ -297,8 +322,14 @@
             Slog.d(TAG, "Temporary lock disabled");
             return;
         }
+        final int currentRotation = mDisplayAreaOrganizer.getDisplayLayout().rotation();
+        if (currentRotation != Surface.ROTATION_0 && currentRotation != Surface.ROTATION_180) {
+            Slog.w(TAG, "One handed mode only support portrait mode");
+            return;
+        }
         if (!mDisplayAreaOrganizer.isInOneHanded()) {
-            final int yOffSet = Math.round(getDisplaySize().height() * mOffSetFraction);
+            final int yOffSet = Math.round(
+                    mDisplayAreaOrganizer.getDisplayLayout().height() * mOffSetFraction);
             mDisplayAreaOrganizer.scheduleOffset(0, yOffSet);
             mTimeoutHandler.resetTimer();
 
@@ -371,6 +402,12 @@
                 .getSettingsSwipeToNotificationEnabled(mContext.getContentResolver()));
     }
 
+    private void updateDisplayLayout(int displayId) {
+        mDisplayAreaOrganizer.setDisplayLayout(
+                mDisplayController.getDisplayLayout(displayId));
+        mGestureHandler.onDisplayChanged(mDisplayAreaOrganizer.getDisplayLayout());
+    }
+
     private ContentObserver getObserver(Runnable onChangeRunnable) {
         return new ContentObserver(mMainHandler) {
             @Override
@@ -454,24 +491,6 @@
                 OneHandedUiEventLogger.EVENT_ONE_HANDED_TRIGGER_TIMEOUT_OUT));
     }
 
-    /**
-     * Query the current display real size from {@link WindowManager}
-     *
-     * @return {@link WindowManager#getCurrentWindowMetrics()#getBounds()}
-     */
-    private Rect getDisplaySize() {
-        if (mWindowManager == null) {
-            Slog.e(TAG, "WindowManager instance is null! Can not get display size!");
-            return new Rect();
-        }
-        final Rect displaySize = mWindowManager.getCurrentWindowMetrics().getBounds();
-        if (displaySize.width() == 0 || displaySize.height() == 0) {
-            Slog.e(TAG, "Display size error! width = " + displaySize.width()
-                    + ", height = " + displaySize.height());
-        }
-        return displaySize;
-    }
-
     @VisibleForTesting
     boolean isLockedDisabled() {
         return mLockedDisabled;
@@ -483,7 +502,7 @@
         }
 
         mTouchHandler.onOneHandedEnabled(mIsOneHandedEnabled);
-        mGestureHandler.onOneHandedEnabled(mIsOneHandedEnabled || mIsSwipeToNotificationEnabled);
+        mGestureHandler.onGestureEnabled(mIsOneHandedEnabled || mIsSwipeToNotificationEnabled);
 
         if (!mIsOneHandedEnabled) {
             mDisplayAreaOrganizer.unregisterOrganizer();
@@ -532,10 +551,15 @@
 
     @VisibleForTesting
     void setLockedDisabled(boolean locked, boolean enabled) {
-        if (enabled == mIsOneHandedEnabled) {
+        final boolean isFeatureEnabled = mIsOneHandedEnabled || mIsSwipeToNotificationEnabled;
+
+        if (enabled == isFeatureEnabled) {
             return;
         }
         mLockedDisabled = locked && !enabled;
+
+        // Disabled gesture when keyguard ON
+        mGestureHandler.onGestureEnabled(!mLockedDisabled && isFeatureEnabled);
     }
 
     private void onConfigChanged(Configuration newConfig) {
@@ -556,6 +580,10 @@
         pw.print(innerPrefix + "mLockedDisabled=");
         pw.println(mLockedDisabled);
 
+        if (mBackgroundPanelOrganizer != null) {
+            mBackgroundPanelOrganizer.dump(pw);
+        }
+
         if (mDisplayAreaOrganizer != null) {
             mDisplayAreaOrganizer.dump(pw);
         }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java
index 5eec231..682c9a3f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java
@@ -23,9 +23,7 @@
 import android.graphics.Rect;
 import android.os.SystemProperties;
 import android.util.ArrayMap;
-import android.util.Slog;
 import android.view.SurfaceControl;
-import android.view.WindowManager;
 import android.window.DisplayAreaAppearedInfo;
 import android.window.DisplayAreaInfo;
 import android.window.DisplayAreaOrganizer;
@@ -37,6 +35,7 @@
 import androidx.annotation.VisibleForTesting;
 
 import com.android.wm.shell.R;
+import com.android.wm.shell.common.DisplayLayout;
 import com.android.wm.shell.common.ShellExecutor;
 
 import java.io.PrintWriter;
@@ -58,7 +57,8 @@
     private static final String ONE_HANDED_MODE_TRANSLATE_ANIMATION_DURATION =
             "persist.debug.one_handed_translate_animation_duration";
 
-    private final WindowManager mWindowManager;
+    private DisplayLayout mDisplayLayout = new DisplayLayout();
+
     private final Rect mLastVisualDisplayBounds = new Rect();
     private final Rect mDefaultDisplayBounds = new Rect();
 
@@ -108,15 +108,15 @@
      * Constructor of OneHandedDisplayAreaOrganizer
      */
     public OneHandedDisplayAreaOrganizer(Context context,
-            WindowManager windowManager,
+            DisplayLayout displayLayout,
             OneHandedAnimationController animationController,
             OneHandedTutorialHandler tutorialHandler,
             OneHandedBackgroundPanelOrganizer oneHandedBackgroundGradientOrganizer,
             ShellExecutor mainExecutor) {
         super(mainExecutor);
-        mWindowManager = windowManager;
+        mDisplayLayout.set(displayLayout);
+        updateDisplayBounds();
         mAnimationController = animationController;
-        mLastVisualDisplayBounds.set(getDisplayBounds());
         final int animationDurationConfig = context.getResources().getInteger(
                 R.integer.config_one_handed_translate_animation_duration);
         mEnterExitAnimationDurationMs =
@@ -146,7 +146,7 @@
             final DisplayAreaAppearedInfo info = displayAreaInfos.get(i);
             onDisplayAreaAppeared(info.getDisplayAreaInfo(), info.getLeash());
         }
-        mDefaultDisplayBounds.set(getDisplayBounds());
+        updateDisplayBounds();
         return displayAreaInfos;
     }
 
@@ -157,29 +157,21 @@
     }
 
     /**
-     * Handler for display rotation changes by below policy which
-     * handles 90 degree display rotation changes {@link Surface.Rotation}.
+     * Handler for display rotation changes by {@link DisplayLayout}
      *
-     * @param fromRotation starting rotation of the display.
-     * @param toRotation   target rotation of the display (after rotating).
-     * @param wct          A task transaction {@link WindowContainerTransaction} from
-     *                     {@link DisplayChangeController} to populate.
+     * @param context       Any context
+     * @param toRotation    target rotation of the display (after rotating).
+     * @param wct           A task transaction {@link WindowContainerTransaction} from
+     *                      {@link DisplayChangeController} to populate.
      */
-    public void onRotateDisplay(int fromRotation, int toRotation, WindowContainerTransaction wct) {
-        // Stop one handed without animation and reset cropped size immediately
-        final Rect newBounds = new Rect(getDisplayBounds());
-        // This diff rule will only filter the cases portrait <-> landscape
-        final boolean isOrientationDiff = Math.abs(fromRotation - toRotation) % 2 == 1;
-
-        if (isOrientationDiff) {
-            // getDisplayBounds() will return window metrics bounds which dose not update to
-            // corresponding display orientation yet, we have to manual rotate bounds
-            newBounds.set(0, 0, newBounds.bottom, newBounds.right);
-            resetWindowsOffset(wct);
-            mDefaultDisplayBounds.set(newBounds);
-            mLastVisualDisplayBounds.set(newBounds);
-            finishOffset(0, TRANSITION_DIRECTION_EXIT);
+    public void onRotateDisplay(Context context, int toRotation, WindowContainerTransaction wct) {
+        if (mDisplayLayout.rotation() == toRotation) {
+            return;
         }
+        mDisplayLayout.rotateTo(context.getResources(), toRotation);
+        resetWindowsOffset(wct);
+        updateDisplayBounds();
+        finishOffset(0, TRANSITION_DIRECTION_EXIT);
     }
 
     /**
@@ -191,9 +183,7 @@
                 mDefaultDisplayBounds.top + yOffset,
                 mDefaultDisplayBounds.right,
                 mDefaultDisplayBounds.bottom + yOffset);
-        final Rect fromBounds = getLastVisualDisplayBounds() != null
-                ? getLastVisualDisplayBounds()
-                : mDefaultDisplayBounds;
+        final Rect fromBounds = getLastVisualDisplayBounds();
         final int direction = yOffset > 0
                 ? TRANSITION_DIRECTION_TRIGGER
                 : TRANSITION_DIRECTION_EXIT;
@@ -219,7 +209,8 @@
         applyTransaction(wct);
     }
 
-    private void resetWindowsOffset(WindowContainerTransaction wct) {
+    @VisibleForTesting
+    void resetWindowsOffset(WindowContainerTransaction wct) {
         final SurfaceControl.Transaction tx =
                 mSurfaceControlTransactionFactory.getTransaction();
         mDisplayAreaTokenMap.forEach(
@@ -292,19 +283,19 @@
         return mLastVisualDisplayBounds;
     }
 
-    @Nullable
     @VisibleForTesting
-    Rect getDisplayBounds() {
-        if (mWindowManager == null) {
-            Slog.e(TAG, "WindowManager instance is null! Can not get display size!");
-            return new Rect();
-        }
-        final Rect displayBounds = mWindowManager.getCurrentWindowMetrics().getBounds();
-        if (displayBounds.width() == 0 || displayBounds.height() == 0) {
-            Slog.e(TAG, "Display size error! width = " + displayBounds.width()
-                    + ", height = " + displayBounds.height());
-        }
-        return displayBounds;
+    @Nullable
+    Rect getLastDisplayBounds() {
+        return mLastVisualDisplayBounds;
+    }
+
+    public DisplayLayout getDisplayLayout() {
+        return mDisplayLayout;
+    }
+
+    @VisibleForTesting
+    void setDisplayLayout(@NonNull DisplayLayout displayLayout) {
+        mDisplayLayout.set(displayLayout);
     }
 
     @VisibleForTesting
@@ -312,6 +303,11 @@
         return mDisplayAreaTokenMap;
     }
 
+    void updateDisplayBounds() {
+        mDefaultDisplayBounds.set(0, 0, mDisplayLayout.width(), mDisplayLayout.height());
+        mLastVisualDisplayBounds.set(mDefaultDisplayBounds);
+    }
+
     /**
      * Register transition callback
      */
@@ -324,13 +320,13 @@
         pw.println(TAG + "states: ");
         pw.print(innerPrefix + "mIsInOneHanded=");
         pw.println(mIsInOneHanded);
+        pw.print(innerPrefix + "mDisplayLayout.rotation()=");
+        pw.println(mDisplayLayout.rotation());
         pw.print(innerPrefix + "mDisplayAreaTokenMap=");
         pw.println(mDisplayAreaTokenMap);
         pw.print(innerPrefix + "mDefaultDisplayBounds=");
         pw.println(mDefaultDisplayBounds);
         pw.print(innerPrefix + "mLastVisualDisplayBounds=");
         pw.println(mLastVisualDisplayBounds);
-        pw.print(innerPrefix + "getDisplayBounds()=");
-        pw.println(getDisplayBounds());
     }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedGestureHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedGestureHandler.java
index 778876c..495362a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedGestureHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedGestureHandler.java
@@ -24,7 +24,6 @@
 import android.graphics.Rect;
 import android.hardware.input.InputManager;
 import android.os.Looper;
-import android.util.Log;
 import android.view.Display;
 import android.view.InputChannel;
 import android.view.InputEvent;
@@ -33,29 +32,23 @@
 import android.view.MotionEvent;
 import android.view.Surface;
 import android.view.ViewConfiguration;
-import android.view.WindowManager;
-import android.window.WindowContainerTransaction;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.VisibleForTesting;
 
 import com.android.wm.shell.R;
-import com.android.wm.shell.common.DisplayChangeController;
-import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.common.DisplayLayout;
 import com.android.wm.shell.common.ShellExecutor;
 
 import java.io.PrintWriter;
 
 /**
- * The class manage swipe up and down gesture for 3-Button mode navigation,
- * others(e.g, 2-button, full gesture mode) are handled by Launcher quick steps.
- * TODO(b/160934654) Migrate to Launcher quick steps
+ * The class manage swipe up and down gesture for 3-Button mode navigation, others(e.g, 2-button,
+ * full gesture mode) are handled by Launcher quick steps. TODO(b/160934654) Migrate to Launcher
+ * quick steps
  */
-public class OneHandedGestureHandler implements OneHandedTransitionCallback,
-        DisplayChangeController.OnDisplayChangingListener {
+public class OneHandedGestureHandler implements OneHandedTransitionCallback {
     private static final String TAG = "OneHandedGestureHandler";
-    private static final boolean DEBUG_GESTURE = false;
 
     private static final int ANGLE_MAX = 150;
     private static final int ANGLE_MIN = 30;
@@ -64,14 +57,13 @@
     private final PointF mDownPos = new PointF();
     private final PointF mLastPos = new PointF();
     private final PointF mStartDragPos = new PointF();
-    private final WindowManager mWindowManager;
 
     private boolean mPassedSlop;
     private boolean mAllowGesture;
     private boolean mIsEnabled;
     private int mNavGestureHeight;
     private boolean mIsThreeButtonModeEnabled;
-    private int mRotation = Surface.ROTATION_0;
+    private int mRotation;
 
     @VisibleForTesting
     InputMonitor mInputMonitor;
@@ -85,37 +77,35 @@
     private boolean mIsStopGesture;
 
     /**
-     * Constructor of OneHandedGestureHandler, we only handle the gesture of
-     * {@link Display#DEFAULT_DISPLAY}
+     * Constructor of OneHandedGestureHandler, we only handle the gesture of {@link
+     * Display#DEFAULT_DISPLAY}
      *
-     * @param context                  {@link Context}
-     * @param displayController        {@link DisplayController}
+     * @param context       Any context
+     * @param displayLayout Current {@link DisplayLayout} from controller
+     * @param viewConfig    {@link ViewConfiguration} to obtain touch slop
+     * @param mainExecutor  The wm-shell main executor
      */
-    public OneHandedGestureHandler(Context context, WindowManager windowManager,
-            DisplayController displayController, ViewConfiguration viewConfig,
+    public OneHandedGestureHandler(Context context,
+            DisplayLayout displayLayout,
+            ViewConfiguration viewConfig,
             ShellExecutor mainExecutor) {
-        mWindowManager = windowManager;
         mMainExecutor = mainExecutor;
-        displayController.addDisplayChangingController(this);
-        mNavGestureHeight = getNavBarSize(context,
-                displayController.getDisplayLayout(DEFAULT_DISPLAY));
         mDragDistThreshold = context.getResources().getDimensionPixelSize(
                 R.dimen.gestures_onehanded_drag_threshold);
+
         final float slop = viewConfig.getScaledTouchSlop();
         mSquaredSlop = slop * slop;
-
+        onDisplayChanged(displayLayout);
         updateIsEnabled();
     }
 
     /**
-     * Notified by {@link OneHandedController}, when user update settings of Enabled or Disabled
+     * Notifies by {@link OneHandedController}, when swipe down gesture is enabled on 3 button
+     * navigation bar mode.
      *
-     * @param isEnabled is one handed settings enabled or not
+     * @param isEnabled Either one handed mode or swipe for notification function enabled or not
      */
-    public void onOneHandedEnabled(boolean isEnabled) {
-        if (DEBUG_GESTURE) {
-            Log.d(TAG, "onOneHandedEnabled, isEnabled = " + isEnabled);
-        }
+    public void onGestureEnabled(boolean isEnabled) {
         mIsEnabled = isEnabled;
         updateIsEnabled();
     }
@@ -126,25 +116,31 @@
     }
 
     /**
-     * Register {@link OneHandedGestureEventCallback} to receive onStart(), onStop() callback
+     * Registers {@link OneHandedGestureEventCallback} to receive onStart(), onStop() callback
      */
     public void setGestureEventListener(OneHandedGestureEventCallback callback) {
         mGestureEventCallback = callback;
     }
 
+    /**
+     * Called when onDisplayAdded() or onDisplayRemoved() callback
+     * @param displayLayout The latest {@link DisplayLayout} representing current displayId
+     */
+    public void onDisplayChanged(DisplayLayout displayLayout) {
+        mNavGestureHeight = getNavBarSize(displayLayout);
+        mGestureRegion.set(0, displayLayout.height() - mNavGestureHeight, displayLayout.width(),
+                displayLayout.height());
+        mRotation = displayLayout.rotation();
+    }
+
     private void onMotionEvent(MotionEvent ev) {
         int action = ev.getActionMasked();
         if (action == MotionEvent.ACTION_DOWN) {
-            mAllowGesture = isWithinTouchRegion(ev.getX(), ev.getY())
-                    && mRotation == Surface.ROTATION_0;
+            mAllowGesture = isWithinTouchRegion(ev.getX(), ev.getY()) && isGestureAvailable();
             if (mAllowGesture) {
                 mDownPos.set(ev.getX(), ev.getY());
                 mLastPos.set(mDownPos);
             }
-            if (DEBUG_GESTURE) {
-                Log.d(TAG, "ACTION_DOWN, mDownPos=" + mDownPos + ", mAllowGesture="
-                        + mAllowGesture);
-            }
         } else if (mAllowGesture) {
             switch (action) {
                 case MotionEvent.ACTION_MOVE:
@@ -204,34 +200,17 @@
     }
 
     private boolean isWithinTouchRegion(float x, float y) {
-        if (DEBUG_GESTURE) {
-            Log.d(TAG, "isWithinTouchRegion(), mGestureRegion=" + mGestureRegion + ", downX=" + x
-                    + ", downY=" + y);
-        }
         return mGestureRegion.contains(Math.round(x), Math.round(y));
     }
 
-    private int getNavBarSize(Context context, @Nullable DisplayLayout displayLayout) {
-        if (displayLayout != null) {
-            return displayLayout.navBarFrameHeight();
-        } else {
-            return isRotated()
-                    ? context.getResources().getDimensionPixelSize(
-                    com.android.internal.R.dimen.navigation_bar_height_landscape)
-                    : context.getResources().getDimensionPixelSize(
-                            com.android.internal.R.dimen.navigation_bar_height);
-        }
+    private int getNavBarSize(@NonNull DisplayLayout displayLayout) {
+        return isGestureAvailable() ? displayLayout.navBarFrameHeight() : 0 /* In landscape */;
     }
 
     private void updateIsEnabled() {
         disposeInputChannel();
 
-        // Either OHM or swipe notification shade can activate in portrait mode only
-        if (mIsEnabled && mIsThreeButtonModeEnabled && !isRotated()) {
-            final Rect displaySize = mWindowManager.getCurrentWindowMetrics().getBounds();
-            // Register input event receiver to monitor the touch region of NavBar gesture height
-            mGestureRegion.set(0, displaySize.height() - mNavGestureHeight, displaySize.width(),
-                    displaySize.height());
+        if (mIsEnabled && mIsThreeButtonModeEnabled && isGestureAvailable()) {
             mInputMonitor = InputManager.getInstance().monitorGestureInput(
                     "onehanded-gesture-offset", DEFAULT_DISPLAY);
             try {
@@ -251,10 +230,16 @@
         }
     }
 
-    @Override
-    public void onRotateDisplay(int displayId, int fromRotation, int toRotation,
-            WindowContainerTransaction t) {
-        mRotation = toRotation;
+    /**
+     * Handler for display rotation changes by {@link DisplayLayout}
+     *
+     * @param displayLayout The rotated displayLayout
+     */
+    public void onRotateDisplay(DisplayLayout displayLayout) {
+        mRotation = displayLayout.rotation();
+        mNavGestureHeight = getNavBarSize(displayLayout);
+        mGestureRegion.set(0, displayLayout.height() - mNavGestureHeight, displayLayout.width(),
+                displayLayout.height());
         updateIsEnabled();
     }
 
@@ -270,8 +255,9 @@
         }
     }
 
-    private boolean isRotated() {
-        return mRotation == Surface.ROTATION_90 || mRotation == Surface.ROTATION_270;
+    private boolean isGestureAvailable() {
+        // Either OHM or swipe notification shade can activate in portrait mode only
+        return mRotation == Surface.ROTATION_0 || mRotation == Surface.ROTATION_180;
     }
 
     private boolean isValidStartAngle(float deltaX, float deltaY) {
@@ -291,14 +277,18 @@
     void dump(@NonNull PrintWriter pw) {
         final String innerPrefix = "  ";
         pw.println(TAG + "States: ");
+        pw.print(innerPrefix + "mAllowGesture=");
+        pw.println(mAllowGesture);
         pw.print(innerPrefix + "mIsEnabled=");
         pw.println(mIsEnabled);
+        pw.print(innerPrefix + "mGestureRegion=");
+        pw.println(mGestureRegion);
         pw.print(innerPrefix + "mNavGestureHeight=");
         pw.println(mNavGestureHeight);
         pw.print(innerPrefix + "mIsThreeButtonModeEnabled=");
         pw.println(mIsThreeButtonModeEnabled);
-        pw.print(innerPrefix + "isLandscape=");
-        pw.println(isRotated());
+        pw.print(innerPrefix + "mRotation=");
+        pw.println(mRotation);
     }
 
     /**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedSettingsUtil.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedSettingsUtil.java
index 4768cf5..fa94ec5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedSettingsUtil.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedSettingsUtil.java
@@ -126,7 +126,7 @@
      */
     public boolean getSettingsSwipeToNotificationEnabled(ContentResolver resolver) {
         return Settings.Secure.getInt(resolver,
-                Settings.Secure.SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED, 1) == 1;
+                Settings.Secure.SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED, 0 /* Default OFF */) == 1;
     }
 
     void dump(PrintWriter pw, String prefix, ContentResolver resolver) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SideStage.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SideStage.java
index e7cd38f..01a81d2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SideStage.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SideStage.java
@@ -40,15 +40,17 @@
     void addTask(ActivityManager.RunningTaskInfo task, Rect rootBounds,
             WindowContainerTransaction wct) {
         final WindowContainerToken rootToken = mRootTaskInfo.token;
-        wct.setHidden(rootToken, false)
-                .setBounds(rootToken, rootBounds)
+        wct.setBounds(rootToken, rootBounds)
                 .reparent(task.token, rootToken, true /* onTop*/)
                 // Moving the root task to top after the child tasks were repareted , or the root
                 // task cannot be visible and focused.
-                .reorder(rootToken, true);
+                .reorder(rootToken, true /* onTop */);
     }
 
     boolean removeAllTasks(WindowContainerTransaction wct, boolean toTop) {
+        // No matter if the root task is empty or not, moving the root to bottom because it no
+        // longer preserves visible child task.
+        wct.reorder(mRootTaskInfo.token, false /* onTop */);
         if (mChildrenTaskInfo.size() == 0) return false;
         wct.reparentTasks(
                 mRootTaskInfo.token,
@@ -62,10 +64,7 @@
     boolean removeTask(int taskId, WindowContainerToken newParent, WindowContainerTransaction wct) {
         final ActivityManager.RunningTaskInfo task = mChildrenTaskInfo.get(taskId);
         if (task == null) return false;
-
-        wct.setHidden(mRootTaskInfo.token, true)
-                .reorder(mRootTaskInfo.token, false)
-                .reparent(task.token, newParent, false /* onTop */);
+        wct.reparent(task.token, newParent, false /* onTop */);
         return true;
     }
 }
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 3f46fee..855faaa 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
@@ -16,10 +16,14 @@
 
 package com.android.wm.shell.startingsurface;
 
+import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
+import static android.os.UserHandle.getUserHandleForUid;
+
 import android.annotation.ColorInt;
 import android.annotation.NonNull;
 import android.app.ActivityThread;
 import android.content.Context;
+import android.content.pm.ActivityInfo;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.graphics.Bitmap;
@@ -31,6 +35,7 @@
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.LayerDrawable;
 import android.os.Build;
+import android.os.Trace;
 import android.util.Slog;
 import android.view.SurfaceControl;
 import android.window.SplashScreenView;
@@ -39,6 +44,7 @@
 import com.android.internal.graphics.palette.Palette;
 import com.android.internal.graphics.palette.Quantizer;
 import com.android.internal.graphics.palette.VariationalKMeansQuantizer;
+import com.android.launcher3.icons.IconProvider;
 import com.android.wm.shell.common.TransactionPool;
 
 import java.util.List;
@@ -59,6 +65,7 @@
     // also 108*108 pixels, then do not enlarge this icon if only need to show foreground icon.
     private static final float ENLARGE_FOREGROUND_ICON_THRESHOLD = (72f * 72f) / (108f * 108f);
     private final Context mContext;
+    private final IconProvider mIconProvider;
     private final int mMaxAnimatableIconDuration;
 
     private int mIconSize;
@@ -70,10 +77,12 @@
     private int mIconNormalExitDistance;
     private int mIconEarlyExitDistance;
     private final TransactionPool mTransactionPool;
+    private final SplashScreenWindowAttrs mTmpAttrs = new SplashScreenWindowAttrs();
 
     SplashscreenContentDrawer(Context context, int maxAnimatableIconDuration,
             int iconExitAnimDuration, int appRevealAnimDuration, TransactionPool pool) {
         mContext = context;
+        mIconProvider = new IconProvider(context);
         mMaxAnimatableIconDuration = maxAnimatableIconDuration;
         mAppRevealDuration = appRevealAnimDuration;
         mIconExitDuration = iconExitAnimDuration;
@@ -109,49 +118,85 @@
         return new ColorDrawable(getSystemBGColor());
     }
 
-    SplashScreenView makeSplashScreenContentView(Context context, int iconRes,
-            int splashscreenContentResId) {
-        updateDensity();
-        // splash screen content will be deprecated after S.
-        final SplashScreenView ssc =
-                makeSplashscreenContentDrawable(context, splashscreenContentResId);
-
-        if (ssc != null) {
-            return ssc;
-        }
-
-        final SplashScreenWindowAttrs attrs =
-                SplashScreenWindowAttrs.createWindowAttrs(context);
-        final StartingWindowViewBuilder builder = new StartingWindowViewBuilder();
+    private @ColorInt int peekWindowBGColor(Context context) {
+        Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "peekWindowBGColor");
         final Drawable themeBGDrawable;
-
-        if (attrs.mWindowBgColor != 0) {
-            themeBGDrawable = new ColorDrawable(attrs.mWindowBgColor);
-        } else if (attrs.mWindowBgResId != 0) {
-            themeBGDrawable = context.getDrawable(attrs.mWindowBgResId);
+        if (mTmpAttrs.mWindowBgColor != 0) {
+            themeBGDrawable = new ColorDrawable(mTmpAttrs.mWindowBgColor);
+        } else if (mTmpAttrs.mWindowBgResId != 0) {
+            themeBGDrawable = context.getDrawable(mTmpAttrs.mWindowBgResId);
         } else {
-            Slog.w(TAG, "Window background not exist!");
             themeBGDrawable = createDefaultBackgroundDrawable();
+            Slog.w(TAG, "Window background does not exist, using " + themeBGDrawable);
         }
-        final int animationDuration;
-        final Drawable iconDrawable;
-        if (attrs.mReplaceIcon != null) {
-            iconDrawable = attrs.mReplaceIcon;
-            animationDuration = Math.max(0,
-                    Math.min(attrs.mAnimationDuration, mMaxAnimatableIconDuration));
+        final int estimatedWindowBGColor = estimateWindowBGColor(themeBGDrawable);
+        Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+        return estimatedWindowBGColor;
+    }
+
+    private int estimateWindowBGColor(Drawable themeBGDrawable) {
+        final DrawableColorTester themeBGTester =
+                new DrawableColorTester(themeBGDrawable, true /* filterTransparent */);
+        if (themeBGTester.nonTransparentRatio() == 0) {
+            // the window background is transparent, unable to draw
+            Slog.w(TAG, "Window background is transparent, fill background with black color");
+            return getSystemBGColor();
         } else {
-            iconDrawable = iconRes != 0 ? context.getDrawable(iconRes)
-                    : context.getPackageManager().getDefaultActivityIcon();
+            return themeBGTester.getDominateColor();
+        }
+    }
+
+    SplashScreenView makeSplashScreenContentView(Context context, ActivityInfo ai) {
+        updateDensity();
+
+        getWindowAttrs(context, mTmpAttrs);
+        final StartingWindowViewBuilder builder = new StartingWindowViewBuilder();
+        final int animationDuration;
+        Drawable iconDrawable;
+        if (mTmpAttrs.mReplaceIcon != null) {
+            iconDrawable = mTmpAttrs.mReplaceIcon;
+            animationDuration = Math.max(0,
+                    Math.min(mTmpAttrs.mAnimationDuration, mMaxAnimatableIconDuration));
+        } else {
+            iconDrawable = mIconProvider.getIconForUI(
+                    ai, getUserHandleForUid(ai.applicationInfo.uid));
+            if (iconDrawable == null) {
+                iconDrawable = context.getPackageManager().getDefaultActivityIcon();
+            }
             animationDuration = 0;
         }
+        final int themeBGColor = peekWindowBGColor(context);
         // TODO (b/173975965) Tracking the performance on improved splash screen.
         return builder
                 .setContext(context)
-                .setThemeDrawable(themeBGDrawable)
+                .setWindowBGColor(themeBGColor)
                 .setIconDrawable(iconDrawable)
                 .setIconAnimationDuration(animationDuration)
-                .setBrandingDrawable(attrs.mBrandingImage)
-                .setIconBackground(attrs.mIconBgColor).build();
+                .setBrandingDrawable(mTmpAttrs.mBrandingImage)
+                .setIconBackground(mTmpAttrs.mIconBgColor).build();
+    }
+
+    private static void getWindowAttrs(Context context, SplashScreenWindowAttrs attrs) {
+        final TypedArray typedArray = context.obtainStyledAttributes(
+                com.android.internal.R.styleable.Window);
+        attrs.mWindowBgResId = typedArray.getResourceId(R.styleable.Window_windowBackground, 0);
+        attrs.mWindowBgColor = typedArray.getColor(
+                R.styleable.Window_windowSplashScreenBackground, Color.TRANSPARENT);
+        attrs.mReplaceIcon = typedArray.getDrawable(
+                R.styleable.Window_windowSplashScreenAnimatedIcon);
+        attrs.mAnimationDuration = typedArray.getInt(
+                R.styleable.Window_windowSplashScreenAnimationDuration, 0);
+        attrs.mBrandingImage = typedArray.getDrawable(
+                R.styleable.Window_windowSplashScreenBrandingImage);
+        attrs.mIconBgColor = typedArray.getColor(
+                R.styleable.Window_windowSplashScreenIconBackgroundColor, Color.TRANSPARENT);
+        typedArray.recycle();
+        if (DEBUG) {
+            Slog.d(TAG, "window attributes color: "
+                    + Integer.toHexString(attrs.mWindowBgColor)
+                    + " icon " + attrs.mReplaceIcon + " duration " + attrs.mAnimationDuration
+                    + " brandImage " + attrs.mBrandingImage);
+        }
     }
 
     static class SplashScreenWindowAttrs {
@@ -161,35 +206,9 @@
         private Drawable mBrandingImage = null;
         private int mIconBgColor = Color.TRANSPARENT;
         private int mAnimationDuration = 0;
-
-        static SplashScreenWindowAttrs createWindowAttrs(Context context) {
-            final SplashScreenWindowAttrs attrs = new SplashScreenWindowAttrs();
-            final TypedArray typedArray = context.obtainStyledAttributes(
-                    com.android.internal.R.styleable.Window);
-            attrs.mWindowBgResId = typedArray.getResourceId(R.styleable.Window_windowBackground, 0);
-            attrs.mWindowBgColor = typedArray.getColor(
-                    R.styleable.Window_windowSplashScreenBackground, Color.TRANSPARENT);
-            attrs.mReplaceIcon = typedArray.getDrawable(
-                    R.styleable.Window_windowSplashScreenAnimatedIcon);
-            attrs.mAnimationDuration = typedArray.getInt(
-                    R.styleable.Window_windowSplashScreenAnimationDuration, 0);
-            attrs.mBrandingImage = typedArray.getDrawable(
-                    R.styleable.Window_windowSplashScreenBrandingImage);
-            attrs.mIconBgColor = typedArray.getColor(
-                    R.styleable.Window_windowSplashScreenIconBackgroundColor, Color.TRANSPARENT);
-            typedArray.recycle();
-            if (DEBUG) {
-                Slog.d(TAG, "window attributes color: "
-                        + Integer.toHexString(attrs.mWindowBgColor)
-                        + " icon " + attrs.mReplaceIcon + " duration " + attrs.mAnimationDuration
-                        + " brandImage " + attrs.mBrandingImage);
-            }
-            return attrs;
-        }
     }
 
     private class StartingWindowViewBuilder {
-        private Drawable mThemeBGDrawable;
         private Drawable mIconDrawable;
         private int mIconAnimationDuration;
         private Context mContext;
@@ -203,8 +222,8 @@
         private Drawable mFinalIconDrawable;
         private float mScale = 1f;
 
-        StartingWindowViewBuilder setThemeDrawable(Drawable background) {
-            mThemeBGDrawable = background;
+        StartingWindowViewBuilder setWindowBGColor(@ColorInt int background) {
+            mThemeColor = background;
             mBuildComplete = false;
             return this;
         }
@@ -247,18 +266,14 @@
                 Slog.e(TAG, "Unable to create StartingWindowView, lack of materials!");
                 return null;
             }
-            if (mThemeBGDrawable == null) {
-                Slog.w(TAG, "Theme Background Drawable is null, forget to set Theme Drawable?");
-                mThemeBGDrawable = createDefaultBackgroundDrawable();
-            }
-            processThemeColor();
+
             if (!processAdaptiveIcon() && mIconDrawable != null) {
                 if (DEBUG) {
                     Slog.d(TAG, "The icon is not an AdaptiveIconDrawable");
                 }
                 mFinalIconDrawable = SplashscreenIconDrawableFactory.makeIconDrawable(
                         mIconBackground != Color.TRANSPARENT
-                        ? mIconBackground : mThemeColor, mIconDrawable);
+                        ? mIconBackground : mThemeColor, mIconDrawable, mIconSize);
             }
             final int iconSize = mFinalIconDrawable != null ? (int) (mIconSize * mScale) : 0;
             mCachedResult = fillViewWithIcon(mContext, iconSize, mFinalIconDrawable);
@@ -266,22 +281,10 @@
             return mCachedResult;
         }
 
-        private void createIconDrawable(Drawable iconDrawable) {
+        private void createIconDrawable(Drawable iconDrawable, int iconSize) {
             mFinalIconDrawable = SplashscreenIconDrawableFactory.makeIconDrawable(
                     mIconBackground != Color.TRANSPARENT
-                    ? mIconBackground : mThemeColor, iconDrawable);
-        }
-
-        private void processThemeColor() {
-            final DrawableColorTester themeBGTester =
-                    new DrawableColorTester(mThemeBGDrawable, true /* filterTransparent */);
-            if (themeBGTester.nonTransparentRatio() == 0) {
-                // the window background is transparent, unable to draw
-                Slog.w(TAG, "Window background is transparent, fill background with black color");
-                mThemeColor = getSystemBGColor();
-            } else {
-                mThemeColor = themeBGTester.getDominateColor();
-            }
+                    ? mIconBackground : mThemeColor, iconDrawable, iconSize);
         }
 
         private boolean processAdaptiveIcon() {
@@ -289,6 +292,7 @@
                 return false;
             }
 
+            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "processAdaptiveIcon");
             final AdaptiveIconDrawable adaptiveIconDrawable = (AdaptiveIconDrawable) mIconDrawable;
             final DrawableColorTester backIconTester =
                     new DrawableColorTester(adaptiveIconDrawable.getBackground());
@@ -325,29 +329,28 @@
                 if (DEBUG) {
                     Slog.d(TAG, "makeSplashScreenContentView: choose fg icon");
                 }
-                // Using AdaptiveIconDrawable here can help keep the shape consistent with the
-                // current settings.
-                createIconDrawable(iconForeground);
                 // Reference AdaptiveIcon description, outer is 108 and inner is 72, so we
                 // should enlarge the size 108/72 if we only draw adaptiveIcon's foreground.
                 if (foreIconTester.nonTransparentRatio() < ENLARGE_FOREGROUND_ICON_THRESHOLD) {
                     mScale = 1.5f;
                 }
+                // Using AdaptiveIconDrawable here can help keep the shape consistent with the
+                // current settings.
+                final int iconSize = (int) (0.5f + mIconSize * mScale);
+                createIconDrawable(iconForeground, iconSize);
             } else {
                 if (DEBUG) {
                     Slog.d(TAG, "makeSplashScreenContentView: draw whole icon");
                 }
-                if (mIconBackground != Color.TRANSPARENT) {
-                    createIconDrawable(adaptiveIconDrawable);
-                } else {
-                    mFinalIconDrawable = adaptiveIconDrawable;
-                }
+                createIconDrawable(adaptiveIconDrawable, mIconSize);
             }
+            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
             return true;
         }
 
         private SplashScreenView fillViewWithIcon(Context context,
                 int iconSize, Drawable iconDrawable) {
+            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "fillViewWithIcon");
             final SplashScreenView.Builder builder = new SplashScreenView.Builder(context);
             builder.setIconSize(iconSize).setBackgroundColor(mThemeColor)
                     .setIconBackground(mIconBackground);
@@ -364,6 +367,7 @@
                 Slog.d(TAG, "fillViewWithIcon surfaceWindowView " + splashScreenView);
             }
             splashScreenView.makeSystemUIColorsTransparent();
+            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
             return splashScreenView;
         }
     }
@@ -395,7 +399,7 @@
         return root < 0.1;
     }
 
-    private static SplashScreenView makeSplashscreenContentDrawable(Context ctx,
+    static SplashScreenView makeSplashscreenContent(Context ctx,
             int splashscreenContentResId) {
         // doesn't support windowSplashscreenContent after S
         // TODO add an allowlist to skip some packages if needed
@@ -525,6 +529,7 @@
                     new TransparentFilterQuantizer();
 
             ComplexDrawableTester(Drawable drawable, boolean filterTransparent) {
+                Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "ComplexDrawableTester");
                 final Rect initialBounds = drawable.copyBounds();
                 int width = drawable.getIntrinsicWidth();
                 int height = drawable.getIntrinsicHeight();
@@ -559,6 +564,7 @@
                 }
                 mPalette = builder.generate();
                 bitmap.recycle();
+                Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
             }
 
             @Override
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 8626dbc..a4a83eb 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
@@ -16,11 +16,15 @@
 
 package com.android.wm.shell.startingsurface;
 
+import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
+
 import android.animation.Animator;
 import android.animation.ValueAnimator;
 import android.annotation.ColorInt;
 import android.annotation.NonNull;
 import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapShader;
 import android.graphics.Canvas;
 import android.graphics.ColorFilter;
 import android.graphics.Matrix;
@@ -28,11 +32,13 @@
 import android.graphics.Path;
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
+import android.graphics.Shader;
 import android.graphics.drawable.AdaptiveIconDrawable;
 import android.graphics.drawable.Animatable;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.os.SystemClock;
+import android.os.Trace;
 import android.util.PathParser;
 import android.window.SplashScreenView;
 
@@ -47,12 +53,57 @@
 public class SplashscreenIconDrawableFactory {
 
     static Drawable makeIconDrawable(@ColorInt int backgroundColor,
-            @NonNull Drawable foregroundDrawable) {
+            @NonNull Drawable foregroundDrawable, int iconSize) {
         if (foregroundDrawable instanceof Animatable) {
             return new AnimatableIconDrawable(backgroundColor, foregroundDrawable);
+        } else if (foregroundDrawable instanceof AdaptiveIconDrawable) {
+            return new ImmobileIconDrawable((AdaptiveIconDrawable) foregroundDrawable, iconSize);
         } else {
-            // TODO make a light weight drawable instead of AdaptiveIconDrawable
-            return new AdaptiveIconDrawable(new ColorDrawable(backgroundColor), foregroundDrawable);
+            return new ImmobileIconDrawable(new AdaptiveIconDrawable(
+                    new ColorDrawable(backgroundColor), foregroundDrawable), iconSize);
+        }
+    }
+
+    private static class ImmobileIconDrawable extends Drawable {
+        private Shader mLayersShader;
+        private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG
+                | Paint.FILTER_BITMAP_FLAG);
+
+        ImmobileIconDrawable(AdaptiveIconDrawable drawable, int iconSize) {
+            cachePaint(drawable, iconSize, iconSize);
+        }
+
+        private void cachePaint(AdaptiveIconDrawable drawable, int width, int height) {
+            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "cachePaint");
+            final Bitmap layersBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+            final Canvas canvas = new Canvas(layersBitmap);
+            drawable.setBounds(0, 0, width, height);
+            drawable.draw(canvas);
+            mLayersShader = new BitmapShader(layersBitmap, Shader.TileMode.CLAMP,
+                    Shader.TileMode.CLAMP);
+            mPaint.setShader(mLayersShader);
+            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+        }
+
+        @Override
+        public void draw(Canvas canvas) {
+            final Rect bounds = getBounds();
+            canvas.drawRect(bounds, mPaint);
+        }
+
+        @Override
+        public void setAlpha(int alpha) {
+
+        }
+
+        @Override
+        public void setColorFilter(ColorFilter colorFilter) {
+
+        }
+
+        @Override
+        public int getOpacity() {
+            return 1;
         }
     }
 
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 b592121..1302314 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
@@ -126,6 +126,7 @@
             labelRes = app.labelRes;
         }
 
+        final int taskId = taskInfo.taskId;
         Context context = mContext;
         // replace with the default theme if the application didn't set
         final int theme = windowInfo.splashScreenThemeResId != 0
@@ -153,6 +154,7 @@
             } catch (PackageManager.NameNotFoundException e) {
                 Slog.w(TAG, "Failed creating package context with package name "
                         + activityInfo.packageName + " for user " + taskInfo.userId, e);
+                return;
             }
         }
 
@@ -167,25 +169,27 @@
             final TypedArray typedArray = overrideContext.obtainStyledAttributes(
                     com.android.internal.R.styleable.Window);
             final int resId = typedArray.getResourceId(R.styleable.Window_windowBackground, 0);
-            if (resId != 0 && overrideContext.getDrawable(resId) != null) {
-                // We want to use the windowBackground for the override context if it is
-                // available, otherwise we use the default one to make sure a themed starting
-                // window is displayed for the app.
-                if (DEBUG_SPLASH_SCREEN) {
-                    Slog.d(TAG, "addSplashScreen: apply overrideConfig"
-                            + taskConfig + " to starting window resId=" + resId);
+            try {
+                if (resId != 0 && overrideContext.getDrawable(resId) != null) {
+                    // We want to use the windowBackground for the override context if it is
+                    // available, otherwise we use the default one to make sure a themed starting
+                    // window is displayed for the app.
+                    if (DEBUG_SPLASH_SCREEN) {
+                        Slog.d(TAG, "addSplashScreen: apply overrideConfig"
+                                + taskConfig + " to starting window resId=" + resId);
+                    }
+                    context = overrideContext;
                 }
-                context = overrideContext;
+            } catch (Resources.NotFoundException e) {
+                Slog.w(TAG, "failed creating starting window for overrideConfig at taskId: "
+                        + taskId, e);
+                return;
             }
             typedArray.recycle();
         }
 
         int windowFlags = 0;
-        final boolean enableHardAccelerated =
-                (activityInfo.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0;
-        if (enableHardAccelerated) {
-            windowFlags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
-        }
+        windowFlags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
 
         final boolean[] showWallpaper = new boolean[1];
         final int[] splashscreenContentResId = new int[1];
@@ -246,8 +250,6 @@
         params.packageName = activityInfo.packageName;
         params.windowAnimations = win.getWindowStyle().getResourceId(
                 com.android.internal.R.styleable.Window_windowAnimationStyle, 0);
-        params.privateFlags |=
-                WindowManager.LayoutParams.PRIVATE_FLAG_FAKE_HARDWARE_ACCELERATED;
         params.privateFlags |= WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS;
         // Setting as trusted overlay to let touches pass through. This is safe because this
         // window is controlled by the system.
@@ -264,24 +266,34 @@
         params.setTitle("Splash Screen " + activityInfo.packageName);
 
         // TODO(b/173975965) tracking performance
-        final int taskId = taskInfo.taskId;
         SplashScreenView sView = null;
         try {
-            sView = mSplashscreenContentDrawer.makeSplashScreenContentView(context, iconRes,
-                            splashscreenContentResId[0]);
             final View view = win.getDecorView();
             final WindowManager wm = mContext.getSystemService(WindowManager.class);
-            if (postAddWindow(taskId, appToken, view, wm, params)) {
+            // splash screen content will be deprecated after S.
+            sView = SplashscreenContentDrawer.makeSplashscreenContent(
+                    context, splashscreenContentResId[0]);
+            final boolean splashscreenContentCompatible = sView != null;
+            if (splashscreenContentCompatible) {
+                win.setContentView(sView);
+            } else {
+                sView = mSplashscreenContentDrawer
+                        .makeSplashScreenContentView(context, activityInfo);
                 win.setContentView(sView);
                 sView.cacheRootWindow(win);
             }
+            postAddWindow(taskId, appToken, view, wm, params);
         } catch (RuntimeException e) {
             // don't crash if something else bad happens, for example a
             // failure loading resources because we are loading from an app
             // on external storage that has been unmounted.
-            Slog.w(TAG, " failed creating starting window", e);
+            Slog.w(TAG, " failed creating starting window at taskId: " + taskId, e);
+            sView = null;
         } finally {
-            setSplashScreenRecord(taskId, sView);
+            final StartingWindowRecord record = mStartingWindowRecords.get(taskId);
+            if (record != null) {
+                record.setSplashScreenView(sView);
+            }
         }
     }
 
@@ -328,7 +340,7 @@
         ActivityTaskManager.getInstance().onSplashScreenViewCopyFinished(taskId, parcelable);
     }
 
-    protected boolean postAddWindow(int taskId, IBinder appToken, View view, WindowManager wm,
+    protected void postAddWindow(int taskId, IBinder appToken, View view, WindowManager wm,
             WindowManager.LayoutParams params) {
         boolean shouldSaveView = true;
         try {
@@ -349,7 +361,6 @@
             removeWindowNoAnimate(taskId);
             saveSplashScreenRecord(taskId, view);
         }
-        return shouldSaveView;
     }
 
     private void saveSplashScreenRecord(int taskId, View view) {
@@ -358,13 +369,6 @@
         mStartingWindowRecords.put(taskId, tView);
     }
 
-    private void setSplashScreenRecord(int taskId, SplashScreenView splashScreenView) {
-        final StartingWindowRecord record = mStartingWindowRecords.get(taskId);
-        if (record != null) {
-            record.setSplashScreenView(splashScreenView);
-        }
-    }
-
     private void removeWindowNoAnimate(int taskId) {
         removeWindowSynced(taskId, null, null, false);
     }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt
index 35bab7a..fcd333f 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt
@@ -73,7 +73,8 @@
 fun FlickerTestParameter.appPairsPrimaryBoundsIsVisible(rotation: Int, primaryLayerName: String) {
     assertLayersEnd {
         val dividerRegion = entry.getVisibleBounds(APP_PAIR_SPLIT_DIVIDER)
-        this.coversExactly(getPrimaryRegion(dividerRegion, rotation), primaryLayerName)
+        visibleRegion(primaryLayerName)
+            .coversExactly(getPrimaryRegion(dividerRegion, rotation))
     }
 }
 
@@ -83,7 +84,8 @@
 ) {
     assertLayersEnd {
         val dividerRegion = entry.getVisibleBounds(DOCKED_STACK_DIVIDER)
-        this.coversExactly(getPrimaryRegion(dividerRegion, rotation), primaryLayerName)
+        visibleRegion(primaryLayerName)
+            .coversExactly(getPrimaryRegion(dividerRegion, rotation))
     }
 }
 
@@ -93,7 +95,8 @@
 ) {
     assertLayersEnd {
         val dividerRegion = entry.getVisibleBounds(APP_PAIR_SPLIT_DIVIDER)
-        this.coversExactly(getSecondaryRegion(dividerRegion, rotation), secondaryLayerName)
+        visibleRegion(secondaryLayerName)
+            .coversExactly(getSecondaryRegion(dividerRegion, rotation))
     }
 }
 
@@ -103,7 +106,8 @@
 ) {
     assertLayersEnd {
         val dividerRegion = entry.getVisibleBounds(DOCKED_STACK_DIVIDER)
-        this.coversExactly(getSecondaryRegion(dividerRegion, rotation), secondaryLayerName)
+        visibleRegion(secondaryLayerName)
+            .coversExactly(getSecondaryRegion(dividerRegion, rotation))
     }
 }
 
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestPairPrimaryAndSecondaryApps.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestPairPrimaryAndSecondaryApps.kt
index 63e9a78..614530b 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestPairPrimaryAndSecondaryApps.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestPairPrimaryAndSecondaryApps.kt
@@ -82,10 +82,10 @@
     fun appsEndingBounds() {
         testSpec.assertLayersEnd {
             val dividerRegion = entry.getVisibleBounds(APP_PAIR_SPLIT_DIVIDER)
-            this.coversExactly(appPairsHelper.getPrimaryBounds(dividerRegion),
-                primaryApp.defaultWindowName)
-                .coversExactly(appPairsHelper.getSecondaryBounds(dividerRegion),
-                    secondaryApp.defaultWindowName)
+            visibleRegion(primaryApp.defaultWindowName)
+                .coversExactly(appPairsHelper.getPrimaryBounds(dividerRegion))
+            visibleRegion(secondaryApp.defaultWindowName)
+                .coversExactly(appPairsHelper.getSecondaryBounds(dividerRegion))
         }
     }
 
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestUnpairPrimaryAndSecondaryApps.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestUnpairPrimaryAndSecondaryApps.kt
index 234dda4..ef68ed6 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestUnpairPrimaryAndSecondaryApps.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestUnpairPrimaryAndSecondaryApps.kt
@@ -87,10 +87,10 @@
     fun appsStartingBounds() {
         testSpec.assertLayersStart {
             val dividerRegion = entry.getVisibleBounds(APP_PAIR_SPLIT_DIVIDER)
-            coversExactly(appPairsHelper.getPrimaryBounds(dividerRegion),
-                primaryApp.defaultWindowName)
-            coversExactly(appPairsHelper.getSecondaryBounds(dividerRegion),
-                secondaryApp.defaultWindowName)
+            visibleRegion(primaryApp.defaultWindowName)
+                .coversExactly(appPairsHelper.getPrimaryBounds(dividerRegion))
+            visibleRegion(secondaryApp.defaultWindowName)
+                .coversExactly(appPairsHelper.getSecondaryBounds(dividerRegion))
         }
     }
 
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ResizeLegacySplitScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ResizeLegacySplitScreen.kt
index f40a08c..33ade38 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ResizeLegacySplitScreen.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ResizeLegacySplitScreen.kt
@@ -183,8 +183,8 @@
                 dividerBounds.bottom - WindowUtils.dockedStackDividerInset,
                 displayBounds.right,
                 displayBounds.bottom - WindowUtils.navigationBarHeight)
-            this.coversExactly(topAppBounds, "SimpleActivity")
-                .coversExactly(bottomAppBounds, "ImeActivity")
+            visibleRegion("SimpleActivity").coversExactly(topAppBounds)
+            visibleRegion("ImeActivity").coversExactly(bottomAppBounds)
         }
     }
 
@@ -203,8 +203,8 @@
                 displayBounds.right,
                 displayBounds.bottom - WindowUtils.navigationBarHeight)
 
-            this.coversExactly(topAppBounds, sSimpleActivity)
-                .coversExactly(bottomAppBounds, sImeActivity)
+            visibleRegion(sSimpleActivity).coversExactly(topAppBounds)
+            visibleRegion(sImeActivity).coversExactly(bottomAppBounds)
         }
     }
 
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterExitPipTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterExitPipTest.kt
index 0333227..1ba1f3b 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterExitPipTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterExitPipTest.kt
@@ -90,8 +90,8 @@
     @Test
     fun testAppCoversFullScreenWithPipOnDisplay() {
         testSpec.assertLayersStart {
-            coversExactly(displayBounds, testApp.defaultWindowName)
-            coversAtMost(displayBounds, pipApp.defaultWindowName)
+            visibleRegion(testApp.defaultWindowName).coversExactly(displayBounds)
+            visibleRegion(pipApp.defaultWindowName).coversAtMost(displayBounds)
         }
     }
 
@@ -99,7 +99,7 @@
     @Test
     fun pipAppCoversFullScreen() {
         testSpec.assertLayersEnd {
-            coversExactly(displayBounds, pipApp.defaultWindowName)
+            visibleRegion(pipApp.defaultWindowName).coversExactly(displayBounds)
         }
     }
 
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt
index ba88ee5..dd6195c 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt
@@ -116,7 +116,7 @@
     @Test
     fun pipAppLayerHidesTestApp() {
         testSpec.assertLayersStart {
-            coversExactly(startingBounds, pipApp.defaultWindowName)
+            visibleRegion(pipApp.defaultWindowName).coversExactly(startingBounds)
             isInvisible(testApp.defaultWindowName)
         }
     }
@@ -125,7 +125,7 @@
     @Test
     fun testAppLayerCoversFullScreen() {
         testSpec.assertLayersEnd {
-            coversExactly(endingBounds, testApp.defaultWindowName)
+            visibleRegion(testApp.defaultWindowName).coversExactly(endingBounds)
         }
     }
 
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipLegacySplitScreenTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipLegacySplitScreenTest.kt
index bf148bc..6166721 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipLegacySplitScreenTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipLegacySplitScreenTest.kt
@@ -116,8 +116,8 @@
     @Test
     fun bothAppLayersVisible() {
         testSpec.assertLayersEnd {
-            coversAtMost(displayBounds, testApp.defaultWindowName)
-            coversAtMost(displayBounds, imeApp.defaultWindowName)
+            visibleRegion(testApp.defaultWindowName).coversAtMost(displayBounds)
+            visibleRegion(imeApp.defaultWindowName).coversAtMost(displayBounds)
         }
     }
 
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipMovesInAllApps.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipMovesInAllApps.kt
index f554ca3..acc013a 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipMovesInAllApps.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipMovesInAllApps.kt
@@ -63,7 +63,7 @@
     @Test
     fun pipLayerInsideDisplay() {
         testSpec.assertLayersStart {
-            coversAtMost(displayBounds, pipApp.defaultWindowName)
+            visibleRegion(pipApp.defaultWindowName).coversAtMost(displayBounds)
         }
     }
 
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt
index 8ceef8a..852ee47 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt
@@ -26,11 +26,11 @@
 import com.android.server.wm.flicker.endRotation
 import com.android.server.wm.flicker.helpers.WindowUtils
 import com.android.server.wm.flicker.helpers.setRotation
-import com.android.server.wm.flicker.startRotation
-import com.android.wm.shell.flicker.helpers.FixedAppHelper
-import com.android.server.wm.flicker.noUncoveredRegions
 import com.android.server.wm.flicker.navBarLayerRotatesAndScales
+import com.android.server.wm.flicker.noUncoveredRegions
+import com.android.server.wm.flicker.startRotation
 import com.android.server.wm.flicker.statusBarLayerRotatesScales
+import com.android.wm.shell.flicker.helpers.FixedAppHelper
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -91,8 +91,8 @@
     @Test
     fun appLayerRotates_StartingBounds() {
         testSpec.assertLayersStart {
-            coversExactly(startingBounds, fixedApp.defaultWindowName)
-            coversAtMost(startingBounds, pipApp.defaultWindowName)
+            visibleRegion(fixedApp.defaultWindowName).coversExactly(startingBounds)
+            visibleRegion(pipApp.defaultWindowName).coversAtMost(startingBounds)
         }
     }
 
@@ -100,8 +100,8 @@
     @Test
     fun appLayerRotates_EndingBounds() {
         testSpec.assertLayersEnd {
-            coversExactly(endingBounds, fixedApp.defaultWindowName)
-            coversAtMost(endingBounds, pipApp.defaultWindowName)
+            visibleRegion(fixedApp.defaultWindowName).coversExactly(endingBounds)
+            visibleRegion(pipApp.defaultWindowName).coversAtMost(endingBounds)
         }
     }
 
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipToAppTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipToAppTest.kt
index 945a20b..6f17a2c 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipToAppTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipToAppTest.kt
@@ -83,7 +83,7 @@
     @Test
     fun testAppCoversFullScreen() {
         testSpec.assertLayersStart {
-            coversExactly(displayBounds, pipApp.defaultWindowName)
+            visibleRegion(pipApp.defaultWindowName).coversExactly(displayBounds)
         }
     }
 
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 102af92..9aab7f3 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
@@ -91,7 +91,7 @@
     @Test
     fun pipWindowInsideDisplay() {
         testSpec.assertWmStart {
-            coversAtMost(startingBounds, pipApp.defaultWindowName)
+            frameRegion(pipApp.defaultWindowName).coversAtMost(startingBounds)
         }
     }
 
@@ -107,7 +107,7 @@
     @Test
     fun pipLayerInsideDisplay() {
         testSpec.assertLayersStart {
-            coversAtMost(startingBounds, pipApp.defaultWindowName)
+            visibleRegion(pipApp.defaultWindowName).coversAtMost(startingBounds)
         }
     }
 
@@ -121,7 +121,7 @@
     @Test
     fun pipAppLayerCoversFullScreen() {
         testSpec.assertLayersEnd {
-            coversExactly(endingBounds, pipApp.defaultWindowName)
+            visibleRegion(pipApp.defaultWindowName).coversExactly(endingBounds)
         }
     }
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizerTest.java
index d6bcf03..3f47c04 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizerTest.java
@@ -22,6 +22,7 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
 
 import android.testing.AndroidTestingRunner;
@@ -35,6 +36,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.wm.shell.common.DisplayController;
+import com.android.wm.shell.common.DisplayLayout;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -48,7 +50,8 @@
 public class OneHandedBackgroundPanelOrganizerTest extends OneHandedTestCase {
     private DisplayAreaInfo mDisplayAreaInfo;
     private Display mDisplay;
-    private OneHandedBackgroundPanelOrganizer mBackgroundPanelOrganizer;
+    private DisplayLayout mDisplayLayout;
+    private OneHandedBackgroundPanelOrganizer mSpiedBackgroundPanelOrganizer;
     private WindowContainerToken mToken;
     private SurfaceControl mLeash;
     private TestableLooper mTestableLooper;
@@ -65,37 +68,38 @@
         mToken = new WindowContainerToken(mMockRealToken);
         mLeash = new SurfaceControl();
         mDisplay = mContext.getDisplay();
+        mDisplayLayout = new DisplayLayout(mContext, mDisplay);
         when(mMockDisplayController.getDisplay(anyInt())).thenReturn(mDisplay);
         mDisplayAreaInfo = new DisplayAreaInfo(mToken, DEFAULT_DISPLAY,
                 FEATURE_ONE_HANDED_BACKGROUND_PANEL);
 
-        mBackgroundPanelOrganizer = new OneHandedBackgroundPanelOrganizer(mContext, mWindowManager,
-                mMockDisplayController, Runnable::run);
+        mSpiedBackgroundPanelOrganizer = spy(
+                new OneHandedBackgroundPanelOrganizer(mContext, mDisplayLayout, Runnable::run));
     }
 
     @Test
     public void testOnDisplayAreaAppeared() {
-        mBackgroundPanelOrganizer.onDisplayAreaAppeared(mDisplayAreaInfo, mLeash);
+        mSpiedBackgroundPanelOrganizer.onDisplayAreaAppeared(mDisplayAreaInfo, mLeash);
         mTestableLooper.processAllMessages();
 
-        assertThat(mBackgroundPanelOrganizer.getBackgroundSurface()).isNotNull();
+        assertThat(mSpiedBackgroundPanelOrganizer.getBackgroundSurface()).isNotNull();
     }
 
     @Test
     public void testShowBackgroundLayer() {
-        mBackgroundPanelOrganizer.onDisplayAreaAppeared(mDisplayAreaInfo, mLeash);
-        mBackgroundPanelOrganizer.showBackgroundPanelLayer();
+        mSpiedBackgroundPanelOrganizer.onDisplayAreaAppeared(mDisplayAreaInfo, mLeash);
+        mSpiedBackgroundPanelOrganizer.showBackgroundPanelLayer();
         mTestableLooper.processAllMessages();
 
-        assertThat(mBackgroundPanelOrganizer.mIsShowing).isTrue();
+        assertThat(mSpiedBackgroundPanelOrganizer.mIsShowing).isTrue();
     }
 
     @Test
     public void testRemoveBackgroundLayer() {
-        mBackgroundPanelOrganizer.onDisplayAreaAppeared(mDisplayAreaInfo, mLeash);
-        mBackgroundPanelOrganizer.removeBackgroundPanelLayer();
+        mSpiedBackgroundPanelOrganizer.onDisplayAreaAppeared(mDisplayAreaInfo, mLeash);
+        mSpiedBackgroundPanelOrganizer.removeBackgroundPanelLayer();
         mTestableLooper.processAllMessages();
 
-        assertThat(mBackgroundPanelOrganizer.mIsShowing).isFalse();
+        assertThat(mSpiedBackgroundPanelOrganizer.mIsShowing).isFalse();
     }
 }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java
index bd5fe2b..b0fc4c1 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java
@@ -23,20 +23,24 @@
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.content.om.IOverlayManager;
+import android.graphics.Rect;
 import android.os.Handler;
 import android.testing.AndroidTestingRunner;
 import android.util.ArrayMap;
 import android.view.Display;
+import android.view.Surface;
 import android.view.SurfaceControl;
 
 import androidx.test.filters.SmallTest;
 
 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.TaskStackListenerImpl;
 
@@ -50,6 +54,7 @@
 @RunWith(AndroidTestingRunner.class)
 public class OneHandedControllerTest extends OneHandedTestCase {
     Display mDisplay;
+    DisplayLayout mDisplayLayout;
     OneHandedController mSpiedOneHandedController;
     OneHandedTimeoutHandler mSpiedTimeoutHandler;
 
@@ -88,6 +93,7 @@
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         mDisplay = mContext.getDisplay();
+        mDisplayLayout = new DisplayLayout(mContext, mDisplay);
         mSpiedTimeoutHandler = spy(new OneHandedTimeoutHandler(mMockShellMainExecutor));
 
         when(mMockDisplayController.getDisplay(anyInt())).thenReturn(mDisplay);
@@ -103,9 +109,12 @@
         when(mMockSettingsUitl.getSettingsSwipeToNotificationEnabled(any())).thenReturn(
                 mDefaultSwipeToNotificationEnabled);
 
+        when(mMockDisplayAreaOrganizer.getLastDisplayBounds()).thenReturn(
+                new Rect(0, 0, mDisplayLayout.width(), mDisplayLayout.height()));
+        when(mMockDisplayAreaOrganizer.getDisplayLayout()).thenReturn(mDisplayLayout);
+
         mSpiedOneHandedController = spy(new OneHandedController(
                 mContext,
-                mWindowManager,
                 mMockDisplayController,
                 mMockBackgroundOrganizer,
                 mMockDisplayAreaOrganizer,
@@ -127,7 +136,7 @@
         final OneHandedAnimationController animationController = new OneHandedAnimationController(
                 mContext);
         OneHandedDisplayAreaOrganizer displayAreaOrganizer = new OneHandedDisplayAreaOrganizer(
-                mContext, mWindowManager, animationController, mMockTutorialHandler,
+                mContext, mDisplayLayout, animationController, mMockTutorialHandler,
                 mMockBackgroundOrganizer, mMockShellMainExecutor);
 
         assertThat(displayAreaOrganizer.isInOneHanded()).isFalse();
@@ -188,7 +197,7 @@
         mSpiedOneHandedController.setOneHandedEnabled(true);
 
         verify(mMockTouchHandler, atLeastOnce()).onOneHandedEnabled(anyBoolean());
-        verify(mMockGestureHandler, atLeastOnce()).onOneHandedEnabled(anyBoolean());
+        verify(mMockGestureHandler, atLeastOnce()).onGestureEnabled(anyBoolean());
     }
 
     @Test
@@ -196,7 +205,7 @@
         mSpiedOneHandedController.setSwipeToNotificationEnabled(mDefaultSwipeToNotificationEnabled);
 
         verify(mMockTouchHandler, atLeastOnce()).onOneHandedEnabled(anyBoolean());
-        verify(mMockGestureHandler, atLeastOnce()).onOneHandedEnabled(anyBoolean());
+        verify(mMockGestureHandler, atLeastOnce()).onGestureEnabled(anyBoolean());
     }
 
     @Test
@@ -282,4 +291,67 @@
 
         verify(mMockDisplayAreaOrganizer).scheduleOffset(anyInt(), anyInt());
     }
+
+    @Test
+    public void testRotation90CanNotStartOneHanded() {
+        final DisplayLayout landscapeDisplayLayout = new DisplayLayout(mDisplayLayout);
+        landscapeDisplayLayout.rotateTo(mContext.getResources(), Surface.ROTATION_90);
+        when(mMockDisplayAreaOrganizer.isInOneHanded()).thenReturn(false);
+        when(mMockDisplayAreaOrganizer.getDisplayLayout()).thenReturn(landscapeDisplayLayout);
+        mSpiedOneHandedController.setOneHandedEnabled(true);
+        mSpiedOneHandedController.setLockedDisabled(false /* locked */, false /* enabled */);
+        mSpiedOneHandedController.startOneHanded();
+
+        verify(mMockDisplayAreaOrganizer, never()).scheduleOffset(anyInt(), anyInt());
+    }
+
+    @Test
+    public void testRotation180CanStartOneHanded() {
+        final DisplayLayout testDisplayLayout = new DisplayLayout(mDisplayLayout);
+        testDisplayLayout.rotateTo(mContext.getResources(), Surface.ROTATION_180);
+        when(mMockDisplayAreaOrganizer.isInOneHanded()).thenReturn(false);
+        when(mMockDisplayAreaOrganizer.getDisplayLayout()).thenReturn(testDisplayLayout);
+        mSpiedOneHandedController.setOneHandedEnabled(true);
+        mSpiedOneHandedController.setLockedDisabled(false /* locked */, false /* enabled */);
+        mSpiedOneHandedController.startOneHanded();
+
+        verify(mMockDisplayAreaOrganizer).scheduleOffset(anyInt(), anyInt());
+    }
+
+    @Test
+    public void testRotation270CanNotStartOneHanded() {
+        final DisplayLayout testDisplayLayout = new DisplayLayout(mDisplayLayout);
+        testDisplayLayout.rotateTo(mContext.getResources(), Surface.ROTATION_270);
+        when(mMockDisplayAreaOrganizer.isInOneHanded()).thenReturn(false);
+        when(mMockDisplayAreaOrganizer.getDisplayLayout()).thenReturn(testDisplayLayout);
+        mSpiedOneHandedController.setOneHandedEnabled(true);
+        mSpiedOneHandedController.setLockedDisabled(false /* locked */, false /* enabled */);
+        mSpiedOneHandedController.startOneHanded();
+
+        verify(mMockDisplayAreaOrganizer, never()).scheduleOffset(anyInt(), anyInt());
+    }
+
+    @Test
+    public void testDisabled3ButtonGestureWhenKeyguardOn() {
+        final boolean isOneHandedEnabled = true;
+        final boolean isLockWhenKeyguardOn = true;
+        final boolean isEnabledWhenKeyguardOn = false;
+        mSpiedOneHandedController.setOneHandedEnabled(isOneHandedEnabled);
+        mSpiedOneHandedController.setLockedDisabled(isLockWhenKeyguardOn, isEnabledWhenKeyguardOn);
+
+        verify(mMockGestureHandler).onGestureEnabled(isEnabledWhenKeyguardOn);
+    }
+
+    @Test
+    public void testEnabled3ButtonGestureWhenKeyguardGoingAway() {
+        final boolean isOneHandedEnabled = true;
+        final boolean isLockWhenKeyguardOn = false;
+        final boolean isEnabledWhenKeyguardOn = false;
+        mSpiedOneHandedController.setOneHandedEnabled(isOneHandedEnabled);
+        reset(mMockGestureHandler);
+
+        mSpiedOneHandedController.setLockedDisabled(isLockWhenKeyguardOn, isEnabledWhenKeyguardOn);
+
+        verify(mMockGestureHandler).onGestureEnabled(isOneHandedEnabled);
+    }
 }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizerTest.java
index f897b09..f654bb5 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizerTest.java
@@ -19,6 +19,9 @@
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.window.DisplayAreaOrganizer.FEATURE_ONE_HANDED;
 
+import static com.android.wm.shell.onehanded.OneHandedAnimationController.TRANSITION_DIRECTION_EXIT;
+import static com.android.wm.shell.onehanded.OneHandedAnimationController.TRANSITION_DIRECTION_TRIGGER;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.anyFloat;
@@ -32,6 +35,7 @@
 import static org.mockito.Mockito.when;
 
 import android.content.res.Configuration;
+import android.graphics.Rect;
 import android.os.Binder;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
@@ -47,6 +51,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.wm.shell.common.DisplayController;
+import com.android.wm.shell.common.DisplayLayout;
 import com.android.wm.shell.common.ShellExecutor;
 
 import org.junit.Before;
@@ -67,6 +72,7 @@
 
     DisplayAreaInfo mDisplayAreaInfo;
     Display mDisplay;
+    DisplayLayout mDisplayLayout;
     OneHandedDisplayAreaOrganizer mSpiedDisplayAreaOrganizer;
     OneHandedTutorialHandler mTutorialHandler;
     OneHandedAnimationController.OneHandedTransitionAnimator mFakeAnimator;
@@ -103,6 +109,7 @@
         mToken = new WindowContainerToken(mMockRealToken);
         mLeash = new SurfaceControl();
         mDisplay = mContext.getDisplay();
+        mDisplayLayout = new DisplayLayout(mContext, mDisplay);
         mDisplayAreaInfo = new DisplayAreaInfo(mToken, DEFAULT_DISPLAY, FEATURE_ONE_HANDED);
         mDisplayAreaInfo.configuration.orientation = Configuration.ORIENTATION_PORTRAIT;
         when(mMockAnimationController.getAnimator(any(), any(), any(), any())).thenReturn(null);
@@ -121,7 +128,7 @@
         when(mMockLeash.getHeight()).thenReturn(DISPLAY_HEIGHT);
 
         mSpiedDisplayAreaOrganizer = spy(new OneHandedDisplayAreaOrganizer(mContext,
-                mWindowManager,
+                mDisplayLayout,
                 mMockAnimationController,
                 mTutorialHandler,
                 mMockBackgroundOrganizer,
@@ -169,20 +176,13 @@
     }
 
     @Test
-    public void testRotation_getNewDisplayBounds() {
-        when(mMockLeash.isValid()).thenReturn(false);
-        // Rotate 0 -> 90
-        mSpiedDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_0, Surface.ROTATION_90,
-                mMockWindowContainerTransaction);
-        verify(mSpiedDisplayAreaOrganizer).getDisplayBounds();
-    }
-
-    @Test
     public void testRotation_portrait_0_to_landscape_90() {
         when(mMockLeash.isValid()).thenReturn(false);
         // Rotate 0 -> 90
-        mSpiedDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_0, Surface.ROTATION_90,
+        mSpiedDisplayAreaOrganizer.onRotateDisplay(mContext, Surface.ROTATION_90,
                 mMockWindowContainerTransaction);
+
+        verify(mSpiedDisplayAreaOrganizer).resetWindowsOffset(mMockWindowContainerTransaction);
         verify(mSpiedDisplayAreaOrganizer).finishOffset(anyInt(), anyInt());
     }
 
@@ -190,8 +190,10 @@
     public void testRotation_portrait_0_to_seascape_270() {
         when(mMockLeash.isValid()).thenReturn(false);
         // Rotate 0 -> 270
-        mSpiedDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_0, Surface.ROTATION_270,
+        mSpiedDisplayAreaOrganizer.onRotateDisplay(mContext, Surface.ROTATION_270,
                 mMockWindowContainerTransaction);
+
+        verify(mSpiedDisplayAreaOrganizer).resetWindowsOffset(mMockWindowContainerTransaction);
         verify(mSpiedDisplayAreaOrganizer).finishOffset(anyInt(), anyInt());
     }
 
@@ -199,8 +201,12 @@
     public void testRotation_portrait_180_to_landscape_90() {
         when(mMockLeash.isValid()).thenReturn(false);
         // Rotate 180 -> 90
-        mSpiedDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_180, Surface.ROTATION_90,
+        mDisplayLayout.rotateTo(mContext.getResources(), Surface.ROTATION_180);
+        mSpiedDisplayAreaOrganizer.setDisplayLayout(mDisplayLayout);
+        mSpiedDisplayAreaOrganizer.onRotateDisplay(mContext, Surface.ROTATION_90,
                 mMockWindowContainerTransaction);
+
+        verify(mSpiedDisplayAreaOrganizer).resetWindowsOffset(mMockWindowContainerTransaction);
         verify(mSpiedDisplayAreaOrganizer).finishOffset(anyInt(), anyInt());
     }
 
@@ -208,8 +214,12 @@
     public void testRotation_portrait_180_to_seascape_270() {
         when(mMockLeash.isValid()).thenReturn(false);
         // Rotate 180 -> 270
-        mSpiedDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_180, Surface.ROTATION_270,
+        mDisplayLayout.rotateTo(mContext.getResources(), Surface.ROTATION_180);
+        mSpiedDisplayAreaOrganizer.setDisplayLayout(mDisplayLayout);
+        mSpiedDisplayAreaOrganizer.onRotateDisplay(mContext, Surface.ROTATION_270,
                 mMockWindowContainerTransaction);
+
+        verify(mSpiedDisplayAreaOrganizer).resetWindowsOffset(mMockWindowContainerTransaction);
         verify(mSpiedDisplayAreaOrganizer).finishOffset(anyInt(), anyInt());
     }
 
@@ -217,8 +227,12 @@
     public void testRotation_landscape_90_to_portrait_0() {
         when(mMockLeash.isValid()).thenReturn(false);
         // Rotate 90 -> 0
-        mSpiedDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_90, Surface.ROTATION_0,
+        mDisplayLayout.rotateTo(mContext.getResources(), Surface.ROTATION_90);
+        mSpiedDisplayAreaOrganizer.setDisplayLayout(mDisplayLayout);
+        mSpiedDisplayAreaOrganizer.onRotateDisplay(mContext, Surface.ROTATION_0,
                 mMockWindowContainerTransaction);
+
+        verify(mSpiedDisplayAreaOrganizer).resetWindowsOffset(mMockWindowContainerTransaction);
         verify(mSpiedDisplayAreaOrganizer).finishOffset(anyInt(), anyInt());
     }
 
@@ -226,26 +240,38 @@
     public void testRotation_landscape_90_to_portrait_180() {
         when(mMockLeash.isValid()).thenReturn(false);
         // Rotate 90 -> 180
-        mSpiedDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_90, Surface.ROTATION_180,
+        mDisplayLayout.rotateTo(mContext.getResources(), Surface.ROTATION_90);
+        mSpiedDisplayAreaOrganizer.setDisplayLayout(mDisplayLayout);
+        mSpiedDisplayAreaOrganizer.onRotateDisplay(mContext, Surface.ROTATION_180,
                 mMockWindowContainerTransaction);
+
+        verify(mSpiedDisplayAreaOrganizer).resetWindowsOffset(mMockWindowContainerTransaction);
         verify(mSpiedDisplayAreaOrganizer).finishOffset(anyInt(), anyInt());
     }
 
     @Test
-    public void testRotation_Seascape_270_to_portrait_0() {
+    public void testRotation_seascape_270_to_portrait_0() {
         when(mMockLeash.isValid()).thenReturn(false);
         // Rotate 270 -> 0
-        mSpiedDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_270, Surface.ROTATION_0,
+        mDisplayLayout.rotateTo(mContext.getResources(), Surface.ROTATION_270);
+        mSpiedDisplayAreaOrganizer.setDisplayLayout(mDisplayLayout);
+        mSpiedDisplayAreaOrganizer.onRotateDisplay(mContext, Surface.ROTATION_0,
                 mMockWindowContainerTransaction);
+
+        verify(mSpiedDisplayAreaOrganizer).resetWindowsOffset(mMockWindowContainerTransaction);
         verify(mSpiedDisplayAreaOrganizer).finishOffset(anyInt(), anyInt());
     }
 
     @Test
-    public void testRotation_seascape_90_to_portrait_180() {
+    public void testRotation_seascape_270_to_portrait_180() {
         when(mMockLeash.isValid()).thenReturn(false);
         // Rotate 270 -> 180
-        mSpiedDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_270, Surface.ROTATION_180,
+        mDisplayLayout.rotateTo(mContext.getResources(), Surface.ROTATION_270);
+        mSpiedDisplayAreaOrganizer.setDisplayLayout(mDisplayLayout);
+        mSpiedDisplayAreaOrganizer.onRotateDisplay(mContext, Surface.ROTATION_180,
                 mMockWindowContainerTransaction);
+
+        verify(mSpiedDisplayAreaOrganizer).resetWindowsOffset(mMockWindowContainerTransaction);
         verify(mSpiedDisplayAreaOrganizer).finishOffset(anyInt(), anyInt());
     }
 
@@ -253,7 +279,10 @@
     public void testRotation_portrait_0_to_portrait_0() {
         when(mMockLeash.isValid()).thenReturn(false);
         // Rotate 0 -> 0
-        mSpiedDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_0, Surface.ROTATION_0,
+        mSpiedDisplayAreaOrganizer.onRotateDisplay(mContext, Surface.ROTATION_0,
+                mMockWindowContainerTransaction);
+
+        verify(mSpiedDisplayAreaOrganizer, never()).resetWindowsOffset(
                 mMockWindowContainerTransaction);
         verify(mSpiedDisplayAreaOrganizer, never()).finishOffset(anyInt(), anyInt());
     }
@@ -262,16 +291,23 @@
     public void testRotation_portrait_0_to_portrait_180() {
         when(mMockLeash.isValid()).thenReturn(false);
         // Rotate 0 -> 180
-        mSpiedDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_0, Surface.ROTATION_180,
+        mSpiedDisplayAreaOrganizer.onRotateDisplay(mContext, Surface.ROTATION_180,
                 mMockWindowContainerTransaction);
-        verify(mSpiedDisplayAreaOrganizer, never()).finishOffset(anyInt(), anyInt());
+
+        verify(mSpiedDisplayAreaOrganizer).resetWindowsOffset(mMockWindowContainerTransaction);
+        verify(mSpiedDisplayAreaOrganizer).finishOffset(anyInt(), anyInt());
     }
 
     @Test
     public void testRotation_portrait_180_to_portrait_180() {
         when(mMockLeash.isValid()).thenReturn(false);
         // Rotate 180 -> 180
-        mSpiedDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_180, Surface.ROTATION_180,
+        mDisplayLayout.rotateTo(mContext.getResources(), Surface.ROTATION_180);
+        mSpiedDisplayAreaOrganizer.setDisplayLayout(mDisplayLayout);
+        mSpiedDisplayAreaOrganizer.onRotateDisplay(mContext, Surface.ROTATION_180,
+                mMockWindowContainerTransaction);
+
+        verify(mSpiedDisplayAreaOrganizer, never()).resetWindowsOffset(
                 mMockWindowContainerTransaction);
         verify(mSpiedDisplayAreaOrganizer, never()).finishOffset(anyInt(), anyInt());
     }
@@ -280,16 +316,25 @@
     public void testRotation_portrait_180_to_portrait_0() {
         when(mMockLeash.isValid()).thenReturn(false);
         // Rotate 180 -> 0
-        mSpiedDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_180, Surface.ROTATION_0,
+        mDisplayLayout.rotateTo(mContext.getResources(), Surface.ROTATION_90);
+        mSpiedDisplayAreaOrganizer.setDisplayLayout(mDisplayLayout);
+        mSpiedDisplayAreaOrganizer.onRotateDisplay(mContext, Surface.ROTATION_0,
                 mMockWindowContainerTransaction);
-        verify(mSpiedDisplayAreaOrganizer, never()).finishOffset(anyInt(), anyInt());
+
+        verify(mSpiedDisplayAreaOrganizer).resetWindowsOffset(mMockWindowContainerTransaction);
+        verify(mSpiedDisplayAreaOrganizer).finishOffset(anyInt(), anyInt());
     }
 
     @Test
     public void testRotation_landscape_90_to_landscape_90() {
         when(mMockLeash.isValid()).thenReturn(false);
         // Rotate 90 -> 90
-        mSpiedDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_90, Surface.ROTATION_90,
+        mDisplayLayout.rotateTo(mContext.getResources(), Surface.ROTATION_90);
+        mSpiedDisplayAreaOrganizer.setDisplayLayout(mDisplayLayout);
+        mSpiedDisplayAreaOrganizer.onRotateDisplay(mContext, Surface.ROTATION_90,
+                mMockWindowContainerTransaction);
+
+        verify(mSpiedDisplayAreaOrganizer, never()).resetWindowsOffset(
                 mMockWindowContainerTransaction);
         verify(mSpiedDisplayAreaOrganizer, never()).finishOffset(anyInt(), anyInt());
     }
@@ -298,26 +343,60 @@
     public void testRotation_landscape_90_to_seascape_270() {
         when(mMockLeash.isValid()).thenReturn(false);
         // Rotate 90 -> 270
-        mSpiedDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_90, Surface.ROTATION_270,
+        mDisplayLayout.rotateTo(mContext.getResources(), Surface.ROTATION_90);
+        mSpiedDisplayAreaOrganizer.setDisplayLayout(mDisplayLayout);
+        mSpiedDisplayAreaOrganizer.onRotateDisplay(mContext, Surface.ROTATION_270,
                 mMockWindowContainerTransaction);
-        verify(mSpiedDisplayAreaOrganizer, never()).finishOffset(anyInt(), anyInt());
+
+        verify(mSpiedDisplayAreaOrganizer).resetWindowsOffset(mMockWindowContainerTransaction);
+        verify(mSpiedDisplayAreaOrganizer).finishOffset(anyInt(), anyInt());
     }
 
     @Test
     public void testRotation_seascape_270_to_seascape_270() {
         when(mMockLeash.isValid()).thenReturn(false);
         // Rotate 270 -> 270
-        mSpiedDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_270, Surface.ROTATION_270,
+        mDisplayLayout.rotateTo(mContext.getResources(), Surface.ROTATION_270);
+        mSpiedDisplayAreaOrganizer.setDisplayLayout(mDisplayLayout);
+        mSpiedDisplayAreaOrganizer.onRotateDisplay(mContext, Surface.ROTATION_270,
+                mMockWindowContainerTransaction);
+
+        verify(mSpiedDisplayAreaOrganizer, never()).resetWindowsOffset(
                 mMockWindowContainerTransaction);
         verify(mSpiedDisplayAreaOrganizer, never()).finishOffset(anyInt(), anyInt());
     }
 
     @Test
-    public void testRotation_seascape_90_to_landscape_90() {
+    public void testRotation_seascape_270_to_landscape_90() {
         when(mMockLeash.isValid()).thenReturn(false);
         // Rotate 270 -> 90
-        mSpiedDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_270, Surface.ROTATION_90,
+        mDisplayLayout.rotateTo(mContext.getResources(), Surface.ROTATION_270);
+        mSpiedDisplayAreaOrganizer.setDisplayLayout(mDisplayLayout);
+        mSpiedDisplayAreaOrganizer.onRotateDisplay(mContext, Surface.ROTATION_90,
                 mMockWindowContainerTransaction);
-        verify(mSpiedDisplayAreaOrganizer, never()).finishOffset(anyInt(), anyInt());
+
+        verify(mSpiedDisplayAreaOrganizer).resetWindowsOffset(
+                mMockWindowContainerTransaction);
+        verify(mSpiedDisplayAreaOrganizer).finishOffset(anyInt(), anyInt());
+    }
+
+    @Test
+    public void testTriggerOffset() {
+        final Rect testBounds = mSpiedDisplayAreaOrganizer.getLastDisplayBounds();
+        final int offset = 100;
+        testBounds.offsetTo(0, offset);
+        mSpiedDisplayAreaOrganizer.finishOffset(offset, TRANSITION_DIRECTION_TRIGGER);
+
+        assertThat(mSpiedDisplayAreaOrganizer.getLastDisplayBounds()).isEqualTo(testBounds);
+    }
+
+    @Test
+    public void testExitOffsetToZero() {
+        final Rect testBounds = mSpiedDisplayAreaOrganizer.getLastDisplayBounds();
+        final int offset = 100;
+        mSpiedDisplayAreaOrganizer.finishOffset(offset, TRANSITION_DIRECTION_TRIGGER);
+        mSpiedDisplayAreaOrganizer.finishOffset(0, TRANSITION_DIRECTION_EXIT);
+
+        assertThat(mSpiedDisplayAreaOrganizer.getLastDisplayBounds()).isEqualTo(testBounds);
     }
 }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedGestureHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedGestureHandlerTest.java
index f683e4a..5d82a70 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedGestureHandlerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedGestureHandlerTest.java
@@ -16,21 +16,19 @@
 
 package com.android.wm.shell.onehanded;
 
-import static android.view.Display.DEFAULT_DISPLAY;
-
 import static com.google.common.truth.Truth.assertThat;
 
-import static org.mockito.ArgumentMatchers.anyInt;
+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.testing.AndroidTestingRunner;
 import android.view.Surface;
 import android.view.ViewConfiguration;
-import android.window.WindowContainerTransaction;
 
 import androidx.test.filters.SmallTest;
 
-import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.common.DisplayLayout;
 import com.android.wm.shell.common.ShellExecutor;
 
@@ -44,24 +42,20 @@
 @RunWith(AndroidTestingRunner.class)
 public class OneHandedGestureHandlerTest extends OneHandedTestCase {
     OneHandedGestureHandler mGestureHandler;
-    @Mock
-    DisplayController mMockDisplayController;
+    DisplayLayout mDisplayLayout;
     @Mock
     DisplayLayout mMockDisplayLayout;
     @Mock
     ShellExecutor mMockShellMainExecutor;
-    @Mock
-    WindowContainerTransaction mMockWct;
 
     @Before
     public void setUp() {
         final int mockNavBarHeight = 100;
         MockitoAnnotations.initMocks(this);
-        mGestureHandler = new OneHandedGestureHandler(mContext, mWindowManager,
-                mMockDisplayController, ViewConfiguration.get(mTestContext),
-                mMockShellMainExecutor);
+        mDisplayLayout = new DisplayLayout(mContext, mContext.getDisplay());
+        mGestureHandler = new OneHandedGestureHandler(mContext, mDisplayLayout,
+                ViewConfiguration.get(mTestContext), mMockShellMainExecutor);
         when(mMockDisplayLayout.navBarFrameHeight()).thenReturn(mockNavBarHeight);
-        when(mMockDisplayController.getDisplayLayout(anyInt())).thenReturn(mMockDisplayLayout);
     }
 
     @Test
@@ -81,7 +75,7 @@
 
     @Test
     public void testOneHandedDisabled_shouldDisposeInputChannel() {
-        mGestureHandler.onOneHandedEnabled(false);
+        mGestureHandler.onGestureEnabled(false);
 
         assertThat(mGestureHandler.mInputMonitor).isNull();
         assertThat(mGestureHandler.mInputEventReceiver).isNull();
@@ -89,7 +83,7 @@
 
     @Test
     public void testChangeNavBarToNon3Button_shouldDisposeInputChannel() {
-        mGestureHandler.onOneHandedEnabled(true);
+        mGestureHandler.onGestureEnabled(true);
         mGestureHandler.onThreeButtonModeEnabled(false);
 
         assertThat(mGestureHandler.mInputMonitor).isNull();
@@ -98,11 +92,38 @@
 
     @Test
     public void testOnlyHandleGestureInPortraitMode() {
-        mGestureHandler.onOneHandedEnabled(true);
-        mGestureHandler.onRotateDisplay(DEFAULT_DISPLAY, Surface.ROTATION_0, Surface.ROTATION_90,
-                mMockWct);
+        mDisplayLayout.rotateTo(mContext.getResources(), Surface.ROTATION_90);
+        mGestureHandler.onGestureEnabled(true);
+        mGestureHandler.onRotateDisplay(mDisplayLayout);
 
         assertThat(mGestureHandler.mInputMonitor).isNull();
         assertThat(mGestureHandler.mInputEventReceiver).isNull();
     }
+
+    @Test
+    public void testRotation90ShouldNotRegisterEventReceiver() throws InterruptedException {
+        mDisplayLayout.rotateTo(mContext.getResources(), Surface.ROTATION_90);
+        mGestureHandler.onGestureEnabled(true);
+        mGestureHandler.onRotateDisplay(mDisplayLayout);
+
+        verify(mMockShellMainExecutor, never()).executeBlocking(any());
+    }
+
+    @Test
+    public void testRotation180ShouldNotRegisterEventReceiver() throws InterruptedException {
+        mDisplayLayout.rotateTo(mContext.getResources(), Surface.ROTATION_180);
+        mGestureHandler.onGestureEnabled(true);
+        mGestureHandler.onRotateDisplay(mDisplayLayout);
+
+        verify(mMockShellMainExecutor, never()).executeBlocking(any());
+    }
+
+    @Test
+    public void testRotation270ShouldNotRegisterEventReceiver() throws InterruptedException {
+        mDisplayLayout.rotateTo(mContext.getResources(), Surface.ROTATION_270);
+        mGestureHandler.onGestureEnabled(true);
+        mGestureHandler.onRotateDisplay(mDisplayLayout);
+
+        verify(mMockShellMainExecutor, never()).executeBlocking(any());
+    }
 }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTutorialHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTutorialHandlerTest.java
index f586dda..2886bb1 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTutorialHandlerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTutorialHandlerTest.java
@@ -75,7 +75,6 @@
         when(mMockDisplayAreaOrganizer.getDisplayAreaTokenMap()).thenReturn(new ArrayMap<>());
         mOneHandedController = new OneHandedController(
                 mContext,
-                mWindowManager,
                 mMockDisplayController,
                 mMockBackgroundOrganizer,
                 mMockDisplayAreaOrganizer,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java
index 207db9e..78b3d4e 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java
@@ -83,12 +83,11 @@
         }
 
         @Override
-        protected boolean postAddWindow(int taskId, IBinder appToken,
+        protected void postAddWindow(int taskId, IBinder appToken,
                 View view, WindowManager wm, WindowManager.LayoutParams params) {
             // listen for addView
             mAddWindowForTask = taskId;
             mViewThemeResId = view.getContext().getThemeResId();
-            return true;
         }
 
         @Override
@@ -113,7 +112,8 @@
         spyOn(context);
         spyOn(realWindowManager);
         try {
-            doReturn(context).when(context).createPackageContext(anyString(), anyInt());
+            doReturn(context).when(context)
+                    .createPackageContextAsUser(anyString(), anyInt(), any());
         } catch (PackageManager.NameNotFoundException e) {
             //
         }
diff --git a/libs/androidfw/include/androidfw/ResourceTypes.h b/libs/androidfw/include/androidfw/ResourceTypes.h
index 168a863..1e90b7c 100644
--- a/libs/androidfw/include/androidfw/ResourceTypes.h
+++ b/libs/androidfw/include/androidfw/ResourceTypes.h
@@ -1379,6 +1379,11 @@
     enum : uint32_t {
         // Additional flag indicating an entry is public.
         SPEC_PUBLIC = 0x40000000u,
+
+        // Additional flag indicating the resource id for this resource may change in a future
+        // build. If this flag is set, the SPEC_PUBLIC flag is also set since the resource must be
+        // public to be exposed as an API to other applications.
+        SPEC_STAGED_API = 0x20000000u,
     };
 };
 
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index 42aa87b..ea9cbd5 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -162,6 +162,12 @@
  */
 #define PROPERTY_IS_EMULATOR "ro.boot.qemu"
 
+/**
+ * Turns on the Skia GPU option "reduceOpsTaskSplitting" which improves GPU
+ * efficiency but may increase VRAM consumption. Default is "false".
+ */
+#define PROPERTY_REDUCE_OPS_TASK_SPLITTING "renderthread.skia.reduceopstasksplitting"
+
 ///////////////////////////////////////////////////////////////////////////////
 // Misc
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/Readback.cpp b/libs/hwui/Readback.cpp
index b71bb07..1455269 100644
--- a/libs/hwui/Readback.cpp
+++ b/libs/hwui/Readback.cpp
@@ -120,12 +120,6 @@
     int imgHeight = image->height();
     sk_sp<GrDirectContext> grContext = sk_ref_sp(mRenderThread.getGrContext());
 
-    if (bitmap->colorType() == kRGBA_F16_SkColorType &&
-        !grContext->colorTypeSupportedAsSurface(bitmap->colorType())) {
-        ALOGW("Can't copy surface into bitmap, RGBA_F16 config is not supported");
-        return CopyResult::DestinationInvalid;
-    }
-
     CopyResult copyResult = CopyResult::UnknownError;
 
     int displayedWidth = imgWidth, displayedHeight = imgHeight;
@@ -159,12 +153,10 @@
 
 bool Readback::copyLayerInto(Layer* layer, const SkRect* srcRect, const SkRect* dstRect,
                              SkBitmap* bitmap) {
-    /* This intermediate surface is present to work around a bug in SwiftShader that
-     * prevents us from reading the contents of the layer's texture directly. The
-     * workaround involves first rendering that texture into an intermediate buffer and
-     * then reading from the intermediate buffer into the bitmap.
-     * Another reason to render in an offscreen buffer is to scale and to avoid an issue b/62262733
-     * with reading incorrect data from EGLImage backed SkImage (likely a driver bug).
+    /* This intermediate surface is present to work around limitations that LayerDrawable expects
+     * to render into a GPU backed canvas.  Additionally, the offscreen buffer solution works around
+     * a scaling issue (b/62262733) that was encountered when sampling from an EGLImage into a
+     * software buffer.
      */
     sk_sp<SkSurface> tmpSurface = SkSurface::MakeRenderTarget(mRenderThread.getGrContext(),
                                                               SkBudgeted::kYes, bitmap->info(), 0,
diff --git a/libs/hwui/hwui/ImageDecoder.cpp b/libs/hwui/hwui/ImageDecoder.cpp
index ade63e5..5d9fad5 100644
--- a/libs/hwui/hwui/ImageDecoder.cpp
+++ b/libs/hwui/hwui/ImageDecoder.cpp
@@ -45,7 +45,8 @@
     return SkColorSpace::MakeSRGB();
 }
 
-ImageDecoder::ImageDecoder(std::unique_ptr<SkAndroidCodec> codec, sk_sp<SkPngChunkReader> peeker)
+ImageDecoder::ImageDecoder(std::unique_ptr<SkAndroidCodec> codec, sk_sp<SkPngChunkReader> peeker,
+                           SkCodec::ZeroInitialized zeroInit)
     : mCodec(std::move(codec))
     , mPeeker(std::move(peeker))
     , mDecodeSize(mCodec->codec()->dimensions())
@@ -57,6 +58,7 @@
     mTargetSize = swapWidthHeight() ? SkISize { mDecodeSize.height(), mDecodeSize.width() }
                                     : mDecodeSize;
     this->rewind();
+    mOptions.fZeroInitialized = zeroInit;
 }
 
 ImageDecoder::~ImageDecoder() = default;
@@ -446,10 +448,17 @@
                 ALOGE("Failed to invert matrix!");
             }
         }
+
+        // Even if the client did not provide zero initialized memory, the
+        // memory we decode into is.
+        mOptions.fZeroInitialized = SkCodec::kYes_ZeroInitialized;
     }
 
     auto result = mCodec->getAndroidPixels(decodeInfo, decodePixels, decodeRowBytes, &mOptions);
 
+    // The next call to decode() may not provide zero initialized memory.
+    mOptions.fZeroInitialized = SkCodec::kNo_ZeroInitialized;
+
     if (scale || handleOrigin || mCropRect) {
         SkBitmap scaledBm;
         if (!scaledBm.installPixels(outputInfo, pixels, rowBytes)) {
diff --git a/libs/hwui/hwui/ImageDecoder.h b/libs/hwui/hwui/ImageDecoder.h
index cbfffd5..cef2233 100644
--- a/libs/hwui/hwui/ImageDecoder.h
+++ b/libs/hwui/hwui/ImageDecoder.h
@@ -34,8 +34,8 @@
     std::unique_ptr<SkAndroidCodec> mCodec;
     sk_sp<SkPngChunkReader> mPeeker;
 
-    ImageDecoder(std::unique_ptr<SkAndroidCodec> codec,
-                 sk_sp<SkPngChunkReader> peeker = nullptr);
+    ImageDecoder(std::unique_ptr<SkAndroidCodec> codec, sk_sp<SkPngChunkReader> peeker = nullptr,
+                 SkCodec::ZeroInitialized zeroInit = SkCodec::kNo_ZeroInitialized);
     ~ImageDecoder();
 
     SkISize getSampledDimensions(int sampleSize) const;
diff --git a/libs/hwui/jni/ImageDecoder.cpp b/libs/hwui/jni/ImageDecoder.cpp
index ad7741b..f7b8c01 100644
--- a/libs/hwui/jni/ImageDecoder.cpp
+++ b/libs/hwui/jni/ImageDecoder.cpp
@@ -141,7 +141,8 @@
     }
 
     const bool isNinePatch = peeker->mPatch != nullptr;
-    ImageDecoder* decoder = new ImageDecoder(std::move(androidCodec), std::move(peeker));
+    ImageDecoder* decoder = new ImageDecoder(std::move(androidCodec), std::move(peeker),
+                                             SkCodec::kYes_ZeroInitialized);
     return env->NewObject(gImageDecoder_class, gImageDecoder_constructorMethodID,
                           reinterpret_cast<jlong>(decoder), decoder->width(), decoder->height(),
                           animated, isNinePatch);
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index 5dc02e8..adf4aee 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -20,6 +20,7 @@
 #include "CanvasContext.h"
 #include "DeviceInfo.h"
 #include "EglManager.h"
+#include "Properties.h"
 #include "Readback.h"
 #include "RenderProxy.h"
 #include "VulkanManager.h"
@@ -40,6 +41,7 @@
 #include <utils/Mutex.h>
 #include <thread>
 
+#include <android-base/properties.h>
 #include <ui/FatVector.h>
 
 namespace android {
@@ -251,6 +253,11 @@
 void RenderThread::initGrContextOptions(GrContextOptions& options) {
     options.fPreferExternalImagesOverES3 = true;
     options.fDisableDistanceFieldPaths = true;
+    if (android::base::GetBoolProperty(PROPERTY_REDUCE_OPS_TASK_SPLITTING, false)) {
+        options.fReduceOpsTaskSplitting = GrContextOptions::Enable::kYes;
+    } else {
+        options.fReduceOpsTaskSplitting = GrContextOptions::Enable::kNo;
+    }
 }
 
 void RenderThread::destroyRenderingContext() {
diff --git a/location/java/android/location/GnssCapabilities.java b/location/java/android/location/GnssCapabilities.java
index a5e2815..fdf0f59 100644
--- a/location/java/android/location/GnssCapabilities.java
+++ b/location/java/android/location/GnssCapabilities.java
@@ -61,6 +61,8 @@
     public static final int TOP_HAL_CAPABILITY_CORRELATION_VECTOR = 4096;
     /** @hide */
     public static final int TOP_HAL_CAPABILITY_SATELLITE_PVT = 8192;
+    /** @hide */
+    public static final int TOP_HAL_CAPABILITY_MEASUREMENT_CORRECTIONS_FOR_DRIVING = 16384;
 
     /** @hide */
     @IntDef(flag = true, prefix = {"TOP_HAL_CAPABILITY_"}, value = {TOP_HAL_CAPABILITY_SCHEDULING,
@@ -69,7 +71,8 @@
             TOP_HAL_CAPABILITY_MEASUREMENTS, TOP_HAL_CAPABILITY_NAV_MESSAGES,
             TOP_HAL_CAPABILITY_LOW_POWER_MODE, TOP_HAL_CAPABILITY_SATELLITE_BLOCKLIST,
             TOP_HAL_CAPABILITY_MEASUREMENT_CORRECTIONS, TOP_HAL_CAPABILITY_ANTENNA_INFO,
-            TOP_HAL_CAPABILITY_CORRELATION_VECTOR, TOP_HAL_CAPABILITY_SATELLITE_PVT})
+            TOP_HAL_CAPABILITY_CORRELATION_VECTOR, TOP_HAL_CAPABILITY_SATELLITE_PVT,
+            TOP_HAL_CAPABILITY_MEASUREMENT_CORRECTIONS_FOR_DRIVING})
 
     @Retention(RetentionPolicy.SOURCE)
     public @interface TopHalCapabilityFlags {}
@@ -351,6 +354,17 @@
     }
 
     /**
+     * Returns {@code true} if GNSS chipset will benefit from measurement corrections for driving
+     * use case if provided, {@code false} otherwise.
+     *
+     * @hide
+     */
+    @SystemApi
+    public boolean hasMeasurementCorrectionsForDriving() {
+        return (mTopFlags & TOP_HAL_CAPABILITY_MEASUREMENT_CORRECTIONS_FOR_DRIVING) != 0;
+    }
+
+    /**
      * Returns {@code true} if GNSS chipset supports line-of-sight satellite identification
      * measurement corrections, {@code false} otherwise.
      *
@@ -550,6 +564,9 @@
         if (hasMeasurementCorrelationVectors()) {
             builder.append("MEASUREMENT_CORRELATION_VECTORS ");
         }
+        if (hasMeasurementCorrectionsForDriving()) {
+            builder.append("MEASUREMENT_CORRECTIONS_FOR_DRIVING ");
+        }
         if (hasMeasurementCorrectionsLosSats()) {
             builder.append("LOS_SATS ");
         }
@@ -748,6 +765,18 @@
         }
 
         /**
+         * Sets measurement corrections for driving capability.
+         *
+         * @hide
+         */
+        @SystemApi
+        public @NonNull Builder setHasMeasurementCorrectionsForDriving(boolean capable) {
+            mTopFlags = setFlag(mTopFlags, TOP_HAL_CAPABILITY_MEASUREMENT_CORRECTIONS_FOR_DRIVING,
+                    capable);
+            return this;
+        }
+
+        /**
          * Sets measurement corrections line-of-sight satellites capabilitity.
          *
          * @hide
diff --git a/location/java/android/location/Location.java b/location/java/android/location/Location.java
index 5e2e559..5f8d795 100644
--- a/location/java/android/location/Location.java
+++ b/location/java/android/location/Location.java
@@ -1246,20 +1246,42 @@
      * Returns true if the Location came from a mock provider.
      *
      * @return true if this Location came from a mock provider, false otherwise
+     * @deprecated Prefer {@link #isMock()} instead.
      */
+    @Deprecated
     public boolean isFromMockProvider() {
-        return (mFieldsMask & HAS_MOCK_PROVIDER_MASK) != 0;
+        return isMock();
     }
 
     /**
      * Flag this Location as having come from a mock provider or not.
      *
      * @param isFromMockProvider true if this Location came from a mock provider, false otherwise
+     * @deprecated Prefer {@link #setMock(boolean)} instead.
      * @hide
      */
+    @Deprecated
     @SystemApi
     public void setIsFromMockProvider(boolean isFromMockProvider) {
-        if (isFromMockProvider) {
+        setMock(isFromMockProvider);
+    }
+
+    /**
+     * Returns true if this location is marked as a mock location. If this location comes from the
+     * Android framework, this indicates that the location was provided by a test location provider,
+     * and thus may not be related to the actual location of the device.
+     *
+     * @see LocationManager#addTestProvider
+     */
+    public boolean isMock() {
+        return (mFieldsMask & HAS_MOCK_PROVIDER_MASK) != 0;
+    }
+
+    /**
+     * Sets whether this location is marked as a mock location.
+     */
+    public void setMock(boolean mock) {
+        if (mock) {
             mFieldsMask |= HAS_MOCK_PROVIDER_MASK;
         } else {
             mFieldsMask &= ~HAS_MOCK_PROVIDER_MASK;
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index e73e915..f1879fc 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -346,43 +346,6 @@
      */
     public static final String EXTRA_GNSS_CAPABILITIES = "android.location.extra.GNSS_CAPABILITIES";
 
-    /**
-     * Broadcast intent action for Settings app to inject a footer at the bottom of location
-     * settings. This is for use only by apps that are included in the system image.
-     *
-     * <p>To inject a footer to location settings, you must declare a broadcast receiver for
-     * this action in the manifest:
-     * <pre>
-     *     &lt;receiver android:name="com.example.android.footer.MyFooterInjector"&gt;
-     *         &lt;intent-filter&gt;
-     *             &lt;action android:name="com.android.settings.location.INJECT_FOOTER" /&gt;
-     *         &lt;/intent-filter&gt;
-     *         &lt;meta-data
-     *             android:name="com.android.settings.location.FOOTER_STRING"
-     *             android:resource="@string/my_injected_footer_string" /&gt;
-     *     &lt;/receiver&gt;
-     * </pre>
-     *
-     * <p>This broadcast receiver will never actually be invoked. See also
-     * {#METADATA_SETTINGS_FOOTER_STRING}.
-     *
-     * @hide
-     */
-    public static final String SETTINGS_FOOTER_DISPLAYED_ACTION =
-            "com.android.settings.location.DISPLAYED_FOOTER";
-
-    /**
-     * Metadata name for {@link LocationManager#SETTINGS_FOOTER_DISPLAYED_ACTION} broadcast
-     * receivers to specify a string resource id as location settings footer text. This is for use
-     * only by apps that are included in the system image.
-     *
-     * <p>See {@link #SETTINGS_FOOTER_DISPLAYED_ACTION} for more detail on how to use.
-     *
-     * @hide
-     */
-    public static final String METADATA_SETTINGS_FOOTER_STRING =
-            "com.android.settings.location.FOOTER_STRING";
-
     private static final long MAX_SINGLE_LOCATION_TIMEOUT_MS = 30 * 1000;
 
     private static final String CACHE_KEY_LOCATION_ENABLED_PROPERTY =
diff --git a/location/java/android/location/SatellitePvt.java b/location/java/android/location/SatellitePvt.java
index 144fa13..27c7eda 100644
--- a/location/java/android/location/SatellitePvt.java
+++ b/location/java/android/location/SatellitePvt.java
@@ -25,8 +25,9 @@
 
 /**
  * A class that contains GNSS satellite position, velocity and time information at the
- * signal transmission time {@link GnssMeasurement#getReceivedSvTimeNanos()}.
+ * same signal transmission time {@link GnssMeasurement#getReceivedSvTimeNanos()}.
  *
+ * <p>The position and velocity must be in ECEF coordinates.
  * @hide
  */
 @SystemApi
@@ -39,6 +40,9 @@
 
     /**
      * Class containing estimates of the satellite position fields in ECEF coordinate frame.
+     *
+     * <p>The satellite position must be defined at the time of transmission of the signal
+     * receivedSvTimeNs.
      */
     public static final class PositionEcef implements Parcelable {
         private final double mXMeters;
@@ -133,6 +137,9 @@
 
     /**
      * Class containing estimates of the satellite velocity fields in the ECEF coordinate frame.
+     *
+     * <p>The satellite velocity must be defined at the time of transmission of the signal
+     * receivedSvTimeNs.
      */
     public static final class VelocityEcef implements Parcelable {
         private final double mXMetersPerSecond;
diff --git a/location/java/android/location/provider/ILocationProviderManager.aidl b/location/java/android/location/provider/ILocationProviderManager.aidl
index 50ed046..092ec67f 100644
--- a/location/java/android/location/provider/ILocationProviderManager.aidl
+++ b/location/java/android/location/provider/ILocationProviderManager.aidl
@@ -24,7 +24,7 @@
  * @hide
  */
 interface ILocationProviderManager {
-    void onInitialize(boolean allowed, in ProviderProperties properties, @nullable String packageName, @nullable String attributionTag);
+    void onInitialize(boolean allowed, in ProviderProperties properties, @nullable String attributionTag);
     void onSetAllowed(boolean allowed);
     void onSetProperties(in ProviderProperties properties);
 
diff --git a/location/java/android/location/provider/LocationProviderBase.java b/location/java/android/location/provider/LocationProviderBase.java
index ae6395d..eada22c 100644
--- a/location/java/android/location/provider/LocationProviderBase.java
+++ b/location/java/android/location/provider/LocationProviderBase.java
@@ -96,7 +96,6 @@
             "com.android.location.service.FusedLocationProvider";
 
     private final String mTag;
-    private final @Nullable String mPackageName;
     private final @Nullable String mAttributionTag;
     private final IBinder mBinder;
 
@@ -108,7 +107,6 @@
     public LocationProviderBase(@NonNull Context context, @NonNull String tag,
             @NonNull ProviderProperties properties) {
         mTag = tag;
-        mPackageName = context.getPackageName();
         mAttributionTag = context.getAttributionTag();
         mBinder = new Service();
 
@@ -305,7 +303,7 @@
         public void setLocationProviderManager(ILocationProviderManager manager) {
             synchronized (mBinder) {
                 try {
-                    manager.onInitialize(mAllowed, mProperties, mPackageName, mAttributionTag);
+                    manager.onInitialize(mAllowed, mProperties, mAttributionTag);
                 } catch (RemoteException e) {
                     throw e.rethrowFromSystemServer();
                 } catch (RuntimeException e) {
diff --git a/location/java/android/location/util/identity/CallerIdentity.java b/location/java/android/location/util/identity/CallerIdentity.java
index 85a083e..ade0ea4 100644
--- a/location/java/android/location/util/identity/CallerIdentity.java
+++ b/location/java/android/location/util/identity/CallerIdentity.java
@@ -55,6 +55,20 @@
     }
 
     /**
+     * Returns a CallerIdentity with PID and listener ID information stripped. This is mostly
+     * useful for aggregating information for debug purposes, and should not be used in any API with
+     * security requirements.
+     */
+    public static CallerIdentity forAggregation(CallerIdentity callerIdentity) {
+        if (callerIdentity.getPid() == 0 && callerIdentity.getListenerId() == null) {
+            return callerIdentity;
+        }
+
+        return new CallerIdentity(callerIdentity.getUid(), 0, callerIdentity.getPackageName(),
+                callerIdentity.getAttributionTag(), null);
+    }
+
+    /**
      * Creates a CallerIdentity for the current process and context.
      */
     public static CallerIdentity fromContext(Context context) {
@@ -180,17 +194,6 @@
         }
     }
 
-    /**
-     * Returns a CallerIdentity corrosponding to this CallerIdentity but with a null listener id.
-     */
-    public CallerIdentity stripListenerId() {
-        if (mListenerId == null) {
-            return this;
-        } else {
-            return new CallerIdentity(mUid, mPid, mPackageName, mAttributionTag, null);
-        }
-    }
-
     @Override
     public String toString() {
         int length = 10 + mPackageName.length();
diff --git a/location/lib/java/com/android/location/provider/LocationProviderBase.java b/location/lib/java/com/android/location/provider/LocationProviderBase.java
index 7f1cf6d..95f6c2f 100644
--- a/location/lib/java/com/android/location/provider/LocationProviderBase.java
+++ b/location/lib/java/com/android/location/provider/LocationProviderBase.java
@@ -96,7 +96,6 @@
     public static final String FUSED_PROVIDER = LocationManager.FUSED_PROVIDER;
 
     final String mTag;
-    @Nullable final String mPackageName;
     @Nullable final String mAttributionTag;
     final IBinder mBinder;
 
@@ -133,7 +132,6 @@
     public LocationProviderBase(Context context, String tag,
             ProviderPropertiesUnbundled properties) {
         mTag = tag;
-        mPackageName = context != null ? context.getPackageName() : null;
         mAttributionTag = context != null ? context.getAttributionTag() : null;
         mBinder = new Service();
 
@@ -370,7 +368,7 @@
         public void setLocationProviderManager(ILocationProviderManager manager) {
             synchronized (mBinder) {
                 try {
-                    manager.onInitialize(mAllowed, mProperties, mPackageName, mAttributionTag);
+                    manager.onInitialize(mAllowed, mProperties, mAttributionTag);
                 } catch (RemoteException e) {
                     throw e.rethrowFromSystemServer();
                 } catch (RuntimeException e) {
diff --git a/media/java/android/media/AudioDescriptor.java b/media/java/android/media/AudioDescriptor.java
new file mode 100644
index 0000000..11371b1
--- /dev/null
+++ b/media/java/android/media/AudioDescriptor.java
@@ -0,0 +1,90 @@
+/*
+ * 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 android.media;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * The AudioDescriptor contains the information to describe the audio playback/capture
+ * capabilities. The capabilities are described by a byte array, which is defined by a
+ * particular standard. This is used when the format is unrecognized to the platform.
+ */
+public class AudioDescriptor {
+    /**
+     * The audio standard is not specified.
+     */
+    public static final int STANDARD_NONE = 0;
+    /**
+     * The Extended Display Identification Data (EDID) standard for a short audio descriptor.
+     */
+    public static final int STANDARD_EDID = 1;
+
+    /** @hide */
+    @IntDef({
+            STANDARD_NONE,
+            STANDARD_EDID,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface AudioDescriptorStandard {}
+
+    private final int mStandard;
+    private final byte[] mDescriptor;
+    private final int mEncapsulationType;
+
+    AudioDescriptor(int standard, int encapsulationType, @NonNull byte[] descriptor) {
+        mStandard = standard;
+        mEncapsulationType = encapsulationType;
+        mDescriptor = descriptor;
+    }
+
+    /**
+     * @return the standard that defines audio playback/capture capabilities.
+     */
+    public @AudioDescriptorStandard int getStandard() {
+        return mStandard;
+    }
+
+    /**
+     * @return a byte array that describes audio playback/capture capabilities as encoded by the
+     * standard for this AudioDescriptor.
+     */
+    public @NonNull byte[] getDescriptor() {
+        return mDescriptor;
+    }
+
+    /**
+     * The encapsulation type indicates what encapsulation type is required when the framework is
+     * using this extra audio descriptor for playing to a device exposing this audio profile.
+     * When encapsulation is required, only playback with {@link android.media.AudioTrack} API is
+     * supported. But playback with {@link android.media.MediaPlayer} is not.
+     * When an encapsulation type is required, the {@link AudioFormat} encoding selected when
+     * creating the {@link AudioTrack} must match the encapsulation type, e.g
+     * AudioFormat#ENCODING_IEC61937 for AudioProfile.AUDIO_ENCAPSULATION_TYPE_IEC61937.
+     *
+     * @return an integer representing the encapsulation type
+     *
+     * @see AudioProfile#AUDIO_ENCAPSULATION_TYPE_NONE
+     * @see AudioProfile#AUDIO_ENCAPSULATION_TYPE_IEC61937
+     */
+    public @AudioProfile.EncapsulationType int getEncapsulationType() {
+        return mEncapsulationType;
+    }
+}
diff --git a/media/java/android/media/AudioDeviceInfo.java b/media/java/android/media/AudioDeviceInfo.java
index 383c93d..9300f13 100644
--- a/media/java/android/media/AudioDeviceInfo.java
+++ b/media/java/android/media/AudioDeviceInfo.java
@@ -519,6 +519,13 @@
     }
 
     /**
+     * @return A list of {@link AudioDescriptor} supported by the audio devices.
+     */
+    public @NonNull List<AudioDescriptor> getAudioDescriptors() {
+        return mPort.audioDescriptors();
+    }
+
+    /**
      * Returns an array of supported encapsulation modes for the device.
      *
      * The array can include any of the {@code AudioTrack} encapsulation modes,
diff --git a/media/java/android/media/AudioDevicePort.java b/media/java/android/media/AudioDevicePort.java
index 9c42bf7..ebe0882 100644
--- a/media/java/android/media/AudioDevicePort.java
+++ b/media/java/android/media/AudioDevicePort.java
@@ -60,10 +60,11 @@
 
     AudioDevicePort(AudioHandle handle, String deviceName, List<AudioProfile> profiles,
             AudioGain[] gains, int type, String address, int[] encapsulationModes,
-              @AudioTrack.EncapsulationMetadataType int[] encapsulationMetadataTypes) {
+            @AudioTrack.EncapsulationMetadataType int[] encapsulationMetadataTypes,
+            List<AudioDescriptor> descriptors) {
         super(handle,
                 AudioManager.isInputDevice(type) ? AudioPort.ROLE_SOURCE : AudioPort.ROLE_SINK,
-                deviceName, profiles, gains);
+                deviceName, profiles, gains, descriptors);
         mType = type;
         mAddress = address;
         mEncapsulationModes = encapsulationModes;
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index f957a73..a717a90 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -568,6 +568,42 @@
     public static final int FLAG_FROM_KEY = 1 << 12;
 
     /** @hide */
+    @IntDef(prefix = {"ENCODED_SURROUND_OUTPUT_"}, value = {
+            ENCODED_SURROUND_OUTPUT_AUTO,
+            ENCODED_SURROUND_OUTPUT_NEVER,
+            ENCODED_SURROUND_OUTPUT_ALWAYS,
+            ENCODED_SURROUND_OUTPUT_MANUAL
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface EncodedSurroundOutputMode {}
+
+    /**
+     * The surround sound formats are available for use if they are detected. This is the default
+     * mode.
+     */
+    public static final int ENCODED_SURROUND_OUTPUT_AUTO = 0;
+
+    /**
+     * The surround sound formats are NEVER available, even if they are detected by the hardware.
+     * Those formats will not be reported.
+     */
+    public static final int ENCODED_SURROUND_OUTPUT_NEVER = 1;
+
+    /**
+     * The surround sound formats are ALWAYS available, even if they are not detected by the
+     * hardware. Those formats will be reported as part of the HDMI output capability.
+     * Applications are then free to use either PCM or encoded output.
+     */
+    public static final int ENCODED_SURROUND_OUTPUT_ALWAYS = 2;
+
+    /**
+     * Surround sound formats are available according to the choice of user, even if they are not
+     * detected by the hardware. Those formats will be reported as part of the HDMI output
+     * capability. Applications are then free to use either PCM or encoded output.
+     */
+    public static final int ENCODED_SURROUND_OUTPUT_MANUAL = 3;
+
+    /** @hide */
     @IntDef(flag = true, prefix = "FLAG", value = {
             FLAG_SHOW_UI,
             FLAG_ALLOW_RINGER_MODES,
@@ -3185,6 +3221,23 @@
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     public static final int NUM_SOUND_EFFECTS = 16;
 
+    /** @hide */
+    @IntDef(prefix = { "FX_" }, value = {
+            FX_KEY_CLICK,
+            FX_FOCUS_NAVIGATION_UP,
+            FX_FOCUS_NAVIGATION_DOWN,
+            FX_FOCUS_NAVIGATION_LEFT,
+            FX_FOCUS_NAVIGATION_RIGHT,
+            FX_KEYPRESS_STANDARD,
+            FX_KEYPRESS_SPACEBAR,
+            FX_KEYPRESS_DELETE,
+            FX_KEYPRESS_RETURN,
+            FX_KEYPRESS_INVALID,
+            FX_BACK
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface SystemSoundEffect {}
+
     /**
      * @hide Number of FX_FOCUS_NAVIGATION_REPEAT_* sound effects
      */
@@ -3260,22 +3313,11 @@
 
     /**
      * Plays a sound effect (Key clicks, lid open/close...)
-     * @param effectType The type of sound effect. One of
-     *            {@link #FX_KEY_CLICK},
-     *            {@link #FX_FOCUS_NAVIGATION_UP},
-     *            {@link #FX_FOCUS_NAVIGATION_DOWN},
-     *            {@link #FX_FOCUS_NAVIGATION_LEFT},
-     *            {@link #FX_FOCUS_NAVIGATION_RIGHT},
-     *            {@link #FX_KEYPRESS_STANDARD},
-     *            {@link #FX_KEYPRESS_SPACEBAR},
-     *            {@link #FX_KEYPRESS_DELETE},
-     *            {@link #FX_KEYPRESS_RETURN},
-     *            {@link #FX_KEYPRESS_INVALID},
-     *            {@link #FX_BACK},
+     * @param effectType The type of sound effect.
      * NOTE: This version uses the UI settings to determine
      * whether sounds are heard or not.
      */
-    public void playSoundEffect(int effectType) {
+    public void playSoundEffect(@SystemSoundEffect int effectType) {
         if (effectType < 0 || effectType >= NUM_SOUND_EFFECTS) {
             return;
         }
@@ -3294,24 +3336,13 @@
 
     /**
      * Plays a sound effect (Key clicks, lid open/close...)
-     * @param effectType The type of sound effect. One of
-     *            {@link #FX_KEY_CLICK},
-     *            {@link #FX_FOCUS_NAVIGATION_UP},
-     *            {@link #FX_FOCUS_NAVIGATION_DOWN},
-     *            {@link #FX_FOCUS_NAVIGATION_LEFT},
-     *            {@link #FX_FOCUS_NAVIGATION_RIGHT},
-     *            {@link #FX_KEYPRESS_STANDARD},
-     *            {@link #FX_KEYPRESS_SPACEBAR},
-     *            {@link #FX_KEYPRESS_DELETE},
-     *            {@link #FX_KEYPRESS_RETURN},
-     *            {@link #FX_KEYPRESS_INVALID},
-     *            {@link #FX_BACK},
+     * @param effectType The type of sound effect.
      * @param userId The current user to pull sound settings from
      * NOTE: This version uses the UI settings to determine
      * whether sounds are heard or not.
      * @hide
      */
-    public void  playSoundEffect(int effectType, int userId) {
+    public void  playSoundEffect(@SystemSoundEffect int effectType, int userId) {
         if (effectType < 0 || effectType >= NUM_SOUND_EFFECTS) {
             return;
         }
@@ -3330,25 +3361,14 @@
 
     /**
      * Plays a sound effect (Key clicks, lid open/close...)
-     * @param effectType The type of sound effect. One of
-     *            {@link #FX_KEY_CLICK},
-     *            {@link #FX_FOCUS_NAVIGATION_UP},
-     *            {@link #FX_FOCUS_NAVIGATION_DOWN},
-     *            {@link #FX_FOCUS_NAVIGATION_LEFT},
-     *            {@link #FX_FOCUS_NAVIGATION_RIGHT},
-     *            {@link #FX_KEYPRESS_STANDARD},
-     *            {@link #FX_KEYPRESS_SPACEBAR},
-     *            {@link #FX_KEYPRESS_DELETE},
-     *            {@link #FX_KEYPRESS_RETURN},
-     *            {@link #FX_KEYPRESS_INVALID},
-     *            {@link #FX_BACK},
+     * @param effectType The type of sound effect.
      * @param volume Sound effect volume.
      * The volume value is a raw scalar so UI controls should be scaled logarithmically.
      * If a volume of -1 is specified, the AudioManager.STREAM_MUSIC stream volume minus 3dB will be used.
      * NOTE: This version is for applications that have their own
      * settings panel for enabling and controlling volume.
      */
-    public void  playSoundEffect(int effectType, float volume) {
+    public void  playSoundEffect(@SystemSoundEffect int effectType, float volume) {
         if (effectType < 0 || effectType >= NUM_SOUND_EFFECTS) {
             return;
         }
@@ -3791,6 +3811,14 @@
      */
     @SystemApi
     public static final int AUDIOFOCUS_FLAG_LOCK     = 0x1 << 2;
+
+    /**
+     * @hide
+     * flag set on test API calls,
+     * see {@link #requestAudioFocusForTest(AudioFocusRequest, String, int, int)},
+     * note that it isn't used in conjunction with other flags, it is passed as the single
+     * value for flags */
+    public static final int AUDIOFOCUS_FLAG_TEST = 0x1 << 3;
     /** @hide */
     public static final int AUDIOFOCUS_FLAGS_APPS = AUDIOFOCUS_FLAG_DELAY_OK
             | AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS;
@@ -3952,6 +3980,76 @@
 
     /**
      * @hide
+     * Test API to request audio focus for an arbitrary client operating from a (fake) given UID.
+     * Used to simulate conditions of the test, not the behavior of the focus requester under test.
+     * @param afr the parameters of the request
+     * @param clientFakeId the identifier of the AudioManager the client would be requesting from
+     * @param clientFakeUid the UID of the client, here an arbitrary int,
+     *                      doesn't have to be a real UID
+     * @param clientTargetSdk the target SDK used by the client
+     * @return return code indicating status of the request
+     */
+    @TestApi
+    @RequiresPermission("android.permission.QUERY_AUDIO_STATE")
+    public @FocusRequestResult int requestAudioFocusForTest(@NonNull AudioFocusRequest afr,
+            @NonNull String clientFakeId, int clientFakeUid, int clientTargetSdk) {
+        Objects.requireNonNull(afr);
+        Objects.requireNonNull(clientFakeId);
+        try {
+            return getService().requestAudioFocusForTest(afr.getAudioAttributes(),
+                    afr.getFocusGain(),
+                    mICallBack,
+                    mAudioFocusDispatcher,
+                    clientFakeId, "com.android.test.fakeclient", clientFakeUid, clientTargetSdk);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     * Test API to abandon audio focus for an arbitrary client.
+     * Used to simulate conditions of the test, not the behavior of the focus requester under test.
+     * @param afr the parameters used for the request
+     * @param clientFakeId clientFakeId the identifier of the AudioManager from which the client
+     *      would be requesting
+     * @return return code indicating status of the request
+     */
+    @TestApi
+    @RequiresPermission("android.permission.QUERY_AUDIO_STATE")
+    public @FocusRequestResult int abandonAudioFocusForTest(@NonNull AudioFocusRequest afr,
+            @NonNull String clientFakeId) {
+        Objects.requireNonNull(afr);
+        Objects.requireNonNull(clientFakeId);
+        try {
+            return getService().abandonAudioFocusForTest(mAudioFocusDispatcher,
+                    clientFakeId, afr.getAudioAttributes(), "com.android.test.fakeclient");
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     * Return the duration of the fade out applied when a player of the given AudioAttributes
+     * is losing audio focus
+     * @param aa the AudioAttributes of the player losing focus with {@link #AUDIOFOCUS_LOSS}
+     * @return a duration in ms, 0 indicates no fade out is applied
+     */
+    @TestApi
+    @RequiresPermission("android.permission.QUERY_AUDIO_STATE")
+    public @IntRange(from = 0) long getFadeOutDurationOnFocusLossMillis(@NonNull AudioAttributes aa)
+    {
+        Objects.requireNonNull(aa);
+        try {
+            return getService().getFadeOutDurationOnFocusLossMillis(aa);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
      * Request or lock audio focus.
      * This method is to be used by system components that have registered an
      * {@link android.media.audiopolicy.AudioPolicy} to request audio focus, but also to "lock" it
@@ -6754,6 +6852,34 @@
     }
 
     /**
+     * Sets the surround sound mode.
+     *
+     * @return true if successful, otherwise false
+     */
+    @RequiresPermission(android.Manifest.permission.WRITE_SETTINGS)
+    public boolean setEncodedSurroundMode(@EncodedSurroundOutputMode int mode) {
+        try {
+            return getService().setEncodedSurroundMode(mode);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Gets the surround sound mode.
+     *
+     * @return true if successful, otherwise false
+     */
+    @RequiresPermission(android.Manifest.permission.WRITE_SETTINGS)
+    public @EncodedSurroundOutputMode int getEncodedSurroundMode() {
+        try {
+            return getService().getEncodedSurroundMode();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * @hide
      * Returns all surround formats.
      * @return a map where the key is a surround format and
@@ -6771,7 +6897,6 @@
     }
 
     /**
-     * @hide
      * Set a certain surround format as enabled or not.
      * @param audioFormat a surround format, the value is one of
      *        {@link AudioFormat#ENCODING_AC3}, {@link AudioFormat#ENCODING_E_AC3},
@@ -6785,10 +6910,29 @@
      * @param enabled the required surround format state, true for enabled, false for disabled
      * @return true if successful, otherwise false
      */
+    @RequiresPermission(android.Manifest.permission.WRITE_SETTINGS)
     public boolean setSurroundFormatEnabled(
             @AudioFormat.SurroundSoundEncoding int audioFormat, boolean enabled) {
-        int status = AudioSystem.setSurroundFormatEnabled(audioFormat, enabled);
-        return status == AudioManager.SUCCESS;
+        try {
+            return getService().setSurroundFormatEnabled(audioFormat, enabled);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Gets whether a certain surround format is enabled or not.
+     * @param audioFormat a surround format
+     *
+     * @return whether the required surround format is enabled
+     */
+    @RequiresPermission(android.Manifest.permission.WRITE_SETTINGS)
+    public boolean isSurroundFormatEnabled(@AudioFormat.SurroundSoundEncoding int audioFormat) {
+        try {
+            return getService().isSurroundFormatEnabled(audioFormat);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
     }
 
     /**
diff --git a/media/java/android/media/AudioMixPort.java b/media/java/android/media/AudioMixPort.java
index 7f2249d..b24268a 100644
--- a/media/java/android/media/AudioMixPort.java
+++ b/media/java/android/media/AudioMixPort.java
@@ -46,7 +46,7 @@
 
     AudioMixPort(AudioHandle handle, int ioHandle, int role, String deviceName,
             List<AudioProfile> profiles, AudioGain[] gains) {
-        super(handle, role, deviceName, profiles, gains);
+        super(handle, role, deviceName, profiles, gains, null);
         mIoHandle = ioHandle;
     }
 
diff --git a/media/java/android/media/AudioPort.java b/media/java/android/media/AudioPort.java
index 0302250..8a2d096 100644
--- a/media/java/android/media/AudioPort.java
+++ b/media/java/android/media/AudioPort.java
@@ -86,6 +86,7 @@
     private final int[] mChannelIndexMasks;
     private final int[] mFormats;
     private final List<AudioProfile> mProfiles;
+    private final List<AudioDescriptor> mDescriptors;
     @UnsupportedAppUsage
     private final AudioGain[] mGains;
     @UnsupportedAppUsage
@@ -107,17 +108,21 @@
         if (mFormats != null) {
             for (int format : mFormats) {
                 mProfiles.add(new AudioProfile(
-                        format, samplingRates, channelMasks, channelIndexMasks));
+                        format, samplingRates, channelMasks, channelIndexMasks,
+                        AudioProfile.AUDIO_ENCAPSULATION_TYPE_NONE));
             }
         }
+        mDescriptors = new ArrayList<>();
     }
 
     AudioPort(AudioHandle handle, int role, String name,
-            List<AudioProfile> profiles, AudioGain[] gains) {
+              List<AudioProfile> profiles, AudioGain[] gains,
+              List<AudioDescriptor> descriptors) {
         mHandle = handle;
         mRole = role;
         mName = name;
         mProfiles = profiles;
+        mDescriptors = descriptors;
         mGains = gains;
         Set<Integer> formats = new HashSet<>();
         Set<Integer> samplingRates = new HashSet<>();
@@ -210,6 +215,13 @@
     }
 
     /**
+     * Get the list of audio descriptor
+     */
+    public List<AudioDescriptor> audioDescriptors() {
+        return mDescriptors;
+    }
+
+    /**
      * Get the list of gain descriptors
      * Empty array if this port does not have gain control
      */
diff --git a/media/java/android/media/AudioProfile.java b/media/java/android/media/AudioProfile.java
index 3cd615b..ae8d0a5 100644
--- a/media/java/android/media/AudioProfile.java
+++ b/media/java/android/media/AudioProfile.java
@@ -16,24 +16,55 @@
 
 package android.media;
 
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Arrays;
+import java.util.stream.Collectors;
+
 /**
  * An AudioProfile is specific to an audio format and lists supported sampling rates and
  * channel masks for that format.  An {@link AudioDeviceInfo} has a list of supported AudioProfiles.
+ * There can be multiple profiles whose encoding format is the same. This usually happens when
+ * an encoding format is only supported when it is encapsulated by some particular encapsulation
+ * types. If there are multiple encapsulation types that can carry this encoding format, they will
+ * be reported in different audio profiles. The application can choose any of the encapsulation
+ * types.
  */
 public class AudioProfile {
+    /**
+     * No encapsulation type is specified.
+     */
+    public static final int AUDIO_ENCAPSULATION_TYPE_NONE = 0;
+    /**
+     * Encapsulation format is defined in standard IEC 61937.
+     */
+    public static final int AUDIO_ENCAPSULATION_TYPE_IEC61937 = 1;
+
+    /** @hide */
+    @IntDef({
+            AUDIO_ENCAPSULATION_TYPE_NONE,
+            AUDIO_ENCAPSULATION_TYPE_IEC61937,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface EncapsulationType {}
+
     private final int mFormat;
     private final int[] mSamplingRates;
     private final int[] mChannelMasks;
     private final int[] mChannelIndexMasks;
+    private final int mEncapsulationType;
 
     AudioProfile(int format, @NonNull int[] samplingRates, @NonNull int[] channelMasks,
-                 @NonNull int[] channelIndexMasks) {
+                 @NonNull int[] channelIndexMasks,
+                 int encapsulationType) {
         mFormat = format;
         mSamplingRates = samplingRates;
         mChannelMasks = channelMasks;
         mChannelIndexMasks = channelIndexMasks;
+        mEncapsulationType = encapsulationType;
     }
 
     /**
@@ -63,4 +94,47 @@
     public @NonNull int[] getSampleRates() {
         return mSamplingRates;
     }
+
+    /**
+     * The encapsulation type indicates what encapsulation type is required when the framework is
+     * using this format when playing to a device exposing this audio profile.
+     * When encapsulation is required, only playback with {@link android.media.AudioTrack} API is
+     * supported. But playback with {@link android.media.MediaPlayer} is not.
+     * When an encapsulation type is required, the {@link AudioFormat} encoding selected when
+     * creating the {@link AudioTrack} must match the encapsulation type, e.g
+     * AudioFormat.ENCODING_IEC61937 for AUDIO_ENCAPSULATION_TYPE_IEC61937.
+     *
+     * @return an integer representing the encapsulation type
+     *
+     * @see #AUDIO_ENCAPSULATION_TYPE_NONE
+     * @see #AUDIO_ENCAPSULATION_TYPE_IEC61937
+     */
+    public @EncapsulationType int getEncapsulationType() {
+        return mEncapsulationType;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder("{");
+        sb.append(AudioFormat.toLogFriendlyEncoding(mFormat));
+        if (mSamplingRates != null && mSamplingRates.length > 0) {
+            sb.append(", sampling rates=").append(Arrays.toString(mSamplingRates));
+        }
+        if (mChannelMasks != null && mChannelMasks.length > 0) {
+            sb.append(", channel masks=").append(toHexString(mChannelMasks));
+        }
+        if (mChannelIndexMasks != null && mChannelIndexMasks.length > 0) {
+            sb.append(", channel index masks=").append(Arrays.toString(mChannelIndexMasks));
+        }
+        sb.append("}");
+        return sb.toString();
+    }
+
+    private static String toHexString(int[] ints) {
+        if (ints == null || ints.length == 0) {
+            return "";
+        }
+        return Arrays.stream(ints).mapToObj(anInt -> String.format("0x%02X", anInt))
+                .collect(Collectors.joining(", "));
+    }
 }
diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java
index 0d61399..3399377 100644
--- a/media/java/android/media/AudioRecord.java
+++ b/media/java/android/media/AudioRecord.java
@@ -32,6 +32,7 @@
 import android.media.MediaRecorder.Source;
 import android.media.audiopolicy.AudioMix;
 import android.media.audiopolicy.AudioPolicy;
+import android.media.metrics.LogSessionId;
 import android.media.permission.Identity;
 import android.media.projection.MediaProjection;
 import android.os.Binder;
@@ -282,9 +283,9 @@
 
     /**
      * The log session id used for metrics.
-     * A null or empty string here means it is not set.
+     * {@link LogSessionId#LOG_SESSION_ID_NONE} here means it is not set.
      */
-    private String mLogSessionId;
+    @NonNull private LogSessionId mLogSessionId = LogSessionId.LOG_SESSION_ID_NONE;
 
     //---------------------------------------------------------
     // Constructor, Finalize
@@ -1963,24 +1964,34 @@
     }
 
     /**
-     * Sets a string handle to this AudioRecord for metrics collection.
+     * Sets a {@link LogSessionId} instance to this AudioRecord for metrics collection.
      *
-     * @param logSessionId a string which is used to identify this object
-     *        to the metrics service.  Proper generated Ids must be obtained
-     *        from the Java metrics service and should be considered opaque.
-     *        Use null to remove the logSessionId association.
+     * @param logSessionId a {@link LogSessionId} instance which is used to
+     *        identify this object to the metrics service. Proper generated
+     *        Ids must be obtained from the Java metrics service and should
+     *        be considered opaque. Use
+     *        {@link LogSessionId#LOG_SESSION_ID_NONE} to remove the
+     *        logSessionId association.
      * @throws IllegalStateException if AudioRecord not initialized.
-     *
-     * @hide
      */
-    public void setLogSessionId(@Nullable String logSessionId) {
+    public void setLogSessionId(@NonNull LogSessionId logSessionId) {
+        Objects.requireNonNull(logSessionId);
         if (mState == STATE_UNINITIALIZED) {
             throw new IllegalStateException("AudioRecord not initialized");
         }
-        native_setLogSessionId(logSessionId);
+        String stringId = logSessionId.getStringId();
+        native_setLogSessionId(stringId);
         mLogSessionId = logSessionId;
     }
 
+    /**
+     * Returns the {@link LogSessionId}.
+     */
+    @NonNull
+    public LogSessionId getLogSessionId() {
+        return mLogSessionId;
+    }
+
     //---------------------------------------------------------
     // Interface definitions
     //--------------------
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index bccefdf..7a2b022 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -26,6 +26,7 @@
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
 import android.compat.annotation.UnsupportedAppUsage;
+import android.media.metrics.LogSessionId;
 import android.os.Binder;
 import android.os.Build;
 import android.os.Handler;
@@ -45,6 +46,7 @@
 import java.nio.ByteOrder;
 import java.nio.NioUtils;
 import java.util.LinkedList;
+import java.util.Objects;
 import java.util.concurrent.Executor;
 
 /**
@@ -567,9 +569,9 @@
 
     /**
      * The log session id used for metrics.
-     * A null or empty string here means it is not set.
+     * {@link LogSessionId#LOG_SESSION_ID_NONE} here means it is not set.
      */
-    private String mLogSessionId;
+    @NonNull private LogSessionId mLogSessionId = LogSessionId.LOG_SESSION_ID_NONE;
 
     //--------------------------------
     // Used exclusively by native code
@@ -4044,24 +4046,35 @@
     }
 
     /**
-     * Sets a string handle to this AudioTrack for metrics collection.
+     * Sets a {@link LogSessionId} instance to this AudioTrack for metrics collection.
      *
-     * @param logSessionId a string which is used to identify this object
-     *        to the metrics service.  Proper generated Ids must be obtained
-     *        from the Java metrics service and should be considered opaque.
-     *        Use null to remove the logSessionId association.
+     * @param logSessionId a {@link LogSessionId} instance which is used to
+     *        identify this object to the metrics service. Proper generated
+     *        Ids must be obtained from the Java metrics service and should
+     *        be considered opaque. Use
+     *        {@link LogSessionId#LOG_SESSION_ID_NONE} to remove the
+     *        logSessionId association.
      * @throws IllegalStateException if AudioTrack not initialized.
      *
-     * @hide
      */
-    public void setLogSessionId(@Nullable String logSessionId) {
+    public void setLogSessionId(@NonNull LogSessionId logSessionId) {
+        Objects.requireNonNull(logSessionId);
         if (mState == STATE_UNINITIALIZED) {
             throw new IllegalStateException("track not initialized");
         }
-        native_setLogSessionId(logSessionId);
+        String stringId = logSessionId.getStringId();
+        native_setLogSessionId(stringId);
         mLogSessionId = logSessionId;
     }
 
+    /**
+     * Returns the {@link LogSessionId}.
+     */
+    @NonNull
+    public LogSessionId getLogSessionId() {
+        return mLogSessionId;
+    }
+
     //---------------------------------------------------------
     // Inner classes
     //--------------------
diff --git a/media/java/android/media/CamcorderProfile.java b/media/java/android/media/CamcorderProfile.java
index 9c6b276..2059f02 100644
--- a/media/java/android/media/CamcorderProfile.java
+++ b/media/java/android/media/CamcorderProfile.java
@@ -16,6 +16,9 @@
 
 package android.media;
 
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.hardware.Camera;
 import android.hardware.Camera.CameraInfo;
@@ -23,6 +26,9 @@
 import android.hardware.camera2.CameraMetadata;
 import android.os.Build;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * Retrieves the
  * predefined camcorder profile settings for camcorder applications.
@@ -276,6 +282,53 @@
     private static final int QUALITY_HIGH_SPEED_LIST_END = QUALITY_HIGH_SPEED_4KDCI;
 
     /**
+     * @hide
+     */
+    @IntDef({
+        QUALITY_LOW,
+        QUALITY_HIGH,
+        QUALITY_QCIF,
+        QUALITY_CIF,
+        QUALITY_480P,
+        QUALITY_720P,
+        QUALITY_1080P,
+        QUALITY_QVGA,
+        QUALITY_2160P,
+        QUALITY_VGA,
+        QUALITY_4KDCI,
+        QUALITY_QHD,
+        QUALITY_2K,
+        QUALITY_8KUHD,
+
+        QUALITY_TIME_LAPSE_LOW ,
+        QUALITY_TIME_LAPSE_HIGH,
+        QUALITY_TIME_LAPSE_QCIF,
+        QUALITY_TIME_LAPSE_CIF,
+        QUALITY_TIME_LAPSE_480P,
+        QUALITY_TIME_LAPSE_720P,
+        QUALITY_TIME_LAPSE_1080P,
+        QUALITY_TIME_LAPSE_QVGA,
+        QUALITY_TIME_LAPSE_2160P,
+        QUALITY_TIME_LAPSE_VGA,
+        QUALITY_TIME_LAPSE_4KDCI,
+        QUALITY_TIME_LAPSE_QHD,
+        QUALITY_TIME_LAPSE_2K,
+        QUALITY_TIME_LAPSE_8KUHD,
+
+        QUALITY_HIGH_SPEED_LOW,
+        QUALITY_HIGH_SPEED_HIGH,
+        QUALITY_HIGH_SPEED_480P,
+        QUALITY_HIGH_SPEED_720P,
+        QUALITY_HIGH_SPEED_1080P,
+        QUALITY_HIGH_SPEED_2160P,
+        QUALITY_HIGH_SPEED_CIF,
+        QUALITY_HIGH_SPEED_VGA,
+        QUALITY_HIGH_SPEED_4KDCI,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Quality {}
+
+    /**
      * Default recording duration in seconds before the session is terminated.
      * This is useful for applications like MMS has limited file size requirement.
      */
@@ -385,9 +438,8 @@
     public int audioChannels;
 
     /**
-     * Returns the camcorder profile for the first back-facing camera on the
-     * device at the given quality level. If the device has no back-facing
-     * camera, this returns null.
+     * Returns the default camcorder profile at the given quality level for the first back-facing
+     * camera on the device. If the device has no back-facing camera, this returns null.
      * @param quality the target quality level for the camcorder profile
      * @see #get(int, int)
      */
@@ -404,8 +456,7 @@
     }
 
     /**
-     * Returns the camcorder profile for the given camera at the given
-     * quality level.
+     * Returns the default camcorder profile for the given camera at the given quality level.
      *
      * Quality levels QUALITY_LOW, QUALITY_HIGH are guaranteed to be supported, while
      * other levels may or may not be supported. The supported levels can be checked using
@@ -457,6 +508,7 @@
      * @see #QUALITY_HIGH_SPEED_720P
      * @see #QUALITY_HIGH_SPEED_1080P
      * @see #QUALITY_HIGH_SPEED_2160P
+     * @throws IllegalArgumentException if quality is not one of the defined QUALITY_ values.
     */
     public static CamcorderProfile get(int cameraId, int quality) {
         if (!((quality >= QUALITY_LIST_START &&
@@ -472,7 +524,119 @@
     }
 
     /**
-     * Returns true if camcorder profile exists for the first back-facing
+     * Returns all encoder profiles of a camcorder profile for the given camera at
+     * the given quality level.
+     *
+     * Quality levels QUALITY_LOW, QUALITY_HIGH are guaranteed to be supported, while
+     * other levels may or may not be supported. The supported levels can be checked using
+     * {@link #hasProfile(int, int)}.
+     * QUALITY_LOW refers to the lowest quality available, while QUALITY_HIGH refers to
+     * the highest quality available.
+     * QUALITY_LOW/QUALITY_HIGH have to match one of qcif, cif, 480p, 720p, 1080p or 2160p.
+     * E.g. if the device supports 480p, 720p, 1080p and 2160p, then low is 480p and high is
+     * 2160p.
+     *
+     * The same is true for time lapse quality levels, i.e. QUALITY_TIME_LAPSE_LOW,
+     * QUALITY_TIME_LAPSE_HIGH are guaranteed to be supported and have to match one of
+     * qcif, cif, 480p, 720p, 1080p, or 2160p.
+     *
+     * For high speed quality levels, they may or may not be supported. If a subset of the levels
+     * are supported, QUALITY_HIGH_SPEED_LOW and QUALITY_HIGH_SPEED_HIGH are guaranteed to be
+     * supported and have to match one of 480p, 720p, or 1080p.
+     *
+     * A camcorder recording session with higher quality level usually has higher output
+     * bit rate, better video and/or audio recording quality, larger video frame
+     * resolution and higher audio sampling rate, etc, than those with lower quality
+     * level.
+     *
+     * @param cameraId the id for the camera. Numeric camera ids parsed from the list received by
+     *                 invoking {@link CameraManager#getCameraIdList} can be used as long as they
+     *                 are {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE}
+     *                 and not
+     *                 {@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL EXTERNAL}.
+     * @param quality the target quality level for the camcorder profile.
+     * @return null if there are no encoder profiles defined for the quality level for the
+     * given camera.
+     * @throws IllegalArgumentException if quality is not one of the defined QUALITY_ values.
+     * @see #QUALITY_LOW
+     * @see #QUALITY_HIGH
+     * @see #QUALITY_QCIF
+     * @see #QUALITY_CIF
+     * @see #QUALITY_480P
+     * @see #QUALITY_720P
+     * @see #QUALITY_1080P
+     * @see #QUALITY_2160P
+     * @see #QUALITY_TIME_LAPSE_LOW
+     * @see #QUALITY_TIME_LAPSE_HIGH
+     * @see #QUALITY_TIME_LAPSE_QCIF
+     * @see #QUALITY_TIME_LAPSE_CIF
+     * @see #QUALITY_TIME_LAPSE_480P
+     * @see #QUALITY_TIME_LAPSE_720P
+     * @see #QUALITY_TIME_LAPSE_1080P
+     * @see #QUALITY_TIME_LAPSE_2160P
+     * @see #QUALITY_HIGH_SPEED_LOW
+     * @see #QUALITY_HIGH_SPEED_HIGH
+     * @see #QUALITY_HIGH_SPEED_480P
+     * @see #QUALITY_HIGH_SPEED_720P
+     * @see #QUALITY_HIGH_SPEED_1080P
+     * @see #QUALITY_HIGH_SPEED_2160P
+    */
+    @Nullable public static EncoderProfiles getAll(
+            @NonNull String cameraId, @Quality int quality) {
+        if (!((quality >= QUALITY_LIST_START &&
+               quality <= QUALITY_LIST_END) ||
+              (quality >= QUALITY_TIME_LAPSE_LIST_START &&
+               quality <= QUALITY_TIME_LAPSE_LIST_END) ||
+               (quality >= QUALITY_HIGH_SPEED_LIST_START &&
+               quality <= QUALITY_HIGH_SPEED_LIST_END))) {
+            String errMessage = "Unsupported quality level: " + quality;
+            throw new IllegalArgumentException(errMessage);
+        }
+
+        // TODO: get all profiles
+        int id;
+        try {
+            id = Integer.valueOf(cameraId);
+        } catch (NumberFormatException e) {
+            return null;
+        }
+        CamcorderProfile cp = native_get_camcorder_profile(id, quality);
+        if (cp == null) {
+            return null;
+        };
+
+        EncoderProfiles.AudioProfile[] audioProfiles;
+        // timelapse profiles do not list audio profiles
+        if (cp.quality >= QUALITY_TIME_LAPSE_LIST_START
+                && cp.quality <= QUALITY_TIME_LAPSE_LIST_END) {
+            audioProfiles = new EncoderProfiles.AudioProfile[] { };
+        } else {
+            audioProfiles = new EncoderProfiles.AudioProfile[] {
+                new EncoderProfiles.AudioProfile(
+                        cp.audioCodec,
+                        cp.audioChannels,
+                        cp.audioSampleRate,
+                        cp.audioBitRate)
+            };
+        }
+
+        return new EncoderProfiles(
+                cp.duration,
+                cp.fileFormat,
+                new EncoderProfiles.VideoProfile[] {
+                    new EncoderProfiles.VideoProfile(
+                        cp.videoCodec,
+                        cp.videoFrameWidth,
+                        cp.videoFrameHeight,
+                        cp.videoFrameRate,
+                        cp.videoBitRate,
+                        0 /* TODO: get profile */)
+                },
+                audioProfiles);
+    }
+
+    /**
+     * Returns true if a camcorder profile exists for the first back-facing
      * camera at the given quality level.
      *
      * <p>
@@ -507,7 +671,7 @@
     }
 
     /**
-     * Returns true if camcorder profile exists for the given camera at
+     * Returns true if a camcorder profile exists for the given camera at
      * the given quality level.
      *
      * <p>
diff --git a/media/java/android/media/EncoderProfiles.java b/media/java/android/media/EncoderProfiles.java
new file mode 100644
index 0000000..ca3daef
--- /dev/null
+++ b/media/java/android/media/EncoderProfiles.java
@@ -0,0 +1,351 @@
+/*
+ * 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 android.media;
+
+import android.annotation.NonNull;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Describes a set of encoding profiles for a given media (audio and/or video) profile.
+ * These settings are read-only.
+ *
+ * <p>Currently, this is used to describe camera recording profile with more detail than {@link
+ * CamcorderProfile}, by providing encoding parameters for more than just the default audio
+ * and/or video codec.
+ *
+ * <p>The compressed output from a camera recording session contains two tracks:
+ * one for audio and one for video.
+ * <p>In the future audio-only recording profiles may be defined.
+ *
+ * <p>Each media profile specifies a set of audio and a set of video specific settings.
+ * <ul>
+ * <li> The file output format
+ * <li> Default file duration
+ * <p>Video-specific settings are:
+ * <li> Video codec format
+ * <li> Video bit rate in bits per second
+ * <li> Video frame rate in frames per second
+ * <li> Video frame width and height,
+ * <li> Video encoder profile.
+ * <p>Audio-specific settings are:
+ * <li> Audio codec format
+ * <li> Audio bit rate in bits per second,
+ * <li> Audio sample rate
+ * <li> Number of audio channels for recording.
+ * </ul>
+ */
+public class EncoderProfiles
+{
+    /**
+     * Default recording duration in seconds before the session is terminated.
+     * This is useful for applications like MMS has limited file size requirement.
+     * This could be 0 if there is no default recording duration.
+     */
+    public int getDurationSeconds() {
+        return durationSecs;
+    }
+
+    /**
+     * Recommended output file format
+     * @see android.media.MediaRecorder.OutputFormat
+     */
+    public int getFileFormat() {
+        return fileFormat;
+    }
+
+    /**
+     * Configuration for a video encoder.
+     */
+    public static class VideoProfile {
+        /**
+         * The video encoder being used for the video track
+         * @see android.media.MediaRecorder.VideoEncoder
+         */
+        public int getCodec() {
+            return codec;
+        }
+
+        /**
+         * The media type of the video encoder being used for the video track
+         * @see android.media.MediaFormat#KEY_MIME
+         */
+        public @NonNull String getMediaType() {
+            if (codec == MediaRecorder.VideoEncoder.H263) {
+                return MediaFormat.MIMETYPE_VIDEO_H263;
+            } else if (codec == MediaRecorder.VideoEncoder.H264) {
+                return MediaFormat.MIMETYPE_VIDEO_AVC;
+            } else if (codec == MediaRecorder.VideoEncoder.MPEG_4_SP) {
+                return MediaFormat.MIMETYPE_VIDEO_MPEG4;
+            } else if (codec == MediaRecorder.VideoEncoder.VP8) {
+                return MediaFormat.MIMETYPE_VIDEO_VP8;
+            } else if (codec == MediaRecorder.VideoEncoder.HEVC) {
+                return MediaFormat.MIMETYPE_VIDEO_HEVC;
+            }
+            // we should never be here
+            throw new RuntimeException("Unknown codec");
+        }
+
+        /**
+         * The target video output bitrate in bits per second
+         * <p>
+         * This is the target recorded video output bitrate if the application configures the video
+         * recording via {@link MediaRecorder#setProfile} without specifying any other
+         * {@link MediaRecorder} encoding parameters. For example, for high speed quality profiles
+         * (from {@link CamcorderProfile#QUALITY_HIGH_SPEED_LOW} to {@link
+         * CamcorderProfile#QUALITY_HIGH_SPEED_2160P}), this is the bitrate where the video is
+         * recorded with. If the application intends to record slow motion videos with the high
+         * speed quality profiles, it must set a different video bitrate that is corresponding to
+         * the desired recording output bit rate (i.e., the encoded video bitrate during normal
+         * playback) via {@link MediaRecorder#setVideoEncodingBitRate}. For example, if {@link
+         * CamcorderProfile#QUALITY_HIGH_SPEED_720P} advertises 240fps {@link #getFrameRate} and
+         * 64Mbps {@link #getBitrate} in the high speed VideoProfile, and the application
+         * intends to record 1/8 factor slow motion recording videos, the application must set 30fps
+         * via {@link MediaRecorder#setVideoFrameRate} and 8Mbps ( {@link #getBitrate} * slow motion
+         * factor) via {@link MediaRecorder#setVideoEncodingBitRate}. Failing to do so will result
+         * in videos with unexpected frame rate and bit rate, or {@link MediaRecorder} error if the
+         * output bit rate exceeds the encoder limit. If the application intends to do the video
+         * recording with {@link MediaCodec} encoder, it must set each individual field of {@link
+         * MediaFormat} similarly according to this VideoProfile.
+         * </p>
+         *
+         * @see #getFrameRate
+         * @see MediaRecorder
+         * @see MediaCodec
+         * @see MediaFormat
+         */
+        public int getBitrate() {
+            return bitrate;
+        }
+
+        /**
+         * The target video frame rate in frames per second.
+         * <p>
+         * This is the target recorded video output frame rate per second if the application
+         * configures the video recording via {@link MediaRecorder#setProfile} without specifying
+         * any other {@link MediaRecorder} encoding parameters. For example, for high speed quality
+         * profiles (from {@link CamcorderProfile#QUALITY_HIGH_SPEED_LOW} to {@link
+         * CamcorderProfile#QUALITY_HIGH_SPEED_2160P}), this is the frame rate where the video is
+         * recorded and played back with. If the application intends to create slow motion use case
+         * with the high speed quality profiles, it must set a different video frame rate that is
+         * corresponding to the desired output (playback) frame rate via {@link
+         * MediaRecorder#setVideoFrameRate}. For example, if {@link
+         * CamcorderProfile#QUALITY_HIGH_SPEED_720P} advertises 240fps {@link #getFrameRate}
+         * in the VideoProfile, and the application intends to create 1/8 factor slow motion
+         * recording videos, the application must set 30fps via {@link
+         * MediaRecorder#setVideoFrameRate}. Failing to do so will result in high speed videos with
+         * normal speed playback frame rate (240fps for above example). If the application intends
+         * to do the video recording with {@link MediaCodec} encoder, it must set each individual
+         * field of {@link MediaFormat} similarly according to this VideoProfile.
+         * </p>
+         *
+         * @see #getBitrate
+         * @see MediaRecorder
+         * @see MediaCodec
+         * @see MediaFormat
+         */
+        public int getFrameRate() {
+            return frameRate;
+        }
+
+        /**
+         * The target video frame width in pixels
+         */
+        public int getWidth() {
+            return width;
+        }
+
+        /**
+         * The target video frame height in pixels
+         */
+        public int getHeight() {
+            return height;
+        }
+
+        /**
+         * The video encoder profile being used for the video track.
+         * <p>
+         * This value is 0 if there is no profile defined for the video codec.
+         *
+         * @see MediaRecorder#setVideoEncodingProfileLevel
+         * @see MediaFormat#KEY_PROFILE
+         */
+        public int getProfile() {
+            return profile;
+        }
+
+        // Constructor called by JNI and CamcorderProfile
+        /* package private */ VideoProfile(int codec,
+                             int width,
+                             int height,
+                             int frameRate,
+                             int bitrate,
+                             int profile) {
+            this.codec = codec;
+            this.width = width;
+            this.height = height;
+            this.frameRate = frameRate;
+            this.bitrate = bitrate;
+            this.profile = profile;
+        }
+
+        private int codec;
+        private int width;
+        private int height;
+        private int frameRate;
+        private int bitrate;
+        private int profile;
+    }
+
+    /**
+     * Returns the defined audio encoder profiles.
+     * <p>
+     * The list may be empty. This means there are no audio encoder
+     * profiles defined. Otherwise, the first profile is the default
+     * audio profile.
+     */
+    public @NonNull List<AudioProfile> getAudioProfiles() {
+        return audioProfiles;
+    }
+
+    /**
+     * Returns the defined video encoder profiles.
+     * <p>
+     * The list may be empty. This means there are no video encoder
+     * profiles defined. Otherwise, the first profile is the default
+     * video profile.
+     */
+    public @NonNull List<VideoProfile> getVideoProfiles() {
+        return videoProfiles;
+    }
+
+    /**
+     * Configuration for an audio encoder.
+     */
+    public static class AudioProfile {
+        /**
+         * The audio encoder being used for the audio track.
+         * @see android.media.MediaRecorder.AudioEncoder
+         */
+        public int getCodec() {
+            return codec;
+        }
+
+        /**
+         * The media type of the audio encoder being used for the video track
+         * @see android.media.MediaFormat#KEY_MIME
+         */
+        public @NonNull String getMediaType() {
+            if (codec == MediaRecorder.AudioEncoder.AMR_NB) {
+                return MediaFormat.MIMETYPE_AUDIO_AMR_NB;
+            } else if (codec == MediaRecorder.AudioEncoder.AMR_WB) {
+                return MediaFormat.MIMETYPE_AUDIO_AMR_WB;
+            } else if (codec == MediaRecorder.AudioEncoder.AAC
+                    || codec == MediaRecorder.AudioEncoder.HE_AAC
+                    || codec == MediaRecorder.AudioEncoder.AAC_ELD) {
+                return MediaFormat.MIMETYPE_AUDIO_AAC;
+            } else if (codec == MediaRecorder.AudioEncoder.VORBIS) {
+                return MediaFormat.MIMETYPE_AUDIO_VORBIS;
+            } else if (codec == MediaRecorder.AudioEncoder.OPUS) {
+                return MediaFormat.MIMETYPE_AUDIO_OPUS;
+            }
+            // we should never be here
+            throw new RuntimeException("Unknown codec");
+        }
+
+        /**
+         * The target audio output bitrate in bits per second
+         */
+        public int getBitrate() {
+            return bitrate;
+        }
+
+        /**
+         * The audio sampling rate used for the audio track
+         */
+        public int getSampleRate() {
+            return sampleRate;
+        }
+
+        /**
+         * The number of audio channels used for the audio track
+         */
+        public int getChannels() {
+            return channels;
+        }
+
+        /**
+         * The audio encoder profile being used for the audio track
+         * <p>
+         * This value is 0 if there is no profile defined for the audio codec.
+         * @see MediaFormat#KEY_PROFILE
+         */
+        public int getProfile() {
+            if (codec == MediaRecorder.AudioEncoder.AAC) {
+                return MediaCodecInfo.CodecProfileLevel.AACObjectMain;
+            } else if (codec == MediaRecorder.AudioEncoder.HE_AAC) {
+                return MediaCodecInfo.CodecProfileLevel.AACObjectHE;
+            } else if (codec == MediaRecorder.AudioEncoder.AAC_ELD) {
+                return MediaCodecInfo.CodecProfileLevel.AACObjectELD;
+            }
+            return 0;
+        }
+
+
+        // Constructor called by JNI and CamcorderProfile
+        /* package private */ AudioProfile(
+                int codec,
+                int channels,
+                int sampleRate,
+                int bitrate) {
+            this.codec = codec;
+            this.channels = channels;
+            this.sampleRate = sampleRate;
+            this.bitrate = bitrate;
+        }
+
+        private int codec;
+        private int channels;
+        private int sampleRate;
+        private int bitrate;
+    }
+
+    //static {
+    //    System.loadLibrary("media_jni");
+    //native_init();
+    //}
+
+    private int durationSecs;
+    private int fileFormat;
+    // non-modifiable lists
+    private @NonNull List<AudioProfile> audioProfiles;
+    private @NonNull List<VideoProfile> videoProfiles;
+
+    // Constructor called by JNI and CamcorderProfile
+    /* package private */ EncoderProfiles(
+            int duration,
+            int fileFormat,
+            VideoProfile[] videoProfiles,
+            AudioProfile[] audioProfiles) {
+        this.durationSecs     = duration;
+        this.fileFormat       = fileFormat;
+        this.videoProfiles    = Collections.unmodifiableList(Arrays.asList(videoProfiles));
+        this.audioProfiles    = Collections.unmodifiableList(Arrays.asList(audioProfiles));
+    }
+}
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index 4f87fe6..36cf989 100755
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -158,6 +158,14 @@
 
     oneway void reloadAudioSettings();
 
+    boolean setSurroundFormatEnabled(int audioFormat, boolean enabled);
+
+    boolean isSurroundFormatEnabled(int audioFormat);
+
+    boolean setEncodedSurroundMode(int mode);
+
+    int getEncodedSurroundMode();
+
     oneway void avrcpSupportsAbsoluteVolume(String address, boolean support);
 
     void setSpeakerphoneOn(IBinder cb, boolean on);
@@ -366,4 +374,13 @@
     long getAdditionalOutputDeviceDelay(in AudioDeviceAttributes device);
 
     long getMaxAdditionalOutputDeviceDelay(in AudioDeviceAttributes device);
+
+    int requestAudioFocusForTest(in AudioAttributes aa, int durationHint, IBinder cb,
+            in IAudioFocusDispatcher fd, in String clientId, in String callingPackageName,
+            int uid, int sdk);
+
+    int abandonAudioFocusForTest(in IAudioFocusDispatcher fd, in String clientId,
+            in AudioAttributes aa, in String callingPackageName);
+
+    long getFadeOutDurationOnFocusLossMillis(in AudioAttributes aa);
 }
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index cf31e41..b51777c 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -25,7 +25,6 @@
 import android.graphics.SurfaceTexture;
 import android.hardware.HardwareBuffer;
 import android.media.MediaCodecInfo.CodecCapabilities;
-import android.media.metrics.PlaybackComponent;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
@@ -46,6 +45,7 @@
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
@@ -1539,7 +1539,7 @@
   </tbody>
  </table>
  */
-final public class MediaCodec implements PlaybackComponent {
+final public class MediaCodec {
 
     /**
      * Per buffer metadata includes an offset and size specifying
@@ -1674,9 +1674,11 @@
     public @interface BufferFlag {}
 
     private EventHandler mEventHandler;
+    private EventHandler mOnFirstTunnelFrameReadyHandler;
     private EventHandler mOnFrameRenderedHandler;
     private EventHandler mCallbackHandler;
     private Callback mCallback;
+    private OnFirstTunnelFrameReadyListener mOnFirstTunnelFrameReadyListener;
     private OnFrameRenderedListener mOnFrameRenderedListener;
     private final Object mListenerLock = new Object();
     private MediaCodecInfo mCodecInfo;
@@ -1687,6 +1689,7 @@
     private static final int EVENT_CALLBACK = 1;
     private static final int EVENT_SET_CALLBACK = 2;
     private static final int EVENT_FRAME_RENDERED = 3;
+    private static final int EVENT_FIRST_TUNNEL_FRAME_READY = 4;
 
     private static final int CB_INPUT_AVAILABLE = 1;
     private static final int CB_OUTPUT_AVAILABLE = 2;
@@ -1694,22 +1697,6 @@
     private static final int CB_OUTPUT_FORMAT_CHANGE = 4;
 
 
-    /**
-     * @hide
-     */
-    @Override
-    public void setPlaybackId(@NonNull String playbackId) {
-        // TODO: add a native method to pass the ID to the native code for logging.
-        mPlaybackId = playbackId;
-    }
-    /**
-     * @hide
-     */
-    @Override
-    public String getPlaybackId() {
-        return mPlaybackId;
-    }
-
     private class EventHandler extends Handler {
         private MediaCodec mCodec;
 
@@ -1748,6 +1735,16 @@
                                 mCodec, (long)mediaTimeUs, (long)systemNano);
                     }
                     break;
+                case EVENT_FIRST_TUNNEL_FRAME_READY:
+                    OnFirstTunnelFrameReadyListener onFirstTunnelFrameReadyListener;
+                    synchronized (mListenerLock) {
+                        onFirstTunnelFrameReadyListener = mOnFirstTunnelFrameReadyListener;
+                    }
+                    if (onFirstTunnelFrameReadyListener == null) {
+                        break;
+                    }
+                    onFirstTunnelFrameReadyListener.onFirstTunnelFrameReady(mCodec);
+                    break;
                 default:
                 {
                     break;
@@ -1923,6 +1920,7 @@
             mEventHandler = null;
         }
         mCallbackHandler = mEventHandler;
+        mOnFirstTunnelFrameReadyHandler = mEventHandler;
         mOnFrameRenderedHandler = mEventHandler;
 
         mBufferLock = new Object();
@@ -2277,6 +2275,9 @@
                 mCallbackHandler.removeMessages(EVENT_SET_CALLBACK);
                 mCallbackHandler.removeMessages(EVENT_CALLBACK);
             }
+            if (mOnFirstTunnelFrameReadyHandler != null) {
+                mOnFirstTunnelFrameReadyHandler.removeMessages(EVENT_FIRST_TUNNEL_FRAME_READY);
+            }
             if (mOnFrameRenderedHandler != null) {
                 mOnFrameRenderedHandler.removeMessages(EVENT_FRAME_RENDERED);
             }
@@ -4447,6 +4448,41 @@
             MediaFormat.KEY_LOW_LATENCY;
 
     /**
+     * Control video peek of the first frame when a codec is configured for tunnel mode with
+     * {@link MediaFormat#KEY_AUDIO_SESSION_ID} while the {@link AudioTrack} is paused.
+     *<p>
+     * When disabled (1) after a {@link #flush} or {@link #start}, (2) while the corresponding
+     * {@link AudioTrack} is paused and (3) before any buffers are queued, the first frame is not to
+     * be rendered until either this parameter is enabled or the corresponding {@link AudioTrack}
+     * has begun playback. Once the frame is decoded and ready to be rendered,
+     * {@link OnFirstTunnelFrameReadyListener#onFirstTunnelFrameReady} is called but the frame is
+     * not rendered. The surface continues to show the previously-rendered content, or black if the
+     * surface is new. A subsequent call to {@link AudioTrack#play} renders this frame and triggers
+     * a callback to {@link OnFrameRenderedListener#onFrameRendered}, and video playback begins.
+     *<p>
+     * <b>Note</b>: To clear any previously rendered content and show black, configure the
+     * MediaCodec with {@code KEY_PUSH_BLANK_BUFFERS_ON_STOP(1)}, and call {@link #stop} before
+     * pushing new video frames to the codec.
+     *<p>
+     * When enabled (1) after a {@link #flush} or {@link #start} and (2) while the corresponding
+     * {@link AudioTrack} is paused, the first frame is rendered as soon as it is decoded, or
+     * immediately, if it has already been decoded. If not already decoded, when the frame is
+     * decoded and ready to be rendered,
+     * {@link OnFirstTunnelFrameReadyListener#onFirstTunnelFrameReady} is called. The frame is then
+     * immediately rendered and {@link OnFrameRenderedListener#onFrameRendered} is subsequently
+     * called.
+     *<p>
+     * The value is an Integer object containing the value 1 to enable or the value 0 to disable.
+     *<p>
+     * The default for this parameter is <b>enabled</b>. Once a frame has been rendered, changing
+     * this parameter has no effect until a subsequent {@link #flush} or
+     * {@link #stop}/{@link #start}.
+     *
+     * @see #setParameters(Bundle)
+     */
+    public static final String PARAMETER_KEY_TUNNEL_PEEK = "tunnel-peek";
+
+    /**
      * Communicate additional parameter changes to the component instance.
      * <b>Note:</b> Some of these parameter changes may silently fail to apply.
      *
@@ -4545,6 +4581,55 @@
     }
 
     /**
+     * Listener to be called when the first output frame has been decoded
+     * and is ready to be rendered for a codec configured for tunnel mode with
+     * {@code KEY_AUDIO_SESSION_ID}.
+     *
+     * @see MediaCodec#setOnFirstTunnelFrameReadyListener
+     */
+    public interface OnFirstTunnelFrameReadyListener {
+
+        /**
+         * Called when the first output frame has been decoded and is ready to be
+         * rendered.
+         */
+        void onFirstTunnelFrameReady(@NonNull MediaCodec codec);
+    }
+
+    /**
+     * Registers a callback to be invoked when the first output frame has been decoded
+     * and is ready to be rendered on a codec configured for tunnel mode with {@code
+     * KEY_AUDIO_SESSION_ID}.
+     *
+     * @param handler the callback will be run on the handler's thread. If {@code
+     * null}, the callback will be run on the default thread, which is the looper from
+     * which the codec was created, or a new thread if there was none.
+     *
+     * @param listener the callback that will be run. If {@code null}, clears any registered
+     * listener.
+     */
+    public void setOnFirstTunnelFrameReadyListener(
+            @Nullable Handler handler, @Nullable OnFirstTunnelFrameReadyListener listener) {
+        synchronized (mListenerLock) {
+            mOnFirstTunnelFrameReadyListener = listener;
+            if (listener != null) {
+                EventHandler newHandler = getEventHandlerOn(
+                        handler,
+                        mOnFirstTunnelFrameReadyHandler);
+                if (newHandler != mOnFirstTunnelFrameReadyHandler) {
+                    mOnFirstTunnelFrameReadyHandler.removeMessages(EVENT_FIRST_TUNNEL_FRAME_READY);
+                }
+                mOnFirstTunnelFrameReadyHandler = newHandler;
+            } else if (mOnFirstTunnelFrameReadyHandler != null) {
+                mOnFirstTunnelFrameReadyHandler.removeMessages(EVENT_FIRST_TUNNEL_FRAME_READY);
+            }
+            native_enableOnFirstTunnelFrameReadyListener(listener != null);
+        }
+    }
+
+    private native void native_enableOnFirstTunnelFrameReadyListener(boolean enable);
+
+    /**
      * Listener to be called when an output frame has rendered on the output surface
      *
      * @see MediaCodec#setOnFrameRenderedListener
@@ -4606,6 +4691,128 @@
 
     private native void native_enableOnFrameRenderedListener(boolean enable);
 
+    /**
+     * Returns a list of vendor parameter names.
+     * <p>
+     * This method can be called in any codec state except for released state.
+     *
+     * @return a list containing supported vendor parameters; an empty
+     *         list if no vendor parameters are supported. The order of the
+     *         parameters is arbitrary.
+     * @throws IllegalStateException if in the Released state.
+     */
+    @NonNull
+    public List<String> getSupportedVendorParameters() {
+        return native_getSupportedVendorParameters();
+    }
+
+    @NonNull
+    private native List<String> native_getSupportedVendorParameters();
+
+    /**
+     * Contains description of a parameter.
+     */
+    public static class ParameterDescriptor {
+        private ParameterDescriptor() {}
+
+        /**
+         * Returns the name of the parameter.
+         */
+        @NonNull
+        public String getName() {
+            return mName;
+        }
+
+        /**
+         * Returns the type of the parameter.
+         * {@link MediaFormat#TYPE_NULL} is never returned.
+         */
+        @MediaFormat.Type
+        public int getType() {
+            return mType;
+        }
+
+        private String mName;
+        private @MediaFormat.Type int mType;
+    }
+
+    /**
+     * Describe a parameter with the name.
+     * <p>
+     * This method can be called in any codec state except for released state.
+     *
+     * @param name name of the parameter to describe, typically one from
+     *             {@link #getSupportedVendorParameters}.
+     * @return {@link ParameterDescriptor} object that describes the parameter.
+     *         {@code null} if unrecognized / not able to describe.
+     * @throws IllegalStateException if in the Released state.
+     */
+    @Nullable
+    public ParameterDescriptor getParameterDescriptor(@NonNull String name) {
+        return native_getParameterDescriptor(name);
+    }
+
+    @Nullable
+    private native ParameterDescriptor native_getParameterDescriptor(@NonNull String name);
+
+    /**
+     * Subscribe to vendor parameters, so that changes to these parameters generate
+     * output format change event.
+     * <p>
+     * Unrecognized parameter names or standard (non-vendor) parameter names will be ignored.
+     * {@link #reset} also resets the list of subscribed parameters.
+     * If a parameter in {@code names} is already subscribed, it will remain subscribed.
+     * <p>
+     * This method can be called in any codec state except for released state. When called in
+     * running state with newly subscribed parameters, it takes effect no later than the
+     * processing of the subsequently queued buffer. For the new parameters, the codec will generate
+     * output format change event.
+     * <p>
+     * Note that any vendor parameters set in a {@link #configure} or
+     * {@link #setParameters} call are automatically subscribed.
+     * <p>
+     * See also {@link #INFO_OUTPUT_FORMAT_CHANGED} or {@link Callback#onOutputFormatChanged}
+     * for output format change events.
+     *
+     * @param names names of the vendor parameters to subscribe. This may be an empty list,
+     *              and in that case this method will not change the list of subscribed parameters.
+     * @throws IllegalStateException if in the Released state.
+     */
+    public void subscribeToVendorParameters(@NonNull List<String> names) {
+        native_subscribeToVendorParameters(names);
+    }
+
+    private native void native_subscribeToVendorParameters(@NonNull List<String> names);
+
+    /**
+     * Unsubscribe from vendor parameters, so that changes to these parameters
+     * no longer generate output format change event.
+     * <p>
+     * Unrecognized parameter names, standard (non-vendor) parameter names will be ignored.
+     * {@link #reset} also resets the list of subscribed parameters.
+     * If a parameter in {@code names} is already unsubscribed, it will remain unsubscribed.
+     * <p>
+     * This method can be called in any codec state except for released state. When called in
+     * running state with newly unsubscribed parameters, it takes effect no later than the
+     * processing of the subsequently queued buffer.
+     * <p>
+     * Note that any vendor parameters set in a {@link #configure} or
+     * {@link #setParameters} call are automatically subscribed, and with this method
+     * they can be unsubscribed.
+     * <p>
+     * See also {@link #INFO_OUTPUT_FORMAT_CHANGED} or {@link Callback#onOutputFormatChanged}
+     * for output format change events.
+     *
+     * @param names names of the vendor parameters to unsubscribe. This may be an empty list,
+     *              and in that case this method will not change the list of subscribed parameters.
+     * @throws IllegalStateException if in the Released state.
+     */
+    public void unsubscribeFromVendorParameters(@NonNull List<String> names) {
+        native_unsubscribeFromVendorParameters(names);
+    }
+
+    private native void native_unsubscribeFromVendorParameters(@NonNull List<String> names);
+
     private EventHandler getEventHandlerOn(
             @Nullable Handler handler, @NonNull EventHandler lastHandler) {
         if (handler == null) {
@@ -4667,6 +4874,8 @@
             EventHandler handler = mEventHandler;
             if (what == EVENT_CALLBACK) {
                 handler = mCallbackHandler;
+            } else if (what == EVENT_FIRST_TUNNEL_FRAME_READY) {
+                handler = mOnFirstTunnelFrameReadyHandler;
             } else if (what == EVENT_FRAME_RENDERED) {
                 handler = mOnFrameRenderedHandler;
             }
diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java
index 06d0eb0..c3b1bca 100644
--- a/media/java/android/media/MediaCodecInfo.java
+++ b/media/java/android/media/MediaCodecInfo.java
@@ -571,6 +571,14 @@
         public static final String FEATURE_LowLatency = "low-latency";
 
         /**
+         * <b>video encoder only</b>: codec supports quantization parameter bounds.
+         * @see MediaFormat#KEY_VIDEO_QP_MAX
+         * @see MediaFormat#KEY_VIDEO_QP_MIN
+         */
+        @SuppressLint("AllUpper")
+        public static final String FEATURE_QpBounds = "qp-bounds";
+
+        /**
          * Query codec feature capabilities.
          * <p>
          * These features are supported to be used by the codec.  These
@@ -606,6 +614,7 @@
             new Feature(FEATURE_IntraRefresh, (1 << 0), false),
             new Feature(FEATURE_MultipleFrames, (1 << 1), false),
             new Feature(FEATURE_DynamicTimestamp, (1 << 2), false),
+            new Feature(FEATURE_QpBounds, (1 << 3), false),
         };
 
         /** @hide */
@@ -3434,11 +3443,14 @@
         public static final int BITRATE_MODE_VBR = 1;
         /** Constant bitrate mode */
         public static final int BITRATE_MODE_CBR = 2;
+        /** Constant bitrate mode with frame drops */
+        public static final int BITRATE_MODE_CBR_FD =  3;
 
         private static final Feature[] bitrates = new Feature[] {
             new Feature("VBR", BITRATE_MODE_VBR, true),
             new Feature("CBR", BITRATE_MODE_CBR, false),
-            new Feature("CQ",  BITRATE_MODE_CQ,  false)
+            new Feature("CQ",  BITRATE_MODE_CQ,  false),
+            new Feature("CBR-FD", BITRATE_MODE_CBR_FD, false)
         };
 
         private static int parseBitrateMode(String mode) {
diff --git a/media/java/android/media/MediaDrm.java b/media/java/android/media/MediaDrm.java
index ae64c02..10b99dc 100644
--- a/media/java/android/media/MediaDrm.java
+++ b/media/java/android/media/MediaDrm.java
@@ -27,7 +27,7 @@
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.Signature;
-import android.media.metrics.PlaybackComponent;
+import android.media.metrics.LogSessionId;
 import android.os.Handler;
 import android.os.HandlerExecutor;
 import android.os.Looper;
@@ -50,6 +50,7 @@
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Set;
 import java.util.UUID;
 import java.util.concurrent.ConcurrentHashMap;
@@ -1379,7 +1380,7 @@
     public byte[] openSession(@SecurityLevel int level) throws
             NotProvisionedException, ResourceBusyException {
         byte[] sessionId = openSessionNative(level);
-        mPlaybackComponentMap.put(ByteBuffer.wrap(sessionId), new PlaybackComponentImpl(sessionId));
+        mPlaybackComponentMap.put(ByteBuffer.wrap(sessionId), new PlaybackComponent(sessionId));
         return sessionId;
     }
 
@@ -2929,8 +2930,8 @@
 
     /**
      * Obtain a {@link PlaybackComponent} associated with a DRM session.
-     * Call {@link PlaybackComponent#setPlaybackId(String)} on the returned object
-     * to associate a playback session with the DRM session.
+     * Call {@link PlaybackComponent#setLogSessionId(LogSessionId)} on
+     * the returned object to associate a playback session with the DRM session.
      *
      * @param sessionId a DRM session ID obtained from {@link #openSession()}
      * @return a {@link PlaybackComponent} associated with the session,
@@ -2945,28 +2946,37 @@
         return mPlaybackComponentMap.get(ByteBuffer.wrap(sessionId));
     }
 
-    private native void setPlaybackId(byte[] sessionId, String playbackId);
+    private native void setPlaybackId(byte[] sessionId, String logSessionId);
 
-    private final class PlaybackComponentImpl implements PlaybackComponent {
+    /** This class contains the Drm session ID and log session ID */
+    public final class PlaybackComponent {
         private final byte[] mSessionId;
-        private String mPlaybackId = "";
+        @NonNull private LogSessionId mLogSessionId = LogSessionId.LOG_SESSION_ID_NONE;
 
-        public PlaybackComponentImpl(byte[] sessionId) {
+        /** @hide */
+        public PlaybackComponent(byte[] sessionId) {
             mSessionId = sessionId;
         }
 
-        @Override
-        public void setPlaybackId(@NonNull String playbackId) {
-            if (playbackId == null) {
+
+        /**
+         * Gets the {@link LogSessionId}.
+         */
+        public void setLogSessionId(@NonNull LogSessionId logSessionId) {
+            Objects.requireNonNull(logSessionId);
+            if (logSessionId.getStringId() == null) {
                 throw new IllegalArgumentException("playbackId is null");
             }
-            MediaDrm.this.setPlaybackId(mSessionId, playbackId);
-            mPlaybackId = playbackId;
+            MediaDrm.this.setPlaybackId(mSessionId, logSessionId.getStringId());
+            mLogSessionId = logSessionId;
         }
 
-        @Override
-        @NonNull public String getPlaybackId() {
-            return mPlaybackId;
+
+        /**
+         * Returns the {@link LogSessionId}.
+         */
+        @NonNull public LogSessionId getLogSessionId() {
+            return mLogSessionId;
         }
     }
 
diff --git a/media/java/android/media/MediaExtractor.java b/media/java/android/media/MediaExtractor.java
index 8f60330..283f1f1 100644
--- a/media/java/android/media/MediaExtractor.java
+++ b/media/java/android/media/MediaExtractor.java
@@ -22,6 +22,7 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.res.AssetFileDescriptor;
+import android.media.metrics.LogSessionId;
 import android.net.Uri;
 import android.os.IBinder;
 import android.os.IHwBinder;
@@ -40,6 +41,7 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.UUID;
 import java.util.stream.Collectors;
 
@@ -73,7 +75,7 @@
  * <p>This class requires the {@link android.Manifest.permission#INTERNET} permission
  * when used with network-based content.
  */
-final public class MediaExtractor {
+public final class MediaExtractor {
     public MediaExtractor() {
         native_setup();
     }
@@ -768,6 +770,22 @@
     public native boolean hasCacheReachedEndOfStream();
 
     /**
+     * Sets the {@link LogSessionId} for MediaExtractor.
+     */
+    public void setLogSessionId(@NonNull LogSessionId logSessionId) {
+        mLogSessionId = Objects.requireNonNull(logSessionId);
+        // TODO: implement native_setPlaybackId(playbackId);
+    }
+
+    /**
+     * Returns the {@link LogSessionId} for MediaExtractor.
+     */
+    @NonNull
+    public LogSessionId getLogSessionId() {
+        return mLogSessionId;
+    }
+
+    /**
      *  Return Metrics data about the current media container.
      *
      * @return a {@link PersistableBundle} containing the set of attributes and values
@@ -796,6 +814,7 @@
     }
 
     private MediaCas mMediaCas;
+    @NonNull private LogSessionId mLogSessionId = LogSessionId.LOG_SESSION_ID_NONE;
 
     private long mNativeContext;
 
diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java
index 4e8a273..af0a9cf 100644
--- a/media/java/android/media/MediaFormat.java
+++ b/media/java/android/media/MediaFormat.java
@@ -985,19 +985,27 @@
 
     /**
      * A key describing the maximum Quantization Parameter allowed for encoding video.
-     * This key applies to all three video frame types (I, P, and B). This value fills
-     * in for any of the frame-specific #KEY_VIDEO_QP_I_MAX, #KEY_VIDEO_QP_P_MAX, or
-     * #KEY_VIDEO_QP_B_MAX keys that are not specified
+     * This key applies to all three video picture types (I, P, and B).
+     * The value is used directly for picture type I; a per-mime formula is used
+     * to calculate the value for the remaining picture types.
+     *
+     * This calculation can be avoided by directly specifying values for each picture type
+     * using the type-specific keys {@link #KEY_VIDEO_QP_I_MAX}, {@link #KEY_VIDEO_QP_P_MAX},
+     * and {@link #KEY_VIDEO_QP_B_MAX}.
      *
      * The associated value is an integer.
      */
     public static final String KEY_VIDEO_QP_MAX = "video-qp-max";
 
     /**
-     * A key describing the maximum Quantization Parameter allowed for encoding video.
-     * This key applies to all three video frame types (I, P, and B). This value fills
-     * in for any of the frame-specific #KEY_VIDEO_QP_I_MIN, #KEY_VIDEO_QP_P_MIN, or
-     * #KEY_VIDEO_QP_B_MIN keys that are not specified
+     * A key describing the minimum Quantization Parameter allowed for encoding video.
+     * This key applies to all three video frame types (I, P, and B).
+     * The value is used directly for picture type I; a per-mime formula is used
+     * to calculate the value for the remaining picture types.
+     *
+     * This calculation can be avoided by directly specifying values for each picture type
+     * using the type-specific keys {@link #KEY_VIDEO_QP_I_MIN}, {@link #KEY_VIDEO_QP_P_MIN},
+     * and {@link #KEY_VIDEO_QP_B_MIN}.
      *
      * The associated value is an integer.
      */
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 3de78bb..644afb7 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -99,9 +99,7 @@
 
 
 /**
- * MediaPlayer class can be used to control playback
- * of audio/video files and streams. An example on how to use the methods in
- * this class can be found in {@link android.widget.VideoView}.
+ * MediaPlayer class can be used to control playback of audio/video files and streams.
  *
  * <p>MediaPlayer is not thread-safe. Creation of and all access to player instances
  * should be on the same thread. If registering <a href="#Callbacks">callbacks</a>,
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index dd08d8a..5eb57da 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -29,6 +29,7 @@
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.hardware.Camera;
+import android.media.metrics.LogSessionId;
 import android.media.permission.Identity;
 import android.os.Build;
 import android.os.Handler;
@@ -130,6 +131,8 @@
 
     private int mChannelCount;
 
+    @NonNull private LogSessionId mLogSessionId = LogSessionId.LOG_SESSION_ID_NONE;
+
     /**
      * Default constructor.
      *
@@ -165,6 +168,27 @@
     }
 
     /**
+     * Sets the {@link LogSessionId} for MediaRecorder.
+     *
+     * @param id the global ID for monitoring the MediaRecorder performance
+     */
+    public void setLogSessionId(@NonNull LogSessionId id) {
+        Objects.requireNonNull(id);
+        mLogSessionId = id;
+        setParameter("log-session-id=" + id.getStringId());
+    }
+
+    /**
+     * Returns the {@link LogSessionId} for MediaRecorder.
+     *
+     * @return the global ID for monitoring the MediaRecorder performance
+     */
+    @NonNull
+    public LogSessionId getLogSessionId() {
+        return mLogSessionId;
+    }
+
+    /**
      * Sets a {@link android.hardware.Camera} to use for recording.
      *
      * <p>Use this function to switch quickly between preview and capture mode without a teardown of
@@ -729,6 +753,47 @@
     }
 
     /**
+     * Uses the settings from an AudioProfile for recording.
+     * <p>
+     * This method should be called after the video AND audio sources are set, and before
+     * setOutputFile().
+     * <p>
+     * This method can be used instead of {@link #setProfile} when using EncoderProfiles.
+     *
+     * @param profile the AudioProfile to use
+     * @see android.media.EncoderProfiles
+     * @see android.media.CamcorderProfile#getAll
+     */
+    public void setAudioProfile(@NonNull EncoderProfiles.AudioProfile profile) {
+        setAudioEncodingBitRate(profile.getBitrate());
+        setAudioChannels(profile.getChannels());
+        setAudioSamplingRate(profile.getSampleRate());
+        setAudioEncoder(profile.getCodec());
+    }
+
+    /**
+     * Uses the settings from a VideoProfile object for recording.
+     * <p>
+     * This method should be called after the video AND audio sources are set, and before
+     * setOutputFile().
+     * <p>
+     * This method can be used instead of {@link #setProfile} when using EncoderProfiles.
+     *
+     * @param profile the VideoProfile to use
+     * @see android.media.EncoderProfiles
+     * @see android.media.CamcorderProfile#getAll
+     */
+    public void setVideoProfile(@NonNull EncoderProfiles.VideoProfile profile) {
+        setVideoFrameRate(profile.getFrameRate());
+        setVideoSize(profile.getWidth(), profile.getHeight());
+        setVideoEncodingBitRate(profile.getBitrate());
+        setVideoEncoder(profile.getCodec());
+        if (profile.getProfile() > 0) {
+            setVideoEncodingProfileLevel(profile.getProfile(), 0 /* level */);
+        }
+    }
+
+    /**
      * Set video frame capture rate. This can be used to set a different video frame capture
      * rate than the recorded video's playback rate. This method also sets the recording mode
      * to time lapse. In time lapse video recording, only video is recorded. Audio related
@@ -1937,4 +2002,3 @@
 
     }
 }
-
diff --git a/media/java/android/media/MediaRouter2.java b/media/java/android/media/MediaRouter2.java
index 02fa040..1f6855a 100644
--- a/media/java/android/media/MediaRouter2.java
+++ b/media/java/android/media/MediaRouter2.java
@@ -194,6 +194,14 @@
 
     /**
      * 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.
      *
      * @see #stopScan()
@@ -208,6 +216,15 @@
 
     /**
      * 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.
      *
      * @see #startScan()
diff --git a/media/java/android/media/MediaRouter2Manager.java b/media/java/android/media/MediaRouter2Manager.java
index 6fefbe1..758a813 100644
--- a/media/java/android/media/MediaRouter2Manager.java
+++ b/media/java/android/media/MediaRouter2Manager.java
@@ -148,6 +148,14 @@
 
     /**
      * 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 Callback} to get the route related events.
+     * <p>
      * @see #stopScan()
      */
     public void startScan() {
@@ -163,6 +171,15 @@
 
     /**
      * 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 Callback#onRoutesAdded(List)}
+     * is not called afterwards.
+     * <p>
+     * Use {@link Callback} to get the route related events.
+     *
      * @see #startScan()
      */
     public void stopScan() {
diff --git a/media/java/android/media/RouteDiscoveryPreference.java b/media/java/android/media/RouteDiscoveryPreference.java
index 2f95247..37fee84 100644
--- a/media/java/android/media/RouteDiscoveryPreference.java
+++ b/media/java/android/media/RouteDiscoveryPreference.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.SystemApi;
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -68,9 +69,10 @@
     private final Bundle mExtras;
 
     /**
-     * An empty discovery preference
+     * An empty discovery preference.
      * @hide
      */
+    @SystemApi
     public static final RouteDiscoveryPreference EMPTY =
             new Builder(Collections.emptyList(), false).build();
 
diff --git a/media/java/android/media/metrics/Event.java b/media/java/android/media/metrics/Event.java
index 96b61d2..17218f0 100644
--- a/media/java/android/media/metrics/Event.java
+++ b/media/java/android/media/metrics/Event.java
@@ -17,6 +17,7 @@
 package android.media.metrics;
 
 import android.annotation.IntRange;
+import android.annotation.NonNull;
 import android.os.Bundle;
 
 /**
@@ -24,7 +25,7 @@
  */
 public abstract class Event {
     final long mTimeSinceCreatedMillis;
-    Bundle mExtras;
+    Bundle mMetricsBundle = new Bundle();
 
     // hide default constructor
     /* package */ Event() {
@@ -38,7 +39,7 @@
 
     /* package */ Event(long timeSinceCreatedMillis, Bundle extras) {
         mTimeSinceCreatedMillis = timeSinceCreatedMillis;
-        mExtras = extras;
+        mMetricsBundle = extras;
     }
 
     /**
@@ -50,8 +51,12 @@
         return mTimeSinceCreatedMillis;
     }
 
-    /** @hide */
-    public Bundle getExtras() {
-        return mExtras;
+    /**
+     * Gets metrics-related information that is not supported by dedicated methods.
+     * <p>It is intended to be used for backwards compatibility by the metrics infrastructure.
+     */
+    @NonNull
+    public Bundle getMetricsBundle() {
+        return mMetricsBundle;
     }
 }
diff --git a/media/java/android/media/metrics/LogSessionId.java b/media/java/android/media/metrics/LogSessionId.java
index 7ddb259..41f3093 100644
--- a/media/java/android/media/metrics/LogSessionId.java
+++ b/media/java/android/media/metrics/LogSessionId.java
@@ -16,19 +16,50 @@
 
 package android.media.metrics;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.TestApi;
+
+import java.util.Objects;
+
 /**
  * An instances of this class represents the ID of a log session.
- * @hide
  */
-public class LogSessionId {
-    private final String mSessionId;
+public final class LogSessionId {
+    @NonNull private final String mSessionId;
 
-    /* package */ LogSessionId(String id) {
-        mSessionId = id;
-    }
+    /**
+     * A {@link LogSessionId} object which is used to clear any existing session ID.
+     */
+    @NonNull public static final LogSessionId LOG_SESSION_ID_NONE = new LogSessionId("");
 
     /** @hide */
+    @TestApi
+    public LogSessionId(@NonNull String id) {
+        mSessionId = Objects.requireNonNull(id);
+    }
+
+    /** Returns the ID represented by a string. */
+    @NonNull
     public String getStringId() {
         return mSessionId;
     }
+
+    @Override
+    public String toString() {
+        return mSessionId;
+    }
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        LogSessionId that = (LogSessionId) o;
+        return Objects.equals(mSessionId, that.mSessionId);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mSessionId);
+    }
 }
diff --git a/media/java/android/media/metrics/MediaMetricsManager.java b/media/java/android/media/metrics/MediaMetricsManager.java
index 9710e88..b4a74a3 100644
--- a/media/java/android/media/metrics/MediaMetricsManager.java
+++ b/media/java/android/media/metrics/MediaMetricsManager.java
@@ -104,7 +104,6 @@
 
     /**
      * Creates a recording session.
-     * @hide
      */
     @NonNull
     public RecordingSession createRecordingSession() {
diff --git a/media/java/android/media/metrics/NetworkEvent.java b/media/java/android/media/metrics/NetworkEvent.java
index 18660682..0e80543 100644
--- a/media/java/android/media/metrics/NetworkEvent.java
+++ b/media/java/android/media/metrics/NetworkEvent.java
@@ -32,10 +32,7 @@
  * Media network event.
  */
 public final class NetworkEvent extends Event implements Parcelable {
-    /** Network type is not specified. Default type. */
-    public static final int NETWORK_TYPE_NONE = 0;
-    // TODO: replace NONE with UNKNOWN
-    /** @hide */
+    /** Network type is not known. Default type. */
     public static final int NETWORK_TYPE_UNKNOWN = 0;
     /** Other network type */
     public static final int NETWORK_TYPE_OTHER = 1;
@@ -54,7 +51,6 @@
     /** 5G SA network */
     public static final int NETWORK_TYPE_5G_SA = 8;
     /** Not network connected */
-    /** @hide */
     public static final int NETWORK_TYPE_OFFLINE = 9;
 
     private final int mNetworkType;
@@ -62,7 +58,6 @@
 
     /** @hide */
     @IntDef(prefix = "NETWORK_TYPE_", value = {
-        NETWORK_TYPE_NONE,
         NETWORK_TYPE_UNKNOWN,
         NETWORK_TYPE_OTHER,
         NETWORK_TYPE_WIFI,
@@ -83,8 +78,8 @@
      */
     public static String networkTypeToString(@NetworkType int value) {
         switch (value) {
-            case NETWORK_TYPE_NONE:
-                return "NETWORK_TYPE_NONE";
+            case NETWORK_TYPE_UNKNOWN:
+                return "NETWORK_TYPE_UNKNOWN";
             case NETWORK_TYPE_OTHER:
                 return "NETWORK_TYPE_OTHER";
             case NETWORK_TYPE_WIFI:
@@ -114,10 +109,10 @@
      * @hide
      */
     public NetworkEvent(@NetworkType int type, long timeSinceCreatedMillis,
-            @Nullable Bundle extras) {
+            @NonNull Bundle extras) {
         this.mNetworkType = type;
         this.mTimeSinceCreatedMillis = timeSinceCreatedMillis;
-        this.mExtras = extras == null ? null : extras.deepCopy();
+        this.mMetricsBundle = extras == null ? null : extras.deepCopy();
     }
 
     /**
@@ -138,6 +133,16 @@
         return mTimeSinceCreatedMillis;
     }
 
+    /**
+     * Gets metrics-related information that is not supported by dedicated methods.
+     * <p>It is intended to be used for backwards compatibility by the metrics infrastructure.
+     */
+    @Override
+    @NonNull
+    public Bundle getMetricsBundle() {
+        return mMetricsBundle;
+    }
+
     @Override
     public String toString() {
         return "NetworkEvent { "
@@ -162,12 +167,9 @@
 
     @Override
     public void writeToParcel(@NonNull android.os.Parcel dest, int flags) {
-        byte flg = 0;
-        if (mExtras != null) flg |= 0x1;
-        dest.writeByte(flg);
         dest.writeInt(mNetworkType);
         dest.writeLong(mTimeSinceCreatedMillis);
-        if (mExtras != null) dest.writeBundle(mExtras);
+        dest.writeBundle(mMetricsBundle);
     }
 
     @Override
@@ -177,14 +179,13 @@
 
     /** @hide */
     /* package-private */ NetworkEvent(@NonNull android.os.Parcel in) {
-        byte flg = in.readByte();
         int type = in.readInt();
         long timeSinceCreatedMillis = in.readLong();
-        Bundle extras = (flg & 0x2) == 0 ? null : in.readBundle();
+        Bundle extras = in.readBundle();
 
         this.mNetworkType = type;
         this.mTimeSinceCreatedMillis = timeSinceCreatedMillis;
-        this.mExtras = extras;
+        this.mMetricsBundle = extras;
     }
 
     /**
@@ -207,9 +208,9 @@
      * A builder for {@link NetworkEvent}
      */
     public static final class Builder {
-        private int mNetworkType = NETWORK_TYPE_NONE;
+        private int mNetworkType = NETWORK_TYPE_UNKNOWN;
         private long mTimeSinceCreatedMillis = -1;
-        private Bundle mExtras;
+        private Bundle mMetricsBundle = new Bundle();
 
         /**
          * Creates a new Builder.
@@ -236,18 +237,20 @@
         }
 
         /**
-         * Set extras for compatibility.
-         * <p>Should be used by support library only.
-         * @hide
+         * Sets metrics-related information that is not supported by dedicated
+         * methods.
+         * <p>It is intended to be used for backwards compatibility by the
+         * metrics infrastructure.
          */
-        public @NonNull Builder setExtras(@NonNull Bundle extras) {
-            mExtras = extras;
+        public @NonNull Builder setMetricsBundle(@NonNull Bundle metricsBundle) {
+            mMetricsBundle = metricsBundle;
             return this;
         }
 
         /** Builds the instance. */
         public @NonNull NetworkEvent build() {
-            NetworkEvent o = new NetworkEvent(mNetworkType, mTimeSinceCreatedMillis, mExtras);
+            NetworkEvent o =
+                    new NetworkEvent(mNetworkType, mTimeSinceCreatedMillis, mMetricsBundle);
             return o;
         }
     }
diff --git a/media/java/android/media/metrics/PlaybackErrorEvent.java b/media/java/android/media/metrics/PlaybackErrorEvent.java
index ccf848b..f36c04e 100644
--- a/media/java/android/media/metrics/PlaybackErrorEvent.java
+++ b/media/java/android/media/metrics/PlaybackErrorEvent.java
@@ -33,11 +33,77 @@
  */
 public final class PlaybackErrorEvent extends Event implements Parcelable {
     /** Unknown error code. */
-    public static final int ERROR_CODE_UNKNOWN = 0;
+    public static final int ERROR_UNKNOWN = 0;
     /** Error code for other errors */
-    public static final int ERROR_CODE_OTHER = 1;
+    public static final int ERROR_OTHER = 1;
     /** Error code for runtime errors */
-    public static final int ERROR_CODE_RUNTIME = 2;
+    public static final int ERROR_RUNTIME = 2;
+
+    /** No network */
+    public static final int ERROR_NETWORK_OFFLINE = 3;
+    /** Connection opening error */
+    public static final int ERROR_NETWORK_CONNECT = 4;
+    /** Bad HTTP status code */
+    public static final int ERROR_NETWORK_BAD_STATUS = 5;
+    /** DNS resolution error */
+    public static final int ERROR_NETWORK_DNS = 6;
+    /** Network socket timeout */
+    public static final int ERROR_NETWORK_TIMEOUT = 7;
+    /** Connection closed */
+    public static final int ERROR_NETWORK_CLOSED = 8;
+    /** Other network errors */
+    public static final int ERROR_NETWORK_OTHER = 9;
+
+    /** Manifest parsing error */
+    public static final int ERROR_MEDIA_MANIFEST = 10;
+    /**
+     * Media bitstream (audio, video, text, metadata) parsing error, either malformed or
+     * unsupported.
+     */
+    public static final int ERROR_MEDIA_PARSER = 11;
+    /** Other media errors */
+    public static final int ERROR_MEDIA_OTHER = 12;
+
+    /** Codec initialization failed */
+    public static final int ERROR_DECODER_INIT = 13;
+    /** Decoding failed */
+    public static final int ERROR_DECODER_DECODE = 14;
+    /** Out of memory */
+    public static final int ERROR_DECODER_OOM = 15;
+    /** Other decoder errors */
+    public static final int ERROR_DECODER_OTHER = 16;
+
+    /** AudioTrack initialization failed */
+    public static final int ERROR_AUDIOTRACK_INIT = 17;
+    /** AudioTrack writing failed */
+    public static final int ERROR_AUDIOTRACK_WRITE = 18;
+    /** Other AudioTrack errors */
+    public static final int ERROR_AUDIOTRACK_OTHER = 19;
+
+    /** Exception in remote controller or player */
+    public static final int ERROR_PLAYER_REMOTE = 20;
+    /** Error when a Live playback falls behind the Live DVR window. */
+    public static final int ERROR_PLAYER_BEHIND_LIVE_WINDOW = 21;
+    /** Other player errors */
+    public static final int ERROR_PLAYER_OTHER = 22;
+
+    /** Scheme unsupported by device */
+    public static final int ERROR_DRM_UNAVAILABLE = 23;
+    /** Provisioning failed */
+    public static final int ERROR_DRM_PROVISIONING_FAILED = 24;
+    /** Failed to acquire license */
+    public static final int ERROR_DRM_LICENSE_ERROR = 25;
+    /** Operation prevented by license policy */
+    public static final int ERROR_DRM_DISALLOWED = 26;
+    /** Failure in the DRM system */
+    public static final int ERROR_DRM_SYSTEM_ERROR = 27;
+    /** Incompatible content */
+    public static final int ERROR_DRM_CONTENT_ERROR = 28;
+    /** Device has been revoked */
+    public static final int ERROR_DRM_REVOKED = 29;
+    /** Other drm errors */
+    public static final int ERROR_DRM_OTHER = 30;
+
 
     private final @Nullable String mExceptionStack;
     private final int mErrorCode;
@@ -46,11 +112,38 @@
 
 
     /** @hide */
-    // TODO: more error types
-    @IntDef(prefix = "ERROR_CODE_", value = {
-        ERROR_CODE_UNKNOWN,
-        ERROR_CODE_OTHER,
-        ERROR_CODE_RUNTIME
+    @IntDef(prefix = "ERROR_", value = {
+        ERROR_UNKNOWN,
+        ERROR_OTHER,
+        ERROR_RUNTIME,
+        ERROR_NETWORK_OFFLINE,
+        ERROR_NETWORK_CONNECT,
+        ERROR_NETWORK_BAD_STATUS,
+        ERROR_NETWORK_DNS,
+        ERROR_NETWORK_TIMEOUT,
+        ERROR_NETWORK_CLOSED,
+        ERROR_NETWORK_OTHER,
+        ERROR_MEDIA_MANIFEST,
+        ERROR_MEDIA_PARSER,
+        ERROR_MEDIA_OTHER,
+        ERROR_DECODER_INIT,
+        ERROR_DECODER_DECODE,
+        ERROR_DECODER_OOM,
+        ERROR_DECODER_OTHER,
+        ERROR_AUDIOTRACK_INIT,
+        ERROR_AUDIOTRACK_WRITE,
+        ERROR_AUDIOTRACK_OTHER,
+        ERROR_PLAYER_REMOTE,
+        ERROR_PLAYER_BEHIND_LIVE_WINDOW,
+        ERROR_PLAYER_OTHER,
+        ERROR_DRM_UNAVAILABLE,
+        ERROR_DRM_PROVISIONING_FAILED,
+        ERROR_DRM_LICENSE_ERROR,
+        ERROR_DRM_DISALLOWED,
+        ERROR_DRM_SYSTEM_ERROR,
+        ERROR_DRM_CONTENT_ERROR,
+        ERROR_DRM_REVOKED,
+        ERROR_DRM_OTHER,
     })
     @Retention(java.lang.annotation.RetentionPolicy.SOURCE)
     public @interface ErrorCode {}
@@ -65,12 +158,12 @@
             int errorCode,
             int subErrorCode,
             long timeSinceCreatedMillis,
-            @Nullable Bundle extras) {
+            @NonNull Bundle extras) {
         this.mExceptionStack = exceptionStack;
         this.mErrorCode = errorCode;
         this.mSubErrorCode = subErrorCode;
         this.mTimeSinceCreatedMillis = timeSinceCreatedMillis;
-        this.mExtras = extras == null ? null : extras.deepCopy();
+        this.mMetricsBundle = extras.deepCopy();
     }
 
     /** @hide */
@@ -107,6 +200,16 @@
         return mTimeSinceCreatedMillis;
     }
 
+    /**
+     * Gets metrics-related information that is not supported by dedicated methods.
+     * <p>It is intended to be used for backwards compatibility by the metrics infrastructure.
+     */
+    @Override
+    @NonNull
+    public Bundle getMetricsBundle() {
+        return mMetricsBundle;
+    }
+
     @Override
     public String toString() {
         return "PlaybackErrorEvent { "
@@ -138,13 +241,12 @@
     public void writeToParcel(@NonNull Parcel dest, int flags) {
         byte flg = 0;
         if (mExceptionStack != null) flg |= 0x1;
-        if (mExtras != null) flg |= 0x2;
         dest.writeByte(flg);
         if (mExceptionStack != null) dest.writeString(mExceptionStack);
         dest.writeInt(mErrorCode);
         dest.writeInt(mSubErrorCode);
         dest.writeLong(mTimeSinceCreatedMillis);
-        if (mExtras != null) dest.writeBundle(mExtras);
+        dest.writeBundle(mMetricsBundle);
     }
 
     @Override
@@ -159,13 +261,13 @@
         int errorCode = in.readInt();
         int subErrorCode = in.readInt();
         long timeSinceCreatedMillis = in.readLong();
-        Bundle extras = (flg & 0x2) == 0 ? null : in.readBundle();
+        Bundle extras = in.readBundle();
 
         this.mExceptionStack = exceptionStack;
         this.mErrorCode = errorCode;
         this.mSubErrorCode = subErrorCode;
         this.mTimeSinceCreatedMillis = timeSinceCreatedMillis;
-        this.mExtras = extras;
+        this.mMetricsBundle = extras;
     }
 
 
@@ -190,7 +292,7 @@
         private int mErrorCode;
         private int mSubErrorCode;
         private long mTimeSinceCreatedMillis = -1;
-        private Bundle mExtras;
+        private Bundle mMetricsBundle = new Bundle();
 
         /**
          * Creates a new Builder.
@@ -235,12 +337,13 @@
         }
 
         /**
-         * Set extras for compatibility.
-         * <p>Should be used by support library only.
-         * @hide
+         * Sets metrics-related information that is not supported by dedicated
+         * methods.
+         * <p>It is intended to be used for backwards compatibility by the
+         * metrics infrastructure.
          */
-        public @NonNull Builder setExtras(@NonNull Bundle extras) {
-            mExtras = extras;
+        public @NonNull Builder setMetricsBundle(@NonNull Bundle metricsBundle) {
+            mMetricsBundle = metricsBundle;
             return this;
         }
 
@@ -260,7 +363,7 @@
                     mErrorCode,
                     mSubErrorCode,
                     mTimeSinceCreatedMillis,
-                    mExtras);
+                    mMetricsBundle);
             return o;
         }
     }
diff --git a/media/java/android/media/metrics/PlaybackMetrics.java b/media/java/android/media/metrics/PlaybackMetrics.java
index 3ffd10f..5f606a0 100644
--- a/media/java/android/media/metrics/PlaybackMetrics.java
+++ b/media/java/android/media/metrics/PlaybackMetrics.java
@@ -60,15 +60,13 @@
     public static final int STREAM_TYPE_SS = 5;
 
     /** Unknown playback type. */
-    // TODO: change the PLAYBACK_TYPE_ values
-    /** @hide */
     public static final int PLAYBACK_TYPE_UNKNOWN = 0;
     /** VOD (Video on Demand) playback type. */
-    public static final int PLAYBACK_TYPE_VOD = 0;
+    public static final int PLAYBACK_TYPE_VOD = 1;
     /** Live playback type. */
-    public static final int PLAYBACK_TYPE_LIVE = 1;
+    public static final int PLAYBACK_TYPE_LIVE = 2;
     /** Other playback type. */
-    public static final int PLAYBACK_TYPE_OTHER = 2;
+    public static final int PLAYBACK_TYPE_OTHER = 3;
 
     /** DRM is not used. */
     public static final int DRM_TYPE_NONE = 0;
@@ -86,15 +84,13 @@
     public static final int DRM_TYPE_CLEARKEY = 6;
 
     /** Unknown content type. */
-    // TODO: change the CONTENT_TYPE_ values
-    /** @hide */
     public static final int CONTENT_TYPE_UNKNOWN = 0;
     /** Main contents. */
-    public static final int CONTENT_TYPE_MAIN = 0;
+    public static final int CONTENT_TYPE_MAIN = 1;
     /** Advertisement contents. */
-    public static final int CONTENT_TYPE_AD = 1;
+    public static final int CONTENT_TYPE_AD = 2;
     /** Other contents. */
-    public static final int CONTENT_TYPE_OTHER = 2;
+    public static final int CONTENT_TYPE_OTHER = 3;
 
 
     /** @hide */
@@ -170,7 +166,7 @@
     private final long mLocalBytesRead;
     private final long mNetworkTransferDurationMillis;
     private final byte[] mDrmSessionId;
-    private final Bundle mExtras;
+    private final @NonNull Bundle mMetricsBundle;
 
     /**
      * Creates a new PlaybackMetrics.
@@ -194,7 +190,7 @@
             long localBytesRead,
             long networkTransferDurationMillis,
             byte[] drmSessionId,
-            @Nullable Bundle extras) {
+            @NonNull Bundle extras) {
         this.mMediaDurationMillis = mediaDurationMillis;
         this.mStreamSource = streamSource;
         this.mStreamType = streamType;
@@ -212,7 +208,7 @@
         this.mLocalBytesRead = localBytesRead;
         this.mNetworkTransferDurationMillis = networkTransferDurationMillis;
         this.mDrmSessionId = drmSessionId;
-        this.mExtras = extras == null ? null : extras.deepCopy();
+        this.mMetricsBundle = extras.deepCopy();
     }
 
     /**
@@ -338,12 +334,23 @@
         return mNetworkTransferDurationMillis;
     }
 
-    /** @hide */
+    /**
+     * Gets DRM session ID.
+     */
     @NonNull
     public byte[] getDrmSessionId() {
         return mDrmSessionId;
     }
 
+    /**
+     * Gets metrics-related information that is not supported by dedicated methods.
+     * <p>It is intended to be used for backwards compatibility by the metrics infrastructure.
+     */
+    @NonNull
+    public Bundle getMetricsBundle() {
+        return mMetricsBundle;
+    }
+
     @Override
     public String toString() {
         return "PlaybackMetrics { "
@@ -402,7 +409,6 @@
         long flg = 0;
         if (mPlayerName != null) flg |= 0x80;
         if (mPlayerVersion != null) flg |= 0x100;
-        if (mExtras != null) flg |= 0x200;
         dest.writeLong(flg);
         dest.writeLong(mMediaDurationMillis);
         dest.writeInt(mStreamSource);
@@ -412,7 +418,6 @@
         dest.writeInt(mContentType);
         if (mPlayerName != null) dest.writeString(mPlayerName);
         if (mPlayerVersion != null) dest.writeString(mPlayerVersion);
-        if (mExtras != null) dest.writeBundle(mExtras);
         dest.writeLongArray(mExperimentIds);
         dest.writeInt(mVideoFramesPlayed);
         dest.writeInt(mVideoFramesDropped);
@@ -422,6 +427,7 @@
         dest.writeLong(mNetworkTransferDurationMillis);
         dest.writeInt(mDrmSessionId.length);
         dest.writeByteArray(mDrmSessionId);
+        dest.writeBundle(mMetricsBundle);
     }
 
     @Override
@@ -440,7 +446,6 @@
         int contentType = in.readInt();
         String playerName = (flg & 0x80) == 0 ? null : in.readString();
         String playerVersion = (flg & 0x100) == 0 ? null : in.readString();
-        Bundle extras = (flg & 0x200) == 0 ? null : in.readBundle();
         long[] experimentIds = in.createLongArray();
         int videoFramesPlayed = in.readInt();
         int videoFramesDropped = in.readInt();
@@ -451,6 +456,7 @@
         int drmSessionIdLen = in.readInt();
         byte[] drmSessionId = new byte[drmSessionIdLen];
         in.readByteArray(drmSessionId);
+        Bundle extras = in.readBundle();
 
         this.mMediaDurationMillis = mediaDurationMillis;
         this.mStreamSource = streamSource;
@@ -469,7 +475,7 @@
         this.mLocalBytesRead = localBytesRead;
         this.mNetworkTransferDurationMillis = networkTransferDurationMillis;
         this.mDrmSessionId = drmSessionId;
-        this.mExtras = extras;
+        this.mMetricsBundle = extras;
     }
 
     public static final @NonNull Parcelable.Creator<PlaybackMetrics> CREATOR =
@@ -506,7 +512,7 @@
         private long mLocalBytesRead = -1;
         private long mNetworkTransferDurationMillis = -1;
         private byte[] mDrmSessionId = new byte[0];
-        private Bundle mExtras;
+        private Bundle mMetricsBundle = new Bundle();
 
         /**
          * Creates a new Builder.
@@ -646,7 +652,7 @@
         }
 
         /**
-         * @hide
+         * Sets DRM session ID.
          */
         public @NonNull Builder setDrmSessionId(@NonNull byte[] drmSessionId) {
             mDrmSessionId = drmSessionId;
@@ -654,12 +660,13 @@
         }
 
         /**
-         * Set extras for compatibility.
-         * <p>Should be used by support library only.
-         * @hide
+         * Sets metrics-related information that is not supported by dedicated
+         * methods.
+         * <p>It is intended to be used for backwards compatibility by the
+         * metrics infrastructure.
          */
-        public @NonNull Builder setExtras(@NonNull Bundle extras) {
-            mExtras = extras;
+        public @NonNull Builder setMetricsBundle(@NonNull Bundle metricsBundle) {
+            mMetricsBundle = metricsBundle;
             return this;
         }
 
@@ -683,7 +690,7 @@
                     mLocalBytesRead,
                     mNetworkTransferDurationMillis,
                     mDrmSessionId,
-                    mExtras);
+                    mMetricsBundle);
             return o;
         }
 
diff --git a/media/java/android/media/metrics/PlaybackSession.java b/media/java/android/media/metrics/PlaybackSession.java
index 272fd9b..aad510e 100644
--- a/media/java/android/media/metrics/PlaybackSession.java
+++ b/media/java/android/media/metrics/PlaybackSession.java
@@ -80,14 +80,7 @@
         mManager.reportTrackChangeEvent(mId, event);
     }
 
-    public @NonNull String getId() {
-        // TODO: remove this method and use getSessionId();
-        return mId;
-    }
-
-    /** @hide */
     public @NonNull LogSessionId getSessionId() {
-        // TODO: remove getId() and use this method;
         return mLogSessionId;
     }
 
diff --git a/media/java/android/media/metrics/PlaybackStateEvent.java b/media/java/android/media/metrics/PlaybackStateEvent.java
index 2bab5c9..449abe9 100644
--- a/media/java/android/media/metrics/PlaybackStateEvent.java
+++ b/media/java/android/media/metrics/PlaybackStateEvent.java
@@ -138,10 +138,10 @@
     public PlaybackStateEvent(
             int state,
             long timeSinceCreatedMillis,
-            @Nullable Bundle extras) {
+            @NonNull Bundle extras) {
         this.mTimeSinceCreatedMillis = timeSinceCreatedMillis;
         this.mState = state;
-        this.mExtras = extras == null ? null : extras.deepCopy();
+        this.mMetricsBundle = extras.deepCopy();
     }
 
     /**
@@ -161,6 +161,16 @@
         return mTimeSinceCreatedMillis;
     }
 
+    /**
+     * Gets metrics-related information that is not supported by dedicated methods.
+     * <p>It is intended to be used for backwards compatibility by the metrics infrastructure.
+     */
+    @Override
+    @NonNull
+    public Bundle getMetricsBundle() {
+        return mMetricsBundle;
+    }
+
     @Override
     public boolean equals(@Nullable Object o) {
         if (this == o) return true;
@@ -177,12 +187,9 @@
 
     @Override
     public void writeToParcel(@NonNull Parcel dest, int flags) {
-        byte flg = 0;
-        if (mExtras != null) flg |= 0x1;
-        dest.writeByte(flg);
         dest.writeInt(mState);
         dest.writeLong(mTimeSinceCreatedMillis);
-        if (mExtras != null) dest.writeBundle(mExtras);
+        dest.writeBundle(mMetricsBundle);
     }
 
     @Override
@@ -192,14 +199,13 @@
 
     /** @hide */
     /* package-private */ PlaybackStateEvent(@NonNull Parcel in) {
-        byte flg = in.readByte();
         int state = in.readInt();
         long timeSinceCreatedMillis = in.readLong();
-        Bundle extras = (flg & 0x1) == 0 ? null : in.readBundle();
+        Bundle extras = in.readBundle();
 
         this.mState = state;
         this.mTimeSinceCreatedMillis = timeSinceCreatedMillis;
-        this.mExtras = extras;
+        this.mMetricsBundle = extras;
     }
 
     public static final @NonNull Parcelable.Creator<PlaybackStateEvent> CREATOR =
@@ -221,7 +227,7 @@
     public static final class Builder {
         private int mState = STATE_NOT_STARTED;
         private long mTimeSinceCreatedMillis = -1;
-        private Bundle mExtras;
+        private Bundle mMetricsBundle = new Bundle();
 
         /**
          * Creates a new Builder.
@@ -248,12 +254,13 @@
         }
 
         /**
-         * Set extras for compatibility.
-         * <p>Should be used by support library only.
-         * @hide
+         * Sets metrics-related information that is not supported by dedicated
+         * methods.
+         * <p>It is intended to be used for backwards compatibility by the
+         * metrics infrastructure.
          */
-        public @NonNull Builder setExtras(@NonNull Bundle extras) {
-            mExtras = extras;
+        public @NonNull Builder setMetricsBundle(@NonNull Bundle metricsBundle) {
+            mMetricsBundle = metricsBundle;
             return this;
         }
 
@@ -262,7 +269,7 @@
             PlaybackStateEvent o = new PlaybackStateEvent(
                     mState,
                     mTimeSinceCreatedMillis,
-                    mExtras);
+                    mMetricsBundle);
             return o;
         }
     }
diff --git a/media/java/android/media/metrics/RecordingSession.java b/media/java/android/media/metrics/RecordingSession.java
index 541d129..d388351 100644
--- a/media/java/android/media/metrics/RecordingSession.java
+++ b/media/java/android/media/metrics/RecordingSession.java
@@ -25,7 +25,6 @@
 
 /**
  * An instances of this class represents a session of media recording.
- * @hide
  */
 public final class RecordingSession implements AutoCloseable {
     private final @NonNull String mId;
@@ -42,6 +41,10 @@
         mLogSessionId = new LogSessionId(mId);
     }
 
+    public @NonNull LogSessionId getSessionId() {
+        return mLogSessionId;
+    }
+
     @Override
     public boolean equals(@Nullable Object o) {
         if (this == o) return true;
diff --git a/media/java/android/media/metrics/TrackChangeEvent.java b/media/java/android/media/metrics/TrackChangeEvent.java
index a3eb4ad..c3670269 100644
--- a/media/java/android/media/metrics/TrackChangeEvent.java
+++ b/media/java/android/media/metrics/TrackChangeEvent.java
@@ -102,39 +102,6 @@
     @Retention(RetentionPolicy.SOURCE)
     public @interface TrackType {}
 
-    // TODO: remove this constructor. Use the private one below.
-    public TrackChangeEvent(
-            int state,
-            int reason,
-            @Nullable String containerMimeType,
-            @Nullable String sampleMimeType,
-            @Nullable String codecName,
-            int bitrate,
-            long timeSinceCreatedMillis,
-            int type,
-            @Nullable String language,
-            @Nullable String languageRegion,
-            int channelCount,
-            int sampleRate,
-            int width,
-            int height) {
-        this.mState = state;
-        this.mReason = reason;
-        this.mContainerMimeType = containerMimeType;
-        this.mSampleMimeType = sampleMimeType;
-        this.mCodecName = codecName;
-        this.mBitrate = bitrate;
-        this.mTimeSinceCreatedMillis = timeSinceCreatedMillis;
-        this.mType = type;
-        this.mLanguage = language;
-        this.mLanguageRegion = languageRegion;
-        this.mChannelCount = channelCount;
-        this.mAudioSampleRate = sampleRate;
-        this.mWidth = width;
-        this.mHeight = height;
-        this.mVideoFrameRate = -1;
-    }
-
     private TrackChangeEvent(
             int state,
             int reason,
@@ -151,7 +118,7 @@
             int width,
             int height,
             float videoFrameRate,
-            @Nullable Bundle extras) {
+            @NonNull Bundle extras) {
         this.mState = state;
         this.mReason = reason;
         this.mContainerMimeType = containerMimeType;
@@ -167,7 +134,7 @@
         this.mWidth = width;
         this.mHeight = height;
         this.mVideoFrameRate = videoFrameRate;
-        this.mExtras = extras == null ? null : extras.deepCopy();
+        this.mMetricsBundle = extras.deepCopy();
     }
 
     /**
@@ -258,11 +225,11 @@
     }
 
     /**
-     * Gets sample rate.
+     * Gets audio sample rate.
      * @return the sample rate, or -1 if unknown.
      */
     @IntRange(from = -1, to = Integer.MAX_VALUE)
-    public int getSampleRate() {
+    public int getAudioSampleRate() {
         return mAudioSampleRate;
     }
 
@@ -287,13 +254,22 @@
     /**
      * Gets video frame rate.
      * @return the video frame rate, or -1 if unknown.
-     * @hide
      */
     @FloatRange(from = -1, to = Float.MAX_VALUE)
     public float getVideoFrameRate() {
         return mVideoFrameRate;
     }
 
+    /**
+     * Gets metrics-related information that is not supported by dedicated methods.
+     * <p>It is intended to be used for backwards compatibility by the metrics infrastructure.
+     */
+    @Override
+    @NonNull
+    public Bundle getMetricsBundle() {
+        return mMetricsBundle;
+    }
+
     @Override
     public void writeToParcel(@NonNull Parcel dest, int flags) {
         int flg = 0;
@@ -302,7 +278,6 @@
         if (mCodecName != null) flg |= 0x10;
         if (mLanguage != null) flg |= 0x100;
         if (mLanguageRegion != null) flg |= 0x200;
-        if (mExtras != null) flg |= 0x400;
         dest.writeInt(flg);
         dest.writeInt(mState);
         dest.writeInt(mReason);
@@ -319,7 +294,7 @@
         dest.writeInt(mWidth);
         dest.writeInt(mHeight);
         dest.writeFloat(mVideoFrameRate);
-        if (mExtras != null) dest.writeBundle(mExtras);
+        dest.writeBundle(mMetricsBundle);
     }
 
     @Override
@@ -345,7 +320,7 @@
         int width = in.readInt();
         int height = in.readInt();
         float videoFrameRate = in.readFloat();
-        Bundle extras = (flg & 0x400) == 0 ? null : in.readBundle();
+        Bundle extras = in.readBundle();
 
         this.mState = state;
         this.mReason = reason;
@@ -362,7 +337,7 @@
         this.mWidth = width;
         this.mHeight = height;
         this.mVideoFrameRate = videoFrameRate;
-        this.mExtras = extras;
+        this.mMetricsBundle = extras;
     }
 
     public static final @NonNull Parcelable.Creator<TrackChangeEvent> CREATOR =
@@ -448,7 +423,7 @@
         private int mWidth = -1;
         private int mHeight = -1;
         private float mVideoFrameRate = -1;
-        private Bundle mExtras;
+        private Bundle mMetricsBundle = new Bundle();
 
         private long mBuilderFieldsSet = 0L;
 
@@ -571,9 +546,8 @@
          * Sets sample rate.
          * @param value the sample rate. -1 indicates the value is unknown.
          */
-        public @NonNull Builder setSampleRate(
+        public @NonNull Builder setAudioSampleRate(
                 @IntRange(from = -1, to = Integer.MAX_VALUE) int value) {
-            // TODO: rename it to setAudioSampleRate
             checkNotUsed();
             mBuilderFieldsSet |= 0x800;
             mAudioSampleRate = value;
@@ -605,7 +579,6 @@
         /**
          * Sets video frame rate.
          * @param value the video frame rate. -1 indicates the value is unknown.
-         * @hide
          */
         public @NonNull Builder setVideoFrameRate(
                 @FloatRange(from = -1, to = Float.MAX_VALUE) float value) {
@@ -615,12 +588,13 @@
         }
 
         /**
-         * Set extras for compatibility.
-         * <p>Should be used by support library only.
-         * @hide
+         * Sets metrics-related information that is not supported by dedicated
+         * methods.
+         * <p>It is intended to be used for backwards compatibility by the
+         * metrics infrastructure.
          */
-        public @NonNull Builder setExtras(@NonNull Bundle extras) {
-            mExtras = extras;
+        public @NonNull Builder setMetricsBundle(@NonNull Bundle metricsBundle) {
+            mMetricsBundle = metricsBundle;
             return this;
         }
 
@@ -645,7 +619,7 @@
                     mWidth,
                     mHeight,
                     mVideoFrameRate,
-                    mExtras);
+                    mMetricsBundle);
             return o;
         }
 
diff --git a/media/java/android/media/session/ISessionManager.aidl b/media/java/android/media/session/ISessionManager.aidl
index 96bffee117..3b0f577 100644
--- a/media/java/android/media/session/ISessionManager.aidl
+++ b/media/java/android/media/session/ISessionManager.aidl
@@ -39,6 +39,8 @@
     ISession createSession(String packageName, in ISessionCallback sessionCb, String tag,
             in Bundle sessionInfo, int userId);
     List<MediaSession.Token> getSessions(in ComponentName compName, int userId);
+    MediaSession.Token getMediaKeyEventSession();
+    String getMediaKeyEventSessionPackageName();
     void dispatchMediaKeyEvent(String packageName, boolean asSystemService, in KeyEvent keyEvent,
             boolean needWakeLock);
     boolean dispatchMediaKeyEventToSessionAsSystemService(String packageName,
diff --git a/media/java/android/media/session/MediaSessionManager.java b/media/java/android/media/session/MediaSessionManager.java
index 78db750..269b70b 100644
--- a/media/java/android/media/session/MediaSessionManager.java
+++ b/media/java/android/media/session/MediaSessionManager.java
@@ -195,6 +195,44 @@
     }
 
     /**
+     * Gets the media key event session, which would receive a media key event unless specified.
+     * @return The media key event session, which would receive key events by default, unless
+     *          the caller has specified the target. Can be {@code null}.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(value = android.Manifest.permission.MEDIA_CONTENT_CONTROL)
+    @Nullable
+    public MediaSession.Token getMediaKeyEventSession() {
+        try {
+            return mService.getMediaKeyEventSession();
+        } catch (RemoteException ex) {
+            Log.e(TAG, "Failed to get media key event session", ex);
+        }
+        return null;
+    }
+
+    /**
+     * Gets the package name of the media key event session.
+     * @return The package name of the media key event session or the last session's media button
+     *          receiver if the media key event session is {@code null}.
+     * @see #getMediaKeyEventSession()
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(value = android.Manifest.permission.MEDIA_CONTENT_CONTROL)
+    @NonNull
+    public String getMediaKeyEventSessionPackageName() {
+        try {
+            String packageName = mService.getMediaKeyEventSessionPackageName();
+            return (packageName != null) ? packageName : "";
+        } catch (RemoteException ex) {
+            Log.e(TAG, "Failed to get media key event session", ex);
+        }
+        return "";
+    }
+
+    /**
      * Get active sessions for the given user.
      * <p>
      * This requires the {@link android.Manifest.permission#MEDIA_CONTENT_CONTROL} permission be
@@ -856,7 +894,7 @@
     }
 
     /**
-     * Add a {@link OnMediaKeyEventDispatchedListener}.
+     * Add a {@link OnMediaKeyEventSessionChangedListener}.
      *
      * @param executor The executor on which the listener should be invoked
      * @param listener A {@link OnMediaKeyEventSessionChangedListener}.
diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp
index 7f5dd5d..f694482 100644
--- a/media/jni/android_media_MediaCodec.cpp
+++ b/media/jni/android_media_MediaCodec.cpp
@@ -53,6 +53,7 @@
 
 #include <media/MediaCodecBuffer.h>
 #include <media/hardware/VideoAPI.h>
+#include <media/stagefright/CodecBase.h>
 #include <media/stagefright/MediaCodec.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ADebug.h>
@@ -81,6 +82,17 @@
     EVENT_CALLBACK = 1,
     EVENT_SET_CALLBACK = 2,
     EVENT_FRAME_RENDERED = 3,
+    EVENT_FIRST_TUNNEL_FRAME_READY = 4,
+};
+
+// From MediaFormat.java
+enum {
+    TYPE_NULL           = 0,
+    TYPE_INTEGER        = 1,
+    TYPE_LONG           = 2,
+    TYPE_FLOAT          = 3,
+    TYPE_STRING         = 4,
+    TYPE_BYTE_BUFFER    = 5,
 };
 
 static struct CryptoErrorCodes {
@@ -139,6 +151,8 @@
 } gByteBufferInfo;
 
 static struct {
+    jclass clazz;
+    jmethodID ctorId;
     jmethodID sizeId;
     jmethodID getId;
     jmethodID addId;
@@ -153,6 +167,13 @@
     jfieldID lockId;
 } gLinearBlockInfo;
 
+static struct {
+    jclass clazz;
+    jmethodID ctorId;
+    jfieldID nameId;
+    jfieldID typeId;
+} gDescriptorInfo;
+
 struct fields_t {
     jmethodID postEventFromNativeID;
     jmethodID lockAndGetContextID;
@@ -269,6 +290,18 @@
     mClass = NULL;
 }
 
+status_t JMediaCodec::enableOnFirstTunnelFrameReadyListener(jboolean enable) {
+    if (enable) {
+        if (mOnFirstTunnelFrameReadyNotification == NULL) {
+            mOnFirstTunnelFrameReadyNotification = new AMessage(kWhatFirstTunnelFrameReady, this);
+        }
+    } else {
+        mOnFirstTunnelFrameReadyNotification.clear();
+    }
+
+    return mCodec->setOnFirstTunnelFrameReadyNotification(mOnFirstTunnelFrameReadyNotification);
+}
+
 status_t JMediaCodec::enableOnFrameRenderedListener(jboolean enable) {
     if (enable) {
         if (mOnFrameRenderedNotification == NULL) {
@@ -924,6 +957,74 @@
     (void)mCodec->setParameters(msg);
 }
 
+status_t JMediaCodec::querySupportedVendorParameters(JNIEnv *env, jobject *namesObj) {
+    std::vector<std::string> names;
+    status_t status = mCodec->querySupportedVendorParameters(&names);
+    if (status != OK) {
+        return status;
+    }
+    *namesObj = env->NewObject(gArrayListInfo.clazz, gArrayListInfo.ctorId);
+    for (const std::string &name : names) {
+        ScopedLocalRef<jstring> nameStr{env, env->NewStringUTF(name.c_str())};
+        (void)env->CallBooleanMethod(*namesObj, gArrayListInfo.addId, nameStr.get());
+    }
+    return OK;
+}
+
+status_t JMediaCodec::describeParameter(JNIEnv *env, jstring name, jobject *descObj) {
+    const char *tmp = env->GetStringUTFChars(name, nullptr);
+    CodecParameterDescriptor desc;
+    status_t status = mCodec->describeParameter(tmp, &desc);
+    env->ReleaseStringUTFChars(name, tmp);
+    if (status != OK) {
+        return status;
+    }
+    jint type = TYPE_NULL;
+    switch (desc.type) {
+        case AMessage::kTypeInt32:  type = TYPE_INTEGER;     break;
+        case AMessage::kTypeSize:
+        case AMessage::kTypeInt64:  type = TYPE_LONG;        break;
+        case AMessage::kTypeFloat:  type = TYPE_FLOAT;       break;
+        case AMessage::kTypeString: type = TYPE_STRING;      break;
+        case AMessage::kTypeBuffer: type = TYPE_BYTE_BUFFER; break;
+        default:                    type = TYPE_NULL;        break;
+    }
+    if (type == TYPE_NULL) {
+        return BAD_VALUE;
+    }
+    *descObj = env->NewObject(gDescriptorInfo.clazz, gDescriptorInfo.ctorId);
+    env->SetObjectField(*descObj, gDescriptorInfo.nameId, name);
+    env->SetIntField(*descObj, gDescriptorInfo.typeId, type);
+    return OK;
+}
+
+static void BuildVectorFromList(JNIEnv *env, jobject list, std::vector<std::string> *vec) {
+    ScopedLocalRef<jclass> listClazz{env, env->FindClass("java/util/List")};
+    ScopedLocalRef<jclass> iterClazz{env, env->FindClass("java/util/Iterator")};
+    jmethodID hasNextID = env->GetMethodID(iterClazz.get(), "hasNext", "()Z");
+    jmethodID nextID = env->GetMethodID(iterClazz.get(), "next", "()Ljava/lang/Object;");
+    jobject it = env->CallObjectMethod(
+            list, env->GetMethodID(listClazz.get(), "iterator", "()Ljava/util/Iterator;"));
+    while (env->CallBooleanMethod(it, hasNextID)) {
+        jstring name = (jstring)env->CallObjectMethod(it, nextID);
+        const char *tmp = env->GetStringUTFChars(name, nullptr);
+        vec->push_back(tmp);
+        env->ReleaseStringUTFChars(name, tmp);
+    }
+}
+
+status_t JMediaCodec::subscribeToVendorParameters(JNIEnv *env, jobject namesObj) {
+    std::vector<std::string> names;
+    BuildVectorFromList(env, namesObj, &names);
+    return mCodec->subscribeToVendorParameters(names);
+}
+
+status_t JMediaCodec::unsubscribeFromVendorParameters(JNIEnv *env, jobject namesObj) {
+    std::vector<std::string> names;
+    BuildVectorFromList(env, namesObj, &names);
+    return mCodec->unsubscribeFromVendorParameters(names);
+}
+
 static jthrowable createCodecException(
         JNIEnv *env, status_t err, int32_t actionCode, const char *msg = NULL) {
     ScopedLocalRef<jclass> clazz(
@@ -1058,6 +1159,27 @@
     env->DeleteLocalRef(obj);
 }
 
+void JMediaCodec::handleFirstTunnelFrameReadyNotification(const sp<AMessage> &msg) {
+    int32_t arg1 = 0, arg2 = 0;
+    jobject obj = NULL;
+    JNIEnv *env = AndroidRuntime::getJNIEnv();
+
+    sp<AMessage> data;
+    CHECK(msg->findMessage("data", &data));
+
+    status_t err = ConvertMessageToMap(env, data, &obj);
+    if (err != OK) {
+        jniThrowException(env, "java/lang/IllegalStateException", NULL);
+        return;
+    }
+
+    env->CallVoidMethod(
+            mObject, gFields.postEventFromNativeID,
+            EVENT_FIRST_TUNNEL_FRAME_READY, arg1, arg2, obj);
+
+    env->DeleteLocalRef(obj);
+}
+
 void JMediaCodec::handleFrameRenderedNotification(const sp<AMessage> &msg) {
     int32_t arg1 = 0, arg2 = 0;
     jobject obj = NULL;
@@ -1100,6 +1222,11 @@
             }
             break;
         }
+        case kWhatFirstTunnelFrameReady:
+        {
+            handleFirstTunnelFrameReadyNotification(msg);
+            break;
+        }
         default:
             TRESPASS();
     }
@@ -1256,6 +1383,22 @@
     }
 }
 
+static void android_media_MediaCodec_native_enableOnFirstTunnelFrameReadyListener(
+        JNIEnv *env,
+        jobject thiz,
+        jboolean enabled) {
+    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
+
+    if (codec == NULL || codec->initCheck() != OK) {
+        throwExceptionAsNecessary(env, INVALID_OPERATION);
+        return;
+    }
+
+    status_t err = codec->enableOnFirstTunnelFrameReadyListener(enabled);
+
+    throwExceptionAsNecessary(env, err);
+}
+
 static void android_media_MediaCodec_native_enableOnFrameRenderedListener(
         JNIEnv *env,
         jobject thiz,
@@ -2616,6 +2759,73 @@
     codec->selectAudioPresentation((int32_t)presentationId, (int32_t)programId);
 }
 
+static jobject android_media_MediaCodec_getSupportedVendorParameters(
+        JNIEnv *env, jobject thiz) {
+    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
+
+    if (codec == NULL || codec->initCheck() != OK) {
+        throwExceptionAsNecessary(env, INVALID_OPERATION);
+        return NULL;
+    }
+
+    jobject ret = NULL;
+    status_t status = codec->querySupportedVendorParameters(env, &ret);
+    if (status != OK) {
+        throwExceptionAsNecessary(env, status);
+    }
+
+    return ret;
+}
+
+static jobject android_media_MediaCodec_getParameterDescriptor(
+        JNIEnv *env, jobject thiz, jstring name) {
+    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
+
+    if (codec == NULL || codec->initCheck() != OK) {
+        throwExceptionAsNecessary(env, INVALID_OPERATION);
+        return NULL;
+    }
+
+    jobject ret = NULL;
+    status_t status = codec->describeParameter(env, name, &ret);
+    if (status != OK) {
+        ret = NULL;
+    }
+    return ret;
+}
+
+static void android_media_MediaCodec_subscribeToVendorParameters(
+        JNIEnv *env, jobject thiz, jobject names) {
+    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
+
+    if (codec == NULL || codec->initCheck() != OK) {
+        throwExceptionAsNecessary(env, INVALID_OPERATION);
+        return;
+    }
+
+    status_t status = codec->subscribeToVendorParameters(env, names);
+    if (status != OK) {
+        throwExceptionAsNecessary(env, status);
+    }
+    return;
+}
+
+static void android_media_MediaCodec_unsubscribeFromVendorParameters(
+        JNIEnv *env, jobject thiz, jobject names) {
+    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
+
+    if (codec == NULL || codec->initCheck() != OK) {
+        throwExceptionAsNecessary(env, INVALID_OPERATION);
+        return;
+    }
+
+    status_t status = codec->unsubscribeFromVendorParameters(env, names);
+    if (status != OK) {
+        throwExceptionAsNecessary(env, status);
+    }
+    return;
+}
+
 static void android_media_MediaCodec_native_init(JNIEnv *env, jclass) {
     ScopedLocalRef<jclass> clazz(
             env, env->FindClass("android/media/MediaCodec"));
@@ -2875,6 +3085,10 @@
 
     clazz.reset(env->FindClass("java/util/ArrayList"));
     CHECK(clazz.get() != NULL);
+    gArrayListInfo.clazz = (jclass)env->NewGlobalRef(clazz.get());
+
+    gArrayListInfo.ctorId = env->GetMethodID(clazz.get(), "<init>", "()V");
+    CHECK(gArrayListInfo.ctorId != NULL);
 
     gArrayListInfo.sizeId = env->GetMethodID(clazz.get(), "size", "()I");
     CHECK(gArrayListInfo.sizeId != NULL);
@@ -2905,6 +3119,19 @@
 
     gLinearBlockInfo.lockId = env->GetFieldID(clazz.get(), "mLock", "Ljava/lang/Object;");
     CHECK(gLinearBlockInfo.lockId != NULL);
+
+    clazz.reset(env->FindClass("android/media/MediaCodec$ParameterDescriptor"));
+    CHECK(clazz.get() != NULL);
+    gDescriptorInfo.clazz = (jclass)env->NewGlobalRef(clazz.get());
+
+    gDescriptorInfo.ctorId = env->GetMethodID(clazz.get(), "<init>", "()V");
+    CHECK(gDescriptorInfo.ctorId != NULL);
+
+    gDescriptorInfo.nameId = env->GetFieldID(clazz.get(), "mName", "Ljava/lang/String;");
+    CHECK(gDescriptorInfo.nameId != NULL);
+
+    gDescriptorInfo.typeId = env->GetFieldID(clazz.get(), "mType", "I");
+    CHECK(gDescriptorInfo.typeId != NULL);
 }
 
 static void android_media_MediaCodec_native_setup(
@@ -3138,6 +3365,9 @@
     { "native_setInputSurface", "(Landroid/view/Surface;)V",
       (void *)android_media_MediaCodec_setInputSurface },
 
+    { "native_enableOnFirstTunnelFrameReadyListener", "(Z)V",
+      (void *)android_media_MediaCodec_native_enableOnFirstTunnelFrameReadyListener },
+
     { "native_enableOnFrameRenderedListener", "(Z)V",
       (void *)android_media_MediaCodec_native_enableOnFrameRenderedListener },
 
@@ -3231,6 +3461,21 @@
     { "native_setAudioPresentation", "(II)V",
       (void *)android_media_MediaCodec_setAudioPresentation },
 
+    { "native_getSupportedVendorParameters", "()Ljava/util/List;",
+      (void *)android_media_MediaCodec_getSupportedVendorParameters },
+
+    { "native_getParameterDescriptor",
+      "(Ljava/lang/String;)Landroid/media/MediaCodec$ParameterDescriptor;",
+      (void *)android_media_MediaCodec_getParameterDescriptor },
+
+    { "native_subscribeToVendorParameters",
+      "(Ljava/util/List;)V",
+      (void *)android_media_MediaCodec_subscribeToVendorParameters},
+
+    { "native_unsubscribeFromVendorParameters",
+      "(Ljava/util/List;)V",
+      (void *)android_media_MediaCodec_unsubscribeFromVendorParameters},
+
     { "native_init", "()V", (void *)android_media_MediaCodec_native_init },
 
     { "native_setup", "(Ljava/lang/String;ZZ)V",
diff --git a/media/jni/android_media_MediaCodec.h b/media/jni/android_media_MediaCodec.h
index f16bcf3..ee456c9 100644
--- a/media/jni/android_media_MediaCodec.h
+++ b/media/jni/android_media_MediaCodec.h
@@ -63,6 +63,8 @@
     void release();
     void releaseAsync();
 
+    status_t enableOnFirstTunnelFrameReadyListener(jboolean enable);
+
     status_t enableOnFrameRenderedListener(jboolean enable);
 
     status_t setCallback(jobject cb);
@@ -162,6 +164,14 @@
 
     void selectAudioPresentation(const int32_t presentationId, const int32_t programId);
 
+    status_t querySupportedVendorParameters(JNIEnv *env, jobject *names);
+
+    status_t describeParameter(JNIEnv *env, jstring name, jobject *desc);
+
+    status_t subscribeToVendorParameters(JNIEnv *env, jobject names);
+
+    status_t unsubscribeFromVendorParameters(JNIEnv *env, jobject names);
+
     bool hasCryptoOrDescrambler() { return mHasCryptoOrDescrambler; }
 
     const sp<ICrypto> &getCrypto() { return mCrypto; }
@@ -176,6 +186,7 @@
         kWhatCallbackNotify,
         kWhatFrameRendered,
         kWhatAsyncReleaseComplete,
+        kWhatFirstTunnelFrameReady,
     };
 
     jclass mClass;
@@ -191,6 +202,7 @@
     std::once_flag mAsyncReleaseFlag;
 
     sp<AMessage> mCallbackNotification;
+    sp<AMessage> mOnFirstTunnelFrameReadyNotification;
     sp<AMessage> mOnFrameRenderedNotification;
 
     status_t mInitStatus;
@@ -203,6 +215,7 @@
             jobject *buf) const;
 
     void handleCallback(const sp<AMessage> &msg);
+    void handleFirstTunnelFrameReadyNotification(const sp<AMessage> &msg);
     void handleFrameRenderedNotification(const sp<AMessage> &msg);
 
     DISALLOW_EVIL_CONSTRUCTORS(JMediaCodec);
diff --git a/media/packages/BluetoothMidiService/AndroidManifest.xml b/media/packages/BluetoothMidiService/AndroidManifest.xml
index fc96fd9..3794ccd 100644
--- a/media/packages/BluetoothMidiService/AndroidManifest.xml
+++ b/media/packages/BluetoothMidiService/AndroidManifest.xml
@@ -27,6 +27,9 @@
     <uses-feature android:name="android.software.midi"
          android:required="true"/>
     <uses-permission android:name="android.permission.BLUETOOTH"/>
+    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
+    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>
+    <uses-permission android:name="android.permission.BLUETOOTH_SCAN"/>
 
     <application
         tools:replace="android:label"
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaInserterTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaInserterTest.java
index de353bf..a0d4492 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaInserterTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaInserterTest.java
@@ -24,8 +24,10 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.content.AttributionSource;
 import android.content.ContentProviderClient;
 import android.content.ContentValues;
+import android.content.Context;
 import android.content.IContentProvider;
 import android.media.MediaInserter;
 import android.net.Uri;
@@ -46,7 +48,7 @@
     private MediaInserter mMediaInserter;
     private static final int TEST_BUFFER_SIZE = 10;
     private @Mock IContentProvider mMockProvider;
-    private String mPackageName;
+    private AttributionSource mAttributionSource;
 
     private int mFilesCounter;
     private int mAudioCounter;
@@ -86,11 +88,14 @@
         super.setUp();
         MockitoAnnotations.initMocks(this);
 
-        final ContentProviderClient client = new ContentProviderClient(
-                getInstrumentation().getContext().createFeatureContext(TEST_FEATURE_ID)
+        final Context attributionContext = getInstrumentation().getContext()
+                .createFeatureContext(TEST_FEATURE_ID);
+
+        final ContentProviderClient client = new ContentProviderClient(attributionContext
                         .getContentResolver(), mMockProvider, true);
+
         mMediaInserter = new MediaInserter(client, TEST_BUFFER_SIZE);
-        mPackageName = getInstrumentation().getContext().getPackageName();
+        mAttributionSource = attributionContext.getAttributionSource();
         mFilesCounter = 0;
         mAudioCounter = 0;
         mVideoCounter = 0;
@@ -144,13 +149,13 @@
         fillBuffer(sVideoUri, TEST_BUFFER_SIZE - 2);
         fillBuffer(sImagesUri, TEST_BUFFER_SIZE - 1);
 
-        verify(mMockProvider, never()).bulkInsert(eq(mPackageName), eq(TEST_FEATURE_ID), any(),
+        verify(mMockProvider, never()).bulkInsert(eq(mAttributionSource), any(),
                 any());
     }
 
     @SmallTest
     public void testInsertContentsEqualToBufferSize() throws Exception {
-        when(mMockProvider.bulkInsert(eq(mPackageName), eq(TEST_FEATURE_ID), any(),
+        when(mMockProvider.bulkInsert(eq(mAttributionSource), any(),
                 any())).thenReturn(1);
 
         fillBuffer(sFilesUri, TEST_BUFFER_SIZE);
@@ -158,13 +163,13 @@
         fillBuffer(sVideoUri, TEST_BUFFER_SIZE);
         fillBuffer(sImagesUri, TEST_BUFFER_SIZE);
 
-        verify(mMockProvider, times(4)).bulkInsert(eq(mPackageName), eq(TEST_FEATURE_ID), any(),
+        verify(mMockProvider, times(4)).bulkInsert(eq(mAttributionSource), any(),
                 any());
     }
 
     @SmallTest
     public void testInsertContentsMoreThanBufferSize() throws Exception {
-        when(mMockProvider.bulkInsert(eq(mPackageName), eq(TEST_FEATURE_ID), any(),
+        when(mMockProvider.bulkInsert(eq(mAttributionSource), any(),
                 any())).thenReturn(1);
 
         fillBuffer(sFilesUri, TEST_BUFFER_SIZE + 1);
@@ -172,7 +177,7 @@
         fillBuffer(sVideoUri, TEST_BUFFER_SIZE + 3);
         fillBuffer(sImagesUri, TEST_BUFFER_SIZE + 4);
 
-        verify(mMockProvider, times(4)).bulkInsert(eq(mPackageName), eq(TEST_FEATURE_ID), any(),
+        verify(mMockProvider, times(4)).bulkInsert(eq(mAttributionSource), any(),
                 any());
     }
 
@@ -183,7 +188,7 @@
 
     @SmallTest
     public void testFlushAllWithSomeContents() throws Exception {
-        when(mMockProvider.bulkInsert(eq(mPackageName), eq(TEST_FEATURE_ID), any(),
+        when(mMockProvider.bulkInsert(eq(mAttributionSource), any(),
                 any())).thenReturn(1);
 
         fillBuffer(sFilesUri, TEST_BUFFER_SIZE - 4);
@@ -192,13 +197,13 @@
         fillBuffer(sImagesUri, TEST_BUFFER_SIZE - 1);
         mMediaInserter.flushAll();
 
-        verify(mMockProvider, times(4)).bulkInsert(eq(mPackageName), eq(TEST_FEATURE_ID), any(),
+        verify(mMockProvider, times(4)).bulkInsert(eq(mAttributionSource), any(),
                 any());
     }
 
     @SmallTest
     public void testInsertContentsAfterFlushAll() throws Exception {
-        when(mMockProvider.bulkInsert(eq(mPackageName), eq(TEST_FEATURE_ID), any(),
+        when(mMockProvider.bulkInsert(eq(mAttributionSource), any(),
                 any())).thenReturn(1);
 
         fillBuffer(sFilesUri, TEST_BUFFER_SIZE - 4);
@@ -212,19 +217,19 @@
         fillBuffer(sVideoUri, TEST_BUFFER_SIZE + 3);
         fillBuffer(sImagesUri, TEST_BUFFER_SIZE + 4);
 
-        verify(mMockProvider, times(8)).bulkInsert(eq(mPackageName), eq(TEST_FEATURE_ID), any(),
+        verify(mMockProvider, times(8)).bulkInsert(eq(mAttributionSource), any(),
                 any());
     }
 
     @SmallTest
     public void testInsertContentsWithDifferentSizePerContentType() throws Exception {
-        when(mMockProvider.bulkInsert(eq(mPackageName), eq(TEST_FEATURE_ID), eqUri(sFilesUri),
+        when(mMockProvider.bulkInsert(eq(mAttributionSource), eqUri(sFilesUri),
                 any())).thenReturn(1);
-        when(mMockProvider.bulkInsert(eq(mPackageName), eq(TEST_FEATURE_ID), eqUri(sAudioUri),
+        when(mMockProvider.bulkInsert(eq(mAttributionSource), eqUri(sAudioUri),
                 any())).thenReturn(1);
-        when(mMockProvider.bulkInsert(eq(mPackageName), eq(TEST_FEATURE_ID), eqUri(sVideoUri),
+        when(mMockProvider.bulkInsert(eq(mAttributionSource), eqUri(sVideoUri),
                 any())).thenReturn(1);
-        when(mMockProvider.bulkInsert(eq(mPackageName), eq(TEST_FEATURE_ID), eqUri(sImagesUri),
+        when(mMockProvider.bulkInsert(eq(mAttributionSource), eqUri(sImagesUri),
                 any())).thenReturn(1);
 
         for (int i = 0; i < TEST_BUFFER_SIZE; ++i) {
@@ -234,13 +239,13 @@
             fillBuffer(sImagesUri, 4);
         }
 
-        verify(mMockProvider, times(1)).bulkInsert(eq(mPackageName), eq(TEST_FEATURE_ID),
+        verify(mMockProvider, times(1)).bulkInsert(eq(mAttributionSource),
                 eqUri(sFilesUri), any());
-        verify(mMockProvider, times(2)).bulkInsert(eq(mPackageName), eq(TEST_FEATURE_ID),
+        verify(mMockProvider, times(2)).bulkInsert(eq(mAttributionSource),
                 eqUri(sAudioUri), any());
-        verify(mMockProvider, times(3)).bulkInsert(eq(mPackageName), eq(TEST_FEATURE_ID),
+        verify(mMockProvider, times(3)).bulkInsert(eq(mAttributionSource),
                 eqUri(sVideoUri), any());
-        verify(mMockProvider, times(4)).bulkInsert(eq(mPackageName), eq(TEST_FEATURE_ID),
+        verify(mMockProvider, times(4)).bulkInsert(eq(mAttributionSource),
                 eqUri(sImagesUri), any());
     }
 }
diff --git a/media/tests/ScoAudioTest/AndroidManifest.xml b/media/tests/ScoAudioTest/AndroidManifest.xml
index a0fba73..5af77ee 100644
--- a/media/tests/ScoAudioTest/AndroidManifest.xml
+++ b/media/tests/ScoAudioTest/AndroidManifest.xml
@@ -22,6 +22,9 @@
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.BROADCAST_STICKY"/>
    <uses-permission android:name="android.permission.BLUETOOTH"/>
+   <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
+   <uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>
+   <uses-permission android:name="android.permission.BLUETOOTH_SCAN"/>
 
    <application>    
         <activity android:label="@string/app_name"
diff --git a/native/android/libandroid.map.txt b/native/android/libandroid.map.txt
index b01878b..35249f6 100644
--- a/native/android/libandroid.map.txt
+++ b/native/android/libandroid.map.txt
@@ -258,6 +258,9 @@
     ASurfaceTransaction_setHdrMetadata_cta861_3; # introduced=29
     ASurfaceTransaction_setHdrMetadata_smpte2086; # introduced=29
     ASurfaceTransaction_setOnComplete; # introduced=29
+    ASurfaceTransaction_setPosition; # introduced=31
+    ASurfaceTransaction_setSourceRect; # introduced=31
+    ASurfaceTransaction_setTransform; # introduced=31
     ASurfaceTransaction_setVisibility; # introduced=29
     ASurfaceTransaction_setZOrder; # introduced=29
     ASystemFontIterator_open; # introduced=29
@@ -285,7 +288,10 @@
     ATrace_endAsyncSection; # introduced=29
     ATrace_setCounter; # introduced=29
     android_getaddrinfofornetwork; # introduced=23
+    android_getprocnetwork; # introduced=31
     android_setprocnetwork; # introduced=23
+    android_getprocdns; # introduced=31
+    android_setprocdns; # introduced=31
     android_setsocknetwork; # introduced=23
     android_res_cancel; # introduced=29
     android_res_nquery; # introduced=29
@@ -309,4 +315,4 @@
         ASurfaceControlStats_getAcquireTime*;
         ASurfaceControlStats_getFrameNumber*;
     };
-} LIBANDROID;
\ No newline at end of file
+} LIBANDROID;
diff --git a/native/android/libandroid_net.map.txt b/native/android/libandroid_net.map.txt
index 8d4e900..a6c1b50 100644
--- a/native/android/libandroid_net.map.txt
+++ b/native/android/libandroid_net.map.txt
@@ -14,6 +14,10 @@
     android_res_nquery; # llndk
     android_res_nresult; # llndk
     android_res_nsend; # llndk
+    # These functions have been part of the NDK since API 31.
+    android_getprocnetwork; # llndk
+    android_setprocdns; # llndk
+    android_getprocdns; # llndk
   local:
     *;
 };
diff --git a/native/android/net.c b/native/android/net.c
index a8104fc..e2f36a7 100644
--- a/native/android/net.c
+++ b/native/android/net.c
@@ -22,12 +22,13 @@
 #include <stdlib.h>
 #include <sys/limits.h>
 
+// This value MUST be kept in sync with the corresponding value in
+// the android.net.Network#getNetworkHandle() implementation.
+static const uint32_t kHandleMagic = 0xcafed00d;
+static const uint32_t kHandleMagicSize = 32;
 
 static int getnetidfromhandle(net_handle_t handle, unsigned *netid) {
     static const uint32_t k32BitMask = 0xffffffff;
-    // This value MUST be kept in sync with the corresponding value in
-    // the android.net.Network#getNetworkHandle() implementation.
-    static const uint32_t kHandleMagic = 0xcafed00d;
 
     // Check for minimum acceptable version of the API in the low bits.
     if (handle != NETWORK_UNSPECIFIED &&
@@ -41,6 +42,12 @@
     return 1;
 }
 
+static net_handle_t gethandlefromnetid(unsigned netid) {
+    if (netid == NETID_UNSET) {
+        return NETWORK_UNSPECIFIED;
+    }
+    return (((net_handle_t) netid) << kHandleMagicSize) | kHandleMagic;
+}
 
 int android_setsocknetwork(net_handle_t network, int fd) {
     unsigned netid;
@@ -72,6 +79,49 @@
     return rval;
 }
 
+int android_getprocnetwork(net_handle_t *network) {
+    if (network == NULL) {
+        errno = EINVAL;
+        return -1;
+    }
+
+    unsigned netid = getNetworkForProcess();
+    *network = gethandlefromnetid(netid);
+    return 0;
+}
+
+int android_setprocdns(net_handle_t network) {
+    unsigned netid;
+    if (!getnetidfromhandle(network, &netid)) {
+        errno = EINVAL;
+        return -1;
+    }
+
+    int rval = setNetworkForResolv(netid);
+    if (rval < 0) {
+        errno = -rval;
+        rval = -1;
+    }
+    return rval;
+}
+
+int android_getprocdns(net_handle_t *network) {
+    if (network == NULL) {
+        errno = EINVAL;
+        return -1;
+    }
+
+    unsigned netid;
+    int rval = getNetworkForDns(&netid);
+    if (rval < 0) {
+        errno = -rval;
+        return -1;
+    }
+
+    *network = gethandlefromnetid(netid);
+    return 0;
+}
+
 int android_getaddrinfofornetwork(net_handle_t network,
         const char *node, const char *service,
         const struct addrinfo *hints, struct addrinfo **res) {
diff --git a/native/android/surface_control.cpp b/native/android/surface_control.cpp
index e8cf63f..195fd5e 100644
--- a/native/android/surface_control.cpp
+++ b/native/android/surface_control.cpp
@@ -446,6 +446,44 @@
     transaction->setTransformToDisplayInverse(surfaceControl, transformToInverseDisplay);
 }
 
+void ASurfaceTransaction_setSourceRect(ASurfaceTransaction* aSurfaceTransaction,
+                                       ASurfaceControl* aSurfaceControl, const ARect& source) {
+    CHECK_NOT_NULL(aSurfaceTransaction);
+    CHECK_NOT_NULL(aSurfaceControl);
+    CHECK_VALID_RECT(source);
+
+    sp<SurfaceControl> surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl);
+    Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
+
+    transaction->setCrop(surfaceControl, static_cast<const Rect&>(source));
+}
+
+void ASurfaceTransaction_setPosition(ASurfaceTransaction* aSurfaceTransaction,
+                                     ASurfaceControl* aSurfaceControl, const ARect& destination) {
+    CHECK_NOT_NULL(aSurfaceTransaction);
+    CHECK_NOT_NULL(aSurfaceControl);
+    CHECK_VALID_RECT(destination);
+
+    sp<SurfaceControl> surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl);
+    Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
+
+    transaction->setFrame(surfaceControl, static_cast<const Rect&>(destination));
+}
+
+void ASurfaceTransaction_setTransform(ASurfaceTransaction* aSurfaceTransaction,
+                                      ASurfaceControl* aSurfaceControl, int32_t transform) {
+    CHECK_NOT_NULL(aSurfaceTransaction);
+    CHECK_NOT_NULL(aSurfaceControl);
+
+    sp<SurfaceControl> surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl);
+    Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
+
+    transaction->setTransform(surfaceControl, transform);
+    bool transformToInverseDisplay = (NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY & transform) ==
+            NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY;
+    transaction->setTransformToDisplayInverse(surfaceControl, transformToInverseDisplay);
+}
+
 void ASurfaceTransaction_setBufferTransparency(ASurfaceTransaction* aSurfaceTransaction,
                                                ASurfaceControl* aSurfaceControl,
                                                int8_t transparency) {
diff --git a/packages/CompanionDeviceManager/AndroidManifest.xml b/packages/CompanionDeviceManager/AndroidManifest.xml
index f9795c6..d36836c 100644
--- a/packages/CompanionDeviceManager/AndroidManifest.xml
+++ b/packages/CompanionDeviceManager/AndroidManifest.xml
@@ -25,6 +25,8 @@
 
     <uses-permission android:name="android.permission.BLUETOOTH"/>
     <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
+    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>
+    <uses-permission android:name="android.permission.BLUETOOTH_SCAN"/>
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
     <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
diff --git a/packages/CompanionDeviceManager/res/values-af/strings.xml b/packages/CompanionDeviceManager/res/values-af/strings.xml
index 36e59ba..3faed55 100644
--- a/packages/CompanionDeviceManager/res/values-af/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-af/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"Kies \'n <xliff:g id="PROFILE_NAME">%1$s</xliff:g> om deur &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; bestuur te word"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"toestel"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"horlosie"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"Stel &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; om jou &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; te bestuur"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"Laat &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; toe om jou &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; te bestuur"</string>
     <string name="profile_summary" msgid="2059360676631420073">"Hierdie program is nodig om jou <xliff:g id="PROFILE_NAME">%1$s</xliff:g> te bestuur. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Laat toe"</string>
     <string name="consent_no" msgid="2640796915611404382">"Moenie toelaat nie"</string>
diff --git a/packages/CompanionDeviceManager/res/values-am/strings.xml b/packages/CompanionDeviceManager/res/values-am/strings.xml
index 0fefa8a..99466d7 100644
--- a/packages/CompanionDeviceManager/res/values-am/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-am/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"በ&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; የሚተዳደር <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ይምረጡ"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"መሣሪያ"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"ሰዓት"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; የእርስዎን <xliff:g id="DEVICE_NAME">%2$s</xliff:g> - &lt;strong&gt;&lt;/strong&gt; ለማስተዳደር"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; የእርስዎን <xliff:g id="DEVICE_NAME">%2$s</xliff:g> - &lt;strong&gt;&lt;/strong&gt; እንዲያስተዳደር ይፍቀዱ"</string>
     <string name="profile_summary" msgid="2059360676631420073">"የእርስዎን <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ለማስተዳደር ይህ መተግበሪያ ያስፈልጋል <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"ፍቀድ"</string>
     <string name="consent_no" msgid="2640796915611404382">"አትፍቀድ"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ar/strings.xml b/packages/CompanionDeviceManager/res/values-ar/strings.xml
index ca3b9f3..e6ed735 100644
--- a/packages/CompanionDeviceManager/res/values-ar/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ar/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"‏اختَر <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ليديره تطبيق &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"جهاز"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"ساعة"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"‏ضبط &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; لإدارة &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"‏السماح لـ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; بإدارة جهازك &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_summary" msgid="2059360676631420073">"هذا التطبيق مطلوب لإدارة <xliff:g id="PROFILE_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"السماح"</string>
     <string name="consent_no" msgid="2640796915611404382">"عدم السماح"</string>
diff --git a/packages/CompanionDeviceManager/res/values-as/strings.xml b/packages/CompanionDeviceManager/res/values-as/strings.xml
index 34ce062..2a2bc25 100644
--- a/packages/CompanionDeviceManager/res/values-as/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-as/strings.xml
@@ -20,12 +20,8 @@
     <string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;এ পৰিচালনা কৰিব লগা এটা <xliff:g id="PROFILE_NAME">%1$s</xliff:g> বাছনি কৰক"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"ডিভাইচ"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"ঘড়ী"</string>
-    <!-- no translation found for confirmation_title (814973816731238955) -->
-    <skip />
-    <!-- no translation found for profile_summary (2059360676631420073) -->
-    <skip />
-    <!-- no translation found for consent_yes (8344487259618762872) -->
-    <skip />
-    <!-- no translation found for consent_no (2640796915611404382) -->
-    <skip />
+    <string name="confirmation_title" msgid="8455544820286920304">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;ক আপোনাৰ &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; পৰিচালনা কৰিবলৈ দিয়ক"</string>
+    <string name="profile_summary" msgid="2059360676631420073">"আপোনাৰ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> পৰিচালনা কৰিবলৈ এই এপ্‌টোৰ আৱশ্যক। <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
+    <string name="consent_yes" msgid="8344487259618762872">"অনুমতি দিয়ক"</string>
+    <string name="consent_no" msgid="2640796915611404382">"অনুমতি নিদিব"</string>
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-az/strings.xml b/packages/CompanionDeviceManager/res/values-az/strings.xml
index 8e4a202..4710dbe 100644
--- a/packages/CompanionDeviceManager/res/values-az/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-az/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; tərəfindən idarə ediləcək <xliff:g id="PROFILE_NAME">%1$s</xliff:g> seçin"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"cihaz"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"izləyin"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; cihazınızı idarə etmək üçün &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ayarlayın"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; tətbiqinin &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; cihazınızı idarə etməsinə icazə verin"</string>
     <string name="profile_summary" msgid="2059360676631420073">"Bu tətbiq <xliff:g id="PROFILE_NAME">%1$s</xliff:g> profilinizi idarə etmək üçün lazımdır. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"İcazə verin"</string>
     <string name="consent_no" msgid="2640796915611404382">"İcazə verməyin"</string>
diff --git a/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml b/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml
index ef19c48..d687b05 100644
--- a/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"Odaberite profil <xliff:g id="PROFILE_NAME">%1$s</xliff:g> kojim će upravljati aplikacija &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"uređaj"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"sat"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"Podesite aplikaciju &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; tako da upravlja uređajem &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"Dozvolite aplikaciji &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; da upravlja uređajem &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_summary" msgid="2059360676631420073">"Ova aplikacija je potrebna za upravljanje profilom <xliff:g id="PROFILE_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Dozvoli"</string>
     <string name="consent_no" msgid="2640796915611404382">"Ne dozvoli"</string>
diff --git a/packages/CompanionDeviceManager/res/values-be/strings.xml b/packages/CompanionDeviceManager/res/values-be/strings.xml
index 4366a08..2236052f5 100644
--- a/packages/CompanionDeviceManager/res/values-be/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-be/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"Выберыце прыладу (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>), якой будзе кіраваць праграма &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"прылада"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"гадзіннік"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"Дазвольце праграме &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; кіраваць прыладай &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"Дазвольце праграме &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; кіраваць прыладай &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_summary" msgid="2059360676631420073">"Гэта праграма неабходная для кіравання профілем \"<xliff:g id="PROFILE_NAME">%1$s</xliff:g>\". <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Дазволіць"</string>
     <string name="consent_no" msgid="2640796915611404382">"Не дазваляць"</string>
diff --git a/packages/CompanionDeviceManager/res/values-bg/strings.xml b/packages/CompanionDeviceManager/res/values-bg/strings.xml
index 77f3413..996ca90 100644
--- a/packages/CompanionDeviceManager/res/values-bg/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-bg/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"Изберете устройство (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>), което да се управлява от &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"устройство"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"часовник"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"Задайте &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; да управлява устройството ви &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"Разрешаване на &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; да управлява устройството ви &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_summary" msgid="2059360676631420073">"Това приложение е необходимо за управление на <xliff:g id="PROFILE_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Разрешаване"</string>
     <string name="consent_no" msgid="2640796915611404382">"Забраняване"</string>
diff --git a/packages/CompanionDeviceManager/res/values-bn/strings.xml b/packages/CompanionDeviceManager/res/values-bn/strings.xml
index 5fa4781..a0294cd 100644
--- a/packages/CompanionDeviceManager/res/values-bn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-bn/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"<xliff:g id="PROFILE_NAME">%1$s</xliff:g> বেছে নিন যেটি &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; ম্যানেজ করবে"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"ডিভাইস"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"দেখুন"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"আপনার &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ম্যানেজ করার জন্য &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; সেট করুন"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"আপনার &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ম্যানেজ করার জন্য &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; -কে অনুমতি দিন"</string>
     <string name="profile_summary" msgid="2059360676631420073">"আপনার <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ম্যানেজ করতে এই অ্যাপটি প্রয়োজন। <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"অনুমতি দিন"</string>
     <string name="consent_no" msgid="2640796915611404382">"অনুমতি দেবেন না"</string>
diff --git a/packages/CompanionDeviceManager/res/values-bs/strings.xml b/packages/CompanionDeviceManager/res/values-bs/strings.xml
index 18153b5..10f753c 100644
--- a/packages/CompanionDeviceManager/res/values-bs/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-bs/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"Odaberite uređaj <xliff:g id="PROFILE_NAME">%1$s</xliff:g> kojim će upravljati aplikacija &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"uređaj"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"sat"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"Postavite aplikaciju &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; da upravlja vašim uređajem &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"Dozvolite aplikaciji &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; da upravlja uređajem &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_summary" msgid="2059360676631420073">"Ova aplikacija je potrebna za upravljanje profilom: <xliff:g id="PROFILE_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Dozvoli"</string>
     <string name="consent_no" msgid="2640796915611404382">"Nemoj dozvoliti"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ca/strings.xml b/packages/CompanionDeviceManager/res/values-ca/strings.xml
index bbd1125..6569cb9 100644
--- a/packages/CompanionDeviceManager/res/values-ca/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ca/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"Tria un <xliff:g id="PROFILE_NAME">%1$s</xliff:g> perquè el gestioni &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"dispositiu"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"rellotge"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"Defineix que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; gestioni el dispositiu &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"Permet que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; gestioni el dispositiu &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_summary" msgid="2059360676631420073">"Aquesta aplicació es necessita per gestionar <xliff:g id="PROFILE_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Permet"</string>
     <string name="consent_no" msgid="2640796915611404382">"No permetis"</string>
diff --git a/packages/CompanionDeviceManager/res/values-cs/strings.xml b/packages/CompanionDeviceManager/res/values-cs/strings.xml
index c5fed33..4e88a7e 100644
--- a/packages/CompanionDeviceManager/res/values-cs/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-cs/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"Vyberte zařízení <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, které chcete spravovat pomocí aplikace &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"zařízení"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"hodinky"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"Nastavit aplikaci &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; pro správu vašeho zařízení: &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"Povolit aplikaci &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; spravovat vaše zařízení &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_summary" msgid="2059360676631420073">"Tato aplikace je nutná pro správu profilu <xliff:g id="PROFILE_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Povolit"</string>
     <string name="consent_no" msgid="2640796915611404382">"Nepovolovat"</string>
diff --git a/packages/CompanionDeviceManager/res/values-da/strings.xml b/packages/CompanionDeviceManager/res/values-da/strings.xml
index 21280d5..522e644 100644
--- a/packages/CompanionDeviceManager/res/values-da/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-da/strings.xml
@@ -16,11 +16,11 @@
 
 <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="4470785958457506021">"Medfølgende enhedshåndtering"</string>
+    <string name="app_label" msgid="4470785958457506021">"Medfølgende enhedsadministrator"</string>
     <string name="chooser_title" msgid="2262294130493605839">"Vælg den enhed (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>), som skal administreres af &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"enhed"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"ur"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"Indstil &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; til at administrere &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"Tillad &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; at administrere: &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_summary" msgid="2059360676631420073">"Du skal bruge denne app for at administrere dit <xliff:g id="PROFILE_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Tillad"</string>
     <string name="consent_no" msgid="2640796915611404382">"Tillad ikke"</string>
diff --git a/packages/CompanionDeviceManager/res/values-de/strings.xml b/packages/CompanionDeviceManager/res/values-de/strings.xml
index 1c7ec74..2caa3a9 100644
--- a/packages/CompanionDeviceManager/res/values-de/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-de/strings.xml
@@ -20,12 +20,8 @@
     <string name="chooser_title" msgid="2262294130493605839">"Gerät (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>) auswählen, das von &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; verwaltet werden soll"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"Gerät"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"Smartwatch"</string>
-    <!-- no translation found for confirmation_title (814973816731238955) -->
-    <skip />
-    <!-- no translation found for profile_summary (2059360676631420073) -->
-    <skip />
-    <!-- no translation found for consent_yes (8344487259618762872) -->
-    <skip />
-    <!-- no translation found for consent_no (2640796915611404382) -->
-    <skip />
+    <string name="confirmation_title" msgid="8455544820286920304">"Zulassen, dass &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; dein Gerät &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; verwalten darf"</string>
+    <string name="profile_summary" msgid="2059360676631420073">"Diese App wird zur Verwaltung des Profils „<xliff:g id="PROFILE_NAME">%1$s</xliff:g>“ benötigt. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
+    <string name="consent_yes" msgid="8344487259618762872">"Zulassen"</string>
+    <string name="consent_no" msgid="2640796915611404382">"Nicht zulassen"</string>
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-el/strings.xml b/packages/CompanionDeviceManager/res/values-el/strings.xml
index 162d6fc..7a78c06 100644
--- a/packages/CompanionDeviceManager/res/values-el/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-el/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"Επιλέξτε ένα προφίλ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> για διαχείριση από την εφαρμογή &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"συσκευή"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"ρολόι"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"Ορίστε την εφαρμογή &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; για διαχείριση της συσκευής &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"Επιτρέψτε στην εφαρμογή &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; να διαχειρίζεται τη συσκευή &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_summary" msgid="2059360676631420073">"Αυτή η εφαρμογή είναι απαραίτητη για τη διαχείριση του προφίλ σας <xliff:g id="PROFILE_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Να επιτρέπεται"</string>
     <string name="consent_no" msgid="2640796915611404382">"Να μην επιτρέπεται"</string>
diff --git a/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml b/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml
index de89b39..a6ebe65 100644
--- a/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"Choose a <xliff:g id="PROFILE_NAME">%1$s</xliff:g> to be managed by &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"device"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"watch"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"Set &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to manage your &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to manage your &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_summary" msgid="2059360676631420073">"This app is needed to manage your <xliff:g id="PROFILE_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Allow"</string>
     <string name="consent_no" msgid="2640796915611404382">"Don\'t allow"</string>
diff --git a/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml b/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml
index de89b39..a6ebe65 100644
--- a/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"Choose a <xliff:g id="PROFILE_NAME">%1$s</xliff:g> to be managed by &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"device"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"watch"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"Set &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to manage your &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to manage your &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_summary" msgid="2059360676631420073">"This app is needed to manage your <xliff:g id="PROFILE_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Allow"</string>
     <string name="consent_no" msgid="2640796915611404382">"Don\'t allow"</string>
diff --git a/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml b/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml
index de89b39..a6ebe65 100644
--- a/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"Choose a <xliff:g id="PROFILE_NAME">%1$s</xliff:g> to be managed by &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"device"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"watch"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"Set &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to manage your &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to manage your &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_summary" msgid="2059360676631420073">"This app is needed to manage your <xliff:g id="PROFILE_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Allow"</string>
     <string name="consent_no" msgid="2640796915611404382">"Don\'t allow"</string>
diff --git a/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml b/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml
index de89b39..a6ebe65 100644
--- a/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"Choose a <xliff:g id="PROFILE_NAME">%1$s</xliff:g> to be managed by &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"device"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"watch"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"Set &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to manage your &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to manage your &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_summary" msgid="2059360676631420073">"This app is needed to manage your <xliff:g id="PROFILE_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Allow"</string>
     <string name="consent_no" msgid="2640796915611404382">"Don\'t allow"</string>
diff --git a/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml b/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml
index 10c2012..6cc56a4 100644
--- a/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml
@@ -20,8 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‎‎‏‎‏‎‏‎‎‏‎‎‎‏‎‎‎‎‏‏‎‏‎‎‎‏‎‎‏‏‎‎‎‎‏‎‏‏‏‎‎‎‏‏‏‏‏‎‎‏‏‏‏‎Choose a ‎‏‎‎‏‏‎<xliff:g id="PROFILE_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ to be managed by &lt;strong&gt;‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%2$s</xliff:g>‎‏‎‎‏‏‏‎&lt;/strong&gt;‎‏‎‎‏‎"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‎‏‎‎‏‏‏‎‏‏‏‏‏‎‎‏‎‎‏‎‎‏‏‏‏‎‎‎‏‏‏‎‏‏‏‎‎‎‎‎‎‎‎‏‏‏‎‏‏‎‏‏‎‎‎device‎‏‎‎‏‎"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‏‎‏‎‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‎‏‎‏‎‏‏‏‏‏‏‏‎‎‏‎‏‎‎‎‎watch‎‏‎‎‏‎"</string>
-    <!-- no translation found for confirmation_title (814973816731238955) -->
-    <skip />
+    <string name="confirmation_title" msgid="8455544820286920304">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‏‏‎‎‎‎‎‏‎‎‎‎‏‎‎‏‏‎‏‏‎‏‏‏‏‎‎‏‏‏‎‎‏‏‎‎‎‏‎‎‏‎‏‏‎‎‏‏‏‎‎‎‎‎Allow &lt;strong&gt;‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎&lt;/strong&gt; to manage your &lt;strong&gt;‎‏‎‎‏‏‎<xliff:g id="DEVICE_NAME">%2$s</xliff:g>‎‏‎‎‏‏‏‎&lt;/strong&gt;‎‏‎‎‏‎"</string>
     <string name="profile_summary" msgid="2059360676631420073">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‏‎‎‏‎‏‎‎‎‏‎‏‎‎‎‏‏‎‎‏‏‏‏‏‏‏‎‏‏‎‏‏‎‎‎‎‎‏‏‎‎‎‎‏‏‏‎‎‏‎‏‎‏‎‎‏‎This app is needed to manage your ‎‏‎‎‏‏‎<xliff:g id="PROFILE_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎. ‎‏‎‎‏‏‎<xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="consent_yes" msgid="8344487259618762872">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‎‏‏‎‏‏‎‎‏‎‎‏‎‏‏‏‏‎‎‏‏‏‎‎‏‏‏‏‎‎‏‎‏‏‎‎‏‎‏‏‎‎‎‎‎‎‏‏‏‏‎‎‎‎Allow‎‏‎‎‏‎"</string>
     <string name="consent_no" msgid="2640796915611404382">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‏‎‏‎‎‏‎‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‎‏‏‎‎‏‏‏‏‎‏‏‏‏‎‏‏‏‎‎‎‎‏‎‎‎‎‏‎‏‏‏‏‎‎Don’t allow‎‏‎‎‏‎"</string>
diff --git a/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml b/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml
index 8dae51c..dc13159 100644
--- a/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"Elige un <xliff:g id="PROFILE_NAME">%1$s</xliff:g> para que &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; lo administre"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"reloj"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"Configura &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; para administrar el dispositivo &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"Permite que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; administre tu &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_summary" msgid="2059360676631420073">"Esta app es necesaria para administrar tu <xliff:g id="PROFILE_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
     <string name="consent_no" msgid="2640796915611404382">"No permitir"</string>
diff --git a/packages/CompanionDeviceManager/res/values-es/strings.xml b/packages/CompanionDeviceManager/res/values-es/strings.xml
index a307b61..5fc8d10 100644
--- a/packages/CompanionDeviceManager/res/values-es/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-es/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"Elige un <xliff:g id="PROFILE_NAME">%1$s</xliff:g> para gestionarlo con &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"reloj"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"Configura &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; para que gestione tu dispositivo &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"Permitir que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; gestione tu dispositivo &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_summary" msgid="2059360676631420073">"Se necesita esta aplicación para gestionar tu <xliff:g id="PROFILE_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
     <string name="consent_no" msgid="2640796915611404382">"No permitir"</string>
diff --git a/packages/CompanionDeviceManager/res/values-et/strings.xml b/packages/CompanionDeviceManager/res/values-et/strings.xml
index 2fb2bc4..399556d 100644
--- a/packages/CompanionDeviceManager/res/values-et/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-et/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"Valige seade <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, mida haldab rakendus &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"seade"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"käekell"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"Määrake rakendus &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; haldama teie seadet &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"Lubage rakendusel &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; hallata teie seadet &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_summary" msgid="2059360676631420073">"Seda rakendust on vaja teie profiili <xliff:g id="PROFILE_NAME">%1$s</xliff:g> haldamiseks. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Luba"</string>
     <string name="consent_no" msgid="2640796915611404382">"Ära luba"</string>
diff --git a/packages/CompanionDeviceManager/res/values-eu/strings.xml b/packages/CompanionDeviceManager/res/values-eu/strings.xml
index 646f844..764505e 100644
--- a/packages/CompanionDeviceManager/res/values-eu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-eu/strings.xml
@@ -20,8 +20,8 @@
     <string name="chooser_title" msgid="2262294130493605839">"Aukeratu &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; aplikazioak kudeatu beharreko <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"gailua"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"erlojua"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"Konfiguratu &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; kudea dezan"</string>
-    <string name="profile_summary" msgid="2059360676631420073">"<xliff:g id="PROFILE_NAME">%1$s</xliff:g> kudeatzeko beharrezkoa da aplikazioa. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"Eman &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; kudeatzeko baimena &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; aplikazioari"</string>
+    <string name="profile_summary" msgid="2059360676631420073">"Aplikazioa <xliff:g id="PROFILE_NAME">%1$s</xliff:g> kudeatzeko beharrezkoa da. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Eman baimena"</string>
     <string name="consent_no" msgid="2640796915611404382">"Ez eman baimenik"</string>
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-fa/strings.xml b/packages/CompanionDeviceManager/res/values-fa/strings.xml
index 69b9647..83cc263 100644
--- a/packages/CompanionDeviceManager/res/values-fa/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fa/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"‏انتخاب <xliff:g id="PROFILE_NAME">%1$s</xliff:g> برای مدیریت کردن با &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>‏&lt;/strong&gt;"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"دستگاه"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"ساعت"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"‏تنظیم &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; برای مدیریت &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"‏مجاز کردن &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; برای مدیریت کردن &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_summary" msgid="2059360676631420073">"این برنامه برای مدیریت <xliff:g id="PROFILE_NAME">%1$s</xliff:g> شما لازم است. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"مجاز"</string>
     <string name="consent_no" msgid="2640796915611404382">"مجاز نیست"</string>
diff --git a/packages/CompanionDeviceManager/res/values-fi/strings.xml b/packages/CompanionDeviceManager/res/values-fi/strings.xml
index b174b8a..0e66302 100644
--- a/packages/CompanionDeviceManager/res/values-fi/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fi/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"Valitse <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, jota &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; hallinnoi"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"laite"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"kello"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"Valitse &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; laitteen (&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;) ylläpitäjäksi"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"Salli, että &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; voi ylläpitää laitettasi: &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_summary" msgid="2059360676631420073">"Profiilin (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>) ylläpitoon tarvitaan tätä sovellusta. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Salli"</string>
     <string name="consent_no" msgid="2640796915611404382">"Älä salli"</string>
diff --git a/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml b/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
index 696598d..2cf872c 100644
--- a/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"Choisissez un <xliff:g id="PROFILE_NAME">%1$s</xliff:g> qui sera géré par &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"appareil"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"montre"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"Utiliser &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; pour gérer votre &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"Autoriser &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; pour gérer votre &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_summary" msgid="2059360676631420073">"Cette application est nécessaire pour gérer votre <xliff:g id="PROFILE_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Autoriser"</string>
     <string name="consent_no" msgid="2640796915611404382">"Ne pas autoriser"</string>
diff --git a/packages/CompanionDeviceManager/res/values-fr/strings.xml b/packages/CompanionDeviceManager/res/values-fr/strings.xml
index 787794b..ba2fc8e 100644
--- a/packages/CompanionDeviceManager/res/values-fr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fr/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"Sélectionner le/la <xliff:g id="PROFILE_NAME">%1$s</xliff:g> qui sera géré(e) par &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"appareil"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"montre"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"Définir &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; pour gérer votre &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"Autoriser &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; à gérer votre &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_summary" msgid="2059360676631420073">"Cette appli est nécessaire pour gérer votre <xliff:g id="PROFILE_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Autoriser"</string>
     <string name="consent_no" msgid="2640796915611404382">"Ne pas autoriser"</string>
diff --git a/packages/CompanionDeviceManager/res/values-gl/strings.xml b/packages/CompanionDeviceManager/res/values-gl/strings.xml
index a3efc4c..5f9a8d7 100644
--- a/packages/CompanionDeviceManager/res/values-gl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-gl/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"Escolle un perfil (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>) para que o xestione a aplicación &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"reloxo"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"Configura &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; para que xestione o teu dispositivo &lt;strong&gt;(<xliff:g id="DEVICE_NAME">%2$s</xliff:g>)&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"Permitir que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; xestione o teu dispositivo (&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;)"</string>
     <string name="profile_summary" msgid="2059360676631420073">"Esta aplicación é necesaria para xestionar o teu perfil (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>). <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
     <string name="consent_no" msgid="2640796915611404382">"Non permitir"</string>
diff --git a/packages/CompanionDeviceManager/res/values-gu/strings.xml b/packages/CompanionDeviceManager/res/values-gu/strings.xml
index 1b0fe1a..71cf012 100644
--- a/packages/CompanionDeviceManager/res/values-gu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-gu/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; દ્વારા મેનેજ કરવા માટે કોઈ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> પસંદ કરો"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"ડિવાઇસ"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"સ્માર્ટવૉચ"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"તમારું &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; મેનેજ કરવા માટે, &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; સેટ કરો"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"તમારા &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;ને મેનેજ કરવા માટે &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;ને મંજૂર કરો"</string>
     <string name="profile_summary" msgid="2059360676631420073">"તમારી <xliff:g id="PROFILE_NAME">%1$s</xliff:g> મેનેજ કરવા માટે આ ઍપ જરૂરી છે. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"મંજૂરી આપો"</string>
     <string name="consent_no" msgid="2640796915611404382">"મંજૂરી આપશો નહીં"</string>
diff --git a/packages/CompanionDeviceManager/res/values-hi/strings.xml b/packages/CompanionDeviceManager/res/values-hi/strings.xml
index dee30f2..e875e42 100644
--- a/packages/CompanionDeviceManager/res/values-hi/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hi/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"कोई <xliff:g id="PROFILE_NAME">%1$s</xliff:g> चुनें, ताकि उसे &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; की मदद से प्रबंधित किया जा सके"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"डिवाइस"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"स्मार्टवॉच"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; को मैनेज करने के लिए, &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; सेट अप करें"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"अपने &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; को मैनेज करने के लिए, &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; को अनुमति दें"</string>
     <string name="profile_summary" msgid="2059360676631420073">"यह ऐप्लिकेशन, <xliff:g id="PROFILE_NAME">%1$s</xliff:g> मैनेज करने के लिए ज़रूरी है. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"अनुमति दें"</string>
     <string name="consent_no" msgid="2640796915611404382">"अनुमति न दें"</string>
diff --git a/packages/CompanionDeviceManager/res/values-hr/strings.xml b/packages/CompanionDeviceManager/res/values-hr/strings.xml
index bc36521..b9df54f 100644
--- a/packages/CompanionDeviceManager/res/values-hr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hr/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"Odaberite profil <xliff:g id="PROFILE_NAME">%1$s</xliff:g> kojim će upravljati aplikacija &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"uređaj"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"satom"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"Postavite aplikaciju &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; da upravlja vašim uređajem &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"Dopustite aplikaciji &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; da upravlja vašim uređajem &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_summary" msgid="2059360676631420073">"Ta je aplikacija potrebna za upravljanje vašim profilom <xliff:g id="PROFILE_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Dopusti"</string>
     <string name="consent_no" msgid="2640796915611404382">"Nemoj dopustiti"</string>
diff --git a/packages/CompanionDeviceManager/res/values-hu/strings.xml b/packages/CompanionDeviceManager/res/values-hu/strings.xml
index ef50544..c7ceb38 100644
--- a/packages/CompanionDeviceManager/res/values-hu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hu/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"A(z) &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; alkalmazással kezelni kívánt <xliff:g id="PROFILE_NAME">%1$s</xliff:g> kiválasztása"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"eszköz"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"óra"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"A(z) &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; alkalmazás beállítva a(z) <xliff:g id="DEVICE_NAME">%2$s</xliff:g> (&lt;strong&gt;&lt;/strong&gt;) kezelésére"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"A(z) &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; engedélyezése a(z) &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; kezelésére"</string>
     <string name="profile_summary" msgid="2059360676631420073">"Szükség van erre az alkalmazásra a következő kezeléséhez: <xliff:g id="PROFILE_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Engedélyezés"</string>
     <string name="consent_no" msgid="2640796915611404382">"Tiltás"</string>
diff --git a/packages/CompanionDeviceManager/res/values-hy/strings.xml b/packages/CompanionDeviceManager/res/values-hy/strings.xml
index 103361a..9819367 100644
--- a/packages/CompanionDeviceManager/res/values-hy/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hy/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"Ընտրեք <xliff:g id="PROFILE_NAME">%1$s</xliff:g>ը, որը պետք է կառավարվի &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; հավելվածի կողմից"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"սարք"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"ժամացույց"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"Ընտրեք &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; հավելվածը որպես &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; սարքի կառավարիչ"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"Թույլատրեք &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; հավելվածին կառավարել ձեր &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; սարքը"</string>
     <string name="profile_summary" msgid="2059360676631420073">"Այս հավելվածն անհրաժեշտ է ձեր <xliff:g id="PROFILE_NAME">%1$s</xliff:g> պրոֆիլը կառավարելու համար։ <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Թույլատրել"</string>
     <string name="consent_no" msgid="2640796915611404382">"Չթույլատրել"</string>
diff --git a/packages/CompanionDeviceManager/res/values-in/strings.xml b/packages/CompanionDeviceManager/res/values-in/strings.xml
index 225b276..b0618d4 100644
--- a/packages/CompanionDeviceManager/res/values-in/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-in/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"Pilih <xliff:g id="PROFILE_NAME">%1$s</xliff:g> untuk dikelola oleh &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"perangkat"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"smartwatch"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"Tetapkan &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; untuk mengelola &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"Izinkan &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; untuk mengelola &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_summary" msgid="2059360676631420073">"Aplikasi ini diperlukan untuk mengelola <xliff:g id="PROFILE_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Izinkan"</string>
     <string name="consent_no" msgid="2640796915611404382">"Jangan izinkan"</string>
diff --git a/packages/CompanionDeviceManager/res/values-is/strings.xml b/packages/CompanionDeviceManager/res/values-is/strings.xml
index 7855a2a..296f852 100644
--- a/packages/CompanionDeviceManager/res/values-is/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-is/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"Velja <xliff:g id="PROFILE_NAME">%1$s</xliff:g> sem &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; á að stjórna"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"tæki"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"úr"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"Veita &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; stjórn á &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"Veita &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; stjórn á &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_summary" msgid="2059360676631420073">"Þetta forrit er nauðsynlegt til að hafa umsjón með <xliff:g id="PROFILE_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Leyfa"</string>
     <string name="consent_no" msgid="2640796915611404382">"Ekki leyfa"</string>
diff --git a/packages/CompanionDeviceManager/res/values-it/strings.xml b/packages/CompanionDeviceManager/res/values-it/strings.xml
index 9e503e1..ce003e7 100644
--- a/packages/CompanionDeviceManager/res/values-it/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-it/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"Scegli un <xliff:g id="PROFILE_NAME">%1$s</xliff:g> che sia gestito da &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"orologio"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"Configura l\'app &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; affinché gestisca &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"Consenti all\'app &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; di gestire &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_summary" msgid="2059360676631420073">"Questa app è necessaria per gestire il tuo <xliff:g id="PROFILE_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Consenti"</string>
     <string name="consent_no" msgid="2640796915611404382">"Non consentire"</string>
diff --git a/packages/CompanionDeviceManager/res/values-iw/strings.xml b/packages/CompanionDeviceManager/res/values-iw/strings.xml
index d293fb0..3af66260 100644
--- a/packages/CompanionDeviceManager/res/values-iw/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-iw/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"‏בחירה של <xliff:g id="PROFILE_NAME">%1$s</xliff:g> לניהול באמצעות &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"מכשיר"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"שעון"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"‏הגדרה של &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; לניהול &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"‏אישור לאפליקציה &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; לנהל את &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_summary" msgid="2059360676631420073">"האפליקציה הזו נחוצה כדי לנהל את <xliff:g id="PROFILE_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"יש אישור"</string>
     <string name="consent_no" msgid="2640796915611404382">"אין אישור"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ja/strings.xml b/packages/CompanionDeviceManager/res/values-ja/strings.xml
index ac8e2d2..83f3817 100644
--- a/packages/CompanionDeviceManager/res/values-ja/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ja/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; の管理対象となる<xliff:g id="PROFILE_NAME">%1$s</xliff:g>の選択"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"デバイス"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"ウォッチ"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; を管理する &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; の設定"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; に &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; の管理を許可する"</string>
     <string name="profile_summary" msgid="2059360676631420073">"このアプリは<xliff:g id="PROFILE_NAME">%1$s</xliff:g>の管理に必要です。<xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"許可"</string>
     <string name="consent_no" msgid="2640796915611404382">"許可しない"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ka/strings.xml b/packages/CompanionDeviceManager/res/values-ka/strings.xml
index 8b7680e..34efdd2 100644
--- a/packages/CompanionDeviceManager/res/values-ka/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ka/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"აირჩიეთ <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, რომელიც უნდა მართოს &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;-მა"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"მოწყობილობა"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"საათი"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"დააყენეთ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;, რათა მართოთ თქვენი &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"ნება დართეთ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>-ს&lt;/strong&gt;, რომ მართოს თქვენი &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_summary" msgid="2059360676631420073">"ეს აპი საჭიროა თქვენი <xliff:g id="PROFILE_NAME">%1$s</xliff:g>-ს სამართავად. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"დაშვება"</string>
     <string name="consent_no" msgid="2640796915611404382">"არ დაიშვას"</string>
diff --git a/packages/CompanionDeviceManager/res/values-kk/strings.xml b/packages/CompanionDeviceManager/res/values-kk/strings.xml
index 1ad854e..3c7f697 100644
--- a/packages/CompanionDeviceManager/res/values-kk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-kk/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; арқылы басқарылатын <xliff:g id="PROFILE_NAME">%1$s</xliff:g> құрылғысын таңдаңыз"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"құрылғы"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"сағат"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; қолданбасына &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; құрылғысын басқаруға рұқсат беріңіз"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; қолданбасына &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; құрылғысын басқаруға рұқсат беру"</string>
     <string name="profile_summary" msgid="2059360676631420073">"Бұл қолданба <xliff:g id="PROFILE_NAME">%1$s</xliff:g> профиліңізді басқару үшін қажет. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Рұқсат беру"</string>
     <string name="consent_no" msgid="2640796915611404382">"Рұқсат бермеу"</string>
diff --git a/packages/CompanionDeviceManager/res/values-km/strings.xml b/packages/CompanionDeviceManager/res/values-km/strings.xml
index 7231c2d..74ccd84 100644
--- a/packages/CompanionDeviceManager/res/values-km/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-km/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"ជ្រើសរើស <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ដើម្បីឱ្យស្ថិតក្រោម​ការគ្រប់គ្រងរបស់ &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"ឧបករណ៍"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"នាឡិកា"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"កំណត់ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ដើម្បីគ្រប់គ្រង &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; របស់អ្នក"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"អនុញ្ញាតឱ្យ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; គ្រប់គ្រង &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; របស់អ្នក"</string>
     <string name="profile_summary" msgid="2059360676631420073">"ត្រូវការកម្មវិធីនេះ ដើម្បីគ្រប់គ្រង <xliff:g id="PROFILE_NAME">%1$s</xliff:g> របស់អ្នក។ <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"អនុញ្ញាត"</string>
     <string name="consent_no" msgid="2640796915611404382">"កុំអនុញ្ញាត"</string>
diff --git a/packages/CompanionDeviceManager/res/values-kn/strings.xml b/packages/CompanionDeviceManager/res/values-kn/strings.xml
index 6f75328..2a82d1f 100644
--- a/packages/CompanionDeviceManager/res/values-kn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-kn/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; ಮೂಲಕ ನಿರ್ವಹಿಸಬೇಕಾದ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ಅನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"ಸಾಧನ"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"ವೀಕ್ಷಿಸಿ"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"ನಿಮ್ಮ &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ಅನ್ನು ನಿರ್ವಹಿಸಲು &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ಅನ್ನು ಸೆಟ್ ಮಾಡಿ"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"ನಿಮ್ಮ &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ಅನ್ನು ನಿರ್ವಹಿಸಲು &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ಅನ್ನು ಅನುಮತಿಸಿ"</string>
     <string name="profile_summary" msgid="2059360676631420073">"ನಿಮ್ಮ <xliff:g id="PROFILE_NAME">%1$s</xliff:g>. ಅನ್ನು ನಿರ್ವಹಿಸಲು ಈ ಆ್ಯಪ್‌ನ ಅಗತ್ಯವಿದೆ. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"ಅನುಮತಿಸಿ"</string>
     <string name="consent_no" msgid="2640796915611404382">"ಅನುಮತಿಸಬೇಡಿ"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ko/strings.xml b/packages/CompanionDeviceManager/res/values-ko/strings.xml
index 5b171ea..6ca01bf 100644
--- a/packages/CompanionDeviceManager/res/values-ko/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ko/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;에서 관리할 <xliff:g id="PROFILE_NAME">%1$s</xliff:g>을(를) 선택"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"기기"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"시계"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; 앱이 &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; 기기를 관리하도록 설정"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;에서 &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; 기기를 관리하도록 허용"</string>
     <string name="profile_summary" msgid="2059360676631420073">"이 앱은 <xliff:g id="PROFILE_NAME">%1$s</xliff:g> 프로필을 관리하는 데 필요합니다. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"허용"</string>
     <string name="consent_no" msgid="2640796915611404382">"허용 안함"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ky/strings.xml b/packages/CompanionDeviceManager/res/values-ky/strings.xml
index f7c896b..18d38a8 100644
--- a/packages/CompanionDeviceManager/res/values-ky/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ky/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"<xliff:g id="PROFILE_NAME">%1$s</xliff:g> &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; тарабынан башкарылсын"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"түзмөк"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"саат"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; түзмөгүңүздү башкаруу үчүн &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; колдонмосун жөндөңүз"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; колдонмосуна &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; түзмөгүңүздү башкарууга уруксат бериңиз"</string>
     <string name="profile_summary" msgid="2059360676631420073">"Бул колдонмо <xliff:g id="PROFILE_NAME">%1$s</xliff:g> профилиңизди башкаруу үчүн керек. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Уруксат берүү"</string>
     <string name="consent_no" msgid="2640796915611404382">"Уруксат берилбесин"</string>
diff --git a/packages/CompanionDeviceManager/res/values-lo/strings.xml b/packages/CompanionDeviceManager/res/values-lo/strings.xml
index 8ad881f..a1eb713 100644
--- a/packages/CompanionDeviceManager/res/values-lo/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-lo/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"ເລືອກ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ເພື່ອໃຫ້ຖືກຈັດການໂດຍ &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"ອຸປະກອນ"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"ໂມງ"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"ຕັ້ງຄ່າ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ເພື່ອຈັດການ &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ຂອງທ່ານ"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"ອະນຸຍາດໃຫ້ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ຈັດການ &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ຂອງທ່ານໄດ້"</string>
     <string name="profile_summary" msgid="2059360676631420073">"ຕ້ອງໃຊ້ແອັບນີ້ເພື່ອຈັດການ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ຂອງທ່ານ. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"ອະນຸຍາດ"</string>
     <string name="consent_no" msgid="2640796915611404382">"ບໍ່ອະນຸຍາດ"</string>
diff --git a/packages/CompanionDeviceManager/res/values-lt/strings.xml b/packages/CompanionDeviceManager/res/values-lt/strings.xml
index c40d4a7..0103f7c 100644
--- a/packages/CompanionDeviceManager/res/values-lt/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-lt/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"Jūsų <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, kurį valdys &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; (pasirinkite)"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"įrenginys"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"laikrodis"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; tvarkymo naudojant &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; nustatymas"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"Leisti &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; tvarkyti &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_summary" msgid="2059360676631420073">"Ši programa reikalinga norint tvarkyti jūsų <xliff:g id="PROFILE_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Leisti"</string>
     <string name="consent_no" msgid="2640796915611404382">"Neleisti"</string>
diff --git a/packages/CompanionDeviceManager/res/values-lv/strings.xml b/packages/CompanionDeviceManager/res/values-lv/strings.xml
index c842ee1..b18bfe4 100644
--- a/packages/CompanionDeviceManager/res/values-lv/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-lv/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"Profila (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>) izvēle, ko pārvaldīt lietotnē &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"ierīce"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"pulkstenis"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"Lietotnes &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; iestatīšana ierīces &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; pārvaldībai"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"Atļauja lietotnei &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; pārvaldīt ierīci &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_summary" msgid="2059360676631420073">"Šī lietotne ir nepieciešama jūsu profila (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>) pārvaldībai. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Atļaut"</string>
     <string name="consent_no" msgid="2640796915611404382">"Neatļaut"</string>
diff --git a/packages/CompanionDeviceManager/res/values-mk/strings.xml b/packages/CompanionDeviceManager/res/values-mk/strings.xml
index fdc366e..9d745c4 100644
--- a/packages/CompanionDeviceManager/res/values-mk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-mk/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"Изберете <xliff:g id="PROFILE_NAME">%1$s</xliff:g> со којшто ќе управува &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"уред"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"часовник"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"Поставете &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; за да управувате со вашиот &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"Дозволете &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; да управува со вашиот &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_summary" msgid="2059360676631420073">"Апликацијава е потребна за управување со вашиот <xliff:g id="PROFILE_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Дозволи"</string>
     <string name="consent_no" msgid="2640796915611404382">"Не дозволувај"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ml/strings.xml b/packages/CompanionDeviceManager/res/values-ml/strings.xml
index ae445a3..28c88da 100644
--- a/packages/CompanionDeviceManager/res/values-ml/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ml/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; ഉപയോഗിച്ച് മാനേജ് ചെയ്യുന്നതിന് ഒരു <xliff:g id="PROFILE_NAME">%1$s</xliff:g> തിരഞ്ഞെടുക്കുക"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"ഉപകരണം"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"വാച്ച്"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"നിങ്ങളുടെ &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; മാനേജ് ചെയ്യുന്നതിന് &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; സജ്ജീകരിക്കുക"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"നിങ്ങളുടെ &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; മാനേജ് ചെയ്യാൻ, &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; എന്നതിനെ അനുവദിക്കുക"</string>
     <string name="profile_summary" msgid="2059360676631420073">"നിങ്ങളുടെ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> മാനേജ് ചെയ്യാൻ ഈ ആപ്പ് ആവശ്യമാണ്. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"അനുവദിക്കുക"</string>
     <string name="consent_no" msgid="2640796915611404382">"അനുവദിക്കരുത്"</string>
diff --git a/packages/CompanionDeviceManager/res/values-mn/strings.xml b/packages/CompanionDeviceManager/res/values-mn/strings.xml
index 01850e7..11e61d9 100644
--- a/packages/CompanionDeviceManager/res/values-mn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-mn/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;-н удирдах<xliff:g id="PROFILE_NAME">%1$s</xliff:g>-г сонгоно уу"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"төхөөрөмж"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"цаг"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"Та &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;-г удирдахын тулд &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;-г тохируулна уу"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;-г удирдахын тулд &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;-г зөвшөөрнө үү"</string>
     <string name="profile_summary" msgid="2059360676631420073">"Энэ апп таны <xliff:g id="PROFILE_NAME">%1$s</xliff:g>-г удирдахад шаардлагатай. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Зөвшөөрөх"</string>
     <string name="consent_no" msgid="2640796915611404382">"Бүү зөвшөөр"</string>
diff --git a/packages/CompanionDeviceManager/res/values-mr/strings.xml b/packages/CompanionDeviceManager/res/values-mr/strings.xml
index 7eea9bf..ca86d76 100644
--- a/packages/CompanionDeviceManager/res/values-mr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-mr/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; द्वारे व्यवस्थापित करण्यासाठी <xliff:g id="PROFILE_NAME">%1$s</xliff:g> निवडा"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"डिव्हाइस"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"पाहा"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"तुमचे &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; व्यवस्थापित करण्यासाठी &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; सेट करा"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"तुमचे &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; व्यवस्थापित करण्यासाठी &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ला अनुमती द्या"</string>
     <string name="profile_summary" msgid="2059360676631420073">"तुमची <xliff:g id="PROFILE_NAME">%1$s</xliff:g> प्रोफाइल व्यवस्थापित करण्यासाठी हे ॲप आवश्यक आहे. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"अनुमती द्या"</string>
     <string name="consent_no" msgid="2640796915611404382">"अनुमती देऊ नका"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ms/strings.xml b/packages/CompanionDeviceManager/res/values-ms/strings.xml
index e43a27f..d32f60f 100644
--- a/packages/CompanionDeviceManager/res/values-ms/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ms/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"Pilih <xliff:g id="PROFILE_NAME">%1$s</xliff:g> untuk diurus oleh &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"peranti"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"jam tangan"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"Tetapkan &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; untuk mengurus &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; anda"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"Benarkan &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; untuk mengurus &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; anda"</string>
     <string name="profile_summary" msgid="2059360676631420073">"Apl ini diperlukan untuk menguruskan <xliff:g id="PROFILE_NAME">%1$s</xliff:g> anda. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Benarkan"</string>
     <string name="consent_no" msgid="2640796915611404382">"Jangan benarkan"</string>
diff --git a/packages/CompanionDeviceManager/res/values-my/strings.xml b/packages/CompanionDeviceManager/res/values-my/strings.xml
index 1bd3a1d..45c9d8b 100644
--- a/packages/CompanionDeviceManager/res/values-my/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-my/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; က စီမံခန့်ခွဲရန် <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ကို ရွေးချယ်ပါ"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"စက်"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"နာရီ"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"သင်၏ &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ကို စီမံခန့်ခွဲရန် &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ကို သတ်မှတ်ပါ"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"သင်၏ &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ကို စီမံခန့်ခွဲရန် &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ကို ခွင့်ပြုပါ"</string>
     <string name="profile_summary" msgid="2059360676631420073">"သင်၏ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ကို စီမံခန့်ခွဲရန် ဤအက်ပ်ကိုလိုအပ်သည်။ <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"ခွင့်ပြုရန်"</string>
     <string name="consent_no" msgid="2640796915611404382">"ခွင့်မပြုပါ"</string>
diff --git a/packages/CompanionDeviceManager/res/values-nb/strings.xml b/packages/CompanionDeviceManager/res/values-nb/strings.xml
index e4d247b..af1ffe9 100644
--- a/packages/CompanionDeviceManager/res/values-nb/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-nb/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"Velg <xliff:g id="PROFILE_NAME">%1$s</xliff:g> som skal administreres av &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"enhet"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"klokke"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"Velg at &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; skal administrere &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"Tillat at &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; administrerer &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_summary" msgid="2059360676631420073">"Denne appen kreves for å administrere <xliff:g id="PROFILE_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Tillat"</string>
     <string name="consent_no" msgid="2640796915611404382">"Ikke tillat"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ne/strings.xml b/packages/CompanionDeviceManager/res/values-ne/strings.xml
index 45bfb5f..cb75ab5 100644
--- a/packages/CompanionDeviceManager/res/values-ne/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ne/strings.xml
@@ -20,12 +20,8 @@
     <string name="chooser_title" msgid="2262294130493605839">"आफूले &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; प्रयोग गरी व्यवस्थापन गर्न चाहेको <xliff:g id="PROFILE_NAME">%1$s</xliff:g> चयन गर्नुहोस्"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"यन्त्र"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"घडी"</string>
-    <!-- no translation found for confirmation_title (814973816731238955) -->
-    <skip />
-    <!-- no translation found for profile_summary (2059360676631420073) -->
-    <skip />
-    <!-- no translation found for consent_yes (8344487259618762872) -->
-    <skip />
-    <!-- no translation found for consent_no (2640796915611404382) -->
-    <skip />
+    <string name="confirmation_title" msgid="8455544820286920304">"आफ्नो &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; लाई &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; व्यवस्थापन गर्ने अनुमति दिनुहोस्"</string>
+    <string name="profile_summary" msgid="2059360676631420073">"तपाईंको <xliff:g id="PROFILE_NAME">%1$s</xliff:g> व्यवस्थापन गर्न यो एपलाई अनुमति दिनु पर्ने हुन्छ। <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
+    <string name="consent_yes" msgid="8344487259618762872">"अनुमति दिनुहोस्"</string>
+    <string name="consent_no" msgid="2640796915611404382">"अनुमति नदिनुहोस्"</string>
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-nl/strings.xml b/packages/CompanionDeviceManager/res/values-nl/strings.xml
index 9dc23e7..a56fb9a 100644
--- a/packages/CompanionDeviceManager/res/values-nl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-nl/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"Een <xliff:g id="PROFILE_NAME">%1$s</xliff:g> kiezen om te beheren met &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"apparaat"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"horloge"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; instellen om je &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; te beheren"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; toestaan je &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; te beheren"</string>
     <string name="profile_summary" msgid="2059360676631420073">"Deze app is vereist om je <xliff:g id="PROFILE_NAME">%1$s</xliff:g> te beheren. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Toestaan"</string>
     <string name="consent_no" msgid="2640796915611404382">"Niet toestaan"</string>
diff --git a/packages/CompanionDeviceManager/res/values-or/strings.xml b/packages/CompanionDeviceManager/res/values-or/strings.xml
index 4cfe057..8e43213 100644
--- a/packages/CompanionDeviceManager/res/values-or/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-or/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; ଦ୍ୱାରା ପରିଚାଳିତ ହେବା ପାଇଁ ଏକ <xliff:g id="PROFILE_NAME">%1$s</xliff:g>କୁ ବାଛନ୍ତୁ"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"ଡିଭାଇସ୍"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"ୱାଚ୍"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"ଆପଣଙ୍କ &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;କୁ ପରିଚାଳନା କରିବା ପାଇଁ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;କୁ ସେଟ୍ କରନ୍ତୁ"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"ଆପଣଙ୍କ &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;କୁ ପରିଚାଳନା କରିବା ପାଇଁ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;କୁ ଅନୁମତି ଦିଅନ୍ତୁ"</string>
     <string name="profile_summary" msgid="2059360676631420073">"ଆପଣଙ୍କ <xliff:g id="PROFILE_NAME">%1$s</xliff:g>କୁ ପରିଚାଳନା କରିବା ପାଇଁ ଏହି ଆପ୍ ଆବଶ୍ୟକ। <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"ଅନୁମତି ଦିଅନ୍ତୁ"</string>
     <string name="consent_no" msgid="2640796915611404382">"ଅନୁମତି ଦିଅନ୍ତୁ ନାହିଁ"</string>
diff --git a/packages/CompanionDeviceManager/res/values-pa/strings.xml b/packages/CompanionDeviceManager/res/values-pa/strings.xml
index 03693dc..54f4f8c 100644
--- a/packages/CompanionDeviceManager/res/values-pa/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pa/strings.xml
@@ -20,12 +20,8 @@
     <string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; ਵੱਲੋਂ ਪ੍ਰਬੰਧਿਤ ਕੀਤੇ ਜਾਣ ਲਈ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ਚੁਣੋ"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"ਡੀਵਾਈਸ"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"ਸਮਾਰਟ-ਵਾਚ"</string>
-    <!-- no translation found for confirmation_title (814973816731238955) -->
-    <skip />
-    <!-- no translation found for profile_summary (2059360676631420073) -->
-    <skip />
-    <!-- no translation found for consent_yes (8344487259618762872) -->
-    <skip />
-    <!-- no translation found for consent_no (2640796915611404382) -->
-    <skip />
+    <string name="confirmation_title" msgid="8455544820286920304">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ਨੂੰ ਤੁਹਾਡੇ &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ਦਾ ਪ੍ਰਬੰਧਨ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਦਿਓ"</string>
+    <string name="profile_summary" msgid="2059360676631420073">"ਤੁਹਾਡੇ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ਦਾ ਪ੍ਰਬੰਧਨ ਕਰਨ ਲਈ ਇਹ ਐਪ ਲੋੜੀਂਦੀ ਹੈ। <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
+    <string name="consent_yes" msgid="8344487259618762872">"ਇਜਾਜ਼ਤ ਦਿਓ"</string>
+    <string name="consent_no" msgid="2640796915611404382">"ਇਜਾਜ਼ਤ ਨਾ ਦਿਓ"</string>
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-pl/strings.xml b/packages/CompanionDeviceManager/res/values-pl/strings.xml
index 3dbd2f7..a989baa 100644
--- a/packages/CompanionDeviceManager/res/values-pl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pl/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"Wybierz profil <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, którym ma zarządzać aplikacja &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"urządzenie"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"zegarek"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"Skonfiguruj aplikację &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;, aby zarządzała urządzeniem &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"Zezwól na zarządzanie urządzeniem &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; przez aplikację &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_summary" msgid="2059360676631420073">"Ta aplikacja jest niezbędna do zarządzania profilem <xliff:g id="PROFILE_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Zezwól"</string>
     <string name="consent_no" msgid="2640796915611404382">"Nie zezwalaj"</string>
diff --git a/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml b/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml
index 91a9fa4..d2724c0 100644
--- a/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"Escolha um <xliff:g id="PROFILE_NAME">%1$s</xliff:g> para ser gerenciado pelo app &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"relógio"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"Configure o app &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; para gerenciar seu &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"Permitir que o app &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; gerencie seu &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_summary" msgid="2059360676631420073">"Esse app é necessário para gerenciar seu <xliff:g id="PROFILE_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
     <string name="consent_no" msgid="2640796915611404382">"Não permitir"</string>
diff --git a/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml b/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml
index 5ad9389..2f5a53b 100644
--- a/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"Escolha um <xliff:g id="PROFILE_NAME">%1$s</xliff:g> para ser gerido pela app &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"relógio"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"Defina a app &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; para gerir o seu &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"Permita que a app &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; faça a gestão do seu &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_summary" msgid="2059360676631420073">"Esta app é necessária para gerir o seu <xliff:g id="PROFILE_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
     <string name="consent_no" msgid="2640796915611404382">"Não permitir"</string>
diff --git a/packages/CompanionDeviceManager/res/values-pt/strings.xml b/packages/CompanionDeviceManager/res/values-pt/strings.xml
index 91a9fa4..d2724c0 100644
--- a/packages/CompanionDeviceManager/res/values-pt/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pt/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"Escolha um <xliff:g id="PROFILE_NAME">%1$s</xliff:g> para ser gerenciado pelo app &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"relógio"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"Configure o app &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; para gerenciar seu &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"Permitir que o app &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; gerencie seu &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_summary" msgid="2059360676631420073">"Esse app é necessário para gerenciar seu <xliff:g id="PROFILE_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
     <string name="consent_no" msgid="2640796915611404382">"Não permitir"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ro/strings.xml b/packages/CompanionDeviceManager/res/values-ro/strings.xml
index 15f5393..4df74de 100644
--- a/packages/CompanionDeviceManager/res/values-ro/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ro/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"Alegeți un profil <xliff:g id="PROFILE_NAME">%1$s</xliff:g> pe care să îl gestioneze &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"dispozitiv"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"ceas"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"Setați &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; pentru a vă gestiona dispozitivul &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"Permiteți ca &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; să vă gestioneze dispozitivul &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_summary" msgid="2059360676631420073">"Această aplicație este necesară pentru a gestiona <xliff:g id="PROFILE_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Permiteți"</string>
     <string name="consent_no" msgid="2640796915611404382">"Nu permiteți"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ru/strings.xml b/packages/CompanionDeviceManager/res/values-ru/strings.xml
index 2f79416..1d2ee7c 100644
--- a/packages/CompanionDeviceManager/res/values-ru/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ru/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"Выберите устройство (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>), которым будет управлять приложение &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"устройство"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"часы"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"Разрешите приложению &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; управлять устройством &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"Разрешите приложению &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; управлять устройством &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_summary" msgid="2059360676631420073">"Это приложение необходимо для управления вашим профилем (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>). <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Разрешить"</string>
     <string name="consent_no" msgid="2640796915611404382">"Запретить"</string>
diff --git a/packages/CompanionDeviceManager/res/values-si/strings.xml b/packages/CompanionDeviceManager/res/values-si/strings.xml
index d108a25..a5c2c88 100644
--- a/packages/CompanionDeviceManager/res/values-si/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-si/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; මගින් කළමනාකරණය කරනු ලැබීමට <xliff:g id="PROFILE_NAME">%1$s</xliff:g>ක් තෝරන්න"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"උපාංගය"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"ඔරලෝසුව"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ඔබගේ &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; කළමනාකරණය කිරීමට සකසන්න"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; හට ඔබගේ &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; කළමනාකරණය කිරීමට ඉඩ දෙන්න"</string>
     <string name="profile_summary" msgid="2059360676631420073">"මෙම යෙදුමට ඔබගේ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> කළමනාකරණය කිරීමට අවශ්‍යයි. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"ඉඩ දෙන්න"</string>
     <string name="consent_no" msgid="2640796915611404382">"ඉඩ නොදෙන්න"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sk/strings.xml b/packages/CompanionDeviceManager/res/values-sk/strings.xml
index d53728b..e144303 100644
--- a/packages/CompanionDeviceManager/res/values-sk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sk/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"Vyberte profil <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, ktorý bude spravovať aplikácia &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"zariadenie"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"hodinky"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"Nastavte aplikáciu &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;, aby spravovala zariadenie &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"Povoľte aplikácii &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; spravovať zariadenie &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_summary" msgid="2059360676631420073">"Táto aplikácia sa vyžaduje na správu profilu <xliff:g id="PROFILE_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Povoliť"</string>
     <string name="consent_no" msgid="2640796915611404382">"Nepovoliť"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sl/strings.xml b/packages/CompanionDeviceManager/res/values-sl/strings.xml
index 2849210..4eb8f50 100644
--- a/packages/CompanionDeviceManager/res/values-sl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sl/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"Izbira naprave <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, ki jo bo upravljala aplikacija &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"naprava"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"ura"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"Nastavitev aplikacije &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; za upravljanje naprave &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"Aplikaciji &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; dovolite upravljanje naprave &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_summary" msgid="2059360676631420073">"Ta aplikacija je potrebna za upravljanje profila »<xliff:g id="PROFILE_NAME">%1$s</xliff:g>«. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Dovoli"</string>
     <string name="consent_no" msgid="2640796915611404382">"Ne dovoli"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sq/strings.xml b/packages/CompanionDeviceManager/res/values-sq/strings.xml
index a57835a..34357b4 100644
--- a/packages/CompanionDeviceManager/res/values-sq/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sq/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"Zgjidh një profil <xliff:g id="PROFILE_NAME">%1$s</xliff:g> që do të menaxhohet nga &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"pajisja"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"ora inteligjente"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"Cakto &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; që të menaxhojë pajisjen tënde &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"Lejo që &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; të menaxhojë pajisjen tënde &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_summary" msgid="2059360676631420073">"Ky aplikacion nevojitet për të menaxhuar profilin tënd <xliff:g id="PROFILE_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Lejo"</string>
     <string name="consent_no" msgid="2640796915611404382">"Mos lejo"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sr/strings.xml b/packages/CompanionDeviceManager/res/values-sr/strings.xml
index 0b01cbc..37af185 100644
--- a/packages/CompanionDeviceManager/res/values-sr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sr/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"Одаберите профил <xliff:g id="PROFILE_NAME">%1$s</xliff:g> којим ће управљати апликација &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"уређај"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"сат"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"Подесите апликацију &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; тако да управља уређајем &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"Дозволите апликацији &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; да управља уређајем &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_summary" msgid="2059360676631420073">"Ова апликација је потребна за управљање профилом <xliff:g id="PROFILE_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Дозволи"</string>
     <string name="consent_no" msgid="2640796915611404382">"Не дозволи"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sv/strings.xml b/packages/CompanionDeviceManager/res/values-sv/strings.xml
index f6dcec9..f78fadf 100644
--- a/packages/CompanionDeviceManager/res/values-sv/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sv/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"Välj en <xliff:g id="PROFILE_NAME">%1$s</xliff:g> för hantering av &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"enhet"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"klocka"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"Konfigurera &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; för att hantera din &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"Tillåt att &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; hanterar din &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_summary" msgid="2059360676631420073">"Appen behövs för att hantera <xliff:g id="PROFILE_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Tillåt"</string>
     <string name="consent_no" msgid="2640796915611404382">"Tillåt inte"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sw/strings.xml b/packages/CompanionDeviceManager/res/values-sw/strings.xml
index 0999c5b..495c441 100644
--- a/packages/CompanionDeviceManager/res/values-sw/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sw/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"Chagua <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ili idhibitiwe na &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"kifaa"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"saa"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"Weka &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ili udhibiti &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; yako"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"Ruhusu &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; idhibiti &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; yako"</string>
     <string name="profile_summary" msgid="2059360676631420073">"Programu hii inahitajika ili udhibiti wasifu wako wa <xliff:g id="PROFILE_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Ruhusu"</string>
     <string name="consent_no" msgid="2640796915611404382">"Usiruhusu"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ta/strings.xml b/packages/CompanionDeviceManager/res/values-ta/strings.xml
index 884d57f..20845bd 100644
--- a/packages/CompanionDeviceManager/res/values-ta/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ta/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; ஆப்ஸ் நிர்வகிக்கக்கூடிய <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ஐத் தேர்ந்தெடுங்கள்"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"சாதனம்"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"வாட்ச்"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"உங்கள் &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; சாதனத்தை நிர்வகிக்க &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ஆப்ஸை அமையுங்கள்"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"உங்கள் &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ஐ நிர்வகிக்க &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ஆப்ஸை அனுமதியுங்கள்"</string>
     <string name="profile_summary" msgid="2059360676631420073">"உங்கள் <xliff:g id="PROFILE_NAME">%1$s</xliff:g> சுயவிவரத்தை நிர்வகிக்க இந்த ஆப்ஸ் தேவைப்படுகிறது. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"அனுமதி"</string>
     <string name="consent_no" msgid="2640796915611404382">"அனுமதிக்க வேண்டாம்"</string>
diff --git a/packages/CompanionDeviceManager/res/values-te/strings.xml b/packages/CompanionDeviceManager/res/values-te/strings.xml
index 9c3e334..c855cf2 100644
--- a/packages/CompanionDeviceManager/res/values-te/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-te/strings.xml
@@ -20,12 +20,8 @@
     <string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; ద్వారా మేనేజ్ చేయబడటానికి ఒక <xliff:g id="PROFILE_NAME">%1$s</xliff:g>ను ఎంచుకోండి"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"పరికరం"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"వాచ్"</string>
-    <!-- no translation found for confirmation_title (814973816731238955) -->
-    <skip />
-    <!-- no translation found for profile_summary (2059360676631420073) -->
-    <skip />
-    <!-- no translation found for consent_yes (8344487259618762872) -->
-    <skip />
-    <!-- no translation found for consent_no (2640796915611404382) -->
-    <skip />
+    <string name="confirmation_title" msgid="8455544820286920304">"మీ &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;ను మేనేజ్ చేయడానికి &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;ను అనుమతించండి;"</string>
+    <string name="profile_summary" msgid="2059360676631420073">"మీ <xliff:g id="PROFILE_NAME">%1$s</xliff:g>ను మేనేజ్ చేయడానికి ఈ యాప్ అవసరం. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
+    <string name="consent_yes" msgid="8344487259618762872">"అనుమతించు"</string>
+    <string name="consent_no" msgid="2640796915611404382">"అనుమతించవద్దు"</string>
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-th/strings.xml b/packages/CompanionDeviceManager/res/values-th/strings.xml
index 58ebda6..d78ada2 100644
--- a/packages/CompanionDeviceManager/res/values-th/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-th/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"เลือก<xliff:g id="PROFILE_NAME">%1$s</xliff:g>ที่จะให้มีการจัดการโดย &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"อุปกรณ์"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"นาฬิกา"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"ตั้งค่าให้ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; จัดการ &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ของคุณ"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"อนุญาตให้ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; จัดการ &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ของคุณ"</string>
     <string name="profile_summary" msgid="2059360676631420073">"ต้องใช้แอปนี้ในการจัดการ<xliff:g id="PROFILE_NAME">%1$s</xliff:g>ของคุณ <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"อนุญาต"</string>
     <string name="consent_no" msgid="2640796915611404382">"ไม่อนุญาต"</string>
diff --git a/packages/CompanionDeviceManager/res/values-tl/strings.xml b/packages/CompanionDeviceManager/res/values-tl/strings.xml
index 1a83284..03165b4 100644
--- a/packages/CompanionDeviceManager/res/values-tl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-tl/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"Pumili ng <xliff:g id="PROFILE_NAME">%1$s</xliff:g> para pamahalaan ng &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"device"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"relo"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"Itakda ang &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; para pamahalaan ang iyong &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"Payagan ang &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; na pamahalaan ang iyong &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_summary" msgid="2059360676631420073">"Kinakailangan ang app na ito para pamahalaan ang iyong <xliff:g id="PROFILE_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Payagan"</string>
     <string name="consent_no" msgid="2640796915611404382">"Huwag payagan"</string>
diff --git a/packages/CompanionDeviceManager/res/values-tr/strings.xml b/packages/CompanionDeviceManager/res/values-tr/strings.xml
index b89e874..93e81e6 100644
--- a/packages/CompanionDeviceManager/res/values-tr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-tr/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; tarafından yönetilecek bir <xliff:g id="PROFILE_NAME">%1$s</xliff:g> seçin"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"cihaz"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"saat"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; cihazınızı yönetmek için &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; uygulamasını ayarlayın"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; cihazınızı yönetmek için &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; uygulamasına izin verin"</string>
     <string name="profile_summary" msgid="2059360676631420073">"Bu uygulama, <xliff:g id="PROFILE_NAME">%1$s</xliff:g> profilinizin yönetilmesi için gereklidir. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"İzin ver"</string>
     <string name="consent_no" msgid="2640796915611404382">"İzin verme"</string>
diff --git a/packages/CompanionDeviceManager/res/values-uk/strings.xml b/packages/CompanionDeviceManager/res/values-uk/strings.xml
index 2ae852c..61b78e9 100644
--- a/packages/CompanionDeviceManager/res/values-uk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-uk/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"Виберіть <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, яким керуватиме додаток &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"пристрій"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"годинник"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"Налаштуйте додаток &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;, щоб керувати пристроєм &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"Дозволити додатку &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; керувати вашим пристроєм &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_summary" msgid="2059360676631420073">"Цей додаток потрібен, щоб керувати профілем \"<xliff:g id="PROFILE_NAME">%1$s</xliff:g>\". <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Дозволити"</string>
     <string name="consent_no" msgid="2640796915611404382">"Не дозволяти"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ur/strings.xml b/packages/CompanionDeviceManager/res/values-ur/strings.xml
index 83e20d8..88c8a4b 100644
--- a/packages/CompanionDeviceManager/res/values-ur/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ur/strings.xml
@@ -20,12 +20,8 @@
     <string name="chooser_title" msgid="2262294130493605839">"‏&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; کے ذریعے نظم کئے جانے کیلئے <xliff:g id="PROFILE_NAME">%1$s</xliff:g> کو منتخب کریں"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"آلہ"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"دیکھیں"</string>
-    <!-- no translation found for confirmation_title (814973816731238955) -->
-    <skip />
-    <!-- no translation found for profile_summary (2059360676631420073) -->
-    <skip />
-    <!-- no translation found for consent_yes (8344487259618762872) -->
-    <skip />
-    <!-- no translation found for consent_no (2640796915611404382) -->
-    <skip />
+    <string name="confirmation_title" msgid="8455544820286920304">"‏اپنے ‎&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; کا نظم کرنے کے لیے ‎&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; کو اجازت دیں"</string>
+    <string name="profile_summary" msgid="2059360676631420073">"اس ایپ کو آپ کے <xliff:g id="PROFILE_NAME">%1$s</xliff:g> کا نظم کرنے کی ضرورت ہے۔ <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
+    <string name="consent_yes" msgid="8344487259618762872">"اجازت دیں"</string>
+    <string name="consent_no" msgid="2640796915611404382">"اجازت نہ دیں"</string>
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-uz/strings.xml b/packages/CompanionDeviceManager/res/values-uz/strings.xml
index 5681118..7221b6d 100644
--- a/packages/CompanionDeviceManager/res/values-uz/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-uz/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; boshqaradigan <xliff:g id="PROFILE_NAME">%1$s</xliff:g> qurilmasini tanlang"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"qurilma"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"soat"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; qurilmasini boshqarish uchun &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ilovasini sozlang"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; qurilmasini boshqarish uchun &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ilovasiga ruxsat bering"</string>
     <string name="profile_summary" msgid="2059360676631420073">"Bu ilova <xliff:g id="PROFILE_NAME">%1$s</xliff:g> profilini boshqarish uchun kerak. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Ruxsat"</string>
     <string name="consent_no" msgid="2640796915611404382">"Ruxsat berilmasin"</string>
diff --git a/packages/CompanionDeviceManager/res/values-vi/strings.xml b/packages/CompanionDeviceManager/res/values-vi/strings.xml
index 3bbdb57..2819e1d 100644
--- a/packages/CompanionDeviceManager/res/values-vi/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-vi/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"Chọn một <xliff:g id="PROFILE_NAME">%1$s</xliff:g> sẽ do &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; quản lý"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"thiết bị"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"đồng hồ"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"Đặt &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; để quản lý &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; của bạn"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"Cho phép &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; quản lý &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; của bạn"</string>
     <string name="profile_summary" msgid="2059360676631420073">"Cần có ứng dụng này để quản lý <xliff:g id="PROFILE_NAME">%1$s</xliff:g> của bạn. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Cho phép"</string>
     <string name="consent_no" msgid="2640796915611404382">"Không cho phép"</string>
diff --git a/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml
index 788f8f9..1440c40 100644
--- a/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml
@@ -20,12 +20,8 @@
     <string name="chooser_title" msgid="2262294130493605839">"选择要由&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;管理的<xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"设备"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"手表"</string>
-    <!-- no translation found for confirmation_title (814973816731238955) -->
-    <skip />
-    <!-- no translation found for profile_summary (2059360676631420073) -->
-    <skip />
-    <!-- no translation found for consent_yes (8344487259618762872) -->
-    <skip />
-    <!-- no translation found for consent_no (2640796915611404382) -->
-    <skip />
+    <string name="confirmation_title" msgid="8455544820286920304">"允许&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;管理您的&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="profile_summary" msgid="2059360676631420073">"需要使用此应用,才能管理您的<xliff:g id="PROFILE_NAME">%1$s</xliff:g>。<xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
+    <string name="consent_yes" msgid="8344487259618762872">"允许"</string>
+    <string name="consent_no" msgid="2640796915611404382">"不允许"</string>
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml
index be29925b..2e81a17 100644
--- a/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml
@@ -16,11 +16,11 @@
 
 <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="4470785958457506021">"隨附裝置管理員"</string>
+    <string name="app_label" msgid="4470785958457506021">"隨附裝置管理工具"</string>
     <string name="chooser_title" msgid="2262294130493605839">"選擇由 &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; 管理的<xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"裝置"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"手錶"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"設定 &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; 來管理您的 <xliff:g id="DEVICE_NAME">%2$s</xliff:g> - &lt;strong&gt;&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"允許 &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; 管理您的 &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_summary" msgid="2059360676631420073">"必須使用此應用程式,才能管理<xliff:g id="PROFILE_NAME">%1$s</xliff:g>。<xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"允許"</string>
     <string name="consent_no" msgid="2640796915611404382">"不允許"</string>
diff --git a/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
index 8044869..150022a 100644
--- a/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"選擇要讓「<xliff:g id="APP_NAME">%2$s</xliff:g>」&lt;strong&gt;&lt;/strong&gt;管理的<xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"裝置"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"手錶"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」&lt;strong&gt;&lt;/strong&gt;管理你的「<xliff:g id="DEVICE_NAME">%2$s</xliff:g>」&lt;strong&gt;&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」&lt;strong&gt;&lt;/strong&gt;管理你的「<xliff:g id="DEVICE_NAME">%2$s</xliff:g>」&lt;strong&gt;&lt;/strong&gt;"</string>
     <string name="profile_summary" msgid="2059360676631420073">"你必須使用這個應用程式,才能管理<xliff:g id="PROFILE_NAME">%1$s</xliff:g>。<xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"允許"</string>
     <string name="consent_no" msgid="2640796915611404382">"不允許"</string>
diff --git a/packages/CompanionDeviceManager/res/values-zu/strings.xml b/packages/CompanionDeviceManager/res/values-zu/strings.xml
index 3ed177c..dc933ae 100644
--- a/packages/CompanionDeviceManager/res/values-zu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zu/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"Khetha i-<xliff:g id="PROFILE_NAME">%1$s</xliff:g> ezophathwa yi-&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"idivayisi"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"buka"</string>
-    <string name="confirmation_title" msgid="814973816731238955">"Setha i-&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ukuze iphathe i-<xliff:g id="DEVICE_NAME">%2$s</xliff:g> yakho - &lt;strong&gt;&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"Vumela i-&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ukuthi iphathe i-&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; yakho"</string>
     <string name="profile_summary" msgid="2059360676631420073">"I-app iyadingeka ukuphatha i-<xliff:g id="PROFILE_NAME">%1$s</xliff:g> yakho. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Vumela"</string>
     <string name="consent_no" msgid="2640796915611404382">"Ungavumeli"</string>
diff --git a/packages/Connectivity/TEST_MAPPING b/packages/Connectivity/TEST_MAPPING
new file mode 100644
index 0000000..94f9232
--- /dev/null
+++ b/packages/Connectivity/TEST_MAPPING
@@ -0,0 +1,19 @@
+{
+  "imports": [
+    {
+      "path": "frameworks/base/core/java/android/net"
+    },
+    {
+      "path": "packages/modules/NetworkStack"
+    },
+    {
+      "path": "packages/modules/CaptivePortalLogin"
+    },
+    {
+      "path": "packages/modules/Connectivity"
+    },
+    {
+      "path": "packages/modules/Connectivity/Tethering"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/packages/Connectivity/framework/Android.bp b/packages/Connectivity/framework/Android.bp
index 657d5a3..74cecdd 100644
--- a/packages/Connectivity/framework/Android.bp
+++ b/packages/Connectivity/framework/Android.bp
@@ -26,6 +26,7 @@
 java_library {
     name: "framework-connectivity-protos",
     sdk_version: "module_current",
+    min_sdk_version: "30",
     proto: {
         type: "nano",
     },
@@ -34,7 +35,6 @@
         ":framework-javastream-protos",
     ],
     apex_available: [
-        "//apex_available:platform",
         "com.android.tethering",
     ],
     jarjar_rules: "jarjar-rules-proto.txt",
@@ -81,11 +81,13 @@
 
 java_sdk_library {
     name: "framework-connectivity",
-    api_only: true,
+    sdk_version: "module_current",
+    min_sdk_version: "30",
     defaults: ["framework-module-defaults"],
     installable: true,
     srcs: [
         ":framework-connectivity-sources",
+        ":net-utils-framework-common-srcs",
     ],
     aidl: {
         include_dirs: [
@@ -97,10 +99,33 @@
             "frameworks/native/aidl/binder", // For PersistableBundle.aidl
         ],
     },
+    impl_only_libs: [
+        // TODO (b/183097033) remove once module_current includes core_platform
+        "stable.core.platform.api.stubs",
+        "framework-tethering.stubs.module_lib",
+        "framework-wifi.stubs.module_lib",
+        "net-utils-device-common",
+    ],
     libs: [
         "unsupportedappusage",
     ],
+    static_libs: [
+        "framework-connectivity-protos",
+    ],
+    jarjar_rules: "jarjar-rules.txt",
     permitted_packages: ["android.net"],
+    impl_library_visibility: [
+        "//packages/modules/Connectivity/Tethering/apex",
+        // In preparation for future move
+        "//packages/modules/Connectivity/apex",
+        "//packages/modules/Connectivity/service",
+        "//frameworks/base/packages/Connectivity/service",
+        "//frameworks/base",
+        "//packages/modules/Connectivity/Tethering/tests/unit",
+    ],
+    apex_available: [
+        "com.android.tethering",
+    ],
 }
 
 cc_defaults {
@@ -109,13 +134,15 @@
         "-Wall",
         "-Werror",
         "-Wno-unused-parameter",
+        // Don't warn about S API usage even with
+        // min_sdk 30: the library is only loaded
+        // on S+ devices
+        "-Wno-unguarded-availability",
         "-Wthread-safety",
     ],
     shared_libs: [
-        "libbase",
         "liblog",
         "libnativehelper",
-        "libnetd_client",
     ],
     header_libs: [
         "dnsproxyd_protocol_headers",
@@ -128,6 +155,7 @@
     srcs: [
         "jni/android_net_NetworkUtils.cpp",
     ],
+    shared_libs: ["libandroid_net"],
     apex_available: [
         "//apex_available:platform",
         "com.android.tethering",
@@ -136,42 +164,15 @@
 
 cc_library_shared {
     name: "libframework-connectivity-jni",
+    min_sdk_version: "30",
     defaults: ["libframework-connectivity-defaults"],
     srcs: [
+        "jni/android_net_NetworkUtils.cpp",
         "jni/onload.cpp",
     ],
-    static_libs: ["libconnectivityframeworkutils"],
+    shared_libs: ["libandroid"],
+    stl: "libc++_static",
     apex_available: [
-        "//apex_available:platform",
         "com.android.tethering",
     ],
 }
-
-java_library {
-    name: "framework-connectivity.impl",
-    sdk_version: "module_current",
-    srcs: [
-        ":framework-connectivity-sources",
-    ],
-    aidl: {
-        include_dirs: [
-            "frameworks/base/core/java", // For framework parcelables
-            "frameworks/native/aidl/binder", // For PersistableBundle.aidl
-        ],
-    },
-    libs: [
-        // TODO (b/183097033) remove once module_current includes core_current
-        "stable.core.platform.api.stubs",
-        "framework-tethering",
-        "framework-wifi",
-        "unsupportedappusage",
-    ],
-    static_libs: [
-        "framework-connectivity-protos",
-        "net-utils-device-common",
-    ],
-    jarjar_rules: "jarjar-rules.txt",
-    apex_available: ["com.android.tethering"],
-    installable: true,
-    permitted_packages: ["android.net"],
-}
diff --git a/packages/Connectivity/framework/api/current.txt b/packages/Connectivity/framework/api/current.txt
index e415e01..7428c6e 100644
--- a/packages/Connectivity/framework/api/current.txt
+++ b/packages/Connectivity/framework/api/current.txt
@@ -68,6 +68,7 @@
     method public boolean bindProcessToNetwork(@Nullable android.net.Network);
     method @NonNull public android.net.SocketKeepalive createSocketKeepalive(@NonNull android.net.Network, @NonNull android.net.IpSecManager.UdpEncapsulationSocket, @NonNull java.net.InetAddress, @NonNull java.net.InetAddress, @NonNull java.util.concurrent.Executor, @NonNull android.net.SocketKeepalive.Callback);
     method @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.Network getActiveNetwork();
+    method @Nullable @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public android.net.Network getActiveNetworkForUid(int);
     method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.NetworkInfo getActiveNetworkInfo();
     method @Deprecated @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.NetworkInfo[] getAllNetworkInfo();
     method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.Network[] getAllNetworks();
@@ -310,6 +311,7 @@
     field public static final int NET_CAPABILITY_ENTERPRISE = 29; // 0x1d
     field public static final int NET_CAPABILITY_FOREGROUND = 19; // 0x13
     field public static final int NET_CAPABILITY_FOTA = 3; // 0x3
+    field public static final int NET_CAPABILITY_HEAD_UNIT = 32; // 0x20
     field public static final int NET_CAPABILITY_IA = 7; // 0x7
     field public static final int NET_CAPABILITY_IMS = 4; // 0x4
     field public static final int NET_CAPABILITY_INTERNET = 12; // 0xc
@@ -333,6 +335,7 @@
     field public static final int TRANSPORT_CELLULAR = 0; // 0x0
     field public static final int TRANSPORT_ETHERNET = 3; // 0x3
     field public static final int TRANSPORT_LOWPAN = 6; // 0x6
+    field public static final int TRANSPORT_USB = 8; // 0x8
     field public static final int TRANSPORT_VPN = 4; // 0x4
     field public static final int TRANSPORT_WIFI = 1; // 0x1
     field public static final int TRANSPORT_WIFI_AWARE = 5; // 0x5
@@ -387,7 +390,9 @@
   public class NetworkRequest implements android.os.Parcelable {
     method public boolean canBeSatisfiedBy(@Nullable android.net.NetworkCapabilities);
     method public int describeContents();
+    method @NonNull public int[] getCapabilities();
     method @Nullable public android.net.NetworkSpecifier getNetworkSpecifier();
+    method @NonNull public int[] getTransportTypes();
     method public boolean hasCapability(int);
     method public boolean hasTransport(int);
     method public void writeToParcel(android.os.Parcel, int);
@@ -396,6 +401,7 @@
 
   public static class NetworkRequest.Builder {
     ctor public NetworkRequest.Builder();
+    ctor public NetworkRequest.Builder(@NonNull android.net.NetworkRequest);
     method public android.net.NetworkRequest.Builder addCapability(int);
     method public android.net.NetworkRequest.Builder addTransportType(int);
     method public android.net.NetworkRequest build();
diff --git a/packages/Connectivity/framework/api/module-lib-current.txt b/packages/Connectivity/framework/api/module-lib-current.txt
index 5bd01a6..2065559 100644
--- a/packages/Connectivity/framework/api/module-lib-current.txt
+++ b/packages/Connectivity/framework/api/module-lib-current.txt
@@ -11,19 +11,34 @@
     method @Nullable public android.net.ProxyInfo getGlobalProxy();
     method @NonNull public static android.util.Range<java.lang.Integer> getIpSecNetIdRange();
     method @NonNull public static String getPrivateDnsMode(@NonNull android.content.Context);
+    method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void registerDefaultNetworkCallbackAsUid(int, @NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler);
     method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void registerSystemDefaultNetworkCallback(@NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler);
     method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void requestBackgroundNetwork(@NonNull android.net.NetworkRequest, @NonNull android.os.Handler, @NonNull android.net.ConnectivityManager.NetworkCallback);
+    method @Deprecated public boolean requestRouteToHostAddress(int, java.net.InetAddress);
     method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void setAcceptPartialConnectivity(@NonNull android.net.Network, boolean, boolean);
     method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void setAcceptUnvalidated(@NonNull android.net.Network, boolean, boolean);
     method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void setAvoidUnvalidated(@NonNull android.net.Network);
     method @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public void setGlobalProxy(@Nullable android.net.ProxyInfo);
+    method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void setLegacyLockdownVpnEnabled(boolean);
+    method public static void setPrivateDnsMode(@NonNull android.content.Context, @NonNull String);
     method @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public void setProfileNetworkPreference(@NonNull android.os.UserHandle, int, @Nullable java.util.concurrent.Executor, @Nullable Runnable);
+    method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void setRequireVpnForUids(boolean, @NonNull java.util.Collection<android.util.Range<java.lang.Integer>>);
     method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_TEST_NETWORKS, android.Manifest.permission.NETWORK_STACK}) public void simulateDataStall(int, long, @NonNull android.net.Network, @NonNull android.os.PersistableBundle);
     method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void startCaptivePortalApp(@NonNull android.net.Network);
     method public void systemReady();
     field public static final String ACTION_PROMPT_LOST_VALIDATION = "android.net.action.PROMPT_LOST_VALIDATION";
     field public static final String ACTION_PROMPT_PARTIAL_CONNECTIVITY = "android.net.action.PROMPT_PARTIAL_CONNECTIVITY";
     field public static final String ACTION_PROMPT_UNVALIDATED = "android.net.action.PROMPT_UNVALIDATED";
+    field public static final int BLOCKED_METERED_REASON_ADMIN_DISABLED = 262144; // 0x40000
+    field public static final int BLOCKED_METERED_REASON_DATA_SAVER = 65536; // 0x10000
+    field public static final int BLOCKED_METERED_REASON_MASK = -65536; // 0xffff0000
+    field public static final int BLOCKED_METERED_REASON_USER_RESTRICTED = 131072; // 0x20000
+    field public static final int BLOCKED_REASON_APP_STANDBY = 4; // 0x4
+    field public static final int BLOCKED_REASON_BATTERY_SAVER = 1; // 0x1
+    field public static final int BLOCKED_REASON_DOZE = 2; // 0x2
+    field public static final int BLOCKED_REASON_LOCKDOWN_VPN = 16; // 0x10
+    field public static final int BLOCKED_REASON_NONE = 0; // 0x0
+    field public static final int BLOCKED_REASON_RESTRICTED_MODE = 8; // 0x8
     field public static final String PRIVATE_DNS_MODE_OFF = "off";
     field public static final String PRIVATE_DNS_MODE_OPPORTUNISTIC = "opportunistic";
     field public static final String PRIVATE_DNS_MODE_PROVIDER_HOSTNAME = "hostname";
@@ -31,16 +46,75 @@
     field public static final int PROFILE_NETWORK_PREFERENCE_ENTERPRISE = 1; // 0x1
   }
 
+  public static class ConnectivityManager.NetworkCallback {
+    method public void onBlockedStatusChanged(@NonNull android.net.Network, int);
+  }
+
+  public class ConnectivitySettingsManager {
+    method public static void clearGlobalProxy(@NonNull android.content.Context);
+    method @Nullable public static String getCaptivePortalHttpUrl(@NonNull android.content.Context);
+    method public static int getCaptivePortalMode(@NonNull android.content.Context, int);
+    method @NonNull public static java.time.Duration getConnectivityKeepPendingIntentDuration(@NonNull android.content.Context, @NonNull java.time.Duration);
+    method @NonNull public static android.util.Range<java.lang.Integer> getDnsResolverSampleRanges(@NonNull android.content.Context);
+    method @NonNull public static java.time.Duration getDnsResolverSampleValidityDuration(@NonNull android.content.Context, @NonNull java.time.Duration);
+    method public static int getDnsResolverSuccessThresholdPercent(@NonNull android.content.Context, int);
+    method @Nullable public static android.net.ProxyInfo getGlobalProxy(@NonNull android.content.Context);
+    method @NonNull public static java.time.Duration getMobileDataActivityTimeout(@NonNull android.content.Context, @NonNull java.time.Duration);
+    method public static boolean getMobileDataAlwaysOn(@NonNull android.content.Context, boolean);
+    method @Nullable public static String getMobileDataPreferredApps(@NonNull android.content.Context);
+    method public static int getNetworkAvoidBadWifi(@NonNull android.content.Context);
+    method @Nullable public static String getNetworkMeteredMultipathPreference(@NonNull android.content.Context);
+    method public static int getNetworkSwitchNotificationMaximumDailyCount(@NonNull android.content.Context, int);
+    method @NonNull public static java.time.Duration getNetworkSwitchNotificationRateDuration(@NonNull android.content.Context, @NonNull java.time.Duration);
+    method @NonNull public static String getPrivateDnsDefaultMode(@NonNull android.content.Context);
+    method @Nullable public static String getPrivateDnsHostname(@NonNull android.content.Context);
+    method public static boolean getWifiAlwaysRequested(@NonNull android.content.Context, boolean);
+    method @NonNull public static java.time.Duration getWifiDataActivityTimeout(@NonNull android.content.Context, @NonNull java.time.Duration);
+    method public static void setCaptivePortalHttpUrl(@NonNull android.content.Context, @Nullable String);
+    method public static void setCaptivePortalMode(@NonNull android.content.Context, int);
+    method public static void setConnectivityKeepPendingIntentDuration(@NonNull android.content.Context, @NonNull java.time.Duration);
+    method public static void setDnsResolverSampleRanges(@NonNull android.content.Context, @NonNull android.util.Range<java.lang.Integer>);
+    method public static void setDnsResolverSampleValidityDuration(@NonNull android.content.Context, @NonNull java.time.Duration);
+    method public static void setDnsResolverSuccessThresholdPercent(@NonNull android.content.Context, @IntRange(from=0, to=100) int);
+    method public static void setGlobalProxy(@NonNull android.content.Context, @NonNull android.net.ProxyInfo);
+    method public static void setMobileDataActivityTimeout(@NonNull android.content.Context, @NonNull java.time.Duration);
+    method public static void setMobileDataAlwaysOn(@NonNull android.content.Context, boolean);
+    method public static void setMobileDataPreferredApps(@NonNull android.content.Context, @Nullable String);
+    method public static void setNetworkAvoidBadWifi(@NonNull android.content.Context, int);
+    method public static void setNetworkMeteredMultipathPreference(@NonNull android.content.Context, @NonNull String);
+    method public static void setNetworkSwitchNotificationMaximumDailyCount(@NonNull android.content.Context, @IntRange(from=0) int);
+    method public static void setNetworkSwitchNotificationRateDuration(@NonNull android.content.Context, @NonNull java.time.Duration);
+    method public static void setPrivateDnsDefaultMode(@NonNull android.content.Context, @NonNull String);
+    method public static void setPrivateDnsHostname(@NonNull android.content.Context, @Nullable String);
+    method public static void setWifiAlwaysRequested(@NonNull android.content.Context, boolean);
+    method public static void setWifiDataActivityTimeout(@NonNull android.content.Context, @NonNull java.time.Duration);
+    field public static final int CAPTIVE_PORTAL_MODE_AVOID = 2; // 0x2
+    field public static final int CAPTIVE_PORTAL_MODE_IGNORE = 0; // 0x0
+    field public static final int CAPTIVE_PORTAL_MODE_PROMPT = 1; // 0x1
+    field public static final int NETWORK_AVOID_BAD_WIFI_AVOID = 2; // 0x2
+    field public static final int NETWORK_AVOID_BAD_WIFI_IGNORE = 0; // 0x0
+    field public static final int NETWORK_AVOID_BAD_WIFI_PROMPT = 1; // 0x1
+  }
+
   public final class NetworkAgentConfig implements android.os.Parcelable {
     method @Nullable public String getSubscriberId();
+    method public boolean isBypassableVpn();
   }
 
   public static final class NetworkAgentConfig.Builder {
+    method @NonNull public android.net.NetworkAgentConfig.Builder setBypassableVpn(boolean);
     method @NonNull public android.net.NetworkAgentConfig.Builder setSubscriberId(@Nullable String);
   }
 
   public final class NetworkCapabilities implements android.os.Parcelable {
+    ctor public NetworkCapabilities(@Nullable android.net.NetworkCapabilities, long);
     method @Nullable public java.util.Set<android.util.Range<java.lang.Integer>> getUids();
+    method public boolean hasUnwantedCapability(int);
+    field public static final long REDACT_ALL = -1L; // 0xffffffffffffffffL
+    field public static final long REDACT_FOR_ACCESS_FINE_LOCATION = 1L; // 0x1L
+    field public static final long REDACT_FOR_LOCAL_MAC_ADDRESS = 2L; // 0x2L
+    field public static final long REDACT_FOR_NETWORK_SETTINGS = 4L; // 0x4L
+    field public static final long REDACT_NONE = 0L; // 0x0L
     field public static final int TRANSPORT_TEST = 7; // 0x7
   }
 
@@ -48,7 +122,14 @@
     method @NonNull public android.net.NetworkCapabilities.Builder setUids(@Nullable java.util.Set<android.util.Range<java.lang.Integer>>);
   }
 
+  public class NetworkRequest implements android.os.Parcelable {
+    method @NonNull public int[] getUnwantedCapabilities();
+    method public boolean hasUnwantedCapability(int);
+  }
+
   public static class NetworkRequest.Builder {
+    method @NonNull public android.net.NetworkRequest.Builder addUnwantedCapability(int);
+    method @NonNull public android.net.NetworkRequest.Builder removeUnwantedCapability(int);
     method @NonNull public android.net.NetworkRequest.Builder setUids(@Nullable java.util.Set<android.util.Range<java.lang.Integer>>);
   }
 
@@ -92,11 +173,18 @@
     field @NonNull public static final android.os.Parcelable.Creator<android.net.TestNetworkSpecifier> CREATOR;
   }
 
+  public interface TransportInfo {
+    method public default long getApplicableRedactions();
+    method @NonNull public default android.net.TransportInfo makeCopy(long);
+  }
+
   public final class VpnTransportInfo implements android.os.Parcelable android.net.TransportInfo {
-    ctor public VpnTransportInfo(int);
+    ctor public VpnTransportInfo(int, @Nullable String);
     method public int describeContents();
+    method @NonNull public android.net.VpnTransportInfo makeCopy(long);
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.net.VpnTransportInfo> CREATOR;
+    field @Nullable public final String sessionId;
     field public final int type;
   }
 
diff --git a/packages/Connectivity/framework/api/system-current.txt b/packages/Connectivity/framework/api/system-current.txt
index 8845225..6c3b620 100644
--- a/packages/Connectivity/framework/api/system-current.txt
+++ b/packages/Connectivity/framework/api/system-current.txt
@@ -52,7 +52,7 @@
     method @Deprecated @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void getLatestTetheringEntitlementResult(int, boolean, @NonNull java.util.concurrent.Executor, @NonNull android.net.ConnectivityManager.OnTetheringEntitlementResultListener);
     method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public boolean isTetheringSupported();
     method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_FACTORY}) public int registerNetworkProvider(@NonNull android.net.NetworkProvider);
-    method public void registerQosCallback(@NonNull android.net.QosSocketInfo, @NonNull android.net.QosCallback, @NonNull java.util.concurrent.Executor);
+    method public void registerQosCallback(@NonNull android.net.QosSocketInfo, @NonNull java.util.concurrent.Executor, @NonNull android.net.QosCallback);
     method @Deprecated @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void registerTetheringEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.ConnectivityManager.OnTetheringEventCallback);
     method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public void requestNetwork(@NonNull android.net.NetworkRequest, int, int, @NonNull android.os.Handler, @NonNull android.net.ConnectivityManager.NetworkCallback);
     method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_AIRPLANE_MODE, android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void setAirplaneMode(boolean);
@@ -212,10 +212,14 @@
 
   public abstract class NetworkAgent {
     ctor public NetworkAgent(@NonNull android.content.Context, @NonNull android.os.Looper, @NonNull String, @NonNull android.net.NetworkCapabilities, @NonNull android.net.LinkProperties, int, @NonNull android.net.NetworkAgentConfig, @Nullable android.net.NetworkProvider);
+    ctor public NetworkAgent(@NonNull android.content.Context, @NonNull android.os.Looper, @NonNull String, @NonNull android.net.NetworkCapabilities, @NonNull android.net.LinkProperties, @NonNull android.net.NetworkScore, @NonNull android.net.NetworkAgentConfig, @Nullable android.net.NetworkProvider);
     method @Nullable public android.net.Network getNetwork();
     method public void markConnected();
     method public void onAddKeepalivePacketFilter(int, @NonNull android.net.KeepalivePacketData);
     method public void onAutomaticReconnectDisabled();
+    method public void onBandwidthUpdateRequested();
+    method public void onNetworkCreated();
+    method public void onNetworkDestroyed();
     method public void onNetworkUnwanted();
     method public void onQosCallbackRegistered(int, @NonNull android.net.QosFilter);
     method public void onQosCallbackUnregistered(int);
@@ -230,9 +234,11 @@
     method public final void sendNetworkCapabilities(@NonNull android.net.NetworkCapabilities);
     method public final void sendNetworkScore(@IntRange(from=0, to=99) int);
     method public final void sendQosCallbackError(int, int);
-    method public final void sendQosSessionAvailable(int, int, @NonNull android.telephony.data.EpsBearerQosSessionAttributes);
-    method public final void sendQosSessionLost(int, int);
+    method public final void sendQosSessionAvailable(int, int, @NonNull android.net.QosSessionAttributes);
+    method public final void sendQosSessionLost(int, int, int);
     method public final void sendSocketKeepaliveEvent(int, int);
+    method @Deprecated public void setLegacySubtype(int, @NonNull String);
+    method public void setTeardownDelayMs(@IntRange(from=0, to=0x1388) int);
     method public final void setUnderlyingNetworks(@Nullable java.util.List<android.net.Network>);
     method public void unregister();
     field public static final int VALIDATION_STATUS_NOT_VALID = 2; // 0x2
@@ -253,7 +259,12 @@
   public static final class NetworkAgentConfig.Builder {
     ctor public NetworkAgentConfig.Builder();
     method @NonNull public android.net.NetworkAgentConfig build();
+    method @NonNull public android.net.NetworkAgentConfig.Builder disableNat64Detection();
+    method @NonNull public android.net.NetworkAgentConfig.Builder disableProvisioningNotification();
     method @NonNull public android.net.NetworkAgentConfig.Builder setExplicitlySelected(boolean);
+    method @NonNull public android.net.NetworkAgentConfig.Builder setLegacyExtraInfo(@NonNull String);
+    method @NonNull public android.net.NetworkAgentConfig.Builder setLegacySubType(int);
+    method @NonNull public android.net.NetworkAgentConfig.Builder setLegacySubTypeName(@NonNull String);
     method @NonNull public android.net.NetworkAgentConfig.Builder setLegacyType(int);
     method @NonNull public android.net.NetworkAgentConfig.Builder setLegacyTypeName(@NonNull String);
     method @NonNull public android.net.NetworkAgentConfig.Builder setPartialConnectivityAcceptable(boolean);
@@ -261,17 +272,19 @@
   }
 
   public final class NetworkCapabilities implements android.os.Parcelable {
-    ctor public NetworkCapabilities(@Nullable android.net.NetworkCapabilities, boolean);
     method @NonNull public int[] getAdministratorUids();
+    method @Nullable public static String getCapabilityCarrierName(int);
     method @Nullable public String getSsid();
     method @NonNull public int[] getTransportTypes();
     method public boolean isPrivateDnsBroken();
     method public boolean satisfiedByNetworkCapabilities(@Nullable android.net.NetworkCapabilities);
+    field public static final int NET_CAPABILITY_BIP = 31; // 0x1f
     field public static final int NET_CAPABILITY_NOT_VCN_MANAGED = 28; // 0x1c
     field public static final int NET_CAPABILITY_OEM_PAID = 22; // 0x16
     field public static final int NET_CAPABILITY_OEM_PRIVATE = 26; // 0x1a
     field public static final int NET_CAPABILITY_PARTIAL_CONNECTIVITY = 24; // 0x18
     field public static final int NET_CAPABILITY_VEHICLE_INTERNAL = 27; // 0x1b
+    field public static final int NET_CAPABILITY_VSIM = 30; // 0x1e
   }
 
   public static final class NetworkCapabilities.Builder {
@@ -302,9 +315,16 @@
     method public int getProviderId();
     method public void onNetworkRequestWithdrawn(@NonNull android.net.NetworkRequest);
     method public void onNetworkRequested(@NonNull android.net.NetworkRequest, @IntRange(from=0, to=99) int, int);
+    method @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void registerNetworkOffer(@NonNull android.net.NetworkScore, @NonNull android.net.NetworkCapabilities, @NonNull java.util.concurrent.Executor, @NonNull android.net.NetworkProvider.NetworkOfferCallback);
+    method @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void unregisterNetworkOffer(@NonNull android.net.NetworkProvider.NetworkOfferCallback);
     field public static final int ID_NONE = -1; // 0xffffffff
   }
 
+  public static interface NetworkProvider.NetworkOfferCallback {
+    method public void onNetworkNeeded(@NonNull android.net.NetworkRequest);
+    method public void onNetworkUnneeded(@NonNull android.net.NetworkRequest);
+  }
+
   public class NetworkReleasedException extends java.lang.Exception {
   }
 
@@ -317,6 +337,23 @@
     method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP) public android.net.NetworkRequest.Builder setSignalStrength(int);
   }
 
+  public final class NetworkScore implements android.os.Parcelable {
+    method public int describeContents();
+    method public int getKeepConnectedReason();
+    method public int getLegacyInt();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkScore> CREATOR;
+    field public static final int KEEP_CONNECTED_FOR_HANDOVER = 1; // 0x1
+    field public static final int KEEP_CONNECTED_NONE = 0; // 0x0
+  }
+
+  public static final class NetworkScore.Builder {
+    ctor public NetworkScore.Builder();
+    method @NonNull public android.net.NetworkScore build();
+    method @NonNull public android.net.NetworkScore.Builder setKeepConnectedReason(int);
+    method @NonNull public android.net.NetworkScore.Builder setLegacyInt(int);
+  }
+
   public final class OemNetworkPreferences implements android.os.Parcelable {
     method public int describeContents();
     method @NonNull public java.util.Map<java.lang.String,java.lang.Integer> getNetworkPreferences();
@@ -364,6 +401,7 @@
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.net.QosSession> CREATOR;
     field public static final int TYPE_EPS_BEARER = 1; // 0x1
+    field public static final int TYPE_NR_BEARER = 2; // 0x2
   }
 
   public interface QosSessionAttributes {
@@ -389,6 +427,7 @@
   }
 
   public abstract class SocketKeepalive implements java.lang.AutoCloseable {
+    field public static final int ERROR_NO_SUCH_SLOT = -33; // 0xffffffdf
     field public static final int SUCCESS = 0; // 0x0
   }
 
@@ -435,11 +474,6 @@
     field public final int tcpWindowScale;
   }
 
-  public interface TransportInfo {
-    method public default boolean hasLocationSensitiveFields();
-    method @NonNull public default android.net.TransportInfo makeCopy(boolean);
-  }
-
 }
 
 package android.net.apf {
diff --git a/packages/Connectivity/framework/jarjar-rules.txt b/packages/Connectivity/framework/jarjar-rules.txt
index 0959840..7474c24 100644
--- a/packages/Connectivity/framework/jarjar-rules.txt
+++ b/packages/Connectivity/framework/jarjar-rules.txt
@@ -1,4 +1,5 @@
 rule com.android.net.module.util.** android.net.connectivity.framework.util.@1
+rule android.net.NetworkFactory* android.net.connectivity.framework.NetworkFactory@1
 
 # TODO (b/149403767): remove the annotations from net-utils-device-common instead of here
 zap android.annotation.**
diff --git a/packages/Connectivity/framework/jni/android_net_NetworkUtils.cpp b/packages/Connectivity/framework/jni/android_net_NetworkUtils.cpp
index 19ffe77..e8bb42d 100644
--- a/packages/Connectivity/framework/jni/android_net_NetworkUtils.cpp
+++ b/packages/Connectivity/framework/jni/android_net_NetworkUtils.cpp
@@ -19,6 +19,7 @@
 #include <vector>
 
 #include <android/file_descriptor_jni.h>
+#include <android/multinetwork.h>
 #include <arpa/inet.h>
 #include <linux/filter.h>
 #include <linux/if_arp.h>
@@ -30,12 +31,12 @@
 
 #include <DnsProxydProtocol.h> // NETID_USE_LOCAL_NAMESERVERS
 #include <cutils/properties.h>
+#include <nativehelper/JNIHelp.h>
 #include <nativehelper/JNIPlatformHelp.h>
 #include <nativehelper/ScopedLocalRef.h>
 #include <utils/Log.h>
 #include <utils/misc.h>
 
-#include "NetdClient.h"
 #include "jni.h"
 
 extern "C" {
@@ -57,14 +58,6 @@
     return clazz;
 }
 
-static inline jmethodID GetMethodIDOrDie(JNIEnv* env, jclass clazz, const char* method_name,
-                                         const char* method_signature) {
-    jmethodID res = env->GetMethodID(clazz, method_name, method_signature);
-    LOG_ALWAYS_FATAL_IF(res == NULL, "Unable to find method %s with signature %s", method_name,
-                        method_signature);
-    return res;
-}
-
 template <typename T>
 static inline T MakeGlobalRefOrDie(JNIEnv* env, T in) {
     jobject res = env->NewGlobalRef(in);
@@ -72,27 +65,6 @@
     return static_cast<T>(res);
 }
 
-static void throwErrnoException(JNIEnv* env, const char* functionName, int error) {
-    ScopedLocalRef<jstring> detailMessage(env, env->NewStringUTF(functionName));
-    if (detailMessage.get() == NULL) {
-        // Not really much we can do here. We're probably dead in the water,
-        // but let's try to stumble on...
-        env->ExceptionClear();
-    }
-    static jclass errnoExceptionClass =
-            MakeGlobalRefOrDie(env, FindClassOrDie(env, "android/system/ErrnoException"));
-
-    static jmethodID errnoExceptionCtor =
-            GetMethodIDOrDie(env, errnoExceptionClass,
-            "<init>", "(Ljava/lang/String;I)V");
-
-    jobject exception = env->NewObject(errnoExceptionClass,
-                                       errnoExceptionCtor,
-                                       detailMessage.get(),
-                                       error);
-    env->Throw(reinterpret_cast<jthrowable>(exception));
-}
-
 static void android_net_utils_attachDropAllBPFFilter(JNIEnv *env, jobject clazz, jobject javaFd)
 {
     struct sock_filter filter_code[] = {
@@ -122,30 +94,32 @@
     }
 }
 
-static jboolean android_net_utils_bindProcessToNetwork(JNIEnv *env, jobject thiz, jint netId)
+static jboolean android_net_utils_bindProcessToNetworkHandle(JNIEnv *env, jobject thiz,
+        jlong netHandle)
 {
-    return (jboolean) !setNetworkForProcess(netId);
+    return (jboolean) !android_setprocnetwork(netHandle);
 }
 
-static jint android_net_utils_getBoundNetworkForProcess(JNIEnv *env, jobject thiz)
+static jlong android_net_utils_getBoundNetworkHandleForProcess(JNIEnv *env, jobject thiz)
 {
-    return getNetworkForProcess();
+    net_handle_t network;
+    if (android_getprocnetwork(&network) != 0) {
+        jniThrowExceptionFmt(env, "java/lang/IllegalStateException",
+                "android_getprocnetwork(): %s", strerror(errno));
+        return NETWORK_UNSPECIFIED;
+    }
+    return (jlong) network;
 }
 
 static jboolean android_net_utils_bindProcessToNetworkForHostResolution(JNIEnv *env, jobject thiz,
-        jint netId)
+        jint netId, jlong netHandle)
 {
-    return (jboolean) !setNetworkForResolv(netId);
+    return (jboolean) !android_setprocdns(netHandle);
 }
 
-static jint android_net_utils_bindSocketToNetwork(JNIEnv *env, jobject thiz, jobject javaFd,
-                                                  jint netId) {
-    return setNetworkForSocket(netId, AFileDescriptor_getFD(env, javaFd));
-}
-
-static jboolean android_net_utils_queryUserAccess(JNIEnv *env, jobject thiz, jint uid, jint netId)
-{
-    return (jboolean) !queryUserAccess(uid, netId);
+static jint android_net_utils_bindSocketToNetworkHandle(JNIEnv *env, jobject thiz, jobject javaFd,
+                                                  jlong netHandle) {
+    return android_setsocknetwork(netHandle, AFileDescriptor_getFD(env, javaFd));
 }
 
 static bool checkLenAndCopy(JNIEnv* env, const jbyteArray& addr, int len, void* dst)
@@ -157,7 +131,7 @@
     return true;
 }
 
-static jobject android_net_utils_resNetworkQuery(JNIEnv *env, jobject thiz, jint netId,
+static jobject android_net_utils_resNetworkQuery(JNIEnv *env, jobject thiz, jlong netHandle,
         jstring dname, jint ns_class, jint ns_type, jint flags) {
     const jsize javaCharsCount = env->GetStringLength(dname);
     const jsize byteCountUTF8 = env->GetStringUTFLength(dname);
@@ -167,25 +141,26 @@
     std::vector<char> queryname(byteCountUTF8 + 1, 0);
 
     env->GetStringUTFRegion(dname, 0, javaCharsCount, queryname.data());
-    int fd = resNetworkQuery(netId, queryname.data(), ns_class, ns_type, flags);
+
+    int fd = android_res_nquery(netHandle, queryname.data(), ns_class, ns_type, flags);
 
     if (fd < 0) {
-        throwErrnoException(env, "resNetworkQuery", -fd);
+        jniThrowErrnoException(env, "resNetworkQuery", -fd);
         return nullptr;
     }
 
     return jniCreateFileDescriptor(env, fd);
 }
 
-static jobject android_net_utils_resNetworkSend(JNIEnv *env, jobject thiz, jint netId,
+static jobject android_net_utils_resNetworkSend(JNIEnv *env, jobject thiz, jlong netHandle,
         jbyteArray msg, jint msgLen, jint flags) {
     uint8_t data[MAXCMDSIZE];
 
     checkLenAndCopy(env, msg, msgLen, data);
-    int fd = resNetworkSend(netId, data, msgLen, flags);
+    int fd = android_res_nsend(netHandle, data, msgLen, flags);
 
     if (fd < 0) {
-        throwErrnoException(env, "resNetworkSend", -fd);
+        jniThrowErrnoException(env, "resNetworkSend", -fd);
         return nullptr;
     }
 
@@ -197,16 +172,16 @@
     int rcode;
     std::vector<uint8_t> buf(MAXPACKETSIZE, 0);
 
-    int res = resNetworkResult(fd, &rcode, buf.data(), MAXPACKETSIZE);
+    int res = android_res_nresult(fd, &rcode, buf.data(), MAXPACKETSIZE);
     jniSetFileDescriptorOfFD(env, javaFd, -1);
     if (res < 0) {
-        throwErrnoException(env, "resNetworkResult", -res);
+        jniThrowErrnoException(env, "resNetworkResult", -res);
         return nullptr;
     }
 
     jbyteArray answer = env->NewByteArray(res);
     if (answer == nullptr) {
-        throwErrnoException(env, "resNetworkResult", ENOMEM);
+        jniThrowErrnoException(env, "resNetworkResult", ENOMEM);
         return nullptr;
     } else {
         env->SetByteArrayRegion(answer, 0, res,
@@ -221,23 +196,22 @@
 
 static void android_net_utils_resNetworkCancel(JNIEnv *env, jobject thiz, jobject javaFd) {
     int fd = AFileDescriptor_getFD(env, javaFd);
-    resNetworkCancel(fd);
+    android_res_cancel(fd);
     jniSetFileDescriptorOfFD(env, javaFd, -1);
 }
 
 static jobject android_net_utils_getDnsNetwork(JNIEnv *env, jobject thiz) {
-    unsigned dnsNetId = 0;
-    if (int res = getNetworkForDns(&dnsNetId) < 0) {
-        throwErrnoException(env, "getDnsNetId", -res);
+    net_handle_t dnsNetHandle = NETWORK_UNSPECIFIED;
+    if (int res = android_getprocdns(&dnsNetHandle) < 0) {
+        jniThrowErrnoException(env, "getDnsNetwork", -res);
         return nullptr;
     }
-    bool privateDnsBypass = dnsNetId & NETID_USE_LOCAL_NAMESERVERS;
 
     static jclass class_Network = MakeGlobalRefOrDie(
             env, FindClassOrDie(env, "android/net/Network"));
-    static jmethodID ctor = env->GetMethodID(class_Network, "<init>", "(IZ)V");
-    return env->NewObject(
-            class_Network, ctor, dnsNetId & ~NETID_USE_LOCAL_NAMESERVERS, privateDnsBypass);
+    static jmethodID method = env->GetStaticMethodID(class_Network, "fromNetworkHandle",
+            "(J)Landroid/net/Network;");
+    return env->CallStaticObjectMethod(class_Network, method, static_cast<jlong>(dnsNetHandle));
 }
 
 static jobject android_net_utils_getTcpRepairWindow(JNIEnv *env, jobject thiz, jobject javaFd) {
@@ -253,7 +227,7 @@
     // Obtain the parameters of the TCP repair window.
     int rc = getsockopt(fd, IPPROTO_TCP, TCP_REPAIR_WINDOW, &trw, &size);
     if (rc == -1) {
-        throwErrnoException(env, "getsockopt : TCP_REPAIR_WINDOW", errno);
+        jniThrowErrnoException(env, "getsockopt : TCP_REPAIR_WINDOW", errno);
         return NULL;
     }
 
@@ -264,7 +238,7 @@
     // should be applied to the window size.
     rc = getsockopt(fd, IPPROTO_TCP, TCP_INFO, &tcpinfo, &tcpinfo_size);
     if (rc == -1) {
-        throwErrnoException(env, "getsockopt : TCP_INFO", errno);
+        jniThrowErrnoException(env, "getsockopt : TCP_INFO", errno);
         return NULL;
     }
 
@@ -283,16 +257,15 @@
 // clang-format off
 static const JNINativeMethod gNetworkUtilMethods[] = {
     /* name, signature, funcPtr */
-    { "bindProcessToNetwork", "(I)Z", (void*) android_net_utils_bindProcessToNetwork },
-    { "getBoundNetworkForProcess", "()I", (void*) android_net_utils_getBoundNetworkForProcess },
+    { "bindProcessToNetworkHandle", "(J)Z", (void*) android_net_utils_bindProcessToNetworkHandle },
+    { "getBoundNetworkHandleForProcess", "()J", (void*) android_net_utils_getBoundNetworkHandleForProcess },
     { "bindProcessToNetworkForHostResolution", "(I)Z", (void*) android_net_utils_bindProcessToNetworkForHostResolution },
-    { "bindSocketToNetwork", "(Ljava/io/FileDescriptor;I)I", (void*) android_net_utils_bindSocketToNetwork },
-    { "queryUserAccess", "(II)Z", (void*)android_net_utils_queryUserAccess },
+    { "bindSocketToNetworkHandle", "(Ljava/io/FileDescriptor;J)I", (void*) android_net_utils_bindSocketToNetworkHandle },
     { "attachDropAllBPFFilter", "(Ljava/io/FileDescriptor;)V", (void*) android_net_utils_attachDropAllBPFFilter },
     { "detachBPFFilter", "(Ljava/io/FileDescriptor;)V", (void*) android_net_utils_detachBPFFilter },
     { "getTcpRepairWindow", "(Ljava/io/FileDescriptor;)Landroid/net/TcpRepairWindow;", (void*) android_net_utils_getTcpRepairWindow },
-    { "resNetworkSend", "(I[BII)Ljava/io/FileDescriptor;", (void*) android_net_utils_resNetworkSend },
-    { "resNetworkQuery", "(ILjava/lang/String;III)Ljava/io/FileDescriptor;", (void*) android_net_utils_resNetworkQuery },
+    { "resNetworkSend", "(J[BII)Ljava/io/FileDescriptor;", (void*) android_net_utils_resNetworkSend },
+    { "resNetworkQuery", "(JLjava/lang/String;III)Ljava/io/FileDescriptor;", (void*) android_net_utils_resNetworkQuery },
     { "resNetworkResult", "(Ljava/io/FileDescriptor;)Landroid/net/DnsResolver$DnsResponse;", (void*) android_net_utils_resNetworkResult },
     { "resNetworkCancel", "(Ljava/io/FileDescriptor;)V", (void*) android_net_utils_resNetworkCancel },
     { "getDnsNetwork", "()Landroid/net/Network;", (void*) android_net_utils_getDnsNetwork },
diff --git a/packages/Connectivity/framework/src/android/net/ConnectivityManager.java b/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
index f8a0e4e..350b47f 100644
--- a/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
+++ b/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
@@ -38,7 +38,9 @@
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
 import android.app.PendingIntent;
+import android.app.admin.DevicePolicyManager;
 import android.compat.annotation.UnsupportedAppUsage;
+import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
@@ -829,6 +831,114 @@
     })
     public @interface PrivateDnsMode {}
 
+    /**
+     * Flag to indicate that an app is not subject to any restrictions that could result in its
+     * network access blocked.
+     *
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public static final int BLOCKED_REASON_NONE = 0;
+
+    /**
+     * Flag to indicate that an app is subject to Battery saver restrictions that would
+     * result in its network access being blocked.
+     *
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public static final int BLOCKED_REASON_BATTERY_SAVER = 1 << 0;
+
+    /**
+     * Flag to indicate that an app is subject to Doze restrictions that would
+     * result in its network access being blocked.
+     *
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public static final int BLOCKED_REASON_DOZE = 1 << 1;
+
+    /**
+     * Flag to indicate that an app is subject to App Standby restrictions that would
+     * result in its network access being blocked.
+     *
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public static final int BLOCKED_REASON_APP_STANDBY = 1 << 2;
+
+    /**
+     * Flag to indicate that an app is subject to Restricted mode restrictions that would
+     * result in its network access being blocked.
+     *
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public static final int BLOCKED_REASON_RESTRICTED_MODE = 1 << 3;
+
+    /**
+     * Flag to indicate that an app is blocked because it is subject to an always-on VPN but the VPN
+     * is not currently connected.
+     *
+     * @see DevicePolicyManager#setAlwaysOnVpnPackage(ComponentName, String, boolean)
+     *
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public static final int BLOCKED_REASON_LOCKDOWN_VPN = 1 << 4;
+
+    /**
+     * Flag to indicate that an app is subject to Data saver restrictions that would
+     * result in its metered network access being blocked.
+     *
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public static final int BLOCKED_METERED_REASON_DATA_SAVER = 1 << 16;
+
+    /**
+     * Flag to indicate that an app is subject to user restrictions that would
+     * result in its metered network access being blocked.
+     *
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public static final int BLOCKED_METERED_REASON_USER_RESTRICTED = 1 << 17;
+
+    /**
+     * Flag to indicate that an app is subject to Device admin restrictions that would
+     * result in its metered network access being blocked.
+     *
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public static final int BLOCKED_METERED_REASON_ADMIN_DISABLED = 1 << 18;
+
+    /**
+     * @hide
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(flag = true, prefix = {"BLOCKED_"}, value = {
+            BLOCKED_REASON_NONE,
+            BLOCKED_REASON_BATTERY_SAVER,
+            BLOCKED_REASON_DOZE,
+            BLOCKED_REASON_APP_STANDBY,
+            BLOCKED_REASON_RESTRICTED_MODE,
+            BLOCKED_REASON_LOCKDOWN_VPN,
+            BLOCKED_METERED_REASON_DATA_SAVER,
+            BLOCKED_METERED_REASON_USER_RESTRICTED,
+            BLOCKED_METERED_REASON_ADMIN_DISABLED,
+    })
+    public @interface BlockedReason {}
+
+    /**
+     * Set of blocked reasons that are only applicable on metered networks.
+     *
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public static final int BLOCKED_METERED_REASON_MASK = 0xffff0000;
+
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 130143562)
     private final IConnectivityManager mService;
 
@@ -1083,8 +1193,7 @@
      *
      * @return a {@link Network} object for the current default network for the
      *         given UID or {@code null} if no default network is currently active
-     *
-     * @hide
+     * TODO: b/183465229 Cleanup getActiveNetworkForUid once b/165835257 is fixed
      */
     @RequiresPermission(android.Manifest.permission.NETWORK_STACK)
     @Nullable
@@ -1125,12 +1234,13 @@
      * @param ranges the UID ranges to restrict
      * @param requireVpn whether the specified UID ranges must use a VPN
      *
-     * TODO: expose as @SystemApi.
      * @hide
      */
     @RequiresPermission(anyOf = {
             NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
-            android.Manifest.permission.NETWORK_STACK})
+            android.Manifest.permission.NETWORK_STACK,
+            android.Manifest.permission.NETWORK_SETTINGS})
+    @SystemApi(client = MODULE_LIBRARIES)
     public void setRequireVpnForUids(boolean requireVpn,
             @NonNull Collection<Range<Integer>> ranges) {
         Objects.requireNonNull(ranges);
@@ -1174,13 +1284,13 @@
      *
      * @param enabled whether legacy lockdown VPN is enabled or disabled
      *
-     * TODO: @SystemApi(client = MODULE_LIBRARIES)
-     *
      * @hide
      */
     @RequiresPermission(anyOf = {
             NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+            android.Manifest.permission.NETWORK_STACK,
             android.Manifest.permission.NETWORK_SETTINGS})
+    @SystemApi(client = MODULE_LIBRARIES)
     public void setLegacyLockdownVpnEnabled(boolean enabled) {
         try {
             mService.setLegacyLockdownVpnEnabled(enabled);
@@ -2127,6 +2237,7 @@
      */
     @Deprecated
     @UnsupportedAppUsage
+    @SystemApi(client = MODULE_LIBRARIES)
     public boolean requestRouteToHostAddress(int networkType, InetAddress hostAddress) {
         checkLegacyRoutingApiAccess();
         try {
@@ -3233,7 +3344,61 @@
         provider.setProviderId(NetworkProvider.ID_NONE);
     }
 
+    /**
+     * Register or update a network offer with ConnectivityService.
+     *
+     * ConnectivityService keeps track of offers made by the various providers and matches
+     * them to networking requests made by apps or the system. A callback identifies an offer
+     * uniquely, and later calls with the same callback update the offer. The provider supplies a
+     * score and the capabilities of the network it might be able to bring up ; these act as
+     * filters used by ConnectivityService to only send those requests that can be fulfilled by the
+     * provider.
+     *
+     * The provider is under no obligation to be able to bring up the network it offers at any
+     * given time. Instead, this mechanism is meant to limit requests received by providers
+     * to those they actually have a chance to fulfill, as providers don't have a way to compare
+     * the quality of the network satisfying a given request to their own offer.
+     *
+     * An offer can be updated by calling this again with the same callback object. This is
+     * similar to calling unofferNetwork and offerNetwork again, but will only update the
+     * provider with the changes caused by the changes in the offer.
+     *
+     * @param provider The provider making this offer.
+     * @param score The prospective score of the network.
+     * @param caps The prospective capabilities of the network.
+     * @param callback The callback to call when this offer is needed or unneeded.
+     * @hide exposed via the NetworkProvider class.
+     */
+    @RequiresPermission(anyOf = {
+            NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+            android.Manifest.permission.NETWORK_FACTORY})
+    public void offerNetwork(@NonNull final int providerId,
+            @NonNull final NetworkScore score, @NonNull final NetworkCapabilities caps,
+            @NonNull final INetworkOfferCallback callback) {
+        try {
+            mService.offerNetwork(providerId,
+                    Objects.requireNonNull(score, "null score"),
+                    Objects.requireNonNull(caps, "null caps"),
+                    Objects.requireNonNull(callback, "null callback"));
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
 
+    /**
+     * Withdraw a network offer made with {@link #offerNetwork}.
+     *
+     * @param callback The callback passed at registration time. This must be the same object
+     *                 that was passed to {@link #offerNetwork}
+     * @hide exposed via the NetworkProvider class.
+     */
+    public void unofferNetwork(@NonNull final INetworkOfferCallback callback) {
+        try {
+            mService.unofferNetwork(Objects.requireNonNull(callback));
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
     /** @hide exposed via the NetworkProvider class. */
     @RequiresPermission(anyOf = {
             NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
@@ -3355,12 +3520,30 @@
          * @param blocked Whether access to the {@link Network} is blocked due to system policy.
          * @hide
          */
-        public void onAvailable(@NonNull Network network,
+        public final void onAvailable(@NonNull Network network,
                 @NonNull NetworkCapabilities networkCapabilities,
-                @NonNull LinkProperties linkProperties, boolean blocked) {
+                @NonNull LinkProperties linkProperties, @BlockedReason int blocked) {
             // Internally only this method is called when a new network is available, and
             // it calls the callback in the same way and order that older versions used
             // to call so as not to change the behavior.
+            onAvailable(network, networkCapabilities, linkProperties, blocked != 0);
+            onBlockedStatusChanged(network, blocked);
+        }
+
+        /**
+         * Legacy variant of onAvailable that takes a boolean blocked reason.
+         *
+         * This method has never been public API, but it's not final, so there may be apps that
+         * implemented it and rely on it being called. Do our best not to break them.
+         * Note: such apps will also get a second call to onBlockedStatusChanged immediately after
+         * this method is called. There does not seem to be a way to avoid this.
+         * TODO: add a compat check to move apps off this method, and eventually stop calling it.
+         *
+         * @hide
+         */
+        public void onAvailable(@NonNull Network network,
+                @NonNull NetworkCapabilities networkCapabilities,
+                @NonNull LinkProperties linkProperties, boolean blocked) {
             onAvailable(network);
             if (!networkCapabilities.hasCapability(
                     NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED)) {
@@ -3368,7 +3551,7 @@
             }
             onCapabilitiesChanged(network, networkCapabilities);
             onLinkPropertiesChanged(network, linkProperties);
-            onBlockedStatusChanged(network, blocked);
+            // No call to onBlockedStatusChanged here. That is done by the caller.
         }
 
         /**
@@ -3532,6 +3715,27 @@
          */
         public void onBlockedStatusChanged(@NonNull Network network, boolean blocked) {}
 
+        /**
+         * Called when access to the specified network is blocked or unblocked, or the reason for
+         * access being blocked changes.
+         *
+         * If a NetworkCallback object implements this method,
+         * {@link #onBlockedStatusChanged(Network, boolean)} will not be called.
+         *
+         * <p>Do NOT call {@link #getNetworkCapabilities(Network)} or
+         * {@link #getLinkProperties(Network)} or other synchronous ConnectivityManager methods in
+         * this callback as this is prone to race conditions : calling these methods while in a
+         * callback may return an outdated or even a null object.
+         *
+         * @param network The {@link Network} whose blocked status has changed.
+         * @param blocked The blocked status of this {@link Network}.
+         * @hide
+         */
+        @SystemApi(client = MODULE_LIBRARIES)
+        public void onBlockedStatusChanged(@NonNull Network network, @BlockedReason int blocked) {
+            onBlockedStatusChanged(network, blocked != 0);
+        }
+
         private NetworkRequest networkRequest;
         private final int mFlags;
     }
@@ -3646,7 +3850,7 @@
                 case CALLBACK_AVAILABLE: {
                     NetworkCapabilities cap = getObject(message, NetworkCapabilities.class);
                     LinkProperties lp = getObject(message, LinkProperties.class);
-                    callback.onAvailable(network, cap, lp, message.arg1 != 0);
+                    callback.onAvailable(network, cap, lp, message.arg1);
                     break;
                 }
                 case CALLBACK_LOSING: {
@@ -3680,8 +3884,7 @@
                     break;
                 }
                 case CALLBACK_BLK_CHANGED: {
-                    boolean blocked = message.arg1 != 0;
-                    callback.onBlockedStatusChanged(network, blocked);
+                    callback.onBlockedStatusChanged(network, message.arg1);
                 }
             }
         }
@@ -3703,8 +3906,9 @@
     private static final HashMap<NetworkRequest, NetworkCallback> sCallbacks = new HashMap<>();
     private static CallbackHandler sCallbackHandler;
 
-    private NetworkRequest sendRequestForNetwork(NetworkCapabilities need, NetworkCallback callback,
-            int timeoutMs, NetworkRequest.Type reqType, int legacyType, CallbackHandler handler) {
+    private NetworkRequest sendRequestForNetwork(int asUid, NetworkCapabilities need,
+            NetworkCallback callback, int timeoutMs, NetworkRequest.Type reqType, int legacyType,
+            CallbackHandler handler) {
         printStackTrace();
         checkCallbackNotNull(callback);
         if (reqType != TRACK_DEFAULT && reqType != TRACK_SYSTEM_DEFAULT && need == null) {
@@ -3729,8 +3933,8 @@
                             getAttributionTag());
                 } else {
                     request = mService.requestNetwork(
-                            need, reqType.ordinal(), messenger, timeoutMs, binder, legacyType,
-                            callbackFlags, callingPackageName, getAttributionTag());
+                            asUid, need, reqType.ordinal(), messenger, timeoutMs, binder,
+                            legacyType, callbackFlags, callingPackageName, getAttributionTag());
                 }
                 if (request != null) {
                     sCallbacks.put(request, callback);
@@ -3745,6 +3949,12 @@
         return request;
     }
 
+    private NetworkRequest sendRequestForNetwork(NetworkCapabilities need, NetworkCallback callback,
+            int timeoutMs, NetworkRequest.Type reqType, int legacyType, CallbackHandler handler) {
+        return sendRequestForNetwork(Process.INVALID_UID, need, callback, timeoutMs, reqType,
+                legacyType, handler);
+    }
+
     /**
      * Helper function to request a network with a particular legacy type.
      *
@@ -4230,8 +4440,40 @@
     @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
     public void registerDefaultNetworkCallback(@NonNull NetworkCallback networkCallback,
             @NonNull Handler handler) {
+        registerDefaultNetworkCallbackAsUid(Process.INVALID_UID, networkCallback, handler);
+    }
+
+    /**
+     * Registers to receive notifications about changes in the default network for the specified
+     * UID. This may be a physical network or a virtual network, such as a VPN that applies to the
+     * UID. The callbacks will continue to be called until either the application exits or
+     * {@link #unregisterNetworkCallback(NetworkCallback)} is called.
+     *
+     * <p>To avoid performance issues due to apps leaking callbacks, the system will limit the
+     * number of outstanding requests to 100 per app (identified by their UID), shared with
+     * all variants of this method, of {@link #requestNetwork} as well as
+     * {@link ConnectivityDiagnosticsManager#registerConnectivityDiagnosticsCallback}.
+     * Requesting a network with this method will count toward this limit. If this limit is
+     * exceeded, an exception will be thrown. To avoid hitting this issue and to conserve resources,
+     * make sure to unregister the callbacks with
+     * {@link #unregisterNetworkCallback(NetworkCallback)}.
+     *
+     * @param uid the UID for which to track default network changes.
+     * @param networkCallback The {@link NetworkCallback} that the system will call as the
+     *                        UID's default network changes.
+     * @param handler {@link Handler} to specify the thread upon which the callback will be invoked.
+     * @throws RuntimeException if the app already has too many callbacks registered.
+     * @hide
+     */
+    @SystemApi(client = MODULE_LIBRARIES)
+    @SuppressLint({"ExecutorRegistration", "PairedRegistration"})
+    @RequiresPermission(anyOf = {
+            NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+            android.Manifest.permission.NETWORK_SETTINGS})
+    public void registerDefaultNetworkCallbackAsUid(int uid,
+            @NonNull NetworkCallback networkCallback, @NonNull Handler handler) {
         CallbackHandler cbHandler = new CallbackHandler(handler);
-        sendRequestForNetwork(null /* NetworkCapabilities need */, networkCallback, 0,
+        sendRequestForNetwork(uid, null /* need */, networkCallback, 0 /* timeoutMs */,
                 TRACK_DEFAULT, TYPE_NONE, cbHandler);
     }
 
@@ -4942,20 +5184,20 @@
      * {@link QosCallback#onError(QosCallbackException)}.  see: {@link QosCallbackException}.
      *
      * @param socketInfo the socket information used to match QoS events
-     * @param callback receives qos events that satisfy socketInfo
      * @param executor The executor on which the callback will be invoked. The provided
      *                 {@link Executor} must run callback sequentially, otherwise the order of
-     *                 callbacks cannot be guaranteed.
+     *                 callbacks cannot be guaranteed.onQosCallbackRegistered
+     * @param callback receives qos events that satisfy socketInfo
      *
      * @hide
      */
     @SystemApi
     public void registerQosCallback(@NonNull final QosSocketInfo socketInfo,
-            @NonNull final QosCallback callback,
-            @CallbackExecutor @NonNull final Executor executor) {
+            @CallbackExecutor @NonNull final Executor executor,
+            @NonNull final QosCallback callback) {
         Objects.requireNonNull(socketInfo, "socketInfo must be non-null");
-        Objects.requireNonNull(callback, "callback must be non-null");
         Objects.requireNonNull(executor, "executor must be non-null");
+        Objects.requireNonNull(callback, "callback must be non-null");
 
         try {
             synchronized (mQosCallbackConnections) {
@@ -5245,4 +5487,23 @@
         if (TextUtils.isEmpty(mode)) mode = PRIVATE_DNS_MODE_OPPORTUNISTIC;
         return mode;
     }
+
+    /**
+     * Set private DNS mode to settings.
+     *
+     * @param context The {@link Context} to set the private DNS mode.
+     * @param mode The private dns mode. This should be one of the PRIVATE_DNS_MODE_* constants.
+     *
+     * @hide
+     */
+    @SystemApi(client = MODULE_LIBRARIES)
+    public static void setPrivateDnsMode(@NonNull Context context,
+            @NonNull @PrivateDnsMode String mode) {
+        if (!(mode == PRIVATE_DNS_MODE_OFF
+                || mode == PRIVATE_DNS_MODE_OPPORTUNISTIC
+                || mode == PRIVATE_DNS_MODE_PROVIDER_HOSTNAME)) {
+            throw new IllegalArgumentException("Invalid private dns mode");
+        }
+        Settings.Global.putString(context.getContentResolver(), PRIVATE_DNS_MODE, mode);
+    }
 }
diff --git a/packages/Connectivity/framework/src/android/net/ConnectivitySettingsManager.java b/packages/Connectivity/framework/src/android/net/ConnectivitySettingsManager.java
index bbd8393..9a00055 100644
--- a/packages/Connectivity/framework/src/android/net/ConnectivitySettingsManager.java
+++ b/packages/Connectivity/framework/src/android/net/ConnectivitySettingsManager.java
@@ -16,16 +16,38 @@
 
 package android.net;
 
+import static android.net.ConnectivityManager.MULTIPATH_PREFERENCE_HANDOVER;
+import static android.net.ConnectivityManager.MULTIPATH_PREFERENCE_PERFORMANCE;
+import static android.net.ConnectivityManager.MULTIPATH_PREFERENCE_RELIABILITY;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME;
+
 import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.content.Context;
+import android.net.ConnectivityManager.MultipathPreference;
+import android.net.ConnectivityManager.PrivateDnsMode;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.util.Range;
+
+import com.android.net.module.util.ProxyUtils;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.time.Duration;
+import java.util.List;
 
 /**
  * A manager class for connectivity module settings.
  *
  * @hide
  */
+@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
 public class ConnectivitySettingsManager {
 
     private ConnectivitySettingsManager() {}
@@ -45,12 +67,16 @@
      * Network activity refers to transmitting or receiving data on the network interfaces.
      *
      * Tracking is disabled if set to zero or negative value.
+     *
+     * @hide
      */
     public static final String DATA_ACTIVITY_TIMEOUT_MOBILE = "data_activity_timeout_mobile";
 
     /**
      * Timeout to tracking Wifi data activity. Same as {@code DATA_ACTIVITY_TIMEOUT_MOBILE}
      * but for Wifi network.
+     *
+     * @hide
      */
     public static final String DATA_ACTIVITY_TIMEOUT_WIFI = "data_activity_timeout_wifi";
 
@@ -58,12 +84,16 @@
 
     /**
      * Sample validity in seconds to configure for the system DNS resolver.
+     *
+     * @hide
      */
     public static final String DNS_RESOLVER_SAMPLE_VALIDITY_SECONDS =
             "dns_resolver_sample_validity_seconds";
 
     /**
      * Success threshold in percent for use with the system DNS resolver.
+     *
+     * @hide
      */
     public static final String DNS_RESOLVER_SUCCESS_THRESHOLD_PERCENT =
             "dns_resolver_success_threshold_percent";
@@ -71,24 +101,35 @@
     /**
      * Minimum number of samples needed for statistics to be considered meaningful in the
      * system DNS resolver.
+     *
+     * @hide
      */
     public static final String DNS_RESOLVER_MIN_SAMPLES = "dns_resolver_min_samples";
 
     /**
      * Maximum number taken into account for statistics purposes in the system DNS resolver.
+     *
+     * @hide
      */
     public static final String DNS_RESOLVER_MAX_SAMPLES = "dns_resolver_max_samples";
 
+    private static final int DNS_RESOLVER_DEFAULT_MIN_SAMPLES = 8;
+    private static final int DNS_RESOLVER_DEFAULT_MAX_SAMPLES = 64;
+
     /** Network switch notification settings */
 
     /**
      * The maximum number of notifications shown in 24 hours when switching networks.
+     *
+     * @hide
      */
     public static final String NETWORK_SWITCH_NOTIFICATION_DAILY_LIMIT =
             "network_switch_notification_daily_limit";
 
     /**
      * The minimum time in milliseconds between notifications when switching networks.
+     *
+     * @hide
      */
     public static final String NETWORK_SWITCH_NOTIFICATION_RATE_LIMIT_MILLIS =
             "network_switch_notification_rate_limit_millis";
@@ -98,14 +139,18 @@
     /**
      * The URL used for HTTP captive portal detection upon a new connection.
      * A 204 response code from the server is used for validation.
+     *
+     * @hide
      */
     public static final String CAPTIVE_PORTAL_HTTP_URL = "captive_portal_http_url";
 
     /**
      * What to do when connecting a network that presents a captive portal.
-     * Must be one of the CAPTIVE_PORTAL_MODE_* constants above.
+     * Must be one of the CAPTIVE_PORTAL_MODE_* constants below.
      *
      * The default for this setting is CAPTIVE_PORTAL_MODE_PROMPT.
+     *
+     * @hide
      */
     public static final String CAPTIVE_PORTAL_MODE = "captive_portal_mode";
 
@@ -139,11 +184,15 @@
 
     /**
      * Host name for global http proxy. Set via ConnectivityManager.
+     *
+     * @hide
      */
     public static final String GLOBAL_HTTP_PROXY_HOST = "global_http_proxy_host";
 
     /**
      * Integer host port for global http proxy. Set via ConnectivityManager.
+     *
+     * @hide
      */
     public static final String GLOBAL_HTTP_PROXY_PORT = "global_http_proxy_port";
 
@@ -153,12 +202,16 @@
      * Domains should be listed in a comma- separated list. Example of
      * acceptable formats: ".domain1.com,my.domain2.com" Use
      * ConnectivityManager to set/get.
+     *
+     * @hide
      */
     public static final String GLOBAL_HTTP_PROXY_EXCLUSION_LIST =
             "global_http_proxy_exclusion_list";
 
     /**
      * The location PAC File for the proxy.
+     *
+     * @hide
      */
     public static final String GLOBAL_HTTP_PROXY_PAC = "global_proxy_pac_url";
 
@@ -171,11 +224,15 @@
      * a specific provider. It may be used to store the provider name even when the
      * mode changes so that temporarily disabling and re-enabling the specific
      * provider mode does not necessitate retyping the provider hostname.
+     *
+     * @hide
      */
     public static final String PRIVATE_DNS_MODE = "private_dns_mode";
 
     /**
      * The specific Private DNS provider name.
+     *
+     * @hide
      */
     public static final String PRIVATE_DNS_SPECIFIER = "private_dns_specifier";
 
@@ -185,6 +242,8 @@
      * all of which require explicit user action to enable/configure. See also b/79719289.
      *
      * Value is a string, suitable for assignment to PRIVATE_DNS_MODE above.
+     *
+     * @hide
      */
     public static final String PRIVATE_DNS_DEFAULT_MODE = "private_dns_default_mode";
 
@@ -194,6 +253,8 @@
      * The number of milliseconds to hold on to a PendingIntent based request. This delay gives
      * the receivers of the PendingIntent an opportunity to make a new network request before
      * the Network satisfying the request is potentially removed.
+     *
+     * @hide
      */
     public static final String CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS =
             "connectivity_release_pending_intent_delay_ms";
@@ -205,6 +266,8 @@
      * See ConnectivityService for more info.
      *
      * (0 = disabled, 1 = enabled)
+     *
+     * @hide
      */
     public static final String MOBILE_DATA_ALWAYS_ON = "mobile_data_always_on";
 
@@ -217,6 +280,8 @@
      * See ConnectivityService for more info.
      *
      * (0 = disabled, 1 = enabled)
+     *
+     * @hide
      */
     public static final String WIFI_ALWAYS_REQUESTED = "wifi_always_requested";
 
@@ -228,14 +293,637 @@
      * 0: Don't avoid bad wifi, don't prompt the user. Get stuck on bad wifi like it's 2013.
      * null: Ask the user whether to switch away from bad wifi.
      * 1: Avoid bad wifi.
+     *
+     * @hide
      */
     public static final String NETWORK_AVOID_BAD_WIFI = "network_avoid_bad_wifi";
 
     /**
+     * Don't avoid bad wifi, don't prompt the user. Get stuck on bad wifi like it's 2013.
+     */
+    public static final int NETWORK_AVOID_BAD_WIFI_IGNORE = 0;
+
+    /**
+     * Ask the user whether to switch away from bad wifi.
+     */
+    public static final int NETWORK_AVOID_BAD_WIFI_PROMPT = 1;
+
+    /**
+     * Avoid bad wifi.
+     */
+    public static final int NETWORK_AVOID_BAD_WIFI_AVOID = 2;
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(value = {
+            NETWORK_AVOID_BAD_WIFI_IGNORE,
+            NETWORK_AVOID_BAD_WIFI_PROMPT,
+            NETWORK_AVOID_BAD_WIFI_AVOID,
+    })
+    public @interface NetworkAvoidBadWifi {}
+
+    /**
      * User setting for ConnectivityManager.getMeteredMultipathPreference(). This value may be
      * overridden by the system based on device or application state. If null, the value
      * specified by config_networkMeteredMultipathPreference is used.
+     *
+     * @hide
      */
     public static final String NETWORK_METERED_MULTIPATH_PREFERENCE =
             "network_metered_multipath_preference";
+
+    /**
+     * A list of apps that should go on cellular networks in preference even when higher-priority
+     * networks are connected.
+     *
+     * @hide
+     */
+    public static final String MOBILE_DATA_PREFERRED_APPS = "mobile_data_preferred_apps";
+
+    /**
+     * Get mobile data activity timeout from {@link Settings}.
+     *
+     * @param context The {@link Context} to query the setting.
+     * @param def The default timeout if no setting value.
+     * @return The {@link Duration} of timeout to track mobile data activity.
+     */
+    @NonNull
+    public static Duration getMobileDataActivityTimeout(@NonNull Context context,
+            @NonNull Duration def) {
+        final int timeout = Settings.Global.getInt(
+                context.getContentResolver(), DATA_ACTIVITY_TIMEOUT_MOBILE, (int) def.getSeconds());
+        return Duration.ofSeconds(timeout);
+    }
+
+    /**
+     * Set mobile data activity timeout to {@link Settings}.
+     * Tracking is disabled if set to zero or negative value.
+     *
+     * Note: Only use the number of seconds in this duration, lower second(nanoseconds) will be
+     * ignored.
+     *
+     * @param context The {@link Context} to set the setting.
+     * @param timeout The mobile data activity timeout.
+     */
+    public static void setMobileDataActivityTimeout(@NonNull Context context,
+            @NonNull Duration timeout) {
+        Settings.Global.putInt(context.getContentResolver(), DATA_ACTIVITY_TIMEOUT_MOBILE,
+                (int) timeout.getSeconds());
+    }
+
+    /**
+     * Get wifi data activity timeout from {@link Settings}.
+     *
+     * @param context The {@link Context} to query the setting.
+     * @param def The default timeout if no setting value.
+     * @return The {@link Duration} of timeout to track wifi data activity.
+     */
+    @NonNull
+    public static Duration getWifiDataActivityTimeout(@NonNull Context context,
+            @NonNull Duration def) {
+        final int timeout = Settings.Global.getInt(
+                context.getContentResolver(), DATA_ACTIVITY_TIMEOUT_WIFI, (int) def.getSeconds());
+        return Duration.ofSeconds(timeout);
+    }
+
+    /**
+     * Set wifi data activity timeout to {@link Settings}.
+     * Tracking is disabled if set to zero or negative value.
+     *
+     * Note: Only use the number of seconds in this duration, lower second(nanoseconds) will be
+     * ignored.
+     *
+     * @param context The {@link Context} to set the setting.
+     * @param timeout The wifi data activity timeout.
+     */
+    public static void setWifiDataActivityTimeout(@NonNull Context context,
+            @NonNull Duration timeout) {
+        Settings.Global.putInt(context.getContentResolver(), DATA_ACTIVITY_TIMEOUT_WIFI,
+                (int) timeout.getSeconds());
+    }
+
+    /**
+     * Get dns resolver sample validity duration from {@link Settings}.
+     *
+     * @param context The {@link Context} to query the setting.
+     * @param def The default duration if no setting value.
+     * @return The {@link Duration} of sample validity duration to configure for the system DNS
+     *         resolver.
+     */
+    @NonNull
+    public static Duration getDnsResolverSampleValidityDuration(@NonNull Context context,
+            @NonNull Duration def) {
+        final int duration = Settings.Global.getInt(context.getContentResolver(),
+                DNS_RESOLVER_SAMPLE_VALIDITY_SECONDS, (int) def.getSeconds());
+        return Duration.ofSeconds(duration);
+    }
+
+    /**
+     * Set dns resolver sample validity duration to {@link Settings}. The duration must be a
+     * positive number of seconds.
+     *
+     * @param context The {@link Context} to set the setting.
+     * @param duration The sample validity duration.
+     */
+    public static void setDnsResolverSampleValidityDuration(@NonNull Context context,
+            @NonNull Duration duration) {
+        final int time = (int) duration.getSeconds();
+        if (time <= 0) {
+            throw new IllegalArgumentException("Invalid duration");
+        }
+        Settings.Global.putInt(
+                context.getContentResolver(), DNS_RESOLVER_SAMPLE_VALIDITY_SECONDS, time);
+    }
+
+    /**
+     * Get dns resolver success threshold percent from {@link Settings}.
+     *
+     * @param context The {@link Context} to query the setting.
+     * @param def The default value if no setting value.
+     * @return The success threshold in percent for use with the system DNS resolver.
+     */
+    public static int getDnsResolverSuccessThresholdPercent(@NonNull Context context, int def) {
+        return Settings.Global.getInt(
+                context.getContentResolver(), DNS_RESOLVER_SUCCESS_THRESHOLD_PERCENT, def);
+    }
+
+    /**
+     * Set dns resolver success threshold percent to {@link Settings}. The threshold percent must
+     * be 0~100.
+     *
+     * @param context The {@link Context} to set the setting.
+     * @param percent The success threshold percent.
+     */
+    public static void setDnsResolverSuccessThresholdPercent(@NonNull Context context,
+            @IntRange(from = 0, to = 100) int percent) {
+        if (percent < 0 || percent > 100) {
+            throw new IllegalArgumentException("Percent must be 0~100");
+        }
+        Settings.Global.putInt(
+                context.getContentResolver(), DNS_RESOLVER_SUCCESS_THRESHOLD_PERCENT, percent);
+    }
+
+    /**
+     * Get dns resolver samples range from {@link Settings}.
+     *
+     * @param context The {@link Context} to query the setting.
+     * @return The {@link Range<Integer>} of samples needed for statistics to be considered
+     *         meaningful in the system DNS resolver.
+     */
+    @NonNull
+    public static Range<Integer> getDnsResolverSampleRanges(@NonNull Context context) {
+        final int minSamples = Settings.Global.getInt(context.getContentResolver(),
+                DNS_RESOLVER_MIN_SAMPLES, DNS_RESOLVER_DEFAULT_MIN_SAMPLES);
+        final int maxSamples = Settings.Global.getInt(context.getContentResolver(),
+                DNS_RESOLVER_MAX_SAMPLES, DNS_RESOLVER_DEFAULT_MAX_SAMPLES);
+        return new Range<>(minSamples, maxSamples);
+    }
+
+    /**
+     * Set dns resolver samples range to {@link Settings}.
+     *
+     * @param context The {@link Context} to set the setting.
+     * @param range The samples range. The minimum number should be more than 0 and the maximum
+     *              number should be less that 64.
+     */
+    public static void setDnsResolverSampleRanges(@NonNull Context context,
+            @NonNull Range<Integer> range) {
+        if (range.getLower() < 0 || range.getUpper() > 64) {
+            throw new IllegalArgumentException("Argument must be 0~64");
+        }
+        Settings.Global.putInt(
+                context.getContentResolver(), DNS_RESOLVER_MIN_SAMPLES, range.getLower());
+        Settings.Global.putInt(
+                context.getContentResolver(), DNS_RESOLVER_MAX_SAMPLES, range.getUpper());
+    }
+
+    /**
+     * Get maximum count (from {@link Settings}) of switching network notifications shown in 24
+     * hours.
+     *
+     * @param context The {@link Context} to query the setting.
+     * @param def The default value if no setting value.
+     * @return The maximum count of notifications shown in 24 hours when switching networks.
+     */
+    public static int getNetworkSwitchNotificationMaximumDailyCount(@NonNull Context context,
+            int def) {
+        return Settings.Global.getInt(
+                context.getContentResolver(), NETWORK_SWITCH_NOTIFICATION_DAILY_LIMIT, def);
+    }
+
+    /**
+     * Set maximum count (to {@link Settings}) of switching network notifications shown in 24 hours.
+     * The count must be at least 0.
+     *
+     * @param context The {@link Context} to set the setting.
+     * @param count The maximum count of switching network notifications shown in 24 hours.
+     */
+    public static void setNetworkSwitchNotificationMaximumDailyCount(@NonNull Context context,
+            @IntRange(from = 0) int count) {
+        if (count < 0) {
+            throw new IllegalArgumentException("Count must be 0~10.");
+        }
+        Settings.Global.putInt(
+                context.getContentResolver(), NETWORK_SWITCH_NOTIFICATION_DAILY_LIMIT, count);
+    }
+
+    /**
+     * Get minimum duration (from {@link Settings}) between each switching network notifications.
+     *
+     * @param context The {@link Context} to query the setting.
+     * @param def The default time if no setting value.
+     * @return The minimum duration between notifications when switching networks.
+     */
+    @NonNull
+    public static Duration getNetworkSwitchNotificationRateDuration(@NonNull Context context,
+            @NonNull Duration def) {
+        final int duration = Settings.Global.getInt(context.getContentResolver(),
+                NETWORK_SWITCH_NOTIFICATION_RATE_LIMIT_MILLIS, (int) def.toMillis());
+        return Duration.ofMillis(duration);
+    }
+
+    /**
+     * Set minimum duration (to {@link Settings}) between each switching network notifications.
+     *
+     * @param context The {@link Context} to set the setting.
+     * @param duration The minimum duration between notifications when switching networks.
+     */
+    public static void setNetworkSwitchNotificationRateDuration(@NonNull Context context,
+            @NonNull Duration duration) {
+        final int time = (int) duration.toMillis();
+        if (time < 0) {
+            throw new IllegalArgumentException("Invalid duration.");
+        }
+        Settings.Global.putInt(context.getContentResolver(),
+                NETWORK_SWITCH_NOTIFICATION_RATE_LIMIT_MILLIS, time);
+    }
+
+    /**
+     * Get URL (from {@link Settings}) used for HTTP captive portal detection upon a new connection.
+     *
+     * @param context The {@link Context} to query the setting.
+     * @return The URL used for HTTP captive portal detection upon a new connection.
+     */
+    @Nullable
+    public static String getCaptivePortalHttpUrl(@NonNull Context context) {
+        return Settings.Global.getString(context.getContentResolver(), CAPTIVE_PORTAL_HTTP_URL);
+    }
+
+    /**
+     * Set URL (to {@link Settings}) used for HTTP captive portal detection upon a new connection.
+     * This URL should respond with a 204 response to a GET request to indicate no captive portal is
+     * present. And this URL must be HTTP as redirect responses are used to find captive portal
+     * sign-in pages. If the URL set to null or be incorrect, it will result in captive portal
+     * detection failed and lost the connection.
+     *
+     * @param context The {@link Context} to set the setting.
+     * @param url The URL used for HTTP captive portal detection upon a new connection.
+     */
+    public static void setCaptivePortalHttpUrl(@NonNull Context context, @Nullable String url) {
+        Settings.Global.putString(context.getContentResolver(), CAPTIVE_PORTAL_HTTP_URL, url);
+    }
+
+    /**
+     * Get mode (from {@link Settings}) when connecting a network that presents a captive portal.
+     *
+     * @param context The {@link Context} to query the setting.
+     * @param def The default mode if no setting value.
+     * @return The mode when connecting a network that presents a captive portal.
+     */
+    @CaptivePortalMode
+    public static int getCaptivePortalMode(@NonNull Context context,
+            @CaptivePortalMode int def) {
+        return Settings.Global.getInt(context.getContentResolver(), CAPTIVE_PORTAL_MODE, def);
+    }
+
+    /**
+     * Set mode (to {@link Settings}) when connecting a network that presents a captive portal.
+     *
+     * @param context The {@link Context} to set the setting.
+     * @param mode The mode when connecting a network that presents a captive portal.
+     */
+    public static void setCaptivePortalMode(@NonNull Context context, @CaptivePortalMode int mode) {
+        if (!(mode == CAPTIVE_PORTAL_MODE_IGNORE
+                || mode == CAPTIVE_PORTAL_MODE_PROMPT
+                || mode == CAPTIVE_PORTAL_MODE_AVOID)) {
+            throw new IllegalArgumentException("Invalid captive portal mode");
+        }
+        Settings.Global.putInt(context.getContentResolver(), CAPTIVE_PORTAL_MODE, mode);
+    }
+
+    /**
+     * Get the global HTTP proxy applied to the device, or null if none.
+     *
+     * @param context The {@link Context} to query the setting.
+     * @return The {@link ProxyInfo} which build from global http proxy settings.
+     */
+    @Nullable
+    public static ProxyInfo getGlobalProxy(@NonNull Context context) {
+        final String host = Settings.Global.getString(
+                context.getContentResolver(), GLOBAL_HTTP_PROXY_HOST);
+        final int port = Settings.Global.getInt(
+                context.getContentResolver(), GLOBAL_HTTP_PROXY_PORT, 0 /* def */);
+        final String exclusionList = Settings.Global.getString(
+                context.getContentResolver(), GLOBAL_HTTP_PROXY_EXCLUSION_LIST);
+        final String pacFileUrl = Settings.Global.getString(
+                context.getContentResolver(), GLOBAL_HTTP_PROXY_PAC);
+
+        if (TextUtils.isEmpty(host) && TextUtils.isEmpty(pacFileUrl)) {
+            return null; // No global proxy.
+        }
+
+        if (TextUtils.isEmpty(pacFileUrl)) {
+            return ProxyInfo.buildDirectProxy(
+                    host, port, ProxyUtils.exclusionStringAsList(exclusionList));
+        } else {
+            return ProxyInfo.buildPacProxy(Uri.parse(pacFileUrl));
+        }
+    }
+
+    /**
+     * Set global http proxy settings from given {@link ProxyInfo}.
+     *
+     * @param context The {@link Context} to set the setting.
+     * @param proxyInfo The {@link ProxyInfo} for global http proxy settings which build from
+     *                    {@link ProxyInfo#buildPacProxy(Uri)} or
+     *                    {@link ProxyInfo#buildDirectProxy(String, int, List)}
+     */
+    public static void setGlobalProxy(@NonNull Context context, @NonNull ProxyInfo proxyInfo) {
+        final String host = proxyInfo.getHost();
+        final int port = proxyInfo.getPort();
+        final String exclusionList = proxyInfo.getExclusionListAsString();
+        final String pacFileUrl = proxyInfo.getPacFileUrl().toString();
+
+        if (TextUtils.isEmpty(pacFileUrl)) {
+            Settings.Global.putString(context.getContentResolver(), GLOBAL_HTTP_PROXY_HOST, host);
+            Settings.Global.putInt(context.getContentResolver(), GLOBAL_HTTP_PROXY_PORT, port);
+            Settings.Global.putString(
+                    context.getContentResolver(), GLOBAL_HTTP_PROXY_EXCLUSION_LIST, exclusionList);
+            Settings.Global.putString(
+                    context.getContentResolver(), GLOBAL_HTTP_PROXY_PAC, "" /* value */);
+        } else {
+            Settings.Global.putString(
+                    context.getContentResolver(), GLOBAL_HTTP_PROXY_PAC, pacFileUrl);
+            Settings.Global.putString(
+                    context.getContentResolver(), GLOBAL_HTTP_PROXY_HOST, "" /* value */);
+            Settings.Global.putInt(
+                    context.getContentResolver(), GLOBAL_HTTP_PROXY_PORT, 0 /* value */);
+            Settings.Global.putString(
+                    context.getContentResolver(), GLOBAL_HTTP_PROXY_EXCLUSION_LIST, "" /* value */);
+        }
+    }
+
+    /**
+     * Clear all global http proxy settings.
+     *
+     * @param context The {@link Context} to set the setting.
+     */
+    public static void clearGlobalProxy(@NonNull Context context) {
+        Settings.Global.putString(
+                context.getContentResolver(), GLOBAL_HTTP_PROXY_HOST, "" /* value */);
+        Settings.Global.putInt(
+                context.getContentResolver(), GLOBAL_HTTP_PROXY_PORT, 0 /* value */);
+        Settings.Global.putString(
+                context.getContentResolver(), GLOBAL_HTTP_PROXY_EXCLUSION_LIST, "" /* value */);
+        Settings.Global.putString(
+                context.getContentResolver(), GLOBAL_HTTP_PROXY_PAC, "" /* value */);
+    }
+
+    /**
+     * Get specific private dns provider name from {@link Settings}.
+     *
+     * @param context The {@link Context} to query the setting.
+     * @return The specific private dns provider name, or null if no setting value.
+     */
+    @Nullable
+    public static String getPrivateDnsHostname(@NonNull Context context) {
+        return Settings.Global.getString(context.getContentResolver(), PRIVATE_DNS_SPECIFIER);
+    }
+
+    /**
+     * Set specific private dns provider name to {@link Settings}.
+     *
+     * @param context The {@link Context} to set the setting.
+     * @param specifier The specific private dns provider name.
+     */
+    public static void setPrivateDnsHostname(@NonNull Context context,
+            @Nullable String specifier) {
+        Settings.Global.putString(context.getContentResolver(), PRIVATE_DNS_SPECIFIER, specifier);
+    }
+
+    /**
+     * Get default private dns mode from {@link Settings}.
+     *
+     * @param context The {@link Context} to query the setting.
+     * @return The default private dns mode.
+     */
+    @PrivateDnsMode
+    @NonNull
+    public static String getPrivateDnsDefaultMode(@NonNull Context context) {
+        return Settings.Global.getString(context.getContentResolver(), PRIVATE_DNS_DEFAULT_MODE);
+    }
+
+    /**
+     * Set default private dns mode to {@link Settings}.
+     *
+     * @param context The {@link Context} to set the setting.
+     * @param mode The default private dns mode. This should be one of the PRIVATE_DNS_MODE_*
+     *             constants.
+     */
+    public static void setPrivateDnsDefaultMode(@NonNull Context context,
+            @NonNull @PrivateDnsMode String mode) {
+        if (!(mode == PRIVATE_DNS_MODE_OFF
+                || mode == PRIVATE_DNS_MODE_OPPORTUNISTIC
+                || mode == PRIVATE_DNS_MODE_PROVIDER_HOSTNAME)) {
+            throw new IllegalArgumentException("Invalid private dns mode");
+        }
+        Settings.Global.putString(context.getContentResolver(), PRIVATE_DNS_DEFAULT_MODE, mode);
+    }
+
+    /**
+     * Get duration (from {@link Settings}) to keep a PendingIntent-based request.
+     *
+     * @param context The {@link Context} to query the setting.
+     * @param def The default duration if no setting value.
+     * @return The duration to keep a PendingIntent-based request.
+     */
+    @NonNull
+    public static Duration getConnectivityKeepPendingIntentDuration(@NonNull Context context,
+            @NonNull Duration def) {
+        final int duration = Settings.Secure.getInt(context.getContentResolver(),
+                CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS, (int) def.toMillis());
+        return Duration.ofMillis(duration);
+    }
+
+    /**
+     * Set duration (to {@link Settings}) to keep a PendingIntent-based request.
+     *
+     * @param context The {@link Context} to set the setting.
+     * @param duration The duration to keep a PendingIntent-based request.
+     */
+    public static void setConnectivityKeepPendingIntentDuration(@NonNull Context context,
+            @NonNull Duration duration) {
+        final int time = (int) duration.toMillis();
+        if (time < 0) {
+            throw new IllegalArgumentException("Invalid duration.");
+        }
+        Settings.Secure.putInt(
+                context.getContentResolver(), CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS, time);
+    }
+
+    /**
+     * Read from {@link Settings} whether the mobile data connection should remain active
+     * even when higher priority networks are active.
+     *
+     * @param context The {@link Context} to query the setting.
+     * @param def The default value if no setting value.
+     * @return Whether the mobile data connection should remain active even when higher
+     *         priority networks are active.
+     */
+    public static boolean getMobileDataAlwaysOn(@NonNull Context context, boolean def) {
+        final int enable = Settings.Global.getInt(
+                context.getContentResolver(), MOBILE_DATA_ALWAYS_ON, (def ? 1 : 0));
+        return (enable != 0) ? true : false;
+    }
+
+    /**
+     * Write into {@link Settings} whether the mobile data connection should remain active
+     * even when higher priority networks are active.
+     *
+     * @param context The {@link Context} to set the setting.
+     * @param enable Whether the mobile data connection should remain active even when higher
+     *               priority networks are active.
+     */
+    public static void setMobileDataAlwaysOn(@NonNull Context context, boolean enable) {
+        Settings.Global.putInt(
+                context.getContentResolver(), MOBILE_DATA_ALWAYS_ON, (enable ? 1 : 0));
+    }
+
+    /**
+     * Read from {@link Settings} whether the wifi data connection should remain active
+     * even when higher priority networks are active.
+     *
+     * @param context The {@link Context} to query the setting.
+     * @param def The default value if no setting value.
+     * @return Whether the wifi data connection should remain active even when higher
+     *         priority networks are active.
+     */
+    public static boolean getWifiAlwaysRequested(@NonNull Context context, boolean def) {
+        final int enable = Settings.Global.getInt(
+                context.getContentResolver(), WIFI_ALWAYS_REQUESTED, (def ? 1 : 0));
+        return (enable != 0) ? true : false;
+    }
+
+    /**
+     * Write into {@link Settings} whether the wifi data connection should remain active
+     * even when higher priority networks are active.
+     *
+     * @param context The {@link Context} to set the setting.
+     * @param enable Whether the wifi data connection should remain active even when higher
+     *               priority networks are active
+     */
+    public static void setWifiAlwaysRequested(@NonNull Context context, boolean enable) {
+        Settings.Global.putInt(
+                context.getContentResolver(), WIFI_ALWAYS_REQUESTED, (enable ? 1 : 0));
+    }
+
+    /**
+     * Get avoid bad wifi setting from {@link Settings}.
+     *
+     * @param context The {@link Context} to query the setting.
+     * @return The setting whether to automatically switch away from wifi networks that lose
+     *         internet access.
+     */
+    @NetworkAvoidBadWifi
+    public static int getNetworkAvoidBadWifi(@NonNull Context context) {
+        final String setting =
+                Settings.Global.getString(context.getContentResolver(), NETWORK_AVOID_BAD_WIFI);
+        if ("0".equals(setting)) {
+            return NETWORK_AVOID_BAD_WIFI_IGNORE;
+        } else if ("1".equals(setting)) {
+            return NETWORK_AVOID_BAD_WIFI_AVOID;
+        } else {
+            return NETWORK_AVOID_BAD_WIFI_PROMPT;
+        }
+    }
+
+    /**
+     * Set avoid bad wifi setting to {@link Settings}.
+     *
+     * @param context The {@link Context} to set the setting.
+     * @param value Whether to automatically switch away from wifi networks that lose internet
+     *              access.
+     */
+    public static void setNetworkAvoidBadWifi(@NonNull Context context,
+            @NetworkAvoidBadWifi int value) {
+        final String setting;
+        if (value == NETWORK_AVOID_BAD_WIFI_IGNORE) {
+            setting = "0";
+        } else if (value == NETWORK_AVOID_BAD_WIFI_AVOID) {
+            setting = "1";
+        } else if (value == NETWORK_AVOID_BAD_WIFI_PROMPT) {
+            setting = null;
+        } else {
+            throw new IllegalArgumentException("Invalid avoid bad wifi setting");
+        }
+        Settings.Global.putString(context.getContentResolver(), NETWORK_AVOID_BAD_WIFI, setting);
+    }
+
+    /**
+     * Get network metered multipath preference from {@link Settings}.
+     *
+     * @param context The {@link Context} to query the setting.
+     * @return The network metered multipath preference which should be one of
+     *         ConnectivityManager#MULTIPATH_PREFERENCE_* value or null if the value specified
+     *         by config_networkMeteredMultipathPreference is used.
+     */
+    @Nullable
+    public static String getNetworkMeteredMultipathPreference(@NonNull Context context) {
+        return Settings.Global.getString(
+                context.getContentResolver(), NETWORK_METERED_MULTIPATH_PREFERENCE);
+    }
+
+    /**
+     * Set network metered multipath preference to {@link Settings}.
+     *
+     * @param context The {@link Context} to set the setting.
+     * @param preference The network metered multipath preference which should be one of
+     *                   ConnectivityManager#MULTIPATH_PREFERENCE_* value or null if the value
+     *                   specified by config_networkMeteredMultipathPreference is used.
+     */
+    public static void setNetworkMeteredMultipathPreference(@NonNull Context context,
+            @NonNull @MultipathPreference String preference) {
+        if (!(Integer.valueOf(preference) == MULTIPATH_PREFERENCE_HANDOVER
+                || Integer.valueOf(preference) == MULTIPATH_PREFERENCE_RELIABILITY
+                || Integer.valueOf(preference) == MULTIPATH_PREFERENCE_PERFORMANCE)) {
+            throw new IllegalArgumentException("Invalid private dns mode");
+        }
+        Settings.Global.putString(
+                context.getContentResolver(), NETWORK_METERED_MULTIPATH_PREFERENCE, preference);
+    }
+
+    /**
+     * Get the list of apps(from {@link Settings}) that should go on cellular networks in preference
+     * even when higher-priority networks are connected.
+     *
+     * @param context The {@link Context} to query the setting.
+     * @return A list of apps that should go on cellular networks in preference even when
+     *         higher-priority networks are connected or null if no setting value.
+     */
+    @Nullable
+    public static String getMobileDataPreferredApps(@NonNull Context context) {
+        return Settings.Secure.getString(context.getContentResolver(), MOBILE_DATA_PREFERRED_APPS);
+    }
+
+    /**
+     * Set the list of apps(to {@link Settings}) that should go on cellular networks in preference
+     * even when higher-priority networks are connected.
+     *
+     * @param context The {@link Context} to set the setting.
+     * @param list A list of apps that should go on cellular networks in preference even when
+     *             higher-priority networks are connected.
+     */
+    public static void setMobileDataPreferredApps(@NonNull Context context, @Nullable String list) {
+        Settings.Secure.putString(context.getContentResolver(), MOBILE_DATA_PREFERRED_APPS, list);
+    }
 }
diff --git a/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl b/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl
index 3300fa8..728f375 100644
--- a/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl
+++ b/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl
@@ -23,6 +23,7 @@
 import android.net.INetworkAgent;
 import android.net.IOnCompleteListener;
 import android.net.INetworkActivityListener;
+import android.net.INetworkOfferCallback;
 import android.net.IQosCallback;
 import android.net.ISocketKeepaliveCallback;
 import android.net.LinkProperties;
@@ -142,7 +143,7 @@
             in NetworkCapabilities nc, in NetworkScore score, in NetworkAgentConfig config,
             in int factorySerialNumber);
 
-    NetworkRequest requestNetwork(in NetworkCapabilities networkCapabilities, int reqType,
+    NetworkRequest requestNetwork(int uid, in NetworkCapabilities networkCapabilities, int reqType,
             in Messenger messenger, int timeoutSec, in IBinder binder, int legacy,
             int callbackFlags, String callingPackageName, String callingAttributionTag);
 
@@ -221,4 +222,8 @@
             in IOnCompleteListener listener);
 
     int getRestrictBackgroundStatusByCaller();
+
+    void offerNetwork(int providerId, in NetworkScore score,
+            in NetworkCapabilities caps, in INetworkOfferCallback callback);
+    void unofferNetwork(in INetworkOfferCallback callback);
 }
diff --git a/packages/Connectivity/framework/src/android/net/INetworkAgent.aidl b/packages/Connectivity/framework/src/android/net/INetworkAgent.aidl
index 1f66e18..d941d4b 100644
--- a/packages/Connectivity/framework/src/android/net/INetworkAgent.aidl
+++ b/packages/Connectivity/framework/src/android/net/INetworkAgent.aidl
@@ -46,4 +46,6 @@
     void onRemoveKeepalivePacketFilter(int slot);
     void onQosFilterCallbackRegistered(int qosCallbackId, in QosFilterParcelable filterParcel);
     void onQosCallbackUnregistered(int qosCallbackId);
+    void onNetworkCreated();
+    void onNetworkDestroyed();
 }
diff --git a/packages/Connectivity/framework/src/android/net/INetworkAgentRegistry.aidl b/packages/Connectivity/framework/src/android/net/INetworkAgentRegistry.aidl
index c5464d3..26cb1ed 100644
--- a/packages/Connectivity/framework/src/android/net/INetworkAgentRegistry.aidl
+++ b/packages/Connectivity/framework/src/android/net/INetworkAgentRegistry.aidl
@@ -22,6 +22,7 @@
 import android.net.NetworkScore;
 import android.net.QosSession;
 import android.telephony.data.EpsBearerQosSessionAttributes;
+import android.telephony.data.NrQosSessionAttributes;
 
 /**
  * Interface for NetworkAgents to send network properties.
@@ -37,6 +38,8 @@
     void sendSocketKeepaliveEvent(int slot, int reason);
     void sendUnderlyingNetworks(in @nullable List<Network> networks);
     void sendEpsQosSessionAvailable(int callbackId, in QosSession session, in EpsBearerQosSessionAttributes attributes);
+    void sendNrQosSessionAvailable(int callbackId, in QosSession session, in NrQosSessionAttributes attributes);
     void sendQosSessionLost(int qosCallbackId, in QosSession session);
     void sendQosCallbackError(int qosCallbackId, int exceptionType);
+    void sendTeardownDelayMs(int teardownDelayMs);
 }
diff --git a/packages/Connectivity/framework/src/android/net/INetworkOfferCallback.aidl b/packages/Connectivity/framework/src/android/net/INetworkOfferCallback.aidl
new file mode 100644
index 0000000..ecfba21
--- /dev/null
+++ b/packages/Connectivity/framework/src/android/net/INetworkOfferCallback.aidl
@@ -0,0 +1,61 @@
+/*
+ * 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 android.net;
+
+import android.net.NetworkRequest;
+
+/**
+ * A callback registered with connectivity by network providers together with
+ * a NetworkOffer.
+ *
+ * When the network for this offer is needed to satisfy some application or
+ * system component, connectivity will call onNetworkNeeded on this callback.
+ * When this happens, the provider should try and bring up the network.
+ *
+ * When the network for this offer is no longer needed, for example because
+ * the application has withdrawn the request or if the request is being
+ * satisfied by a network that this offer will never be able to beat,
+ * connectivity calls onNetworkUnneeded. When this happens, the provider
+ * should stop trying to bring up the network, or tear it down if it has
+ * already been brought up.
+ *
+ * When NetworkProvider#offerNetwork is called, the provider can expect to
+ * immediately receive all requests that can be fulfilled by that offer and
+ * are not already satisfied by a better network. It is possible no such
+ * request is currently outstanding, because no requests have been made that
+ * can be satisfied by this offer, or because all such requests are already
+ * satisfied by a better network.
+ * onNetworkNeeded can be called at any time after registration and until the
+ * offer is withdrawn with NetworkProvider#unofferNetwork is called. This
+ * typically happens when a new network request is filed by an application,
+ * or when the network satisfying a request disconnects and this offer now
+ * stands a chance to supply the best network for it.
+ *
+ * @hide
+ */
+oneway interface INetworkOfferCallback {
+    /**
+     * Called when a network for this offer is needed to fulfill this request.
+     * @param networkRequest the request to satisfy
+     */
+    void onNetworkNeeded(in NetworkRequest networkRequest);
+
+    /**
+     * Informs the registrant that the offer is no longer valuable to fulfill this request.
+     */
+    void onNetworkUnneeded(in NetworkRequest networkRequest);
+}
diff --git a/packages/Connectivity/framework/src/android/net/IQosCallback.aidl b/packages/Connectivity/framework/src/android/net/IQosCallback.aidl
index 91c7575..c973541 100644
--- a/packages/Connectivity/framework/src/android/net/IQosCallback.aidl
+++ b/packages/Connectivity/framework/src/android/net/IQosCallback.aidl
@@ -19,6 +19,7 @@
 import android.os.Bundle;
 import android.net.QosSession;
 import android.telephony.data.EpsBearerQosSessionAttributes;
+import android.telephony.data.NrQosSessionAttributes;
 
 /**
  * AIDL interface for QosCallback
@@ -29,6 +30,8 @@
 {
      void onQosEpsBearerSessionAvailable(in QosSession session,
         in EpsBearerQosSessionAttributes attributes);
+     void onNrQosSessionAvailable(in QosSession session,
+        in NrQosSessionAttributes attributes);
      void onQosSessionLost(in QosSession session);
      void onError(in int type);
 }
diff --git a/packages/Connectivity/framework/src/android/net/Network.java b/packages/Connectivity/framework/src/android/net/Network.java
index 0741414..1f49033 100644
--- a/packages/Connectivity/framework/src/android/net/Network.java
+++ b/packages/Connectivity/framework/src/android/net/Network.java
@@ -27,7 +27,6 @@
 import android.system.ErrnoException;
 import android.system.Os;
 import android.system.OsConstants;
-import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.annotations.GuardedBy;
 
@@ -93,6 +92,7 @@
     // value in the native/android/net.c NDK implementation.
     private static final long HANDLE_MAGIC = 0xcafed00dL;
     private static final int HANDLE_MAGIC_SIZE = 32;
+    private static final int USE_LOCAL_NAMESERVERS_FLAG = 0x80000000;
 
     // A boolean to control how getAllByName()/getByName() behaves in the face
     // of Private DNS.
@@ -190,7 +190,7 @@
      */
     public int getNetIdForResolv() {
         return mPrivateDnsBypass
-                ? (int) (0x80000000L | (long) netId)  // Non-portable DNS resolution flag.
+                ? (USE_LOCAL_NAMESERVERS_FLAG | netId)  // Non-portable DNS resolution flag.
                 : netId;
     }
 
@@ -453,12 +453,13 @@
             throw new IllegalArgumentException(
                     "Network.fromNetworkHandle refusing to instantiate NETID_UNSET Network.");
         }
-        if ((networkHandle & ((1L << HANDLE_MAGIC_SIZE) - 1)) != HANDLE_MAGIC
-                || networkHandle < 0) {
+        if ((networkHandle & ((1L << HANDLE_MAGIC_SIZE) - 1)) != HANDLE_MAGIC) {
             throw new IllegalArgumentException(
                     "Value passed to fromNetworkHandle() is not a network handle.");
         }
-        return new Network((int) (networkHandle >> HANDLE_MAGIC_SIZE));
+        final int netIdForResolv = (int) (networkHandle >>> HANDLE_MAGIC_SIZE);
+        return new Network((netIdForResolv & ~USE_LOCAL_NAMESERVERS_FLAG),
+                ((netIdForResolv & USE_LOCAL_NAMESERVERS_FLAG) != 0) /* privateDnsBypass */);
     }
 
     /**
@@ -486,7 +487,7 @@
         if (netId == 0) {
             return 0L;  // make this zero condition obvious for debugging
         }
-        return (((long) netId) << HANDLE_MAGIC_SIZE) | HANDLE_MAGIC;
+        return (((long) getNetIdForResolv()) << HANDLE_MAGIC_SIZE) | HANDLE_MAGIC;
     }
 
     // implement the Parcelable interface
@@ -526,11 +527,4 @@
     public String toString() {
         return Integer.toString(netId);
     }
-
-    /** @hide */
-    public void dumpDebug(ProtoOutputStream proto, long fieldId) {
-        final long token = proto.start(fieldId);
-        proto.write(NetworkProto.NET_ID, netId);
-        proto.end(token);
-    }
 }
diff --git a/packages/Connectivity/framework/src/android/net/NetworkAgent.java b/packages/Connectivity/framework/src/android/net/NetworkAgent.java
index 1416bb9..c57da53 100644
--- a/packages/Connectivity/framework/src/android/net/NetworkAgent.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkAgent.java
@@ -32,6 +32,7 @@
 import android.os.Message;
 import android.os.RemoteException;
 import android.telephony.data.EpsBearerQosSessionAttributes;
+import android.telephony.data.NrQosSessionAttributes;
 import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -184,6 +185,20 @@
     public static final int EVENT_UNDERLYING_NETWORKS_CHANGED = BASE + 5;
 
     /**
+     * Sent by the NetworkAgent to ConnectivityService to pass the current value of the teardown
+     * delay.
+     * arg1 = teardown delay in milliseconds
+     * @hide
+     */
+    public static final int EVENT_TEARDOWN_DELAY_CHANGED = BASE + 6;
+
+    /**
+     * The maximum value for the teardown delay, in milliseconds.
+     * @hide
+     */
+    public static final int MAX_TEARDOWN_DELAY_MS = 5000;
+
+    /**
      * Sent by ConnectivityService to the NetworkAgent to inform the agent of the
      * networks status - whether we could use the network or could not, due to
      * either a bad network configuration (no internet link) or captive portal.
@@ -196,7 +211,6 @@
      */
     public static final int CMD_REPORT_NETWORK_STATUS = BASE + 7;
 
-
     /**
      * Network validation suceeded.
      * Corresponds to {@link NetworkCapabilities.NET_CAPABILITY_VALIDATED}.
@@ -361,10 +375,25 @@
      */
     public static final int CMD_UNREGISTER_QOS_CALLBACK = BASE + 21;
 
+    /**
+     * Sent by ConnectivityService to {@link NetworkAgent} to inform the agent that its native
+     * network was created and the Network object is now valid.
+     *
+     * @hide
+     */
+    public static final int CMD_NETWORK_CREATED = BASE + 22;
+
+    /**
+     * Sent by ConnectivityService to {@link NetworkAgent} to inform the agent that its native
+     * network was destroyed.
+     *
+     * @hide
+     */
+    public static final int CMD_NETWORK_DESTROYED = BASE + 23;
+
     private static NetworkInfo getLegacyNetworkInfo(final NetworkAgentConfig config) {
-        // The subtype can be changed with (TODO) setLegacySubtype, but it starts
-        // with 0 (TelephonyManager.NETWORK_TYPE_UNKNOWN) and an empty description.
-        final NetworkInfo ni = new NetworkInfo(config.legacyType, 0, config.legacyTypeName, "");
+        final NetworkInfo ni = new NetworkInfo(config.legacyType, config.legacySubType,
+                config.legacyTypeName, config.legacySubTypeName);
         ni.setIsAvailable(true);
         ni.setDetailedState(NetworkInfo.DetailedState.CONNECTING, null /* reason */,
                 config.getLegacyExtraInfo());
@@ -390,7 +419,6 @@
      * @param score the initial score of this network. Update with sendNetworkScore.
      * @param config an immutable {@link NetworkAgentConfig} for this agent.
      * @param provider the {@link NetworkProvider} managing this agent.
-     * @hide TODO : unhide when impl is complete
      */
     public NetworkAgent(@NonNull Context context, @NonNull Looper looper, @NonNull String logTag,
             @NonNull NetworkCapabilities nc, @NonNull LinkProperties lp,
@@ -434,7 +462,7 @@
         }
 
         mInitialConfiguration = new InitialConfiguration(context,
-                new NetworkCapabilities(nc, /* parcelLocationSensitiveFields */ true),
+                new NetworkCapabilities(nc, NetworkCapabilities.REDACT_NONE),
                 new LinkProperties(lp), score, config, ni);
     }
 
@@ -562,6 +590,14 @@
                             msg.arg1 /* QoS callback id */);
                     break;
                 }
+                case CMD_NETWORK_CREATED: {
+                    onNetworkCreated();
+                    break;
+                }
+                case CMD_NETWORK_DESTROYED: {
+                    onNetworkDestroyed();
+                    break;
+                }
             }
         }
     }
@@ -702,6 +738,16 @@
             mHandler.sendMessage(mHandler.obtainMessage(
                     CMD_UNREGISTER_QOS_CALLBACK, qosCallbackId, 0, null));
         }
+
+        @Override
+        public void onNetworkCreated() {
+            mHandler.sendMessage(mHandler.obtainMessage(CMD_NETWORK_CREATED));
+        }
+
+        @Override
+        public void onNetworkDestroyed() {
+            mHandler.sendMessage(mHandler.obtainMessage(CMD_NETWORK_DESTROYED));
+        }
     }
 
     /**
@@ -818,6 +864,29 @@
     }
 
     /**
+     * Sets the value of the teardown delay.
+     *
+     * The teardown delay is the time between when the network disconnects and when the native
+     * network corresponding to this {@code NetworkAgent} is destroyed. By default, the native
+     * network is destroyed immediately. If {@code teardownDelayMs} is non-zero, then when this
+     * network disconnects, the system will instead immediately mark the network as restricted
+     * and unavailable to unprivileged apps, but will defer destroying the native network until the
+     * teardown delay timer expires.
+     *
+     * The interfaces in use by this network will remain in use until the native network is
+     * destroyed and cannot be reused until {@link #onNetworkDestroyed()} is called.
+     *
+     * This method may be called at any time while the network is connected. It has no effect if
+     * the network is already disconnected and the teardown delay timer is running.
+     *
+     * @param teardownDelayMs the teardown delay to set, or 0 to disable teardown delay.
+     */
+    public void setTeardownDelayMs(
+            @IntRange(from = 0, to = MAX_TEARDOWN_DELAY_MS) int teardownDelayMs) {
+        queueOrSendMessage(reg -> reg.sendTeardownDelayMs(teardownDelayMs));
+    }
+
+    /**
      * Change the legacy subtype of this network agent.
      *
      * This is only for backward compatibility and should not be used by non-legacy network agents,
@@ -829,6 +898,7 @@
      * @hide
      */
     @Deprecated
+    @SystemApi
     public void setLegacySubtype(final int legacySubtype, @NonNull final String legacySubtypeName) {
         mNetworkInfo.setSubtype(legacySubtype, legacySubtypeName);
         queueOrSendNetworkInfo(mNetworkInfo);
@@ -878,8 +948,7 @@
         mBandwidthUpdatePending.set(false);
         mLastBwRefreshTime = System.currentTimeMillis();
         final NetworkCapabilities nc =
-                new NetworkCapabilities(networkCapabilities,
-                        /* parcelLocationSensitiveFields */ true);
+                new NetworkCapabilities(networkCapabilities, NetworkCapabilities.REDACT_NONE);
         queueOrSendMessage(reg -> reg.sendNetworkCapabilities(nc));
     }
 
@@ -963,6 +1032,7 @@
      * shall try to overwrite this method and produce a bandwidth update if capable.
      * @hide
      */
+    @SystemApi
     public void onBandwidthUpdateRequested() {
         pollLceData();
     }
@@ -1011,6 +1081,17 @@
     }
 
     /**
+     * Called when ConnectivityService has successfully created this NetworkAgent's native network.
+     */
+    public void onNetworkCreated() {}
+
+
+    /**
+     * Called when ConnectivityService has successfully destroy this NetworkAgent's native network.
+     */
+    public void onNetworkDestroyed() {}
+
+    /**
      * Requests that the network hardware send the specified packet at the specified interval.
      *
      * @param slot the hardware slot on which to start the keepalive.
@@ -1161,29 +1242,37 @@
 
 
     /**
-     * Sends the attributes of Eps Bearer Qos Session back to the Application
+     * Sends the attributes of Qos Session back to the Application
      *
      * @param qosCallbackId the callback id that the session belongs to
-     * @param sessionId the unique session id across all Eps Bearer Qos Sessions
-     * @param attributes the attributes of the Eps Qos Session
+     * @param sessionId the unique session id across all Qos Sessions
+     * @param attributes the attributes of the Qos Session
      */
     public final void sendQosSessionAvailable(final int qosCallbackId, final int sessionId,
-            @NonNull final EpsBearerQosSessionAttributes attributes) {
+            @NonNull final QosSessionAttributes attributes) {
         Objects.requireNonNull(attributes, "The attributes must be non-null");
-        queueOrSendMessage(ra -> ra.sendEpsQosSessionAvailable(qosCallbackId,
-                new QosSession(sessionId, QosSession.TYPE_EPS_BEARER),
-                attributes));
+        if (attributes instanceof EpsBearerQosSessionAttributes) {
+            queueOrSendMessage(ra -> ra.sendEpsQosSessionAvailable(qosCallbackId,
+                    new QosSession(sessionId, QosSession.TYPE_EPS_BEARER),
+                    (EpsBearerQosSessionAttributes)attributes));
+        } else if (attributes instanceof NrQosSessionAttributes) {
+            queueOrSendMessage(ra -> ra.sendNrQosSessionAvailable(qosCallbackId,
+                    new QosSession(sessionId, QosSession.TYPE_NR_BEARER),
+                    (NrQosSessionAttributes)attributes));
+        }
     }
 
     /**
-     * Sends event that the Eps Qos Session was lost.
+     * Sends event that the Qos Session was lost.
      *
      * @param qosCallbackId the callback id that the session belongs to
-     * @param sessionId the unique session id across all Eps Bearer Qos Sessions
+     * @param sessionId the unique session id across all Qos Sessions
+     * @param qosSessionType the session type {@code QosSesson#QosSessionType}
      */
-    public final void sendQosSessionLost(final int qosCallbackId, final int sessionId) {
+    public final void sendQosSessionLost(final int qosCallbackId,
+            final int sessionId, final int qosSessionType) {
         queueOrSendMessage(ra -> ra.sendQosSessionLost(qosCallbackId,
-                new QosSession(sessionId, QosSession.TYPE_EPS_BEARER)));
+                new QosSession(sessionId, qosSessionType)));
     }
 
     /**
diff --git a/packages/Connectivity/framework/src/android/net/NetworkAgentConfig.java b/packages/Connectivity/framework/src/android/net/NetworkAgentConfig.java
index 5e50a64..3f058d8 100644
--- a/packages/Connectivity/framework/src/android/net/NetworkAgentConfig.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkAgentConfig.java
@@ -64,6 +64,16 @@
     }
 
     /**
+     * @return whether this VPN connection can be bypassed by the apps.
+     *
+     * @hide
+     */
+    @SystemApi(client = MODULE_LIBRARIES)
+    public boolean isBypassableVpn() {
+        return allowBypass;
+    }
+
+    /**
      * Set if the user desires to use this network even if it is unvalidated. This field has meaning
      * only if {@link explicitlySelected} is true. If it is, this field must also be set to the
      * appropriate value based on previous user choice.
@@ -165,6 +175,12 @@
     }
 
     /**
+     * The legacy Sub type of this network agent, or TYPE_NONE if unset.
+     * @hide
+     */
+    public int legacySubType = ConnectivityManager.TYPE_NONE;
+
+    /**
      * Set to true if the PRIVATE_DNS_BROKEN notification has shown for this network.
      * Reset this bit when private DNS mode is changed from strict mode to opportunistic/off mode.
      *
@@ -190,6 +206,13 @@
     }
 
     /**
+     * The name of the legacy Sub network type. It's a free-form string.
+     * @hide
+     */
+    @NonNull
+    public String legacySubTypeName = "";
+
+    /**
      * The legacy extra info of the agent. The extra info should only be :
      * <ul>
      *   <li>For cellular agents, the APN name.</li>
@@ -225,6 +248,8 @@
             skip464xlat = nac.skip464xlat;
             legacyType = nac.legacyType;
             legacyTypeName = nac.legacyTypeName;
+            legacySubType = nac.legacySubType;
+            legacySubTypeName = nac.legacySubTypeName;
             mLegacyExtraInfo = nac.mLegacyExtraInfo;
         }
     }
@@ -290,7 +315,6 @@
          * and reduce idle traffic on networks that are known to be IPv6-only without a NAT64.
          *
          * @return this builder, to facilitate chaining.
-         * @hide
          */
         @NonNull
         public Builder disableNat64Detection() {
@@ -303,7 +327,6 @@
          * perform its own carrier-specific provisioning procedure.
          *
          * @return this builder, to facilitate chaining.
-         * @hide
          */
         @NonNull
         public Builder disableProvisioningNotification() {
@@ -324,6 +347,18 @@
         }
 
         /**
+         * Sets the legacy sub-type for this network.
+         *
+         * @param legacySubType the type
+         * @return this builder, to facilitate chaining.
+         */
+        @NonNull
+        public Builder setLegacySubType(final int legacySubType) {
+            mConfig.legacySubType = legacySubType;
+            return this;
+        }
+
+        /**
          * Sets the name of the legacy type of the agent. It's a free-form string used in logging.
          * @param legacyTypeName the name
          * @return this builder, to facilitate chaining.
@@ -335,10 +370,20 @@
         }
 
         /**
+         * Sets the name of the legacy Sub-type of the agent. It's a free-form string.
+         * @param legacySubTypeName the name
+         * @return this builder, to facilitate chaining.
+         */
+        @NonNull
+        public Builder setLegacySubTypeName(@NonNull String legacySubTypeName) {
+            mConfig.legacySubTypeName = legacySubTypeName;
+            return this;
+        }
+
+        /**
          * Sets the legacy extra info of the agent.
          * @param legacyExtraInfo the legacy extra info.
          * @return this builder, to facilitate chaining.
-         * @hide
          */
         @NonNull
         public Builder setLegacyExtraInfo(@NonNull String legacyExtraInfo) {
@@ -347,6 +392,19 @@
         }
 
         /**
+         * Sets whether the apps can bypass the VPN connection.
+         *
+         * @return this builder, to facilitate chaining.
+         * @hide
+         */
+        @NonNull
+        @SystemApi(client = MODULE_LIBRARIES)
+        public Builder setBypassableVpn(boolean allowBypass) {
+            mConfig.allowBypass = allowBypass;
+            return this;
+        }
+
+        /**
          * Returns the constructed {@link NetworkAgentConfig} object.
          */
         @NonNull
@@ -412,6 +470,8 @@
         out.writeInt(skip464xlat ? 1 : 0);
         out.writeInt(legacyType);
         out.writeString(legacyTypeName);
+        out.writeInt(legacySubType);
+        out.writeString(legacySubTypeName);
         out.writeString(mLegacyExtraInfo);
     }
 
@@ -429,6 +489,8 @@
             networkAgentConfig.skip464xlat = in.readInt() != 0;
             networkAgentConfig.legacyType = in.readInt();
             networkAgentConfig.legacyTypeName = in.readString();
+            networkAgentConfig.legacySubType = in.readInt();
+            networkAgentConfig.legacySubTypeName = in.readString();
             networkAgentConfig.mLegacyExtraInfo = in.readString();
             return networkAgentConfig;
         }
diff --git a/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java b/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java
index 1466629..4f95ccc 100644
--- a/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java
@@ -19,6 +19,7 @@
 import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE;
 
 import android.annotation.IntDef;
+import android.annotation.LongDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
@@ -34,7 +35,6 @@
 import android.text.TextUtils;
 import android.util.ArraySet;
 import android.util.Range;
-import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.net.module.util.CollectionUtils;
@@ -64,6 +64,68 @@
 public final class NetworkCapabilities implements Parcelable {
     private static final String TAG = "NetworkCapabilities";
 
+    /**
+     * Mechanism to support redaction of fields in NetworkCapabilities that are guarded by specific
+     * app permissions.
+     **/
+    /**
+     * Don't redact any fields since the receiving app holds all the necessary permissions.
+     *
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public static final long REDACT_NONE = 0;
+
+    /**
+     * Redact any fields that need {@link android.Manifest.permission#ACCESS_FINE_LOCATION}
+     * permission since the receiving app does not hold this permission or the location toggle
+     * is off.
+     *
+     * @see android.Manifest.permission#ACCESS_FINE_LOCATION
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public static final long REDACT_FOR_ACCESS_FINE_LOCATION = 1 << 0;
+
+    /**
+     * Redact any fields that need {@link android.Manifest.permission#LOCAL_MAC_ADDRESS}
+     * permission since the receiving app does not hold this permission.
+     *
+     * @see android.Manifest.permission#LOCAL_MAC_ADDRESS
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public static final long REDACT_FOR_LOCAL_MAC_ADDRESS = 1 << 1;
+
+    /**
+     *
+     * Redact any fields that need {@link android.Manifest.permission#NETWORK_SETTINGS}
+     * permission since the receiving app does not hold this permission.
+     *
+     * @see android.Manifest.permission#NETWORK_SETTINGS
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public static final long REDACT_FOR_NETWORK_SETTINGS = 1 << 2;
+
+    /**
+     * Redact all fields in this object that require any relevant permission.
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public static final long REDACT_ALL = -1L;
+
+    /** @hide */
+    @LongDef(flag = true, prefix = { "REDACT_" }, value = {
+            REDACT_NONE,
+            REDACT_FOR_ACCESS_FINE_LOCATION,
+            REDACT_FOR_LOCAL_MAC_ADDRESS,
+            REDACT_FOR_NETWORK_SETTINGS,
+            REDACT_ALL
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface RedactionType {}
+
     // Set to true when private DNS is broken.
     private boolean mPrivateDnsBroken;
 
@@ -78,32 +140,31 @@
     private String mRequestorPackageName;
 
     /**
-     * Indicates whether parceling should preserve fields that are set based on permissions of
-     * the process receiving the {@link NetworkCapabilities}.
+     * Indicates what fields should be redacted from this instance.
      */
-    private final boolean mParcelLocationSensitiveFields;
+    private final @RedactionType long mRedactions;
 
     public NetworkCapabilities() {
-        mParcelLocationSensitiveFields = false;
+        mRedactions = REDACT_ALL;
         clearAll();
         mNetworkCapabilities = DEFAULT_CAPABILITIES;
     }
 
     public NetworkCapabilities(NetworkCapabilities nc) {
-        this(nc, false /* parcelLocationSensitiveFields */);
+        this(nc, REDACT_ALL);
     }
 
     /**
      * Make a copy of NetworkCapabilities.
      *
      * @param nc Original NetworkCapabilities
-     * @param parcelLocationSensitiveFields Whether to parcel location sensitive data or not.
+     * @param redactions bitmask of redactions that needs to be performed on this new instance of
+     *                   {@link NetworkCapabilities}.
      * @hide
      */
-    @SystemApi
-    public NetworkCapabilities(
-            @Nullable NetworkCapabilities nc, boolean parcelLocationSensitiveFields) {
-        mParcelLocationSensitiveFields = parcelLocationSensitiveFields;
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public NetworkCapabilities(@Nullable NetworkCapabilities nc, @RedactionType long redactions) {
+        mRedactions = redactions;
         if (nc != null) {
             set(nc);
         }
@@ -115,11 +176,13 @@
      * @hide
      */
     public void clearAll() {
-        // Ensures that the internal copies maintained by the connectivity stack does not set
-        // this bit.
-        if (mParcelLocationSensitiveFields) {
+        // Ensures that the internal copies maintained by the connectivity stack does not set it to
+        // anything other than |REDACT_ALL|.
+        if (mRedactions != REDACT_ALL) {
+            // This is needed because the current redaction mechanism relies on redaction while
+            // parceling.
             throw new UnsupportedOperationException(
-                    "Cannot clear NetworkCapabilities when parcelLocationSensitiveFields is set");
+                    "Cannot clear NetworkCapabilities when mRedactions is set");
         }
         mNetworkCapabilities = mTransportTypes = mUnwantedNetworkCapabilities = 0;
         mLinkUpBandwidthKbps = mLinkDownBandwidthKbps = LINK_BANDWIDTH_UNSPECIFIED;
@@ -149,7 +212,7 @@
         mLinkDownBandwidthKbps = nc.mLinkDownBandwidthKbps;
         mNetworkSpecifier = nc.mNetworkSpecifier;
         if (nc.getTransportInfo() != null) {
-            setTransportInfo(nc.getTransportInfo().makeCopy(mParcelLocationSensitiveFields));
+            setTransportInfo(nc.getTransportInfo().makeCopy(mRedactions));
         } else {
             setTransportInfo(null);
         }
@@ -210,6 +273,9 @@
             NET_CAPABILITY_VEHICLE_INTERNAL,
             NET_CAPABILITY_NOT_VCN_MANAGED,
             NET_CAPABILITY_ENTERPRISE,
+            NET_CAPABILITY_VSIM,
+            NET_CAPABILITY_BIP,
+            NET_CAPABILITY_HEAD_UNIT,
     })
     public @interface NetCapability { }
 
@@ -429,8 +495,27 @@
      */
     public static final int NET_CAPABILITY_ENTERPRISE = 29;
 
+    /**
+     * Indicates that this network has ability to access the carrier's Virtual Sim service.
+     * @hide
+     */
+    @SystemApi
+    public static final int NET_CAPABILITY_VSIM = 30;
+
+    /**
+     * Indicates that this network has ability to support Bearer Independent Protol.
+     * @hide
+     */
+    @SystemApi
+    public static final int NET_CAPABILITY_BIP = 31;
+
+    /**
+     * Indicates that this network is connected to an automotive head unit.
+     */
+    public static final int NET_CAPABILITY_HEAD_UNIT = 32;
+
     private static final int MIN_NET_CAPABILITY = NET_CAPABILITY_MMS;
-    private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_ENTERPRISE;
+    private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_HEAD_UNIT;
 
     /**
      * Network capabilities that are expected to be mutable, i.e., can change while a particular
@@ -448,7 +533,10 @@
             | (1 << NET_CAPABILITY_NOT_SUSPENDED)
             | (1 << NET_CAPABILITY_PARTIAL_CONNECTIVITY)
             | (1 << NET_CAPABILITY_TEMPORARILY_NOT_METERED)
-            | (1 << NET_CAPABILITY_NOT_VCN_MANAGED);
+            | (1 << NET_CAPABILITY_NOT_VCN_MANAGED)
+            // The value of NET_CAPABILITY_HEAD_UNIT is 32, which cannot use int to do bit shift,
+            // otherwise there will be an overflow. Use long to do bit shift instead.
+            | (1L << NET_CAPABILITY_HEAD_UNIT);
 
     /**
      * Network capabilities that are not allowed in NetworkRequests. This exists because the
@@ -474,43 +562,6 @@
             | (1 << NET_CAPABILITY_NOT_VPN);
 
     /**
-     * Capabilities that suggest that a network is restricted.
-     * {@see #maybeMarkCapabilitiesRestricted}, {@see #FORCE_RESTRICTED_CAPABILITIES}
-     */
-    @VisibleForTesting
-    /* package */ static final long RESTRICTED_CAPABILITIES =
-            (1 << NET_CAPABILITY_CBS)
-            | (1 << NET_CAPABILITY_DUN)
-            | (1 << NET_CAPABILITY_EIMS)
-            | (1 << NET_CAPABILITY_FOTA)
-            | (1 << NET_CAPABILITY_IA)
-            | (1 << NET_CAPABILITY_IMS)
-            | (1 << NET_CAPABILITY_MCX)
-            | (1 << NET_CAPABILITY_RCS)
-            | (1 << NET_CAPABILITY_VEHICLE_INTERNAL)
-            | (1 << NET_CAPABILITY_XCAP)
-            | (1 << NET_CAPABILITY_ENTERPRISE);
-
-    /**
-     * Capabilities that force network to be restricted.
-     * {@see #maybeMarkCapabilitiesRestricted}.
-     */
-    private static final long FORCE_RESTRICTED_CAPABILITIES =
-            (1 << NET_CAPABILITY_OEM_PAID)
-            | (1 << NET_CAPABILITY_OEM_PRIVATE);
-
-    /**
-     * Capabilities that suggest that a network is unrestricted.
-     * {@see #maybeMarkCapabilitiesRestricted}.
-     */
-    @VisibleForTesting
-    /* package */ static final long UNRESTRICTED_CAPABILITIES =
-            (1 << NET_CAPABILITY_INTERNET)
-            | (1 << NET_CAPABILITY_MMS)
-            | (1 << NET_CAPABILITY_SUPL)
-            | (1 << NET_CAPABILITY_WIFI_P2P);
-
-    /**
      * Capabilities that are managed by ConnectivityService.
      */
     private static final long CONNECTIVITY_MANAGED_CAPABILITIES =
@@ -575,19 +626,31 @@
     }
 
     /**
-     * Removes (if found) the given capability from this {@code NetworkCapability} instance.
+     * Removes (if found) the given capability from this {@code NetworkCapability}
+     * instance that were added via addCapability(int) or setCapabilities(int[], int[]).
      *
      * @param capability the capability to be removed.
      * @return This NetworkCapabilities instance, to facilitate chaining.
      * @hide
      */
     public @NonNull NetworkCapabilities removeCapability(@NetCapability int capability) {
-        // Note that this method removes capabilities that were added via addCapability(int),
-        // addUnwantedCapability(int) or setCapabilities(int[], int[]).
         checkValidCapability(capability);
         final long mask = ~(1 << capability);
         mNetworkCapabilities &= mask;
-        mUnwantedNetworkCapabilities &= mask;
+        return this;
+    }
+
+    /**
+     * Removes (if found) the given unwanted capability from this {@code NetworkCapability}
+     * instance that were added via addUnwantedCapability(int) or setCapabilities(int[], int[]).
+     *
+     * @param capability the capability to be removed.
+     * @return This NetworkCapabilities instance, to facilitate chaining.
+     * @hide
+     */
+    public @NonNull NetworkCapabilities removeUnwantedCapability(@NetCapability int capability) {
+        checkValidCapability(capability);
+        mUnwantedNetworkCapabilities &= ~(1 << capability);
         return this;
     }
 
@@ -659,6 +722,7 @@
     }
 
     /** @hide */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     public boolean hasUnwantedCapability(@NetCapability int capability) {
         return isValidCapability(capability)
                 && ((mUnwantedNetworkCapabilities & (1 << capability)) != 0);
@@ -672,10 +736,33 @@
         return ((mNetworkCapabilities & CONNECTIVITY_MANAGED_CAPABILITIES) != 0);
     }
 
-    /** Note this method may result in having the same capability in wanted and unwanted lists. */
+    /**
+     * Get the name of the given capability that carriers use.
+     * If the capability does not have a carrier-name, returns null.
+     *
+     * @param capability The capability to get the carrier-name of.
+     * @return The carrier-name of the capability, or null if it doesn't exist.
+     * @hide
+     */
+    @SystemApi
+    public static @Nullable String getCapabilityCarrierName(@NetCapability int capability) {
+        if (capability == NET_CAPABILITY_ENTERPRISE) {
+            return capabilityNameOf(capability);
+        } else {
+            return null;
+        }
+    }
+
     private void combineNetCapabilities(@NonNull NetworkCapabilities nc) {
-        this.mNetworkCapabilities |= nc.mNetworkCapabilities;
-        this.mUnwantedNetworkCapabilities |= nc.mUnwantedNetworkCapabilities;
+        final long wantedCaps = this.mNetworkCapabilities | nc.mNetworkCapabilities;
+        final long unwantedCaps =
+                this.mUnwantedNetworkCapabilities | nc.mUnwantedNetworkCapabilities;
+        if ((wantedCaps & unwantedCaps) != 0) {
+            throw new IllegalArgumentException(
+                    "Cannot have the same capability in wanted and unwanted lists.");
+        }
+        this.mNetworkCapabilities = wantedCaps;
+        this.mUnwantedNetworkCapabilities = unwantedCaps;
     }
 
     /**
@@ -728,37 +815,12 @@
     }
 
     /**
-     * Deduces that all the capabilities it provides are typically provided by restricted networks
-     * or not.
-     *
-     * @return {@code true} if the network should be restricted.
-     * @hide
-     */
-    public boolean deduceRestrictedCapability() {
-        // Check if we have any capability that forces the network to be restricted.
-        final boolean forceRestrictedCapability =
-                (mNetworkCapabilities & FORCE_RESTRICTED_CAPABILITIES) != 0;
-
-        // Verify there aren't any unrestricted capabilities.  If there are we say
-        // the whole thing is unrestricted unless it is forced to be restricted.
-        final boolean hasUnrestrictedCapabilities =
-                (mNetworkCapabilities & UNRESTRICTED_CAPABILITIES) != 0;
-
-        // Must have at least some restricted capabilities.
-        final boolean hasRestrictedCapabilities =
-                (mNetworkCapabilities & RESTRICTED_CAPABILITIES) != 0;
-
-        return forceRestrictedCapability
-                || (hasRestrictedCapabilities && !hasUnrestrictedCapabilities);
-    }
-
-    /**
-     * Removes the NET_CAPABILITY_NOT_RESTRICTED capability if deducing the network is restricted.
+     * Removes the NET_CAPABILITY_NOT_RESTRICTED capability if inferring the network is restricted.
      *
      * @hide
      */
     public void maybeMarkCapabilitiesRestricted() {
-        if (deduceRestrictedCapability()) {
+        if (NetworkCapabilitiesUtils.inferRestrictedCapability(this)) {
             removeCapability(NET_CAPABILITY_NOT_RESTRICTED);
         }
     }
@@ -814,6 +876,7 @@
             TRANSPORT_WIFI_AWARE,
             TRANSPORT_LOWPAN,
             TRANSPORT_TEST,
+            TRANSPORT_USB,
     })
     public @interface Transport { }
 
@@ -860,10 +923,15 @@
     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     public static final int TRANSPORT_TEST = 7;
 
+    /**
+     * Indicates this network uses a USB transport.
+     */
+    public static final int TRANSPORT_USB = 8;
+
     /** @hide */
     public static final int MIN_TRANSPORT = TRANSPORT_CELLULAR;
     /** @hide */
-    public static final int MAX_TRANSPORT = TRANSPORT_TEST;
+    public static final int MAX_TRANSPORT = TRANSPORT_USB;
 
     /** @hide */
     public static boolean isValidTransport(@Transport int transportType) {
@@ -878,7 +946,8 @@
         "VPN",
         "WIFI_AWARE",
         "LOWPAN",
-        "TEST"
+        "TEST",
+        "USB"
     };
 
     /**
@@ -2004,34 +2073,6 @@
         }
     }
 
-    /** @hide */
-    public void dumpDebug(@NonNull ProtoOutputStream proto, long fieldId) {
-        final long token = proto.start(fieldId);
-
-        for (int transport : getTransportTypes()) {
-            proto.write(NetworkCapabilitiesProto.TRANSPORTS, transport);
-        }
-
-        for (int capability : getCapabilities()) {
-            proto.write(NetworkCapabilitiesProto.CAPABILITIES, capability);
-        }
-
-        proto.write(NetworkCapabilitiesProto.LINK_UP_BANDWIDTH_KBPS, mLinkUpBandwidthKbps);
-        proto.write(NetworkCapabilitiesProto.LINK_DOWN_BANDWIDTH_KBPS, mLinkDownBandwidthKbps);
-
-        if (mNetworkSpecifier != null) {
-            proto.write(NetworkCapabilitiesProto.NETWORK_SPECIFIER, mNetworkSpecifier.toString());
-        }
-        if (mTransportInfo != null) {
-            // TODO b/120653863: write transport-specific info to proto?
-        }
-
-        proto.write(NetworkCapabilitiesProto.CAN_REPORT_SIGNAL_STRENGTH, hasSignalStrength());
-        proto.write(NetworkCapabilitiesProto.SIGNAL_STRENGTH, mSignalStrength);
-
-        proto.end(token);
-    }
-
     /**
      * @hide
      */
@@ -2080,6 +2121,9 @@
             case NET_CAPABILITY_VEHICLE_INTERNAL:     return "VEHICLE_INTERNAL";
             case NET_CAPABILITY_NOT_VCN_MANAGED:      return "NOT_VCN_MANAGED";
             case NET_CAPABILITY_ENTERPRISE:           return "ENTERPRISE";
+            case NET_CAPABILITY_VSIM:                 return "VSIM";
+            case NET_CAPABILITY_BIP:                  return "BIP";
+            case NET_CAPABILITY_HEAD_UNIT:            return "HEAD_UNIT";
             default:                                  return Integer.toString(capability);
         }
     }
@@ -2350,6 +2394,23 @@
     }
 
     /**
+     * Returns a bitmask of all the applicable redactions (based on the permissions held by the
+     * receiving app) to be performed on this object.
+     *
+     * @return bitmask of redactions applicable on this instance.
+     * @hide
+     */
+    public @RedactionType long getApplicableRedactions() {
+        // Currently, there are no fields redacted in NetworkCapabilities itself, so we just
+        // passthrough the redactions required by the embedded TransportInfo. If this changes
+        // in the future, modify this method.
+        if (mTransportInfo == null) {
+            return NetworkCapabilities.REDACT_NONE;
+        }
+        return mTransportInfo.getApplicableRedactions();
+    }
+
+    /**
      * Builder class for NetworkCapabilities.
      *
      * This class is mainly for for {@link NetworkAgent} instances to use. Many fields in
diff --git a/packages/Connectivity/framework/src/android/net/NetworkProvider.java b/packages/Connectivity/framework/src/android/net/NetworkProvider.java
index 14cb51c..cfb7325 100644
--- a/packages/Connectivity/framework/src/android/net/NetworkProvider.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkProvider.java
@@ -28,6 +28,11 @@
 import android.os.Messenger;
 import android.util.Log;
 
+import com.android.internal.annotations.GuardedBy;
+
+import java.util.ArrayList;
+import java.util.concurrent.Executor;
+
 /**
  * Base class for network providers such as telephony or Wi-Fi. NetworkProviders connect the device
  * to networks and makes them available to the core network stack by creating
@@ -78,7 +83,9 @@
      */
     @SystemApi
     public NetworkProvider(@NonNull Context context, @NonNull Looper looper, @NonNull String name) {
-        Handler handler = new Handler(looper) {
+        // TODO (b/174636568) : this class should be able to cache an instance of
+        // ConnectivityManager so it doesn't have to fetch it again every time.
+        final Handler handler = new Handler(looper) {
             @Override
             public void handleMessage(Message m) {
                 switch (m.what) {
@@ -159,4 +166,159 @@
     public void declareNetworkRequestUnfulfillable(@NonNull NetworkRequest request) {
         ConnectivityManager.from(mContext).declareNetworkRequestUnfulfillable(request);
     }
+
+    /** @hide */
+    @SystemApi
+    public interface NetworkOfferCallback {
+        /**
+         * Called by the system when a network for this offer is needed to satisfy some
+         * networking request.
+         */
+        void onNetworkNeeded(@NonNull NetworkRequest request);
+        /**
+         * Called by the system when this offer is no longer valuable for this request.
+         */
+        void onNetworkUnneeded(@NonNull NetworkRequest request);
+    }
+
+    private class NetworkOfferCallbackProxy extends INetworkOfferCallback.Stub {
+        @NonNull public final NetworkOfferCallback callback;
+        @NonNull private final Executor mExecutor;
+
+        NetworkOfferCallbackProxy(@NonNull final NetworkOfferCallback callback,
+                @NonNull final Executor executor) {
+            this.callback = callback;
+            this.mExecutor = executor;
+        }
+
+        @Override
+        public void onNetworkNeeded(final @NonNull NetworkRequest request) {
+            mExecutor.execute(() -> callback.onNetworkNeeded(request));
+        }
+
+        @Override
+        public void onNetworkUnneeded(final @NonNull NetworkRequest request) {
+            mExecutor.execute(() -> callback.onNetworkUnneeded(request));
+        }
+    }
+
+    @GuardedBy("mProxies")
+    @NonNull private final ArrayList<NetworkOfferCallbackProxy> mProxies = new ArrayList<>();
+
+    // Returns the proxy associated with this callback, or null if none.
+    @Nullable
+    private NetworkOfferCallbackProxy findProxyForCallback(@NonNull final NetworkOfferCallback cb) {
+        synchronized (mProxies) {
+            for (final NetworkOfferCallbackProxy p : mProxies) {
+                if (p.callback == cb) return p;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Register or update an offer for network with the passed capabilities and score.
+     *
+     * A NetworkProvider's role is to provide networks. This method is how a provider tells the
+     * connectivity stack what kind of network it may provide. The score and caps arguments act
+     * as filters that the connectivity stack uses to tell when the offer is valuable. When an
+     * offer might be preferred over existing networks, the provider will receive a call to
+     * the associated callback's {@link NetworkOfferCallback#onNetworkNeeded} method. The provider
+     * should then try to bring up this network. When an offer is no longer useful, the stack
+     * will inform the provider by calling {@link NetworkOfferCallback#onNetworkUnneeded}. The
+     * provider should stop trying to bring up such a network, or disconnect it if it already has
+     * one.
+     *
+     * The stack determines what offers are valuable according to what networks are currently
+     * available to the system, and what networking requests are made by applications. If an
+     * offer looks like it could connect a better network than any existing network for any
+     * particular request, that's when the stack decides the network is needed. If the current
+     * networking requests are all satisfied by networks that this offer couldn't possibly be a
+     * better match for, that's when the offer is no longer valuable. An offer starts out as
+     * unneeded ; the provider should not try to bring up the network until
+     * {@link NetworkOfferCallback#onNetworkNeeded} is called.
+     *
+     * Note that the offers are non-binding to the providers, in particular because providers
+     * often don't know if they will be able to bring up such a network at any given time. For
+     * example, no wireless network may be in range when the offer would be valuable. This is fine
+     * and expected ; the provider should simply continue to try to bring up the network and do so
+     * if/when it becomes possible. In the mean time, the stack will continue to satisfy requests
+     * with the best network currently available, or if none, keep the apps informed that no
+     * network can currently satisfy this request. When/if the provider can bring up the network,
+     * the connectivity stack will match it against requests, and inform interested apps of the
+     * availability of this network. This may, in turn, render the offer of some other provider
+     * low-value if all requests it used to satisfy are now better served by this network.
+     *
+     * A network can become unneeded for a reason like the above : whether the provider managed
+     * to bring up the offered network after it became needed or not, some other provider may
+     * bring up a better network than this one, making this network unneeded. A network may also
+     * become unneeded if the application making the request withdrew it (for example, after it
+     * is done transferring data, or if the user canceled an operation).
+     *
+     * The capabilities and score act as filters as to what requests the provider will see.
+     * They are not promises, but for best performance, the providers should strive to put
+     * as much known information as possible in the offer. For the score, it should put as
+     * strong a score as the networks will have, since this will filter what requests the
+     * provider sees – it's not a promise, it only serves to avoid sending requests that
+     * the provider can't ever hope to satisfy better than any current network. For capabilities,
+     * it should put all NetworkAgent-managed capabilities a network may have, even if it doesn't
+     * have them at first. This applies to INTERNET, for example ; if a provider thinks the
+     * network it can bring up for this offer may offer Internet access it should include the
+     * INTERNET bit. It's fine if the brought up network ends up not actually having INTERNET.
+     *
+     * TODO : in the future, to avoid possible infinite loops, there should be constraints on
+     * what can be put in capabilities of networks brought up for an offer. If a provider might
+     * bring up a network with or without INTERNET, then it should file two offers : this will
+     * let it know precisely what networks are needed, so it can avoid bringing up networks that
+     * won't actually satisfy requests and remove the risk for bring-up-bring-down loops.
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
+    public void registerNetworkOffer(@NonNull final NetworkScore score,
+            @NonNull final NetworkCapabilities caps, @NonNull final Executor executor,
+            @NonNull final NetworkOfferCallback callback) {
+        // Can't offer a network with a provider that is not yet registered or already unregistered.
+        final int providerId = mProviderId;
+        if (providerId == ID_NONE) return;
+        NetworkOfferCallbackProxy proxy = null;
+        synchronized (mProxies) {
+            for (final NetworkOfferCallbackProxy existingProxy : mProxies) {
+                if (existingProxy.callback == callback) {
+                    proxy = existingProxy;
+                    break;
+                }
+            }
+            if (null == proxy) {
+                proxy = new NetworkOfferCallbackProxy(callback, executor);
+                mProxies.add(proxy);
+            }
+        }
+        mContext.getSystemService(ConnectivityManager.class)
+                .offerNetwork(providerId, score, caps, proxy);
+    }
+
+    /**
+     * Withdraw a network offer previously made to the networking stack.
+     *
+     * If a provider can no longer provide a network they offered, it should call this method.
+     * An example of usage could be if the hardware necessary to bring up the network was turned
+     * off in UI by the user. Note that because offers are never binding, the provider might
+     * alternatively decide not to withdraw this offer and simply refuse to bring up the network
+     * even when it's needed. However, withdrawing the request is slightly more resource-efficient
+     * because the networking stack won't have to compare this offer to exiting networks to see
+     * if it could beat any of them, and may be advantageous to the provider's implementation that
+     * can rely on no longer receiving callbacks for a network that they can't bring up anyways.
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
+    public void unregisterNetworkOffer(final @NonNull NetworkOfferCallback callback) {
+        final NetworkOfferCallbackProxy proxy = findProxyForCallback(callback);
+        if (null == proxy) return;
+        mProxies.remove(proxy);
+        mContext.getSystemService(ConnectivityManager.class).unofferNetwork(proxy);
+    }
 }
diff --git a/packages/Connectivity/framework/src/android/net/NetworkRequest.java b/packages/Connectivity/framework/src/android/net/NetworkRequest.java
index cf131f0..5313f08 100644
--- a/packages/Connectivity/framework/src/android/net/NetworkRequest.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkRequest.java
@@ -47,7 +47,6 @@
 import android.os.Process;
 import android.text.TextUtils;
 import android.util.Range;
-import android.util.proto.ProtoOutputStream;
 
 import java.util.Arrays;
 import java.util.List;
@@ -216,6 +215,14 @@
         }
 
         /**
+         * Creates a new Builder of NetworkRequest from an existing instance.
+         */
+        public Builder(@NonNull final NetworkRequest request) {
+            Objects.requireNonNull(request);
+            mNetworkCapabilities = request.networkCapabilities;
+        }
+
+        /**
          * Build {@link NetworkRequest} give the current set of capabilities.
          */
         public NetworkRequest build() {
@@ -305,12 +312,31 @@
          *
          * @hide
          */
+        @NonNull
+        @SuppressLint("MissingGetterMatchingBuilder")
+        @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
         public Builder addUnwantedCapability(@NetworkCapabilities.NetCapability int capability) {
             mNetworkCapabilities.addUnwantedCapability(capability);
             return this;
         }
 
         /**
+         * Removes (if found) the given unwanted capability from this builder instance.
+         *
+         * @param capability The unwanted capability to remove.
+         * @return The builder to facilitate chaining.
+         *
+         * @hide
+         */
+        @NonNull
+        @SuppressLint("BuilderSetStyle")
+        @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+        public Builder removeUnwantedCapability(@NetworkCapabilities.NetCapability int capability) {
+            mNetworkCapabilities.removeUnwantedCapability(capability);
+            return this;
+        }
+
+        /**
          * Completely clears all the {@code NetworkCapabilities} from this builder instance,
          * removing even the capabilities that are set by default when the object is constructed.
          *
@@ -567,6 +593,7 @@
      *
      * @hide
      */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     public boolean hasUnwantedCapability(@NetCapability int capability) {
         return networkCapabilities.hasUnwantedCapability(capability);
     }
@@ -647,18 +674,6 @@
         }
     }
 
-    /** @hide */
-    public void dumpDebug(ProtoOutputStream proto, long fieldId) {
-        final long token = proto.start(fieldId);
-
-        proto.write(NetworkRequestProto.TYPE, typeToProtoEnum(type));
-        proto.write(NetworkRequestProto.REQUEST_ID, requestId);
-        proto.write(NetworkRequestProto.LEGACY_TYPE, legacyType);
-        networkCapabilities.dumpDebug(proto, NetworkRequestProto.NETWORK_CAPABILITIES);
-
-        proto.end(token);
-    }
-
     public boolean equals(@Nullable Object obj) {
         if (obj instanceof NetworkRequest == false) return false;
         NetworkRequest that = (NetworkRequest)obj;
@@ -671,4 +686,43 @@
     public int hashCode() {
         return Objects.hash(requestId, legacyType, networkCapabilities, type);
     }
+
+    /**
+     * Gets all the capabilities set on this {@code NetworkRequest} instance.
+     *
+     * @return an array of capability values for this instance.
+     */
+    @NonNull
+    public @NetCapability int[] getCapabilities() {
+        // No need to make a defensive copy here as NC#getCapabilities() already returns
+        // a new array.
+        return networkCapabilities.getCapabilities();
+    }
+
+    /**
+     * Gets all the unwanted capabilities set on this {@code NetworkRequest} instance.
+     *
+     * @return an array of unwanted capability values for this instance.
+     *
+     * @hide
+     */
+    @NonNull
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public @NetCapability int[] getUnwantedCapabilities() {
+        // No need to make a defensive copy here as NC#getUnwantedCapabilities() already returns
+        // a new array.
+        return networkCapabilities.getUnwantedCapabilities();
+    }
+
+    /**
+     * Gets all the transports set on this {@code NetworkRequest} instance.
+     *
+     * @return an array of transport type values for this instance.
+     */
+    @NonNull
+    public @Transport int[] getTransportTypes() {
+        // No need to make a defensive copy here as NC#getTransportTypes() already returns
+        // a new array.
+        return networkCapabilities.getTransportTypes();
+    }
 }
diff --git a/packages/Connectivity/framework/src/android/net/NetworkScore.java b/packages/Connectivity/framework/src/android/net/NetworkScore.java
index eadcb2d..9786b09 100644
--- a/packages/Connectivity/framework/src/android/net/NetworkScore.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkScore.java
@@ -16,12 +16,17 @@
 
 package android.net;
 
+import android.annotation.IntDef;
 import android.annotation.NonNull;
+import android.annotation.SystemApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 
 import com.android.internal.annotations.VisibleForTesting;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * Object representing the quality of a network as perceived by the user.
  *
@@ -29,12 +34,23 @@
  * network is considered for a particular use.
  * @hide
  */
-// TODO : @SystemApi when the implementation is complete
+@SystemApi
 public final class NetworkScore implements Parcelable {
     // This will be removed soon. Do *NOT* depend on it for any new code that is not part of
     // a migration.
     private final int mLegacyInt;
 
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(value = {
+            KEEP_CONNECTED_NONE,
+            KEEP_CONNECTED_FOR_HANDOVER
+    })
+    public @interface KeepConnectedReason { }
+
+    public static final int KEEP_CONNECTED_NONE = 0;
+    public static final int KEEP_CONNECTED_FOR_HANDOVER = 1;
+
     // Agent-managed policies
     // TODO : add them here, starting from 1
     /** @hide */
@@ -45,15 +61,20 @@
     // Bitmask of all the policies applied to this score.
     private final long mPolicies;
 
+    private final int mKeepConnectedReason;
+
     /** @hide */
-    NetworkScore(final int legacyInt, final long policies) {
+    NetworkScore(final int legacyInt, final long policies,
+            @KeepConnectedReason final int keepConnectedReason) {
         mLegacyInt = legacyInt;
         mPolicies = policies;
+        mKeepConnectedReason = keepConnectedReason;
     }
 
     private NetworkScore(@NonNull final Parcel in) {
         mLegacyInt = in.readInt();
         mPolicies = in.readLong();
+        mKeepConnectedReason = in.readInt();
     }
 
     public int getLegacyInt() {
@@ -61,7 +82,16 @@
     }
 
     /**
+     * Returns the keep-connected reason, or KEEP_CONNECTED_NONE.
+     */
+    public int getKeepConnectedReason() {
+        return mKeepConnectedReason;
+    }
+
+    /**
      * @return whether this score has a particular policy.
+     *
+     * @hide
      */
     @VisibleForTesting
     public boolean hasPolicy(final int policy) {
@@ -77,6 +107,7 @@
     public void writeToParcel(@NonNull final Parcel dest, final int flags) {
         dest.writeInt(mLegacyInt);
         dest.writeLong(mPolicies);
+        dest.writeInt(mKeepConnectedReason);
     }
 
     @Override
@@ -105,6 +136,7 @@
         private static final long POLICY_NONE = 0L;
         private static final int INVALID_LEGACY_INT = Integer.MIN_VALUE;
         private int mLegacyInt = INVALID_LEGACY_INT;
+        private int mKeepConnectedReason = KEEP_CONNECTED_NONE;
 
         /**
          * Sets the legacy int for this score.
@@ -121,12 +153,23 @@
         }
 
         /**
+         * Set the keep-connected reason.
+         *
+         * This can be reset by calling it again with {@link KEEP_CONNECTED_NONE}.
+         */
+        @NonNull
+        public Builder setKeepConnectedReason(@KeepConnectedReason final int reason) {
+            mKeepConnectedReason = reason;
+            return this;
+        }
+
+        /**
          * Builds this NetworkScore.
          * @return The built NetworkScore object.
          */
         @NonNull
         public NetworkScore build() {
-            return new NetworkScore(mLegacyInt, POLICY_NONE);
+            return new NetworkScore(mLegacyInt, POLICY_NONE, mKeepConnectedReason);
         }
     }
 }
diff --git a/packages/Connectivity/framework/src/android/net/NetworkUtils.java b/packages/Connectivity/framework/src/android/net/NetworkUtils.java
index c0f2628..2679b62 100644
--- a/packages/Connectivity/framework/src/android/net/NetworkUtils.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkUtils.java
@@ -16,6 +16,8 @@
 
 package android.net;
 
+import static android.net.ConnectivityManager.NETID_UNSET;
+
 import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Build;
 import android.system.ErrnoException;
@@ -40,6 +42,9 @@
  * {@hide}
  */
 public class NetworkUtils {
+    static {
+        System.loadLibrary("framework-connectivity-jni");
+    }
 
     private static final String TAG = "NetworkUtils";
 
@@ -55,6 +60,8 @@
      */
     public static native void detachBPFFilter(FileDescriptor fd) throws SocketException;
 
+    private static native boolean bindProcessToNetworkHandle(long netHandle);
+
     /**
      * Binds the current process to the network designated by {@code netId}.  All sockets created
      * in the future (and not explicitly bound via a bound {@link SocketFactory} (see
@@ -63,13 +70,20 @@
      * is by design so an application doesn't accidentally use sockets it thinks are still bound to
      * a particular {@code Network}.  Passing NETID_UNSET clears the binding.
      */
-    public native static boolean bindProcessToNetwork(int netId);
+    public static boolean bindProcessToNetwork(int netId) {
+        return bindProcessToNetworkHandle(new Network(netId).getNetworkHandle());
+    }
+
+    private static native long getBoundNetworkHandleForProcess();
 
     /**
      * Return the netId last passed to {@link #bindProcessToNetwork}, or NETID_UNSET if
      * {@link #unbindProcessToNetwork} has been called since {@link #bindProcessToNetwork}.
      */
-    public native static int getBoundNetworkForProcess();
+    public static int getBoundNetworkForProcess() {
+        final long netHandle = getBoundNetworkHandleForProcess();
+        return netHandle == 0L ? NETID_UNSET : Network.fromNetworkHandle(netHandle).getNetId();
+    }
 
     /**
      * Binds host resolutions performed by this process to the network designated by {@code netId}.
@@ -81,18 +95,28 @@
     @Deprecated
     public native static boolean bindProcessToNetworkForHostResolution(int netId);
 
+    private static native int bindSocketToNetworkHandle(FileDescriptor fd, long netHandle);
+
     /**
      * Explicitly binds {@code fd} to the network designated by {@code netId}.  This
      * overrides any binding via {@link #bindProcessToNetwork}.
      * @return 0 on success or negative errno on failure.
      */
-    public static native int bindSocketToNetwork(FileDescriptor fd, int netId);
+    public static int bindSocketToNetwork(FileDescriptor fd, int netId) {
+        return bindSocketToNetworkHandle(fd, new Network(netId).getNetworkHandle());
+    }
 
     /**
      * Determine if {@code uid} can access network designated by {@code netId}.
      * @return {@code true} if {@code uid} can access network, {@code false} otherwise.
      */
-    public native static boolean queryUserAccess(int uid, int netId);
+    public static boolean queryUserAccess(int uid, int netId) {
+        // TODO (b/183485986): remove this method
+        return false;
+    }
+
+    private static native FileDescriptor resNetworkSend(
+            long netHandle, byte[] msg, int msglen, int flags) throws ErrnoException;
 
     /**
      * DNS resolver series jni method.
@@ -100,8 +124,13 @@
      * {@code flags} is an additional config to control actual querying behavior.
      * @return a file descriptor to watch for read events
      */
-    public static native FileDescriptor resNetworkSend(
-            int netId, byte[] msg, int msglen, int flags) throws ErrnoException;
+    public static FileDescriptor resNetworkSend(
+            int netId, byte[] msg, int msglen, int flags) throws ErrnoException {
+        return resNetworkSend(new Network(netId).getNetworkHandle(), msg, msglen, flags);
+    }
+
+    private static native FileDescriptor resNetworkQuery(
+            long netHandle, String dname, int nsClass, int nsType, int flags) throws ErrnoException;
 
     /**
      * DNS resolver series jni method.
@@ -110,8 +139,11 @@
      * {@code flags} is an additional config to control actual querying behavior.
      * @return a file descriptor to watch for read events
      */
-    public static native FileDescriptor resNetworkQuery(
-            int netId, String dname, int nsClass, int nsType, int flags) throws ErrnoException;
+    public static FileDescriptor resNetworkQuery(
+            int netId, String dname, int nsClass, int nsType, int flags) throws ErrnoException {
+        return resNetworkQuery(new Network(netId).getNetworkHandle(), dname, nsClass, nsType,
+                flags);
+    }
 
     /**
      * DNS resolver series jni method.
@@ -323,22 +355,7 @@
      */
     @UnsupportedAppUsage
     public static String trimV4AddrZeros(String addr) {
-        if (addr == null) return null;
-        String[] octets = addr.split("\\.");
-        if (octets.length != 4) return addr;
-        StringBuilder builder = new StringBuilder(16);
-        String result = null;
-        for (int i = 0; i < 4; i++) {
-            try {
-                if (octets[i].length() > 3) return addr;
-                builder.append(Integer.parseInt(octets[i]));
-            } catch (NumberFormatException e) {
-                return addr;
-            }
-            if (i < 3) builder.append('.');
-        }
-        result = builder.toString();
-        return result;
+        return Inet4AddressUtils.trimAddressZeros(addr);
     }
 
     /**
diff --git a/packages/Connectivity/framework/src/android/net/QosCallbackConnection.java b/packages/Connectivity/framework/src/android/net/QosCallbackConnection.java
index bdb4ad6..de0fc24 100644
--- a/packages/Connectivity/framework/src/android/net/QosCallbackConnection.java
+++ b/packages/Connectivity/framework/src/android/net/QosCallbackConnection.java
@@ -19,6 +19,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.telephony.data.EpsBearerQosSessionAttributes;
+import android.telephony.data.NrQosSessionAttributes;
 
 import com.android.internal.annotations.VisibleForTesting;
 
@@ -84,6 +85,25 @@
     }
 
     /**
+     * Called when either the {@link NrQosSessionAttributes} has changed or on the first time
+     * the attributes have become available.
+     *
+     * @param session the session that is now available
+     * @param attributes the corresponding attributes of session
+     */
+    @Override
+    public void onNrQosSessionAvailable(@NonNull final QosSession session,
+            @NonNull final NrQosSessionAttributes attributes) {
+
+        mExecutor.execute(() -> {
+            final QosCallback callback = mCallback;
+            if (callback != null) {
+                callback.onQosSessionAvailable(session, attributes);
+            }
+        });
+    }
+
+    /**
      * Called when the session is lost.
      *
      * @param session the session that was lost
diff --git a/packages/Connectivity/framework/src/android/net/QosSession.java b/packages/Connectivity/framework/src/android/net/QosSession.java
index 4f3bb77..93f2ff2 100644
--- a/packages/Connectivity/framework/src/android/net/QosSession.java
+++ b/packages/Connectivity/framework/src/android/net/QosSession.java
@@ -36,6 +36,11 @@
      */
     public static final int TYPE_EPS_BEARER = 1;
 
+    /**
+     * The {@link QosSession} is a NR Session.
+     */
+    public static final int TYPE_NR_BEARER = 2;
+
     private final int mSessionId;
 
     private final int mSessionType;
@@ -100,6 +105,7 @@
      */
     @IntDef(value = {
             TYPE_EPS_BEARER,
+            TYPE_NR_BEARER,
     })
     @interface QosSessionType {}
 
diff --git a/packages/Connectivity/framework/src/android/net/SocketKeepalive.java b/packages/Connectivity/framework/src/android/net/SocketKeepalive.java
index d007a95..f6cae72 100644
--- a/packages/Connectivity/framework/src/android/net/SocketKeepalive.java
+++ b/packages/Connectivity/framework/src/android/net/SocketKeepalive.java
@@ -55,36 +55,68 @@
     static final String TAG = "SocketKeepalive";
 
     /**
-     * No errors.
+     * Success. It indicates there is no error.
      * @hide
      */
     @SystemApi
     public static final int SUCCESS = 0;
 
-    /** @hide */
+    /**
+     * No keepalive. This should only be internally as it indicates There is no keepalive.
+     * It should not propagate to applications.
+     * @hide
+     */
     public static final int NO_KEEPALIVE = -1;
 
-    /** @hide */
+    /**
+     * Data received.
+     * @hide
+     */
     public static final int DATA_RECEIVED = -2;
 
-    /** @hide */
+    /**
+     * The binder died.
+     * @hide
+     */
     public static final int BINDER_DIED = -10;
 
-    /** The specified {@code Network} is not connected. */
+    /**
+     * The invalid network. It indicates the specified {@code Network} is not connected.
+     */
     public static final int ERROR_INVALID_NETWORK = -20;
-    /** The specified IP addresses are invalid. For example, the specified source IP address is
-     * not configured on the specified {@code Network}. */
+
+    /**
+     * The invalid IP addresses. Indicates the specified IP addresses are invalid.
+     * For example, the specified source IP address is not configured on the
+     * specified {@code Network}.
+     */
     public static final int ERROR_INVALID_IP_ADDRESS = -21;
-    /** The requested port is invalid. */
+
+    /**
+     * The port is invalid.
+     */
     public static final int ERROR_INVALID_PORT = -22;
-    /** The packet length is invalid (e.g., too long). */
+
+    /**
+     * The length is invalid (e.g. too long).
+     */
     public static final int ERROR_INVALID_LENGTH = -23;
-    /** The packet transmission interval is invalid (e.g., too short). */
+
+    /**
+     * The interval is invalid (e.g. too short).
+     */
     public static final int ERROR_INVALID_INTERVAL = -24;
-    /** The target socket is invalid. */
+
+    /**
+     * The socket is invalid.
+     */
     public static final int ERROR_INVALID_SOCKET = -25;
-    /** The target socket is not idle. */
+
+    /**
+     * The socket is not idle.
+     */
     public static final int ERROR_SOCKET_NOT_IDLE = -26;
+
     /**
      * The stop reason is uninitialized. This should only be internally used as initial state
      * of stop reason, instead of propagating to application.
@@ -92,15 +124,29 @@
      */
     public static final int ERROR_STOP_REASON_UNINITIALIZED = -27;
 
-    /** The device does not support this request. */
+    /**
+     * The request is unsupported.
+     */
     public static final int ERROR_UNSUPPORTED = -30;
-    /** @hide TODO: delete when telephony code has been updated. */
-    public static final int ERROR_HARDWARE_UNSUPPORTED = ERROR_UNSUPPORTED;
-    /** The hardware returned an error. */
+
+    /**
+     * There was a hardware error.
+     */
     public static final int ERROR_HARDWARE_ERROR = -31;
-    /** The limitation of resource is reached. */
+
+    /**
+     * Resources are insufficient (e.g. all hardware slots are in use).
+     */
     public static final int ERROR_INSUFFICIENT_RESOURCES = -32;
 
+    /**
+     * There was no such slot. This should only be internally as it indicates
+     * a programming error in the system server. It should not propagate to
+     * applications.
+     * @hide
+     */
+    @SystemApi
+    public static final int ERROR_NO_SUCH_SLOT = -33;
 
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
@@ -111,7 +157,8 @@
             ERROR_INVALID_LENGTH,
             ERROR_INVALID_INTERVAL,
             ERROR_INVALID_SOCKET,
-            ERROR_SOCKET_NOT_IDLE
+            ERROR_SOCKET_NOT_IDLE,
+            ERROR_NO_SUCH_SLOT
     })
     public @interface ErrorCode {}
 
@@ -122,7 +169,6 @@
             ERROR_INVALID_LENGTH,
             ERROR_UNSUPPORTED,
             ERROR_INSUFFICIENT_RESOURCES,
-            ERROR_HARDWARE_UNSUPPORTED
     })
     public @interface KeepaliveEvent {}
 
diff --git a/packages/Connectivity/framework/src/android/net/TransportInfo.java b/packages/Connectivity/framework/src/android/net/TransportInfo.java
index aa4bbb0..fa889ea 100644
--- a/packages/Connectivity/framework/src/android/net/TransportInfo.java
+++ b/packages/Connectivity/framework/src/android/net/TransportInfo.java
@@ -29,35 +29,47 @@
 public interface TransportInfo {
 
     /**
-     * Create a copy of a {@link TransportInfo} that will preserve location sensitive fields that
-     * were set based on the permissions of the process that originally received it.
+     * Create a copy of a {@link TransportInfo} with some fields redacted based on the permissions
+     * held by the receiving app.
      *
-     * <p>By default {@link TransportInfo} does not preserve such fields during parceling, as
-     * they should not be shared outside of the process that receives them without appropriate
-     * checks.
+     * <p>
+     * Usage by connectivity stack:
+     * <ul>
+     * <li> Connectivity stack will invoke {@link #getApplicableRedactions()} to find the list
+     * of redactions that are required by this {@link TransportInfo} instance.</li>
+     * <li> Connectivity stack then loops through each bit in the bitmask returned and checks if the
+     * receiving app holds the corresponding permission.
+     * <ul>
+     * <li> If the app holds the corresponding permission, the bit is cleared from the
+     * |redactions| bitmask. </li>
+     * <li> If the app does not hold the corresponding permission, the bit is retained in the
+     * |redactions| bitmask. </li>
+     * </ul>
+     * <li> Connectivity stack then invokes {@link #makeCopy(long)} with the necessary |redactions|
+     * to create a copy to send to the corresponding app. </li>
+     * </ul>
+     * </p>
      *
-     * @param parcelLocationSensitiveFields Whether the location sensitive fields should be kept
-     *                                      when parceling
-     * @return Copy of this instance.
+     * @param redactions bitmask of redactions that needs to be performed on this instance.
+     * @return Copy of this instance with the necessary redactions.
      * @hide
      */
-    @SystemApi
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     @NonNull
-    default TransportInfo makeCopy(boolean parcelLocationSensitiveFields) {
+    default TransportInfo makeCopy(@NetworkCapabilities.RedactionType long redactions) {
         return this;
     }
 
     /**
-     * Returns whether this TransportInfo type has location sensitive fields or not (helps
-     * to determine whether to perform a location permission check or not before sending to
-     * apps).
+     * Returns a bitmask of all the applicable redactions (based on the permissions held by the
+     * receiving app) to be performed on this TransportInfo.
      *
-     * @return {@code true} if this instance contains location sensitive info, {@code false}
-     * otherwise.
+     * @return bitmask of redactions applicable on this instance.
+     * @see #makeCopy(long)
      * @hide
      */
-    @SystemApi
-    default boolean hasLocationSensitiveFields() {
-        return false;
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    default @NetworkCapabilities.RedactionType long getApplicableRedactions() {
+        return NetworkCapabilities.REDACT_NONE;
     }
 }
diff --git a/packages/Connectivity/framework/src/android/net/VpnTransportInfo.java b/packages/Connectivity/framework/src/android/net/VpnTransportInfo.java
index cd8f4c0..ba83a44 100644
--- a/packages/Connectivity/framework/src/android/net/VpnTransportInfo.java
+++ b/packages/Connectivity/framework/src/android/net/VpnTransportInfo.java
@@ -17,11 +17,14 @@
 package android.net;
 
 import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
+import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.text.TextUtils;
 
 import java.util.Objects;
 
@@ -38,8 +41,26 @@
     /** Type of this VPN. */
     public final int type;
 
-    public VpnTransportInfo(int type) {
+    @Nullable
+    public final String sessionId;
+
+    @Override
+    public long getApplicableRedactions() {
+        return REDACT_FOR_NETWORK_SETTINGS;
+    }
+
+    /**
+     * Create a copy of a {@link VpnTransportInfo} with the sessionId redacted if necessary.
+     */
+    @NonNull
+    public VpnTransportInfo makeCopy(long redactions) {
+        return new VpnTransportInfo(type,
+            ((redactions & REDACT_FOR_NETWORK_SETTINGS) != 0) ? null : sessionId);
+    }
+
+    public VpnTransportInfo(int type, @Nullable String sessionId) {
         this.type = type;
+        this.sessionId = sessionId;
     }
 
     @Override
@@ -47,17 +68,17 @@
         if (!(o instanceof VpnTransportInfo)) return false;
 
         VpnTransportInfo that = (VpnTransportInfo) o;
-        return this.type == that.type;
+        return (this.type == that.type) && TextUtils.equals(this.sessionId, that.sessionId);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(type);
+        return Objects.hash(type, sessionId);
     }
 
     @Override
     public String toString() {
-        return String.format("VpnTransportInfo{type=%d}", type);
+        return String.format("VpnTransportInfo{type=%d, sessionId=%s}", type, sessionId);
     }
 
     @Override
@@ -68,12 +89,13 @@
     @Override
     public void writeToParcel(@NonNull Parcel dest, int flags) {
         dest.writeInt(type);
+        dest.writeString(sessionId);
     }
 
     public static final @NonNull Creator<VpnTransportInfo> CREATOR =
             new Creator<VpnTransportInfo>() {
         public VpnTransportInfo createFromParcel(Parcel in) {
-            return new VpnTransportInfo(in.readInt());
+            return new VpnTransportInfo(in.readInt(), in.readString());
         }
         public VpnTransportInfo[] newArray(int size) {
             return new VpnTransportInfo[size];
diff --git a/packages/Connectivity/service/Android.bp b/packages/Connectivity/service/Android.bp
index f630cea..518f198 100644
--- a/packages/Connectivity/service/Android.bp
+++ b/packages/Connectivity/service/Android.bp
@@ -25,7 +25,7 @@
 
 cc_library_shared {
     name: "libservice-connectivity",
-    // TODO: build against the NDK (sdk_version: "30" for example)
+    min_sdk_version: "30",
     cflags: [
         "-Wall",
         "-Werror",
@@ -36,13 +36,13 @@
         "jni/com_android_server_TestNetworkService.cpp",
         "jni/onload.cpp",
     ],
+    stl: "libc++_static",
+    header_libs: [
+        "libbase_headers",
+    ],
     shared_libs: [
-        "libbase",
         "liblog",
         "libnativehelper",
-        // TODO: remove dependency on ifc_[add/del]_address by having Java code to add/delete
-        // addresses, and remove dependency on libnetutils.
-        "libnetutils",
     ],
     apex_available: [
         "com.android.tethering",
@@ -51,39 +51,69 @@
 
 java_library {
     name: "service-connectivity-pre-jarjar",
+    sdk_version: "system_server_current",
+    min_sdk_version: "30",
     srcs: [
-        ":framework-connectivity-shared-srcs",
         ":connectivity-service-srcs",
+        ":framework-connectivity-shared-srcs",
+        ":services-connectivity-shared-srcs",
+        // TODO: move to net-utils-device-common, enable shrink optimization to avoid extra classes
+        ":net-module-utils-srcs",
     ],
     libs: [
-        "android.net.ipsec.ike",
-        "services.core",
-        "services.net",
+        // TODO (b/183097033) remove once system_server_current includes core_current
+        "stable.core.platform.api.stubs",
+        "android_system_server_stubs_current",
+        "framework-annotations-lib",
+        "framework-connectivity.impl",
+        "framework-tethering.stubs.module_lib",
+        "framework-wifi.stubs.module_lib",
         "unsupportedappusage",
         "ServiceConnectivityResources",
     ],
     static_libs: [
+        "dnsresolver_aidl_interface-V8-java",
         "modules-utils-os",
         "net-utils-device-common",
         "net-utils-framework-common",
         "netd-client",
+        "netlink-client",
+        "networkstack-client",
         "PlatformProperties",
+        "service-connectivity-protos",
     ],
     apex_available: [
-        "//apex_available:platform",
+        "com.android.tethering",
+    ],
+}
+
+java_library {
+    name: "service-connectivity-protos",
+    sdk_version: "system_current",
+    min_sdk_version: "30",
+    proto: {
+        type: "nano",
+    },
+    srcs: [
+        ":system-messages-proto-src",
+    ],
+    libs: ["libprotobuf-java-nano"],
+    apex_available: [
         "com.android.tethering",
     ],
 }
 
 java_library {
     name: "service-connectivity",
+    sdk_version: "system_server_current",
+    min_sdk_version: "30",
     installable: true,
     static_libs: [
         "service-connectivity-pre-jarjar",
     ],
     jarjar_rules: "jarjar-rules.txt",
     apex_available: [
-        "//apex_available:platform",
+        "//apex_available:platform", // For arc-services
         "com.android.tethering",
     ],
 }
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/Android.bp b/packages/Connectivity/service/ServiceConnectivityResources/Android.bp
index fa4501a..d783738 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/Android.bp
+++ b/packages/Connectivity/service/ServiceConnectivityResources/Android.bp
@@ -22,6 +22,7 @@
 android_app {
     name: "ServiceConnectivityResources",
     sdk_version: "module_current",
+    min_sdk_version: "30",
     resource_dirs: [
         "res",
     ],
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-af/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-af/strings.xml
index 68720d5..550ab8a 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-af/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-af/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Meld aan by Wi-Fi-netwerk"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Meld by netwerk aan"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> het geen internettoegang nie"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Tik vir opsies"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"Selnetwerk het nie internettoegang nie"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"Netwerk het nie internettoegang nie"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Daar kan nie by private DNS-bediener ingegaan word nie"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> het beperkte konnektiwiteit"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Tik om in elk geval te koppel"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"Het oorgeskakel na <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Toestel gebruik <xliff:g id="NEW_NETWORK">%1$s</xliff:g> wanneer <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> geen internettoegang het nie. Heffings kan geld."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"Het oorgeskakel van <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> na <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"\'n onbekende netwerktipe"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Stelselkonnektiwiteithulpbronne"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Meld aan by Wi-Fi-netwerk"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Meld by netwerk aan"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> het geen internettoegang nie"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Tik vir opsies"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"Selnetwerk het nie internettoegang nie"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"Netwerk het nie internettoegang nie"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Daar kan nie by private DNS-bediener ingegaan word nie"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> het beperkte konnektiwiteit"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Tik om in elk geval te koppel"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"Het oorgeskakel na <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"Toestel gebruik <xliff:g id="NEW_NETWORK">%1$s</xliff:g> wanneer <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> geen internettoegang het nie. Heffings kan geld."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"Het oorgeskakel van <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> na <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"mobiele data"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Ethernet"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"mobiele data"</item>
+    <item msgid="6341719431034774569">"Wi-fi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Ethernet"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"\'n onbekende netwerktipe"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-am/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-am/strings.xml
index 78d9283..7f1a9db 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-am/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-am/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"ወደ Wi-Fi አውታረ መረብ በመለያ ግባ"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"ወደ አውታረ መረብ በመለያ ይግቡ"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ምንም የበይነ መረብ መዳረሻ የለም"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"ለአማራጮች መታ ያድርጉ"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"የተንቀሳቃሽ ስልክ አውታረ መረብ የበይነመረብ መዳረሻ የለውም"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"አውታረ መረብ የበይነመረብ መዳረሻ የለውም"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"የግል ዲኤንኤስ አገልጋይ ሊደረስበት አይችልም"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> የተገደበ ግንኙነት አለው"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"ለማንኛውም ለማገናኘት መታ ያድርጉ"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"ወደ <xliff:g id="NETWORK_TYPE">%1$s</xliff:g> ተቀይሯል"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> ምንም ዓይነት የበይነመረብ ግንኙነት በማይኖረው ጊዜ መሣሪያዎች <xliff:g id="NEW_NETWORK">%1$s</xliff:g>ን ይጠቀማሉ። ክፍያዎች ተፈጻሚ ሊሆኑ ይችላሉ።"</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"ከ<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> ወደ <xliff:g id="NEW_NETWORK">%2$s</xliff:g> ተቀይሯል"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"አንድ ያልታወቀ አውታረ መረብ ዓይነት"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"የስርዓት ግንኙነት መርጃዎች"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"ወደ Wi-Fi አውታረ መረብ በመለያ ግባ"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"ወደ አውታረ መረብ በመለያ ይግቡ"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ምንም የበይነ መረብ መዳረሻ የለም"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"ለአማራጮች መታ ያድርጉ"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"የተንቀሳቃሽ ስልክ አውታረ መረብ የበይነመረብ መዳረሻ የለውም"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"አውታረ መረብ የበይነመረብ መዳረሻ የለውም"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"የግል ዲኤንኤስ አገልጋይ ሊደረስበት አይችልም"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> የተገደበ ግንኙነት አለው"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"ለማንኛውም ለማገናኘት መታ ያድርጉ"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"ወደ <xliff:g id="NETWORK_TYPE">%1$s</xliff:g> ተቀይሯል"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> ምንም ዓይነት የበይነመረብ ግንኙነት በማይኖረው ጊዜ መሣሪያዎች <xliff:g id="NEW_NETWORK">%1$s</xliff:g>ን ይጠቀማሉ። ክፍያዎች ተፈጻሚ ሊሆኑ ይችላሉ።"</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"ከ<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> ወደ <xliff:g id="NEW_NETWORK">%2$s</xliff:g> ተቀይሯል"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"የተንቀሳቃሽ ስልክ ውሂብ"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"ብሉቱዝ"</item>
-    <item msgid="1616528372438698248">"ኤተርኔት"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"የተንቀሳቃሽ ስልክ ውሂብ"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"ብሉቱዝ"</item>
+    <item msgid="1160736166977503463">"ኢተርኔት"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"አንድ ያልታወቀ አውታረ መረብ ዓይነት"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ar/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ar/strings.xml
index 8698a7e..b7a62c5 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ar/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ar/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"‏تسجيل الدخول إلى شبكة Wi-Fi"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"تسجيل الدخول إلى الشبكة"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"لا يتوفّر في <xliff:g id="NETWORK_SSID">%1$s</xliff:g> إمكانية الاتصال بالإنترنت."</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"انقر للحصول على الخيارات."</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"شبكة الجوّال هذه غير متصلة بالإنترنت"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"الشبكة غير متصلة بالإنترنت"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"لا يمكن الوصول إلى خادم أسماء نظام نطاقات خاص"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"إمكانية اتصال <xliff:g id="NETWORK_SSID">%1$s</xliff:g> محدودة."</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"يمكنك النقر للاتصال على أي حال."</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"تم التبديل إلى <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"يستخدم الجهاز <xliff:g id="NEW_NETWORK">%1$s</xliff:g> عندما لا يتوفر اتصال بالإنترنت في شبكة <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>، ويمكن أن يتم فرض رسوم مقابل ذلك."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"تم التبديل من <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> إلى <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"نوع شبكة غير معروف"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"مصادر إمكانية اتصال الخادم"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"‏تسجيل الدخول إلى شبكة Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"تسجيل الدخول إلى الشبكة"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"لا يتوفّر في <xliff:g id="NETWORK_SSID">%1$s</xliff:g> إمكانية الاتصال بالإنترنت."</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"انقر للحصول على الخيارات."</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"شبكة الجوّال هذه غير متصلة بالإنترنت"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"الشبكة غير متصلة بالإنترنت"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"لا يمكن الوصول إلى خادم أسماء نظام نطاقات خاص"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"إمكانية اتصال <xliff:g id="NETWORK_SSID">%1$s</xliff:g> محدودة."</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"يمكنك النقر للاتصال على أي حال."</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"تم التبديل إلى <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"يستخدم الجهاز <xliff:g id="NEW_NETWORK">%1$s</xliff:g> عندما لا يتوفر اتصال بالإنترنت في شبكة <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>، ويمكن أن يتم فرض رسوم مقابل ذلك."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"تم التبديل من <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> إلى <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"بيانات الجوّال"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"بلوتوث"</item>
-    <item msgid="1616528372438698248">"إيثرنت"</item>
-    <item msgid="9177085807664964627">"‏شبكة افتراضية خاصة (VPN)"</item>
+    <item msgid="5454013645032700715">"بيانات الجوّال"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"بلوتوث"</item>
+    <item msgid="1160736166977503463">"إيثرنت"</item>
+    <item msgid="7347618872551558605">"‏شبكة افتراضية خاصة (VPN)"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"نوع شبكة غير معروف"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-as/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-as/strings.xml
index 10b234a..cf8e6ac 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-as/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-as/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"ৱাই-ফাই নেটৱৰ্কত ছাইন ইন কৰক"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"নেটৱৰ্কত ছাইন ইন কৰক"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>ৰ ইণ্টাৰনেটৰ এক্সেছ নাই"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"অধিক বিকল্পৰ বাবে টিপক"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"ম’বাইল নেটৱৰ্কৰ কোনো ইণ্টাৰনেটৰ এক্সেছ নাই"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"নেটৱৰ্কৰ কোনো ইণ্টাৰনেটৰ এক্সেছ নাই"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"ব্যক্তিগত DNS ছাৰ্ভাৰ এক্সেছ কৰিব নোৱাৰি"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>ৰ সকলো সেৱাৰ এক্সেছ নাই"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"যিকোনো প্ৰকাৰে সংযোগ কৰিবলৈ টিপক"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g>লৈ সলনি কৰা হ’ল"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"যেতিয়া <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>ত ইণ্টাৰনেট নাথাকে, তেতিয়া ডিভাইচে <xliff:g id="NEW_NETWORK">%1$s</xliff:g>ক ব্যৱহাৰ কৰে। মাচুল প্ৰযোজ্য হ\'ব পাৰে।"</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>ৰ পৰা <xliff:g id="NEW_NETWORK">%2$s</xliff:g> লৈ সলনি কৰা হ’ল"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"অজ্ঞাত প্ৰকাৰৰ নেটৱৰ্ক"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"ছিষ্টেম সংযোগৰ উৎস"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"ৱাই-ফাই নেটৱৰ্কত ছাইন ইন কৰক"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"নেটৱৰ্কত ছাইন ইন কৰক"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>ৰ ইণ্টাৰনেটৰ এক্সেছ নাই"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"অধিক বিকল্পৰ বাবে টিপক"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"ম’বাইল নেটৱৰ্কৰ কোনো ইণ্টাৰনেটৰ এক্সেছ নাই"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"নেটৱৰ্কৰ কোনো ইণ্টাৰনেটৰ এক্সেছ নাই"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"ব্যক্তিগত DNS ছাৰ্ভাৰ এক্সেছ কৰিব নোৱাৰি"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>ৰ সকলো সেৱাৰ এক্সেছ নাই"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"যিকোনো প্ৰকাৰে সংযোগ কৰিবলৈ টিপক"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g>লৈ সলনি কৰা হ’ল"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"যেতিয়া <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>ত ইণ্টাৰনেট নাথাকে, তেতিয়া ডিভাইচে <xliff:g id="NEW_NETWORK">%1$s</xliff:g>ক ব্যৱহাৰ কৰে। মাচুল প্ৰযোজ্য হ\'ব পাৰে।"</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>ৰ পৰা <xliff:g id="NEW_NETWORK">%2$s</xliff:g> লৈ সলনি কৰা হ’ল"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"ম’বাইল ডেটা"</item>
-    <item msgid="5520925862115353992">"ৱাই-ফাই"</item>
-    <item msgid="1055487873974272842">"ব্লুটুথ"</item>
-    <item msgid="1616528372438698248">"ইথাৰনেট"</item>
-    <item msgid="9177085807664964627">"ভিপিএন"</item>
+    <item msgid="5454013645032700715">"ম’বাইল ডেটা"</item>
+    <item msgid="6341719431034774569">"ৱাই-ফাই"</item>
+    <item msgid="5081440868800877512">"ব্লুটুথ"</item>
+    <item msgid="1160736166977503463">"ইথাৰনেট"</item>
+    <item msgid="7347618872551558605">"ভিপিএন"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"অজ্ঞাত প্ৰকাৰৰ নেটৱৰ্ক"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-az/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-az/strings.xml
index d75a204..7e927ed 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-az/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-az/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Wi-Fi şəbəkəsinə daxil ol"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Şəbəkəyə daxil olun"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> üçün internet girişi əlçatan deyil"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Seçimlər üçün tıklayın"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"Mobil şəbəkənin internetə girişi yoxdur"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"Şəbəkənin internetə girişi yoxdur"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Özəl DNS serverinə giriş mümkün deyil"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> bağlantını məhdudlaşdırdı"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"İstənilən halda klikləyin"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> şəbəkə növünə keçirildi"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> şəbəkəsinin internetə girişi olmadıqda, cihaz <xliff:g id="NEW_NETWORK">%1$s</xliff:g> şəbəkəsini istifadə edir. Xidmət haqqı tutula bilər."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> şəbəkəsindən <xliff:g id="NEW_NETWORK">%2$s</xliff:g> şəbəkəsinə keçirildi"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"naməlum şəbəkə növü"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Sistem Bağlantı Resursları"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Wi-Fi şəbəkəsinə daxil ol"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Şəbəkəyə daxil olun"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> üçün internet girişi əlçatan deyil"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Seçimlər üçün tıklayın"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"Mobil şəbəkənin internetə girişi yoxdur"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"Şəbəkənin internetə girişi yoxdur"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Özəl DNS serverinə giriş mümkün deyil"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> bağlantını məhdudlaşdırdı"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"İstənilən halda klikləyin"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> şəbəkə növünə keçirildi"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> şəbəkəsinin internetə girişi olmadıqda, cihaz <xliff:g id="NEW_NETWORK">%1$s</xliff:g> şəbəkəsini istifadə edir. Xidmət haqqı tutula bilər."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> şəbəkəsindən <xliff:g id="NEW_NETWORK">%2$s</xliff:g> şəbəkəsinə keçirildi"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"mobil data"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Ethernet"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"mobil data"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Ethernet"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"naməlum şəbəkə növü"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-b+sr+Latn/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-b+sr+Latn/strings.xml
index 11e4957..3f1b976 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-b+sr+Latn/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-b+sr+Latn/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Prijavljivanje na WiFi mrežu"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Prijavite se na mrežu"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> nema pristup internetu"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Dodirnite za opcije"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"Mobilna mreža nema pristup internetu"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"Mreža nema pristup internetu"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Pristup privatnom DNS serveru nije uspeo"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ima ograničenu vezu"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Dodirnite da biste se ipak povezali"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"Prešli ste na tip mreže <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Uređaj koristi tip mreže <xliff:g id="NEW_NETWORK">%1$s</xliff:g> kada tip mreže <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> nema pristup internetu. Možda će se naplaćivati troškovi."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"Prešli ste sa tipa mreže <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> na tip mreže <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"nepoznat tip mreže"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Resursi za povezivanje sa sistemom"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Prijavljivanje na WiFi mrežu"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Prijavite se na mrežu"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> nema pristup internetu"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Dodirnite za opcije"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"Mobilna mreža nema pristup internetu"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"Mreža nema pristup internetu"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Pristup privatnom DNS serveru nije uspeo"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ima ograničenu vezu"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Dodirnite da biste se ipak povezali"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"Prešli ste na tip mreže <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"Uređaj koristi tip mreže <xliff:g id="NEW_NETWORK">%1$s</xliff:g> kada tip mreže <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> nema pristup internetu. Možda će se naplaćivati troškovi."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"Prešli ste sa tipa mreže <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> na tip mreže <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"mobilni podaci"</item>
-    <item msgid="5520925862115353992">"WiFi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Eternet"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"mobilni podaci"</item>
+    <item msgid="6341719431034774569">"WiFi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Eternet"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"nepoznat tip mreže"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-be/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-be/strings.xml
index 6b0b1f1..21edf24 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-be/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-be/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Уваход у сетку Wi-Fi"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Увайдзіце ў сетку"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> не мае доступу ў інтэрнэт"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Дакраніцеся, каб убачыць параметры"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"Мабільная сетка не мае доступу ў інтэрнэт"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"Сетка не мае доступу ў інтэрнэт"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Не ўдалося атрымаць доступ да прыватнага DNS-сервера"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> мае абмежаваную магчымасць падключэння"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Націсніце, каб падключыцца"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"Выкананы пераход да <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Прылада выкарыстоўвае сетку <xliff:g id="NEW_NETWORK">%1$s</xliff:g>, калі ў сетцы <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> няма доступу да інтэрнэту. Можа спаганяцца плата."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"Выкананы пераход з <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> да <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"невядомы тып сеткі"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Рэсурсы для падключэння да сістэмы"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Уваход у сетку Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Увайдзіце ў сетку"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> не мае доступу ў інтэрнэт"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Дакраніцеся, каб убачыць параметры"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"Мабільная сетка не мае доступу ў інтэрнэт"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"Сетка не мае доступу ў інтэрнэт"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Не ўдалося атрымаць доступ да прыватнага DNS-сервера"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> мае абмежаваную магчымасць падключэння"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Націсніце, каб падключыцца"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"Выкананы пераход да <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"Прылада выкарыстоўвае сетку <xliff:g id="NEW_NETWORK">%1$s</xliff:g>, калі ў сетцы <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> няма доступу да інтэрнэту. Можа спаганяцца плата."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"Выкананы пераход з <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> да <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"мабільная перадача даных"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Ethernet"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"мабільная перадача даных"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Ethernet"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"невядомы тып сеткі"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-bg/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-bg/strings.xml
index 6427bd0..c3c2d72 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-bg/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-bg/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Влизане в Wi-Fi мрежа"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Вход в мрежата"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> няма достъп до интернет"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Докоснете за опции"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"Мобилната мрежа няма достъп до интернет"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"Мрежата няма достъп до интернет"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Не може да се осъществи достъп до частния DNS сървър"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> има ограничена свързаност"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Докоснете, за да се свържете въпреки това"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"Превключи се към <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Устройството използва <xliff:g id="NEW_NETWORK">%1$s</xliff:g>, когато <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> няма достъп до интернет. Възможно е да бъдете таксувани."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"Превключи се от <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> към <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"неизвестен тип мрежа"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Ресурси за свързаността на системата"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Влизане в Wi-Fi мрежа"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Вход в мрежата"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> няма достъп до интернет"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Докоснете за опции"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"Мобилната мрежа няма достъп до интернет"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"Мрежата няма достъп до интернет"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Не може да се осъществи достъп до частния DNS сървър"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> има ограничена свързаност"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Докоснете, за да се свържете въпреки това"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"Превключи се към <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"Устройството използва <xliff:g id="NEW_NETWORK">%1$s</xliff:g>, когато <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> няма достъп до интернет. Възможно е да бъдете таксувани."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"Превключи се от <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> към <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"мобилни данни"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Ethernet"</item>
-    <item msgid="9177085807664964627">"виртуална частна мрежа (VPN)"</item>
+    <item msgid="5454013645032700715">"мобилни данни"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Ethernet"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"неизвестен тип мрежа"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-bn/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-bn/strings.xml
index 74d4cd6..0f693bd 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-bn/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-bn/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"ওয়াই-ফাই নেটওয়ার্কে সাইন-ইন করুন"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"নেটওয়ার্কে সাইন-ইন করুন"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>-এর ইন্টারনেটে অ্যাক্সেস নেই"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"বিকল্পগুলির জন্য আলতো চাপুন"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"মোবাইল নেটওয়ার্কে কোনও ইন্টারনেট অ্যাক্সেস নেই"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"নেটওয়ার্কে কোনও ইন্টারনেট অ্যাক্সেস নেই"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"ব্যক্তিগত ডিএনএস সার্ভার অ্যাক্সেস করা যাবে না"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>-এর সীমিত কানেক্টিভিটি আছে"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"তবুও কানেক্ট করতে ট্যাপ করুন"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> এ পাল্টানো হয়েছে"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> এ ইন্টারনেট অ্যাক্সেস না থাকলে <xliff:g id="NEW_NETWORK">%1$s</xliff:g> ব্যবহার করা হয়৷ ডেটা চার্জ প্রযোজ্য৷"</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> থেকে <xliff:g id="NEW_NETWORK">%2$s</xliff:g> এ পাল্টানো হয়েছে"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"এই নেটওয়ার্কের প্রকার অজানা"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"সিস্টেম কানেক্টিভিটি রিসোর্সেস"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"ওয়াই-ফাই নেটওয়ার্কে সাইন-ইন করুন"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"নেটওয়ার্কে সাইন-ইন করুন"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>-এর ইন্টারনেটে অ্যাক্সেস নেই"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"বিকল্পগুলির জন্য আলতো চাপুন"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"মোবাইল নেটওয়ার্কে কোনও ইন্টারনেট অ্যাক্সেস নেই"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"নেটওয়ার্কে কোনও ইন্টারনেট অ্যাক্সেস নেই"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"ব্যক্তিগত ডিএনএস সার্ভার অ্যাক্সেস করা যাবে না"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>-এর সীমিত কানেক্টিভিটি আছে"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"তবুও কানেক্ট করতে ট্যাপ করুন"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> এ পাল্টানো হয়েছে"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> এ ইন্টারনেট অ্যাক্সেস না থাকলে <xliff:g id="NEW_NETWORK">%1$s</xliff:g> ব্যবহার করা হয়৷ ডেটা চার্জ প্রযোজ্য৷"</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> থেকে <xliff:g id="NEW_NETWORK">%2$s</xliff:g> এ পাল্টানো হয়েছে"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"মোবাইল ডেটা"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"ব্লুটুথ"</item>
-    <item msgid="1616528372438698248">"ইথারনেট"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"মোবাইল ডেটা"</item>
+    <item msgid="6341719431034774569">"ওয়াই-ফাই"</item>
+    <item msgid="5081440868800877512">"ব্লুটুথ"</item>
+    <item msgid="1160736166977503463">"ইথারনেট"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"এই নেটওয়ার্কের ধরন অজানা"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-bs/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-bs/strings.xml
index 19f6e1a..33d6ed9 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-bs/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-bs/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Prijavljivanje na WiFi mrežu"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Prijava na mrežu"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"Mreža <xliff:g id="NETWORK_SSID">%1$s</xliff:g> nema pristup internetu"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Dodirnite za opcije"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"Mobilna mreža nema pristup internetu"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"Mreža nema pristup internetu"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Nije moguće pristupiti privatnom DNS serveru"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"Mreža <xliff:g id="NETWORK_SSID">%1$s</xliff:g> ima ograničenu povezivost"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Dodirnite da se ipak povežete"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"Prebačeno na: <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Kada <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> nema pristup internetu, uređaj koristi mrežu <xliff:g id="NEW_NETWORK">%1$s</xliff:g>. Moguća je naplata usluge."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"Prebačeno iz mreže <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> u <xliff:g id="NEW_NETWORK">%2$s</xliff:g> mrežu"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"nepoznata vrsta mreže"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Izvori povezivosti sistema"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Prijavljivanje na WiFi mrežu"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Prijava na mrežu"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"Mreža <xliff:g id="NETWORK_SSID">%1$s</xliff:g> nema pristup internetu"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Dodirnite za opcije"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"Mobilna mreža nema pristup internetu"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"Mreža nema pristup internetu"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Nije moguće pristupiti privatnom DNS serveru"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"Mreža <xliff:g id="NETWORK_SSID">%1$s</xliff:g> ima ograničenu povezivost"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Dodirnite da se ipak povežete"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"Prebačeno na: <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"Kada <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> nema pristup internetu, uređaj koristi mrežu <xliff:g id="NEW_NETWORK">%1$s</xliff:g>. Moguća je naplata usluge."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"Prebačeno iz mreže <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> u <xliff:g id="NEW_NETWORK">%2$s</xliff:g> mrežu"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"prijenos podataka na mobilnoj mreži"</item>
-    <item msgid="5520925862115353992">"WiFi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Ethernet"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"prijenos podataka na mobilnoj mreži"</item>
+    <item msgid="6341719431034774569">"WiFi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Ethernet"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"nepoznata vrsta mreže"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ca/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ca/strings.xml
index c55684d..04f6bd2 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ca/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ca/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Inicia la sessió a la xarxa Wi-Fi"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Inicia la sessió a la xarxa"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> no té accés a Internet"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Toca per veure les opcions"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"La xarxa mòbil no té accés a Internet"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"La xarxa no té accés a Internet"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"No es pot accedir al servidor DNS privat"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> té una connectivitat limitada"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Toca per connectar igualment"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"Actualment en ús: <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"El dispositiu utilitza <xliff:g id="NEW_NETWORK">%1$s</xliff:g> en cas que <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> no tingui accés a Internet. És possible que s\'hi apliquin càrrecs."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"Abans es feia servir la xarxa <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>; ara s\'utilitza <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"una tipus de xarxa desconegut"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Recursos de connectivitat del sistema"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Inicia la sessió a la xarxa Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Inicia la sessió a la xarxa"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> no té accés a Internet"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Toca per veure les opcions"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"La xarxa mòbil no té accés a Internet"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"La xarxa no té accés a Internet"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"No es pot accedir al servidor DNS privat"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> té una connectivitat limitada"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Toca per connectar igualment"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"Actualment en ús: <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"El dispositiu utilitza <xliff:g id="NEW_NETWORK">%1$s</xliff:g> en cas que <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> no tingui accés a Internet. És possible que s\'hi apliquin càrrecs."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"Abans es feia servir la xarxa <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>; ara s\'utilitza <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"dades mòbils"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Ethernet"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"dades mòbils"</item>
+    <item msgid="6341719431034774569">"Wi‑Fi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Ethernet"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"un tipus de xarxa desconegut"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-cs/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-cs/strings.xml
index fa8c411..6309e78 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-cs/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-cs/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Přihlásit se k síti Wi-Fi"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Přihlásit se k síti"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"Síť <xliff:g id="NETWORK_SSID">%1$s</xliff:g> nemá přístup k internetu"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Klepnutím zobrazíte možnosti"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"Mobilní síť nemá přístup k internetu"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"Síť nemá přístup k internetu"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Nelze získat přístup k soukromému serveru DNS"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"Síť <xliff:g id="NETWORK_SSID">%1$s</xliff:g> umožňuje jen omezené připojení"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Klepnutím se i přesto připojíte"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"Přechod na síť <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Když síť <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> nebude mít přístup k internetu, zařízení použije síť <xliff:g id="NEW_NETWORK">%1$s</xliff:g>. Mohou být účtovány poplatky."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"Přechod ze sítě <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> na síť <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"neznámý typ sítě"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Zdroje pro připojení systému"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Přihlásit se k síti Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Přihlásit se k síti"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"Síť <xliff:g id="NETWORK_SSID">%1$s</xliff:g> nemá přístup k internetu"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Klepnutím zobrazíte možnosti"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"Mobilní síť nemá přístup k internetu"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"Síť nemá přístup k internetu"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Nelze získat přístup k soukromému serveru DNS"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"Síť <xliff:g id="NETWORK_SSID">%1$s</xliff:g> umožňuje jen omezené připojení"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Klepnutím se i přesto připojíte"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"Přechod na síť <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"Když síť <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> nebude mít přístup k internetu, zařízení použije síť <xliff:g id="NEW_NETWORK">%1$s</xliff:g>. Mohou být účtovány poplatky."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"Přechod ze sítě <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> na síť <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"mobilní data"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Ethernet"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"mobilní data"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Ethernet"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"neznámý typ sítě"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-da/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-da/strings.xml
index f7be6df..57c58af 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-da/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-da/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Log ind på Wi-Fi-netværk"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Log ind på netværk"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> har ingen internetforbindelse"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Tryk for at se valgmuligheder"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"Mobilnetværket har ingen internetadgang"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"Netværket har ingen internetadgang"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Der er ikke adgang til den private DNS-server"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> har begrænset forbindelse"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Tryk for at oprette forbindelse alligevel"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"Der blev skiftet til <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Enheden benytter <xliff:g id="NEW_NETWORK">%1$s</xliff:g>, når der ikke er internetadgang via <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>. Der opkræves muligvis betaling."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"Der blev skiftet fra <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> til <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"en ukendt netværkstype"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Systemets forbindelsesressourcer"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Log ind på Wi-Fi-netværk"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Log ind på netværk"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> har ingen internetforbindelse"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Tryk for at se valgmuligheder"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"Mobilnetværket har ingen internetadgang"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"Netværket har ingen internetadgang"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Der er ikke adgang til den private DNS-server"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> har begrænset forbindelse"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Tryk for at oprette forbindelse alligevel"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"Der blev skiftet til <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"Enheden benytter <xliff:g id="NEW_NETWORK">%1$s</xliff:g>, når der ikke er internetadgang via <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>. Der opkræves muligvis betaling."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"Der blev skiftet fra <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> til <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"mobildata"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Ethernet"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"mobildata"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Ethernet"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"en ukendt netværkstype"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-de/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-de/strings.xml
index 1e7b80c..d0c2551 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-de/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-de/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"In WLAN anmelden"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Im Netzwerk anmelden"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> hat keinen Internetzugriff"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Für Optionen tippen"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"Mobiles Netzwerk hat keinen Internetzugriff"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"Netzwerk hat keinen Internetzugriff"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Auf den privaten DNS-Server kann nicht zugegriffen werden"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"Schlechte Verbindung mit <xliff:g id="NETWORK_SSID">%1$s</xliff:g>"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Tippen, um die Verbindung trotzdem herzustellen"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"Zu <xliff:g id="NETWORK_TYPE">%1$s</xliff:g> gewechselt"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Auf dem Gerät werden <xliff:g id="NEW_NETWORK">%1$s</xliff:g> genutzt, wenn über <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> kein Internet verfügbar ist. Eventuell fallen Gebühren an."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"Von \"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>\" zu \"<xliff:g id="NEW_NETWORK">%2$s</xliff:g>\" gewechselt"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"ein unbekannter Netzwerktyp"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Systemverbindungsressourcen"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"In WLAN anmelden"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Im Netzwerk anmelden"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> hat keinen Internetzugriff"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Für Optionen tippen"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"Mobiles Netzwerk hat keinen Internetzugriff"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"Netzwerk hat keinen Internetzugriff"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Auf den privaten DNS-Server kann nicht zugegriffen werden"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"Schlechte Verbindung mit <xliff:g id="NETWORK_SSID">%1$s</xliff:g>"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Tippen, um die Verbindung trotzdem herzustellen"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"Zu <xliff:g id="NETWORK_TYPE">%1$s</xliff:g> gewechselt"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"Auf dem Gerät werden <xliff:g id="NEW_NETWORK">%1$s</xliff:g> genutzt, wenn über <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> kein Internet verfügbar ist. Eventuell fallen Gebühren an."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"Von \"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>\" zu \"<xliff:g id="NEW_NETWORK">%2$s</xliff:g>\" gewechselt"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"Mobile Daten"</item>
-    <item msgid="5520925862115353992">"WLAN"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Ethernet"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"Mobile Daten"</item>
+    <item msgid="6341719431034774569">"WLAN"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Ethernet"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"ein unbekannter Netzwerktyp"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-el/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-el/strings.xml
index 89647fdb..1c2838d 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-el/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-el/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Συνδεθείτε στο δίκτυο Wi-Fi"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Σύνδεση στο δίκτυο"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"Η εφαρμογή <xliff:g id="NETWORK_SSID">%1$s</xliff:g> δεν έχει πρόσβαση στο διαδίκτυο"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Πατήστε για να δείτε τις επιλογές"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"Το δίκτυο κινητής τηλεφωνίας δεν έχει πρόσβαση στο διαδίκτυο."</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"Το δίκτυο δεν έχει πρόσβαση στο διαδίκτυο."</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Δεν είναι δυνατή η πρόσβαση στον ιδιωτικό διακομιστή DNS."</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"Το δίκτυο <xliff:g id="NETWORK_SSID">%1$s</xliff:g> έχει περιορισμένη συνδεσιμότητα"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Πατήστε για σύνδεση ούτως ή άλλως"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"Μετάβαση σε δίκτυο <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Η συσκευή χρησιμοποιεί το δίκτυο <xliff:g id="NEW_NETWORK">%1$s</xliff:g> όταν το δίκτυο <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> δεν έχει πρόσβαση στο διαδίκτυο. Μπορεί να ισχύουν χρεώσεις."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"Μετάβαση από το δίκτυο <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> στο δίκτυο <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"άγνωστος τύπος δικτύου"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Πόροι συνδεσιμότητας συστήματος"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Συνδεθείτε στο δίκτυο Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Σύνδεση στο δίκτυο"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"Η εφαρμογή <xliff:g id="NETWORK_SSID">%1$s</xliff:g> δεν έχει πρόσβαση στο διαδίκτυο"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Πατήστε για να δείτε τις επιλογές"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"Το δίκτυο κινητής τηλεφωνίας δεν έχει πρόσβαση στο διαδίκτυο."</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"Το δίκτυο δεν έχει πρόσβαση στο διαδίκτυο."</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Δεν είναι δυνατή η πρόσβαση στον ιδιωτικό διακομιστή DNS."</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"Το δίκτυο <xliff:g id="NETWORK_SSID">%1$s</xliff:g> έχει περιορισμένη συνδεσιμότητα"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Πατήστε για σύνδεση ούτως ή άλλως"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"Μετάβαση σε δίκτυο <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"Η συσκευή χρησιμοποιεί το δίκτυο <xliff:g id="NEW_NETWORK">%1$s</xliff:g> όταν το δίκτυο <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> δεν έχει πρόσβαση στο διαδίκτυο. Μπορεί να ισχύουν χρεώσεις."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"Μετάβαση από το δίκτυο <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> στο δίκτυο <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"δεδομένα κινητής τηλεφωνίας"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Ethernet"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"δεδομένα κινητής τηλεφωνίας"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Ethernet"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"άγνωστος τύπος δικτύου"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-en-rAU/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-en-rAU/strings.xml
index d29e2ec..db5ad70 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-en-rAU/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-en-rAU/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Sign in to a Wi-Fi network"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Sign in to network"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> has no Internet access"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Tap for options"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"Mobile network has no Internet access"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"Network has no Internet access"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Private DNS server cannot be accessed"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> has limited connectivity"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Tap to connect anyway"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"Switched to <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Device uses <xliff:g id="NEW_NETWORK">%1$s</xliff:g> when <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> has no Internet access. Charges may apply."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"Switched from <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> to <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"an unknown network type"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"System connectivity resources"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Sign in to a Wi-Fi network"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Sign in to network"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> has no Internet access"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Tap for options"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"Mobile network has no Internet access"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"Network has no Internet access"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Private DNS server cannot be accessed"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> has limited connectivity"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Tap to connect anyway"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"Switched to <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"Device uses <xliff:g id="NEW_NETWORK">%1$s</xliff:g> when <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> has no Internet access. Charges may apply."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"Switched from <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> to <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"mobile data"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Ethernet"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"mobile data"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Ethernet"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"an unknown network type"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-en-rCA/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-en-rCA/strings.xml
index d29e2ec..db5ad70 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-en-rCA/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-en-rCA/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Sign in to a Wi-Fi network"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Sign in to network"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> has no Internet access"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Tap for options"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"Mobile network has no Internet access"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"Network has no Internet access"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Private DNS server cannot be accessed"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> has limited connectivity"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Tap to connect anyway"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"Switched to <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Device uses <xliff:g id="NEW_NETWORK">%1$s</xliff:g> when <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> has no Internet access. Charges may apply."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"Switched from <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> to <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"an unknown network type"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"System connectivity resources"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Sign in to a Wi-Fi network"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Sign in to network"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> has no Internet access"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Tap for options"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"Mobile network has no Internet access"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"Network has no Internet access"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Private DNS server cannot be accessed"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> has limited connectivity"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Tap to connect anyway"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"Switched to <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"Device uses <xliff:g id="NEW_NETWORK">%1$s</xliff:g> when <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> has no Internet access. Charges may apply."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"Switched from <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> to <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"mobile data"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Ethernet"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"mobile data"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Ethernet"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"an unknown network type"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-en-rGB/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-en-rGB/strings.xml
index d29e2ec..db5ad70 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-en-rGB/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-en-rGB/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Sign in to a Wi-Fi network"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Sign in to network"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> has no Internet access"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Tap for options"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"Mobile network has no Internet access"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"Network has no Internet access"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Private DNS server cannot be accessed"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> has limited connectivity"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Tap to connect anyway"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"Switched to <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Device uses <xliff:g id="NEW_NETWORK">%1$s</xliff:g> when <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> has no Internet access. Charges may apply."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"Switched from <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> to <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"an unknown network type"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"System connectivity resources"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Sign in to a Wi-Fi network"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Sign in to network"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> has no Internet access"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Tap for options"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"Mobile network has no Internet access"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"Network has no Internet access"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Private DNS server cannot be accessed"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> has limited connectivity"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Tap to connect anyway"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"Switched to <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"Device uses <xliff:g id="NEW_NETWORK">%1$s</xliff:g> when <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> has no Internet access. Charges may apply."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"Switched from <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> to <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"mobile data"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Ethernet"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"mobile data"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Ethernet"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"an unknown network type"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-en-rIN/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-en-rIN/strings.xml
index d29e2ec..db5ad70 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-en-rIN/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-en-rIN/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Sign in to a Wi-Fi network"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Sign in to network"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> has no Internet access"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Tap for options"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"Mobile network has no Internet access"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"Network has no Internet access"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Private DNS server cannot be accessed"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> has limited connectivity"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Tap to connect anyway"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"Switched to <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Device uses <xliff:g id="NEW_NETWORK">%1$s</xliff:g> when <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> has no Internet access. Charges may apply."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"Switched from <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> to <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"an unknown network type"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"System connectivity resources"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Sign in to a Wi-Fi network"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Sign in to network"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> has no Internet access"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Tap for options"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"Mobile network has no Internet access"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"Network has no Internet access"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Private DNS server cannot be accessed"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> has limited connectivity"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Tap to connect anyway"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"Switched to <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"Device uses <xliff:g id="NEW_NETWORK">%1$s</xliff:g> when <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> has no Internet access. Charges may apply."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"Switched from <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> to <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"mobile data"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Ethernet"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"mobile data"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Ethernet"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"an unknown network type"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-en-rXC/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-en-rXC/strings.xml
index cd69133..2602bfa 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-en-rXC/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-en-rXC/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‏‎‏‎‎‏‎‎‏‏‏‎‎‎‏‏‏‎‎‏‏‏‎‎‏‎‏‎‏‎‏‎‏‏‏‏‎‎‏‎‏‎‏‎‏‏‎‏‎‏‏‏‎‎‏‎‏‎Sign in to Wi-Fi network‎‏‎‎‏‎"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‏‎‎‎‏‏‎‎‏‎‏‎‏‎‏‏‏‎‏‎‎‎‎‏‎‎‏‏‎‎‎‎‏‎‏‏‏‏‏‎‎‏‏‎‏‏‎‎‏‎‎‏‎‏‎‏‎‎Sign in to network‎‏‎‎‏‎"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‏‎‎‏‏‏‏‏‏‎‏‎‎‏‏‎‎‏‏‎‏‎‏‏‏‎‏‏‎‎‏‏‎‏‎‎‏‏‎‎‏‏‏‏‏‎‏‏‏‎‎‏‏‏‏‎‏‎‎‏‎‎‏‏‎<xliff:g id="NETWORK_SSID">%1$s</xliff:g>‎‏‎‎‏‏‏‎ has no internet access‎‏‎‎‏‎"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‎‏‏‎‎‏‏‏‏‏‏‎‎‎‎‎‏‎‎‏‎‎‏‏‎‏‎‏‎‎‎‎‎‏‏‎‏‎‎‎‏‏‏‏‎‏‎‏‎‏‎‎‏‏‏‏‎‎Tap for options‎‏‎‎‏‎"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‏‏‎‏‏‎‎‎‏‏‎‏‎‏‏‎‏‏‎‎‏‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‏‎‎‎‎‏‏‎‏‎‎‎‎‏‎‏‎‏‎Mobile network has no internet access‎‏‎‎‏‎"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‏‏‏‎‏‏‎‏‎‎‏‏‎‏‎‏‏‎‎‏‎‎‏‎‎‎‏‎‏‎‏‏‎‎‎‎‎‎‎‏‏‏‎‏‏‏‏‏‏‎‏‏‎‎‏‎Network has no internet access‎‏‎‎‏‎"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‏‎‏‏‏‏‎‏‎‎‏‏‎‎‏‎‎‏‏‏‏‏‎‏‎‏‎‏‏‎‏‏‏‎‏‏‎‎‏‏‏‎‎‎‏‎‎‏‎‏‎‎‎‎‏‏‏‎Private DNS server cannot be accessed‎‏‎‎‏‎"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‎‎‏‏‏‏‏‎‏‎‎‏‎‎‎‏‏‏‏‎‎‏‎‎‎‏‏‎‎‏‎‎‎‎‎‏‏‎‏‎‏‎‎‏‎‎‎‎‏‎‏‏‎‎‎‏‏‎‎‏‎‎‏‏‎<xliff:g id="NETWORK_SSID">%1$s</xliff:g>‎‏‎‎‏‏‏‎ has limited connectivity‎‏‎‎‏‎"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‎‏‎‏‏‎‏‎‏‎‎‏‏‎‎‏‎‏‏‎‏‏‎‎‎‎‎‎‎‎‏‏‏‎‎‎‎‏‏‎‎‏‎‎‏‏‎‎‏‏‎‎‎‎‎‎Tap to connect anyway‎‏‎‎‏‎"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‏‎‏‎‎‎‎‏‎‎‏‎‎‏‎‏‏‎‎‏‏‏‎‏‏‏‏‏‏‎‏‎‎‏‏‎‏‎‏‏‏‎‎‏‎‎‎‏‎‎‏‏‏‏‎‎‎‎Switched to ‎‏‎‎‏‏‎<xliff:g id="NETWORK_TYPE">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‎‏‏‎‏‏‎‎‏‏‎‏‎‎‎‏‏‎‎‎‎‎‏‏‎‎‏‎‎‏‏‏‏‏‎‎‎‏‎‎‎‏‎‏‏‎‏‎‏‏‎‎‏‎‎‏‎‎Device uses ‎‏‎‎‏‏‎<xliff:g id="NEW_NETWORK">%1$s</xliff:g>‎‏‎‎‏‏‏‎ when ‎‏‎‎‏‏‎<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>‎‏‎‎‏‏‏‎ has no internet access. Charges may apply.‎‏‎‎‏‎"</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‎‏‏‏‏‎‏‏‎‎‏‎‎‎‎‏‎‏‏‏‏‏‎‎‏‎‏‎‏‏‏‎‏‎‎‏‎‏‎‏‎‎‎‏‎‏‎‏‏‏‏‎‏‏‏‏‏‎Switched from ‎‏‎‎‏‏‎<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>‎‏‎‎‏‏‏‎ to ‎‏‎‎‏‏‎<xliff:g id="NEW_NETWORK">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‎‏‏‎‏‏‏‏‏‎‎‏‎‏‎‏‏‏‏‎‏‏‎‏‏‎‎‎‏‎‏‎‎‏‎‏‎‎‎‎‏‏‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎an unknown network type‎‏‎‎‏‎"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‏‏‏‎‏‏‎‎‎‏‎‎‎‎‎‎‎‎‏‏‎‏‏‏‏‎‎‎‎‏‏‏‎‎‏‏‎‏‏‏‎‏‎‏‏‏‎‎‎‏‎‏‏‎System Connectivity Resources‎‏‎‎‏‎"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‏‎‏‎‏‎‏‎‎‎‎‎‏‏‎‏‏‏‏‎‏‎‏‎‏‎‎‎‎‏‏‏‏‎‎‏‎‎‎‏‏‎‎‏‎‏‎‏‎‏‏‎‎‏‎Sign in to Wi-Fi network‎‏‎‎‏‎"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‏‎‏‎‏‏‎‎‏‎‏‎‎‏‏‎‎‏‏‎‏‏‏‏‏‏‎‎‎‏‎‏‎‎‎‏‏‏‎‎‎‎‎‏‏‎‏‎‎‏‏‎‎‎‎Sign in to network‎‏‎‎‏‎"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‎‏‏‏‏‏‎‏‎‏‏‎‎‎‏‏‎‏‎‏‏‏‎‎‏‎‎‏‏‎‏‏‎‎‏‏‎‏‏‏‎‏‏‏‏‎‎‎‏‏‏‏‏‎‎‏‎‎‎‏‎‎‏‏‎<xliff:g id="NETWORK_SSID">%1$s</xliff:g>‎‏‎‎‏‏‏‎ has no internet access‎‏‎‎‏‎"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‏‎‎‎‎‏‏‏‎‏‎‎‎‎‏‎‏‏‏‏‎‏‏‎‏‎‎‏‏‏‏‎‏‏‎‎‏‏‏‏‎‏‏‏‏‏‎‎‏‎‎‏‎‏‎‎‎‎Tap for options‎‏‎‎‏‎"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‎‎‏‏‎‎‎‎‏‏‎‎‏‏‎‎‏‏‎‎‎‎‏‎‏‏‏‏‎‏‎‏‎‏‎‎‏‎‎‏‎‎‏‎‎‏‏‎‏‎‏‏‏‎Mobile network has no internet access‎‏‎‎‏‎"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‎‏‎‎‎‏‎‏‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‎‏‏‎‏‎‏‎‎‎‏‎‎‎‏‏‎‎‏‏‏‏‏‏‎‏‎‏‏‎Network has no internet access‎‏‎‎‏‎"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‏‎‏‏‎‎‏‎‎‎‎‏‏‏‎‏‏‎‏‎‏‎‎‎‎‏‎‏‎‏‏‎‎‏‏‏‎‎‎‎‎‏‎Private DNS server cannot be accessed‎‏‎‎‏‎"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‎‏‎‏‎‏‏‏‎‏‏‏‏‏‏‎‏‎‏‎‎‎‎‏‏‏‎‎‎‏‏‏‎‏‎‏‏‏‎‏‎‎‏‎‏‎‏‎‎‎‎‏‎‎‏‎‎‏‎‎‏‏‎<xliff:g id="NETWORK_SSID">%1$s</xliff:g>‎‏‎‎‏‏‏‎ has limited connectivity‎‏‎‎‏‎"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‎‎‏‏‏‎‏‏‎‏‏‎‎‏‏‏‏‏‏‎‎‏‏‎‏‏‏‎‏‎‏‎‎‎‎‎‎‎‎‏‎‏‎‎‏‎‏‎‏‎‏‎‏‎‎Tap to connect anyway‎‏‎‎‏‎"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‏‎‎‎‏‎‎‎‎‎‎‏‎‏‏‎‎‏‎‏‎‎‏‎‎‏‎‏‎‏‏‎‎‎‏‎‎‎‏‏‎‎‏‏‏‎‏‏‏‎‎‏‏‎‎‎‎‎Switched to ‎‏‎‎‏‏‎<xliff:g id="NETWORK_TYPE">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‎‎‏‏‎‎‏‏‏‎‏‎‏‎‏‎‏‏‎‏‏‏‎‎‏‏‎‏‏‏‎‎‏‏‎‏‎‎‎‏‎‎‎‏‏‏‎‎‏‎‏‎‎‎‏‎‏‎Device uses ‎‏‎‎‏‏‎<xliff:g id="NEW_NETWORK">%1$s</xliff:g>‎‏‎‎‏‏‏‎ when ‎‏‎‎‏‏‎<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>‎‏‎‎‏‏‏‎ has no internet access. Charges may apply.‎‏‎‎‏‎"</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‏‏‎‎‏‎‏‎‏‏‏‏‎‎‎‎‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‏‎‎‏‎‎‏‎‏‏‎‎‎‎‏‎‎‎‏‎Switched from ‎‏‎‎‏‏‎<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>‎‏‎‎‏‏‏‎ to ‎‏‎‎‏‏‎<xliff:g id="NEW_NETWORK">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‎‏‎‎‏‏‎‏‏‏‎‎‎‎‎‎‎‏‎‏‎‏‏‏‏‏‎‎‏‏‏‎‎‎‏‎‏‏‎‎‏‏‏‏‎‎‏‎‎‎‏‏‏‏‎‏‎mobile data‎‏‎‎‏‎"</item>
-    <item msgid="5520925862115353992">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‎‏‎‎‏‏‏‏‎‎‏‎‎‎‏‎‎‏‏‎‏‎‎‏‎‎‎‎‎‏‎‏‎‏‎‏‎‎‏‏‏‎‎‏‎‎‏‎‏‏‎‎‎‏‎‎‎‎Wi-Fi‎‏‎‎‏‎"</item>
-    <item msgid="1055487873974272842">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‏‎‏‎‎‏‎‏‏‏‎‏‏‎‎‎‏‎‏‎‎‎‎‏‎‎‎‏‎‎‎‎‏‏‏‏‏‎‎‎‎‎‎‎‎‎‏‏‎‏‎‎‏‎‏‎‎Bluetooth‎‏‎‎‏‎"</item>
-    <item msgid="1616528372438698248">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‎‏‏‎‏‏‏‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‎‎‎‏‎‎‎‏‏‎‎‏‎‎‎‏‎‎‏‎‎‎‎‏‎‎‎‎Ethernet‎‏‎‎‏‎"</item>
-    <item msgid="9177085807664964627">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‏‏‎‎‎‏‏‏‎‏‏‏‎‏‎‏‏‎‏‏‏‎‏‏‏‎‎‏‎‎‏‏‎‎‎‏‎‎‏‎‎‎‎‎‏‎‎‏‏‎VPN‎‏‎‎‏‎"</item>
+    <item msgid="5454013645032700715">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‏‏‎‎‎‎‏‎‎‎‏‏‎‎‏‎‎‎‎‎‏‏‎‏‏‏‏‎‎‎‎‏‎‎‏‏‏‎‏‎‏‏‏‎‏‏‎‎‏‎‏‎‏‏‎mobile data‎‏‎‎‏‎"</item>
+    <item msgid="6341719431034774569">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‎‎‎‎‏‎‎‏‎‏‎‎‎‎‎‎‏‏‏‎‎‏‎‎‎‎‎‎‎‎‎‎‎‎‎‏‎‏‎‎‏‎‎‏‎‎‎‎‏‎‏‎‎‏‎Wi-Fi‎‏‎‎‏‎"</item>
+    <item msgid="5081440868800877512">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‎‏‎‎‎‎‏‎‎‏‏‏‎‎‏‏‏‏‎‎‎‏‏‎‎‎‎‏‎‏‏‎‎‎‎‎‎‎‏‏‏‎‏‎‏‎‎‏‏‏‏‎‎‏‎‎‎‎Bluetooth‎‏‎‎‏‎"</item>
+    <item msgid="1160736166977503463">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‎‎‎‎‏‏‎‏‏‏‏‎‎‎‎‏‏‎‏‏‎‎‏‎‎‏‏‎‏‏‏‏‎‏‎‏‎‎‏‎‎‏‎‎‎‎‎‎‎‏‏‏‎‎‏‏‏‎Ethernet‎‏‎‎‏‎"</item>
+    <item msgid="7347618872551558605">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‏‏‎‏‏‏‏‎‏‏‎‏‎‏‏‎‏‏‎‎‏‎‎‎‏‎‎‏‏‎‏‏‏‎‎‏‏‎‏‎VPN‎‏‎‎‏‎"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‎‏‏‏‎‎‏‎‏‏‎‏‎‏‏‏‏‎‏‎‏‏‎‎‏‏‏‎‏‎‏‎‏‎‎‏‎‏‏‎‎‏‎‏‎‏‏‎‏‏‏‏‎‎‎an unknown network type‎‏‎‎‏‎"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-es-rUS/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-es-rUS/strings.xml
index 9102dc0..e5f1833 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-es-rUS/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-es-rUS/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Accede a una red Wi-Fi."</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Acceder a la red"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>no tiene acceso a Internet"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Presiona para ver opciones"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"La red móvil no tiene acceso a Internet"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"La red no tiene acceso a Internet"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"No se puede acceder al servidor DNS privado"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> tiene conectividad limitada"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Presiona para conectarte de todas formas"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"Se cambió a <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"El dispositivo usa <xliff:g id="NEW_NETWORK">%1$s</xliff:g> cuando <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> no tiene acceso a Internet. Es posible que se apliquen cargos."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"Se cambió de <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> a <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"un tipo de red desconocido"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Recursos de conectividad del sistema"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Accede a una red Wi-Fi."</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Acceder a la red"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>no tiene acceso a Internet"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Presiona para ver opciones"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"La red móvil no tiene acceso a Internet"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"La red no tiene acceso a Internet"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"No se puede acceder al servidor DNS privado"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> tiene conectividad limitada"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Presiona para conectarte de todas formas"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"Se cambió a <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"El dispositivo usa <xliff:g id="NEW_NETWORK">%1$s</xliff:g> cuando <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> no tiene acceso a Internet. Es posible que se apliquen cargos."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"Se cambió de <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> a <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"Datos móviles"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Ethernet"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"Datos móviles"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Ethernet"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"un tipo de red desconocido"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-es/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-es/strings.xml
index 4c15566..e4f4307 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-es/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-es/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Iniciar sesión en red Wi-Fi"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Iniciar sesión en la red"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> no tiene acceso a Internet"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Toca para ver opciones"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"La red móvil no tiene acceso a Internet"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"La red no tiene acceso a Internet"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"No se ha podido acceder al servidor DNS privado"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> tiene una conectividad limitada"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Toca para conectarte de todas formas"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"Se ha cambiado a <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"El dispositivo utiliza <xliff:g id="NEW_NETWORK">%1$s</xliff:g> cuando <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> no tiene acceso a Internet. Es posible que se apliquen cargos."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"Se ha cambiado de <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> a <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"tipo de red desconocido"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Recursos de conectividad del sistema"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Iniciar sesión en red Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Iniciar sesión en la red"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> no tiene acceso a Internet"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Toca para ver opciones"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"La red móvil no tiene acceso a Internet"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"La red no tiene acceso a Internet"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"No se ha podido acceder al servidor DNS privado"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> tiene una conectividad limitada"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Toca para conectarte de todas formas"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"Se ha cambiado a <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"El dispositivo utiliza <xliff:g id="NEW_NETWORK">%1$s</xliff:g> cuando <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> no tiene acceso a Internet. Es posible que se apliquen cargos."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"Se ha cambiado de <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> a <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"datos móviles"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Ethernet"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"datos móviles"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Ethernet"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"un tipo de red desconocido"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-et/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-et/strings.xml
index 398223a..cec408f 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-et/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-et/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Logi sisse WiFi-võrku"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Võrku sisselogimine"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"Võrgul <xliff:g id="NETWORK_SSID">%1$s</xliff:g> puudub Interneti-ühendus"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Puudutage valikute nägemiseks"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"Mobiilsidevõrgul puudub Interneti-ühendus"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"Võrgul puudub Interneti-ühendus"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Privaatsele DNS-serverile ei pääse juurde"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"Võrgu <xliff:g id="NETWORK_SSID">%1$s</xliff:g> ühendus on piiratud"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Puudutage, kui soovite siiski ühenduse luua"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"Lülitati võrgule <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Seade kasutab võrku <xliff:g id="NEW_NETWORK">%1$s</xliff:g>, kui võrgul <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> puudub juurdepääs Internetile. Rakenduda võivad tasud."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"Lülitati võrgult <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> võrgule <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"tundmatu võrgutüüp"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Süsteemi ühenduvuse allikad"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Logi sisse WiFi-võrku"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Võrku sisselogimine"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"Võrgul <xliff:g id="NETWORK_SSID">%1$s</xliff:g> puudub Interneti-ühendus"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Puudutage valikute nägemiseks"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"Mobiilsidevõrgul puudub Interneti-ühendus"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"Võrgul puudub Interneti-ühendus"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Privaatsele DNS-serverile ei pääse juurde"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"Võrgu <xliff:g id="NETWORK_SSID">%1$s</xliff:g> ühendus on piiratud"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Puudutage, kui soovite siiski ühenduse luua"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"Lülitati võrgule <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"Seade kasutab võrku <xliff:g id="NEW_NETWORK">%1$s</xliff:g>, kui võrgul <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> puudub juurdepääs Internetile. Rakenduda võivad tasud."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"Lülitati võrgult <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> võrgule <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"mobiilne andmeside"</item>
-    <item msgid="5520925862115353992">"WiFi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Ethernet"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"mobiilne andmeside"</item>
+    <item msgid="6341719431034774569">"WiFi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Ethernet"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"tundmatu võrgutüüp"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-eu/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-eu/strings.xml
index dd70316..f3ee9b1 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-eu/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-eu/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Hasi saioa Wi-Fi sarean"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Hasi saioa sarean"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"Ezin da konektatu Internetera <xliff:g id="NETWORK_SSID">%1$s</xliff:g> sarearen bidez"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Sakatu aukerak ikusteko"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"Sare mugikorra ezin da konektatu Internetera"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"Sarea ezin da konektatu Internetera"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Ezin da atzitu DNS zerbitzari pribatua"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> sareak konektagarritasun murriztua du"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Sakatu hala ere konektatzeko"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> erabiltzen ari zara orain"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> Internetera konektatzeko gauza ez denean, <xliff:g id="NEW_NETWORK">%1$s</xliff:g> erabiltzen du gailuak. Agian kostuak ordaindu beharko dituzu."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> erabiltzen ari zinen, baina <xliff:g id="NEW_NETWORK">%2$s</xliff:g> erabiltzen ari zara orain"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"sare mota ezezaguna"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Sistemaren konexio-baliabideak"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Hasi saioa Wi-Fi sarean"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Hasi saioa sarean"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"Ezin da konektatu Internetera <xliff:g id="NETWORK_SSID">%1$s</xliff:g> sarearen bidez"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Sakatu aukerak ikusteko"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"Sare mugikorra ezin da konektatu Internetera"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"Sarea ezin da konektatu Internetera"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Ezin da atzitu DNS zerbitzari pribatua"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> sareak konektagarritasun murriztua du"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Sakatu hala ere konektatzeko"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> erabiltzen ari zara orain"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> Internetera konektatzeko gauza ez denean, <xliff:g id="NEW_NETWORK">%1$s</xliff:g> erabiltzen du gailuak. Agian kostuak ordaindu beharko dituzu."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> erabiltzen ari zinen, baina <xliff:g id="NEW_NETWORK">%2$s</xliff:g> erabiltzen ari zara orain"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"datu-konexioa"</item>
-    <item msgid="5520925862115353992">"Wifia"</item>
-    <item msgid="1055487873974272842">"Bluetooth-a"</item>
-    <item msgid="1616528372438698248">"Ethernet"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"datu-konexioa"</item>
+    <item msgid="6341719431034774569">"Wifia"</item>
+    <item msgid="5081440868800877512">"Bluetooth-a"</item>
+    <item msgid="1160736166977503463">"Ethernet-a"</item>
+    <item msgid="7347618872551558605">"VPNa"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"sare mota ezezaguna"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-fa/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-fa/strings.xml
index 46a946c..0c5b147 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-fa/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-fa/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"‏ورود به شبکه Wi-Fi"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"ورود به سیستم شبکه"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> به اینترنت دسترسی ندارد"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"برای گزینه‌ها ضربه بزنید"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"شبکه تلفن همراه به اینترنت دسترسی ندارد"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"شبکه به اینترنت دسترسی ندارد"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"‏سرور DNS خصوصی قابل دسترسی نیست"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> اتصال محدودی دارد"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"به‌هرصورت، برای اتصال ضربه بزنید"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"به <xliff:g id="NETWORK_TYPE">%1$s</xliff:g> تغییر کرد"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"وقتی <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> به اینترنت دسترسی نداشته باشد، دستگاه از <xliff:g id="NEW_NETWORK">%1$s</xliff:g> استفاده می‌کند. ممکن است هزینه‌هایی اعمال شود."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"از <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> به <xliff:g id="NEW_NETWORK">%2$s</xliff:g> تغییر کرد"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"نوع شبکه نامشخص"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"منابع اتصال سیستم"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"‏ورود به شبکه Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"ورود به سیستم شبکه"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> به اینترنت دسترسی ندارد"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"برای گزینه‌ها ضربه بزنید"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"شبکه تلفن همراه به اینترنت دسترسی ندارد"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"شبکه به اینترنت دسترسی ندارد"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"‏سرور DNS خصوصی قابل دسترسی نیست"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> اتصال محدودی دارد"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"به‌هرصورت، برای اتصال ضربه بزنید"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"به <xliff:g id="NETWORK_TYPE">%1$s</xliff:g> تغییر کرد"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"وقتی <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> به اینترنت دسترسی نداشته باشد، دستگاه از <xliff:g id="NEW_NETWORK">%1$s</xliff:g> استفاده می‌کند. ممکن است هزینه‌هایی اعمال شود."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"از <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> به <xliff:g id="NEW_NETWORK">%2$s</xliff:g> تغییر کرد"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"داده تلفن همراه"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"بلوتوث"</item>
-    <item msgid="1616528372438698248">"اترنت"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"داده تلفن همراه"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"بلوتوث"</item>
+    <item msgid="1160736166977503463">"اترنت"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"نوع شبکه نامشخص"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-fi/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-fi/strings.xml
index dd94441..84c0034 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-fi/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-fi/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Kirjaudu Wi-Fi-verkkoon"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Kirjaudu verkkoon"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ei ole yhteydessä internetiin"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Näytä vaihtoehdot napauttamalla."</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"Mobiiliverkko ei ole yhteydessä internetiin"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"Verkko ei ole yhteydessä internetiin"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Ei pääsyä yksityiselle DNS-palvelimelle"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> toimii rajoitetulla yhteydellä"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Yhdistä napauttamalla"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> otettiin käyttöön"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"<xliff:g id="NEW_NETWORK">%1$s</xliff:g> otetaan käyttöön, kun <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> ei voi muodostaa yhteyttä internetiin. Veloitukset ovat mahdollisia."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> poistettiin käytöstä ja <xliff:g id="NEW_NETWORK">%2$s</xliff:g> otettiin käyttöön."</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"tuntematon verkon tyyppi"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Järjestelmän yhteysresurssit"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Kirjaudu Wi-Fi-verkkoon"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Kirjaudu verkkoon"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ei ole yhteydessä internetiin"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Näytä vaihtoehdot napauttamalla."</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"Mobiiliverkko ei ole yhteydessä internetiin"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"Verkko ei ole yhteydessä internetiin"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Ei pääsyä yksityiselle DNS-palvelimelle"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> toimii rajoitetulla yhteydellä"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Yhdistä napauttamalla"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> otettiin käyttöön"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"<xliff:g id="NEW_NETWORK">%1$s</xliff:g> otetaan käyttöön, kun <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> ei voi muodostaa yhteyttä internetiin. Veloitukset ovat mahdollisia."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> poistettiin käytöstä ja <xliff:g id="NEW_NETWORK">%2$s</xliff:g> otettiin käyttöön."</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"mobiilidata"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Ethernet"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"mobiilidata"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Ethernet"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"tuntematon verkon tyyppi"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-fr-rCA/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-fr-rCA/strings.xml
index 02ef50b..0badf1b 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-fr-rCA/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-fr-rCA/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Connectez-vous au réseau Wi-Fi"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Connectez-vous au réseau"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"Le réseau <xliff:g id="NETWORK_SSID">%1$s</xliff:g> n\'offre aucun accès à Internet"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Touchez pour afficher les options"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"Le réseau cellulaire n\'offre aucun accès à Internet"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"Le réseau n\'offre aucun accès à Internet"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Impossible d\'accéder au serveur DNS privé"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"Le réseau <xliff:g id="NETWORK_SSID">%1$s</xliff:g> offre une connectivité limitée"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Touchez pour vous connecter quand même"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"Passé au réseau <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"L\'appareil utilise <xliff:g id="NEW_NETWORK">%1$s</xliff:g> quand <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> n\'a pas d\'accès à Internet. Des frais peuvent s\'appliquer."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"Passé du réseau <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> au <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"un type de réseau inconnu"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Ressources de connectivité système"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Connectez-vous au réseau Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Connectez-vous au réseau"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"Le réseau <xliff:g id="NETWORK_SSID">%1$s</xliff:g> n\'offre aucun accès à Internet"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Touchez pour afficher les options"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"Le réseau cellulaire n\'offre aucun accès à Internet"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"Le réseau n\'offre aucun accès à Internet"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Impossible d\'accéder au serveur DNS privé"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"Le réseau <xliff:g id="NETWORK_SSID">%1$s</xliff:g> offre une connectivité limitée"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Touchez pour vous connecter quand même"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"Passé au réseau <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"L\'appareil utilise <xliff:g id="NEW_NETWORK">%1$s</xliff:g> quand <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> n\'a pas d\'accès à Internet. Des frais peuvent s\'appliquer."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"Passé du réseau <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> au <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"données cellulaires"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Ethernet"</item>
-    <item msgid="9177085807664964627">"RPV"</item>
+    <item msgid="5454013645032700715">"données cellulaires"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Ethernet"</item>
+    <item msgid="7347618872551558605">"RPV"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"un type de réseau inconnu"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-fr/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-fr/strings.xml
index 08c9d81..b483525 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-fr/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-fr/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Connectez-vous au réseau Wi-Fi"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Se connecter au réseau"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"Aucune connexion à Internet pour <xliff:g id="NETWORK_SSID">%1$s</xliff:g>"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Appuyez ici pour afficher des options."</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"Le réseau mobile ne dispose d\'aucun accès à Internet"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"Le réseau ne dispose d\'aucun accès à Internet"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Impossible d\'accéder au serveur DNS privé"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"La connectivité de <xliff:g id="NETWORK_SSID">%1$s</xliff:g> est limitée"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Appuyer pour se connecter quand même"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"Nouveau réseau : <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"L\'appareil utilise <xliff:g id="NEW_NETWORK">%1$s</xliff:g> lorsque <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> n\'a pas de connexion Internet. Des frais peuvent s\'appliquer."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"Ancien réseau : <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>. Nouveau réseau : <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"type de réseau inconnu"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Ressources de connectivité système"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Connectez-vous au réseau Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Se connecter au réseau"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"Aucune connexion à Internet pour <xliff:g id="NETWORK_SSID">%1$s</xliff:g>"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Appuyez ici pour afficher des options."</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"Le réseau mobile ne dispose d\'aucun accès à Internet"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"Le réseau ne dispose d\'aucun accès à Internet"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Impossible d\'accéder au serveur DNS privé"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"La connectivité de <xliff:g id="NETWORK_SSID">%1$s</xliff:g> est limitée"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Appuyer pour se connecter quand même"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"Nouveau réseau : <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"L\'appareil utilise <xliff:g id="NEW_NETWORK">%1$s</xliff:g> lorsque <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> n\'a pas de connexion Internet. Des frais peuvent s\'appliquer."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"Ancien réseau : <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>. Nouveau réseau : <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"données mobiles"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Ethernet"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"données mobiles"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Ethernet"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"type de réseau inconnu"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-gl/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-gl/strings.xml
index 9f98055..dfe8137 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-gl/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-gl/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Inicia sesión na rede wifi"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Inicia sesión na rede"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> non ten acceso a Internet"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Toca para ver opcións."</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"A rede de telefonía móbil non ten acceso a Internet"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"A rede non ten acceso a Internet"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Non se puido acceder ao servidor DNS privado"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"A conectividade de <xliff:g id="NETWORK_SSID">%1$s</xliff:g> é limitada"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Toca para conectarte de todas formas"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"Cambiouse a: <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"O dispositivo utiliza <xliff:g id="NEW_NETWORK">%1$s</xliff:g> cando <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> non ten acceso a Internet. Pódense aplicar cargos."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"Cambiouse de <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> a <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"un tipo de rede descoñecido"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Recursos de conectividade do sistema"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Inicia sesión na rede wifi"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Inicia sesión na rede"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> non ten acceso a Internet"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Toca para ver opcións."</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"A rede de telefonía móbil non ten acceso a Internet"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"A rede non ten acceso a Internet"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Non se puido acceder ao servidor DNS privado"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"A conectividade de <xliff:g id="NETWORK_SSID">%1$s</xliff:g> é limitada"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Toca para conectarte de todas formas"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"Cambiouse a: <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"O dispositivo utiliza <xliff:g id="NEW_NETWORK">%1$s</xliff:g> cando <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> non ten acceso a Internet. Pódense aplicar cargos."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"Cambiouse de <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> a <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"datos móbiles"</item>
-    <item msgid="5520925862115353992">"wifi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Ethernet"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"datos móbiles"</item>
+    <item msgid="6341719431034774569">"wifi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Ethernet"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"un tipo de rede descoñecido"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-gu/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-gu/strings.xml
index 4ae5a2c..e49b11d 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-gu/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-gu/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"વાઇ-ફાઇ નેટવર્ક પર સાઇન ઇન કરો"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"નેટવર્ક પર સાઇન ઇન કરો"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ઇન્ટરનેટ ઍક્સેસ ધરાવતું નથી"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"વિકલ્પો માટે ટૅપ કરો"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"મોબાઇલ નેટવર્ક કોઈ ઇન્ટરનેટ ઍક્સેસ ધરાવતું નથી"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"નેટવર્ક કોઈ ઇન્ટરનેટ ઍક્સેસ ધરાવતું નથી"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"ખાનગી DNS સર્વર ઍક્સેસ કરી શકાતા નથી"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> મર્યાદિત કનેક્ટિવિટી ધરાવે છે"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"છતાં કનેક્ટ કરવા માટે ટૅપ કરો"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> પર સ્વિચ કર્યું"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"જ્યારે <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> પાસે કોઈ ઇન્ટરનેટ ઍક્સેસ ન હોય ત્યારે ઉપકરણ <xliff:g id="NEW_NETWORK">%1$s</xliff:g>નો ઉપયોગ કરે છે. શુલ્ક લાગુ થઈ શકે છે."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> પરથી <xliff:g id="NEW_NETWORK">%2$s</xliff:g> પર સ્વિચ કર્યું"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"અજાણ્યો નેટવર્ક પ્રકાર"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"સિસ્ટમની કનેક્ટિવિટીનાં સાધનો"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"વાઇ-ફાઇ નેટવર્ક પર સાઇન ઇન કરો"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"નેટવર્ક પર સાઇન ઇન કરો"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ઇન્ટરનેટ ઍક્સેસ ધરાવતું નથી"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"વિકલ્પો માટે ટૅપ કરો"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"મોબાઇલ નેટવર્ક કોઈ ઇન્ટરનેટ ઍક્સેસ ધરાવતું નથી"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"નેટવર્ક કોઈ ઇન્ટરનેટ ઍક્સેસ ધરાવતું નથી"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"ખાનગી DNS સર્વર ઍક્સેસ કરી શકાતા નથી"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> મર્યાદિત કનેક્ટિવિટી ધરાવે છે"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"છતાં કનેક્ટ કરવા માટે ટૅપ કરો"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> પર સ્વિચ કર્યું"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"જ્યારે <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> પાસે કોઈ ઇન્ટરનેટ ઍક્સેસ ન હોય ત્યારે ઉપકરણ <xliff:g id="NEW_NETWORK">%1$s</xliff:g>નો ઉપયોગ કરે છે. શુલ્ક લાગુ થઈ શકે છે."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> પરથી <xliff:g id="NEW_NETWORK">%2$s</xliff:g> પર સ્વિચ કર્યું"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"મોબાઇલ ડેટા"</item>
-    <item msgid="5520925862115353992">"વાઇ-ફાઇ"</item>
-    <item msgid="1055487873974272842">"બ્લૂટૂથ"</item>
-    <item msgid="1616528372438698248">"ઇથરનેટ"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"મોબાઇલ ડેટા"</item>
+    <item msgid="6341719431034774569">"વાઇ-ફાઇ"</item>
+    <item msgid="5081440868800877512">"બ્લૂટૂથ"</item>
+    <item msgid="1160736166977503463">"ઇથરનેટ"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"કોઈ અજાણ્યો નેટવર્કનો પ્રકાર"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-hi/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-hi/strings.xml
index eff1b60..80ed699 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-hi/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-hi/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"वाई-फ़ाई  नेटवर्क में साइन इन करें"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"नेटवर्क में साइन इन करें"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> का इंटरनेट नहीं चल रहा है"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"विकल्पों के लिए टैप करें"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"मोबाइल नेटवर्क पर इंटरनेट ऐक्सेस नहीं है"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"इस नेटवर्क पर इंटरनेट ऐक्सेस नहीं है"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"निजी डीएनएस सर्वर को ऐक्सेस नहीं किया जा सकता"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> की कनेक्टिविटी सीमित है"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"फिर भी कनेक्ट करने के लिए टैप करें"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> पर ले जाया गया"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> में इंटरनेट की सुविधा नहीं होने पर डिवाइस <xliff:g id="NEW_NETWORK">%1$s</xliff:g> का इस्तेमाल करता है. इसके लिए शुल्क लिया जा सकता है."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> से <xliff:g id="NEW_NETWORK">%2$s</xliff:g> पर ले जाया गया"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"अज्ञात नेटवर्क प्रकार"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"सिस्टम कनेक्टिविटी के संसाधन"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"वाई-फ़ाई  नेटवर्क में साइन इन करें"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"नेटवर्क में साइन इन करें"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> का इंटरनेट नहीं चल रहा है"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"विकल्पों के लिए टैप करें"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"मोबाइल नेटवर्क पर इंटरनेट ऐक्सेस नहीं है"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"इस नेटवर्क पर इंटरनेट ऐक्सेस नहीं है"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"निजी डीएनएस सर्वर को ऐक्सेस नहीं किया जा सकता"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> की कनेक्टिविटी सीमित है"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"फिर भी कनेक्ट करने के लिए टैप करें"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> पर ले जाया गया"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> में इंटरनेट की सुविधा नहीं होने पर डिवाइस <xliff:g id="NEW_NETWORK">%1$s</xliff:g> का इस्तेमाल करता है. इसके लिए शुल्क लिया जा सकता है."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> से <xliff:g id="NEW_NETWORK">%2$s</xliff:g> पर ले जाया गया"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"मोबाइल डेटा"</item>
-    <item msgid="5520925862115353992">"वाई-फ़ाई"</item>
-    <item msgid="1055487873974272842">"ब्लूटूथ"</item>
-    <item msgid="1616528372438698248">"ईथरनेट"</item>
-    <item msgid="9177085807664964627">"वीपीएन"</item>
+    <item msgid="5454013645032700715">"मोबाइल डेटा"</item>
+    <item msgid="6341719431034774569">"वाई-फ़ाई"</item>
+    <item msgid="5081440868800877512">"ब्लूटूथ"</item>
+    <item msgid="1160736166977503463">"ईथरनेट"</item>
+    <item msgid="7347618872551558605">"वीपीएन"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"अज्ञात नेटवर्क टाइप"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-hr/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-hr/strings.xml
index 52bfb93..24bb22f 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-hr/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-hr/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Prijava na Wi-Fi mrežu"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Prijava na mrežu"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> nema pristup internetu"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Dodirnite za opcije"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"Mobilna mreža nema pristup internetu"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"Mreža nema pristup internetu"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Nije moguće pristupiti privatnom DNS poslužitelju"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ima ograničenu povezivost"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Dodirnite da biste se ipak povezali"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"Prelazak na drugu mrežu: <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Kada <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> nema pristup internetu, na uređaju se upotrebljava <xliff:g id="NEW_NETWORK">%1$s</xliff:g>. Moguća je naplata naknade."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"Mreža je promijenjena: <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> &gt; <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"nepoznata vrsta mreže"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Resursi za povezivost sustava"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Prijava na Wi-Fi mrežu"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Prijava na mrežu"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> nema pristup internetu"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Dodirnite za opcije"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"Mobilna mreža nema pristup internetu"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"Mreža nema pristup internetu"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Nije moguće pristupiti privatnom DNS poslužitelju"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ima ograničenu povezivost"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Dodirnite da biste se ipak povezali"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"Prelazak na drugu mrežu: <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"Kada <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> nema pristup internetu, na uređaju se upotrebljava <xliff:g id="NEW_NETWORK">%1$s</xliff:g>. Moguća je naplata naknade."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"Mreža je promijenjena: <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> &gt; <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"mobilni podaci"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Ethernet"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"mobilni podaci"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Ethernet"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"nepoznata vrsta mreže"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-hu/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-hu/strings.xml
index 2ff59b5..47a1142 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-hu/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-hu/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Bejelentkezés Wi-Fi hálózatba"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Bejelentkezés a hálózatba"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"A(z) <xliff:g id="NETWORK_SSID">%1$s</xliff:g> hálózaton nincs internet-hozzáférés"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Koppintson a beállítások megjelenítéséhez"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"A mobilhálózaton nincs internet-hozzáférés"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"A hálózaton nincs internet-hozzáférés"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"A privát DNS-kiszolgálóhoz nem lehet hozzáférni"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"A(z) <xliff:g id="NETWORK_SSID">%1$s</xliff:g> hálózat korlátozott kapcsolatot biztosít"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Koppintson, ha mindenképpen csatlakozni szeretne"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"Átváltva erre: <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"<xliff:g id="NEW_NETWORK">%1$s</xliff:g> használata, ha nincs internet-hozzáférés <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>-kapcsolaton keresztül. A szolgáltató díjat számíthat fel."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"Átváltva <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>-hálózatról erre: <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"ismeretlen hálózati típus"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Rendszerkapcsolat erőforrásai"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Bejelentkezés Wi-Fi hálózatba"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Bejelentkezés a hálózatba"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"A(z) <xliff:g id="NETWORK_SSID">%1$s</xliff:g> hálózaton nincs internet-hozzáférés"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Koppintson a beállítások megjelenítéséhez"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"A mobilhálózaton nincs internet-hozzáférés"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"A hálózaton nincs internet-hozzáférés"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"A privát DNS-kiszolgálóhoz nem lehet hozzáférni"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"A(z) <xliff:g id="NETWORK_SSID">%1$s</xliff:g> hálózat korlátozott kapcsolatot biztosít"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Koppintson, ha mindenképpen csatlakozni szeretne"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"Átváltva erre: <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"<xliff:g id="NEW_NETWORK">%1$s</xliff:g> használata, ha nincs internet-hozzáférés <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>-kapcsolaton keresztül. A szolgáltató díjat számíthat fel."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"Átváltva <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>-hálózatról erre: <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"mobiladatok"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Ethernet"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"mobiladatok"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Ethernet"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"ismeretlen hálózati típus"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-hy/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-hy/strings.xml
index b35d31c..dd951e8 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-hy/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-hy/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Մուտք գործեք Wi-Fi ցանց"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Մուտք գործեք ցանց"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ցանցը չունի մուտք ինտերնետին"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Հպեք՝ ընտրանքները տեսնելու համար"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"Բջջային ցանցը չի ապահովում ինտերնետ կապ"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"Ցանցը միացված չէ ինտերնետին"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Մասնավոր DNS սերվերն անհասանելի է"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ցանցի կապը սահմանափակ է"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Հպեք՝ միանալու համար"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"Անցել է <xliff:g id="NETWORK_TYPE">%1$s</xliff:g> ցանցի"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Երբ <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> ցանցում ինտերնետ կապ չի լինում, սարքն անցնում է <xliff:g id="NEW_NETWORK">%1$s</xliff:g> ցանցի: Նման դեպքում կարող են վճարներ գանձվել:"</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> ցանցից անցել է <xliff:g id="NEW_NETWORK">%2$s</xliff:g> ցանցի"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"ցանցի անհայտ տեսակ"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"System Connectivity Resources"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Մուտք գործեք Wi-Fi ցանց"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Մուտք գործեք ցանց"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ցանցը չունի մուտք ինտերնետին"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Հպեք՝ ընտրանքները տեսնելու համար"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"Բջջային ցանցը չի ապահովում ինտերնետ կապ"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"Ցանցը միացված չէ ինտերնետին"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Մասնավոր DNS սերվերն անհասանելի է"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ցանցի կապը սահմանափակ է"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Հպեք՝ միանալու համար"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"Անցել է <xliff:g id="NETWORK_TYPE">%1$s</xliff:g> ցանցի"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"Երբ <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> ցանցում ինտերնետ կապ չի լինում, սարքն անցնում է <xliff:g id="NEW_NETWORK">%1$s</xliff:g> ցանցի: Նման դեպքում կարող են վճարներ գանձվել:"</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> ցանցից անցել է <xliff:g id="NEW_NETWORK">%2$s</xliff:g> ցանցի"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"բջջային ինտերնետ"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Ethernet"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"բջջային ինտերնետ"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Ethernet"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"ցանցի անհայտ տեսակ"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-in/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-in/strings.xml
index 27d7d89..d559f6b 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-in/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-in/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Login ke jaringan Wi-Fi"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Login ke jaringan"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> tidak memiliki akses internet"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Ketuk untuk melihat opsi"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"Jaringan seluler tidak memiliki akses internet"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"Jaringan tidak memiliki akses internet"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Server DNS pribadi tidak dapat diakses"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> memiliki konektivitas terbatas"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Ketuk untuk tetap menyambungkan"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"Dialihkan ke <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Perangkat menggunakan <xliff:g id="NEW_NETWORK">%1$s</xliff:g> jika <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> tidak memiliki akses internet. Tarif mungkin berlaku."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"Dialihkan dari <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> ke <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"jenis jaringan yang tidak dikenal"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Resource Konektivitas Sistem"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Login ke jaringan Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Login ke jaringan"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> tidak memiliki akses internet"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Ketuk untuk melihat opsi"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"Jaringan seluler tidak memiliki akses internet"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"Jaringan tidak memiliki akses internet"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Server DNS pribadi tidak dapat diakses"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> memiliki konektivitas terbatas"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Ketuk untuk tetap menyambungkan"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"Dialihkan ke <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"Perangkat menggunakan <xliff:g id="NEW_NETWORK">%1$s</xliff:g> jika <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> tidak memiliki akses internet. Tarif mungkin berlaku."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"Dialihkan dari <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> ke <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"data seluler"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Ethernet"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"data seluler"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Ethernet"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"jenis jaringan yang tidak dikenal"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-is/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-is/strings.xml
index 97f42dc..877c85f 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-is/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-is/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Skrá inn á Wi-Fi net"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Skrá inn á net"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> er ekki með internetaðgang"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Ýttu til að sjá valkosti"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"Farsímakerfið er ekki tengt við internetið"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"Netkerfið er ekki tengt við internetið"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Ekki næst í DNS-einkaþjón"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"Tengigeta <xliff:g id="NETWORK_SSID">%1$s</xliff:g> er takmörkuð"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Ýttu til að tengjast samt"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"Skipt yfir á <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Tækið notar <xliff:g id="NEW_NETWORK">%1$s</xliff:g> þegar <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> er ekki með internetaðgang. Gjöld kunna að eiga við."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"Skipt úr <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> yfir í <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"óþekkt tegund netkerfis"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Tengigögn kerfis"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Skrá inn á Wi-Fi net"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Skrá inn á net"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> er ekki með internetaðgang"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Ýttu til að sjá valkosti"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"Farsímakerfið er ekki tengt við internetið"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"Netkerfið er ekki tengt við internetið"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Ekki næst í DNS-einkaþjón"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"Tengigeta <xliff:g id="NETWORK_SSID">%1$s</xliff:g> er takmörkuð"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Ýttu til að tengjast samt"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"Skipt yfir á <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"Tækið notar <xliff:g id="NEW_NETWORK">%1$s</xliff:g> þegar <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> er ekki með internetaðgang. Gjöld kunna að eiga við."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"Skipt úr <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> yfir í <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"farsímagögn"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Ethernet"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"farsímagögn"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Ethernet"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"óþekkt tegund netkerfis"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-it/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-it/strings.xml
index 7836101..bcac393 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-it/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-it/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Accedi a rete Wi-Fi"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Accedi alla rete"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> non ha accesso a Internet"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Tocca per le opzioni"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"La rete mobile non ha accesso a Internet"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"La rete non ha accesso a Internet"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Non è possibile accedere al server DNS privato"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ha una connettività limitata"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Tocca per connettere comunque"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"Passato a <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Il dispositivo utilizza <xliff:g id="NEW_NETWORK">%1$s</xliff:g> quando <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> non ha accesso a Internet. Potrebbero essere applicati costi."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"Passato da <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> a <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"tipo di rete sconosciuto"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Risorse per connettività di sistema"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Accedi a rete Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Accedi alla rete"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> non ha accesso a Internet"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Tocca per le opzioni"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"La rete mobile non ha accesso a Internet"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"La rete non ha accesso a Internet"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Non è possibile accedere al server DNS privato"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ha una connettività limitata"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Tocca per connettere comunque"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"Passato a <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"Il dispositivo utilizza <xliff:g id="NEW_NETWORK">%1$s</xliff:g> quando <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> non ha accesso a Internet. Potrebbero essere applicati costi."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"Passato da <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> a <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"dati mobili"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Ethernet"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"dati mobili"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Ethernet"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"tipo di rete sconosciuto"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-iw/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-iw/strings.xml
index f322b99..d6684ce 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-iw/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-iw/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"‏היכנס לרשת Wi-Fi"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"היכנס לרשת"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"ל-<xliff:g id="NETWORK_SSID">%1$s</xliff:g> אין גישה לאינטרנט"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"הקש לקבלת אפשרויות"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"לרשת הסלולרית אין גישה לאינטרנט"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"לרשת אין גישה לאינטרנט"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"‏לא ניתן לגשת לשרת DNS הפרטי"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"הקישוריות של <xliff:g id="NETWORK_SSID">%1$s</xliff:g> מוגבלת"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"כדי להתחבר למרות זאת יש להקיש"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"מעבר אל <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"המכשיר משתמש ברשת <xliff:g id="NEW_NETWORK">%1$s</xliff:g> כשלרשת <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> אין גישה לאינטרנט. עשויים לחול חיובים."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"עבר מרשת <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> לרשת <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"סוג רשת לא מזוהה"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"משאבי קישוריות מערכת"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"‏היכנס לרשת Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"היכנס לרשת"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"ל-<xliff:g id="NETWORK_SSID">%1$s</xliff:g> אין גישה לאינטרנט"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"הקש לקבלת אפשרויות"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"לרשת הסלולרית אין גישה לאינטרנט"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"לרשת אין גישה לאינטרנט"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"‏לא ניתן לגשת לשרת DNS הפרטי"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"הקישוריות של <xliff:g id="NETWORK_SSID">%1$s</xliff:g> מוגבלת"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"כדי להתחבר למרות זאת יש להקיש"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"מעבר אל <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"המכשיר משתמש ברשת <xliff:g id="NEW_NETWORK">%1$s</xliff:g> כשלרשת <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> אין גישה לאינטרנט. עשויים לחול חיובים."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"עבר מרשת <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> לרשת <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"חבילת גלישה"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Ethernet"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"חבילת גלישה"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"אתרנט"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"סוג רשת לא מזוהה"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ja/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ja/strings.xml
index 1aa3216..fa4a30a 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ja/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ja/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Wi-Fiネットワークにログイン"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"ネットワークにログインしてください"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> はインターネットにアクセスできません"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"タップしてその他のオプションを表示"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"モバイル ネットワークがインターネットに接続されていません"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"ネットワークがインターネットに接続されていません"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"プライベート DNS サーバーにアクセスできません"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> の接続が制限されています"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"接続するにはタップしてください"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"「<xliff:g id="NETWORK_TYPE">%1$s</xliff:g>」に切り替えました"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"デバイスで「<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>」によるインターネット接続ができない場合に「<xliff:g id="NEW_NETWORK">%1$s</xliff:g>」を使用します。通信料が発生することがあります。"</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"「<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>」から「<xliff:g id="NEW_NETWORK">%2$s</xliff:g>」に切り替えました"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"不明なネットワーク タイプ"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"システム接続リソース"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Wi-Fiネットワークにログイン"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"ネットワークにログインしてください"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> はインターネットにアクセスできません"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"タップしてその他のオプションを表示"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"モバイル ネットワークがインターネットに接続されていません"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"ネットワークがインターネットに接続されていません"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"プライベート DNS サーバーにアクセスできません"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> の接続が制限されています"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"接続するにはタップしてください"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"「<xliff:g id="NETWORK_TYPE">%1$s</xliff:g>」に切り替えました"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"デバイスで「<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>」によるインターネット接続ができない場合に「<xliff:g id="NEW_NETWORK">%1$s</xliff:g>」を使用します。通信料が発生することがあります。"</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"「<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>」から「<xliff:g id="NEW_NETWORK">%2$s</xliff:g>」に切り替えました"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"モバイルデータ"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"イーサネット"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"モバイルデータ"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"イーサネット"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"不明なネットワーク タイプ"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ka/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ka/strings.xml
index 61d21b5..4183310 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ka/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ka/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Wi-Fi ქსელთან დაკავშირება"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"ქსელში შესვლა"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>-ს არ აქვს ინტერნეტზე წვდომა"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"შეეხეთ ვარიანტების სანახავად"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"მობილურ ქსელს არ აქვს ინტერნეტზე წვდომა"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"ქსელს არ აქვს ინტერნეტზე წვდომა"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"პირად DNS სერვერზე წვდომა შეუძლებელია"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>-ის კავშირები შეზღუდულია"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"შეეხეთ, თუ მაინც გსურთ დაკავშირება"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"ახლა გამოიყენება <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"თუ <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> ინტერნეტთან კავშირს დაკარგავს, მოწყობილობის მიერ <xliff:g id="NEW_NETWORK">%1$s</xliff:g> იქნება გამოყენებული, რამაც შეიძლება დამატებითი ხარჯები გამოიწვიოს."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"ახლა გამოიყენება <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> (გამოიყენებოდა <xliff:g id="NEW_NETWORK">%2$s</xliff:g>)"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"უცნობი ტიპის ქსელი"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"სისტემის კავშირის რესურსები"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Wi-Fi ქსელთან დაკავშირება"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"ქსელში შესვლა"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>-ს არ აქვს ინტერნეტზე წვდომა"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"შეეხეთ ვარიანტების სანახავად"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"მობილურ ქსელს არ აქვს ინტერნეტზე წვდომა"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"ქსელს არ აქვს ინტერნეტზე წვდომა"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"პირად DNS სერვერზე წვდომა შეუძლებელია"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>-ის კავშირები შეზღუდულია"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"შეეხეთ, თუ მაინც გსურთ დაკავშირება"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"ახლა გამოიყენება <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"თუ <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> ინტერნეტთან კავშირს დაკარგავს, მოწყობილობის მიერ <xliff:g id="NEW_NETWORK">%1$s</xliff:g> იქნება გამოყენებული, რამაც შეიძლება დამატებითი ხარჯები გამოიწვიოს."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"ახლა გამოიყენება <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> (გამოიყენებოდა <xliff:g id="NEW_NETWORK">%2$s</xliff:g>)"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"მობილური ინტერნეტი"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Ethernet"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"მობილური ინტერნეტი"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Ethernet"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"უცნობი ტიპის ქსელი"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-kk/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-kk/strings.xml
index 969aaef..54d5eb3 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-kk/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-kk/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Wi-Fi желісіне кіру"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Желіге кіру"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> желісінің интернетті пайдалану мүмкіндігі шектеулі."</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Опциялар үшін түртіңіз"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"Мобильдік желі интернетке қосылмаған."</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"Желі интернетке қосылмаған."</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Жеке DNS серверіне кіру мүмкін емес."</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> желісінің қосылу мүмкіндігі шектеулі."</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Бәрібір жалғау үшін түртіңіз."</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> желісіне ауысты"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Құрылғы <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> желісінде интернетпен байланыс жоғалған жағдайда <xliff:g id="NEW_NETWORK">%1$s</xliff:g> желісін пайдаланады. Деректер ақысы алынуы мүмкін."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> желісінен <xliff:g id="NEW_NETWORK">%2$s</xliff:g> желісіне ауысты"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"желі түрі белгісіз"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Жүйе байланысы ресурстары"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Wi-Fi желісіне кіру"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Желіге кіру"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> желісінің интернетті пайдалану мүмкіндігі шектеулі."</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Опциялар үшін түртіңіз"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"Мобильдік желі интернетке қосылмаған."</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"Желі интернетке қосылмаған."</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Жеке DNS серверіне кіру мүмкін емес."</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> желісінің қосылу мүмкіндігі шектеулі."</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Бәрібір жалғау үшін түртіңіз."</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> желісіне ауысты"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"Құрылғы <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> желісінде интернетпен байланыс жоғалған жағдайда <xliff:g id="NEW_NETWORK">%1$s</xliff:g> желісін пайдаланады. Деректер ақысы алынуы мүмкін."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> желісінен <xliff:g id="NEW_NETWORK">%2$s</xliff:g> желісіне ауысты"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"мобильдік деректер"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Ethernet"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"мобильдік деректер"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Ethernet"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"желі түрі белгісіз"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-km/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-km/strings.xml
index da3c337..bd778a1 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-km/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-km/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"ចូល​បណ្ដាញ​វ៉ាយហ្វាយ"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"ចូលទៅបណ្តាញ"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> មិនមាន​ការតភ្ជាប់អ៊ីនធឺណិត​ទេ"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"ប៉ះសម្រាប់ជម្រើស"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"បណ្ដាញ​ទូរសព្ទ​ចល័ត​មិនមានការតភ្ជាប់​អ៊ីនធឺណិតទេ"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"បណ្ដាញ​មិនមាន​ការតភ្ជាប់​អ៊ីនធឺណិតទេ"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"មិនអាច​ចូលប្រើ​ម៉ាស៊ីនមេ DNS ឯកជន​បានទេ"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> មានការតភ្ជាប់​មានកម្រិត"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"មិន​អី​ទេ ចុច​​ភ្ជាប់​ចុះ"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"បានប្តូរទៅ <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"ឧបករណ៍​ប្រើ <xliff:g id="NEW_NETWORK">%1$s</xliff:g> នៅ​ពេល​ដែល <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> មិនមាន​ការ​តភ្ជាប់​អ៊ីនធឺណិត។ អាច​គិតថ្លៃ​លើការ​ប្រើប្រាស់​ទិន្នន័យ។"</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"បានប្តូរពី <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> ទៅ <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"ប្រភេទបណ្តាញមិនស្គាល់"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"ធនធាន​តភ្ជាប់​ប្រព័ន្ធ"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"ចូល​បណ្ដាញ​វ៉ាយហ្វាយ"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"ចូលទៅបណ្តាញ"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> មិនមាន​ការតភ្ជាប់អ៊ីនធឺណិត​ទេ"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"ប៉ះសម្រាប់ជម្រើស"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"បណ្ដាញ​ទូរសព្ទ​ចល័ត​មិនមានការតភ្ជាប់​អ៊ីនធឺណិតទេ"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"បណ្ដាញ​មិនមាន​ការតភ្ជាប់​អ៊ីនធឺណិតទេ"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"មិនអាច​ចូលប្រើ​ម៉ាស៊ីនមេ DNS ឯកជន​បានទេ"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> មានការតភ្ជាប់​មានកម្រិត"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"មិន​អី​ទេ ចុច​​ភ្ជាប់​ចុះ"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"បានប្តូរទៅ <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"ឧបករណ៍​ប្រើ <xliff:g id="NEW_NETWORK">%1$s</xliff:g> នៅ​ពេល​ដែល <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> មិនមាន​ការ​តភ្ជាប់​អ៊ីនធឺណិត។ អាច​គិតថ្លៃ​លើការ​ប្រើប្រាស់​ទិន្នន័យ។"</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"បានប្តូរពី <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> ទៅ <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"ទិន្នន័យ​ទូរសព្ទចល័ត"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"ប៊្លូធូស"</item>
-    <item msgid="1616528372438698248">"អ៊ីសឺរណិត"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"ទិន្នន័យ​ទូរសព្ទចល័ត"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"ប៊្លូធូស"</item>
+    <item msgid="1160736166977503463">"អ៊ីសឺរណិត"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"ប្រភេទបណ្តាញដែលមិនស្គាល់"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-kn/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-kn/strings.xml
index 3b5e047..7f3a420 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-kn/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-kn/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"ವೈ-ಫೈ ನೆಟ್‍ವರ್ಕ್‌ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಿ"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"ನೆಟ್‌ವರ್ಕ್‌ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಿ"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ಯಾವುದೇ ಇಂಟರ್ನೆಟ್ ಸಂಪರ್ಕವನ್ನು ಹೊಂದಿಲ್ಲ"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"ಆಯ್ಕೆಗಳಿಗೆ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"ಮೊಬೈಲ್ ನೆಟ್‌ವರ್ಕ್‌ ಯಾವುದೇ ಇಂಟರ್ನೆಟ್ ಪ್ರವೇಶವನ್ನು ಹೊಂದಿಲ್ಲ"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"ನೆಟ್‌ವರ್ಕ್‌ ಇಂಟರ್ನೆಟ್‌ ಪ್ರವೇಶವನ್ನು ಹೊಂದಿಲ್ಲ"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"ಖಾಸಗಿ DNS ಸರ್ವರ್ ಅನ್ನು ಪ್ರವೇಶಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ಸೀಮಿತ ಸಂಪರ್ಕ ಕಲ್ಪಿಸುವಿಕೆಯನ್ನು ಹೊಂದಿದೆ"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"ಹೇಗಾದರೂ ಸಂಪರ್ಕಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> ಗೆ ಬದಲಾಯಿಸಲಾಗಿದೆ"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> ಇಂಟರ್ನೆಟ್ ಪ್ರವೇಶ ಹೊಂದಿಲ್ಲದಿರುವಾಗ, ಸಾಧನವು <xliff:g id="NEW_NETWORK">%1$s</xliff:g> ಬಳಸುತ್ತದೆ. ಶುಲ್ಕಗಳು ಅನ್ವಯವಾಗಬಹುದು."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> ರಿಂದ <xliff:g id="NEW_NETWORK">%2$s</xliff:g> ಗೆ ಬದಲಾಯಿಸಲಾಗಿದೆ"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"ಅಪರಿಚಿತ ನೆಟ್‌ವರ್ಕ್ ಪ್ರಕಾರ"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"ಸಿಸ್ಟಂ ಸಂಪರ್ಕ ಕಲ್ಪಿಸುವಿಕೆ ಮಾಹಿತಿಯ ಮೂಲಗಳು"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"ವೈ-ಫೈ ನೆಟ್‍ವರ್ಕ್‌ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಿ"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"ನೆಟ್‌ವರ್ಕ್‌ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಿ"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ಯಾವುದೇ ಇಂಟರ್ನೆಟ್ ಸಂಪರ್ಕವನ್ನು ಹೊಂದಿಲ್ಲ"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"ಆಯ್ಕೆಗಳಿಗೆ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"ಮೊಬೈಲ್ ನೆಟ್‌ವರ್ಕ್‌ ಯಾವುದೇ ಇಂಟರ್ನೆಟ್ ಪ್ರವೇಶವನ್ನು ಹೊಂದಿಲ್ಲ"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"ನೆಟ್‌ವರ್ಕ್‌ ಇಂಟರ್ನೆಟ್‌ ಪ್ರವೇಶವನ್ನು ಹೊಂದಿಲ್ಲ"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"ಖಾಸಗಿ DNS ಸರ್ವರ್ ಅನ್ನು ಪ್ರವೇಶಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ಸೀಮಿತ ಸಂಪರ್ಕ ಕಲ್ಪಿಸುವಿಕೆಯನ್ನು ಹೊಂದಿದೆ"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"ಹೇಗಾದರೂ ಸಂಪರ್ಕಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> ಗೆ ಬದಲಾಯಿಸಲಾಗಿದೆ"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> ಇಂಟರ್ನೆಟ್ ಪ್ರವೇಶ ಹೊಂದಿಲ್ಲದಿರುವಾಗ, ಸಾಧನವು <xliff:g id="NEW_NETWORK">%1$s</xliff:g> ಬಳಸುತ್ತದೆ. ಶುಲ್ಕಗಳು ಅನ್ವಯವಾಗಬಹುದು."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> ರಿಂದ <xliff:g id="NEW_NETWORK">%2$s</xliff:g> ಗೆ ಬದಲಾಯಿಸಲಾಗಿದೆ"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"ಮೊಬೈಲ್ ಡೇಟಾ"</item>
-    <item msgid="5520925862115353992">"ವೈ-ಫೈ"</item>
-    <item msgid="1055487873974272842">"ಬ್ಲೂಟೂತ್‌"</item>
-    <item msgid="1616528372438698248">"ಇಥರ್ನೆಟ್"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"ಮೊಬೈಲ್ ಡೇಟಾ"</item>
+    <item msgid="6341719431034774569">"ವೈ-ಫೈ"</item>
+    <item msgid="5081440868800877512">"ಬ್ಲೂಟೂತ್"</item>
+    <item msgid="1160736166977503463">"ಇಥರ್ನೆಟ್"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"ಅಪರಿಚಿತ ನೆಟ್‌ವರ್ಕ್ ಪ್ರಕಾರ"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ko/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ko/strings.xml
index 874bd75..a763cc5 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ko/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ko/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Wi-Fi 네트워크에 로그인"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"네트워크에 로그인"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>이(가) 인터넷에 액세스할 수 없습니다."</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"탭하여 옵션 보기"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"모바일 네트워크에 인터넷이 연결되어 있지 않습니다."</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"네트워크에 인터넷이 연결되어 있지 않습니다."</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"비공개 DNS 서버에 액세스할 수 없습니다."</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>에서 연결을 제한했습니다."</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"계속 연결하려면 탭하세요."</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g>(으)로 전환"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>(으)로 인터넷에 연결할 수 없는 경우 기기에서 <xliff:g id="NEW_NETWORK">%1$s</xliff:g>이(가) 사용됩니다. 요금이 부과될 수 있습니다."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>에서 <xliff:g id="NEW_NETWORK">%2$s</xliff:g>(으)로 전환"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"알 수 없는 네트워크 유형"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"시스템 연결 리소스"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Wi-Fi 네트워크에 로그인"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"네트워크에 로그인"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>이(가) 인터넷에 액세스할 수 없습니다."</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"탭하여 옵션 보기"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"모바일 네트워크에 인터넷이 연결되어 있지 않습니다."</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"네트워크에 인터넷이 연결되어 있지 않습니다."</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"비공개 DNS 서버에 액세스할 수 없습니다."</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>에서 연결을 제한했습니다."</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"계속 연결하려면 탭하세요."</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g>(으)로 전환"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>(으)로 인터넷에 연결할 수 없는 경우 기기에서 <xliff:g id="NEW_NETWORK">%1$s</xliff:g>이(가) 사용됩니다. 요금이 부과될 수 있습니다."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>에서 <xliff:g id="NEW_NETWORK">%2$s</xliff:g>(으)로 전환"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"모바일 데이터"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"블루투스"</item>
-    <item msgid="1616528372438698248">"이더넷"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"모바일 데이터"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"블루투스"</item>
+    <item msgid="1160736166977503463">"이더넷"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"알 수 없는 네트워크 유형"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ky/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ky/strings.xml
index 1ace4dc..3550af8 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ky/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ky/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Wi-Fi түйүнүнө кирүү"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Тармакка кирүү"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> Интернетке туташуусу жок"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Параметрлерди ачуу үчүн таптап коюңуз"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"Мобилдик Интернет жок"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"Тармактын Интернет жок"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Жеке DNS сервери жеткиликсиз"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> байланышы чектелген"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Баары бир туташуу үчүн таптаңыз"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> тармагына которуштурулду"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> тармагы Интернетке туташпай турганда, түзмөгүңүз <xliff:g id="NEW_NETWORK">%1$s</xliff:g> тармагын колдонот. Акы алынышы мүмкүн."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> дегенден <xliff:g id="NEW_NETWORK">%2$s</xliff:g> тармагына которуштурулду"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"белгисиз тармак түрү"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Тутумдун байланыш булагы"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Wi-Fi түйүнүнө кирүү"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Тармакка кирүү"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> Интернетке туташуусу жок"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Параметрлерди ачуу үчүн таптап коюңуз"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"Мобилдик Интернет жок"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"Тармактын Интернет жок"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Жеке DNS сервери жеткиликсиз"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> байланышы чектелген"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Баары бир туташуу үчүн таптаңыз"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> тармагына которуштурулду"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> тармагы Интернетке туташпай турганда, түзмөгүңүз <xliff:g id="NEW_NETWORK">%1$s</xliff:g> тармагын колдонот. Акы алынышы мүмкүн."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> дегенден <xliff:g id="NEW_NETWORK">%2$s</xliff:g> тармагына которуштурулду"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"мобилдик трафик"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Ethernet"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"мобилдик трафик"</item>
+    <item msgid="6341719431034774569">"Wi‑Fi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Ethernet"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"белгисиз тармак түрү"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-lo/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-lo/strings.xml
index 3db497e..4b3056f 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-lo/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-lo/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"ເຂົ້າສູ່ລະບົບເຄືອຂ່າຍ Wi-Fi"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"ລົງຊື່ເຂົ້າເຄືອຂ່າຍ"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ບໍ່ມີການເຊື່ອມຕໍ່ອິນເຕີເນັດ"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"ແຕະເພື່ອເບິ່ງຕົວເລືອກ"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"ເຄືອຂ່າຍມືຖືບໍ່ສາມາດເຂົ້າເຖິງອິນເຕີເນັດໄດ້"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"ເຄືອຂ່າຍບໍ່ສາມາດເຂົ້າເຖິງອິນເຕີເນັດໄດ້"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"ບໍ່ສາມາດເຂົ້າເຖິງເຊີບເວີ DNS ສ່ວນຕົວໄດ້"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ມີການເຊື່ອມຕໍ່ທີ່ຈຳກັດ"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"ແຕະເພື່ອຢືນຢັນການເຊື່ອມຕໍ່"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"ສະຫຼັບໄປໃຊ້ <xliff:g id="NETWORK_TYPE">%1$s</xliff:g> ແລ້ວ"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"ອຸປະກອນຈະໃຊ້ <xliff:g id="NEW_NETWORK">%1$s</xliff:g> ເມື່ອ <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> ບໍ່ມີການເຊື່ອມຕໍ່ອິນເຕີເນັດ. ອາດມີການຮຽກເກັບຄ່າບໍລິການ."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"ສະຫຼັບຈາກ <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> ໄປໃຊ້ <xliff:g id="NEW_NETWORK">%2$s</xliff:g> ແລ້ວ"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"ບໍ່ຮູ້ຈັກປະເພດເຄືອຂ່າຍ"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"ແຫຼ່ງຂໍ້ມູນການເຊື່ອມຕໍ່ລະບົບ"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"ເຂົ້າສູ່ລະບົບເຄືອຂ່າຍ Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"ລົງຊື່ເຂົ້າເຄືອຂ່າຍ"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ບໍ່ມີການເຊື່ອມຕໍ່ອິນເຕີເນັດ"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"ແຕະເພື່ອເບິ່ງຕົວເລືອກ"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"ເຄືອຂ່າຍມືຖືບໍ່ສາມາດເຂົ້າເຖິງອິນເຕີເນັດໄດ້"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"ເຄືອຂ່າຍບໍ່ສາມາດເຂົ້າເຖິງອິນເຕີເນັດໄດ້"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"ບໍ່ສາມາດເຂົ້າເຖິງເຊີບເວີ DNS ສ່ວນຕົວໄດ້"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ມີການເຊື່ອມຕໍ່ທີ່ຈຳກັດ"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"ແຕະເພື່ອຢືນຢັນການເຊື່ອມຕໍ່"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"ສະຫຼັບໄປໃຊ້ <xliff:g id="NETWORK_TYPE">%1$s</xliff:g> ແລ້ວ"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"ອຸປະກອນຈະໃຊ້ <xliff:g id="NEW_NETWORK">%1$s</xliff:g> ເມື່ອ <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> ບໍ່ມີການເຊື່ອມຕໍ່ອິນເຕີເນັດ. ອາດມີການຮຽກເກັບຄ່າບໍລິການ."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"ສະຫຼັບຈາກ <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> ໄປໃຊ້ <xliff:g id="NEW_NETWORK">%2$s</xliff:g> ແລ້ວ"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"ອິນເຕີເນັດມືຖື"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"ອີເທີເນັດ"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"ອິນເຕີເນັດມືຖື"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"ອີເທີເນັດ"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"ບໍ່ຮູ້ຈັກປະເພດເຄືອຂ່າຍ"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-lt/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-lt/strings.xml
index c639c1f..8eb41f1 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-lt/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-lt/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Prisijungti prie „Wi-Fi“ tinklo"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Prisijungti prie tinklo"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"„<xliff:g id="NETWORK_SSID">%1$s</xliff:g>“ negali pasiekti interneto"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Palieskite, kad būtų rodomos parinktys."</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"Mobiliojo ryšio tinkle nėra prieigos prie interneto"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"Tinkle nėra prieigos prie interneto"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Privataus DNS serverio negalima pasiekti"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"„<xliff:g id="NETWORK_SSID">%1$s</xliff:g>“ ryšys apribotas"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Palieskite, jei vis tiek norite prisijungti"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"Perjungta į tinklą <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Įrenginyje naudojamas kitas tinklas (<xliff:g id="NEW_NETWORK">%1$s</xliff:g>), kai dabartiniame tinkle (<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>) nėra interneto ryšio. Gali būti taikomi mokesčiai."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"Perjungta iš tinklo <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> į tinklą <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"nežinomas tinklo tipas"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"System Connectivity Resources"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Prisijungti prie „Wi-Fi“ tinklo"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Prisijungti prie tinklo"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"„<xliff:g id="NETWORK_SSID">%1$s</xliff:g>“ negali pasiekti interneto"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Palieskite, kad būtų rodomos parinktys."</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"Mobiliojo ryšio tinkle nėra prieigos prie interneto"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"Tinkle nėra prieigos prie interneto"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Privataus DNS serverio negalima pasiekti"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"„<xliff:g id="NETWORK_SSID">%1$s</xliff:g>“ ryšys apribotas"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Palieskite, jei vis tiek norite prisijungti"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"Perjungta į tinklą <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"Įrenginyje naudojamas kitas tinklas (<xliff:g id="NEW_NETWORK">%1$s</xliff:g>), kai dabartiniame tinkle (<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>) nėra interneto ryšio. Gali būti taikomi mokesčiai."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"Perjungta iš tinklo <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> į tinklą <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"mobiliojo ryšio duomenys"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Eternetas"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"mobiliojo ryšio duomenys"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Eternetas"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"nežinomas tinklo tipas"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-lv/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-lv/strings.xml
index 5774603..0647a4f 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-lv/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-lv/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Pierakstieties Wi-Fi tīklā"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Pierakstīšanās tīklā"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"Tīklā <xliff:g id="NETWORK_SSID">%1$s</xliff:g> nav piekļuves internetam"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Pieskarieties, lai skatītu iespējas."</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"Mobilajā tīklā nav piekļuves internetam."</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"Tīklā nav piekļuves internetam."</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Nevar piekļūt privātam DNS serverim."</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"Tīklā <xliff:g id="NETWORK_SSID">%1$s</xliff:g> ir ierobežota savienojamība"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Lai tik un tā izveidotu savienojumu, pieskarieties"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"Pārslēdzās uz tīklu <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Kad vienā tīklā (<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>) nav piekļuves internetam, ierīcē tiek izmantots cits tīkls (<xliff:g id="NEW_NETWORK">%1$s</xliff:g>). Var tikt piemērota maksa."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"Pārslēdzās no tīkla <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> uz tīklu <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"nezināms tīkla veids"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Sistēmas savienojamības resursi"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Pierakstieties Wi-Fi tīklā"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Pierakstīšanās tīklā"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"Tīklā <xliff:g id="NETWORK_SSID">%1$s</xliff:g> nav piekļuves internetam"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Pieskarieties, lai skatītu iespējas."</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"Mobilajā tīklā nav piekļuves internetam."</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"Tīklā nav piekļuves internetam."</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Nevar piekļūt privātam DNS serverim."</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"Tīklā <xliff:g id="NETWORK_SSID">%1$s</xliff:g> ir ierobežota savienojamība"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Lai tik un tā izveidotu savienojumu, pieskarieties"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"Pārslēdzās uz tīklu <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"Kad vienā tīklā (<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>) nav piekļuves internetam, ierīcē tiek izmantots cits tīkls (<xliff:g id="NEW_NETWORK">%1$s</xliff:g>). Var tikt piemērota maksa."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"Pārslēdzās no tīkla <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> uz tīklu <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"mobilie dati"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Ethernet"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"mobilie dati"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Ethernet"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"nezināms tīkla veids"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-mk/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-mk/strings.xml
index 053c7cf..b0024e2 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-mk/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-mk/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Најавете се на мрежа на Wi-Fi"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Најавете се на мрежа"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> нема интернет-пристап"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Допрете за опции"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"Мобилната мрежа нема интернет-пристап"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"Мрежата нема интернет-пристап"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Не може да се пристапи до приватниот DNS-сервер"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> има ограничена поврзливост"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Допрете за да се поврзете и покрај тоа"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"Префрлено на <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Уредот користи <xliff:g id="NEW_NETWORK">%1$s</xliff:g> кога <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> нема пристап до интернет. Може да се наплатат трошоци."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"Префрлено од <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> на <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"непознат тип мрежа"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"System Connectivity Resources"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Најавете се на мрежа на Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Најавете се на мрежа"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> нема интернет-пристап"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Допрете за опции"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"Мобилната мрежа нема интернет-пристап"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"Мрежата нема интернет-пристап"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Не може да се пристапи до приватниот DNS-сервер"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> има ограничена поврзливост"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Допрете за да се поврзете и покрај тоа"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"Префрлено на <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"Уредот користи <xliff:g id="NEW_NETWORK">%1$s</xliff:g> кога <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> нема пристап до интернет. Може да се наплатат трошоци."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"Префрлено од <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> на <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"мобилен интернет"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Етернет"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"мобилен интернет"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Етернет"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"непознат тип мрежа"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ml/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ml/strings.xml
index 3e80cf1..8ce7667 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ml/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ml/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"വൈഫൈ നെറ്റ്‌വർക്കിലേക്ക് സൈൻ ഇൻ ചെയ്യുക"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"നെറ്റ്‌വർക്കിലേക്ക് സൈൻ ഇൻ ചെയ്യുക"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> എന്നതിന് ഇന്റർനെറ്റ് ആക്‌സസ് ഇല്ല"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"ഓപ്ഷനുകൾക്ക് ടാപ്പുചെയ്യുക"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"മൊബെെൽ നെറ്റ്‌വർക്കിന് ഇന്റർനെറ്റ് ആക്‌സസ് ഇല്ല"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"നെറ്റ്‌വർക്കിന് ഇന്റർനെറ്റ് ആക്‌സസ് ഇല്ല"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"സ്വകാര്യ DNS സെർവർ ആക്‌സസ് ചെയ്യാനാവില്ല"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> എന്നതിന് പരിമിതമായ കണക്റ്റിവിറ്റി ഉണ്ട്"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"ഏതുവിധേനയും കണക്‌റ്റ് ചെയ്യാൻ ടാപ്പ് ചെയ്യുക"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> എന്നതിലേക്ക് മാറി"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>-ന് ഇന്റർനെറ്റ് ആക്‌സസ് ഇല്ലാത്തപ്പോൾ ഉപകരണം <xliff:g id="NEW_NETWORK">%1$s</xliff:g> ഉപയോഗിക്കുന്നു. നിരക്കുകൾ ബാധകമായേക്കാം."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> നെറ്റ്‌വർക്കിൽ നിന്ന് <xliff:g id="NEW_NETWORK">%2$s</xliff:g> നെറ്റ്‌വർക്കിലേക്ക് മാറി"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"തിരിച്ചറിയാനാകാത്ത ഒരു നെറ്റ്‌വർക്ക് തരം"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"സിസ്‌റ്റം കണക്‌റ്റിവിറ്റി ഉറവിടങ്ങൾ"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"വൈഫൈ നെറ്റ്‌വർക്കിലേക്ക് സൈൻ ഇൻ ചെയ്യുക"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"നെറ്റ്‌വർക്കിലേക്ക് സൈൻ ഇൻ ചെയ്യുക"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> എന്നതിന് ഇന്റർനെറ്റ് ആക്‌സസ് ഇല്ല"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"ഓപ്ഷനുകൾക്ക് ടാപ്പുചെയ്യുക"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"മൊബെെൽ നെറ്റ്‌വർക്കിന് ഇന്റർനെറ്റ് ആക്‌സസ് ഇല്ല"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"നെറ്റ്‌വർക്കിന് ഇന്റർനെറ്റ് ആക്‌സസ് ഇല്ല"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"സ്വകാര്യ DNS സെർവർ ആക്‌സസ് ചെയ്യാനാവില്ല"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> എന്നതിന് പരിമിതമായ കണക്റ്റിവിറ്റി ഉണ്ട്"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"ഏതുവിധേനയും കണക്‌റ്റ് ചെയ്യാൻ ടാപ്പ് ചെയ്യുക"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> എന്നതിലേക്ക് മാറി"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>-ന് ഇന്റർനെറ്റ് ആക്‌സസ് ഇല്ലാത്തപ്പോൾ ഉപകരണം <xliff:g id="NEW_NETWORK">%1$s</xliff:g> ഉപയോഗിക്കുന്നു. നിരക്കുകൾ ബാധകമായേക്കാം."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> നെറ്റ്‌വർക്കിൽ നിന്ന് <xliff:g id="NEW_NETWORK">%2$s</xliff:g> നെറ്റ്‌വർക്കിലേക്ക് മാറി"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"മൊബൈൽ ഡാറ്റ"</item>
-    <item msgid="5520925862115353992">"വൈഫൈ"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"ഇതര്‍നെറ്റ്"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"മൊബൈൽ ഡാറ്റ"</item>
+    <item msgid="6341719431034774569">"വൈഫൈ"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"ഇതർനെറ്റ്"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"അജ്ഞാതമായ നെറ്റ്‌വർക്ക് തരം"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-mn/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-mn/strings.xml
index 214fc0c..be8b592 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-mn/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-mn/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Wi-Fi сүлжээнд нэвтэрнэ үү"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Сүлжээнд нэвтэрнэ үү"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>-д интернэтийн хандалт алга"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Сонголт хийхийн тулд товшино уу"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"Мобайл сүлжээнд интернэт хандалт байхгүй байна"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"Сүлжээнд интернэт хандалт байхгүй байна"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Хувийн DNS серверт хандах боломжгүй байна"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> зарим үйлчилгээнд хандах боломжгүй байна"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Ямар ч тохиолдолд холбогдохын тулд товших"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> руу шилжүүлсэн"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> интернет холболтгүй үед төхөөрөмж <xliff:g id="NEW_NETWORK">%1$s</xliff:g>-г ашигладаг. Төлбөр гарч болзошгүй."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>-с <xliff:g id="NEW_NETWORK">%2$s</xliff:g> руу шилжүүлсэн"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"сүлжээний тодорхойгүй төрөл"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Системийн холболтын нөөцүүд"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Wi-Fi сүлжээнд нэвтэрнэ үү"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Сүлжээнд нэвтэрнэ үү"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>-д интернэтийн хандалт алга"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Сонголт хийхийн тулд товшино уу"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"Мобайл сүлжээнд интернэт хандалт байхгүй байна"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"Сүлжээнд интернэт хандалт байхгүй байна"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Хувийн DNS серверт хандах боломжгүй байна"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> зарим үйлчилгээнд хандах боломжгүй байна"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Ямар ч тохиолдолд холбогдохын тулд товших"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> руу шилжүүлсэн"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> интернет холболтгүй үед төхөөрөмж <xliff:g id="NEW_NETWORK">%1$s</xliff:g>-г ашигладаг. Төлбөр гарч болзошгүй."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>-с <xliff:g id="NEW_NETWORK">%2$s</xliff:g> руу шилжүүлсэн"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"мобайл дата"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Этернэт"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"мобайл дата"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Этернэт"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"үл мэдэгдэх сүлжээний төрөл"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-mr/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-mr/strings.xml
index c4b1998..fe7df84 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-mr/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-mr/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"वाय-फाय नेटवर्कमध्‍ये साइन इन करा"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"नेटवर्कवर साइन इन करा"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ला इंटरनेट अ‍ॅक्सेस नाही"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"पर्यायांसाठी टॅप करा"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"मोबाइल नेटवर्कला इंटरनेट ॲक्सेस नाही"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"नेटवर्कला इंटरनेट ॲक्सेस नाही"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"खाजगी DNS सर्व्हर ॲक्सेस करू शकत नाही"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ला मर्यादित कनेक्टिव्हिटी आहे"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"तरीही कनेक्ट करण्यासाठी टॅप करा"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> वर स्विच केले"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> कडे इंटरनेटचा अ‍ॅक्सेस नसताना डिव्हाइस <xliff:g id="NEW_NETWORK">%1$s</xliff:g> वापरते. शुल्क लागू शकते."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> वरून <xliff:g id="NEW_NETWORK">%2$s</xliff:g> वर स्विच केले"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"अज्ञात नेटवर्क प्रकार"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"सिस्टम कनेक्टिव्हिटी चे स्रोत"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"वाय-फाय नेटवर्कमध्‍ये साइन इन करा"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"नेटवर्कवर साइन इन करा"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ला इंटरनेट अ‍ॅक्सेस नाही"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"पर्यायांसाठी टॅप करा"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"मोबाइल नेटवर्कला इंटरनेट ॲक्सेस नाही"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"नेटवर्कला इंटरनेट ॲक्सेस नाही"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"खाजगी DNS सर्व्हर ॲक्सेस करू शकत नाही"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ला मर्यादित कनेक्टिव्हिटी आहे"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"तरीही कनेक्ट करण्यासाठी टॅप करा"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> वर स्विच केले"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> कडे इंटरनेटचा अ‍ॅक्सेस नसताना डिव्हाइस <xliff:g id="NEW_NETWORK">%1$s</xliff:g> वापरते. शुल्क लागू शकते."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> वरून <xliff:g id="NEW_NETWORK">%2$s</xliff:g> वर स्विच केले"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"मोबाइल डेटा"</item>
-    <item msgid="5520925862115353992">"वाय-फाय"</item>
-    <item msgid="1055487873974272842">"ब्लूटूथ"</item>
-    <item msgid="1616528372438698248">"इथरनेट"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"मोबाइल डेटा"</item>
+    <item msgid="6341719431034774569">"वाय-फाय"</item>
+    <item msgid="5081440868800877512">"ब्लूटूथ"</item>
+    <item msgid="1160736166977503463">"इथरनेट"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"अज्ञात नेटवर्क प्रकार"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ms/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ms/strings.xml
index 529d0bd..54b49a2 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ms/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ms/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Log masuk ke rangkaian Wi-Fi"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Log masuk ke rangkaian"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> tiada akses Internet"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Ketik untuk mendapatkan pilihan"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"Rangkaian mudah alih tiada akses Internet"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"Rangkaian tiada akses Internet"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Pelayan DNS peribadi tidak boleh diakses"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> mempunyai kesambungan terhad"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Ketik untuk menyambung juga"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"Beralih kepada <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Peranti menggunakan <xliff:g id="NEW_NETWORK">%1$s</xliff:g> apabila <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> tiada akses Internet. Bayaran mungkin dikenakan."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"Beralih daripada <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> kepada <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"jenis rangkaian tidak diketahui"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Sumber Kesambungan Sistem"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Log masuk ke rangkaian Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Log masuk ke rangkaian"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> tiada akses Internet"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Ketik untuk mendapatkan pilihan"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"Rangkaian mudah alih tiada akses Internet"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"Rangkaian tiada akses Internet"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Pelayan DNS peribadi tidak boleh diakses"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> mempunyai kesambungan terhad"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Ketik untuk menyambung juga"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"Beralih kepada <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"Peranti menggunakan <xliff:g id="NEW_NETWORK">%1$s</xliff:g> apabila <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> tiada akses Internet. Bayaran mungkin dikenakan."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"Beralih daripada <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> kepada <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"data mudah alih"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Ethernet"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"data mudah alih"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Ethernet"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"jenis rangkaian tidak diketahui"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-my/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-my/strings.xml
index 50590fa..15b75f0 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-my/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-my/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"ဝိုင်ဖိုင်ကွန်ရက်သို့ လက်မှတ်ထိုးဝင်ပါ"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"ကွန်ယက်သို့ လက်မှတ်ထိုးဝင်ရန်"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> တွင် အင်တာနက်အသုံးပြုခွင့် မရှိပါ"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"အခြားရွေးချယ်စရာများကိုကြည့်ရန် တို့ပါ"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"မိုဘိုင်းကွန်ရက်တွင် အင်တာနက်ချိတ်ဆက်မှု မရှိပါ"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"ကွန်ရက်တွင် အင်တာနက်အသုံးပြုခွင့် မရှိပါ"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"သီးသန့် ဒီအန်အက်စ် (DNS) ဆာဗာကို သုံး၍မရပါ။"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> တွင် ချိတ်ဆက်မှုကို ကန့်သတ်ထားသည်"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"မည်သို့ပင်ဖြစ်စေ ချိတ်ဆက်ရန် တို့ပါ"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> သို့ ပြောင်းလိုက်ပြီ"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> ဖြင့် အင်တာနက် အသုံးမပြုနိုင်သည့်အချိန်တွင် စက်ပစ္စည်းသည် <xliff:g id="NEW_NETWORK">%1$s</xliff:g> ကို သုံးပါသည်။ ဒေတာသုံးစွဲခ ကျသင့်နိုင်ပါသည်။"</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> မှ <xliff:g id="NEW_NETWORK">%2$s</xliff:g> သို့ ပြောင်းလိုက်ပြီ"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"အမည်မသိကွန်ရက်အမျိုးအစား"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"စနစ်ချိတ်ဆက်နိုင်မှု ရင်းမြစ်များ"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"ဝိုင်ဖိုင်ကွန်ရက်သို့ လက်မှတ်ထိုးဝင်ပါ"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"ကွန်ယက်သို့ လက်မှတ်ထိုးဝင်ရန်"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> တွင် အင်တာနက်အသုံးပြုခွင့် မရှိပါ"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"အခြားရွေးချယ်စရာများကိုကြည့်ရန် တို့ပါ"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"မိုဘိုင်းကွန်ရက်တွင် အင်တာနက်ချိတ်ဆက်မှု မရှိပါ"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"ကွန်ရက်တွင် အင်တာနက်အသုံးပြုခွင့် မရှိပါ"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"သီးသန့် ဒီအန်အက်စ် (DNS) ဆာဗာကို သုံး၍မရပါ။"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> တွင် ချိတ်ဆက်မှုကို ကန့်သတ်ထားသည်"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"မည်သို့ပင်ဖြစ်စေ ချိတ်ဆက်ရန် တို့ပါ"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> သို့ ပြောင်းလိုက်ပြီ"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> ဖြင့် အင်တာနက် အသုံးမပြုနိုင်သည့်အချိန်တွင် စက်ပစ္စည်းသည် <xliff:g id="NEW_NETWORK">%1$s</xliff:g> ကို သုံးပါသည်။ ဒေတာသုံးစွဲခ ကျသင့်နိုင်ပါသည်။"</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> မှ <xliff:g id="NEW_NETWORK">%2$s</xliff:g> သို့ ပြောင်းလိုက်ပြီ"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"မိုဘိုင်းဒေတာ"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"ဘလူးတုသ်"</item>
-    <item msgid="1616528372438698248">"အီသာနက်"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"မိုဘိုင်းဒေတာ"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"ဘလူးတုသ်"</item>
+    <item msgid="1160736166977503463">"အီသာနက်"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"အမည်မသိကွန်ရက်အမျိုးအစား"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-nb/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-nb/strings.xml
index b89d198..a561def 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-nb/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-nb/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Logg på Wi-Fi-nettverket"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Logg på nettverk"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> har ingen internettilkobling"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Trykk for å få alternativer"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"Mobilnettverket har ingen internettilgang"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"Nettverket har ingen internettilgang"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Den private DNS-tjeneren kan ikke nås"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> har begrenset tilkobling"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Trykk for å koble til likevel"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"Byttet til <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Enheten bruker <xliff:g id="NEW_NETWORK">%1$s</xliff:g> når <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> ikke har Internett-tilgang. Avgifter kan påløpe."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"Byttet fra <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> til <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"en ukjent nettverkstype"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Ressurser for systemtilkobling"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Logg på Wi-Fi-nettverket"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Logg på nettverk"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> har ingen internettilkobling"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Trykk for å få alternativer"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"Mobilnettverket har ingen internettilgang"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"Nettverket har ingen internettilgang"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Den private DNS-tjeneren kan ikke nås"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> har begrenset tilkobling"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Trykk for å koble til likevel"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"Byttet til <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"Enheten bruker <xliff:g id="NEW_NETWORK">%1$s</xliff:g> når <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> ikke har Internett-tilgang. Avgifter kan påløpe."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"Byttet fra <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> til <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"mobildata"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Ethernet"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"mobildata"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Ethernet"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"en ukjent nettverkstype"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ne/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ne/strings.xml
index bdcfa3b..f74542d 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ne/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ne/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Wi-Fi नेटवर्कमा साइन इन गर्नुहोस्"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"सञ्जालमा साइन इन गर्नुहोस्"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> को इन्टरनेटमाथि पहुँच छैन"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"विकल्पहरूका लागि ट्याप गर्नुहोस्"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"मोबाइल नेटवर्कको इन्टरनेटमाथि पहुँच छैन"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"नेटवर्कको इन्टरनेटमाथि पहुँच छैन"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"निजी DNS सर्भरमाथि पहुँच प्राप्त गर्न सकिँदैन"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> को जडान सीमित छ"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"जसरी भए पनि जडान गर्न ट्याप गर्नुहोस्"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> मा बदल्नुहोस्"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> मार्फत इन्टरनेटमाथि पहुँच राख्न नसकेको अवस्थामा यन्त्रले <xliff:g id="NEW_NETWORK">%1$s</xliff:g> प्रयोग गर्दछ। शुल्क लाग्न सक्छ।"</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> बाट <xliff:g id="NEW_NETWORK">%2$s</xliff:g> मा परिवर्तन गरियो"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"नेटवर्कको कुनै अज्ञात प्रकार"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"सिस्टम कनेक्टिभिटीका स्रोतहरू"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Wi-Fi नेटवर्कमा साइन इन गर्नुहोस्"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"सञ्जालमा साइन इन गर्नुहोस्"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> को इन्टरनेटमाथि पहुँच छैन"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"विकल्पहरूका लागि ट्याप गर्नुहोस्"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"मोबाइल नेटवर्कको इन्टरनेटमाथि पहुँच छैन"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"नेटवर्कको इन्टरनेटमाथि पहुँच छैन"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"निजी DNS सर्भरमाथि पहुँच प्राप्त गर्न सकिँदैन"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> को जडान सीमित छ"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"जसरी भए पनि जडान गर्न ट्याप गर्नुहोस्"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> मा बदल्नुहोस्"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> मार्फत इन्टरनेटमाथि पहुँच राख्न नसकेको अवस्थामा यन्त्रले <xliff:g id="NEW_NETWORK">%1$s</xliff:g> प्रयोग गर्दछ। शुल्क लाग्न सक्छ।"</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> बाट <xliff:g id="NEW_NETWORK">%2$s</xliff:g> मा परिवर्तन गरियो"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"मोबाइल डेटा"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"ब्लुटुथ"</item>
-    <item msgid="1616528372438698248">"इथरनेट"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"मोबाइल डेटा"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"ब्लुटुथ"</item>
+    <item msgid="1160736166977503463">"इथरनेट"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"नेटवर्कको कुनै अज्ञात प्रकार"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-nl/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-nl/strings.xml
index 8ecff6e..0f3203b 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-nl/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-nl/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Inloggen bij wifi-netwerk"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Inloggen bij netwerk"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> heeft geen internettoegang"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Tik voor opties"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"Mobiel netwerk heeft geen internettoegang"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"Netwerk heeft geen internettoegang"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Geen toegang tot privé-DNS-server"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> heeft beperkte connectiviteit"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Tik om toch verbinding te maken"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"Overgeschakeld naar <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Apparaat gebruikt <xliff:g id="NEW_NETWORK">%1$s</xliff:g> wanneer <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> geen internetverbinding heeft. Er kunnen kosten in rekening worden gebracht."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"Overgeschakeld van <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> naar <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"een onbekend netwerktype"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Resources voor systeemconnectiviteit"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Inloggen bij wifi-netwerk"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Inloggen bij netwerk"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> heeft geen internettoegang"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Tik voor opties"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"Mobiel netwerk heeft geen internettoegang"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"Netwerk heeft geen internettoegang"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Geen toegang tot privé-DNS-server"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> heeft beperkte connectiviteit"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Tik om toch verbinding te maken"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"Overgeschakeld naar <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"Apparaat gebruikt <xliff:g id="NEW_NETWORK">%1$s</xliff:g> wanneer <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> geen internetverbinding heeft. Er kunnen kosten in rekening worden gebracht."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"Overgeschakeld van <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> naar <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"mobiele data"</item>
-    <item msgid="5520925862115353992">"Wifi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Ethernet"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"mobiele data"</item>
+    <item msgid="6341719431034774569">"Wifi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Ethernet"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"een onbekend netwerktype"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-or/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-or/strings.xml
index 6ec1f9d..ecf4d69 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-or/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-or/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"ୱାଇ-ଫାଇ ନେଟୱର୍କରେ ସାଇନ୍‍-ଇନ୍‍ କରନ୍ତୁ"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"ନେଟ୍‌ୱର୍କରେ ସାଇନ୍‍ ଇନ୍‍ କରନ୍ତୁ"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>ର ଇଣ୍ଟର୍ନେଟ୍ ଆକ୍ସେସ୍ ନାହିଁ"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"ବିକଳ୍ପ ପାଇଁ ଟାପ୍‍ କରନ୍ତୁ"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"ମୋବାଇଲ୍ ନେଟ୍‌ୱାର୍କରେ ଇଣ୍ଟର୍ନେଟ୍ ଆକ୍ସେସ୍ ନାହିଁ"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"ନେଟ୍‌ୱାର୍କରେ ଇଣ୍ଟର୍ନେଟ୍ ଆକ୍ସେସ୍ ନାହିଁ"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"ବ୍ୟକ୍ତିଗତ DNS ସର୍ଭର୍ ଆକ୍ସେସ୍ କରିହେବ ନାହିଁ"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>ର ସୀମିତ ସଂଯୋଗ ଅଛି"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"ତଥାପି ଯୋଗାଯୋଗ କରିବାକୁ ଟାପ୍ କରନ୍ତୁ"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g>କୁ ବଦଳାଗଲା"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>ର ଇଣ୍ଟରନେଟ୍‍ ଆକ୍ସେସ୍ ନଥିବାବେଳେ ଡିଭାଇସ୍‍ <xliff:g id="NEW_NETWORK">%1$s</xliff:g> ବ୍ୟବହାର କରିଥାଏ। ଶୁଳ୍କ ଲାଗୁ ହୋଇପାରେ।"</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> ରୁ <xliff:g id="NEW_NETWORK">%2$s</xliff:g>କୁ ବଦଳାଗଲା"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"ଏକ ଅଜଣା ନେଟ୍‌ୱର୍କ ପ୍ରକାର"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"ସିଷ୍ଟମର ସଂଯୋଗ ସମ୍ବନ୍ଧିତ ରିସୋର୍ସଗୁଡ଼ିକ"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"ୱାଇ-ଫାଇ ନେଟୱର୍କରେ ସାଇନ୍‍-ଇନ୍‍ କରନ୍ତୁ"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"ନେଟ୍‌ୱର୍କରେ ସାଇନ୍‍ ଇନ୍‍ କରନ୍ତୁ"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>ର ଇଣ୍ଟର୍ନେଟ୍ ଆକ୍ସେସ୍ ନାହିଁ"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"ବିକଳ୍ପ ପାଇଁ ଟାପ୍‍ କରନ୍ତୁ"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"ମୋବାଇଲ୍ ନେଟ୍‌ୱାର୍କରେ ଇଣ୍ଟର୍ନେଟ୍ ଆକ୍ସେସ୍ ନାହିଁ"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"ନେଟ୍‌ୱାର୍କରେ ଇଣ୍ଟର୍ନେଟ୍ ଆକ୍ସେସ୍ ନାହିଁ"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"ବ୍ୟକ୍ତିଗତ DNS ସର୍ଭର୍ ଆକ୍ସେସ୍ କରିହେବ ନାହିଁ"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>ର ସୀମିତ ସଂଯୋଗ ଅଛି"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"ତଥାପି ଯୋଗାଯୋଗ କରିବାକୁ ଟାପ୍ କରନ୍ତୁ"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g>କୁ ବଦଳାଗଲା"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>ର ଇଣ୍ଟରନେଟ୍‍ ଆକ୍ସେସ୍ ନଥିବାବେଳେ ଡିଭାଇସ୍‍ <xliff:g id="NEW_NETWORK">%1$s</xliff:g> ବ୍ୟବହାର କରିଥାଏ। ଶୁଳ୍କ ଲାଗୁ ହୋଇପାରେ।"</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> ରୁ <xliff:g id="NEW_NETWORK">%2$s</xliff:g>କୁ ବଦଳାଗଲା"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"ମୋବାଇଲ୍‌ ଡାଟା"</item>
-    <item msgid="5520925862115353992">"ୱାଇ-ଫାଇ"</item>
-    <item msgid="1055487873974272842">"ବ୍ଲୁଟୁଥ"</item>
-    <item msgid="1616528372438698248">"ଇଥରନେଟ୍‌"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"ମୋବାଇଲ ଡାଟା"</item>
+    <item msgid="6341719431034774569">"ୱାଇ-ଫାଇ"</item>
+    <item msgid="5081440868800877512">"ବ୍ଲୁଟୁଥ୍"</item>
+    <item msgid="1160736166977503463">"ଇଥରନେଟ୍"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"ଏକ ଅଜଣା ନେଟୱାର୍କ ପ୍ରକାର"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-pa/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-pa/strings.xml
index e948193..4328054 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-pa/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-pa/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"ਵਾਈ-ਫਾਈ ਨੈੱਟਵਰਕ \'ਤੇ ਸਾਈਨ-ਇਨ ਕਰੋ"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"ਨੈੱਟਵਰਕ \'ਤੇ ਸਾਈਨ-ਇਨ ਕਰੋ"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ਕੋਲ ਇੰਟਰਨੈੱਟ ਪਹੁੰਚ ਨਹੀਂ ਹੈ"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"ਵਿਕਲਪਾਂ ਲਈ ਟੈਪ ਕਰੋ"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"ਮੋਬਾਈਲ ਨੈੱਟਵਰਕ ਕੋਲ ਇੰਟਰਨੈੱਟ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਹੈ"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"ਨੈੱਟਵਰਕ ਕੋਲ ਇੰਟਰਨੈੱਟ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਹੈ"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"ਨਿੱਜੀ ਡੋਮੇਨ ਨਾਮ ਪ੍ਰਣਾਲੀ (DNS) ਸਰਵਰ \'ਤੇ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕੀ"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ਕੋਲ ਸੀਮਤ ਕਨੈਕਟੀਵਿਟੀ ਹੈ"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"ਫਿਰ ਵੀ ਕਨੈਕਟ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"ਬਦਲਕੇ <xliff:g id="NETWORK_TYPE">%1$s</xliff:g> ਲਿਆਂਦਾ ਗਿਆ"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> ਦੀ ਇੰਟਰਨੈੱਟ \'ਤੇ ਪਹੁੰਚ ਨਾ ਹੋਣ \'ਤੇ ਡੀਵਾਈਸ <xliff:g id="NEW_NETWORK">%1$s</xliff:g> ਦੀ ਵਰਤੋਂ ਕਰਦਾ ਹੈ। ਖਰਚੇ ਲਾਗੂ ਹੋ ਸਕਦੇ ਹਨ।"</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> ਤੋਂ ਬਦਲਕੇ <xliff:g id="NEW_NETWORK">%2$s</xliff:g> \'ਤੇ ਕੀਤਾ ਗਿਆ"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"ਇੱਕ ਅਗਿਆਤ ਨੈੱਟਵਰਕ ਕਿਸਮ"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"ਸਿਸਟਮ ਕਨੈਕਟੀਵਿਟੀ ਸਰੋਤ"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"ਵਾਈ-ਫਾਈ ਨੈੱਟਵਰਕ \'ਤੇ ਸਾਈਨ-ਇਨ ਕਰੋ"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"ਨੈੱਟਵਰਕ \'ਤੇ ਸਾਈਨ-ਇਨ ਕਰੋ"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ਕੋਲ ਇੰਟਰਨੈੱਟ ਪਹੁੰਚ ਨਹੀਂ ਹੈ"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"ਵਿਕਲਪਾਂ ਲਈ ਟੈਪ ਕਰੋ"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"ਮੋਬਾਈਲ ਨੈੱਟਵਰਕ ਕੋਲ ਇੰਟਰਨੈੱਟ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਹੈ"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"ਨੈੱਟਵਰਕ ਕੋਲ ਇੰਟਰਨੈੱਟ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਹੈ"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"ਨਿੱਜੀ ਡੋਮੇਨ ਨਾਮ ਪ੍ਰਣਾਲੀ (DNS) ਸਰਵਰ \'ਤੇ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕੀ"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ਕੋਲ ਸੀਮਤ ਕਨੈਕਟੀਵਿਟੀ ਹੈ"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"ਫਿਰ ਵੀ ਕਨੈਕਟ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"ਬਦਲਕੇ <xliff:g id="NETWORK_TYPE">%1$s</xliff:g> ਲਿਆਂਦਾ ਗਿਆ"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> ਦੀ ਇੰਟਰਨੈੱਟ \'ਤੇ ਪਹੁੰਚ ਨਾ ਹੋਣ \'ਤੇ ਡੀਵਾਈਸ <xliff:g id="NEW_NETWORK">%1$s</xliff:g> ਦੀ ਵਰਤੋਂ ਕਰਦਾ ਹੈ। ਖਰਚੇ ਲਾਗੂ ਹੋ ਸਕਦੇ ਹਨ।"</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> ਤੋਂ ਬਦਲਕੇ <xliff:g id="NEW_NETWORK">%2$s</xliff:g> \'ਤੇ ਕੀਤਾ ਗਿਆ"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"ਮੋਬਾਈਲ ਡਾਟਾ"</item>
-    <item msgid="5520925862115353992">"ਵਾਈ-ਫਾਈ"</item>
-    <item msgid="1055487873974272842">"ਬਲੂਟੁੱਥ"</item>
-    <item msgid="1616528372438698248">"ਈਥਰਨੈੱਟ"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"ਮੋਬਾਈਲ ਡਾਟਾ"</item>
+    <item msgid="6341719431034774569">"ਵਾਈ-ਫਾਈ"</item>
+    <item msgid="5081440868800877512">"ਬਲੂਟੁੱਥ"</item>
+    <item msgid="1160736166977503463">"ਈਥਰਨੈੱਟ"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"ਕੋਈ ਅਗਿਆਤ ਨੈੱਟਵਰਕ ਦੀ ਕਿਸਮ"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-pl/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-pl/strings.xml
index 038328f..e6b3a0c 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-pl/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-pl/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Zaloguj się w sieci Wi-Fi"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Zaloguj się do sieci"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> nie ma dostępu do internetu"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Kliknij, by wyświetlić opcje"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"Sieć komórkowa nie ma dostępu do internetu"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"Sieć nie ma dostępu do internetu"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Brak dostępu do prywatnego serwera DNS"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ma ograniczoną łączność"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Kliknij, by mimo to nawiązać połączenie"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"Zmieniono na połączenie typu <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Urządzenie korzysta z połączenia typu <xliff:g id="NEW_NETWORK">%1$s</xliff:g>, gdy <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> nie dostępu do internetu. Mogą zostać naliczone opłaty."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"Przełączono z połączenia typu <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> na <xliff:g id="NEW_NETWORK">%2$s</xliff:g>."</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"nieznany typ sieci"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Zasoby systemowe dotyczące łączności"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Zaloguj się w sieci Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Zaloguj się do sieci"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> nie ma dostępu do internetu"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Kliknij, by wyświetlić opcje"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"Sieć komórkowa nie ma dostępu do internetu"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"Sieć nie ma dostępu do internetu"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Brak dostępu do prywatnego serwera DNS"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ma ograniczoną łączność"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Kliknij, by mimo to nawiązać połączenie"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"Zmieniono na połączenie typu <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"Urządzenie korzysta z połączenia typu <xliff:g id="NEW_NETWORK">%1$s</xliff:g>, gdy <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> nie dostępu do internetu. Mogą zostać naliczone opłaty."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"Przełączono z połączenia typu <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> na <xliff:g id="NEW_NETWORK">%2$s</xliff:g>."</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"mobilna transmisja danych"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Ethernet"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"mobilna transmisja danych"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Ethernet"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"nieznany typ sieci"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-pt-rBR/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-pt-rBR/strings.xml
index fe37405..f1d0bc0 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-pt-rBR/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-pt-rBR/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Fazer login na rede Wi-Fi"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Fazer login na rede"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> não tem acesso à Internet"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Toque para ver opções"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"A rede móvel não tem acesso à Internet"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"A rede não tem acesso à Internet"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Não é possível acessar o servidor DNS privado"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> tem conectividade limitada"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Toque para conectar mesmo assim"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"Alternado para <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"O dispositivo usa <xliff:g id="NEW_NETWORK">%1$s</xliff:g> quando <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> não tem acesso à Internet. Esse serviço pode ser cobrado."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"Alternado de <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> para <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"um tipo de rede desconhecido"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Recursos de conectividade do sistema"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Fazer login na rede Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Fazer login na rede"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> não tem acesso à Internet"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Toque para ver opções"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"A rede móvel não tem acesso à Internet"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"A rede não tem acesso à Internet"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Não é possível acessar o servidor DNS privado"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> tem conectividade limitada"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Toque para conectar mesmo assim"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"Alternado para <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"O dispositivo usa <xliff:g id="NEW_NETWORK">%1$s</xliff:g> quando <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> não tem acesso à Internet. Esse serviço pode ser cobrado."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"Alternado de <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> para <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"dados móveis"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Ethernet"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"dados móveis"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Ethernet"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"um tipo de rede desconhecido"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-pt-rPT/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-pt-rPT/strings.xml
index 69060f7..163d70b 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-pt-rPT/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-pt-rPT/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Iniciar sessão na rede Wi-Fi"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Início de sessão na rede"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> não tem acesso à Internet"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Toque para obter mais opções"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"A rede móvel não tem acesso à Internet"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"A rede não tem acesso à Internet"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Não é possível aceder ao servidor DNS."</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> tem conetividade limitada."</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Toque para ligar mesmo assim."</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"Mudou para <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"O dispositivo utiliza <xliff:g id="NEW_NETWORK">%1$s</xliff:g> quando <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> não tem acesso à Internet. Podem aplicar-se custos."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"Mudou de <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> para <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"um tipo de rede desconhecido"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Recursos de conetividade do sistema"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Iniciar sessão na rede Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Início de sessão na rede"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> não tem acesso à Internet"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Toque para obter mais opções"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"A rede móvel não tem acesso à Internet"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"A rede não tem acesso à Internet"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Não é possível aceder ao servidor DNS."</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> tem conetividade limitada."</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Toque para ligar mesmo assim."</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"Mudou para <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"O dispositivo utiliza <xliff:g id="NEW_NETWORK">%1$s</xliff:g> quando <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> não tem acesso à Internet. Podem aplicar-se custos."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"Mudou de <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> para <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"dados móveis"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Ethernet"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"dados móveis"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Ethernet"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"um tipo de rede desconhecido"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-pt/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-pt/strings.xml
index fe37405..f1d0bc0 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-pt/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-pt/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Fazer login na rede Wi-Fi"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Fazer login na rede"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> não tem acesso à Internet"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Toque para ver opções"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"A rede móvel não tem acesso à Internet"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"A rede não tem acesso à Internet"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Não é possível acessar o servidor DNS privado"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> tem conectividade limitada"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Toque para conectar mesmo assim"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"Alternado para <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"O dispositivo usa <xliff:g id="NEW_NETWORK">%1$s</xliff:g> quando <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> não tem acesso à Internet. Esse serviço pode ser cobrado."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"Alternado de <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> para <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"um tipo de rede desconhecido"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Recursos de conectividade do sistema"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Fazer login na rede Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Fazer login na rede"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> não tem acesso à Internet"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Toque para ver opções"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"A rede móvel não tem acesso à Internet"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"A rede não tem acesso à Internet"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Não é possível acessar o servidor DNS privado"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> tem conectividade limitada"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Toque para conectar mesmo assim"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"Alternado para <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"O dispositivo usa <xliff:g id="NEW_NETWORK">%1$s</xliff:g> quando <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> não tem acesso à Internet. Esse serviço pode ser cobrado."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"Alternado de <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> para <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"dados móveis"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Ethernet"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"dados móveis"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Ethernet"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"um tipo de rede desconhecido"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ro/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ro/strings.xml
index 227b7be..221261c 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ro/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ro/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Conectați-vă la rețeaua Wi-Fi"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Conectați-vă la rețea"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> nu are acces la internet"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Atingeți pentru opțiuni"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"Rețeaua mobilă nu are acces la internet"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"Rețeaua nu are acces la internet"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Serverul DNS privat nu poate fi accesat"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> are conectivitate limitată"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Atingeți pentru a vă conecta oricum"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"S-a comutat la <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Dispozitivul folosește <xliff:g id="NEW_NETWORK">%1$s</xliff:g> când <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> nu are acces la internet. Se pot aplica taxe."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"S-a comutat de la <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> la <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"un tip de rețea necunoscut"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Resurse pentru conectivitatea sistemului"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Conectați-vă la rețeaua Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Conectați-vă la rețea"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> nu are acces la internet"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Atingeți pentru opțiuni"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"Rețeaua mobilă nu are acces la internet"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"Rețeaua nu are acces la internet"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Serverul DNS privat nu poate fi accesat"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> are conectivitate limitată"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Atingeți pentru a vă conecta oricum"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"S-a comutat la <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"Dispozitivul folosește <xliff:g id="NEW_NETWORK">%1$s</xliff:g> când <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> nu are acces la internet. Se pot aplica taxe."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"S-a comutat de la <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> la <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"date mobile"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Ethernet"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"date mobile"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Ethernet"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"un tip de rețea necunoscut"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ru/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ru/strings.xml
index 18acf81..ba179b7 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ru/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ru/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Подключение к Wi-Fi"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Регистрация в сети"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"Сеть \"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>\" не подключена к Интернету"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Нажмите, чтобы показать варианты."</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"Мобильная сеть не подключена к Интернету"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"Сеть не подключена к Интернету"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Доступа к частному DNS-серверу нет."</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"Подключение к сети \"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>\" ограничено"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Нажмите, чтобы подключиться"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"Новое подключение: <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Устройство использует <xliff:g id="NEW_NETWORK">%1$s</xliff:g>, если подключение к сети <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> недоступно. Может взиматься плата за передачу данных."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"Устройство отключено от сети <xliff:g id="NEW_NETWORK">%2$s</xliff:g> и теперь использует <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"неизвестный тип сети"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"System Connectivity Resources"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Подключение к Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Регистрация в сети"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"Сеть \"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>\" не подключена к Интернету"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Нажмите, чтобы показать варианты."</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"Мобильная сеть не подключена к Интернету"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"Сеть не подключена к Интернету"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Доступа к частному DNS-серверу нет."</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"Подключение к сети \"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>\" ограничено"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Нажмите, чтобы подключиться"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"Новое подключение: <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"Устройство использует <xliff:g id="NEW_NETWORK">%1$s</xliff:g>, если подключение к сети <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> недоступно. Может взиматься плата за передачу данных."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"Устройство отключено от сети <xliff:g id="NEW_NETWORK">%2$s</xliff:g> и теперь использует <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"мобильный Интернет"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Ethernet"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"мобильный интернет"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Ethernet"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"неизвестный тип сети"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-si/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-si/strings.xml
index 6307c2b..1c493a7 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-si/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-si/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Wi-Fi ජාලයට පුරනය වන්න"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"ජාලයට පුරනය වන්න"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> හට අන්තර්ජාල ප්‍රවේශය නැත"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"විකල්ප සඳහා තට්ටු කරන්න"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"ජංගම ජාලවලට අන්තර්ජාල ප්‍රවේශය නැත"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"ජාලයට අන්තර්ජාල ප්‍රවේශය නැත"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"පුද්ගලික DNS සේවාදායකයට ප්‍රවේශ වීමට නොහැකිය"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> හට සීමිත සබැඳුම් හැකියාවක් ඇත"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"කෙසේ වෙතත් ඉදිරියට යාමට තට්ටු කරන්න"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> වෙත මාරු විය"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"උපාංගය <xliff:g id="NEW_NETWORK">%1$s</xliff:g> <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> සඳහා අන්තර්ජාල ප්‍රවේශය නැති විට භාවිත කරයි. ගාස්තු අදාළ විය හැකිය."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> සිට <xliff:g id="NEW_NETWORK">%2$s</xliff:g> වෙත මාරු විය"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"නොදන්නා ජාල වර්ගයකි"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"පද්ධති සබැඳුම් හැකියා සම්පත්"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Wi-Fi ජාලයට පුරනය වන්න"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"ජාලයට පුරනය වන්න"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> හට අන්තර්ජාල ප්‍රවේශය නැත"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"විකල්ප සඳහා තට්ටු කරන්න"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"ජංගම ජාලවලට අන්තර්ජාල ප්‍රවේශය නැත"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"ජාලයට අන්තර්ජාල ප්‍රවේශය නැත"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"පුද්ගලික DNS සේවාදායකයට ප්‍රවේශ වීමට නොහැකිය"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> හට සීමිත සබැඳුම් හැකියාවක් ඇත"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"කෙසේ වෙතත් ඉදිරියට යාමට තට්ටු කරන්න"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> වෙත මාරු විය"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"උපාංගය <xliff:g id="NEW_NETWORK">%1$s</xliff:g> <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> සඳහා අන්තර්ජාල ප්‍රවේශය නැති විට භාවිත කරයි. ගාස්තු අදාළ විය හැකිය."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> සිට <xliff:g id="NEW_NETWORK">%2$s</xliff:g> වෙත මාරු විය"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"ජංගම දත්ත"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"බ්ලූටූත්"</item>
-    <item msgid="1616528372438698248">"ඊතර්නෙට්"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"ජංගම දත්ත"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"බ්ලූටූත්"</item>
+    <item msgid="1160736166977503463">"ඊතර්නෙට්"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"නොදන්නා ජාල වර්ගයකි"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-sk/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-sk/strings.xml
index e894fef..1b9313a 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-sk/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-sk/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Prihlásiť sa do siete Wi‑Fi"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Prihlásenie do siete"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> nemá prístup k internetu"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Klepnutím získate možnosti"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"Mobilná sieť nemá prístup k internetu"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"Sieť nemá prístup k internetu"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"K súkromnému serveru DNS sa nepodarilo získať prístup"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> má obmedzené pripojenie"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Ak sa chcete aj napriek tomu pripojiť, klepnite"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"Prepnuté na sieť: <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Keď <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> nemá prístup k internetu, zariadenie používa <xliff:g id="NEW_NETWORK">%1$s</xliff:g>. Môžu sa účtovať poplatky."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"Prepnuté zo siete <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> na sieť <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"neznámy typ siete"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Zdroje možností pripojenia systému"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Prihlásiť sa do siete Wi‑Fi"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Prihlásenie do siete"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> nemá prístup k internetu"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Klepnutím získate možnosti"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"Mobilná sieť nemá prístup k internetu"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"Sieť nemá prístup k internetu"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"K súkromnému serveru DNS sa nepodarilo získať prístup"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> má obmedzené pripojenie"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Ak sa chcete aj napriek tomu pripojiť, klepnite"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"Prepnuté na sieť: <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"Keď <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> nemá prístup k internetu, zariadenie používa <xliff:g id="NEW_NETWORK">%1$s</xliff:g>. Môžu sa účtovať poplatky."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"Prepnuté zo siete <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> na sieť <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"mobilné dáta"</item>
-    <item msgid="5520925862115353992">"Wi‑Fi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Ethernet"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"mobilné dáta"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Ethernet"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"neznámy typ siete"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-sl/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-sl/strings.xml
index 954b324..739fb8e 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-sl/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-sl/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Prijavite se v omrežje Wi-Fi"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Prijava v omrežje"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"Omrežje <xliff:g id="NETWORK_SSID">%1$s</xliff:g> nima dostopa do interneta"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Dotaknite se za možnosti"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"Mobilno omrežje nima dostopa do interneta"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"Omrežje nima dostopa do interneta"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Do zasebnega strežnika DNS ni mogoče dostopati"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"Povezljivost omrežja <xliff:g id="NETWORK_SSID">%1$s</xliff:g> je omejena"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Dotaknite se, da kljub temu vzpostavite povezavo"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"Preklopljeno na omrežje vrste <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Naprava uporabi omrežje vrste <xliff:g id="NEW_NETWORK">%1$s</xliff:g>, ko omrežje vrste <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> nima dostopa do interneta. Prenos podatkov se lahko zaračuna."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"Preklopljeno z omrežja vrste <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> na omrežje vrste <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"neznana vrsta omrežja"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Viri povezljivosti sistema"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Prijavite se v omrežje Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Prijava v omrežje"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"Omrežje <xliff:g id="NETWORK_SSID">%1$s</xliff:g> nima dostopa do interneta"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Dotaknite se za možnosti"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"Mobilno omrežje nima dostopa do interneta"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"Omrežje nima dostopa do interneta"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Do zasebnega strežnika DNS ni mogoče dostopati"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"Povezljivost omrežja <xliff:g id="NETWORK_SSID">%1$s</xliff:g> je omejena"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Dotaknite se, da kljub temu vzpostavite povezavo"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"Preklopljeno na omrežje vrste <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"Naprava uporabi omrežje vrste <xliff:g id="NEW_NETWORK">%1$s</xliff:g>, ko omrežje vrste <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> nima dostopa do interneta. Prenos podatkov se lahko zaračuna."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"Preklopljeno z omrežja vrste <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> na omrežje vrste <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"prenos podatkov v mobilnem omrežju"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Ethernet"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"prenos podatkov v mobilnem omrežju"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Ethernet"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"neznana vrsta omrežja"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-sq/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-sq/strings.xml
index bd5d052..cf8cf3b 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-sq/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-sq/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Identifikohu në rrjetin Wi-Fi"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Identifikohu në rrjet"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> nuk ka qasje në internet"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Trokit për opsionet"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"Rrjeti celular nuk ka qasje në internet"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"Rrjeti nuk ka qasje në internet"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Serveri privat DNS nuk mund të qaset"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ka lidhshmëri të kufizuar"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Trokit për t\'u lidhur gjithsesi"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"Kaloi te <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Pajisja përdor <xliff:g id="NEW_NETWORK">%1$s</xliff:g> kur <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> nuk ka qasje në internet. Mund të zbatohen tarifa."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"Kaloi nga <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> te <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"një lloj rrjeti i panjohur"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Burimet e lidhshmërisë së sistemit"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Identifikohu në rrjetin Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Identifikohu në rrjet"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> nuk ka qasje në internet"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Trokit për opsionet"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"Rrjeti celular nuk ka qasje në internet"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"Rrjeti nuk ka qasje në internet"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Serveri privat DNS nuk mund të qaset"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ka lidhshmëri të kufizuar"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Trokit për t\'u lidhur gjithsesi"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"Kaloi te <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"Pajisja përdor <xliff:g id="NEW_NETWORK">%1$s</xliff:g> kur <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> nuk ka qasje në internet. Mund të zbatohen tarifa."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"Kaloi nga <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> te <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"të dhënat celulare"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Eternet"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"të dhënat celulare"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Eternet"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"një lloj rrjeti i panjohur"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-sr/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-sr/strings.xml
index 8bedbff..1f7c95c 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-sr/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-sr/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Пријављивање на WiFi мрежу"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Пријавите се на мрежу"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> нема приступ интернету"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Додирните за опције"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"Мобилна мрежа нема приступ интернету"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"Мрежа нема приступ интернету"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Приступ приватном DNS серверу није успео"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> има ограничену везу"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Додирните да бисте се ипак повезали"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"Прешли сте на тип мреже <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Уређај користи тип мреже <xliff:g id="NEW_NETWORK">%1$s</xliff:g> када тип мреже <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> нема приступ интернету. Можда ће се наплаћивати трошкови."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"Прешли сте са типа мреже <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> на тип мреже <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"непознат тип мреже"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Ресурси за повезивање са системом"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Пријављивање на WiFi мрежу"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Пријавите се на мрежу"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> нема приступ интернету"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Додирните за опције"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"Мобилна мрежа нема приступ интернету"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"Мрежа нема приступ интернету"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Приступ приватном DNS серверу није успео"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> има ограничену везу"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Додирните да бисте се ипак повезали"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"Прешли сте на тип мреже <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"Уређај користи тип мреже <xliff:g id="NEW_NETWORK">%1$s</xliff:g> када тип мреже <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> нема приступ интернету. Можда ће се наплаћивати трошкови."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"Прешли сте са типа мреже <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> на тип мреже <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"мобилни подаци"</item>
-    <item msgid="5520925862115353992">"WiFi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Етернет"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"мобилни подаци"</item>
+    <item msgid="6341719431034774569">"WiFi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Етернет"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"непознат тип мреже"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-sv/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-sv/strings.xml
index b3f1763..7314005 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-sv/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-sv/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Logga in på ett Wi-Fi-nätverk"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Logga in på nätverket"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> har ingen internetanslutning"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Tryck för alternativ"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"Mobilnätverket har ingen internetanslutning"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"Nätverket har ingen internetanslutning"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Det går inte att komma åt den privata DNS-servern."</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> har begränsad anslutning"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Tryck för att ansluta ändå"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"Byte av nätverk till <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"<xliff:g id="NEW_NETWORK">%1$s</xliff:g> används på enheten när det inte finns internetåtkomst via <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>. Avgifter kan tillkomma."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"Byte av nätverk från <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> till <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"en okänd nätverkstyp"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Resurser för systemanslutning"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Logga in på ett Wi-Fi-nätverk"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Logga in på nätverket"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> har ingen internetanslutning"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Tryck för alternativ"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"Mobilnätverket har ingen internetanslutning"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"Nätverket har ingen internetanslutning"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Det går inte att komma åt den privata DNS-servern."</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> har begränsad anslutning"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Tryck för att ansluta ändå"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"Byte av nätverk till <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"<xliff:g id="NEW_NETWORK">%1$s</xliff:g> används på enheten när det inte finns internetåtkomst via <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>. Avgifter kan tillkomma."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"Byte av nätverk från <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> till <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"mobildata"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Ethernet"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"mobildata"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Ethernet"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"en okänd nätverkstyp"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-sw/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-sw/strings.xml
index 9674654..5c4d594 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-sw/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-sw/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Ingia kwa mtandao wa Wi-Fi"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Ingia katika mtandao"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> haina uwezo wa kufikia intaneti"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Gusa ili upate chaguo"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"Mtandao wa simu hauna uwezo wa kufikia intaneti"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"Mtandao hauna uwezo wa kufikia intaneti"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Seva ya faragha ya DNS haiwezi kufikiwa"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ina muunganisho unaofikia huduma chache."</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Gusa ili uunganishe tu"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"Sasa inatumia <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Kifaa hutumia <xliff:g id="NEW_NETWORK">%1$s</xliff:g> wakati <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> haina intaneti. Huenda ukalipishwa."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"Imebadilisha mtandao kutoka <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> na sasa inatumia <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"aina ya mtandao isiyojulikana"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Nyenzo za Muunganisho wa Mfumo"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Ingia kwa mtandao wa Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Ingia katika mtandao"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> haina uwezo wa kufikia intaneti"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Gusa ili upate chaguo"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"Mtandao wa simu hauna uwezo wa kufikia intaneti"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"Mtandao hauna uwezo wa kufikia intaneti"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Seva ya faragha ya DNS haiwezi kufikiwa"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ina muunganisho unaofikia huduma chache."</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Gusa ili uunganishe tu"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"Sasa inatumia <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"Kifaa hutumia <xliff:g id="NEW_NETWORK">%1$s</xliff:g> wakati <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> haina intaneti. Huenda ukalipishwa."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"Imebadilisha mtandao kutoka <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> na sasa inatumia <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"data ya simu"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Ethaneti"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"data ya mtandao wa simu"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Ethaneti"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"aina ya mtandao isiyojulikana"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ta/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ta/strings.xml
index 12604cb..90f89c9 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ta/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ta/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"வைஃபை நெட்வொர்க்கில் உள்நுழையவும்"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"நெட்வொர்க்கில் உள்நுழையவும்"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> நெட்வொர்க்கிற்கு இணைய அணுகல் இல்லை"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"விருப்பங்களுக்கு, தட்டவும்"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"மொபைல் நெட்வொர்க்கிற்கு இணைய அணுகல் இல்லை"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"நெட்வொர்க்கிற்கு இணைய அணுகல் இல்லை"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"தனிப்பட்ட DNS சேவையகத்தை அணுக இயலாது"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> வரம்பிற்கு உட்பட்ட இணைப்புநிலையைக் கொண்டுள்ளது"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"எப்படியேனும் இணைப்பதற்குத் தட்டவும்"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g>க்கு மாற்றப்பட்டது"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> நெட்வொர்க்கில் இண்டர்நெட் அணுகல் இல்லாததால், சாதனமானது <xliff:g id="NEW_NETWORK">%1$s</xliff:g> நெட்வொர்க்கைப் பயன்படுத்துகிறது. கட்டணங்கள் விதிக்கப்படலாம்."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> இலிருந்து <xliff:g id="NEW_NETWORK">%2$s</xliff:g>க்கு மாற்றப்பட்டது"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"தெரியாத நெட்வொர்க் வகை"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"சிஸ்டம் இணைப்பு மூலங்கள்"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"வைஃபை நெட்வொர்க்கில் உள்நுழையவும்"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"நெட்வொர்க்கில் உள்நுழையவும்"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> நெட்வொர்க்கிற்கு இணைய அணுகல் இல்லை"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"விருப்பங்களுக்கு, தட்டவும்"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"மொபைல் நெட்வொர்க்கிற்கு இணைய அணுகல் இல்லை"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"நெட்வொர்க்கிற்கு இணைய அணுகல் இல்லை"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"தனிப்பட்ட DNS சேவையகத்தை அணுக இயலாது"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> வரம்பிற்கு உட்பட்ட இணைப்புநிலையைக் கொண்டுள்ளது"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"எப்படியேனும் இணைப்பதற்குத் தட்டவும்"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g>க்கு மாற்றப்பட்டது"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> நெட்வொர்க்கில் இண்டர்நெட் அணுகல் இல்லாததால், சாதனமானது <xliff:g id="NEW_NETWORK">%1$s</xliff:g> நெட்வொர்க்கைப் பயன்படுத்துகிறது. கட்டணங்கள் விதிக்கப்படலாம்."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> இலிருந்து <xliff:g id="NEW_NETWORK">%2$s</xliff:g>க்கு மாற்றப்பட்டது"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"மொபைல் டேட்டா"</item>
-    <item msgid="5520925862115353992">"வைஃபை"</item>
-    <item msgid="1055487873974272842">"புளூடூத்"</item>
-    <item msgid="1616528372438698248">"ஈத்தர்நெட்"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"மொபைல் டேட்டா"</item>
+    <item msgid="6341719431034774569">"வைஃபை"</item>
+    <item msgid="5081440868800877512">"புளூடூத்"</item>
+    <item msgid="1160736166977503463">"ஈதர்நெட்"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"தெரியாத நெட்வொர்க் வகை"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-te/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-te/strings.xml
index 84a8640..c69b599 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-te/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-te/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Wi-Fi నెట్‌వర్క్‌కి సైన్ ఇన్ చేయండి"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"నెట్‌వర్క్‌కి సైన్ ఇన్ చేయండి"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>కి ఇంటర్నెట్ యాక్సెస్ లేదు"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"ఎంపికల కోసం నొక్కండి"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"మొబైల్ నెట్‌వర్క్‌కు ఇంటర్నెట్ యాక్సెస్ లేదు"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"నెట్‌వర్క్‌కు ఇంటర్నెట్ యాక్సెస్ లేదు"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"ప్రైవేట్ DNS సర్వర్‌ను యాక్సెస్ చేయడం సాధ్యపడదు"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> పరిమిత కనెక్టివిటీని కలిగి ఉంది"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"ఏదేమైనా కనెక్ట్ చేయడానికి నొక్కండి"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g>కి మార్చబడింది"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"పరికరం <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>కి ఇంటర్నెట్ యాక్సెస్ లేనప్పుడు <xliff:g id="NEW_NETWORK">%1$s</xliff:g>ని ఉపయోగిస్తుంది. ఛార్జీలు వర్తించవచ్చు."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> నుండి <xliff:g id="NEW_NETWORK">%2$s</xliff:g>కి మార్చబడింది"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"తెలియని నెట్‌వర్క్ రకం"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"సిస్టమ్ కనెక్టివిటీ రిసోర్స్‌లు"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Wi-Fi నెట్‌వర్క్‌కి సైన్ ఇన్ చేయండి"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"నెట్‌వర్క్‌కి సైన్ ఇన్ చేయండి"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>కి ఇంటర్నెట్ యాక్సెస్ లేదు"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"ఎంపికల కోసం నొక్కండి"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"మొబైల్ నెట్‌వర్క్‌కు ఇంటర్నెట్ యాక్సెస్ లేదు"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"నెట్‌వర్క్‌కు ఇంటర్నెట్ యాక్సెస్ లేదు"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"ప్రైవేట్ DNS సర్వర్‌ను యాక్సెస్ చేయడం సాధ్యపడదు"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> పరిమిత కనెక్టివిటీని కలిగి ఉంది"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"ఏదేమైనా కనెక్ట్ చేయడానికి నొక్కండి"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g>కి మార్చబడింది"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"పరికరం <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>కి ఇంటర్నెట్ యాక్సెస్ లేనప్పుడు <xliff:g id="NEW_NETWORK">%1$s</xliff:g>ని ఉపయోగిస్తుంది. ఛార్జీలు వర్తించవచ్చు."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> నుండి <xliff:g id="NEW_NETWORK">%2$s</xliff:g>కి మార్చబడింది"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"మొబైల్ డేటా"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"బ్లూటూత్"</item>
-    <item msgid="1616528372438698248">"ఈథర్‌నెట్"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"మొబైల్ డేటా"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"బ్లూటూత్"</item>
+    <item msgid="1160736166977503463">"ఈథర్‌నెట్"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"తెలియని నెట్‌వర్క్ రకం"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-th/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-th/strings.xml
index 1616e51..eee5a35 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-th/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-th/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"ลงชื่อเข้าใช้เครือข่าย WiFi"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"ลงชื่อเข้าใช้เครือข่าย"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> เข้าถึงอินเทอร์เน็ตไม่ได้"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"แตะเพื่อดูตัวเลือก"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"เครือข่ายมือถือไม่มีการเข้าถึงอินเทอร์เน็ต"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"เครือข่ายไม่มีการเข้าถึงอินเทอร์เน็ต"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"เข้าถึงเซิร์ฟเวอร์ DNS ไม่ได้"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> มีการเชื่อมต่อจำกัด"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"แตะเพื่อเชื่อมต่อ"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"เปลี่ยนเป็น <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"อุปกรณ์จะใช้ <xliff:g id="NEW_NETWORK">%1$s</xliff:g> เมื่อ <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> เข้าถึงอินเทอร์เน็ตไม่ได้ โดยอาจมีค่าบริการ"</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"เปลี่ยนจาก <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> เป็น <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"ประเภทเครือข่ายที่ไม่รู้จัก"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"ทรัพยากรการเชื่อมต่อของระบบ"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"ลงชื่อเข้าใช้เครือข่าย WiFi"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"ลงชื่อเข้าใช้เครือข่าย"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> เข้าถึงอินเทอร์เน็ตไม่ได้"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"แตะเพื่อดูตัวเลือก"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"เครือข่ายมือถือไม่มีการเข้าถึงอินเทอร์เน็ต"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"เครือข่ายไม่มีการเข้าถึงอินเทอร์เน็ต"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"เข้าถึงเซิร์ฟเวอร์ DNS ไม่ได้"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> มีการเชื่อมต่อจำกัด"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"แตะเพื่อเชื่อมต่อ"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"เปลี่ยนเป็น <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"อุปกรณ์จะใช้ <xliff:g id="NEW_NETWORK">%1$s</xliff:g> เมื่อ <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> เข้าถึงอินเทอร์เน็ตไม่ได้ โดยอาจมีค่าบริการ"</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"เปลี่ยนจาก <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> เป็น <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"เน็ตมือถือ"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"บลูทูธ"</item>
-    <item msgid="1616528372438698248">"อีเทอร์เน็ต"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"อินเทอร์เน็ตมือถือ"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"บลูทูธ"</item>
+    <item msgid="1160736166977503463">"อีเทอร์เน็ต"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"ประเภทเครือข่ายที่ไม่รู้จัก"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-tl/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-tl/strings.xml
index 3bf1ce4..8d665fe 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-tl/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-tl/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Mag-sign in sa Wi-Fi network"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Mag-sign in sa network"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"Walang access sa internet ang <xliff:g id="NETWORK_SSID">%1$s</xliff:g>"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"I-tap para sa mga opsyon"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"Walang access sa internet ang mobile network"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"Walang access sa internet ang network"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Hindi ma-access ang pribadong DNS server"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"Limitado ang koneksyon ng <xliff:g id="NETWORK_SSID">%1$s</xliff:g>"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"I-tap para kumonekta pa rin"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"Lumipat sa <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Ginagamit ng device ang <xliff:g id="NEW_NETWORK">%1$s</xliff:g> kapag walang access sa internet ang <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>. Maaaring may mga malapat na singilin."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"Lumipat sa <xliff:g id="NEW_NETWORK">%2$s</xliff:g> mula sa <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"isang hindi kilalang uri ng network"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Mga Resource ng Pagkakonekta ng System"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Mag-sign in sa Wi-Fi network"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Mag-sign in sa network"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"Walang access sa internet ang <xliff:g id="NETWORK_SSID">%1$s</xliff:g>"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"I-tap para sa mga opsyon"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"Walang access sa internet ang mobile network"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"Walang access sa internet ang network"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Hindi ma-access ang pribadong DNS server"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"Limitado ang koneksyon ng <xliff:g id="NETWORK_SSID">%1$s</xliff:g>"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"I-tap para kumonekta pa rin"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"Lumipat sa <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"Ginagamit ng device ang <xliff:g id="NEW_NETWORK">%1$s</xliff:g> kapag walang access sa internet ang <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>. Maaaring may mga malapat na singilin."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"Lumipat sa <xliff:g id="NEW_NETWORK">%2$s</xliff:g> mula sa <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"mobile data"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Ethernet"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"mobile data"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Ethernet"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"isang hindi kilalang uri ng network"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-tr/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-tr/strings.xml
index 5c326e5..cfb7632 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-tr/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-tr/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Kablosuz ağda oturum açın"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Ağda oturum açın"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ağının internet bağlantısı yok"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Seçenekler için dokunun"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"Mobil ağın internet bağlantısı yok"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"Ağın internet bağlantısı yok"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Gizli DNS sunucusuna erişilemiyor"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> sınırlı bağlantıya sahip"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Yine de bağlanmak için dokunun"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> ağına geçildi"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> ağının internet erişimi olmadığında cihaz <xliff:g id="NEW_NETWORK">%1$s</xliff:g> ağını kullanır. Bunun için ödeme alınabilir."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> ağından <xliff:g id="NEW_NETWORK">%2$s</xliff:g> ağına geçildi"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"bilinmeyen ağ türü"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Sistem Bağlantı Kaynakları"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Kablosuz ağda oturum açın"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Ağda oturum açın"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ağının internet bağlantısı yok"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Seçenekler için dokunun"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"Mobil ağın internet bağlantısı yok"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"Ağın internet bağlantısı yok"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Gizli DNS sunucusuna erişilemiyor"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> sınırlı bağlantıya sahip"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Yine de bağlanmak için dokunun"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> ağına geçildi"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> ağının internet erişimi olmadığında cihaz <xliff:g id="NEW_NETWORK">%1$s</xliff:g> ağını kullanır. Bunun için ödeme alınabilir."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> ağından <xliff:g id="NEW_NETWORK">%2$s</xliff:g> ağına geçildi"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"mobil veri"</item>
-    <item msgid="5520925862115353992">"Kablosuz"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Ethernet"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"mobil veri"</item>
+    <item msgid="6341719431034774569">"Kablosuz"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Ethernet"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"bilinmeyen ağ türü"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-uk/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-uk/strings.xml
index d1382da..c5da746 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-uk/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-uk/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Вхід у мережу Wi-Fi"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Вхід у мережу"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"Мережа <xliff:g id="NETWORK_SSID">%1$s</xliff:g> не має доступу до Інтернету"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Торкніться, щоб відкрити опції"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"Мобільна мережа не має доступу до Інтернету"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"Мережа не має доступу до Інтернету"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Немає доступу до приватного DNS-сервера"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"Підключення до мережі <xliff:g id="NETWORK_SSID">%1$s</xliff:g> обмежено"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Натисніть, щоб усе одно підключитися"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"Пристрій перейшов на мережу <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Коли мережа <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> не має доступу до Інтернету, використовується <xliff:g id="NEW_NETWORK">%1$s</xliff:g>. Може стягуватися плата."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"Пристрій перейшов з мережі <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> на мережу <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"невідомий тип мережі"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Ресурси для підключення системи"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Вхід у мережу Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Вхід у мережу"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"Мережа <xliff:g id="NETWORK_SSID">%1$s</xliff:g> не має доступу до Інтернету"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Торкніться, щоб відкрити опції"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"Мобільна мережа не має доступу до Інтернету"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"Мережа не має доступу до Інтернету"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Немає доступу до приватного DNS-сервера"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"Підключення до мережі <xliff:g id="NETWORK_SSID">%1$s</xliff:g> обмежено"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Натисніть, щоб усе одно підключитися"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"Пристрій перейшов на мережу <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"Коли мережа <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> не має доступу до Інтернету, використовується <xliff:g id="NEW_NETWORK">%1$s</xliff:g>. Може стягуватися плата."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"Пристрій перейшов з мережі <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> на мережу <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"мобільне передавання даних"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Ethernet"</item>
-    <item msgid="9177085807664964627">"Мережа VPN"</item>
+    <item msgid="5454013645032700715">"мобільний Інтернет"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Ethernet"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"невідомий тип мережі"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ur/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ur/strings.xml
index 3c031ad..bd2a228 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ur/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ur/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"‏Wi-Fi نیٹ ورک میں سائن ان کریں"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"نیٹ ورک میں سائن ان کریں"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> کو انٹرنیٹ تک رسائی حاصل نہیں ہے"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"اختیارات کیلئے تھپتھپائیں"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"موبائل نیٹ ورک کو انٹرنیٹ تک رسائی حاصل نہیں ہے"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"نیٹ ورک کو انٹرنیٹ تک رسائی حاصل نہیں ہے"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"‏نجی DNS سرور تک رسائی حاصل نہیں کی جا سکی"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> کی کنیکٹوٹی محدود ہے"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"بہر حال منسلک کرنے کے لیے تھپتھپائیں"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> پر سوئچ ہو گیا"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"جب <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> کو انٹرنیٹ تک رسائی نہیں ہوتی ہے تو آلہ <xliff:g id="NEW_NETWORK">%1$s</xliff:g> کا استعمال کرتا ہے۔ چارجز لاگو ہو سکتے ہیں۔"</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> سے <xliff:g id="NEW_NETWORK">%2$s</xliff:g> پر سوئچ ہو گیا"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"نیٹ ورک کی نامعلوم قسم"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"سسٹم کنیکٹوٹی کے وسائل"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"‏Wi-Fi نیٹ ورک میں سائن ان کریں"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"نیٹ ورک میں سائن ان کریں"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> کو انٹرنیٹ تک رسائی حاصل نہیں ہے"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"اختیارات کیلئے تھپتھپائیں"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"موبائل نیٹ ورک کو انٹرنیٹ تک رسائی حاصل نہیں ہے"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"نیٹ ورک کو انٹرنیٹ تک رسائی حاصل نہیں ہے"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"‏نجی DNS سرور تک رسائی حاصل نہیں کی جا سکی"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> کی کنیکٹوٹی محدود ہے"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"بہر حال منسلک کرنے کے لیے تھپتھپائیں"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> پر سوئچ ہو گیا"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"جب <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> کو انٹرنیٹ تک رسائی نہیں ہوتی ہے تو آلہ <xliff:g id="NEW_NETWORK">%1$s</xliff:g> کا استعمال کرتا ہے۔ چارجز لاگو ہو سکتے ہیں۔"</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> سے <xliff:g id="NEW_NETWORK">%2$s</xliff:g> پر سوئچ ہو گیا"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"موبائل ڈیٹا"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"بلوٹوتھ"</item>
-    <item msgid="1616528372438698248">"ایتھرنیٹ"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"موبائل ڈیٹا"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"بلوٹوتھ"</item>
+    <item msgid="1160736166977503463">"ایتھرنیٹ"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"نامعلوم نیٹ ورک کی قسم"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-uz/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-uz/strings.xml
index 7518db3..567aa88 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-uz/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-uz/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Wi-Fi tarmoqqa kirish"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Tarmoqqa kirish"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> nomli tarmoqda internetga ruxsati yoʻq"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Variantlarni ko‘rsatish uchun bosing"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"Mobil tarmoq internetga ulanmagan"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"Tarmoq internetga ulanmagan"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Xususiy DNS server ishlamayapti"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> nomli tarmoqda aloqa cheklangan"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Baribir ulash uchun bosing"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"Yangi ulanish: <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Agar <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> tarmoqda internet uzilsa, qurilma <xliff:g id="NEW_NETWORK">%1$s</xliff:g>ga ulanadi. Sarflangan trafik uchun haq olinishi mumkin."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> tarmog‘idan <xliff:g id="NEW_NETWORK">%2$s</xliff:g> tarmog‘iga o‘tildi"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"noma’lum tarmoq turi"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Tizim aloqa resurslari"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Wi-Fi tarmoqqa kirish"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Tarmoqqa kirish"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> nomli tarmoqda internetga ruxsati yoʻq"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Variantlarni ko‘rsatish uchun bosing"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"Mobil tarmoq internetga ulanmagan"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"Tarmoq internetga ulanmagan"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Xususiy DNS server ishlamayapti"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> nomli tarmoqda aloqa cheklangan"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Baribir ulash uchun bosing"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"Yangi ulanish: <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"Agar <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> tarmoqda internet uzilsa, qurilma <xliff:g id="NEW_NETWORK">%1$s</xliff:g>ga ulanadi. Sarflangan trafik uchun haq olinishi mumkin."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> tarmog‘idan <xliff:g id="NEW_NETWORK">%2$s</xliff:g> tarmog‘iga o‘tildi"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"mobil internet"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Ethernet"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"mobil internet"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Ethernet"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"nomaʼlum tarmoq turi"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-vi/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-vi/strings.xml
index d2284d4..590b388 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-vi/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-vi/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Đăng nhập vào mạng Wi-Fi"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Đăng nhập vào mạng"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> không có quyền truy cập Internet"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Nhấn để biết tùy chọn"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"Mạng di động không có quyền truy cập Internet"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"Mạng không có quyền truy cập Internet"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Không thể truy cập máy chủ DNS riêng tư"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> có khả năng kết nối giới hạn"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Nhấn để tiếp tục kết nối"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"Đã chuyển sang <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Thiết bị sử dụng <xliff:g id="NEW_NETWORK">%1$s</xliff:g> khi <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> không có quyền truy cập Internet. Bạn có thể phải trả phí."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"Đã chuyển từ <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> sang <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"loại mạng không xác định"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Tài nguyên kết nối hệ thống"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Đăng nhập vào mạng Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Đăng nhập vào mạng"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> không có quyền truy cập Internet"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Nhấn để biết tùy chọn"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"Mạng di động không có quyền truy cập Internet"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"Mạng không có quyền truy cập Internet"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Không thể truy cập máy chủ DNS riêng tư"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> có khả năng kết nối giới hạn"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Nhấn để tiếp tục kết nối"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"Đã chuyển sang <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"Thiết bị sử dụng <xliff:g id="NEW_NETWORK">%1$s</xliff:g> khi <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> không có quyền truy cập Internet. Bạn có thể phải trả phí."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"Đã chuyển từ <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> sang <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"dữ liệu di động"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Ethernet"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"dữ liệu di động"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"Bluetooth"</item>
+    <item msgid="1160736166977503463">"Ethernet"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"loại mạng không xác định"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-zh-rCN/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-zh-rCN/strings.xml
index 813482b..9d6cff9 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-zh-rCN/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-zh-rCN/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"登录到WLAN网络"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"登录到网络"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> 无法访问互联网"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"点按即可查看相关选项"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"此移动网络无法访问互联网"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"此网络无法访问互联网"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"无法访问私人 DNS 服务器"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> 的连接受限"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"点按即可继续连接"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"已切换至<xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"设备会在<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>无法访问互联网时使用<xliff:g id="NEW_NETWORK">%1$s</xliff:g>(可能需要支付相应的费用)。"</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"已从<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>切换至<xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"未知网络类型"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"系统网络连接资源"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"登录到WLAN网络"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"登录到网络"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> 无法访问互联网"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"点按即可查看相关选项"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"此移动网络无法访问互联网"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"此网络无法访问互联网"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"无法访问私人 DNS 服务器"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> 的连接受限"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"点按即可继续连接"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"已切换至<xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"设备会在<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>无法访问互联网时使用<xliff:g id="NEW_NETWORK">%1$s</xliff:g>(可能需要支付相应的费用)。"</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"已从<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>切换至<xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"移动数据"</item>
-    <item msgid="5520925862115353992">"WLAN"</item>
-    <item msgid="1055487873974272842">"蓝牙"</item>
-    <item msgid="1616528372438698248">"以太网"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"移动数据"</item>
+    <item msgid="6341719431034774569">"WLAN"</item>
+    <item msgid="5081440868800877512">"蓝牙"</item>
+    <item msgid="1160736166977503463">"以太网"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"未知网络类型"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-zh-rHK/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-zh-rHK/strings.xml
index 676404f..c84241c 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-zh-rHK/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-zh-rHK/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"登入 Wi-Fi 網絡"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"登入網絡"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>未有連接至互聯網"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"輕按即可查看選項"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"流動網絡並未連接互聯網"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"網絡並未連接互聯網"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"無法存取私人 DNS 伺服器"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>連線受限"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"仍要輕按以連結至此網絡"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"已切換至<xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"裝置會在 <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> 無法連線至互聯網時使用<xliff:g id="NEW_NETWORK">%1$s</xliff:g> (可能需要支付相關費用)。"</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"已從<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>切換至<xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"不明網絡類型"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"系統連線資源"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"登入 Wi-Fi 網絡"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"登入網絡"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>未有連接至互聯網"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"輕按即可查看選項"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"流動網絡並未連接互聯網"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"網絡並未連接互聯網"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"無法存取私人 DNS 伺服器"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>連線受限"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"仍要輕按以連結至此網絡"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"已切換至<xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"裝置會在 <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> 無法連線至互聯網時使用<xliff:g id="NEW_NETWORK">%1$s</xliff:g> (可能需要支付相關費用)。"</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"已從<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>切換至<xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"流動數據"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"藍牙"</item>
-    <item msgid="1616528372438698248">"以太網"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"流動數據"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"藍牙"</item>
+    <item msgid="1160736166977503463">"以太網絡"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"不明網絡類型"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-zh-rTW/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-zh-rTW/strings.xml
index f355138..07540d1 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-zh-rTW/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-zh-rTW/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"登入 Wi-Fi 網路"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"登入網路"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> 沒有網際網路連線"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"輕觸即可查看選項"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"這個行動網路沒有網際網路連線"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"這個網路沒有網際網路連線"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"無法存取私人 DNS 伺服器"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> 的連線能力受限"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"輕觸即可繼續連線"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"已切換至<xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"裝置會在無法連上「<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>」時切換至「<xliff:g id="NEW_NETWORK">%1$s</xliff:g>」(可能需要支付相關費用)。"</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"已從 <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> 切換至<xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"不明的網路類型"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"系統連線資源"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"登入 Wi-Fi 網路"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"登入網路"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> 沒有網際網路連線"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"輕觸即可查看選項"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"這個行動網路沒有網際網路連線"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"這個網路沒有網際網路連線"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"無法存取私人 DNS 伺服器"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> 的連線能力受限"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"輕觸即可繼續連線"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"已切換至<xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"裝置會在無法連上「<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>」時切換至「<xliff:g id="NEW_NETWORK">%1$s</xliff:g>」(可能需要支付相關費用)。"</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"已從 <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> 切換至<xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"行動數據"</item>
-    <item msgid="5520925862115353992">"Wi-Fi"</item>
-    <item msgid="1055487873974272842">"藍牙"</item>
-    <item msgid="1616528372438698248">"乙太網路"</item>
-    <item msgid="9177085807664964627">"VPN"</item>
+    <item msgid="5454013645032700715">"行動數據"</item>
+    <item msgid="6341719431034774569">"Wi-Fi"</item>
+    <item msgid="5081440868800877512">"藍牙"</item>
+    <item msgid="1160736166977503463">"乙太網路"</item>
+    <item msgid="7347618872551558605">"VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"不明的網路類型"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-zu/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-zu/strings.xml
index 55fefb7..19f390b 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-zu/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-zu/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -13,27 +13,31 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
-  -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Ngena ngemvume kunethiwekhi ye-Wi-Fi"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Ngena ngemvume kunethiwekhi"</string>
-    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
-    <string name="wifi_no_internet" msgid="1386911698276448061">"I-<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ayinakho ukufinyelela kwe-inthanethi"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Thepha ukuze uthole izinketho"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"Inethiwekhi yeselula ayinakho ukufinyelela kwe-inthanethi"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"Inethiwekhi ayinakho ukufinyelela kwenethiwekhi"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Iseva eyimfihlo ye-DNS ayikwazi ukufinyelelwa"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"I-<xliff:g id="NETWORK_SSID">%1$s</xliff:g> inokuxhumeka okukhawulelwe"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Thepha ukuze uxhume noma kunjalo"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"Kushintshelwe ku-<xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Idivayisi isebenzisa i-<xliff:g id="NEW_NETWORK">%1$s</xliff:g> uma i-<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> inganakho ukufinyelela kwe-inthanethi. Kungasebenza izindleko."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"Kushintshelewe kusuka ku-<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> kuya ku-<xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"uhlobo olungaziwa lwenethiwekhi"</string>
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Izinsiza Zokuxhumeka Zesistimu"</string>
+    <string name="wifi_available_sign_in" msgid="5254156478006453593">"Ngena ngemvume kunethiwekhi ye-Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="7794369329839408792">"Ngena ngemvume kunethiwekhi"</string>
+    <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
+    <skip />
+    <string name="wifi_no_internet" msgid="3961697321010262514">"I-<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ayinakho ukufinyelela kwe-inthanethi"</string>
+    <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Thepha ukuze uthole izinketho"</string>
+    <string name="mobile_no_internet" msgid="2262524005014119639">"Inethiwekhi yeselula ayinakho ukufinyelela kwe-inthanethi"</string>
+    <string name="other_networks_no_internet" msgid="8226004998719563755">"Inethiwekhi ayinakho ukufinyelela kwenethiwekhi"</string>
+    <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Iseva eyimfihlo ye-DNS ayikwazi ukufinyelelwa"</string>
+    <string name="network_partial_connectivity" msgid="5957065286265771273">"I-<xliff:g id="NETWORK_SSID">%1$s</xliff:g> inokuxhumeka okukhawulelwe"</string>
+    <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Thepha ukuze uxhume noma kunjalo"</string>
+    <string name="network_switch_metered" msgid="2814798852883117872">"Kushintshelwe ku-<xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="605546931076348229">"Idivayisi isebenzisa i-<xliff:g id="NEW_NETWORK">%1$s</xliff:g> uma i-<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> inganakho ukufinyelela kwe-inthanethi. Kungasebenza izindleko."</string>
+    <string name="network_switch_metered_toast" msgid="8831325515040986641">"Kushintshelewe kusuka ku-<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> kuya ku-<xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"idatha yeselula"</item>
-    <item msgid="5520925862115353992">"I-Wi-Fi"</item>
-    <item msgid="1055487873974272842">"I-Bluetooth"</item>
-    <item msgid="1616528372438698248">"I-Ethernet"</item>
-    <item msgid="9177085807664964627">"I-VPN"</item>
+    <item msgid="5454013645032700715">"idatha yeselula"</item>
+    <item msgid="6341719431034774569">"I-Wi-Fi"</item>
+    <item msgid="5081440868800877512">"I-Bluetooth"</item>
+    <item msgid="1160736166977503463">"I-Ethernet"</item>
+    <item msgid="7347618872551558605">"I-VPN"</item>
   </string-array>
+    <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"uhlobo olungaziwa lwenethiwekhi"</string>
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values/config.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values/config.xml
index 71674e4..9ff2a22 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values/config.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values/config.xml
@@ -78,6 +78,11 @@
         <item>1,3</item>
     </string-array>
 
+    <!-- Reserved privileged keepalive slots per transport. -->
+    <integer translatable="false" name="config_reservedPrivilegedKeepaliveSlots">2</integer>
+
+    <!-- Allowed unprivileged keepalive slots per uid. -->
+    <integer translatable="false" name="config_allowedUnprivilegedKeepalivePerUid">2</integer>
 
     <!-- Default value for ConnectivityManager.getMultipathPreference() on metered networks. Actual
          device behaviour is controlled by the metered multipath preference in
@@ -89,4 +94,33 @@
          Settings.Global.NETWORK_AVOID_BAD_WIFI. This is the default value of that setting. -->
     <integer translatable="false" name="config_networkAvoidBadWifi">1</integer>
 
+    <!-- Array of ConnectivityManager.TYPE_xxxx constants for networks that may only
+         be controlled by systemOrSignature apps.  -->
+    <integer-array translatable="false" name="config_protectedNetworks">
+        <item>10</item>
+        <item>11</item>
+        <item>12</item>
+        <item>14</item>
+        <item>15</item>
+    </integer-array>
+
+    <!-- Whether the internal vehicle network should remain active even when no
+         apps requested it. -->
+    <bool name="config_vehicleInternalNetworkAlwaysRequested">false</bool>
+
+
+    <!-- If the hardware supports specially marking packets that caused a wakeup of the
+         main CPU, set this value to the mark used. -->
+    <integer name="config_networkWakeupPacketMark">0</integer>
+
+    <!-- Mask to use when checking skb mark defined in config_networkWakeupPacketMark above. -->
+    <integer name="config_networkWakeupPacketMask">0</integer>
+
+    <!-- Whether/how to notify the user on network switches. See LingerMonitor.java. -->
+    <integer translatable="false" name="config_networkNotifySwitchType">0</integer>
+
+    <!-- What types of network switches to notify. See LingerMonitor.java. -->
+    <string-array translatable="false" name="config_networkNotifySwitches">
+    </string-array>
+
 </resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values/overlayable.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values/overlayable.xml
index 25e19ce..717d08e 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values/overlayable.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values/overlayable.xml
@@ -26,6 +26,12 @@
             <item type="integer" name="config_networkMeteredMultipathPreference"/>
             <item type="array" name="config_networkSupportedKeepaliveCount"/>
             <item type="integer" name="config_networkAvoidBadWifi"/>
+            <item type="array" name="config_protectedNetworks"/>
+            <item type="bool" name="config_vehicleInternalNetworkAlwaysRequested"/>
+            <item type="integer" name="config_networkWakeupPacketMark"/>
+            <item type="integer" name="config_networkWakeupPacketMask"/>
+            <item type="integer" name="config_networkNotifySwitchType"/>
+            <item type="array" name="config_networkNotifySwitches"/>
 
         </policy>
     </overlayable>
diff --git a/packages/Connectivity/service/jarjar-rules.txt b/packages/Connectivity/service/jarjar-rules.txt
index a7b419b..5caa11b 100644
--- a/packages/Connectivity/service/jarjar-rules.txt
+++ b/packages/Connectivity/service/jarjar-rules.txt
@@ -12,3 +12,6 @@
 # the one in com.android.internal.util
 rule android.util.IndentingPrintWriter* android.connectivity.util.IndentingPrintWriter@1
 rule com.android.internal.util.** com.android.connectivity.util.@1
+
+rule com.android.internal.messages.** com.android.connectivity.messages.@1
+rule com.google.protobuf.** com.android.connectivity.protobuf.@1
diff --git a/packages/Connectivity/service/jni/com_android_server_TestNetworkService.cpp b/packages/Connectivity/service/jni/com_android_server_TestNetworkService.cpp
index 36a6fde..e7a40e5 100644
--- a/packages/Connectivity/service/jni/com_android_server_TestNetworkService.cpp
+++ b/packages/Connectivity/service/jni/com_android_server_TestNetworkService.cpp
@@ -35,8 +35,6 @@
 
 #include <log/log.h>
 
-#include "netutils/ifc.h"
-
 #include "jni.h"
 #include <android-base/stringprintf.h>
 #include <android-base/unique_fd.h>
@@ -48,9 +46,8 @@
 //------------------------------------------------------------------------------
 
 static void throwException(JNIEnv* env, int error, const char* action, const char* iface) {
-    const std::string& msg =
-        android::base::StringPrintf("Error %s %s: %s", action, iface, strerror(error));
-
+    const std::string& msg = "Error: " + std::string(action) + " " + std::string(iface) +  ": "
+                + std::string(strerror(error));
     jniThrowException(env, "java/lang/IllegalStateException", msg.c_str());
 }
 
diff --git a/services/core/java/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneIdValidator.java b/packages/Connectivity/service/proto/connectivityproto.proto
similarity index 61%
copy from services/core/java/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneIdValidator.java
copy to packages/Connectivity/service/proto/connectivityproto.proto
index cab5ad2..a992d7c 100644
--- a/services/core/java/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneIdValidator.java
+++ b/packages/Connectivity/service/proto/connectivityproto.proto
@@ -14,17 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server.timezonedetector.location;
+syntax = "proto2";
 
-import android.annotation.NonNull;
-
-import com.android.i18n.timezone.ZoneInfoDb;
-
-class ZoneInfoDbTimeZoneIdValidator implements
-        LocationTimeZoneProvider.TimeZoneIdValidator {
-
-    @Override
-    public boolean isValid(@NonNull String timeZoneId) {
-        return ZoneInfoDb.getInstance().hasTimeZone(timeZoneId);
-    }
-}
+// Connectivity protos can be created in this directory. Note this file must be included before
+// building system-messages-proto, otherwise it will not build by itself.
diff --git a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
index 087275e..801b490 100644
--- a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
+++ b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
@@ -19,6 +19,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.usage.StorageStatsManager;
+import android.content.AttributionSource;
 import android.content.ContentResolver;
 import android.content.UriPermission;
 import android.database.Cursor;
@@ -28,7 +29,6 @@
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Environment;
-import android.os.IBinder;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.storage.DiskInfo;
@@ -141,17 +141,17 @@
     }
 
     @Override
-    protected int enforceReadPermissionInner(Uri uri, String callingPkg,
-            @Nullable String featureId, IBinder callerToken) throws SecurityException {
+    protected int enforceReadPermissionInner(Uri uri,
+            @NonNull AttributionSource attributionSource) throws SecurityException {
         enforceShellRestrictions();
-        return super.enforceReadPermissionInner(uri, callingPkg, featureId, callerToken);
+        return super.enforceReadPermissionInner(uri, attributionSource);
     }
 
     @Override
-    protected int enforceWritePermissionInner(Uri uri, String callingPkg,
-            @Nullable String featureId, IBinder callerToken) throws SecurityException {
+    protected int enforceWritePermissionInner(Uri uri,
+            @NonNull AttributionSource attributionSource) throws SecurityException {
         enforceShellRestrictions();
-        return super.enforceWritePermissionInner(uri, callingPkg, featureId, callerToken);
+        return super.enforceWritePermissionInner(uri, attributionSource);
     }
 
     public void updateVolumes() {
diff --git a/packages/FusedLocation/test/src/com/android/location/fused/tests/FusedLocationServiceTest.java b/packages/FusedLocation/test/src/com/android/location/fused/tests/FusedLocationServiceTest.java
index 7cc5994..c4c60ea 100644
--- a/packages/FusedLocation/test/src/com/android/location/fused/tests/FusedLocationServiceTest.java
+++ b/packages/FusedLocation/test/src/com/android/location/fused/tests/FusedLocationServiceTest.java
@@ -151,20 +151,14 @@
         }
 
         @Override
-        public void onInitialize(boolean allowed, ProviderProperties properties, String packageName,
-                String attributionTag) {
-
-        }
+        public void onInitialize(boolean allowed, ProviderProperties properties,
+                String attributionTag) {}
 
         @Override
-        public void onSetAllowed(boolean allowed) {
-
-        }
+        public void onSetAllowed(boolean allowed) {}
 
         @Override
-        public void onSetProperties(ProviderProperties properties) {
-
-        }
+        public void onSetProperties(ProviderProperties properties) {}
 
         @Override
         public void onReportLocation(Location location) {
@@ -177,9 +171,7 @@
         }
 
         @Override
-        public void onFlushComplete() {
-
-        }
+        public void onFlushComplete() {}
 
         public Location getNextLocation(long timeoutMs) throws InterruptedException {
             return mLocations.poll(timeoutMs, TimeUnit.MILLISECONDS);
diff --git a/packages/PackageInstaller/res/values-iw/strings.xml b/packages/PackageInstaller/res/values-iw/strings.xml
index 7cabdd5..5b17d74 100644
--- a/packages/PackageInstaller/res/values-iw/strings.xml
+++ b/packages/PackageInstaller/res/values-iw/strings.xml
@@ -21,9 +21,9 @@
     <string name="done" msgid="6632441120016885253">"סיום"</string>
     <string name="cancel" msgid="1018267193425558088">"ביטול"</string>
     <string name="installing" msgid="4921993079741206516">"מתקין…"</string>
-    <string name="installing_app" msgid="1165095864863849422">"מתקין את <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"מתבצעת התקנה של <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
     <string name="install_done" msgid="5987363587661783896">"האפליקציה הותקנה."</string>
-    <string name="install_confirm_question" msgid="8176284075816604590">"האם ברצונך להתקין אפליקציה זו?"</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"להתקין את האפליקציה הזו?"</string>
     <string name="install_confirm_question_update" msgid="7942235418781274635">"האם ברצונך להתקין עדכון עבור אפליקציה קיימת זו? הנתונים הקיימים שלך לא יאבדו."</string>
     <string name="install_confirm_question_update_system" msgid="4713001702777910263">"האם ברצונך להתקין עדכון עבור אפליקציה מובנית זו? הנתונים הקיימים שלך לא יאבדו."</string>
     <string name="install_failed" msgid="5777824004474125469">"האפליקציה לא הותקנה."</string>
@@ -31,14 +31,14 @@
     <string name="install_failed_conflict" msgid="3493184212162521426">"האפליקציה לא הותקנה כי החבילה מתנגשת עם חבילה קיימת."</string>
     <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"האפליקציה לא הותקנה כי האפליקציה אינה תואמת לטאבלט."</string>
     <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"האפליקציה הזו אינה תואמת לטלוויזיה שלך."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"האפליקציה לא הותקנה כי האפליקציה אינה תואמת לטלפון."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"האפליקציה לא הותקנה כי היא לא תואמת לטלפון."</string>
     <string name="install_failed_invalid_apk" msgid="8581007676422623930">"האפליקציה לא הותקנה כי נראה שהחבילה לא תקפה."</string>
     <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"לא ניתן להתקין את <xliff:g id="APP_NAME">%1$s</xliff:g> בטאבלט שלך."</string>
     <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"לא ניתן להתקין את <xliff:g id="APP_NAME">%1$s</xliff:g> בטלוויזיה שלך."</string>
     <string name="install_failed_msg" product="default" msgid="6484461562647915707">"לא ניתן להתקין את <xliff:g id="APP_NAME">%1$s</xliff:g> בטלפון שלך."</string>
     <string name="launch" msgid="3952550563999890101">"פתיחה"</string>
     <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"מנהל המערכת שלך לא מתיר התקנה של אפליקציות ממקורות לא ידועים"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"למשתמש זה אין הרשאה להתקין אפליקציות שאינן מוכרות"</string>
+    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"למשתמש הזה אין הרשאה להתקין אפליקציות שאינן מוכרות"</string>
     <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"למשתמש הזה אין הרשאה להתקין אפליקציות"</string>
     <string name="ok" msgid="7871959885003339302">"אישור"</string>
     <string name="manage_applications" msgid="5400164782453975580">"ניהול אפליקציות"</string>
@@ -52,16 +52,16 @@
     <string name="generic_error_dlg_text" msgid="5287861443265795232">"לא ניתן היה להסיר את התקנת האפליקציה."</string>
     <string name="uninstall_application_title" msgid="4045420072401428123">"הסרת התקנה של האפליקציה"</string>
     <string name="uninstall_update_title" msgid="824411791011583031">"הסרת התקנה של עדכון"</string>
-    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> הוא חלק מהאפליקציה הבאה:"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"הפעילות <xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> היא חלק מהאפליקציה הבאה:"</string>
     <string name="uninstall_application_text" msgid="3816830743706143980">"האם ברצונך להסיר את ההתקנה של אפליקציה זו?"</string>
-    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"האם אתה רוצה להסיר את האפליקציה הזו עבור "<b>"כל"</b>" המשתמשים? האפליקציה והנתונים שלה יוסרו מ"<b>"כל"</b>" המשתמשים במכשיר."</string>
-    <string name="uninstall_application_text_user" msgid="498072714173920526">"האם ברצונך להסיר את התקנתה של אפליקציה זו עבור המשתמש <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"להסיר את האפליקציה הזו עבור "<b>"כל"</b>" המשתמשים? האפליקציה והנתונים שלה יוסרו עבור "<b>"כל"</b>" המשתמשים במכשיר."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"להסיר את ההתקנה של האפליקציה הזו עבור <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
     <string name="uninstall_update_text" msgid="863648314632448705">"האם להחליף את האפליקציה הזאת בגרסת היצרן? כל הנתונים יוסרו."</string>
     <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"האם להחליף את האפליקציה הזאת בגרסת היצרן? כל הנתונים יוסרו. הפעולה תשפיע על כל משתמשי המכשיר, כולל משתמשים בעלי פרופיל עבודה."</string>
     <string name="uninstall_keep_data" msgid="7002379587465487550">"שמירת <xliff:g id="SIZE">%1$s</xliff:g> מנתוני האפליקציה."</string>
     <string name="uninstalling_notification_channel" msgid="840153394325714653">"התקנות בתהליכי הסרה"</string>
     <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"הסרות התקנה שנכשלו"</string>
-    <string name="uninstalling" msgid="8709566347688966845">"מסיר התקנה..."</string>
+    <string name="uninstalling" msgid="8709566347688966845">"בתהליך הסרת התקנה..."</string>
     <string name="uninstalling_app" msgid="8866082646836981397">"מסיר את ההתקנה של <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"הסרת ההתקנה הסתיימה."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"ההתקנה של <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> הוסרה"</string>
diff --git a/packages/PackageInstaller/res/values-sv/strings.xml b/packages/PackageInstaller/res/values-sv/strings.xml
index d0902c3..28ad6aa 100644
--- a/packages/PackageInstaller/res/values-sv/strings.xml
+++ b/packages/PackageInstaller/res/values-sv/strings.xml
@@ -24,8 +24,8 @@
     <string name="installing_app" msgid="1165095864863849422">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> installeras …"</string>
     <string name="install_done" msgid="5987363587661783896">"Appen har installerats."</string>
     <string name="install_confirm_question" msgid="8176284075816604590">"Vill du installera det här programmet?"</string>
-    <string name="install_confirm_question_update" msgid="7942235418781274635">"Vill du installera en uppdatering till den här befintliga appen? Dina befintliga data försvinner inte."</string>
-    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Vill du installera en uppdatering av den inbyggda appen? Dina befintliga data försvinner inte."</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Vill du installera en uppdatering till den här befintliga appen? Din befintliga data försvinner inte."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Vill du installera en uppdatering av den inbyggda appen? Din befintliga data försvinner inte."</string>
     <string name="install_failed" msgid="5777824004474125469">"Appen har inte installerats."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"Paketet har blockerats för installation."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"Appen har inte installerats på grund av en konflikt mellan detta paket och ett befintligt paket."</string>
diff --git a/packages/PrintSpooler/res/values-iw/strings.xml b/packages/PrintSpooler/res/values-iw/strings.xml
index 64db711..5dcd7f2 100644
--- a/packages/PrintSpooler/res/values-iw/strings.xml
+++ b/packages/PrintSpooler/res/values-iw/strings.xml
@@ -32,10 +32,10 @@
     <string name="template_page_range" msgid="428638530038286328">"טווח של <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"למשל 1–5‏,8,‏11–13"</string>
     <string name="print_preview" msgid="8010217796057763343">"תצוגה מקדימה של הדפסה"</string>
-    <string name="install_for_print_preview" msgid="6366303997385509332">"‏התקן מציג PDF ליצירת תצוגה מקדימה"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"‏התקנה של PDF viewer‏ ליצירת תצוגה מקדימה"</string>
     <string name="printing_app_crashed" msgid="854477616686566398">"אפליקציית ההדפסה קרסה"</string>
     <string name="generating_print_job" msgid="3119608742651698916">"יוצר עבודת הדפסה"</string>
-    <string name="save_as_pdf" msgid="5718454119847596853">"‏שמור כ-PDF"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"‏שמירה כ-PDF"</string>
     <string name="all_printers" msgid="5018829726861876202">"כל המדפסות…"</string>
     <string name="print_dialog" msgid="32628687461331979">"תיבת דו שיח של מדפסת"</string>
     <string name="current_page_template" msgid="5145005201131935302">"<xliff:g id="CURRENT_PAGE">%1$d</xliff:g>/<xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
@@ -44,7 +44,7 @@
     <string name="expand_handle" msgid="7282974448109280522">"ידית הרחבה"</string>
     <string name="collapse_handle" msgid="6886637989442507451">"ידית כיווץ"</string>
     <string name="print_button" msgid="645164566271246268">"הדפס"</string>
-    <string name="savetopdf_button" msgid="2976186791686924743">"‏שמור כ-PDF"</string>
+    <string name="savetopdf_button" msgid="2976186791686924743">"‏שמירה כ-PDF"</string>
     <string name="print_options_expanded" msgid="6944679157471691859">"אפשרויות ההדפסה הורחבו"</string>
     <string name="print_options_collapsed" msgid="7455930445670414332">"אפשרויות ההדפסה כווצו"</string>
     <string name="search" msgid="5421724265322228497">"חיפוש"</string>
@@ -91,7 +91,7 @@
     <string name="restart" msgid="2472034227037808749">"הפעלה מחדש"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"אין חיבור למדפסת"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"לא ידוע"</string>
-    <string name="print_service_security_warning_title" msgid="2160752291246775320">"האם להשתמש ב-<xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"האם להשתמש בשירות <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"ייתכן שהמסמך שלך יעבור בשרת אחד או יותר בדרכו למדפסת."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"שחור ולבן"</item>
@@ -107,7 +107,7 @@
     <item msgid="3199660090246166812">"לרוחב"</item>
   </string-array>
     <string name="print_write_error_message" msgid="5787642615179572543">"לא ניתן היה לכתוב לקובץ"</string>
-    <string name="print_error_default_message" msgid="8602678405502922346">"מצטערים, אך זה לא עבד. נסה שוב."</string>
+    <string name="print_error_default_message" msgid="8602678405502922346">"מצטערים, הפעולה לא בוצעה. אפשר לנסות שוב."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"כדאי לנסות שוב"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"המדפסת הזו אינה זמינה כעת."</string>
     <string name="print_cannot_load_page" msgid="6179560924492912009">"לא ניתן להציג תצוגה מקדימה"</string>
diff --git a/packages/PrintSpooler/res/values-nl/strings.xml b/packages/PrintSpooler/res/values-nl/strings.xml
index 6448acc..2cd8d9b 100644
--- a/packages/PrintSpooler/res/values-nl/strings.xml
+++ b/packages/PrintSpooler/res/values-nl/strings.xml
@@ -50,7 +50,7 @@
     <string name="search" msgid="5421724265322228497">"Zoeken"</string>
     <string name="all_printers_label" msgid="3178848870161526399">"Alle printers"</string>
     <string name="add_print_service_label" msgid="5356702546188981940">"Service toevoegen"</string>
-    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Zoekvak weergegeven"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Zoekvak wordt getoond"</string>
     <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Zoekvak verborgen"</string>
     <string name="print_add_printer" msgid="1088656468360653455">"Printer toevoegen"</string>
     <string name="print_select_printer" msgid="7388760939873368698">"Printer selecteren"</string>
diff --git a/packages/SettingsLib/Android.bp b/packages/SettingsLib/Android.bp
index d6c66b5..5e69a4e 100644
--- a/packages/SettingsLib/Android.bp
+++ b/packages/SettingsLib/Android.bp
@@ -17,8 +17,8 @@
 
     // TODO(b/149540986): revert this change.
     static_libs: [
-         // All other dependent components should be put in
-         // "SettingsLibDependenciesWithoutWifiTracker".
+        // All other dependent components should be put in
+        // "SettingsLibDependenciesWithoutWifiTracker".
         "WifiTrackerLib",
     ],
 
@@ -27,7 +27,10 @@
 
     resource_dirs: ["res"],
 
-    srcs: ["src/**/*.java", "src/**/*.kt"],
+    srcs: [
+        "src/**/*.java",
+        "src/**/*.kt",
+    ],
 
     min_sdk_version: "21",
 
@@ -68,6 +71,7 @@
         "SettingsLibUsageProgressBarPreference",
         "SettingsLibCollapsingToolbarBaseActivity",
         "SettingsLibTwoTargetPreference",
+        "SettingsLibSettingsTransition",
     ],
 }
 
diff --git a/packages/SettingsLib/AppPreference/res/layout/preference_app.xml b/packages/SettingsLib/AppPreference/res/layout/preference_app.xml
index 8c208e3..0390e86 100644
--- a/packages/SettingsLib/AppPreference/res/layout/preference_app.xml
+++ b/packages/SettingsLib/AppPreference/res/layout/preference_app.xml
@@ -21,7 +21,7 @@
     android:background="?android:attr/selectableItemBackground"
     android:gravity="center_vertical"
     android:minHeight="?android:attr/listPreferredItemHeightSmall"
-    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+    android:paddingStart="@dimen/app_preference_padding_start"
     android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">
 
     <LinearLayout
@@ -29,7 +29,7 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:gravity="start|center_vertical"
-        android:minWidth="56dp"
+        android:minWidth="@dimen/app_icon_min_width"
         android:orientation="horizontal"
         android:paddingEnd="8dp"
         android:paddingTop="4dp"
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/Android.bp b/packages/SettingsLib/CollapsingToolbarBaseActivity/Android.bp
index 231babe..dd9fc2c 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/Android.bp
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/Android.bp
@@ -23,5 +23,6 @@
     apex_available: [
         "//apex_available:platform",
         "com.android.cellbroadcast",
+        "com.android.permission",
     ],
 }
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout-v31/collapsing_toolbar_base_layout.xml b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout-v31/collapsing_toolbar_base_layout.xml
new file mode 100644
index 0000000..24d53ab
--- /dev/null
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout-v31/collapsing_toolbar_base_layout.xml
@@ -0,0 +1,60 @@
+<?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.
+  -->
+<androidx.coordinatorlayout.widget.CoordinatorLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/content_parent"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:transitionGroup="true">
+
+    <com.google.android.material.appbar.AppBarLayout
+        android:id="@+id/app_bar"
+        android:layout_width="match_parent"
+        android:layout_height="180dp"
+        android:theme="@style/Theme.CollapsingToolbar.Settings">
+
+        <com.android.settingslib.collapsingtoolbar.AdjustableToolbarLayout
+            android:id="@+id/collapsing_toolbar"
+            android:background="?android:attr/colorPrimary"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            app:maxLines="3"
+            app:contentScrim="?android:attr/colorPrimary"
+            app:collapsedTitleTextAppearance="@style/CollapsingToolbarTitle.Collapsed"
+            app:statusBarScrim="?android:attr/colorPrimary"
+            app:layout_scrollFlags="scroll|exitUntilCollapsed"
+            app:expandedTitleMarginStart="18dp"
+            app:expandedTitleMarginEnd="18dp"
+            app:toolbarId="@id/action_bar">
+
+            <Toolbar
+                android:id="@+id/action_bar"
+                android:layout_width="match_parent"
+                android:layout_height="?attr/actionBarSize"
+                android:theme="?android:attr/actionBarTheme"
+                app:layout_collapseMode="pin"/>
+
+        </com.android.settingslib.collapsingtoolbar.AdjustableToolbarLayout>
+    </com.google.android.material.appbar.AppBarLayout>
+
+    <FrameLayout
+        android:id="@+id/content_frame"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
+</androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout/collapsing_toolbar_base_layout.xml b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout/collapsing_toolbar_base_layout.xml
index e376930..c799b99 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout/collapsing_toolbar_base_layout.xml
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout/collapsing_toolbar_base_layout.xml
@@ -14,47 +14,23 @@
   See the License for the specific language governing permissions and
   limitations under the License.
 -->
-<androidx.coordinatorlayout.widget.CoordinatorLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
+<!-- The main content view -->
+<LinearLayout
     android:id="@+id/content_parent"
+    xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:transitionGroup="true">
-
-    <com.google.android.material.appbar.AppBarLayout
-        android:id="@+id/app_bar"
+    android:fitsSystemWindows="true"
+    android:transitionGroup="true"
+    android:orientation="vertical">
+    <Toolbar
+        android:id="@+id/action_bar"
+        style="?android:attr/actionBarStyle"
         android:layout_width="match_parent"
-        android:layout_height="180dp"
-        android:theme="@style/Theme.CollapsingToolbar.Settings">
-
-        <com.android.settingslib.collapsingtoolbar.AdjustableToolbarLayout
-            android:id="@+id/collapsing_toolbar"
-            android:background="?android:attr/colorPrimary"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            app:maxLines="3"
-            app:contentScrim="?android:attr/colorPrimary"
-            app:collapsedTitleTextAppearance="@style/CollapsingToolbarTitle.Collapsed"
-            app:statusBarScrim="?android:attr/colorPrimary"
-            app:layout_scrollFlags="scroll|exitUntilCollapsed"
-            app:expandedTitleMarginStart="18dp"
-            app:expandedTitleMarginEnd="18dp"
-            app:toolbarId="@id/action_bar">
-
-            <Toolbar
-                android:id="@+id/action_bar"
-                android:layout_width="match_parent"
-                android:layout_height="?attr/actionBarSize"
-                android:theme="?android:attr/actionBarTheme"
-                app:layout_collapseMode="pin"/>
-
-        </com.android.settingslib.collapsingtoolbar.AdjustableToolbarLayout>
-    </com.google.android.material.appbar.AppBarLayout>
-
+        android:layout_height="wrap_content"
+        android:theme="?android:attr/actionBarTheme" />
     <FrameLayout
         android:id="@+id/content_frame"
         android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
-</androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file
+        android:layout_height="match_parent"/>
+</LinearLayout>
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout/toolbar_base_layout.xml b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout/toolbar_base_layout.xml
deleted file mode 100644
index c799b99..0000000
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout/toolbar_base_layout.xml
+++ /dev/null
@@ -1,36 +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.
--->
-<!-- The main content view -->
-<LinearLayout
-    android:id="@+id/content_parent"
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:fitsSystemWindows="true"
-    android:transitionGroup="true"
-    android:orientation="vertical">
-    <Toolbar
-        android:id="@+id/action_bar"
-        style="?android:attr/actionBarStyle"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:theme="?android:attr/actionBarTheme" />
-    <FrameLayout
-        android:id="@+id/content_frame"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"/>
-</LinearLayout>
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values/styles.xml b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values/styles.xml
index e1a64d4..1157a34 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values/styles.xml
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values/styles.xml
@@ -17,10 +17,10 @@
 <resources>
     <style name="CollapsingToolbarTitle.Collapsed"
            parent="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title">
+        <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
     </style>
 
-    <style name="CollapsingToolbarTitle"
-           parent="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title">
+    <style name="CollapsingToolbarTitle" parent="CollapsingToolbarTitle.Collapsed">
         <item name="android:textSize">36sp</item>
     </style>
 
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java
index ad94cd03..957bac7 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java
@@ -24,7 +24,6 @@
 import android.widget.Toolbar;
 
 import androidx.annotation.Nullable;
-import androidx.core.os.BuildCompat;
 import androidx.fragment.app.FragmentActivity;
 
 import com.google.android.material.appbar.CollapsingToolbarLayout;
@@ -41,15 +40,8 @@
     protected void onCreate(@Nullable Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
-        // TODO(b/181723278): Update the version check after SDK for S is finalized
-        // The collapsing toolbar is only supported if the android platform version is S or higher.
-        // Otherwise the regular action bar will be shown.
-        if (BuildCompat.isAtLeastS()) {
-            super.setContentView(R.layout.collapsing_toolbar_base_layout);
-            mCollapsingToolbarLayout = findViewById(R.id.collapsing_toolbar);
-        } else {
-            super.setContentView(R.layout.toolbar_base_layout);
-        }
+        super.setContentView(R.layout.collapsing_toolbar_base_layout);
+        mCollapsingToolbarLayout = findViewById(R.id.collapsing_toolbar);
 
         final Toolbar toolbar = findViewById(R.id.action_bar);
         setActionBar(toolbar);
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseFragment.java b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseFragment.java
new file mode 100644
index 0000000..c4c74ff
--- /dev/null
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseFragment.java
@@ -0,0 +1,78 @@
+/*
+ * 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.settingslib.collapsingtoolbar;
+
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+import android.widget.Toolbar;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+
+import com.google.android.material.appbar.CollapsingToolbarLayout;
+
+/**
+ * A base fragment that has a collapsing toolbar layout for enabling the collapsing toolbar design.
+ */
+public abstract class CollapsingToolbarBaseFragment extends Fragment {
+
+    @Nullable
+    private CollapsingToolbarLayout mCollapsingToolbarLayout;
+    @NonNull
+    private Toolbar mToolbar;
+    @NonNull
+    private FrameLayout mContentFrameLayout;
+
+    @Nullable
+    @Override
+    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
+            @Nullable Bundle savedInstanceState) {
+        final View view = inflater.inflate(R.layout.collapsing_toolbar_base_layout, container,
+                false);
+        mCollapsingToolbarLayout = view.findViewById(R.id.collapsing_toolbar);
+        mToolbar = view.findViewById(R.id.action_bar);
+        mContentFrameLayout = view.findViewById(R.id.content_frame);
+        return view;
+    }
+
+    @Override
+    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
+        super.onActivityCreated(savedInstanceState);
+
+        requireActivity().setActionBar(mToolbar);
+    }
+
+    /**
+     * Return the collapsing toolbar layout.
+     */
+    @Nullable
+    public CollapsingToolbarLayout getCollapsingToolbarLayout() {
+        return mCollapsingToolbarLayout;
+    }
+
+    /**
+     * Return the content frame layout.
+     */
+    @NonNull
+    public FrameLayout getContentFrameLayout() {
+        return mContentFrameLayout;
+    }
+}
diff --git a/packages/SettingsLib/FooterPreference/res/layout/preference_footer.xml b/packages/SettingsLib/FooterPreference/res/layout/preference_footer.xml
index 5496a01..7a550ae 100644
--- a/packages/SettingsLib/FooterPreference/res/layout/preference_footer.xml
+++ b/packages/SettingsLib/FooterPreference/res/layout/preference_footer.xml
@@ -23,6 +23,7 @@
     android:paddingStart="?android:attr/listPreferredItemPaddingStart"
     android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
     android:background="?android:attr/selectableItemBackground"
+    android:orientation="vertical"
     android:clipToPadding="false">
 
     <LinearLayout
diff --git a/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java
index 8d9a562..ae9261c 100644
--- a/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java
+++ b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java
@@ -63,7 +63,8 @@
             int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
 
-        LayoutInflater.from(context).inflate(R.layout.main_switch_bar, this);
+        LayoutInflater.from(context).inflate(resourceId(context, "layout", "main_switch_bar"),
+                this);
 
         setFocusable(true);
         setClickable(true);
@@ -255,4 +256,8 @@
 
         requestLayout();
     }
+
+    private int resourceId(Context context, String type, String name) {
+        return context.getResources().getIdentifier(name, type, context.getPackageName());
+    }
 }
diff --git a/packages/SettingsLib/SettingsTheme/res/layout/image_frame.xml b/packages/SettingsLib/SettingsTheme/res/layout/image_frame.xml
new file mode 100644
index 0000000..5567790
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/layout/image_frame.xml
@@ -0,0 +1,40 @@
+<?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.
+  -->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/icon_frame"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:minWidth="@dimen/icon_min_width"
+    android:gravity="start|center_vertical"
+    android:orientation="horizontal"
+    android:paddingLeft="0dp"
+    android:paddingStart="0dp"
+    android:paddingRight="8dp"
+    android:paddingEnd="8dp"
+    android:paddingTop="4dp"
+    android:paddingBottom="4dp">
+
+    <androidx.preference.internal.PreferenceImageView
+        android:id="@android:id/icon"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        app:maxWidth="48dp"
+        app:maxHeight="48dp"/>
+
+</LinearLayout>
diff --git a/packages/SettingsLib/SettingsTheme/res/layout/preference_category_settings.xml b/packages/SettingsLib/SettingsTheme/res/layout/preference_category_settings.xml
deleted file mode 100644
index 4a1b089..0000000
--- a/packages/SettingsLib/SettingsTheme/res/layout/preference_category_settings.xml
+++ /dev/null
@@ -1,60 +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.
-  -->
-
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:paddingRight="?android:attr/listPreferredItemPaddingRight"
-    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
-    android:background="?android:attr/selectableItemBackground"
-    android:baselineAligned="false"
-    android:layout_marginTop="16dp"
-    android:gravity="center_vertical"
-    style="@style/PreferenceCategoryStartMargin">
-
-    <RelativeLayout
-        android:layout_width="0dp"
-        android:layout_height="wrap_content"
-        android:layout_weight="1"
-        android:paddingTop="8dp"
-        android:paddingBottom="8dp">
-
-        <TextView
-            android:id="@android:id/title"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_gravity="start"
-            android:textAlignment="viewStart"
-            style="@style/PreferenceCategoryTitleTextStyle"/>
-
-        <TextView
-            android:id="@android:id/summary"
-            android:ellipsize="end"
-            android:singleLine="true"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_below="@android:id/title"
-            android:layout_alignLeft="@android:id/title"
-            android:layout_alignStart="@android:id/title"
-            android:layout_gravity="start"
-            android:textAlignment="viewStart"
-            android:textColor="?android:attr/textColorSecondary"
-            android:maxLines="10"
-            style="@style/PreferenceSummaryTextStyle"/>
-    </RelativeLayout>
-</LinearLayout>
\ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/layout/settings_dropdown_preference.xml b/packages/SettingsLib/SettingsTheme/res/layout/settings_dropdown_preference.xml
new file mode 100644
index 0000000..87977bd
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/layout/settings_dropdown_preference.xml
@@ -0,0 +1,35 @@
+<?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.
+  -->
+
+<!-- We use a FrameLayout as we want to place the invisible spinner on top of the other views -->
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content">
+    <!-- This spinner should be invisible in the layout and take up no space, when the Preference
+         is clicked the dropdown will appear from this location on screen. -->
+    <Spinner
+        android:id="@+id/spinner"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="@dimen/preference_dropdown_padding_start"
+        android:layout_marginLeft="@dimen/preference_dropdown_padding_start"
+        android:visibility="invisible" />
+
+    <include layout="@layout/settings_preference" />
+
+</FrameLayout>
\ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/layout/settings_preference.xml b/packages/SettingsLib/SettingsTheme/res/layout/settings_preference.xml
new file mode 100644
index 0000000..3a289a7
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/layout/settings_preference.xml
@@ -0,0 +1,76 @@
+<?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.
+  -->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:minHeight="?android:attr/listPreferredItemHeightSmall"
+    android:gravity="center_vertical"
+    android:paddingLeft="?android:attr/listPreferredItemPaddingLeft"
+    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+    android:paddingRight="?android:attr/listPreferredItemPaddingRight"
+    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+    android:background="?android:attr/selectableItemBackground"
+    android:clipToPadding="false"
+    android:baselineAligned="false">
+
+    <include layout="@layout/image_frame"/>
+
+    <RelativeLayout
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_weight="1"
+        android:paddingTop="16dp"
+        android:paddingBottom="16dp">
+
+        <TextView
+            android:id="@android:id/title"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:singleLine="true"
+            android:textAppearance="?android:attr/textAppearanceListItem"
+            android:ellipsize="marquee"/>
+
+        <TextView
+            android:id="@android:id/summary"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_below="@android:id/title"
+            android:layout_alignLeft="@android:id/title"
+            android:layout_alignStart="@android:id/title"
+            android:layout_gravity="start"
+            android:textAlignment="viewStart"
+            android:textColor="?android:attr/textColorSecondary"
+            android:maxLines="10"
+            style="@style/PreferenceSummaryTextStyle"/>
+
+    </RelativeLayout>
+
+    <!-- Preference should place its actual preference widget here. -->
+    <LinearLayout
+        android:id="@android:id/widget_frame"
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:gravity="end|center_vertical"
+        android:paddingLeft="16dp"
+        android:paddingStart="16dp"
+        android:paddingRight="0dp"
+        android:paddingEnd="0dp"
+        android:orientation="vertical"/>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/values-v31/config.xml b/packages/SettingsLib/SettingsTheme/res/values-v31/config.xml
new file mode 100644
index 0000000..acf06c4
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-v31/config.xml
@@ -0,0 +1,20 @@
+<?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.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <bool name="config_icon_space_reserved">false</bool>
+    <bool name="config_allow_divider">false</bool>
+</resources>
\ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/values-v31/dimens.xml b/packages/SettingsLib/SettingsTheme/res/values-v31/dimens.xml
new file mode 100644
index 0000000..17b6805
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-v31/dimens.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  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.
+  -->
+
+<resources>
+    <dimen name="preference_title_font_size">20sp</dimen>
+    <dimen name="icon_min_width">48dp</dimen>
+    <dimen name="preference_padding_start">24dp</dimen>
+    <dimen name="preference_padding_end">24dp</dimen>
+    <dimen name="app_preference_padding_start">20dp</dimen>
+    <dimen name="app_icon_min_width">52dp</dimen>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values/config.xml b/packages/SettingsLib/SettingsTheme/res/values/config.xml
new file mode 100644
index 0000000..a3bb1da
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values/config.xml
@@ -0,0 +1,20 @@
+<?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.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <bool name="config_icon_space_reserved">true</bool>
+    <bool name="config_allow_divider">true</bool>
+</resources>
\ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/values/dimens.xml b/packages/SettingsLib/SettingsTheme/res/values/dimens.xml
index 9485655..009ae6b 100644
--- a/packages/SettingsLib/SettingsTheme/res/values/dimens.xml
+++ b/packages/SettingsLib/SettingsTheme/res/values/dimens.xml
@@ -17,4 +17,10 @@
 
 <resources>
     <dimen name="secondary_app_icon_size">32dp</dimen>
+    <dimen name="preference_title_font_size">16sp</dimen>
+    <dimen name="icon_min_width">56dp</dimen>
+    <dimen name="preference_padding_start">?android:attr/dialogPreferredPadding</dimen>
+    <dimen name="preference_padding_end">?android:attr/dialogPreferredPadding</dimen>
+    <dimen name="app_preference_padding_start">?android:attr/listPreferredItemPaddingStart</dimen>
+    <dimen name="app_icon_min_width">56dp</dimen>
 </resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values/styles.xml b/packages/SettingsLib/SettingsTheme/res/values/styles.xml
index a6623b0..f24e008 100644
--- a/packages/SettingsLib/SettingsTheme/res/values/styles.xml
+++ b/packages/SettingsLib/SettingsTheme/res/values/styles.xml
@@ -15,16 +15,8 @@
   limitations under the License.
   -->
 <resources>
-    <style name="TextAppearance.CategoryTitle"
-           parent="@*android:style/TextAppearance.DeviceDefault.Body2">
-        <item name="android:textAllCaps">true</item>
-        <item name="android:textSize">11sp</item>
-        <!-- 0.8 Spacing, 0.8/11 = 0.072727273 -->
-        <item name="android:letterSpacing">0.072727273</item>
-    </style>
-
-    <style name="PreferenceCategoryStartMargin">
-        <item name="android:paddingLeft">?android:attr/listPreferredItemPaddingLeft</item>
-        <item name="android:paddingStart">?android:attr/listPreferredItemPaddingStart</item>
+    <style name="TextAppearance.PreferenceTitle"
+           parent="@*android:style/TextAppearance.DeviceDefault.ListItem">
+        <item name="android:textSize">@dimen/preference_title_font_size</item>
     </style>
 </resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values/styles_preference.xml b/packages/SettingsLib/SettingsTheme/res/values/styles_preference.xml
index 6ca8f577..17596ac2 100644
--- a/packages/SettingsLib/SettingsTheme/res/values/styles_preference.xml
+++ b/packages/SettingsLib/SettingsTheme/res/values/styles_preference.xml
@@ -16,17 +16,54 @@
   -->
 <resources>
     <style name="PreferenceTheme" parent="@style/PreferenceThemeOverlay">
-        <item name="footerPreferenceStyle">@style/Preference.Material</item>
         <item name="preferenceCategoryStyle">@style/SettingsCategoryPreference</item>
-        <!-- For preference category color -->
-        <item name="preferenceCategoryTitleTextAppearance">@style/TextAppearance.CategoryTitle
-        </item>
-        <item name="preferenceCategoryTitleTextColor">?android:attr/textColorSecondary</item>
+        <item name="preferenceStyle">@style/SettingsPreference</item>
+        <item name="checkBoxPreferenceStyle">@style/SettingsCheckBoxPreference</item>
+        <item name="dialogPreferenceStyle">@style/SettingsPreference</item>
+        <item name="editTextPreferenceStyle">@style/SettingsEditTextPreference</item>
+        <item name="dropdownPreferenceStyle">@style/SettingsDropdownPreference</item>
+        <item name="switchPreferenceStyle">@style/SettingsSwitchPreference</item>
+        <item name="seekBarPreferenceStyle">@style/SettingsSeekbarPreference</item>
+        <item name="footerPreferenceStyle">@style/Preference.Material</item>
     </style>
 
     <style name="SettingsCategoryPreference" parent="@style/Preference.Category.Material">
-        <item name="android:layout">@layout/preference_category_settings</item>
-        <item name="allowDividerAbove">false</item>
-        <item name="allowDividerBelow">false</item>
+        <item name="iconSpaceReserved">@bool/config_icon_space_reserved</item>
+        <item name="allowDividerAbove">@bool/config_allow_divider</item>
+        <item name="allowDividerBelow">@bool/config_allow_divider</item>
+    </style>
+
+    <style name="SettingsPreference" parent="@style/Preference.Material">
+        <item name="layout">@layout/settings_preference</item>
+        <item name="iconSpaceReserved">@bool/config_icon_space_reserved</item>
+    </style>
+
+    <style name="SettingsCheckBoxPreference" parent="@style/Preference.CheckBoxPreference.Material">
+        <item name="layout">@layout/settings_preference</item>
+        <item name="iconSpaceReserved">@bool/config_icon_space_reserved</item>
+    </style>
+
+    <style name="SettingsEditTextPreference"
+           parent="@style/Preference.DialogPreference.EditTextPreference.Material">
+        <item name="layout">@layout/settings_preference</item>
+        <item name="iconSpaceReserved">@bool/config_icon_space_reserved</item>
+    </style>
+
+    <style name="SettingsDropdownPreference" parent="@style/Preference.DropDown.Material">
+        <item name="layout">@layout/settings_dropdown_preference</item>
+        <item name="iconSpaceReserved">@bool/config_icon_space_reserved</item>
+    </style>
+
+    <style name="SettingsSwitchPreference" parent="@style/Preference.SwitchPreference.Material">
+        <item name="layout">@layout/settings_preference</item>
+        <item name="iconSpaceReserved">@bool/config_icon_space_reserved</item>
+    </style>
+
+    <style name="SettingsSeekbarPreference" parent="@style/Preference.SeekBarPreference.Material">
+        <item name="iconSpaceReserved">@bool/config_icon_space_reserved</item>
+    </style>
+
+    <style name="SettingFooterPreference" parent="@style/Preference.Material">
+        <item name="allowDividerAbove">@bool/config_allow_divider</item>
     </style>
 </resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values/themes.xml b/packages/SettingsLib/SettingsTheme/res/values/themes.xml
new file mode 100644
index 0000000..36ca684
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values/themes.xml
@@ -0,0 +1,32 @@
+<?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.
+  -->
+
+<resources>
+    <!-- Only using in Settings application -->
+    <style name="Theme.SettingsBase" parent="@android:style/Theme.DeviceDefault.Settings" >
+        <item name="android:textAppearanceListItem">@style/TextAppearance.PreferenceTitle</item>
+        <item name="android:listPreferredItemPaddingStart">@dimen/preference_padding_start</item>
+        <item name="android:listPreferredItemPaddingEnd">@dimen/preference_padding_end</item>
+        <item name="preferenceTheme">@style/PreferenceTheme</item>
+    </style>
+
+    <!-- Using in SubSettings page including injected settings page -->
+    <style name="Theme.SubSettingsBase" parent="Theme.SettingsBase">
+        <item name="android:windowActionBar">false</item>
+        <item name="android:windowNoTitle">true</item>
+    </style>
+</resources>
\ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTransition/Android.bp b/packages/SettingsLib/SettingsTransition/Android.bp
new file mode 100644
index 0000000..c12f6f7
--- /dev/null
+++ b/packages/SettingsLib/SettingsTransition/Android.bp
@@ -0,0 +1,22 @@
+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_library {
+    name: "SettingsLibSettingsTransition",
+
+    srcs: ["src/**/*.java"],
+    resource_dirs: ["res"],
+
+    static_libs: [
+        "com.google.android.material_material",
+    ],
+
+    sdk_version: "system_current",
+    min_sdk_version: "21",
+}
diff --git a/packages/SettingsLib/SettingsTransition/AndroidManifest.xml b/packages/SettingsLib/SettingsTransition/AndroidManifest.xml
new file mode 100644
index 0000000..11660a5f
--- /dev/null
+++ b/packages/SettingsLib/SettingsTransition/AndroidManifest.xml
@@ -0,0 +1,23 @@
+<?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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="com.android.settingslib.transition">
+
+    <uses-sdk android:minSdkVersion="21" />
+
+</manifest>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-sw360dp/styles.xml b/packages/SettingsLib/SettingsTransition/res/values/dimens.xml
similarity index 79%
rename from packages/SettingsLib/SettingsTheme/res/values-sw360dp/styles.xml
rename to packages/SettingsLib/SettingsTransition/res/values/dimens.xml
index 4f40256..0630ca8 100644
--- a/packages/SettingsLib/SettingsTheme/res/values-sw360dp/styles.xml
+++ b/packages/SettingsLib/SettingsTransition/res/values/dimens.xml
@@ -15,8 +15,5 @@
 -->
 
 <resources>
-    <style name="PreferenceCategoryStartMargin">
-        <item name="android:paddingLeft">24dp</item>
-        <item name="android:paddingStart">24dp</item>
-    </style>
-</resources>
+    <dimen name="settings_shared_axis_x_slide_distance">96dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTransition/src/com/android/settingslib/transition/SettingsTransitionHelper.java b/packages/SettingsLib/SettingsTransition/src/com/android/settingslib/transition/SettingsTransitionHelper.java
new file mode 100644
index 0000000..f99fda0
--- /dev/null
+++ b/packages/SettingsLib/SettingsTransition/src/com/android/settingslib/transition/SettingsTransitionHelper.java
@@ -0,0 +1,103 @@
+/*
+ * 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.settingslib.transition;
+
+import android.app.Activity;
+import android.content.Context;
+import android.util.Log;
+import android.view.Window;
+import android.view.animation.AnimationUtils;
+import android.view.animation.Interpolator;
+
+import com.google.android.material.transition.platform.MaterialSharedAxis;
+import com.google.android.material.transition.platform.SlideDistanceProvider;
+
+/**
+ * A helper class to apply Settings Transition
+ */
+public class SettingsTransitionHelper {
+
+    private static final String TAG = "SettingsTransitionHelper";
+    private static final long DURATION = 450L;
+
+    private static MaterialSharedAxis createSettingsSharedAxis(Context context, boolean forward) {
+        final MaterialSharedAxis transition = new MaterialSharedAxis(MaterialSharedAxis.X, forward);
+        transition.excludeTarget(android.R.id.statusBarBackground, true);
+        transition.excludeTarget(android.R.id.navigationBarBackground, true);
+
+        final SlideDistanceProvider forwardDistanceProvider =
+                (SlideDistanceProvider) transition.getPrimaryAnimatorProvider();
+        final int distance = context.getResources().getDimensionPixelSize(
+                R.dimen.settings_shared_axis_x_slide_distance);
+        forwardDistanceProvider.setSlideDistance(distance);
+        transition.setDuration(DURATION);
+
+        final Interpolator interpolator =
+                AnimationUtils.loadInterpolator(context,
+                        android.R.interpolator.fast_out_extra_slow_in);
+        transition.setInterpolator(interpolator);
+
+        // TODO(b/177480673): Update fade through threshold once (cl/362065364) is released
+
+        return transition;
+    }
+
+    /**
+     * Apply the forward transition to the {@link Activity}, including Exit Transition and Enter
+     * Transition.
+     *
+     * The Exit Transition takes effect when leaving the page, while the Enter Transition is
+     * triggered when the page is launched/entering.
+     */
+    public static void applyForwardTransition(Activity activity) {
+        if (activity == null) {
+            Log.w(TAG, "applyForwardTransition: Invalid activity!");
+            return;
+        }
+        final Window window = activity.getWindow();
+        if (window == null) {
+            Log.w(TAG, "applyForwardTransition: Invalid window!");
+            return;
+        }
+        final MaterialSharedAxis forward = createSettingsSharedAxis(activity, true);
+        window.setExitTransition(forward);
+        window.setEnterTransition(forward);
+    }
+
+    /**
+     * Apply the backward transition to the {@link Activity}, including Return Transition and
+     * Reenter Transition.
+     *
+     * Return Transition will be used to move Views out of the scene when the Window is preparing
+     * to close. Reenter Transition will be used to move Views in to the scene when returning from a
+     * previously-started Activity.
+     */
+    public static void applyBackwardTransition(Activity activity) {
+        if (activity == null) {
+            Log.w(TAG, "applyBackwardTransition: Invalid activity!");
+            return;
+        }
+        final Window window = activity.getWindow();
+        if (window == null) {
+            Log.w(TAG, "applyBackwardTransition: Invalid window!");
+            return;
+        }
+        final MaterialSharedAxis backward = createSettingsSharedAxis(activity, false);
+        window.setReturnTransition(backward);
+        window.setReenterTransition(backward);
+    }
+}
diff --git a/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java
index 49f6bd8..a2bec33 100644
--- a/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java
+++ b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java
@@ -555,7 +555,7 @@
             bundle.putString(META_DATA_PREFERENCE_KEYHINT, key);
         }
         try {
-            return provider.call(context.getPackageName(), context.getAttributionTag(),
+            return provider.call(context.getAttributionSource(),
                     uri.getAuthority(), method, uri.toString(), bundle);
         } catch (RemoteException e) {
             return null;
diff --git a/packages/SettingsLib/TwoTargetPreference/src/com/android/settingslib/widget/TwoTargetPreference.java b/packages/SettingsLib/TwoTargetPreference/src/com/android/settingslib/widget/TwoTargetPreference.java
index 9130662..17f257d 100644
--- a/packages/SettingsLib/TwoTargetPreference/src/com/android/settingslib/widget/TwoTargetPreference.java
+++ b/packages/SettingsLib/TwoTargetPreference/src/com/android/settingslib/widget/TwoTargetPreference.java
@@ -72,9 +72,9 @@
     private void init(Context context) {
         setLayoutResource(R.layout.preference_two_target);
         mSmallIconSize = context.getResources().getDimensionPixelSize(
-                R.dimen.two_target_pref_small_icon_size);
+                resourceId(context, "dimen", "two_target_pref_small_icon_size"));
         mMediumIconSize = context.getResources().getDimensionPixelSize(
-                R.dimen.two_target_pref_medium_icon_size);
+                resourceId(context, "dimen", "two_target_pref_medium_icon_size"));
         final int secondTargetResId = getSecondTargetResId();
         if (secondTargetResId != 0) {
             setWidgetLayoutResource(secondTargetResId);
@@ -116,4 +116,8 @@
     protected int getSecondTargetResId() {
         return 0;
     }
+
+    private int resourceId(Context context, String type, String name) {
+        return context.getResources().getIdentifier(name, type, context.getPackageName());
+    }
 }
diff --git a/packages/SettingsLib/UsageProgressBarPreference/res/layout/preference_usage_progress_bar.xml b/packages/SettingsLib/UsageProgressBarPreference/res/layout/preference_usage_progress_bar.xml
index f45105d..31b3fe5 100644
--- a/packages/SettingsLib/UsageProgressBarPreference/res/layout/preference_usage_progress_bar.xml
+++ b/packages/SettingsLib/UsageProgressBarPreference/res/layout/preference_usage_progress_bar.xml
@@ -70,4 +70,13 @@
         android:scaleY="2"
         android:layout_marginTop="4dp"
         android:max="100"/>
+
+    <TextView
+        android:id="@+id/bottom_summary"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:visibility="gone"
+        android:ellipsize="marquee"
+        android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1"
+        android:textSize="14sp"/>
 </LinearLayout>
diff --git a/packages/SettingsLib/UsageProgressBarPreference/src/com/android/settingslib/widget/UsageProgressBarPreference.java b/packages/SettingsLib/UsageProgressBarPreference/src/com/android/settingslib/widget/UsageProgressBarPreference.java
index 2185950..a2b1de2 100644
--- a/packages/SettingsLib/UsageProgressBarPreference/src/com/android/settingslib/widget/UsageProgressBarPreference.java
+++ b/packages/SettingsLib/UsageProgressBarPreference/src/com/android/settingslib/widget/UsageProgressBarPreference.java
@@ -44,6 +44,7 @@
 
     private CharSequence mUsageSummary;
     private CharSequence mTotalSummary;
+    private CharSequence mBottomSummary;
     private ImageView mCustomImageView;
     private int mPercent = -1;
 
@@ -101,6 +102,15 @@
         notifyChanged();
     }
 
+    /** Set bottom summary. */
+    public void setBottomSummary(CharSequence bottomSummary) {
+        if (TextUtils.equals(mBottomSummary, bottomSummary)) {
+            return;
+        }
+        mBottomSummary = bottomSummary;
+        notifyChanged();
+    }
+
     /** Set percentage of the progress bar. */
     public void setPercent(long usage, long total) {
         if (total == 0L || usage >  total) {
@@ -147,6 +157,14 @@
             totalSummary.setText(mTotalSummary);
         }
 
+        final TextView bottomSummary = (TextView) holder.findViewById(R.id.bottom_summary);
+        if (TextUtils.isEmpty(mBottomSummary)) {
+            bottomSummary.setVisibility(View.GONE);
+        } else {
+            bottomSummary.setVisibility(View.VISIBLE);
+            bottomSummary.setText(mBottomSummary);
+        }
+
         final ProgressBar progressBar = (ProgressBar) holder.findViewById(android.R.id.progress);
         if (mPercent < 0) {
             progressBar.setIndeterminate(true);
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index d3e4d1c..1c112c6 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -211,7 +211,7 @@
     <string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Wi-Fi ሲገናኝ የማረም ሁነታ"</string>
     <string name="adb_wireless_error" msgid="721958772149779856">"ስህተት"</string>
     <string name="adb_wireless_settings" msgid="2295017847215680229">"ገመድ-አልባ debugging"</string>
-    <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"የሚገኙ መሣሪያዎችን ለመመልከትና ለመጠቀም ገመድ-አልባ debuggingን ያብሩ"</string>
+    <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"የሚገኙ መሣሪያዎችን ለመመልከትና ለመጠቀም ገመድ-አልባ ማረምን ያብሩ"</string>
     <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"የQR ኮድን በመጠቀም መሣሪያን ያጣምሩ"</string>
     <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"የQR ኮድ መቃኛን በመጠቀም አዲስ መሣሪያዎችን ያጣምሩ"</string>
     <string name="adb_pair_method_code_title" msgid="1122590300445142904">"የማጣመሪያ ኮድን በመጠቀም መሣሪያን ያጣምሩ"</string>
@@ -303,7 +303,7 @@
     <string name="adb_warning_title" msgid="7708653449506485728">"የUSB ማረሚያ ይፈቀድ?"</string>
     <string name="adb_warning_message" msgid="8145270656419669221">"የUSB አድስ ለግንባታ አላማ ብቻ የታሰበ ነው። ከኮምፒዩተርህ ወደ መሳሪያህ ውሂብ ለመገልበጥ፣ መሣሪያህ ላይ ያለ ማሳወቂያ መተግበሪያዎችን መጫን፣ እና ማስታወሻ ውሂብ ማንበብ ለመጠቀም ይቻላል።"</string>
     <string name="adbwifi_warning_title" msgid="727104571653031865">"ገመድ-አልባ debugging ይፈቀድ?"</string>
-    <string name="adbwifi_warning_message" msgid="8005936574322702388">"ገመድ-አልባ debugging ለግንባታ አላማዎች ብቻ የታሰበ ነው። ውሂብን ከኮምፒዩተርዎ ወደ መሳሪያዎ ለመቅዳት፣ መሣሪያዎ ላይ ያለማሳወቂያ መተግበሪያዎችን ለመጫን እና የምዝግብ ማስታወሻ ውሂብን ለማንበብ ይጠቀሙበት።"</string>
+    <string name="adbwifi_warning_message" msgid="8005936574322702388">"ገመድ-አልባ ማረም ለግንባታ አላማዎች ብቻ የታሰበ ነው። ውሂብን ከኮምፒዩተርዎ ወደ መሳሪያዎ ለመቅዳት፣ መሣሪያዎ ላይ ያለማሳወቂያ መተግበሪያዎችን ለመጫን እና የምዝግብ ማስታወሻ ውሂብን ለማንበብ ይጠቀሙበት።"</string>
     <string name="adb_keys_warning_message" msgid="2968555274488101220">"የዩ ኤስ ቢ ማረም መዳረሻ ከዚህ ቀደም ፍቃድ ከሰጧቸው ኮምፒውተሮች ላይ ይሻሩ?"</string>
     <string name="dev_settings_warning_title" msgid="8251234890169074553">"የግንባታ ቅንብሮችን ፍቀድ?"</string>
     <string name="dev_settings_warning_message" msgid="37741686486073668">"እነዚህ ቅንብሮች  የታሰቡት ለግንባታ አጠቃቀም ብቻ ናቸው። መሳሪያህን እና በሱ ላይ ያሉትን መተግበሪያዎች እንዲበለሹ ወይም በትክክል እንዳይሰሩ ሊያደርጉ ይችላሉ።"</string>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index a0bf4b1..765f31c 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -424,8 +424,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>
-    <!-- no translation found for accessibility_display_daltonizer_preference_subtitle (2333641630205214702) -->
-    <skip />
+    <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 Farben genauer dargestellt werden sollen&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="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>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index a18c0f1..b5da6be 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -424,8 +424,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>
-    <!-- no translation found for accessibility_display_daltonizer_preference_subtitle (2333641630205214702) -->
-    <skip />
+    <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="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>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index fc788b6..a351ca0 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -424,8 +424,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>
-    <!-- no translation found for accessibility_display_daltonizer_preference_subtitle (2333641630205214702) -->
-    <skip />
+    <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="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>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 90df3b1..23baeb9 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -131,7 +131,7 @@
     <string name="bluetooth_hearingaid_left_pairing_message" msgid="8561855779703533591">"מתבצעת התאמה של מכשיר שמיעה שמאלי…"</string>
     <string name="bluetooth_hearingaid_right_pairing_message" msgid="2655347721696331048">"מתבצעת התאמה של מכשיר שמיעה ימני…"</string>
     <string name="bluetooth_hearingaid_left_battery_level" msgid="7375621694748104876">"שמאלי - טעינת הסוללה: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_hearingaid_right_battery_level" msgid="1850094448499089312">"ימני - טעינת הסוללה: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_hearingaid_right_battery_level" msgid="1850094448499089312">"ימני – טעינת הסוללה: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="accessibility_wifi_off" msgid="1195445715254137155">"‏Wi-Fi כבוי."</string>
     <string name="accessibility_no_wifi" msgid="5297119459491085771">"‏Wi-Fi מנותק."</string>
     <string name="accessibility_wifi_one_bar" msgid="6025652717281815212">"‏פס אחד של Wi-Fi."</string>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index e2b62a4..6c6a5d9 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -424,8 +424,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>
-    <!-- no translation found for accessibility_display_daltonizer_preference_subtitle (2333641630205214702) -->
-    <skip />
+    <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="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>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index 2b351bc..7ec137a 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -424,8 +424,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>
-    <!-- no translation found for accessibility_display_daltonizer_preference_subtitle (2333641630205214702) -->
-    <skip />
+    <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="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>
diff --git a/packages/SettingsLib/res/values-nl/arrays.xml b/packages/SettingsLib/res/values-nl/arrays.xml
index b5d064e..86b34f54 100644
--- a/packages/SettingsLib/res/values-nl/arrays.xml
+++ b/packages/SettingsLib/res/values-nl/arrays.xml
@@ -248,8 +248,8 @@
   </string-array>
   <string-array name="debug_hw_overdraw_entries">
     <item msgid="1968128556747588800">"Uit"</item>
-    <item msgid="3033215374382962216">"Gedeeltes met overbelasting weergeven"</item>
-    <item msgid="3474333938380896988">"Gebieden voor deuteranomalie weergeven"</item>
+    <item msgid="3033215374382962216">"Gedeelten met overbelasting tonen"</item>
+    <item msgid="3474333938380896988">"Gebieden voor deuteranomalie tonen"</item>
   </string-array>
   <string-array name="app_process_limit_entries">
     <item msgid="794656271086646068">"Standaardlimiet"</item>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index a3a490d..e5e03e1 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -309,7 +309,7 @@
     <string name="dev_settings_warning_message" msgid="37741686486073668">"Deze instellingen zijn uitsluitend bedoeld voor ontwikkelingsgebruik. Je apparaat en apps kunnen hierdoor vastlopen of anders reageren."</string>
     <string name="verify_apps_over_usb_title" msgid="6031809675604442636">"Apps verifiëren via USB"</string>
     <string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Apps die zijn geïnstalleerd via ADB/ADT, controleren op schadelijk gedrag"</string>
-    <string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Bluetooth-apparaten zonder namen (alleen MAC-adressen) worden weergegeven"</string>
+    <string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Bluetooth-apparaten zonder naam (alleen MAC-adressen) worden weergegeven"</string>
     <string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Hiermee wordt de functie voor absoluut volume van Bluetooth uitgeschakeld in geval van volumeproblemen met externe apparaten, zoals een onacceptabel hoog volume of geen volumeregeling."</string>
     <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Hierdoor wordt de Gabeldorsche-functiestack voor bluetooth ingeschakeld."</string>
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Hiermee wordt de functie voor verbeterde connectiviteit ingeschakeld."</string>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index f1d4a8a..9ccfb80 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -424,8 +424,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>
-    <!-- no translation found for accessibility_display_daltonizer_preference_subtitle (2333641630205214702) -->
-    <skip />
+    <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="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>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index 95ba023..f667c6a 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -424,8 +424,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>
-    <!-- no translation found for accessibility_display_daltonizer_preference_subtitle (2333641630205214702) -->
-    <skip />
+    <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="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>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index 0b03d99..4c35d2f 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -424,7 +424,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;&amp;ltlt;br/&gt; ‎&lt;ol&gt;‎&lt;li&gt;‎جب آپ رنگوں کو مزید درست طریقے سے دیکھنا چاہیں ‎&lt;/li&gt; &lt;li&gt;&amp;nbsp;‎فوکس کرنے میں مدد کرنے کے لئے رنگوں کو ہٹائیں ‎&lt;/li&gt; &lt;/ol&gt;‎"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"‏آپ کے آلے پر رنگوں کے ڈسپلے ہونے کے طریقے کو ایڈجسٹ کریں۔ یہ درج ذیل کے لیے مددگار ثابت ہوسکتا ہے ‎:&lt;br/&gt;&amp;ltlt;br/&gt; ‎&lt;ol&gt;‎&lt;li&gt;‎جب آپ رنگوں کو مزید درست طریقے سے دیکھنا چاہیں ‎&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>
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index d801f1b..927e9db 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -1272,6 +1272,22 @@
     <!-- Button label for generic OK action [CHAR LIMIT=20] -->
     <string name="okay">OK</string>
 
+    <!-- Label for the settings activity for controlling apps that can schedule alarms [CHAR LIMIT=30] -->
+    <string name="alarms_and_reminders_label">Alarms and reminders</string>
+    <!-- Label for the switch to toggler the permission for scheduling alarms [CHAR LIMIT=50] -->
+    <string name="alarms_and_reminders_switch_title">Allow to set alarms or reminders</string>
+    <!-- Title for the setting screen for controlling apps that can schedule alarms [CHAR LIMIT=30] -->
+    <string name="alarms_and_reminders_title">Alarms and reminders</string>
+    <!-- Description that appears below the alarms_and_reminders switch [CHAR LIMIT=NONE] -->
+    <string name="alarms_and_reminders_footer_title">
+        Allow this app to schedule alarms or other timing based events.
+        This will allow the app to wake up and run even when you are not using the device.
+        Note that revoking this permission may cause the app to malfunction, specifically any alarms
+        that the app has scheduled will no longer work.
+    </string>
+    <!-- Keywords for setting screen for controlling apps that can schedule alarms [CHAR LIMIT=100] -->
+    <string name="keywords_alarms_and_reminders">schedule, alarm, reminder, event</string>
+
     <!--  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>
     <!-- Do not disturb: Title for the Do not Disturb dialog to turn on Do not disturb. [CHAR LIMIT=50]-->
@@ -1467,7 +1483,7 @@
     <string name="data_connection_5g_plus" translatable="false">5G+</string>
 
     <!-- Content description of the data connection type Carrier WiFi. [CHAR LIMIT=NONE] -->
-    <string name="data_connection_carrier_wifi">CWF</string>
+    <string name="data_connection_carrier_wifi">W+</string>
 
     <!-- Content description of the cell data being disabled. [CHAR LIMIT=NONE] -->
     <string name="cell_data_off_content_description">Mobile data off</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/AppUtils.java b/packages/SettingsLib/src/com/android/settingslib/applications/AppUtils.java
index 8987968..a5da8b6 100644
--- a/packages/SettingsLib/src/com/android/settingslib/applications/AppUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/AppUtils.java
@@ -31,6 +31,7 @@
 import android.os.RemoteException;
 import android.os.SystemProperties;
 import android.os.UserHandle;
+import android.text.TextUtils;
 import android.util.Log;
 
 import com.android.settingslib.R;
@@ -198,4 +199,17 @@
         }
         return false;
     }
+
+    /**
+     * Returns a boolean indicating whether a given package is a default browser.
+     *
+     * @param packageName a given package.
+     * @return true if the given package is default browser.
+     */
+    public static boolean isDefaultBrowser(Context context, String packageName) {
+        final String defaultBrowserPackage =
+                context.getPackageManager().getDefaultBrowserPackageNameAsUser(
+                        UserHandle.myUserId());
+        return TextUtils.equals(packageName, defaultBrowserPackage);
+    }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java
index 8f8f859..253629c 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java
@@ -13,11 +13,14 @@
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
+import android.provider.DeviceConfig;
 import android.provider.MediaStore;
+import android.text.TextUtils;
 import android.util.Log;
 import android.util.Pair;
 
 import androidx.annotation.DrawableRes;
+import androidx.annotation.NonNull;
 import androidx.core.graphics.drawable.IconCompat;
 
 import com.android.settingslib.R;
@@ -34,6 +37,7 @@
     public static final boolean D = true;  // regular logging
 
     public static final int META_INT_ERROR = -1;
+    public static final String BT_ADVANCED_HEADER_ENABLED = "bt_advanced_header_enabled";
 
     private static ErrorListener sErrorListener;
 
@@ -178,14 +182,12 @@
         final Pair<Drawable, String> pair = BluetoothUtils.getBtClassDrawableWithDescription(
                 context, cachedDevice);
         final BluetoothDevice bluetoothDevice = cachedDevice.getDevice();
-        final boolean untetheredHeadset = getBooleanMetaData(
-                bluetoothDevice, BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET);
         final int iconSize = context.getResources().getDimensionPixelSize(
                 R.dimen.bt_nearby_icon_size);
         final Resources resources = context.getResources();
 
-        // Deal with untethered headset
-        if (untetheredHeadset) {
+        // Deal with advanced device icon
+        if (isAdvancedDetailsHeader(bluetoothDevice)) {
             final Uri iconUri = getUriMetaData(bluetoothDevice,
                     BluetoothDevice.METADATA_MAIN_ICON);
             if (iconUri != null) {
@@ -217,6 +219,35 @@
     }
 
     /**
+     * Check if the Bluetooth device supports advanced metadata
+     *
+     * @param bluetoothDevice the BluetoothDevice to get metadata
+     * @return true if it supports advanced metadata, false otherwise.
+     */
+    public static boolean isAdvancedDetailsHeader(@NonNull BluetoothDevice bluetoothDevice) {
+        if (!DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SETTINGS_UI, BT_ADVANCED_HEADER_ENABLED,
+                true)) {
+            Log.d(TAG, "isAdvancedDetailsHeader: advancedEnabled is false");
+            return false;
+        }
+        // The metadata is for Android R
+        if (getBooleanMetaData(bluetoothDevice, BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET)) {
+            Log.d(TAG, "isAdvancedDetailsHeader: untetheredHeadset is true");
+            return true;
+        }
+        // The metadata is for Android S
+        String deviceType = getStringMetaData(bluetoothDevice,
+                BluetoothDevice.METADATA_DEVICE_TYPE);
+        if (TextUtils.equals(deviceType, BluetoothDevice.DEVICE_TYPE_UNTETHERED_HEADSET)
+                || TextUtils.equals(deviceType, BluetoothDevice.DEVICE_TYPE_WATCH)
+                || TextUtils.equals(deviceType, BluetoothDevice.DEVICE_TYPE_DEFAULT)) {
+            Log.d(TAG, "isAdvancedDetailsHeader: deviceType is " + deviceType);
+            return true;
+        }
+        return false;
+    }
+
+    /**
      * Create an Icon pointing to a drawable.
      */
     public static IconCompat createIconWithDrawable(Drawable drawable) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/connectivity/ConnectivitySubsystemsRecoveryManager.java b/packages/SettingsLib/src/com/android/settingslib/connectivity/ConnectivitySubsystemsRecoveryManager.java
index dfde3c7..c61f8a9 100644
--- a/packages/SettingsLib/src/com/android/settingslib/connectivity/ConnectivitySubsystemsRecoveryManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/connectivity/ConnectivitySubsystemsRecoveryManager.java
@@ -250,6 +250,7 @@
      * @param callback Callbacks triggered when recovery status changes.
      */
     public void triggerSubsystemRestart(String reason, @NonNull RecoveryStatusCallback callback) {
+        // TODO: b/183530649 : clean-up or make use of the `reason` argument
         mHandler.post(() -> {
             boolean someSubsystemRestarted = false;
 
@@ -264,7 +265,7 @@
             }
 
             if (isWifiEnabled()) {
-                mWifiManager.restartWifiSubsystem(reason);
+                mWifiManager.restartWifiSubsystem();
                 mWifiRestartInProgress = true;
                 someSubsystemRestarted = true;
                 startTrackingWifiRestart();
diff --git a/packages/SettingsLib/src/com/android/settingslib/development/AbstractEnableAdbPreferenceController.java b/packages/SettingsLib/src/com/android/settingslib/development/AbstractEnableAdbPreferenceController.java
index 1474f18..f62ca32 100644
--- a/packages/SettingsLib/src/com/android/settingslib/development/AbstractEnableAdbPreferenceController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/development/AbstractEnableAdbPreferenceController.java
@@ -86,6 +86,15 @@
         }
     }
 
+    @Override
+    protected void onDeveloperOptionsSwitchEnabled() {
+        super.onDeveloperOptionsSwitchEnabled();
+        if (isAvailable()) {
+            mPreference.setDisabledByAdmin(
+                    checkIfUsbDataSignalingIsDisabled(mContext, UserHandle.myUserId()));
+        }
+    }
+
     public void enablePreference(boolean enabled) {
         if (isAvailable()) {
             mPreference.setEnabled(enabled);
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java
index cbfd4d8..41ccb16 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java
@@ -19,7 +19,6 @@
 import android.content.Intent;
 import android.net.ConnectivityManager;
 import android.net.ConnectivityManager.NetworkCallback;
-import android.net.LinkProperties;
 import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.net.NetworkInfo;
@@ -77,25 +76,23 @@
             .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR).build();
     private final NetworkCallback mNetworkCallback =
             new NetworkCallback(NetworkCallback.FLAG_INCLUDE_LOCATION_INFO) {
-        @Override
-        public void onAvailable(
-                Network network, NetworkCapabilities networkCapabilities,
-                LinkProperties linkProperties, boolean blocked) {
-            boolean isVcnOverWifi =
-                    networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
-                            && (Utils.tryGetWifiInfoForVcn(networkCapabilities) != null);
-            boolean isWifi =
-                    networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI);
-            if (isVcnOverWifi || isWifi) {
-                mNetworks.add(network.getNetId());
-            }
-        }
-
         // Note: onCapabilitiesChanged is guaranteed to be called "immediately" after onAvailable
         // and onLinkPropertiesChanged.
         @Override
         public void onCapabilitiesChanged(
                 Network network, NetworkCapabilities networkCapabilities) {
+            if (!mNetworks.contains(network.getNetId())) {
+                // New network
+                boolean isVcnOverWifi =
+                        networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
+                                && (Utils.tryGetWifiInfoForVcn(networkCapabilities) != null);
+                boolean isWifi =
+                        networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI);
+                if (isVcnOverWifi || isWifi) {
+                    mNetworks.add(network.getNetId());
+                }
+            }
+
             WifiInfo wifiInfo = null;
             if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
                 wifiInfo = Utils.tryGetWifiInfoForVcn(networkCapabilities);
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/widget/UsageProgressBarPreferenceTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/widget/UsageProgressBarPreferenceTest.java
index fe76b06..cd78add 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/widget/UsageProgressBarPreferenceTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/widget/UsageProgressBarPreferenceTest.java
@@ -92,6 +92,28 @@
     }
 
     @Test
+    public void setBottomSummary_getCorrectSummary() {
+        final String expectedText = "Should last until about 7:45 PM";
+        mUsageProgressBarPreference.setBottomSummary(expectedText);
+
+        mUsageProgressBarPreference.onBindViewHolder(mViewHolder);
+
+        final TextView bottomSummary = (TextView) mViewHolder.findViewById(R.id.bottom_summary);
+        assertThat(bottomSummary.getText()).isEqualTo(expectedText);
+        assertThat(bottomSummary.getVisibility()).isEqualTo(View.VISIBLE);
+    }
+
+    @Test
+    public void setBottomSummary_emptyText_isGone() {
+        mUsageProgressBarPreference.setBottomSummary(null);
+
+        mUsageProgressBarPreference.onBindViewHolder(mViewHolder);
+
+        final TextView bottomSummary = (TextView) mViewHolder.findViewById(R.id.bottom_summary);
+        assertThat(bottomSummary.getVisibility()).isEqualTo(View.GONE);
+    }
+
+    @Test
     public void setPercent_getCorrectProgress() {
         mUsageProgressBarPreference.setPercent(31, 80);
 
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothUtilsTest.java
index 3a95852c..2e85514 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothUtilsTest.java
@@ -150,4 +150,45 @@
         assertThat(BluetoothUtils.getUriMetaData(mBluetoothDevice,
                 BluetoothDevice.METADATA_MAIN_ICON)).isNull();
     }
+
+    @Test
+    public void isAdvancedDetailsHeader_untetheredHeadset_returnTrue() {
+        when(mBluetoothDevice.getMetadata(
+                BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET)).thenReturn(
+                BOOL_METADATA.getBytes());
+
+        assertThat(BluetoothUtils.isAdvancedDetailsHeader(mBluetoothDevice)).isEqualTo(true);
+    }
+
+    @Test
+    public void isAdvancedDetailsHeader_deviceTypeUntetheredHeadset_returnTrue() {
+        when(mBluetoothDevice.getMetadata(
+                BluetoothDevice.METADATA_DEVICE_TYPE)).thenReturn(
+                BluetoothDevice.DEVICE_TYPE_UNTETHERED_HEADSET.getBytes());
+
+        assertThat(BluetoothUtils.isAdvancedDetailsHeader(mBluetoothDevice)).isEqualTo(true);
+    }
+
+    @Test
+    public void isAdvancedDetailsHeader_deviceTypeWatch_returnTrue() {
+        when(mBluetoothDevice.getMetadata(
+                BluetoothDevice.METADATA_DEVICE_TYPE)).thenReturn(
+                BluetoothDevice.DEVICE_TYPE_WATCH.getBytes());
+
+        assertThat(BluetoothUtils.isAdvancedDetailsHeader(mBluetoothDevice)).isEqualTo(true);
+    }
+
+    @Test
+    public void isAdvancedDetailsHeader_deviceTypeDefault_returnTrue() {
+        when(mBluetoothDevice.getMetadata(
+                BluetoothDevice.METADATA_DEVICE_TYPE)).thenReturn(
+                BluetoothDevice.DEVICE_TYPE_DEFAULT.getBytes());
+
+        assertThat(BluetoothUtils.isAdvancedDetailsHeader(mBluetoothDevice)).isEqualTo(true);
+    }
+
+    @Test
+    public void isAdvancedDetailsHeader_noMetadata_returnFalse() {
+        assertThat(BluetoothUtils.isAdvancedDetailsHeader(mBluetoothDevice)).isEqualTo(false);
+    }
 }
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index 5d4078d..fbb84fd 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -242,7 +242,7 @@
     <bool name="def_hdmiControlAutoDeviceOff">true</bool>
 
     <!-- Default for Settings.Secure.SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED -->
-    <bool name="def_swipe_bottom_to_notification_enabled">true</bool>
+    <bool name="def_swipe_bottom_to_notification_enabled">false</bool>
 
     <!-- Default for Settings.Secure.ONE_HANDED_MODE_ENABLED -->
     <bool name="def_one_handed_mode_enabled">false</bool>
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java
index 987e82e..77032ba 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java
@@ -72,6 +72,8 @@
         Settings.Global.NOTIFICATION_BUBBLES,
         Settings.Global.CUSTOM_BUGREPORT_HANDLER_APP,
         Settings.Global.CUSTOM_BUGREPORT_HANDLER_USER,
-        Settings.Global.DEVELOPMENT_SETTINGS_ENABLED
+        Settings.Global.DEVELOPMENT_SETTINGS_ENABLED,
+        Settings.Global.USER_DISABLED_HDR_FORMATS,
+        Settings.Global.ARE_USER_DISABLED_HDR_FORMATS_ALLOWED
     };
 }
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/DiscreteValueIntegerListValidator.java b/packages/SettingsProvider/src/android/provider/settings/validators/DiscreteValueIntegerListValidator.java
new file mode 100644
index 0000000..eb38ac5
--- /dev/null
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/DiscreteValueIntegerListValidator.java
@@ -0,0 +1,50 @@
+/*
+ * 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 android.provider.settings.validators;
+
+/**
+ * Validates the elements in a list with the array of allowed integer values.
+ *
+ * @hide
+ */
+class DiscreteValueIntegerListValidator extends ListValidator {
+    private int[] mAllowedValues;
+
+    DiscreteValueIntegerListValidator(String listSplitRegex, int[] allowedValues) {
+        super(listSplitRegex);
+        mAllowedValues = allowedValues;
+    }
+
+    @Override
+    protected boolean isEntryValid(String entry) {
+        return (entry != null);
+    }
+
+    @Override
+    protected boolean isItemValid(String item) {
+        for (int allowedValue : mAllowedValues) {
+            try {
+                if (Integer.parseInt(item) == allowedValue) {
+                    return true;
+                }
+            } catch (NumberFormatException e) {
+                return false;
+            }
+        }
+        return false;
+    }
+}
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
index ad6a531..0790189 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
@@ -16,16 +16,16 @@
 
 package android.provider.settings.validators;
 
+import static android.media.AudioFormat.SURROUND_SOUND_ENCODING;
 import static android.provider.settings.validators.SettingsValidators.ANY_INTEGER_VALIDATOR;
 import static android.provider.settings.validators.SettingsValidators.ANY_STRING_VALIDATOR;
 import static android.provider.settings.validators.SettingsValidators.BOOLEAN_VALIDATOR;
 import static android.provider.settings.validators.SettingsValidators.PACKAGE_NAME_VALIDATOR;
 import static android.provider.settings.validators.SettingsValidators.PERCENTAGE_INTEGER_VALIDATOR;
+import static android.view.Display.HdrCapabilities.HDR_TYPES;
 
-import android.media.AudioFormat;
 import android.os.BatteryManager;
 import android.provider.Settings.Global;
-import android.text.TextUtils;
 import android.util.ArrayMap;
 
 import java.util.Map;
@@ -88,31 +88,17 @@
                 Global.ENABLE_AUTOMATIC_SYSTEM_SERVER_HEAP_DUMPS,
                 new DiscreteValueValidator(new String[] {"0", "1"}));
         VALIDATORS.put(
+                Global.ARE_USER_DISABLED_HDR_FORMATS_ALLOWED,
+                new DiscreteValueValidator(new String[] {"0", "1"}));
+        VALIDATORS.put(
+                Global.USER_DISABLED_HDR_FORMATS,
+                new DiscreteValueIntegerListValidator(",", HDR_TYPES));
+        VALIDATORS.put(
                 Global.ENCODED_SURROUND_OUTPUT,
                 new DiscreteValueValidator(new String[] {"0", "1", "2", "3"}));
         VALIDATORS.put(
                 Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS,
-                value -> {
-                    try {
-                        String[] surroundFormats = TextUtils.split(value, ",");
-                        for (String format : surroundFormats) {
-                            int audioFormat = Integer.valueOf(format);
-                            boolean isSurroundFormat = false;
-                            for (int sf : AudioFormat.SURROUND_SOUND_ENCODING) {
-                                if (sf == audioFormat) {
-                                    isSurroundFormat = true;
-                                    break;
-                                }
-                            }
-                            if (!isSurroundFormat) {
-                                return false;
-                            }
-                        }
-                        return true;
-                    } catch (NumberFormatException e) {
-                        return false;
-                    }
-                });
+                new DiscreteValueIntegerListValidator(",", SURROUND_SOUND_ENCODING));
         VALIDATORS.put(
                 Global.LOW_POWER_MODE_STICKY_AUTO_DISABLE_LEVEL,
                 new InclusiveIntegerRangeValidator(0, 100));
@@ -154,3 +140,4 @@
                         /* last= */Global.ONE_HANDED_KEYGUARD_SIDE_RIGHT));
     }
 }
+
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
index db9b83e..53920f0 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -165,6 +165,8 @@
         VALIDATORS.put(Secure.ASSIST_GESTURE_ENABLED, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.ASSIST_GESTURE_SILENCE_ALERTS_ENABLED, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.ASSIST_GESTURE_WAKE_ENABLED, BOOLEAN_VALIDATOR);
+        VALIDATORS.put(Secure.ASSIST_TOUCH_GESTURE_ENABLED, BOOLEAN_VALIDATOR);
+        VALIDATORS.put(Secure.ASSIST_LONG_PRESS_HOME_ENABLED, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.VR_DISPLAY_MODE, new DiscreteValueValidator(new String[] {"0", "1"}));
         VALIDATORS.put(Secure.NOTIFICATION_BADGING, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.NOTIFICATION_DISMISS_RTL, BOOLEAN_VALIDATOR);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java b/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
index fdbbc39..df6ff73 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
@@ -18,6 +18,7 @@
 
 import android.annotation.SystemApi;
 import android.app.ActivityManager;
+import android.content.AttributionSource;
 import android.content.IContentProvider;
 import android.os.Binder;
 import android.os.Bundle;
@@ -250,7 +251,8 @@
                 Bundle args = new Bundle();
                 args.putInt(Settings.CALL_METHOD_USER_KEY,
                         ActivityManager.getService().getCurrentUser().id);
-                Bundle b = provider.call(resolveCallingPackage(), null, Settings.AUTHORITY,
+                Bundle b = provider.call(new AttributionSource(Process.myUid(),
+                                resolveCallingPackage(), null), Settings.AUTHORITY,
                         Settings.CALL_METHOD_DELETE_CONFIG, compositeKey, args);
                 success = (b != null && b.getInt(SettingsProvider.RESULT_ROWS_DELETED) == 1);
             } catch (RemoteException e) {
@@ -266,7 +268,8 @@
                 Bundle args = new Bundle();
                 args.putInt(Settings.CALL_METHOD_USER_KEY,
                         ActivityManager.getService().getCurrentUser().id);
-                Bundle b = provider.call(resolveCallingPackage(), null, Settings.AUTHORITY,
+                Bundle b = provider.call(new AttributionSource(Process.myUid(),
+                                resolveCallingPackage(), null), Settings.AUTHORITY,
                         Settings.CALL_METHOD_LIST_CONFIG, null, args);
                 if (b != null) {
                     Map<String, String> flagsToValues =
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 7288371..4119dc9f 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -1881,6 +1881,12 @@
         dumpSetting(s, p,
                 Settings.Secure.ASSIST_GESTURE_SETUP_COMPLETE,
                 SecureSettingsProto.Assist.GESTURE_SETUP_COMPLETE);
+        dumpSetting(s, p,
+                Settings.Secure.ASSIST_TOUCH_GESTURE_ENABLED,
+                SecureSettingsProto.Assist.TOUCH_GESTURE_ENABLED);
+        dumpSetting(s, p,
+                Settings.Secure.ASSIST_LONG_PRESS_HOME_ENABLED,
+                SecureSettingsProto.Assist.LONG_PRESS_HOME_ENABLED);
         p.end(assistToken);
 
         final long assistHandlesToken = p.start(SecureSettingsProto.ASSIST_HANDLES);
@@ -2150,6 +2156,9 @@
         dumpSetting(s, p,
                 Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD,
                 SecureSettingsProto.InputMethods.SHOW_IME_WITH_HARD_KEYBOARD);
+        dumpSetting(s, p,
+                Settings.Secure.DEFAULT_VOICE_INPUT_METHOD,
+                SecureSettingsProto.InputMethods.DEFAULT_VOICE_INPUT_METHOD);
         p.end(inputMethodsToken);
 
         dumpSetting(s, p,
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsService.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsService.java
index 3b3ca5b..17ebf6f 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsService.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsService.java
@@ -17,6 +17,7 @@
 package com.android.providers.settings;
 
 import android.app.ActivityManager;
+import android.content.AttributionSource;
 import android.content.IContentProvider;
 import android.content.pm.PackageManager;
 import android.os.Binder;
@@ -309,7 +310,9 @@
             try {
                 Bundle arg = new Bundle();
                 arg.putInt(Settings.CALL_METHOD_USER_KEY, userHandle);
-                Bundle result = provider.call(resolveCallingPackage(), null, Settings.AUTHORITY,
+                final AttributionSource attributionSource = new AttributionSource(
+                        Binder.getCallingUid(), resolveCallingPackage(), /*attributionTag*/ null);
+                Bundle result = provider.call(attributionSource, Settings.AUTHORITY,
                         callListCommand, null, arg);
                 lines.addAll(result.getStringArrayList(SettingsProvider.RESULT_SETTINGS_LIST));
                 Collections.sort(lines);
@@ -334,7 +337,9 @@
             try {
                 Bundle arg = new Bundle();
                 arg.putInt(Settings.CALL_METHOD_USER_KEY, userHandle);
-                Bundle b = provider.call(resolveCallingPackage(), null, Settings.AUTHORITY,
+                final AttributionSource attributionSource = new AttributionSource(
+                        Binder.getCallingUid(), resolveCallingPackage(), /*attributionTag*/ null);
+                Bundle b = provider.call(attributionSource, Settings.AUTHORITY,
                         callGetCommand, key, arg);
                 if (b != null) {
                     result = b.getPairValue();
@@ -372,7 +377,9 @@
                 if (makeDefault) {
                     arg.putBoolean(Settings.CALL_METHOD_MAKE_DEFAULT_KEY, true);
                 }
-                provider.call(resolveCallingPackage(), null, Settings.AUTHORITY,
+                final AttributionSource attributionSource = new AttributionSource(
+                        Binder.getCallingUid(), resolveCallingPackage(), /*attributionTag*/ null);
+                provider.call(attributionSource, Settings.AUTHORITY,
                         callPutCommand, key, arg);
             } catch (RemoteException e) {
                 throw new RuntimeException("Failed in IPC", e);
@@ -396,7 +403,9 @@
             try {
                 Bundle arg = new Bundle();
                 arg.putInt(Settings.CALL_METHOD_USER_KEY, userHandle);
-                Bundle result = provider.call(resolveCallingPackage(), null, Settings.AUTHORITY,
+                final AttributionSource attributionSource = new AttributionSource(
+                        Binder.getCallingUid(), resolveCallingPackage(), /*attributionTag*/ null);
+                Bundle result = provider.call(attributionSource, Settings.AUTHORITY,
                         callDeleteCommand, key, arg);
                 return result.getInt(SettingsProvider.RESULT_ROWS_DELETED);
             } catch (RemoteException e) {
@@ -423,7 +432,9 @@
                 }
                 String packageName = mPackageName != null ? mPackageName : resolveCallingPackage();
                 arg.putInt(Settings.CALL_METHOD_USER_KEY, userHandle);
-                provider.call(packageName, null, Settings.AUTHORITY, callResetCommand, null, arg);
+                final AttributionSource attributionSource = new AttributionSource(
+                        Binder.getCallingUid(), resolveCallingPackage(), /*attributionTag*/ null);
+                provider.call(attributionSource, Settings.AUTHORITY, callResetCommand, null, arg);
             } catch (RemoteException e) {
                 throw new RuntimeException("Failed in IPC", e);
             }
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index c520568..3877b1e 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -139,7 +139,6 @@
                     Settings.Global.AUTOFILL_MAX_VISIBLE_DATASETS,
                     Settings.Global.AUTOMATIC_POWER_SAVE_MODE,
                     Settings.Global.AVERAGE_TIME_TO_DISCHARGE,
-                    Settings.Global.BACKPORT_S_NOTIF_RULES,
                     Settings.Global.BATTERY_CHARGING_STATE_UPDATE_DELAY,
                     Settings.Global.BATTERY_ESTIMATES_LAST_UPDATE_TIME,
                     Settings.Global.BROADCAST_BG_CONSTANTS,
@@ -217,7 +216,6 @@
                     Settings.Global.DEBUG_APP,
                     Settings.Global.DEBUG_VIEW_ATTRIBUTES,
                     Settings.Global.DEBUG_VIEW_ATTRIBUTES_APPLICATION_PACKAGE,
-                    Settings.Global.DECORATED_CUSTOM_VIEW_NOTIF_DECORATION,
                     Settings.Global.DEFAULT_DNS_SERVER,
                     Settings.Global.DEFAULT_INSTALL_LOCATION,
                     Settings.Global.DEFAULT_RESTRICT_BACKGROUND_DATA,
@@ -289,7 +287,6 @@
                     Settings.Global.WIFI_ON_WHEN_PROXY_DISCONNECTED,
                     Settings.Global.FSTRIM_MANDATORY_INTERVAL,
                     Settings.Global.FOREGROUND_SERVICE_STARTS_LOGGING_ENABLED,
-                    Settings.Global.FULLY_CUSTOM_VIEW_NOTIF_DECORATION,
                     Settings.Global.GLOBAL_HTTP_PROXY_EXCLUSION_LIST,
                     Settings.Global.GLOBAL_HTTP_PROXY_HOST,
                     Settings.Global.GLOBAL_HTTP_PROXY_PAC,
@@ -752,7 +749,8 @@
                  Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_MAGNIFICATION_CONTROLLER,
                  Settings.Secure.SUPPRESS_DOZE,
                  Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED,
-                 Settings.Secure.ACCESSIBILITY_SHOW_WINDOW_MAGNIFICATION_PROMPT);
+                 Settings.Secure.ACCESSIBILITY_SHOW_WINDOW_MAGNIFICATION_PROMPT,
+                 Settings.Secure.TRANSFORM_ENABLED);
 
     @Test
     public void systemSettingsBackedUpOrDenied() {
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index b86ae6d..4c56db4 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -35,16 +35,22 @@
     <uses-permission android:name="android.permission.WRITE_CONTACTS" />
     <uses-permission android:name="android.permission.READ_CALENDAR" />
     <uses-permission android:name="android.permission.WRITE_CALENDAR" />
+    <uses-permission android:name="android.permission.READ_CALL_LOG" />
+    <uses-permission android:name="android.permission.WRITE_CALL_LOG" />
     <uses-permission android:name="android.permission.READ_USER_DICTIONARY" />
     <uses-permission android:name="android.permission.WRITE_USER_DICTIONARY" />
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
     <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+    <uses-permission android:name="android.permission.HIGH_SAMPLING_RATE_SENSORS" />
     <!-- ACCESS_BACKGROUND_LOCATION is needed for testing purposes only. -->
     <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
     <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
     <uses-permission android:name="android.permission.BLUETOOTH" />
+    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
+    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
+    <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
     <uses-permission android:name="android.permission.LOCAL_MAC_ADDRESS" />
     <uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
@@ -125,7 +131,6 @@
     <uses-permission android:name="android.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS" />
     <uses-permission android:name="android.permission.FORCE_DEVICE_POLICY_MANAGER_LOGS" />
     <uses-permission android:name="android.permission.CLEAR_FREEZE_PERIOD" />
-    <uses-permission android:name="android.permission.QUERY_USERS" />
     <uses-permission android:name="android.permission.MODIFY_QUIET_MODE" />
     <uses-permission android:name="android.permission.ACCESS_LOWPAN_STATE"/>
     <uses-permission android:name="android.permission.CHANGE_LOWPAN_STATE"/>
@@ -191,11 +196,14 @@
     <uses-permission android:name="android.permission.MANAGE_CAMERA" />
     <!-- Permissions needed to test system only camera devices -->
     <uses-permission android:name="android.permission.CAMERA" />
+    <uses-permission android:name="android.permission.BACKGROUND_CAMERA" />
     <uses-permission android:name="android.permission.SYSTEM_CAMERA" />
       <!-- Permissions needed to test onCameraOpened/Closed callbacks -->
     <uses-permission android:name="android.permission.CAMERA_OPEN_CLOSE_LISTENER" />
     <!-- Permissions needed for CTS camera test: RecordingTest.java when assuming shell id -->
     <uses-permission android:name="android.permission.RECORD_AUDIO" />
+    <uses-permission android:name="android.permission.RECORD_BACKGROUND_AUDIO" />
+
     <!-- Permission needed to enable/disable Bluetooth/Wifi -->
     <uses-permission android:name="android.permission.MANAGE_BLUETOOTH_WHEN_WIRELESS_CONSENT_REQUIRED" />
     <uses-permission android:name="android.permission.MANAGE_WIFI_WHEN_WIRELESS_CONSENT_REQUIRED" />
@@ -238,6 +246,9 @@
     <!-- Permission needed to run keyguard manager tests in CTS -->
     <uses-permission android:name="android.permission.CONTROL_KEYGUARD_SECURE_NOTIFICATIONS" />
 
+    <!-- Permission needed to set/clear/verify lockscreen credentials in CTS tests -->
+    <uses-permission android:name="android.permission.SET_AND_VERIFY_LOCKSCREEN_CREDENTIALS" />
+
     <!-- Permission needed to test wallpaper component -->
     <uses-permission android:name="android.permission.SET_WALLPAPER" />
     <uses-permission android:name="android.permission.SET_WALLPAPER_COMPONENT" />
@@ -438,6 +449,9 @@
     <!-- Permission required for CTS test - ResourceObserverNativeTest -->
     <uses-permission android:name="android.permission.REGISTER_MEDIA_RESOURCE_OBSERVER" />
 
+    <!-- Permission required for CTS test - android.widget.cts.ToastTest -->
+    <uses-permission android:name="android.permission.UNLIMITED_TOASTS" />
+
     <application android:label="@string/app_label"
                 android:theme="@android:style/Theme.DeviceDefault.DayNight"
                 android:defaultToDeviceProtectedStorage="true"
diff --git a/packages/SoundPicker/res/values-pa/strings.xml b/packages/SoundPicker/res/values-pa/strings.xml
index 2653c64..eb630c9 100644
--- a/packages/SoundPicker/res/values-pa/strings.xml
+++ b/packages/SoundPicker/res/values-pa/strings.xml
@@ -17,7 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="ringtone_default" msgid="798836092118824500">"ਪੂਰਵ-ਨਿਰਧਾਰਤ ਰਿੰਗਟੋਨ"</string>
-    <string name="notification_sound_default" msgid="8133121186242636840">"ਪੂਰਵ-ਨਿਰਧਾਰਤ ਸੂਚਨਾ ਧੁਨੀ"</string>
+    <string name="notification_sound_default" msgid="8133121186242636840">"ਪੂਰਵ-ਨਿਰਧਾਰਿਤ ਸੂਚਨਾ ਧੁਨੀ"</string>
     <string name="alarm_sound_default" msgid="4787646764557462649">"ਪੂਰਵ-ਨਿਰਧਾਰਤ ਅਲਾਰਮ ਧੁਨੀ"</string>
     <string name="add_ringtone_text" msgid="6642389991738337529">"ਰਿੰਗਟੋਨ ਸ਼ਾਮਲ ਕਰੋ"</string>
     <string name="add_alarm_text" msgid="3545497316166999225">"ਅਲਾਰਮ ਸ਼ਾਮਲ ਕਰੋ"</string>
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 3904201..4135bbe 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -62,6 +62,8 @@
     <!-- Networking and telephony -->
     <uses-permission android:name="android.permission.BLUETOOTH" />
     <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
+    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
+    <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
     <uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" />
     <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
diff --git a/packages/SystemUI/OWNERS b/packages/SystemUI/OWNERS
index f884270..835471d 100644
--- a/packages/SystemUI/OWNERS
+++ b/packages/SystemUI/OWNERS
@@ -9,6 +9,7 @@
 awickham@google.com
 beverlyt@google.com
 brockman@google.com
+ccassidy@google.com
 cinek@google.com
 cwren@google.com
 dupin@google.com
@@ -19,10 +20,10 @@
 hyunyoungs@google.com
 jaggies@google.com
 jamesoleary@google.com
+jdemeulenaere@google.com
 jeffdq@google.com
 jjaggi@google.com
 jonmiranda@google.com
-joshmcgrath@google.com
 joshtrask@google.com
 juliacr@google.com
 juliatuttle@google.com
@@ -37,7 +38,6 @@
 mpietal@google.com
 mrcasey@google.com
 mrenouf@google.com
-nbenbernou@google.com
 nesciosquid@google.com
 ogunwale@google.com
 peanutbutter@google.com
@@ -45,6 +45,7 @@
 pixel@google.com
 roosa@google.com
 santie@google.com
+shanh@google.com
 snoeberger@google.com
 sreyasr@google.com
 steell@google.com
@@ -59,6 +60,7 @@
 vadimt@google.com
 victortulias@google.com
 winsonc@google.com
+yurilin@google.com
 xuqiu@google.com
 zakcohen@google.com
 
diff --git a/packages/SystemUI/docs/falsing.md b/packages/SystemUI/docs/falsing.md
new file mode 100644
index 0000000..e224ca8
--- /dev/null
+++ b/packages/SystemUI/docs/falsing.md
@@ -0,0 +1,240 @@
+# Falsing in SystemUI
+
+Phones are easily and often accidentally-activated in owners' pockets ("falsing" or "pocket 
+dialing"). Because a phone's screen can be turned on with a single tap, and because we have further
+actions that be activated with basic tapping and swiping, it is critical that we
+analyze touch events on the screen for intentional vs accidental behavior. With analysis, 
+features within SystemUI have an opportunity to ignore or even undo accidental interactions as they
+are occurring.
+
+## Technical Details
+
+The `FalsingManager` tracks all touch interactions happening on a phone's lock screen.
+
+If you support any sort of touch gestures on the lock screen, you **must**, at a
+minimum, inform the `FalsingManager` of what touches are on touch targets vs not (things that may be
+ intentional). If you do not tell the `FalsingManager`, it will assume touches on your feature are
+always accidental and penalize the session accordingly.
+
+Individual touch targets do not _have_ to be separated out; it's acceptable to
+wrap your whole feature in one virtual block that reports touches to the
+`FalsingManager`, however more granular tracking will result in better results
+across the whole lock screen.
+
+You can _act_ on the results of the `FalsingManager`. Instead of only telling
+the `FalsingManager` that touch events were on touch targets, you can further use the
+returned results to decide if you want to respond to an owner's touch, if you
+want to prompt them to confirm their action, or if you simply want to ignore the
+touch.
+
+The flow through the system looks like such:
+
+1. Gesture on the screen.
+2. The `FalsingManager` makes a note of all of the `MotionEvents`.
+    * If no feature/touch target receives the `MotionEvents`, skip to 4. 
+3. Your touch target receives the `MotionEvents`.
+    * Once your feature is ready to respond to the gesture in a substantive manner, it queries
+      the `FalsingManager`.
+      - Dragging animations, touch ripples, and other purely visual effects should not query.
+      - Query once you are ready to launch a new feature or dialogue, or are otherwise going to
+        change the state of the UI. 
+      - Generally, wait until `MotionEvent.ACTION_UP` to query or `View.OnClickListener#onClick`.
+      - Only query once per gesture, at the end.
+    * If the `FalsingManager` says it looks good, respond to the touch.
+4. The `FalsingManager` checks to see if anyone queried about the gesture. If not, mark it as 
+   accidental. 
+   
+There is also an event fired by the `FalsingManager` that can be listened to by anyone, that 
+indicates that the the `FalsingManager` believes the phone is actively being pocket-dialed. When
+fired, modal features, such as quick settings, keyguard bouncer, and others should retract 
+themselves to prevent further pocket-dialing.  
+
+## Falsing "Belief" and History
+
+The `FalsingManager` maintains a recent history of false analyses. Using
+Bayesian statistics, it updates a "belief" in  whether recent
+gestures are intentional or not. Any gesture that it is not explicitly queried about is treated as
+accidental, increasing the overall belief in
+false-iness. Gestures that are explicitly queried and that pass the relevant heuristics
+reduce belief that falsing is occurring. This information is tracked within the `HistoryTracker`.
+
+Changes in belief may influence internal heurstics within the `FalsingManager`,
+making it easier or harder for an owner to interact with their device. (An owner
+will always be able to interact with their device, but we may require double
+taps, or more deliberate swipes.)
+
+## Responding to Touch Events
+
+The methods below inform the `FalsingManager` that a tap is occurring within an expected touch 
+target. Match the methods with the gesture you expect the device owner to use.
+
+### Single Tap
+
+`FalsingManager#isFalseTap(boolean robustCheck, double falsePenalty)`. This
+method tells the `FalsingManager` that you want to validate a single tap. It
+returns true if it thinks the tap should be rejected (i.e. the tap looks more
+like a swipe) and false otherwise.
+
+`robustCheck` determines what heuristics are used. If set to false, the method
+performs a only very basic checking, checking that observed `MotionEvent`s are
+all within some small x & y region ("touch slop").
+
+When `robustCheck` is set to true, several more advanced rules are additionally
+applied:
+
+1.  If the device recognizes a face (i.e. face-auth) the tap is **accepted**.
+2.  If the tap is the _second_ tap in recent history and looks like a valid Double Tap
+    the tap is **accepted**. This works exactly like `FalsingManager#isFalseDoubleTap`.
+3.  If the `HistoryTracker` reports strong belief in recent falsing, the tap is
+    **rejected**.
+4.  Otherwise the tap is **accepted**.
+
+All the above rules are applied only after first confirming the gesture does
+in fact look like a basic tap.
+
+`falsePenalty` is a measure of how much the `HistoryTracker`'s belief should be
+penalized in the event that the tap is rejected. This value is only used if
+`robustCheck` is set to true.
+
+A value of `0` means no change in belief. A value of `1` means a _very_ strong
+confidence in a false tap. In general, as a single tap on the screen is not
+verifiable, a small value should be supplied - on the order of `0.1`. Pass `0`
+if you don't want to penalize belief at all. Pass a higher value
+the earlier in the UX flow your interaction occurs. Once an owner is farther
+along in a UX flow (multiple taps or swipes), its safer to assume that a single
+accidental tap should cause less of a penalty.
+
+### Double Tap
+
+`FalsingManager#isFalseDoubleTap()`. This method tells the `FalsingManager` that
+your UI wants to validate a double tap. There are no parameters to pass to this method.
+Call this when you explicitly receive and want to verify a double tap, _not_ a single tap.
+
+Note that `FalsingManager#isFalseTap(boolean robustCheck, double falsePenalty)`
+will also check for double taps when `robustCheck` is set to true. If you are
+willing to use single taps, use that instead.
+
+### Swipes and Other Gestures
+
+`FalsingManager#isFalseTouch(@Classifier.InteractionType int interactionType)`.
+Use this for any non-tap interactions. This includes expanding notifications,
+expanding quick settings, pulling up the bouncer, and more. You must pass
+the type of interaction you are evaluating when calling it. A large set of
+heuristics will be applied to analyze the gesture, and the exact rules vary depending upon
+the `InteractionType`.
+
+### Ignoring A Gesture
+
+`FalsingCollector#avoidGesture()`. Tell the `FalsingManager` to pretend like the
+observed gesture never happened. **This method must be called when the observed
+`MotionEvent` is `MotionEvent.ACTION_DOWN`.** Attempting to call this method
+later in a gesture will not work.
+
+Notice that this method is actually a method on `FalsingCollector`. It is
+forcefully telling the `FalsingManager` to wholly pretend the gesture never
+happened. This is intended for security and PII sensitive gestures, such as
+password inputs. Please don't use this as a shortcut for avoiding the
+FalsingManager. Falsing works better the more behavior it is told about.
+
+### Other Considerations
+
+Please try to call the `FalsingManager` only once per gesture. Wait until you
+are ready to act on the owner's action, and then query the `FalsingManager`. The `FalsingManager`
+will update its belief in pocket dialing based only on the last call made, so multiple calls per
+gesture are not well defined.
+
+The `FalsingManager` does not update its belief in pocket-dialing until a new
+gesture starts. That is to say, if the owner makes a bad tap on your feature,
+the belief in pocket dialing will not incorporate this new data until the
+following gesture begins.
+
+If you expect a mix of taps, double taps, and swipes on your feature, segment them
+accordingly. Figure out which `FalsingManager` method you need to call first, rather than relying
+on multiple calls to the `FalsingManager` to act as a sieve.
+
+Don't:
+```
+if (!mFalsingManager.isFalseTap(false, 0)) {
+  // its a tap
+} else if (!mFalsingManager.isFalseTouch(GESTURE_A) {
+  // do thing a
+} else if (!mFalsingManager.isFalseTouch(GESTURE_B) {
+  // do thing b
+} else {
+  // must be a false.
+}
+``` 
+
+Do:
+```
+void onTap() {
+  if (!mFalsingManager.isFalseTap(false, 0)) {
+    // its a tap
+}
+
+void onGestureA() {
+  if (!mFalsingManager.isFalseTouch(GESTURE_A) {
+    // do thing a
+  }
+}
+
+void onGestureB() {
+  if (!mFalsingManager.isFalseTouch(GESTURE_B) {
+    // do thing b
+  }
+}
+``` 
+
+
+## Influencing Belief
+
+`FalsingCollector#updateFalseConfidence(FalsingClassifier.Result result)`. This
+method allows you to directly change the `FalsingManager`'s belief in the state
+of pocket dialing. If the owner does something unusual with their phone that you
+think indicates pocket dialing, you can call:
+
+```
+    mFalsingCollector.updateFalseConfidence(
+      FalsingClassifier.Result.falsed(0.6, "Owner is doing something fishy"));
+```
+
+A belief value of `1` indicates a 100% confidence of false behavior. A belief
+value of `0` would make no change in the `FalsingManager` and should be avoided
+as it simply creates noise in the logs. Generally, a middle value between the
+two extremes makes sense.
+
+A good example of where this is used is in the "Pattern" password input. We
+avoid recording those gestures in the `FalsingManager`, but we have the pattern input update
+the `FalsingManager` directly in some cases. If the owner simply taps on the pattern input, we 
+record it as a false, (patterns are always 4 "cells" long, so single "cell" inputs are penalized).
+
+Conversely, if you think the owner does something that deserves a nice reward:
+
+```
+    mFalsingCollector.updateFalseConfidence(
+       FalsingClassifier.Result.passed(0.6));
+```
+
+Again, useful on password inputs where the FalsingManager is avoiding recording
+the gesture. This is used on the "pin" password input, to recognize successful
+taps on the input buttons.
+
+## Global Falsing Event
+
+If the `FalsingManager`'s belief in falsing crosses some internally defined
+threshold, it will fire an event that other parts of the system can listen for.
+This even indicates that the owner is likely actively pocket-dialing, and any
+currently open activities on the phone should retract themselves.
+
+To subscribe to this event, call
+`FalsingManager#addFalsingBeliefListener(FalsingBeliefListener listener)`.
+`FalsingBeliefListener` is a simple one method interface that will be called
+after when activities should retract themselves.
+
+**Do Listen For This**. Your code will work without it, but it is a handy,
+universal signal that will save the phone owner a lot of accidents. A simple
+implementation looks like:
+
+```
+    mFalsingManager.addFalsingBeliefListener(MyFeatureClass::hide);
+```
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/DetailAdapter.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/DetailAdapter.java
index beee03b..95c2d2e 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/DetailAdapter.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/DetailAdapter.java
@@ -16,6 +16,7 @@
 
 import android.content.Context;
 import android.content.Intent;
+import android.content.res.Resources;
 import android.view.View;
 import android.view.ViewGroup;
 
@@ -34,7 +35,31 @@
     }
 
     View createDetailView(Context context, View convertView, ViewGroup parent);
+
+    /**
+     * @return intent for opening more settings related to this detail panel. If null, the more
+     * settings button will not be shown
+     */
     Intent getSettingsIntent();
+
+    /**
+     * @return resource id of the string to use for opening the settings intent. If
+     * {@code Resources.ID_NULL}, then use the default string:
+     * {@code com.android.systemui.R.string.quick_settings_more_settings}
+     */
+    default int getSettingsText() {
+        return Resources.ID_NULL;
+    }
+
+    /**
+     * @return resource id of the string to use for closing the detail panel. If
+     * {@code Resources.ID_NULL}, then use the default string:
+     * {@code com.android.systemui.R.string.quick_settings_done}
+     */
+    default int getDoneText() {
+        return Resources.ID_NULL;
+    }
+
     void setToggleState(boolean state);
     int getMetricsCategory();
 
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml b/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml
index 6b4fbdb..6ecbe06 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml
@@ -73,7 +73,7 @@
             android:layout_height="wrap_content"
             android:layout_gravity="center_horizontal"
             android:gravity="center_horizontal"
-            android:textSize="60dp"
+            android:textSize="86dp"
             android:fontFamily="@font/clock"
             android:typeface="monospace"
             android:elegantTextHeight="false"
@@ -98,7 +98,7 @@
             android:fontFamily="@font/clock"
             android:typeface="monospace"
             android:elegantTextHeight="false"
-            dozeWeight="100"
+            dozeWeight="200"
             lockScreenWeight="400"
         />
     </FrameLayout>
diff --git a/packages/SystemUI/res-keyguard/values-iw/strings.xml b/packages/SystemUI/res-keyguard/values-iw/strings.xml
index 8780dc5..56a71d4 100644
--- a/packages/SystemUI/res-keyguard/values-iw/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-iw/strings.xml
@@ -21,17 +21,17 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_name" msgid="514691256816366517">"מגן מקלדת"</string>
-    <string name="keyguard_password_enter_pin_code" msgid="8582296866585566671">"הזן את קוד הגישה"</string>
+    <string name="keyguard_password_enter_pin_code" msgid="8582296866585566671">"יש להזין את קוד האימות"</string>
     <string name="keyguard_password_enter_puk_code" msgid="3813154965969758868">"‏הזן את קוד ה-PUK של כרטיס ה-SIM ולאחר מכן הזן קוד גישה חדש"</string>
     <string name="keyguard_password_enter_puk_prompt" msgid="3529260761374385243">"‏קוד PUK של כרטיס SIM"</string>
     <string name="keyguard_password_enter_pin_prompt" msgid="2304037870481240781">"‏קוד גישה חדש לכרטיס ה-SIM"</string>
     <string name="keyguard_password_entry_touch_hint" msgid="6180028658339706333"><font size="17">"גע כדי להזין את הסיסמה"</font></string>
     <string name="keyguard_password_enter_password_code" msgid="7393393239623946777">"הזן סיסמה לביטול הנעילה"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="3692259677395250509">"הזן את קוד הגישה לביטול הנעילה"</string>
-    <string name="keyguard_enter_your_pin" msgid="5429932527814874032">"הזנת קוד גישה"</string>
+    <string name="keyguard_enter_your_pin" msgid="5429932527814874032">"צריך להזין קוד אימות"</string>
     <string name="keyguard_enter_your_pattern" msgid="351503370332324745">"יש להזין קו ביטול נעילה"</string>
     <string name="keyguard_enter_your_password" msgid="7225626204122735501">"יש להזין סיסמה"</string>
-    <string name="keyguard_password_wrong_pin_code" msgid="3514267777289393046">"קוד הגישה שגוי"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="3514267777289393046">"קוד האימות שגוי"</string>
     <string name="keyguard_sim_error_message_short" msgid="633630844240494070">"כרטיס לא חוקי."</string>
     <string name="keyguard_charged" msgid="5478247181205188995">"הסוללה טעונה"</string>
     <string name="keyguard_plugged_in_wireless" msgid="2537874724955057383">"<xliff:g id="PERCENTAGE">%s</xliff:g> • בטעינה אלחוטית"</string>
@@ -43,14 +43,14 @@
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"לחץ על \'תפריט\' כדי לבטל את הנעילה."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"הרשת נעולה"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"‏אין כרטיס SIM"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"‏הכנס כרטיס SIM."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"‏יש להכניס כרטיס SIM."</string>
     <string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"‏כרטיס ה-SIM חסר או שלא ניתן לקרוא אותו. הכנס כרטיס SIM."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"‏לא ניתן להשתמש בכרטיס SIM זה."</string>
     <string name="keyguard_permanent_disabled_sim_instructions" msgid="2490584154727897806">"‏כרטיס ה-SIM שלך הושבת לצמיתות.\nפנה לספק השירות האלחוטי שלך לקבלת כרטיס SIM אחר."</string>
     <string name="keyguard_sim_locked_message" msgid="4343544458476911044">"‏כרטיס ה-SIM נעול."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="6253830777745450550">"‏כרטיס ה-SIM נעול באמצעות PUK."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="2394023844117630429">"‏מבטל את הנעילה של כרטיס ה-SIM…"</string>
-    <string name="keyguard_accessibility_pin_area" msgid="7403009340414014734">"אזור לקוד הגישה"</string>
+    <string name="keyguard_accessibility_pin_area" msgid="7403009340414014734">"אזור של קוד האימות"</string>
     <string name="keyguard_accessibility_password" msgid="3524161948484801450">"סיסמת מכשיר"</string>
     <string name="keyguard_accessibility_sim_pin_area" msgid="6272116591533888062">"‏אזור לקוד הגישה של כרטיס ה-SIM"</string>
     <string name="keyguard_accessibility_sim_puk_area" msgid="5537294043180237374">"‏אזור לקוד הגישה של כרטיס ה-SIM"</string>
@@ -63,7 +63,7 @@
     <string name="kg_forgot_pattern_button_text" msgid="3304688032024541260">"שכחתי את קו ביטול הנעילה"</string>
     <string name="kg_wrong_pattern" msgid="5907301342430102842">"קו ביטול נעילה שגוי"</string>
     <string name="kg_wrong_password" msgid="4143127991071670512">"סיסמה שגויה"</string>
-    <string name="kg_wrong_pin" msgid="4160978845968732624">"קוד הגישה שגוי"</string>
+    <string name="kg_wrong_pin" msgid="4160978845968732624">"קוד האימות שגוי"</string>
     <plurals name="kg_too_many_failed_attempts_countdown" formatted="false" msgid="991400408675793914">
       <item quantity="two">אפשר יהיה לנסות שוב בעוד <xliff:g id="NUMBER">%d</xliff:g> שניות.</item>
       <item quantity="many">אפשר יהיה לנסות שוב בעוד <xliff:g id="NUMBER">%d</xliff:g> שניות.</item>
@@ -72,28 +72,28 @@
     </plurals>
     <string name="kg_pattern_instructions" msgid="5376036737065051736">"שרטט את קו ביטול הנעילה"</string>
     <string name="kg_sim_pin_instructions" msgid="1942424305184242951">"‏הזן את קוד הגישה של כרטיס ה-SIM."</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="3639863309953109649">"‏הזן את קוד הגישה של כרטיס ה-SIM של <xliff:g id="CARRIER">%1$s</xliff:g>."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="3639863309953109649">"‏יש להזין את קוד האימות של כרטיס ה-SIM של <xliff:g id="CARRIER">%1$s</xliff:g>."</string>
     <string name="kg_sim_lock_esim_instructions" msgid="5577169988158738030">"‏<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> יש להשבית את כרטיס ה-eSIM כדי להשתמש במכשיר ללא שירות סלולרי."</string>
-    <string name="kg_pin_instructions" msgid="822353548385014361">"הזן קוד גישה"</string>
-    <string name="kg_password_instructions" msgid="324455062831719903">"הזן את הסיסמה"</string>
+    <string name="kg_pin_instructions" msgid="822353548385014361">"יש להזין קוד אימות"</string>
+    <string name="kg_password_instructions" msgid="324455062831719903">"צריך להזין את הסיסמה"</string>
     <string name="kg_puk_enter_puk_hint" msgid="3005288372875367017">"‏כרטיס ה-SIM מושבת כעת. הזן קוד PUK כדי להמשיך. פנה אל הספק לפרטים."</string>
-    <string name="kg_puk_enter_puk_hint_multi" msgid="4876780689904862943">"‏ה-SIM של \"<xliff:g id="CARRIER">%1$s</xliff:g>\" מושבת כעת. הזן קוד PUK כדי להמשיך. לפרטים, פנה אל הספק."</string>
+    <string name="kg_puk_enter_puk_hint_multi" msgid="4876780689904862943">"‏ה-SIM של \"<xliff:g id="CARRIER">%1$s</xliff:g>\" מושבת עכשיו. צריך להזין קוד PUK כדי להמשיך. לפרטים, יש לפנות אל הספק."</string>
     <string name="kg_puk_enter_pin_hint" msgid="6028432138916150399">"הזן את קוד הגישה הרצוי"</string>
-    <string name="kg_enter_confirm_pin_hint" msgid="4261064020391799132">"אשר את קוד הגישה הרצוי"</string>
-    <string name="kg_sim_unlock_progress_dialog_message" msgid="4251352015304070326">"‏מבטל את הנעילה של כרטיס ה-SIM…"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="4261064020391799132">"צריך לאשר את קוד האימות הרצוי"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="4251352015304070326">"‏מתבצע ביטול נעילה של כרטיס ה-SIM…"</string>
     <string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"הקלד קוד גישה שאורכו 4 עד 8 ספרות."</string>
     <string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"‏קוד PUK צריך להיות בן 8 ספרות או יותר."</string>
-    <string name="kg_invalid_puk" msgid="1774337070084931186">"‏הזן את קוד ה-PUK הנכון. ניסיונות חוזרים ישביתו את כרטיס ה-SIM לצמיתות."</string>
+    <string name="kg_invalid_puk" msgid="1774337070084931186">"‏יש להזין את קוד ה-PUK הנכון. ניסיונות חוזרים ישביתו את כרטיס ה-SIM באופן סופי."</string>
     <string name="kg_login_too_many_attempts" msgid="4519957179182578690">"ניסית לשרטט את קו ביטול הנעילה יותר מדי פעמים"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"הקלדת קוד גישה שגוי <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. \n\nנסה שוב בעוד <xliff:g id="NUMBER_1">%2$d</xliff:g> שניות."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"הקלדת קוד גישה שגוי <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. \n\nיש לנסות שוב בעוד <xliff:g id="NUMBER_1">%2$d</xliff:g> שניות."</string>
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"הקלדת סיסמה שגויה <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים.\n\nנסה שוב בעוד <xliff:g id="NUMBER_1">%2$d</xliff:g> שניות."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"שרטטת קו ביטול נעילה שגוי <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. \n\nנסה שוב בעוד <xliff:g id="NUMBER_1">%2$d</xliff:g> שניות."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"‏קוד הגישה של כרטיס ה-SIM שגוי. צור קשר עם הספק כדי לבטל את נעילת המכשיר."</string>
     <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="two">‏קוד הגישה של כרטיס ה-SIM שגוי. נותרו לך עוד <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות.</item>
-      <item quantity="many">‏קוד הגישה של כרטיס ה-SIM שגוי. נותרו לך עוד <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות.</item>
-      <item quantity="other">‏קוד הגישה של כרטיס ה-SIM שגוי. נותרו לך עוד <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות.</item>
-      <item quantity="one">‏קוד הגישה של כרטיס ה-SIM שגוי. נותר לך עוד ניסיון <xliff:g id="NUMBER_0">%d</xliff:g> לפני שיהיה עליך ליצור קשר עם הספק כדי לבטל את נעילת המכשיר.</item>
+      <item quantity="two">‏קוד האימות של כרטיס ה-SIM שגוי. נותרו לך עוד <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות.</item>
+      <item quantity="many">‏קוד האימות של כרטיס ה-SIM שגוי. נותרו לך עוד <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות.</item>
+      <item quantity="other">‏קוד האימות של כרטיס ה-SIM שגוי. נותרו לך עוד <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות.</item>
+      <item quantity="one">‏קוד האימות של כרטיס ה-SIM שגוי. נותר לך עוד ניסיון <xliff:g id="NUMBER_0">%d</xliff:g> לפני שיהיה עליך ליצור קשר עם הספק כדי לבטל את נעילת המכשיר.</item>
     </plurals>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"‏לא ניתן להשתמש בכרטיס ה-SIM. צור קשר עם הספק."</string>
     <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
@@ -103,27 +103,27 @@
       <item quantity="one">‏קוד ה-PUK של כרטיס ה-SIM שגוי. נותר לך ניסיון <xliff:g id="NUMBER_0">%d</xliff:g> נוסף לפני שכרטיס ה-SIM יינעל לצמיתות.</item>
     </plurals>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"‏פעולת קוד הגישה של כרטיס ה-SIM נכשלה!"</string>
-    <string name="kg_password_puk_failed" msgid="6778867411556937118">"‏פעולת קוד ה-PUK של כרטיס ה-SIM נכשלה!"</string>
+    <string name="kg_password_puk_failed" msgid="6778867411556937118">"‏הניסיון לביטול הנעילה של כרטיס ה-SIM באמצעות קוד PUK נכשל!"</string>
     <string name="kg_pin_accepted" msgid="1625501841604389716">"הקוד התקבל!"</string>
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"אין שירות."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"החלפת שיטת קלט"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"מצב טיסה"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"יש להזין את קו ביטול הנעילה לאחר הפעלה מחדש של המכשיר"</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"יש להזין קוד גישה לאחר הפעלה מחדש של המכשיר"</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"צריך להזין קוד אימות לאחר הפעלה מחדש של המכשיר"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"יש להזין סיסמה לאחר הפעלה מחדש של המכשיר"</string>
     <string name="kg_prompt_reason_timeout_pattern" msgid="9170360502528959889">"יש להזין את קו ביטול הנעילה כדי להגביר את רמת האבטחה"</string>
     <string name="kg_prompt_reason_timeout_pin" msgid="5945186097160029201">"יש להזין קוד גישה כדי להגביר את רמת האבטחה"</string>
     <string name="kg_prompt_reason_timeout_password" msgid="2258263949430384278">"יש להזין סיסמה כדי להגביר את רמת האבטחה"</string>
     <string name="kg_prompt_reason_switch_profiles_pattern" msgid="1922016914701991230">"יש להזין את קו ביטול הנעילה בזמן מעבר בין פרופילים"</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="6490434826361055400">"יש להזין את קוד הגישה בזמן מעבר בין פרופילים"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="6490434826361055400">"צריך להזין את קוד האימות כשמחליפים פרופיל"</string>
     <string name="kg_prompt_reason_switch_profiles_password" msgid="1680374696393804441">"יש להזין את הסיסמה בזמן מעבר בין פרופילים"</string>
     <string name="kg_prompt_reason_device_admin" msgid="6961159596224055685">"מנהל המכשיר נעל את המכשיר"</string>
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"המכשיר ננעל באופן ידני"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="1337428979661197957">
-      <item quantity="two">נעילת המכשיר לא בוטלה במשך <xliff:g id="NUMBER_1">%d</xliff:g> שעות. הזן את קו ביטול הנעילה.</item>
-      <item quantity="many">נעילת המכשיר לא בוטלה במשך <xliff:g id="NUMBER_1">%d</xliff:g> שעות. הזן את קו ביטול הנעילה.</item>
-      <item quantity="other">נעילת המכשיר לא בוטלה במשך <xliff:g id="NUMBER_1">%d</xliff:g> שעות. הזן את קו ביטול הנעילה.</item>
-      <item quantity="one">נעילת המכשיר לא בוטלה במשך <xliff:g id="NUMBER_0">%d</xliff:g> שעה. הזן את קו ביטול הנעילה.</item>
+      <item quantity="two">נעילת המכשיר לא בוטלה במשך <xliff:g id="NUMBER_1">%d</xliff:g> שעות. יש להזין את קו ביטול הנעילה.</item>
+      <item quantity="many">נעילת המכשיר לא בוטלה במשך <xliff:g id="NUMBER_1">%d</xliff:g> שעות. יש להזין את קו ביטול הנעילה.</item>
+      <item quantity="other">נעילת המכשיר לא בוטלה במשך <xliff:g id="NUMBER_1">%d</xliff:g> שעות. יש להזין את קו ביטול הנעילה.</item>
+      <item quantity="one">נעילת המכשיר לא בוטלה במשך שעה אחת (<xliff:g id="NUMBER_0">%d</xliff:g>). יש להזין את קו ביטול הנעילה.</item>
     </plurals>
     <plurals name="kg_prompt_reason_time_pin" formatted="false" msgid="6444519502336330270">
       <item quantity="two">נעילת המכשיר לא בוטלה במשך <xliff:g id="NUMBER_1">%d</xliff:g> שעות. הזן את קוד הגישה.</item>
@@ -132,18 +132,18 @@
       <item quantity="one">נעילת המכשיר לא בוטלה במשך <xliff:g id="NUMBER_0">%d</xliff:g> שעה. הזן את קוד הגישה.</item>
     </plurals>
     <plurals name="kg_prompt_reason_time_password" formatted="false" msgid="5343961527665116914">
-      <item quantity="two">נעילת המכשיר לא בוטלה במשך <xliff:g id="NUMBER_1">%d</xliff:g> שעות. הזן את הסיסמה.</item>
-      <item quantity="many">נעילת המכשיר לא בוטלה במשך <xliff:g id="NUMBER_1">%d</xliff:g> שעות. הזן את הסיסמה.</item>
-      <item quantity="other">נעילת המכשיר לא בוטלה במשך <xliff:g id="NUMBER_1">%d</xliff:g> שעות. הזן את הסיסמה.</item>
-      <item quantity="one">נעילת המכשיר לא בוטלה במשך <xliff:g id="NUMBER_0">%d</xliff:g> שעה. הזן את הסיסמה.</item>
+      <item quantity="two">נעילת המכשיר לא בוטלה במשך <xliff:g id="NUMBER_1">%d</xliff:g> שעות. יש להזין את הסיסמה.</item>
+      <item quantity="many">נעילת המכשיר לא בוטלה במשך <xliff:g id="NUMBER_1">%d</xliff:g> שעות. יש להזין את הסיסמה.</item>
+      <item quantity="other">נעילת המכשיר לא בוטלה במשך <xliff:g id="NUMBER_1">%d</xliff:g> שעות. יש להזין את הסיסמה.</item>
+      <item quantity="one">נעילת המכשיר לא בוטלה במשך <xliff:g id="NUMBER_0">%d</xliff:g> שעה. יש להזין את הסיסמה.</item>
     </plurals>
     <string name="kg_fingerprint_not_recognized" msgid="5982606907039479545">"לא זוהתה"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"לא זוהתה"</string>
     <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="two">‏יש להזין קוד גישה לכרטיס SIM. נותרו לך <xliff:g id="NUMBER_1">%d</xliff:g> ניסונות נוספים.</item>
-      <item quantity="many">‏יש להזין קוד גישה לכרטיס SIM. נותרו לך <xliff:g id="NUMBER_1">%d</xliff:g> ניסונות נוספים.</item>
-      <item quantity="other">‏יש להזין קוד גישה לכרטיס SIM. נותרו לך <xliff:g id="NUMBER_1">%d</xliff:g> ניסונות נוספים.</item>
-      <item quantity="one">‏יש להזין קוד גישה לכרטיס SIM. נותר לך <xliff:g id="NUMBER_0">%d</xliff:g> ניסיון נוסף לפני שיהיה צורך ליצור קשר עם הספק כדי לבטל את נעילת המכשיר.</item>
+      <item quantity="two">‏יש להזין קוד אימות של כרטיס SIM. נותרו לך <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות נוספים.</item>
+      <item quantity="many">‏יש להזין קוד אימות של כרטיס SIM. נותרו לך <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות נוספים.</item>
+      <item quantity="other">‏יש להזין קוד אימות של כרטיס SIM. נותרו לך <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות נוספים.</item>
+      <item quantity="one">‏יש להזין קוד אימות של כרטיס SIM. נותר לך ניסיון נוסף (<xliff:g id="NUMBER_0">%d</xliff:g>) לפני שיהיה צורך ליצור קשר עם הספק כדי לבטל את נעילת המכשיר.</item>
     </plurals>
     <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
       <item quantity="two">‏כרטיס ה-SIM מושבת כעת. יש להזין קוד PUK כדי להמשיך. נותרו לך <xliff:g id="_NUMBER_1">%d</xliff:g> ניסיונות נוספים לפני שכרטיס ה-SIM ינעל לצמיתות. למידע נוסף, ניתן לפנות לספק שלך.</item>
diff --git a/packages/SystemUI/res-keyguard/values-pa/strings.xml b/packages/SystemUI/res-keyguard/values-pa/strings.xml
index 04419e0..47b2881 100644
--- a/packages/SystemUI/res-keyguard/values-pa/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pa/strings.xml
@@ -135,7 +135,7 @@
       <item quantity="one">ਸਿਮ ਹੁਣ ਬੰਦ ਹੋ ਗਿਆ ਹੈ। ਜਾਰੀ ਰੱਖਣ ਲਈ PUK ਕੋਡ ਦਾਖਲ ਕਰੋ। ਸਿਮ ਦੇ ਪੱਕੇ ਤੌਰ \'ਤੇ ਬੇਕਾਰ ਹੋ ਜਾਣ ਤੋਂ ਪਹਿਲਾਂ ਤੁਹਾਡੇ ਕੋਲ <xliff:g id="_NUMBER_1">%d</xliff:g> ਕੋਸ਼ਿਸ਼ ਬਾਕੀ ਹੈ। ਵੇਰਵਿਆਂ ਲਈ ਕੈਰੀਅਰ ਨੂੰ ਸੰਪਰਕ ਕਰੋ।</item>
       <item quantity="other">ਸਿਮ ਹੁਣ ਬੰਦ ਹੋ ਗਿਆ ਹੈ। ਜਾਰੀ ਰੱਖਣ ਲਈ PUK ਕੋਡ ਦਾਖਲ ਕਰੋ। ਸਿਮ ਦੇ ਪੱਕੇ ਤੌਰ \'ਤੇ ਬੇਕਾਰ ਹੋ ਜਾਣ ਤੋਂ ਪਹਿਲਾਂ ਤੁਹਾਡੇ ਕੋਲ <xliff:g id="_NUMBER_1">%d</xliff:g> ਕੋਸ਼ਿਸ਼ਾਂ ਬਾਕੀ ਹਨ। ਵੇਰਵਿਆਂ ਲਈ ਕੈਰੀਅਰ ਨੂੰ ਸੰਪਰਕ ਕਰੋ।</item>
     </plurals>
-    <string name="clock_title_default" msgid="6342735240617459864">"ਪੂਰਵ-ਨਿਰਧਾਰਤ"</string>
+    <string name="clock_title_default" msgid="6342735240617459864">"ਪੂਰਵ-ਨਿਰਧਾਰਿਤ"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"ਬੁਲਬੁਲਾ"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"ਐਨਾਲੌਗ"</string>
 </resources>
diff --git a/packages/SystemUI/res-product/values-iw/strings.xml b/packages/SystemUI/res-product/values-iw/strings.xml
index 4ba8657..3fc8013 100644
--- a/packages/SystemUI/res-product/values-iw/strings.xml
+++ b/packages/SystemUI/res-product/values-iw/strings.xml
@@ -31,15 +31,15 @@
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="8710104080409538587">"ניסית לבטל את נעילת הטאבלט <xliff:g id="NUMBER">%d</xliff:g> פעמים. הטאבלט יאופס וכל הנתונים שלו יימחקו."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="6381835450014881813">"ניסית לבטל את נעילת הטלפון <xliff:g id="NUMBER">%d</xliff:g> פעמים. הטלפון יאופס וכל הנתונים שבו יימחקו."</string>
     <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="7325071812832605911">"ניסית לבטל את נעילת הטאבלט <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%2$d</xliff:g> ניסיונות כושלים נוספים, משתמש זה יוסר וכל נתוני המשתמש יימחקו."</string>
-    <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="8110939900089863103">"ניסית לבטל את נעילת הטלפון <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%2$d</xliff:g> ניסיונות כושלים נוספים, משתמש זה יוסר וכל נתוני המשתמש יימחקו."</string>
+    <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="8110939900089863103">"ניסית לבטל את נעילת הטלפון <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%2$d</xliff:g> ניסיונות כושלים נוספים, המשתמש הזה יוסר וכל נתוני המשתמש יימחקו."</string>
     <string name="kg_failed_attempts_now_erasing_user" product="tablet" msgid="8509811676952707883">"ניסית לבטל את נעילת הטאבלט <xliff:g id="NUMBER">%d</xliff:g> פעמים באופן שגוי. משתמש זה יוסר וכל נתוני המשתמש יימחקו."</string>
-    <string name="kg_failed_attempts_now_erasing_user" product="default" msgid="3051962486994265014">"ניסית לבטל את נעילת הטלפון <xliff:g id="NUMBER">%d</xliff:g> פעמים. משתמש זה יוסר וכל נתוני המשתמש יימחקו."</string>
+    <string name="kg_failed_attempts_now_erasing_user" product="default" msgid="3051962486994265014">"ניסית לבטל את נעילת הטלפון <xliff:g id="NUMBER">%d</xliff:g> פעמים. המשתמש הזה יוסר וכל נתוני המשתמש יימחקו."</string>
     <string name="kg_failed_attempts_almost_at_erase_profile" product="tablet" msgid="1049523640263353830">"ניסית לבטל את נעילת הטאבלט <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%2$d</xliff:g> ניסיונות כושלים נוספים, פרופיל העבודה יוסר וכל נתוני הפרופיל יימחקו."</string>
     <string name="kg_failed_attempts_almost_at_erase_profile" product="default" msgid="3280816298678433681">"ניסית לבטל את נעילת הטלפון <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%2$d</xliff:g> ניסיונות כושלים נוספים, פרופיל העבודה יוסר וכל נתוני הפרופיל יימחקו."</string>
     <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="4417100487251371559">"ניסית לבטל את נעילת הטאבלט <xliff:g id="NUMBER">%d</xliff:g> פעמים. פרופיל העבודה יוסר וכל נתוני הפרופיל יימחקו."</string>
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"ניסית לבטל את נעילת הטלפון <xliff:g id="NUMBER">%d</xliff:g> פעמים. פרופיל העבודה יוסר וכל נתוני הפרופיל יימחקו."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"שרטטת קו ביטול נעילה שגוי <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%2$d</xliff:g> ניסיונות כושלים נוספים, ,תישלח אליך בקשה לבטל את נעילת הטאבלט באמצעות חשבון אימייל‏.\n\n יש לנסות שוב בעוד <xliff:g id="NUMBER_2">%3$d</xliff:g> שניות."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"שרטטת קו ביטול נעילה שגוי <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%2$d</xliff:g> ניסיונות כושלים נוספים, תשילח אליך בקשה לבטל את נעילת הטלפון באמצעות חשבון אימייל‏.\n\n יש לנסות שוב בעוד <xliff:g id="NUMBER_2">%3$d</xliff:g> שניות."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"שרטטת קו ביטול נעילה שגוי <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%2$d</xliff:g> ניסיונות כושלים נוספים, תישלח אליך בקשה לבטל את נעילת הטלפון באמצעות חשבון אימייל‏.\n\n יש לנסות שוב בעוד <xliff:g id="NUMBER_2">%3$d</xliff:g> שניות."</string>
     <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"לאפשרויות נוספות, יש לבטל את נעילת הטלפון"</string>
     <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"לאפשרויות נוספות, יש לבטל את נעילת הטאבלט"</string>
     <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"לאפשרויות נוספות, יש לבטל את נעילת המכשיר"</string>
diff --git a/packages/SystemUI/res/color/remote_input_hint.xml b/packages/SystemUI/res/color/remote_input_hint.xml
new file mode 100644
index 0000000..7fe58db
--- /dev/null
+++ b/packages/SystemUI/res/color/remote_input_hint.xml
@@ -0,0 +1,19 @@
+<!--
+  ~ 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.
+  -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:color="?android:attr/textColorPrimary" android:alpha=".6" />
+</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/color/remote_input_text.xml b/packages/SystemUI/res/color/remote_input_text.xml
index 33eeb77..3622c91 100644
--- a/packages/SystemUI/res/color/remote_input_text.xml
+++ b/packages/SystemUI/res/color/remote_input_text.xml
@@ -16,6 +16,6 @@
   -->
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_enabled="true" android:color="?android:attr/textColorTertiary" />
-    <item android:color="?android:attr/textColorTertiary" android:alpha=".6" />
+    <item android:state_enabled="true" android:color="?android:attr/textColorPrimary" />
+    <item android:color="?android:attr/textColorPrimary" android:alpha=".6" />
 </selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable-television/volume_row_seekbar.xml b/packages/SystemUI/res/drawable-television/volume_row_seekbar.xml
new file mode 100644
index 0000000..e49fc15
--- /dev/null
+++ b/packages/SystemUI/res/drawable-television/volume_row_seekbar.xml
@@ -0,0 +1,37 @@
+<?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.
+-->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
+            android:paddingMode="stack">
+    <item android:id="@android:id/background"
+        android:gravity="center_vertical|fill_horizontal">
+        <layer-list>
+            <item android:id="@+id/volume_seekbar_background_solid">
+                <shape>
+                    <size android:height="@dimen/volume_dialog_slider_width" />
+                    <solid android:color="@color/tv_volume_dialog_seek_bar_background"/>
+                    <corners android:radius="@dimen/volume_dialog_slider_corner_radius" />
+                </shape>
+            </item>
+        </layer-list>
+    </item>
+    <item android:id="@android:id/progress"
+          android:gravity="center_vertical|fill_horizontal">
+            <com.android.systemui.util.RoundedCornerProgressDrawable
+                android:drawable="@drawable/volume_row_seekbar_progress"
+            />
+    </item>
+</layer-list>
diff --git a/packages/SystemUI/res/drawable-television/volume_row_seekbar_progress.xml b/packages/SystemUI/res/drawable-television/volume_row_seekbar_progress.xml
new file mode 100644
index 0000000..bce193a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-television/volume_row_seekbar_progress.xml
@@ -0,0 +1,29 @@
+<?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.
+  -->
+
+<!-- Progress drawable for volume row SeekBars. This is the accent-colored round rect that moves up
+     and down as the progress value changes. -->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
+    android:autoMirrored="true">
+    <item android:id="@+id/volume_seekbar_progress_solid">
+        <shape android:shape="rectangle">
+            <size android:height="@dimen/volume_dialog_slider_width"/>
+            <solid android:color="@color/tv_volume_dialog_seek_bar_fill" />
+            <corners android:radius="@dimen/volume_dialog_slider_width" />
+        </shape>
+    </item>
+</layer-list>
diff --git a/packages/SystemUI/res/drawable/notif_footer_btn_background.xml b/packages/SystemUI/res/drawable/notif_footer_btn_background.xml
new file mode 100644
index 0000000..f35f5d1
--- /dev/null
+++ b/packages/SystemUI/res/drawable/notif_footer_btn_background.xml
@@ -0,0 +1,30 @@
+<?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.
+  -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <solid
+        android:color="@color/notif_pill_background"
+        />
+    <corners android:radius="20dp" />
+
+    <padding
+        android:left="20dp"
+        android:right="20dp">
+    </padding>
+
+</shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/people_space_messages_count_background.xml b/packages/SystemUI/res/drawable/people_space_messages_count_background.xml
new file mode 100644
index 0000000..0fc112e
--- /dev/null
+++ b/packages/SystemUI/res/drawable/people_space_messages_count_background.xml
@@ -0,0 +1,20 @@
+<?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.
+  -->
+<shape xmlns:android="http://schemas.android.com/apk/res/android" >
+    <solid android:color="#9ED582" />
+    <corners android:radius="@dimen/people_space_messages_count_radius" />
+</shape>
diff --git a/packages/SystemUI/res/drawable/privacy_chip_bg.xml b/packages/SystemUI/res/drawable/privacy_chip_bg.xml
index 109442d..9f41dbe 100644
--- a/packages/SystemUI/res/drawable/privacy_chip_bg.xml
+++ b/packages/SystemUI/res/drawable/privacy_chip_bg.xml
@@ -16,6 +16,6 @@
 -->
 
 <shape xmlns:android="http://schemas.android.com/apk/res/android">
-    <solid android:color="#FFFFFF" />
+    <solid android:color="@color/privacy_circle" />
     <corners android:radius="@dimen/ongoing_appops_chip_bg_corner_radius" />
 </shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/privacy_item_circle_camera.xml b/packages/SystemUI/res/drawable/privacy_item_circle_camera.xml
index 5cb6f46..54a66e2 100644
--- a/packages/SystemUI/res/drawable/privacy_item_circle_camera.xml
+++ b/packages/SystemUI/res/drawable/privacy_item_circle_camera.xml
@@ -24,7 +24,7 @@
                 android:height="@dimen/ongoing_appops_dialog_circle_size"
                 android:width="@dimen/ongoing_appops_dialog_circle_size"
             />
-            <solid android:color="@color/privacy_circle_camera" />
+            <solid android:color="@color/privacy_circle" />
         </shape>
     </item>
     <item android:id="@id/icon"
diff --git a/packages/SystemUI/res/drawable/privacy_item_circle_location.xml b/packages/SystemUI/res/drawable/privacy_item_circle_location.xml
index bff9b4b..65f4396 100644
--- a/packages/SystemUI/res/drawable/privacy_item_circle_location.xml
+++ b/packages/SystemUI/res/drawable/privacy_item_circle_location.xml
@@ -24,7 +24,7 @@
                 android:height="@dimen/ongoing_appops_dialog_circle_size"
                 android:width="@dimen/ongoing_appops_dialog_circle_size"
             />
-            <solid android:color="@color/privacy_circle_microphone_location" />
+            <solid android:color="@color/privacy_circle" />
         </shape>
     </item>
     <item android:id="@id/icon"
diff --git a/packages/SystemUI/res/drawable/privacy_item_circle_microphone.xml b/packages/SystemUI/res/drawable/privacy_item_circle_microphone.xml
index 28466c8..1565d2d 100644
--- a/packages/SystemUI/res/drawable/privacy_item_circle_microphone.xml
+++ b/packages/SystemUI/res/drawable/privacy_item_circle_microphone.xml
@@ -24,7 +24,7 @@
                 android:height="@dimen/ongoing_appops_dialog_circle_size"
                 android:width="@dimen/ongoing_appops_dialog_circle_size"
             />
-            <solid android:color="@color/privacy_circle_microphone_location" />
+            <solid android:color="@color/privacy_circle" />
         </shape>
     </item>
     <item android:id="@id/icon"
diff --git a/packages/SystemUI/res/drawable/remote_input_view_text_bg.xml b/packages/SystemUI/res/drawable/remote_input_view_text_bg.xml
new file mode 100644
index 0000000..5d374a9
--- /dev/null
+++ b/packages/SystemUI/res/drawable/remote_input_view_text_bg.xml
@@ -0,0 +1,31 @@
+<!--
+  ~ 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.
+  -->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+
+    <solid android:color="?android:attr/colorBackgroundFloating" />
+    <stroke
+        android:width="@dimen/remote_input_view_text_stroke"
+        android:color="?android:attr/colorAccent"/>
+    <padding
+        android:bottom="12dp"
+        android:left="12dp"
+        android:right="12dp"
+        android:top="12dp"/>
+
+    <corners android:radius="24dp" />
+
+</shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/tv_volume_row_seek_bar.xml b/packages/SystemUI/res/drawable/tv_volume_row_seek_bar.xml
deleted file mode 100644
index fe76b63..0000000
--- a/packages/SystemUI/res/drawable/tv_volume_row_seek_bar.xml
+++ /dev/null
@@ -1,32 +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.
--->
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:id="@android:id/background">
-        <shape android:shape="rectangle">
-            <solid android:color="@color/tv_volume_dialog_seek_bar_background" />
-            <corners android:radius="@dimen/tv_volume_seek_bar_width" />
-        </shape>
-    </item>
-    <item android:id="@android:id/progress">
-        <clip>
-            <shape android:shape="rectangle">
-                <solid android:color="@color/tv_volume_dialog_seek_bar_fill" />
-                <corners android:radius="@dimen/tv_volume_seek_bar_width" />
-            </shape>
-        </clip>
-    </item>
-</layer-list>
diff --git a/packages/SystemUI/res/drawable/volume_row_seekbar.xml b/packages/SystemUI/res/drawable/volume_row_seekbar.xml
index b0e0ed5..a845e73 100644
--- a/packages/SystemUI/res/drawable/volume_row_seekbar.xml
+++ b/packages/SystemUI/res/drawable/volume_row_seekbar.xml
@@ -25,9 +25,9 @@
         <layer-list>
             <item android:id="@+id/volume_seekbar_background_solid">
                 <shape>
-                    <size android:height="@dimen/volume_dialog_panel_width" />
+                    <size android:height="@dimen/volume_dialog_slider_width" />
                     <solid android:color="?android:attr/colorBackgroundFloating" />
-                    <corners android:radius="@dimen/volume_dialog_panel_width_half" />
+                    <corners android:radius="@dimen/volume_dialog_slider_corner_radius" />
                 </shape>
             </item>
             <item
@@ -53,4 +53,4 @@
                 android:drawable="@drawable/volume_row_seekbar_progress"
             />
     </item>
-</layer-list>
\ No newline at end of file
+</layer-list>
diff --git a/packages/SystemUI/res/layout-land-television/volume_dialog_row.xml b/packages/SystemUI/res/layout-land-television/volume_dialog_row.xml
index 4f6cb01..0dec981 100644
--- a/packages/SystemUI/res/layout-land-television/volume_dialog_row.xml
+++ b/packages/SystemUI/res/layout-land-television/volume_dialog_row.xml
@@ -17,7 +17,7 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:tag="row"
     android:layout_width="wrap_content"
-    android:layout_height="@dimen/volume_dialog_row_height"
+    android:layout_height="@dimen/volume_dialog_panel_height"
     android:background="@android:color/transparent"
     android:clipChildren="false"
     android:clipToPadding="false"
@@ -54,18 +54,18 @@
         <FrameLayout
             android:id="@+id/volume_row_slider_frame"
             android:layout_width="match_parent"
-            android:layout_height="@dimen/volume_dialog_row_height">
+            android:layout_height="@dimen/volume_dialog_panel_height">
             <SeekBar
                 android:id="@+id/volume_row_slider"
                 android:clickable="false"
-                android:layout_width="@dimen/volume_dialog_row_height"
+                android:layout_width="@dimen/volume_dialog_panel_height"
                 android:layout_height="match_parent"
                 android:layout_gravity="center"
                 android:layoutDirection="ltr"
-                android:maxHeight="@dimen/tv_volume_seek_bar_width"
-                android:minHeight="@dimen/tv_volume_seek_bar_width"
+                android:maxHeight="@dimen/volume_dialog_slider_width"
+                android:minHeight="@dimen/volume_dialog_slider_width"
+                android:progressDrawable="@drawable/volume_row_seekbar"
                 android:thumb="@drawable/tv_volume_row_seek_thumb"
-                android:progressDrawable="@drawable/tv_volume_row_seek_bar"
                 android:splitTrack="false"
                 android:rotation="270" />
         </FrameLayout>
diff --git a/packages/SystemUI/res/layout/long_screenshot.xml b/packages/SystemUI/res/layout/long_screenshot.xml
index 19bcf95..6d44138c 100644
--- a/packages/SystemUI/res/layout/long_screenshot.xml
+++ b/packages/SystemUI/res/layout/long_screenshot.xml
@@ -48,10 +48,10 @@
 
     <ImageView
         android:id="@+id/preview"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
+        android:layout_width="0px"
+        android:layout_height="0px"
         android:layout_marginBottom="42dp"
-        android:layout_marginHorizontal="48dp"
+        android:paddingHorizontal="48dp"
         app:layout_constrainedHeight="true"
         app:layout_constrainedWidth="true"
         app:layout_constraintTop_toBottomOf="@id/save"
@@ -64,8 +64,8 @@
 
     <com.android.systemui.screenshot.CropView
         android:id="@+id/crop_view"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
+        android:layout_width="0px"
+        android:layout_height="0px"
         android:layout_marginBottom="42dp"
         app:layout_constrainedHeight="true"
         app:layout_constrainedWidth="true"
diff --git a/packages/SystemUI/res/layout/people_space_small_view.xml b/packages/SystemUI/res/layout/people_tile_large_empty.xml
similarity index 63%
copy from packages/SystemUI/res/layout/people_space_small_view.xml
copy to packages/SystemUI/res/layout/people_tile_large_empty.xml
index 7b1abae..1e00307 100644
--- a/packages/SystemUI/res/layout/people_space_small_view.xml
+++ b/packages/SystemUI/res/layout/people_tile_large_empty.xml
@@ -20,40 +20,48 @@
     <LinearLayout
         android:id="@+id/item"
         android:layout_width="match_parent"
-        android:layout_height="wrap_content"
+        android:layout_height="match_parent"
         android:layout_gravity="center"
+        android:gravity="center"
         android:background="@drawable/people_space_tile_view_card"
         android:orientation="vertical"
-        android:paddingHorizontal="4dp"
-        android:paddingVertical="8dp">
+        android:paddingHorizontal="16dp"
+        android:paddingVertical="16dp">
 
         <ImageView
             android:id="@+id/person_icon"
             android:layout_gravity="center"
             android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="1" />
-
-        <ImageView
-            android:id="@+id/predefined_icon"
-            android:layout_gravity="center"
-            android:paddingTop="4dp"
-            android:layout_width="18dp"
-            android:layout_height="22dp"
-            android:layout_weight="1" />
+            android:layout_height="wrap_content" />
 
         <TextView
             android:id="@+id/name"
             android:layout_gravity="center"
-            android:paddingTop="4dp"
+            android:paddingTop="14dp"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:layout_weight="1"
             android:ellipsize="end"
-            android:maxLines="1"
-            android:paddingHorizontal="8dp"
+            android:singleLine="true"
             android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem"
             android:textColor="?android:attr/textColorPrimary"
-            android:textSize="14sp" />
+            android:textSize="16sp" />
+        <TextView
+            android:id="@+id/last_interaction"
+            android:layout_gravity="center"
+            android:text="@string/empty_status"
+            android:textColor="?android:attr/textColorSecondary"
+            android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem"
+            android:textSize="14sp"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:ellipsize="end"
+            android:singleLine="true"/>
+        <ImageView
+            android:id="@+id/availability"
+            android:layout_gravity="center"
+            android:layout_width="10dp"
+            android:layout_height="26dp"
+            android:paddingTop="16dp"
+            android:background="@drawable/circle_green_10dp"/>
     </LinearLayout>
 </FrameLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/people_tile_large_with_content.xml b/packages/SystemUI/res/layout/people_tile_large_with_content.xml
new file mode 100644
index 0000000..9990244
--- /dev/null
+++ b/packages/SystemUI/res/layout/people_tile_large_with_content.xml
@@ -0,0 +1,132 @@
+<?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.
+ -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/item"
+    android:background="@drawable/people_space_tile_view_card"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:layout_gravity="center"
+    android:padding="16dp"
+    android:orientation="vertical">
+
+    <RelativeLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:gravity="start|top">
+
+        <LinearLayout
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentStart="true"
+            android:gravity="start|top"
+            android:orientation="horizontal">
+
+            <ImageView
+                android:id="@+id/person_icon"
+                android:layout_marginStart="-2dp"
+                android:layout_marginTop="-2dp"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_weight="1" />
+
+            <ImageView
+                android:id="@+id/availability"
+                android:layout_marginStart="-2dp"
+                android:layout_width="10dp"
+                android:layout_height="10dp"
+                android:background="@drawable/circle_green_10dp" />
+        </LinearLayout>
+
+        <TextView
+            android:id="@+id/messages_count"
+            android:layout_alignParentEnd="true"
+            android:paddingStart="8dp"
+            android:paddingEnd="8dp"
+            android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem"
+            android:textColor="?android:attr/textColorPrimary"
+            android:background="@drawable/people_space_messages_count_background"
+            android:textSize="14sp"
+            android:maxLines="1"
+            android:ellipsize="end"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:visibility="gone"
+            />
+    </RelativeLayout>
+
+    <TextView
+        android:layout_gravity="center"
+        android:id="@+id/name"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingBottom="12dp"
+        android:gravity="start"
+        android:singleLine="true"
+        android:ellipsize="end"
+        android:text="@string/empty_user_name"
+        android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem"
+        android:textColor="?android:attr/textColorPrimary"
+        android:textSize="14sp" />
+
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:paddingBottom="4dp"
+        android:gravity="center_vertical"
+        android:orientation="horizontal">
+
+        <ImageView
+            android:id="@+id/predefined_icon"
+            android:gravity="start|center_vertical"
+            android:paddingEnd="6dp"
+            android:layout_width="24dp"
+            android:layout_height="18dp" />
+
+        <TextView
+            android:layout_gravity="center"
+            android:id="@+id/subtext"
+            android:gravity="center_vertical"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:ellipsize="end"
+            android:singleLine="true"
+            android:text="@string/empty_user_name"
+            android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem"
+            android:textColor="?android:attr/textColorSecondary"
+            android:textSize="12sp" />
+    </LinearLayout>
+
+    <ImageView
+        android:id="@+id/image"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:background="@drawable/people_space_content_background"
+        android:gravity="center"
+        android:scaleType="centerCrop" />
+
+    <TextView
+        android:layout_gravity="center"
+        android:id="@+id/text_content"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:ellipsize="end"
+        android:maxLines="2"
+        android:singleLine="false"
+        android:text="@string/empty_status"
+        android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem"
+        android:textColor="?android:attr/textColorPrimary"
+        android:textSize="12sp" />
+</LinearLayout>
diff --git a/packages/SystemUI/res/layout/people_space_large_avatar_tile.xml b/packages/SystemUI/res/layout/people_tile_medium_empty.xml
similarity index 94%
rename from packages/SystemUI/res/layout/people_space_large_avatar_tile.xml
rename to packages/SystemUI/res/layout/people_tile_medium_empty.xml
index b1a37bf..c35787e 100644
--- a/packages/SystemUI/res/layout/people_space_large_avatar_tile.xml
+++ b/packages/SystemUI/res/layout/people_tile_medium_empty.xml
@@ -35,16 +35,17 @@
             android:layout_height="match_parent">
             <ImageView
                 android:id="@+id/person_icon"
-                android:layout_width="60dp"
-                android:layout_height="60dp"/>
+                android:layout_width="64dp"
+                android:layout_height="64dp"/>
             <ImageView
                 android:id="@+id/availability"
+                android:layout_marginStart="-2dp"
                 android:layout_width="10dp"
                 android:layout_height="10dp"
                 android:background="@drawable/circle_green_10dp"/>
             <LinearLayout
                 android:orientation="vertical"
-                android:paddingStart="4dp"
+                android:paddingStart="6dp"
                 android:gravity="top"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content">
diff --git a/packages/SystemUI/res/layout/people_space_small_avatar_tile.xml b/packages/SystemUI/res/layout/people_tile_medium_with_content.xml
similarity index 66%
rename from packages/SystemUI/res/layout/people_space_small_avatar_tile.xml
rename to packages/SystemUI/res/layout/people_tile_medium_with_content.xml
index 6a606e1..db1d46d 100644
--- a/packages/SystemUI/res/layout/people_space_small_avatar_tile.xml
+++ b/packages/SystemUI/res/layout/people_tile_medium_with_content.xml
@@ -27,28 +27,37 @@
         android:layout_gravity="center"
         android:padding="8dp"
         android:layout_width="match_parent"
-        android:layout_height="wrap_content">
+        android:layout_height="match_parent">
+
         <LinearLayout
             android:orientation="horizontal"
             android:gravity="top"
+            android:layout_weight="1"
             android:layout_width="match_parent"
-            android:layout_height="wrap_content">
-                <ImageView
-                    android:gravity="start"
-                    android:id="@+id/person_icon"
-                    android:layout_width="56dp"
-                    android:layout_height="56dp"/>
+            android:layout_height="0dp">
+
+            <ImageView
+                android:gravity="start"
+                android:id="@+id/person_icon"
+                android:layout_marginStart="-2dp"
+                android:layout_marginTop="-2dp"
+                android:layout_width="52dp"
+                android:layout_height="52dp" />
+
             <ImageView
                 android:id="@+id/availability"
+                android:layout_marginStart="-2dp"
                 android:layout_width="10dp"
                 android:layout_height="10dp"
-                android:background="@drawable/circle_green_10dp"/>
+                android:background="@drawable/circle_green_10dp" />
+
             <LinearLayout
                 android:orientation="vertical"
                 android:gravity="top|start"
                 android:paddingStart="12dp"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content">
+
                 <TextView
                     android:id="@+id/subtext"
                     android:text="@string/empty_user_name"
@@ -58,41 +67,39 @@
                     android:paddingBottom="4dp"
                     android:layout_width="match_parent"
                     android:layout_height="wrap_content"
-                    android:ellipsize="end"/>
-            <LinearLayout
-                android:id="@+id/content_background"
-                android:background="@drawable/people_space_content_background"
-                android:layout_width="match_parent"
-                android:layout_height="match_parent">
+                    android:singleLine="true"
+                    android:ellipsize="end" />
+
                 <ImageView
                     android:id="@+id/image"
                     android:gravity="center"
                     android:background="@drawable/people_space_content_background"
                     android:layout_width="match_parent"
+                    android:layout_height="match_parent"
+                    android:scaleType="centerCrop" />
+
+                <TextView
+                    android:id="@+id/text_content"
+                    android:text="@string/empty_status"
+                    android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem"
+                    android:textColor="?android:attr/textColorPrimary"
+                    android:textSize="12sp"
+                    android:layout_width="match_parent"
                     android:layout_height="wrap_content"
-                    android:scaleType="centerCrop"/>
-            </LinearLayout>
-            <TextView
-                android:id="@+id/text_content"
-                android:text="@string/empty_status"
-                android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem"
-                android:textColor="?android:attr/textColorPrimary"
-                android:textSize="12sp"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:maxLines="2"
-                android:singleLine="false"
-                android:ellipsize="end"/>
+                    android:maxLines="2"
+                    android:singleLine="false"
+                    android:ellipsize="end" />
             </LinearLayout>
         </LinearLayout>
+
         <LinearLayout
             android:gravity="bottom"
+            android:layout_gravity="center_vertical"
             android:orientation="horizontal"
             android:paddingTop="4dp"
-            android:layout_weight="1"
             android:layout_width="match_parent"
-            android:layout_height="wrap_content">
-
+            android:layout_height="wrap_content"
+            android:clipToOutline="true">
             <TextView
                 android:id="@+id/name"
                 android:gravity="center_vertical"
@@ -101,16 +108,31 @@
                 android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem"
                 android:textColor="?android:attr/textColorPrimary"
                 android:textSize="14sp"
+                android:singleLine="true"
+                android:ellipsize="end"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content" />
+            <TextView
+                android:id="@+id/messages_count"
+                android:gravity="end"
+                android:paddingStart="8dp"
+                android:paddingEnd="8dp"
+                android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem"
+                android:textColor="?android:attr/textColorPrimary"
+                android:background="@drawable/people_space_messages_count_background"
+                android:textSize="14sp"
                 android:maxLines="1"
                 android:ellipsize="end"
                 android:layout_width="wrap_content"
-                android:layout_height="wrap_content"/>
+                android:layout_height="wrap_content"
+                android:visibility="gone"
+                />
             <ImageView
                 android:id="@+id/predefined_icon"
-                android:gravity="end"
+                android:gravity="end|center_vertical"
                 android:paddingStart="6dp"
                 android:layout_width="24dp"
-                android:layout_height="18dp"/>
+                android:layout_height="18dp" />
         </LinearLayout>
     </LinearLayout>
 </LinearLayout>
diff --git a/packages/SystemUI/res/layout/people_space_small_view.xml b/packages/SystemUI/res/layout/people_tile_small.xml
similarity index 69%
rename from packages/SystemUI/res/layout/people_space_small_view.xml
rename to packages/SystemUI/res/layout/people_tile_small.xml
index 7b1abae..f0ab187 100644
--- a/packages/SystemUI/res/layout/people_space_small_view.xml
+++ b/packages/SystemUI/res/layout/people_tile_small.xml
@@ -25,33 +25,50 @@
         android:background="@drawable/people_space_tile_view_card"
         android:orientation="vertical"
         android:paddingHorizontal="4dp"
-        android:paddingVertical="8dp">
+        android:paddingTop="6dp"
+        android:paddingBottom="8dp">
 
         <ImageView
             android:id="@+id/person_icon"
             android:layout_gravity="center"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:layout_weight="1" />
+            android:layout_weight="1"
+            android:paddingBottom="4dp"/>
 
         <ImageView
             android:id="@+id/predefined_icon"
             android:layout_gravity="center"
-            android:paddingTop="4dp"
             android:layout_width="18dp"
             android:layout_height="22dp"
             android:layout_weight="1" />
 
         <TextView
+            android:id="@+id/messages_count"
+            android:layout_gravity="center"
+            android:paddingStart="8dp"
+            android:paddingEnd="8dp"
+            android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem"
+            android:textColor="?android:attr/textColorPrimary"
+            android:background="@drawable/people_space_messages_count_background"
+            android:textSize="14sp"
+            android:maxLines="1"
+            android:ellipsize="end"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:visibility="gone"
+            android:layout_weight="1"
+            />
+
+        <TextView
             android:id="@+id/name"
             android:layout_gravity="center"
-            android:paddingTop="4dp"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_weight="1"
             android:ellipsize="end"
             android:maxLines="1"
-            android:paddingHorizontal="8dp"
+            android:paddingHorizontal="4dp"
             android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem"
             android:textColor="?android:attr/textColorPrimary"
             android:textSize="14sp" />
diff --git a/packages/SystemUI/res/layout/quick_qs_status_icons.xml b/packages/SystemUI/res/layout/quick_qs_status_icons.xml
index 44f52ef..bbf69a9 100644
--- a/packages/SystemUI/res/layout/quick_qs_status_icons.xml
+++ b/packages/SystemUI/res/layout/quick_qs_status_icons.xml
@@ -18,32 +18,52 @@
     xmlns:systemui="http://schemas.android.com/apk/res-auto"
     android:id="@+id/quick_qs_status_icons"
     android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:paddingTop="@dimen/qs_header_top_padding"
-    android:paddingBottom="@dimen/qs_header_bottom_padding"
-    android:layout_below="@id/quick_status_bar_system_icons"
+    android:layout_height="@*android:dimen/quick_qs_offset_height"
     android:clipChildren="false"
     android:clipToPadding="false"
-    android:minHeight="20dp"
+    android:minHeight="48dp"
     android:clickable="false"
     android:focusable="true"
     android:theme="@style/QSHeaderTheme">
 
-    <com.android.systemui.statusbar.policy.DateView
-        android:id="@+id/date"
+    <com.android.systemui.statusbar.policy.Clock
+        android:id="@+id/clock"
         android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="start|center_vertical"
-        android:gravity="center_vertical"
+        android:layout_height="match_parent"
+        android:minWidth="48dp"
+        android:minHeight="48dp"
+        android:gravity="center_vertical|start"
+        android:paddingStart="@dimen/status_bar_left_clock_starting_padding"
+        android:paddingEnd="@dimen/status_bar_left_clock_end_padding"
         android:singleLine="true"
-        android:textAppearance="@style/TextAppearance.QS.Status"
-        systemui:datePattern="@string/abbrev_wday_month_day_no_year_alarm" />
+        android:textAppearance="@style/TextAppearance.StatusBar.Clock" />
+
+    <View
+        android:layout_height="match_parent"
+        android:layout_width="0dp"
+        android:layout_weight="1"
+        />
+
+    <!-- Will hold security footer in landscape with media -->
+    <FrameLayout
+        android:id="@+id/header_text_container"
+        android:layout_height="match_parent"
+        android:layout_width="wrap_content"
+        android:gravity="center"
+        />
+
+    <include layout="@layout/qs_carrier_group"
+        android:id="@+id/carrier_group"
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:minHeight="48dp"
+        android:layout_gravity="end|center_vertical"
+        android:focusable="false"/>
 
     <com.android.systemui.statusbar.phone.StatusIconContainer
         android:id="@+id/statusIcons"
-        android:layout_width="0dp"
+        android:layout_width="wrap_content"
         android:layout_height="match_parent"
-        android:layout_weight="1"
         android:paddingEnd="@dimen/signal_cluster_battery_padding" />
 
     <com.android.systemui.BatteryMeterView
diff --git a/packages/SystemUI/res/layout/quick_settings_header_info.xml b/packages/SystemUI/res/layout/quick_settings_header_info.xml
deleted file mode 100644
index fb82304..0000000
--- a/packages/SystemUI/res/layout/quick_settings_header_info.xml
+++ /dev/null
@@ -1,101 +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
-  -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/header_text_container"
-    android:layout_width="match_parent"
-    android:layout_height="@dimen/qs_header_tooltip_height"
-    android:layout_below="@id/quick_status_bar_system_icons"
-    android:visibility="invisible"
-    android:theme="@style/QSHeaderTheme"
-    android:forceHasOverlappingRendering="false">
-
-        <com.android.systemui.qs.QSHeaderInfoLayout
-            android:id="@+id/status_container"
-            android:layout_width="0dp"
-            android:layout_weight="1"
-            android:layout_height="match_parent">
-
-            <LinearLayout
-                android:id = "@+id/alarm_container"
-                android:layout_width="wrap_content"
-                android:layout_height="match_parent"
-                android:gravity="center_vertical"
-                android:focusable="true"
-                android:clickable="true">
-
-                <ImageView
-                    android:id="@+id/next_alarm_icon"
-                    android:layout_width="@dimen/qs_header_alarm_icon_size"
-                    android:layout_height="@dimen/qs_header_alarm_icon_size"
-                    android:src="@drawable/ic_alarm"
-                    android:contentDescription="@string/accessibility_quick_settings_alarm_set"
-                    android:visibility="gone"/>
-
-                <com.android.systemui.util.AutoMarqueeTextView
-                    android:id="@+id/next_alarm_text"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:singleLine="true"
-                    android:ellipsize="marquee"
-                    android:marqueeRepeatLimit="marquee_forever"
-                    android:layout_marginStart="@dimen/qs_header_alarm_text_margin_start"
-                    android:textAppearance="@style/TextAppearance.QS.Status"
-                    android:visibility="gone"/>
-            </LinearLayout>
-
-            <View
-                android:id="@+id/status_separator"
-                android:layout_width="@dimen/qs_header_separator_width"
-                android:layout_height="match_parent"
-                android:visibility="gone"/>
-
-            <LinearLayout
-                android:id = "@+id/ringer_container"
-                android:layout_width="wrap_content"
-                android:layout_height="match_parent"
-                android:gravity="center_vertical"
-                android:focusable="true"
-                android:clickable="true">
-
-                <ImageView
-                    android:id="@+id/ringer_mode_icon"
-                    android:layout_width="@dimen/qs_header_alarm_icon_size"
-                    android:layout_height="@dimen/qs_header_alarm_icon_size"
-                    android:visibility="gone"/>
-
-                <com.android.systemui.util.AutoMarqueeTextView
-                    android:id="@+id/ringer_mode_text"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:singleLine="true"
-                    android:ellipsize="marquee"
-                    android:marqueeRepeatLimit="marquee_forever"
-                    android:layout_marginStart="@dimen/qs_header_alarm_text_margin_start"
-                    android:textAppearance="@style/TextAppearance.QS.Status"
-                    android:visibility="gone"/>
-            </LinearLayout>
-        </com.android.systemui.qs.QSHeaderInfoLayout>
-
-        <include layout="@layout/qs_carrier_group"
-                 android:id="@+id/carrier_group"
-                 android:layout_width="wrap_content"
-                 android:layout_height="match_parent"
-                 android:layout_marginStart="@dimen/qs_status_separator"
-                 android:layout_gravity="end|center_vertical"
-                 android:focusable="false"/>
-
-</LinearLayout>
diff --git a/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml b/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
index 059bda3..5bf6919 100644
--- a/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
+++ b/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
@@ -32,26 +32,32 @@
     android:paddingStart="0dp"
     android:elevation="4dp" >
 
-    <!-- The clock -->
-    <include layout="@layout/quick_status_bar_header_system_icons" />
+    <!-- Date and privacy. Only visible in QS -->
+    <include layout="@layout/quick_status_bar_header_date_privacy"/>
 
-    <!-- Status icons within the panel itself (and not in the top-most status bar) -->
-    <include layout="@layout/quick_qs_status_icons" />
-
-    <!-- Layout containing tooltips, alarm text, etc. -->
-    <include layout="@layout/quick_settings_header_info" />
+    <RelativeLayout
+        android:id="@+id/container"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="top"
+        android:clipChildren="false"
+        android:clipToPadding="false">
+    <!-- Time, icons and Carrier (only in QS) -->
+    <include layout="@layout/quick_qs_status_icons"/>
 
     <com.android.systemui.qs.QuickQSPanel
         android:id="@+id/quick_qs_panel"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_below="@id/quick_qs_status_icons"
-        android:accessibilityTraversalAfter="@+id/date_time_group"
+        android:layout_marginTop="8dp"
+        android:accessibilityTraversalAfter="@id/quick_qs_status_icons"
         android:accessibilityTraversalBefore="@id/expand_indicator"
         android:clipChildren="false"
         android:clipToPadding="false"
         android:focusable="true"
         android:paddingBottom="10dp"
         android:importantForAccessibility="yes" />
+    </RelativeLayout>
 
 </com.android.systemui.qs.QuickStatusBarHeader>
diff --git a/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml b/packages/SystemUI/res/layout/quick_status_bar_header_date_privacy.xml
similarity index 72%
rename from packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml
rename to packages/SystemUI/res/layout/quick_status_bar_header_date_privacy.xml
index f663ab4e..22cf2cb 100644
--- a/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml
+++ b/packages/SystemUI/res/layout/quick_status_bar_header_date_privacy.xml
@@ -17,33 +17,35 @@
 <LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:systemui="http://schemas.android.com/apk/res-auto"
-    android:id="@+id/quick_status_bar_system_icons"
+    android:id="@+id/quick_status_bar_date_privacy"
     android:layout_width="match_parent"
     android:layout_height="@*android:dimen/quick_qs_offset_height"
     android:clipChildren="false"
     android:clipToPadding="false"
     android:gravity="center"
+    android:layout_gravity="top"
     android:orientation="horizontal"
     android:clickable="true"
-    android:paddingTop="@dimen/status_bar_padding_top" >
+    android:paddingTop="@dimen/status_bar_padding_top"
+    android:minHeight="48dp">
 
     <LinearLayout
         android:layout_width="0dp"
         android:layout_height="match_parent"
+        android:minHeight="48dp"
         android:layout_weight="1"
         android:orientation="horizontal"
         android:gravity="center_vertical|start" >
 
-    <com.android.systemui.statusbar.policy.Clock
-        android:id="@+id/clock"
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:minWidth="48dp"
-        android:gravity="center_vertical|start"
-        android:paddingStart="@dimen/status_bar_left_clock_starting_padding"
-        android:paddingEnd="@dimen/status_bar_left_clock_end_padding"
-        android:singleLine="true"
-        android:textAppearance="@style/TextAppearance.StatusBar.Clock" />
+        <com.android.systemui.statusbar.policy.DateView
+            android:id="@+id/date"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="start|center_vertical"
+            android:gravity="center_vertical"
+            android:singleLine="true"
+            android:textAppearance="@style/TextAppearance.QS.Status"
+            systemui:datePattern="@string/abbrev_wday_month_day_no_year_alarm" />
     </LinearLayout>
 
     <android.widget.Space
@@ -56,6 +58,7 @@
     <LinearLayout
         android:layout_width="0dp"
         android:layout_height="match_parent"
+        android:minHeight="48dp"
         android:layout_weight="1"
         android:orientation="horizontal"
         android:gravity="center_vertical|end" >
diff --git a/packages/SystemUI/res/layout/remote_input.xml b/packages/SystemUI/res/layout/remote_input.xml
index 43182eb..ae3adb8 100644
--- a/packages/SystemUI/res/layout/remote_input.xml
+++ b/packages/SystemUI/res/layout/remote_input.xml
@@ -25,26 +25,25 @@
 
     <view class="com.android.systemui.statusbar.policy.RemoteInputView$RemoteEditText"
             android:id="@+id/remote_input_text"
-            android:layout_height="match_parent"
+            android:layout_height="wrap_content"
             android:layout_width="0dp"
             android:layout_weight="1"
             android:paddingTop="2dp"
-            android:paddingBottom="4dp"
             android:paddingStart="16dp"
             android:paddingEnd="12dp"
-            android:layout_marginRight="5dp"
+            android:layout_marginRight="20dp"
             android:layout_marginLeft="20dp"
             android:layout_marginTop="5dp"
-            android:layout_marginBottom="20dp"
-            android:gravity="start|center_vertical"
+            android:layout_marginBottom="16dp"
+            android:layout_gravity="start|center_vertical"
             android:textAppearance="?android:attr/textAppearance"
             android:textColor="@color/remote_input_text"
             android:textColorHint="@color/remote_input_hint"
             android:textSize="16sp"
             android:background="@null"
-            android:singleLine="true"
+            android:maxLines="4"
             android:ellipsize="start"
-            android:inputType="textShortMessage|textAutoCorrect|textCapSentences"
+            android:inputType="textShortMessage|textMultiLine|textAutoCorrect|textCapSentences"
             android:imeOptions="actionSend|flagNoExtractUi|flagNoFullscreen" />
 
     <FrameLayout
@@ -53,12 +52,12 @@
             android:layout_gravity="center_vertical">
 
         <ImageButton
-                android:layout_width="wrap_content"
+        android:layout_width="wrap_content"
                 android:layout_height="match_parent"
                 android:layout_gravity="center"
-                android:paddingBottom="20dp"
-                android:paddingStart="12dp"
-                android:paddingEnd="24dp"
+                android:paddingLeft="10dp"
+                android:layout_marginBottom="12dp"
+                android:layout_marginEnd="12dp"
                 android:id="@+id/remote_input_send"
                 android:src="@drawable/ic_send"
                 android:contentDescription="@*android:string/ime_action_send"
@@ -70,9 +69,8 @@
                 android:id="@+id/remote_input_progress"
                 android:layout_width="24dp"
                 android:layout_height="24dp"
-                android:layout_marginBottom="10dp"
-                android:layout_marginEnd="6dp"
-                android:layout_gravity="center"
+                android:layout_marginBottom="12dp"
+                android:layout_gravity="center_vertical"
                 android:visibility="invisible"
                 android:indeterminate="true"
                 style="?android:attr/progressBarStyleSmall" />
diff --git a/packages/SystemUI/res/layout/status_bar_notification_footer.xml b/packages/SystemUI/res/layout/status_bar_notification_footer.xml
index 5a1e5c4..5c77d16 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_footer.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_footer.xml
@@ -30,9 +30,11 @@
             style="@style/TextAppearance.NotificationSectionHeaderButton"
             android:id="@+id/manage_text"
             android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
+            android:layout_height="40dp"
             android:layout_gravity="start"
+            android:background="@drawable/notif_footer_btn_background"
             android:focusable="true"
+            android:textColor="@color/notif_pill_text"
             android:contentDescription="@string/manage_notifications_history_text"
             android:text="@string/manage_notifications_history_text"
         />
@@ -40,8 +42,9 @@
             style="@style/TextAppearance.NotificationSectionHeaderButton"
             android:id="@+id/dismiss_text"
             android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
+            android:layout_height="40dp"
             android:layout_gravity="end"
+            android:background="@drawable/notif_footer_btn_background"
             android:focusable="true"
             android:contentDescription="@string/accessibility_clear_all"
             android:text="@string/clear_all_notifications_text"
diff --git a/packages/SystemUI/res/layout/volume_dialog_row.xml b/packages/SystemUI/res/layout/volume_dialog_row.xml
index fda59b5..1d5bca9 100644
--- a/packages/SystemUI/res/layout/volume_dialog_row.xml
+++ b/packages/SystemUI/res/layout/volume_dialog_row.xml
@@ -54,6 +54,7 @@
                 android:layout_width="@dimen/volume_row_slider_height"
                 android:layout_height="match_parent"
                 android:layout_gravity="center"
+                android:thumb="@android:color/transparent"
                 android:rotation="270" />
         </FrameLayout>
 
diff --git a/packages/SystemUI/res/layout/wireless_charging_layout.xml b/packages/SystemUI/res/layout/wireless_charging_layout.xml
index 730f24f..d82151d 100644
--- a/packages/SystemUI/res/layout/wireless_charging_layout.xml
+++ b/packages/SystemUI/res/layout/wireless_charging_layout.xml
@@ -22,6 +22,11 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent">
 
+    <com.android.systemui.statusbar.charging.ChargingRippleView
+        android:id="@+id/wireless_charging_ripple"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"/>
+
     <!-- Circle animation -->
     <ImageView
         android:id="@+id/wireless_charging_view"
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 0623205..62c37a2 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Kanselleer"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Deel"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Skermopname is gekanselleer"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Skermopname is gestoor"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Tik om te bekyk"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Kon nie skermopname uitvee nie"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Kon nie toestemmings kry nie"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Kon nie skermopname begin nie"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Nuwe gebruiker"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Internet"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Vliegtuigveilig"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Netwerke is beskikbaar"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Netwerke is nie beskikbaar nie"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Nie gekoppel nie"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Tot sonsopkoms"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Aan om <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Tot <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Verminder helderheid"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC is gedeaktiveer"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC is geaktiveer"</string>
@@ -470,7 +466,6 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Wys profiel"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Voeg gebruiker by"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Nuwe gebruiker"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Beëindig gastesessie"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Verwyder gas?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle programme en data in hierdie sessie sal uitgevee word."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Verwyder"</string>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Hierdie toestel word deur jou ouer bestuur"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Jou organisasie besit hierdie toestel en kan netwerkverkeer monitor"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> besit hierdie toestel en kan netwerkverkeer monitor"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Hierdie toestel word verskaf deur <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Hierdie toestel behoort aan jou organisasie en is gekoppel aan <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Hierdie toestel behoort aan <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> en is gekoppel aan <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Hierdie toestel behoort aan jou organisasie"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Jou werkprofiel is gekoppel aan <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Jou persoonlike profiel is gekoppel aan <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Hierdie toestel is gekoppel aan <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Hierdie toestel word verskaf deur <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Toestelbestuur"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Profielmonitering"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Netwerkmonitering"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Bekyk beleide"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Bekyk kontroles"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Hierdie toestel behoort aan <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nJou IT-admin kan instellings, korporatiewe toegang, programme, data wat met jou toestel geassosieer word, en jou toestel se ligginginligting monitor en bestuur.\n\nKontak jou IT-admin vir meer inligting."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> kan dalk toegang kry tot data wat met hierdie toestel geassosieer word, programme bestuur, en hierdie toestel se instellings verander.\n\nKontak <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g> as jy enige vrae het."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Hierdie toestel behoort aan jou organisasie.\n\nJou IT-admin kan instellings, korporatiewe toegang, programme, data wat met jou toestel geassosieer word, en jou toestel se ligginginligting monitor en bestuur.\n\nKontak jou IT-admin vir meer inligting."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Jou organisasie het \'n sertifikaatoutoriteit op hierdie toestel geïnstalleer. Jou veilige netwerkverkeer kan gemonitor of gewysig word."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Jou organisasie het \'n sertifikaatoutoriteit in jou werkprofiel geïnstalleer. Jou veilige netwerkverkeer kan gemonitor of gewysig word."</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Wys demonstrasiemodus"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Wekker"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Beursie"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Gereed"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Werkprofiel"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Vliegtuigmodus"</string>
     <string name="add_tile" msgid="6239678623873086686">"Voeg teël by"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Maak kitsinstellings toe."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Wekker is gestel."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Aangemeld as <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"kies gebruiker"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Geen internet nie"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Maak besonderhede oop."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"Onbeskikbaar weens <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Maak <xliff:g id="ID_1">%s</xliff:g>-instellings oop."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Wysig volgorde van instellings."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Aan/af-kieslys"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Bladsy <xliff:g id="ID_1">%1$d</xliff:g> van <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Sluitskerm"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"Foon afgeskakel weens hitte"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Beweeg links"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Beweeg regs"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Vergrotingwisselaar"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Vergroot die hele skerm"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Vergroot die hele skerm"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Vergroot \'n deel van die skerm"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Wissel"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"Toeganklikheidknoppie het die toeganklikheidgebaar vervang\n\n"<annotation id="link">"Bekyk instellings"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Skuif knoppie na kant om dit tydelik te versteek"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Toestelkontroles"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Voeg kontroles vir jou gekoppelde toestelle by"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Stel toestelkontroles op"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Bind nuwe toestel saam"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Gespreklegstukke"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Tik op \'n gesprek om dit by jou tuisskerm te voeg"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> gelede"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"Minder as <xliff:g id="DURATION">%1$s</xliff:g> gelede"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"Meer as <xliff:g id="DURATION">%1$s</xliff:g> gelede"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Verjaarsdag"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Verjaar binnekort"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Herdenking"</string>
+    <string name="location_status" msgid="1294990572202541812">"Deel tans ligging"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Nuwe storie"</string>
+    <string name="video_status" msgid="4548544654316843225">"Kyk tans"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Luister tans"</string>
+    <string name="game_status" msgid="1340694320630973259">"Speel tans"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Vriende"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Kom klets vanaand!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"Gemiste oproep"</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="battery_state_unknown_notification_title" msgid="8464703640483773454">"Kon nie jou batterymeter lees nie"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tik vir meer inligting"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Geen wekker nie"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index cf7e9fd..8f67f1b 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -68,7 +68,7 @@
     <string name="wifi_debugging_always" msgid="2968383799517975155">"ሁልጊዜ በዚህ አውታረ መረብ ላይ ፍቀድ"</string>
     <string name="wifi_debugging_allow" msgid="4573224609684957886">"ፍቀድ"</string>
     <string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"ገመድ-አልባ debugging አይፈቀድም"</string>
-    <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"በአሁኑ ጊዜ በመለያ ወደዚህ መሣሪያ የገባው ተጠቃሚ የገመድ-አልባ debuggingን ማብራት አይችልም። ይህን ባህሪ ለመጠቀም ወደ ዋና ተጠቃሚ ይቀይሩ።"</string>
+    <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"በአሁኑ ጊዜ በመለያ ወደዚህ መሣሪያ የገባው ተጠቃሚ የገመድ-አልባ ማረምን ማብራት አይችልም። ይህን ባህሪ ለመጠቀም ወደ ዋና ተጠቃሚ ይቀይሩ።"</string>
     <string name="usb_contaminant_title" msgid="894052515034594113">"የዩኤስቢ ወደብ ተሰናክሏል"</string>
     <string name="usb_contaminant_message" msgid="7730476585174719805">"መሣሪያዎን ከፈሳሽ ወይም ፍርስራሽ ለመጠበቅ ሲባል የዩኤስቢ ወደቡ ተሰናክሏል፣ እና ማናቸውም ተቀጥላዎችን አያገኝም።\n\nየዩኤስቢ ወደቡን እንደገና መጠቀም ችግር በማይኖረው ጊዜ ማሳወቂያ ይደርሰዎታል።"</string>
     <string name="usb_port_enabled" msgid="531823867664717018">"ኃይል መሙያዎችን እና ተጨማሪ መሣሪያዎችን ፈልጎ ለማግኘት የነቃ የዩኤስቢ ወደብ"</string>
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"ይቅር"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"አጋራ"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"የማያ ገጽ ቀረጻ ተሰርዟል"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"የማያ ገጽ ቀረጻ ተቀምጧል"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"ለመመልከት መታ ያድርጉ"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"የማያ ገጽ ቀረጻን መሰረዝ ላይ ስህተት"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"ፈቃዶችን ማግኘት አልተቻለም"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"የማያ ገጽ ቀረጻን መጀመር ላይ ስህተት"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"አዲስ ተጠቃሚ"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"በይነመረብ"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"አውሮፕላን-ደህንነቱ የተጠበቀ"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"አውታረ መረቦች ይገኛሉ"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"አውታረ መረቦች አይገኙም"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"አልተገናኘም"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"ጸሐይ እስክትወጣ ድረስ"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g> ላይ ይበራል"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"እስከ <xliff:g id="TIME">%s</xliff:g> ድረስ"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"ብሩህነትን ይቀንሱ"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"ኤንኤፍሲ"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"ኤንኤፍሲ ተሰናክሏል"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"ኤንኤፍሲ ነቅቷል"</string>
@@ -470,7 +466,6 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"መገለጫ አሳይ"</string>
     <string name="user_add_user" msgid="4336657383006913022">"ተጠቃሚ አክል"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"አዲስ ተጠቃሚ"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"የእንግዳ ክፍለ-ጊዜ ጨርስ"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"እንግዳ ይወገድ?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"በዚህ ክፍለ-ጊዜ ውስጥ ያሉ ሁሉም መተግበሪያዎች እና ውሂብ ይሰረዛሉ።"</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"አስወግድ"</string>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ይህ መሣሪያ በእርስዎ ወላጅ የሚተዳደር ነው።"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"የእርስዎ ድርጅት የዚህ መሣሪያ ባለቤት ነው፣ እና የአውታረ መረብ ትራፊክን ሊከታተል ይችላል"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> የዚህ መሣሪያ ባለቤት ነው፣ እና የአውታረ መረብ ትራፊክን ሊከታተል ይችላል"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"ይህ መሣሪያ በ<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> የሚቀርብ ነው"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"ይህ መሣሪያ የድርጅትዎ ሲሆን ከ<xliff:g id="VPN_APP">%1$s</xliff:g> ጋር ተገናኝቷል"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"ይህ መሳሪያ ንብረትነቱ የ<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>ሲሆን ከ<xliff:g id="VPN_APP">%2$s</xliff:g> ጋር ተገናኝቷል"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"ይህ መሣሪያ የድርጅትዎ ነው"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"የእርስዎ የሥራ መገለጫ ከ<xliff:g id="VPN_APP">%1$s</xliff:g> ጋር ተገናኝቷል።"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"የእርስዎ የግል መገለጫ ከ<xliff:g id="VPN_APP">%1$s</xliff:g> ጋር ተገናኝቷል"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"ይህ መሳሪያ ከ<xliff:g id="VPN_APP">%1$s</xliff:g> ጋር ተገናኝቷል"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"ይህ መሣሪያ በ<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> የሚቀርብ ነው"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"የመሣሪያ አስተዳደር"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"መገለጫን መከታተል"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"የአውታረ መረብ ክትትል"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"መመሪያዎችን ይመልከቱ"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"መቆጣጠሪያዎችን አሳይ"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"ይህ መሣሪያ የ<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ነው።\n\nየእርስዎ የአይቲ አስተዳዳሪ ቅንብሮችን፣ የኮርፖሬት መዳረሻን፣ መተግበሪያዎችን፣ ከመሣሪያዎ ጋር የተጎዳኘ ውሂብን እና የመሣሪያዎ አካባቢ መረጃን መከታተል እና ማቀናበር ይችላል።\n\nተጨማሪ መረጃ የአይቲ አስተዳዳሪዎን ያነጋግሩ።"</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> ከዚህ መሣሪያ ጋር የተጎዳኘ ውሂብን መድረስ፣ መተግበሪያዎችን ማቀናበር እና የዚህ መሣሪያ ቅንብሮችን መለወጥ ይችላል።\n\nጥያቄዎች ካሉዎት <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>ን ያነጋግሩ።"</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"ይህ መሣሪያ የድርጅትዎ ነው።\n\nየእርስዎ የአይቲ አስተዳዳሪ ቅንብሮችን፣ የኮርፖሬት መዳረሻን፣ መተግበሪያዎችን፣ ከመሣሪያዎ ጋር የተጎዳኘ ውሂብን እና የመሣሪያዎ አካባቢ መረጃን መከታተል እና ማቀናበር ይችላል።\n\nለተጨማሪ መረጃ የአይቲ አስተዳዳሪዎን ያነጋግሩ።"</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"የእርስዎ ድርጅት የእውቅና ማረጋገጫ ሰጪ ባለሥልጣን በዚህ መሣሪያ ላይ ጭኗል። የእርስዎ ደኅንነቱ የተጠበቀ አውታረ መረብ ትራፊክ ክትትል ሊደረግበት እና ሊሻሻል ይችላል።"</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"የእርስዎ ድርጅት የእውቅና ማረጋገጫ ሰጪ ባለሥልጣን በእርስዎ የሥራ መገለጫ ላይ ጭኗል። የእርስዎ ደኅንነቱ የተጠበቀ አውታረ መረብ ትራፊክ ክትትል ሊደረግበት እና ሊሻሻል ይችላል።"</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"ማሳያ ሁነታን አሳይ"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"ኤተርኔት"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"ማንቂያ"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"ዝግጁ"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"የስራ መገለጫ"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"የአውሮፕላን ሁነታ"</string>
     <string name="add_tile" msgid="6239678623873086686">"ሰቅ ያክሉ"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"ፈጣን ቅንብሮችን ዝጋ።"</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"ማንቂያ ተዘጋጅቷል።"</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"እንደ <xliff:g id="ID_1">%s</xliff:g> ሆነው ገብተዋል"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"ተጠቃሚ ይምረጡ"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"ምንም በይነመረብ የለም"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"ዝርዝሮችን ክፈት።"</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"በ<xliff:g id="REASON">%s</xliff:g> ምክንያት አይገኝም"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"የ<xliff:g id="ID_1">%s</xliff:g> ቅንብሮችን ክፈት።"</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"የቅንብሮድ ቅደም-ተከተል አርትዕ።"</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"የኃይል ምናሌ"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"ገጽ <xliff:g id="ID_1">%1$d</xliff:g> ከ <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"ማያ ገጽ ቁልፍ"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"ስልክ በሙቀት ምክንያት ጠፍቷል"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"ወደ ግራ ውሰድ"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"ወደ ቀኝ ውሰድ"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"የማጉላት ማብሪያ/ማጥፊያ"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"ሙሉውን ማያ ገጽ አጉላ"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"ሙሉ ገጽ እይታን ያጉሉ"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"የማያ ገጹን ክፍል አጉላ"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"ማብሪያ/ማጥፊያ"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"የተደራሽነት አዝራር የተደራሽነት ምልክትን ተክቷል\n\n"<annotation id="link">" ቅንብሮችን አሳይ"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"ለጊዜው ለመደበቅ አዝራሩን ወደ ጠርዝ ያንቀሳቅሱ"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"የመሣሪያ መቆጣጠሪያዎች"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"ለእርስዎ የተገናኙ መሣሪያዎች መቆጣጠሪያዎችን ያክሉ"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"የመሣሪያ መቆጣጠሪያዎችን ያቀናብሩ"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"አዲስ መሣሪያ ያጣምሩ"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"የውይይት ምግብሮች"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"በመነሻ ማያ ገጽዎ ላይ ለማከል አንድ ውይይት መታ ያድርጉ"</string>
+    <string name="timestamp" msgid="6577851592534538533">"ከ<xliff:g id="DURATION">%1$s</xliff:g> በፊት"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"ከ <xliff:g id="DURATION">%1$s</xliff:g> በፊት"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"ከ <xliff:g id="DURATION">%1$s</xliff:g> በፊት"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"የልደት ቀን"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"የልደት ቀን በቅርቡ"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"ዓመታዊ በዓል"</string>
+    <string name="location_status" msgid="1294990572202541812">"አካባቢን በማጋራት ላይ"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"አዲስ ዘገባ"</string>
+    <string name="video_status" msgid="4548544654316843225">"በመመልከት ላይ"</string>
+    <string name="audio_status" msgid="4237055636967709208">"በማዳመጥ ላይ"</string>
+    <string name="game_status" msgid="1340694320630973259">"በመጫወት ላይ"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"ጓደኞች"</string>
+    <string name="empty_status" msgid="5938893404951307749">"ዛሬ ማታ እንወያይ!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"ያመለጠ ጥሪ"</string>
+    <string name="people_tile_description" msgid="8154966188085545556">"የቅርብ ጊዜ መልዕክቶችን፣ ያመለጡ ጥሪዎች እና፣ የሁኔታ ዝመናዎችን ይመልከቱ"</string>
+    <string name="people_tile_title" msgid="6589377493334871272">"ውይይት"</string>
     <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"የባትሪ መለኪያዎን የማንበብ ችግር"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"ለበለጠ መረጃ መታ ያድርጉ"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"ምንም ማንቂያ አልተቀናበረም"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index db76744..f778c70 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"إلغاء"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"مشاركة"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"تمّ إلغاء تسجيل الشاشة."</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"تم حفظ تسجيل الشاشة."</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"انقر لعرض التسجيل."</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"حدث خطأ أثناء حذف تسجيل الشاشة."</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"تعذّر الحصول على أذونات."</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"حدث خطأ في بدء تسجيل الشاشة"</string>
@@ -365,7 +363,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"مستخدم جديد"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"الإنترنت"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"آمنة في الطائرة"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"الشبكات متوفرة"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"الشبكات غير متوفرة"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"ليست متصلة"</string>
@@ -423,7 +420,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"حتى شروق الشمس"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"تفعيل الوضع في <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"حتى <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"تقليل السطوع"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"تم إيقاف الاتصال القريب المدى"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"تم تفعيل الاتصال القريب المدى"</string>
@@ -478,14 +474,13 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"عرض الملف الشخصي"</string>
     <string name="user_add_user" msgid="4336657383006913022">"إضافة مستخدم"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"مستخدم جديد"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"إنهاء جلسة الضيف"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"هل تريد إزالة جلسة الضيف؟"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"سيتم حذف كل التطبيقات والبيانات في هذه الجلسة."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"إزالة"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"مرحبًا بك مجددًا في جلسة الضيف"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"هل تريد متابعة جلستك؟"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"البدء من جديد"</string>
-    <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"نعم، متابعة."</string>
+    <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"نعم، متابعة"</string>
     <string name="guest_notification_title" msgid="4434456703930764167">"مستخدم ضيف"</string>
     <string name="guest_notification_text" msgid="4202692942089571351">"لحذف التطبيقات والبيانات، عليك إزالة حساب الضيف"</string>
     <string name="guest_notification_remove_action" msgid="4153019027696868099">"إزالة الضيف"</string>
@@ -531,6 +526,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"يتولّى أحد الوالدين إدارة هذا الجهاز."</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"تملك مؤسستك هذا الجهاز ويمكنها تتبّع حركة بيانات الشبكة."</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"تملك مؤسسة <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> هذا الجهاز ويمكنها تتبّع حركة بيانات الشبكة"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"توفر مؤسسة \"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>\" هذا الجهاز."</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"هذا الجهاز يخص مؤسستك وتم ربطه بشبكة <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"هذا الجهاز يخص <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> وتم ربطه بشبكة <xliff:g id="VPN_APP">%2$s</xliff:g>."</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"هذا الجهاز يخص مؤسستك."</string>
@@ -544,6 +540,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"تم ربط الملف الشخصي للعمل بشبكة <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"تم ربط ملفك الشخصي بشبكة <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"تم ربط هذا الجهاز بشبكة <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"توفر مؤسسة \"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>\" هذا الجهاز"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"إدارة الأجهزة"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"مراقبة الملف الشخصي"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"مراقبة الشبكات"</string>
@@ -555,6 +552,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"عرض السياسات"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"عرض عناصر التحكم"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"هذا الجهاز يخص <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nيمكن لمشرف تكنولوجيا المعلومات تتبّع وإدارة الإعدادات والتطبيقات والبيانات المرتبطة بجهازك ومعلومات الموقع الجغرافي للجهاز وعمليات الدخول إلى نظام المؤسسة.\n\nللحصول على المزيد من المعلومات، يمكنك التواصل مع مشرف تكنولوجيا المعلومات."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"قد تتمكّن مؤسسة <xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> من الوصول إلى البيانات المرتبطة بهذا الجهاز وإدارة التطبيقات وتغيير إعدادات الجهاز.\n\nإذا كان لديك أسئلة، يُرجى التواصل مع <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"هذا الجهاز يخص مؤسستك.\n\nيمكن لمشرف تكنولوجيا المعلومات في مؤسستك تتبّع وإدارة الإعدادات والتطبيقات والبيانات المرتبطة بجهازك ومعلومات الموقع الجغرافي للجهاز وعمليات الدخول إلى نظام المؤسسة.\n\nللحصول على المزيد من المعلومات، يمكنك التواصل مع مشرف تكنولوجيا المعلومات."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"ثبّتت مؤسستك مرجعًا مصدّقًا على هذا الجهاز. قد تتم مراقبة حركة بيانات شبكتك الآمنة أو تعديلها."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"ثبّتت مؤسستك مرجعًا مصدّقًا في ملفك الشخصي للعمل. قد تتم مراقبة حركة بيانات شبكتك الآمنة أو تعديلها."</string>
@@ -665,6 +663,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"عرض الوضع التجريبي"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"إيثرنت"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"المنبّه"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"المحفظة"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"جاهزة"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"الملف الشخصي للعمل"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"وضع الطيران"</string>
     <string name="add_tile" msgid="6239678623873086686">"إضافة فئة"</string>
@@ -919,11 +919,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"إغلاق الإعدادات السريعة."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"تم ضبط المنبّه."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"تم تسجيل الدخول باعتبارك <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"اختيار مستخدم"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"لا يتوفر اتصال إنترنت."</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"فتح التفاصيل."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"غير متاحة بسبب <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"فتح إعدادات <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"تعديل ترتيب الإعدادات."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"قائمة زر التشغيل"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"الصفحة <xliff:g id="ID_1">%1$d</xliff:g> من <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"شاشة القفل"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"تم إيقاف الهاتف بسبب الحرارة"</string>
@@ -1031,9 +1033,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"نقل لليسار"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"نقل لليمين"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"مفتاح تبديل وضع التكبير"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"تكبير الشاشة بالكامل"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"تكبير الشاشة كلها"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"تكبير جزء من الشاشة"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"تبديل"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"تم استبدال \"زر أدوات تسهيل الاستخدام\" بإيماءة تسهيل الاستخدام.\n\n"<annotation id="link">"الاطّلاع على الإعدادات"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"يمكنك نقل الزر إلى الحافة لإخفائه مؤقتًا."</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"أدوات التحكم بالأجهزة"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"إضافة عناصر تحكّم لأجهزتك المتصلة"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"إعداد أدوات التحكم بالجهاز"</string>
@@ -1105,6 +1109,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"إقران جهاز جديد"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"أدوات المحادثة"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"انقر على محادثة لإضافتها إلى \"الشاشة الرئيسية\"."</string>
+    <string name="timestamp" msgid="6577851592534538533">"قبل <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"قبل أقل من <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"قبل أكثر <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"تاريخ الميلاد"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"تاريخ ميلاد قريب"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"الذكرى السنوية"</string>
+    <string name="location_status" msgid="1294990572202541812">"تتم مشاركة الموقع الجغرافي"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"قصة جديدة"</string>
+    <string name="video_status" msgid="4548544654316843225">"جارٍ المشاهدة"</string>
+    <string name="audio_status" msgid="4237055636967709208">"يتم الاستماع الآن"</string>
+    <string name="game_status" msgid="1340694320630973259">"جارٍ اللعب"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"الأصدقاء"</string>
+    <string name="empty_status" msgid="5938893404951307749">"لنجرِ محادثة الليلة."</string>
+    <string name="missed_call" msgid="4228016077700161689">"مكالمة فائتة"</string>
+    <string name="people_tile_description" msgid="8154966188085545556">"عرض أحدث الرسائل والمكلمات الفائتة وآخر أخبار الحالة"</string>
+    <string name="people_tile_title" msgid="6589377493334871272">"محادثة"</string>
     <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"حدثت مشكلة أثناء قراءة مقياس مستوى شحن البطارية."</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"انقر للحصول على مزيد من المعلومات."</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"لم يتم ضبط منبّه."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index 47c86ec..2d7b4ac 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"বাতিল কৰক"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"শ্বেয়াৰ কৰক"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"স্ক্রীণ ৰেকৰ্ড কৰাটো বাতিল কৰা হ’ল"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"স্ক্ৰীন ৰেকৰ্ডিং ছেভ কৰা হ’ল"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"চাবলৈ টিপক"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"স্ক্রীণ ৰেকৰ্ডিং মচি থাকোঁতে কিবা আসোঁৱাহ হ’ল"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"অনুমতি পাব পৰা নগ\'ল"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"স্ক্রীন ৰেকৰ্ড কৰা আৰম্ভ কৰোঁতে আসোঁৱাহ হৈছে"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"নতুন ব্যৱহাৰকাৰী"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"ৱাই-ফাই"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"ইণ্টাৰনেট"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"এয়াৰপ্লে’নত ব্যৱহাৰৰ বাবে সুৰক্ষিত"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"নেটৱৰ্ক উপলব্ধ"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"নেটৱৰ্ক উপলব্ধ নহয়"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"সংযোগ হৈ থকা নাই"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"সূৰ্যোদয়লৈকে"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g>ত অন কৰক"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> পৰ্যন্ত"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"উজ্জ্বলতা কমাওক"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC নিষ্ক্ৰিয় হৈ আছে"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC সক্ষম হৈ আছে"</string>
@@ -470,11 +466,10 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"প্ৰ\'ফাইল দেখুৱাওক"</string>
     <string name="user_add_user" msgid="4336657383006913022">"ব্যৱহাৰকাৰী যোগ কৰক"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"নতুন ব্যৱহাৰকাৰী"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"অতিথিৰ ছেশ্বন সমাপ্ত কৰক"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"অতিথি আঁতৰাবনে?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"এই ছেশ্বনৰ সকলো এপ্ আৰু ডেটা মচা হ\'ব।"</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"আঁতৰাওক"</string>
-    <string name="guest_wipe_session_title" msgid="7147965814683990944">"আপোনাক পুনৰাই স্বাগতম জনাইছোঁ!"</string>
+    <string name="guest_wipe_session_title" msgid="7147965814683990944">"অতিথি, আপোনাক পুনৰ স্বাগতম!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"আপুনি আপোনাৰ ছেশ্বন অব্যাহত ৰাখিব বিচাৰেনে?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"আকৌ আৰম্ভ কৰক"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"হয়, অব্যাহত ৰাখক"</string>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"এই ডিভাইচটো আপোনাৰ অভিভাৱকে পৰিচালনা কৰে"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"এই ডিভাইচটোৰ গৰাকী আপোনাৰ প্ৰতিষ্ঠান আৰু ই নেটৱৰ্কৰ ট্ৰেফিক নিৰীক্ষণ কৰিব পাৰে"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"এই ডিভাইচটোৰ গৰাকী <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> আৰু এইটোৱে নেটৱৰ্কৰ ট্ৰেফিক নিৰীক্ষণ কৰিব পাৰে"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"এই ডিভাইচটো <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>এ প্ৰদান কৰিছে"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"এই ডিভাইচটো আপোনাৰ প্ৰতিষ্ঠানৰ আৰু এইটো <xliff:g id="VPN_APP">%1$s</xliff:g>ৰ সৈতে সংযুক্ত হৈ আছে"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"এই ডিভাইচটো <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>ৰ আৰু এইটো <xliff:g id="VPN_APP">%2$s</xliff:g>ৰ সৈতে সংযুক্ত হৈ আছে"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"এই ডিভাইচটো আপোনাৰ প্ৰতিষ্ঠানৰ"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"আপোনাৰ কৰ্মস্থানৰ প্ৰ’ফাইলটো <xliff:g id="VPN_APP">%1$s</xliff:g>ৰ সৈতে সংযুক্ত হৈ আছে"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"আপোনাৰ ব্যক্তিগত প্ৰ’ফাইলটো <xliff:g id="VPN_APP">%1$s</xliff:g>ৰ সৈতে সংযুক্ত হৈ আছে"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"এই ডিভাইচটো <xliff:g id="VPN_APP">%1$s</xliff:g>ৰ সৈতে সংযুক্ত হৈ আছে"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"এই ডিভাইচটো <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>এ প্ৰদান কৰিছে"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"ডিভাইচৰ পৰিচালনা"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"প্ৰ\'ফাইল নিৰীক্ষণ"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"নেটৱৰ্ক নিৰীক্ষণ"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"নীতিসমূহ চাওক"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"নিয়ন্ত্ৰণসমূহ চাওক"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"এই ডিভাইচটো <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>ৰ।\n\nআপোনাৰ আইটি প্ৰশাসকে আপোনাৰ ডিভাইচটোৰ লগত জড়িত ছেটিংসমূহ, কৰ্পৰে’টৰ এক্সেছ, এপ্‌সমূহ, ডেটা আৰু আপোনাৰ ডিভাইচটোৰ অৱস্থান সম্পৰ্কীয় তথ্য নিৰীক্ষণ কৰাৰ লগতে সেয়া পৰিচালনা কৰিব পাৰে।\n\nঅধিক তথ্যৰ বাবে আপোনাৰ আইটি প্ৰশাসকৰ সৈতে যোগাযোগ কৰক।"</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g>এ হয়তো এই ডিভাইচটোৰ সৈতে জড়িত হৈ থকা ডেটা এক্সেছ কৰিব, এপ্‌ পৰিচালনা কৰিব আৰু এই ডিভাইচটোৰ ছেটিং সলনি কৰিব পাৰিব।\n\nআপোনাৰ যদি কিবা প্ৰশ্ন আছে, তেন্তে <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>ৰ সৈতে যোগাযোগ কৰক।"</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"এই ডিভাইচটো আপোনাৰ প্ৰতিষ্ঠানৰ।\n\nআপোনাৰ আইটি প্ৰশাসকে আপোনাৰ ডিভাইচটোৰ লগত জড়িত ছেটিংসমূহ, কৰ্পৰে’টৰ এক্সেছ, এপ্‌সমূহ, ডেটা আৰু আপোনাৰ ডিভাইচটোৰ অৱস্থান সম্পৰ্কীয় তথ্য নিৰীক্ষণ কৰাৰ লগতে সেয়া পৰিচালনা কৰিব পাৰে।\n\nঅধিক তথ্যৰ বাবে আপোনাৰ আইটি প্ৰশাসকৰ সৈতে যোগাযোগ কৰক।"</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"আপোনাৰ প্ৰতিষ্ঠানে এই ডিভাইচটোত এটা প্ৰমাণপত্ৰ সম্পৰ্কীয় কৰ্তৃপক্ষ ইনষ্টল কৰিছে। আপোনাৰ সুৰক্ষিত নেটৱৰ্ক ট্ৰেফিক পৰ্যবেক্ষণ বা সংশোধন কৰা হ\'ব পাৰে।"</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"আপোনাৰ প্ৰতিষ্ঠানে আপোনাৰ কৰ্মস্থানৰ প্ৰ\'ফাইলটোত এটা প্ৰমাণপত্ৰ সম্পৰ্কীয় কৰ্তৃপক্ষ ইনষ্টল কৰিছে। আপোনাৰ সুৰক্ষিত নেটৱৰ্কৰ ট্ৰেফিক পৰ্যবেক্ষণ বা সংশোধন কৰা হ\'ব পাৰে।"</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"ডেম\' ম\'ড দেখুৱাওক"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"ইথাৰনেট"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"এলাৰ্ম"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"ৱালেট"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"সাজু"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"কৰ্মস্থানৰ প্ৰ\'ফাইল"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"এয়াৰপ্লেইন ম\'ড"</string>
     <string name="add_tile" msgid="6239678623873086686">"টাইল যোগ দিয়ক"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"ক্ষিপ্ৰ ছেটিংসমূহ বন্ধ কৰক।"</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"এলার্ম ছেট কৰা হ’ল।"</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"<xliff:g id="ID_1">%s</xliff:g> হিচাপে ছাইন ইন হ’ল"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"ব্যৱহাৰকাৰী বাছনি কৰক"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"ইণ্টাৰনেট সংযোগ নাই"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"বিৱৰণসমূহ খোলক।"</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"<xliff:g id="REASON">%s</xliff:g>ৰ বাবে উপলব্ধ নহয়"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g>ৰ ছেটিংসমূহ খোলক।"</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"ছেটিংসমূহৰ ক্ৰম সম্পাদনা কৰক।"</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"পাৱাৰ মেনু"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g>ৰ পৃষ্ঠা <xliff:g id="ID_1">%1$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"লক স্ক্ৰীণ"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"আপোনাৰ ফ\'নটো গৰম হোৱাৰ কাৰণে অফ কৰা হৈছিল"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"বাওঁফাললৈ নিয়ক"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"সোঁফাললৈ নিয়ক"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"বিবৰ্ধনৰ ছুইচ"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"গোটেই স্ক্ৰীনখন বিবৰ্ধন কৰক"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"পূৰ্ণ স্ক্ৰীন বিবৰ্ধন কৰক"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"স্ক্ৰীনৰ কিছু অংশ বিবৰ্ধন কৰক"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"ছুইচ"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"সাধ্য সুবিধাৰ বুটামটোৱে সাধ্য সুবিধাৰ নিৰ্দেশ সলনি কৰিছে\n\n"<annotation id="link">"ছেটিং চাওক"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"বুটামটোক সাময়িকভাৱে লুকুৱাবলৈ ইয়াক একেবাৰে কাষলৈ লৈ যাওক"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"ডিভাইচৰ নিয়ন্ত্ৰণসমূহ"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"আপোনাৰ সংযোজিত ডিভাইচসমূহৰ বাবে নিয়ন্ত্ৰণসমূহ যোগ কৰক"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"ডিভাইচৰ নিয়ন্ত্ৰণসমূহ ছেট আপ কৰক"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"নতুন ডিভাইচ পেয়াৰ কৰক"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"বাৰ্তালাপ ৱিজেট"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"আপোনাৰ গৃহ স্ক্ৰীনত কোনো বাৰ্তালাপ যোগ দিবলৈ সেইটোত টিপক"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> পূৰ্বে"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"<xliff:g id="DURATION">%1$s</xliff:g>তকৈ কম সময়ৰ পূৰ্বে"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"<xliff:g id="DURATION">%1$s</xliff:g>তকৈ বেছি সময়ৰ পূৰ্বে"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"জন্মদিন"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"জন্মদিন সোনকালে আহি আছে"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"বৰ্ষপূৰ্তি"</string>
+    <string name="location_status" msgid="1294990572202541812">"অৱস্থান শ্বেয়াৰ কৰি থকা হৈছে"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"নতুন কাহিনী"</string>
+    <string name="video_status" msgid="4548544654316843225">"চাই আছোঁ"</string>
+    <string name="audio_status" msgid="4237055636967709208">"শুনি আছোঁ"</string>
+    <string name="game_status" msgid="1340694320630973259">"প্লে’ হৈ আছে"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"বন্ধুবৰ্গ"</string>
+    <string name="empty_status" msgid="5938893404951307749">"আজি ৰাতি চাট কৰোঁ আহক!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"মিছড্‌ কল"</string>
+    <string name="people_tile_description" msgid="8154966188085545556">"শেহতীয়া বাৰ্তা, মিছড্‌ কল আৰু স্থিতিৰ আপডে’ট চাওক"</string>
+    <string name="people_tile_title" msgid="6589377493334871272">"বাৰ্তালাপ"</string>
     <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"আপোনাৰ বেটাৰী মিটাৰ পঢ়োঁতে সমস্যা হৈছে"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"অধিক তথ্যৰ বাবে টিপক"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"কোনো এলাৰ্ম ছেট কৰা হোৱা নাই"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index 8b629c1d..939d805 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Ləğv edin"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Paylaşın"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Ekranın video çəkimi ləğv edildi"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Ekran çəkilişi yadda saxlanıldı"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Baxmaq üçün toxunun"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Ekranın video çəkiminin silinməsi zamanı xəta baş verdi"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"İcazələr əldə edilmədi"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Ekranın yazılması ilə bağlı xəta"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Yeni istifadəçi"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"İnternet"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Təyyarə üçün güvənli şəbəkə"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Şəbəkələr əlçatandır"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Şəbəkələr əlçatan deyil"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Bağlantı yoxdur"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Şəfəq vaxtına qədər"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Bu vaxt aktiv olur: <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Bu vaxtadək: <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Parlaqlığı azaldın"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC deaktiv edilib"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC aktiv edilib"</string>
@@ -470,7 +466,6 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Show profile"</string>
     <string name="user_add_user" msgid="4336657383006913022">"İstifadəçi əlavə edin"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Yeni istifadəçi"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Qonaq sessiyasını bitirin"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Qonaq silinsin?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Bu sessiyada bütün tətbiqlər və data silinəcək."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Yığışdır"</string>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Bu cihaz valideyniniz tərəfindən idarə olunur"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Təşkilatınız bu cihazın sahibidir və şəbəkə trafikinə nəzarət edə bilər"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> bu cihazın sahibidir və şəbəkə trafikinə nəzarət edə bilər"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Bu cihaz <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> tərəfindən təmin edilib"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Bu cihaz təşkilatınıza məxsusdur və <xliff:g id="VPN_APP">%1$s</xliff:g> şəbəkəsinə qoşulub"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Bu cihaz <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> təşkilatına məxsusdur və <xliff:g id="VPN_APP">%2$s</xliff:g> şəbəkəsinə qoşulub"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Bu cihaz təşkilatınıza məxsusdur"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"İş profiliniz <xliff:g id="VPN_APP">%1$s</xliff:g> şəbəkəsinə qoşulub"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Şəxsi profiliniz <xliff:g id="VPN_APP">%1$s</xliff:g> şəbəkəsinə qoşulub"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Bu cihaz <xliff:g id="VPN_APP">%1$s</xliff:g> şəbəkəsinə qoşulub"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Bu cihaz <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> tərəfindən təmin edilib"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Cihaz idarəetməsi"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Profil izlənməsi"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Şəbəkə monitorinqi"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Siyasətlərə Baxın"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Nizamlayıcılara baxın"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Bu cihaz <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> təşkilatına məxsusdur.\n\nIT admininiz cihaz və cihaz məkan məlumatı ilə əlaqəli ayarlara, korporativ girişə, tətbiqə və dataya nəzarət edə və idarə edə bilər.\n\nƏtraflı məlumat üçün IT admini ilə əlaqə saxlayın."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> bu cihazla əlaqəli məlumatlara daxil ola, tətbiqləri idarə edə və bu cihazın ayarlarını dəyişdirə bilər.\n\nSuallarınız varsa, <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g> ilə əlaqə saxlayın."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Bu cihaz təşkilatınıza məxsusdur.\n\nIT admininiz cihaz və cihaz məkan məlumatı ilə əlaqəli ayarlara, korporativ girişə, tətbiqə və dataya nəzarət edə və idarə edə bilər.\n\nƏtraflı məlumat üçün IT admini ilə əlaqə saxlayın."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Təşkilat bu cihazda sertifikat səlahiyyəti quraşdırdı. Təhlükəsiz şəbəkə ötürülməsinə nəzarət edilə və ya dəyişdirilə bilər."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Təşkilat iş profilində sertifikat səlahiyyəti quraşdırdı. Təhlükəsiz şəbəkə ötürülməsinə nəzarət edilə və ya dəyişdirilə bilər."</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Demo rejimini göstərin"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Zəngli saat"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Pulqabı"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Hazır"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"İş profili"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Təyyarə rejimi"</string>
     <string name="add_tile" msgid="6239678623873086686">"Xana əlavə edin"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Cəld ayarları bağlayın."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Siqnal quraşdırıldı."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"<xliff:g id="ID_1">%s</xliff:g> kimi daxil olunub"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"istifadəçi seçin"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"İnternet yoxdur"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Detalları açın."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"<xliff:g id="REASON">%s</xliff:g> səbəbi ilə əlçatan deyil"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> ayarlarını açın."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Ayarların sıralanmasını redaktə edin."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Yandırıb-söndürmə menyusu"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g> səhifədən <xliff:g id="ID_1">%1$d</xliff:g> səhifə"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Ekran kilidi"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"İstiliyə görə telefon söndü"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Sola köçürün"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Sağa köçürün"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Böyütmə dəyişdiricisi"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Bütün ekranı böyüdün"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Tam ekranı böyüdün"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Ekranın bir hissəsini böyüdün"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Dəyişdirici"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"Əlçatımlılıq düyməsi əlçatımlılıq jestini əvəz etdi\n\n"<annotation id="link">"Ayarlara baxın"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Düyməni müvəqqəti gizlətmək üçün kənara çəkin"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Cihaz idarəetmələri"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Qoşulmuş cihazlarınız üçün nizamlayıcılar əlavə edin"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Cihaz idarəetmələrini ayarlayın"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Yeni cihazı qoşalaşdırın"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Versiya 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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Söhbət vidcetləri"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Əsas ekranınıza əlavə etmək üçün söhbətə toxunun"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> əvvəl"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"Maksimum <xliff:g id="DURATION">%1$s</xliff:g> əvvəl"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"Minimum <xliff:g id="DURATION">%1$s</xliff:g> əvvəl"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Doğum günü"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Tezliklə doğum günü"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"İldönümü"</string>
+    <string name="location_status" msgid="1294990572202541812">"Məkan paylaşılır"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Yeni hekayə"</string>
+    <string name="video_status" msgid="4548544654316843225">"Baxır"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Dinlənilir"</string>
+    <string name="game_status" msgid="1340694320630973259">"Oxudulur"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Dostlar"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Bugün söhbət edək!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"Buraxılmış zəng"</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="battery_state_unknown_notification_title" msgid="8464703640483773454">"Batareya ölçüsünü oxuyarkən problem yarandı"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Ətraflı məlumat üçün toxunun"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Siqnal ayarlanmayıb"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 700484c..213fb98 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Otkaži"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Deli"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Snimanje ekrana je otkazano"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Snimak ekrana je sačuvan"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Dodirnite da biste pregledali"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Došlo je do problema pri brisanju snimka ekrana"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Preuzimanje dozvola nije uspelo"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Greška pri pokretanju snimanja ekrana"</string>
@@ -362,7 +360,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Novi korisnik"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"WiFi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Internet"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Bezbedno za avion"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Mreže su dostupne"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Mreže nisu dostupne"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Veza nije uspostavljena"</string>
@@ -417,7 +414,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Do izlaska sunca"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Uključuje se u <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Do <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Smanjite osvetljenost"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC je onemogućen"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC je omogućen"</string>
@@ -472,7 +468,6 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Prikaži profil"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Dodaj korisnika"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Novi korisnik"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Završi sesiju gosta"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Želite li da uklonite gosta?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Sve aplikacije i podaci u ovoj sesiji će biti izbrisani."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Ukloni"</string>
@@ -522,6 +517,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Ovim uređajem upravlja roditelj"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Organizacija je vlasnik uređaja i može da nadgleda mrežni saobraćaj"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> je vlasnik ovog uređaja i može da nadgleda mrežni saobraćaj"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Ovaj uređaj pruža <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Ovaj uređaj pripada organizaciji i povezan je sa aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> i povezan je sa aplikacijom <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Ovaj uređaj pripada organizaciji"</string>
@@ -535,6 +531,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Poslovni profil je povezan sa aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Vaš lični profil je povezan sa aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Ovaj uređaj je povezan sa aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Ovaj uređaj pruža <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Upravljanje uređajima"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Nadgledanje profila"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Nadgledanje mreže"</string>
@@ -546,6 +543,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Prikaži smernice"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Prikaži kontrole"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nIT administrator može da nadgleda podešavanja, korporativni pristup, aplikacije, podatke povezane sa uređajem i informacije o lokaciji uređaja, kao i da upravlja njima.\n\nViše informacija potražite od IT administratora."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> možda može da pristupa podacima povezanim sa ovim uređajem, da upravlja aplikacijama i da menja podešavanja ovog uređaja.\n\nAko imate pitanja, obratite se organizaciji <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Ovaj uređaj pripada organizaciji.\n\nIT administrator može da nadgleda podešavanja, korporativni pristup, aplikacije, podatke povezane sa uređajem i informacije o lokaciji uređaja, kao i da upravlja njima.\n\nViše informacija potražite od IT administratora."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Organizacija je na ovom uređaju instalirala autoritet za izdavanje sertifikata. Bezbedni mrežni saobraćaj može da se prati ili menja."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Organizacija je na poslovnom profilu instalirala autoritet za izdavanje sertifikata. Bezbedni mrežni saobraćaj može da se prati ili menja."</string>
@@ -656,6 +654,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Prikaži režim demonstracije"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Eternet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Alarm"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Novčanik"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Spremno"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Poslovni profil"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Režim rada u avionu"</string>
     <string name="add_tile" msgid="6239678623873086686">"Dodaj pločicu"</string>
@@ -904,11 +904,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Zatvori Brza podešavanja."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Alarm je podešen."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Prijavljeni ste kao <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"odabrali korisnika"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Nema interneta"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Otvori detalje."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"Nije dostupno iz sledećeg razloga: <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Otvori podešavanja za <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Izmeni redosled podešavanja."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Meni dugmeta za uključivanje"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_1">%1$d</xliff:g>. strana od <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Zaključan ekran"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"Telefon se isključio zbog toplote"</string>
@@ -1016,9 +1018,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Pomerite nalevo"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Pomerite nadesno"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Prelazak na drugi režim uvećanja"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Uvećajte ceo ekran"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Uvećajte ceo ekran"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Uvećajte deo ekrana"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Pređi"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"Dugme Pristupačnost je zamenilo pokret za pristupačnost\n\n"<annotation id="link">"Prikaži podešavanja"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Pomerite dugme do ivice da biste ga privremeno sakrili"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Kontrole uređaja"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Dodajte kontrole za povezane uređaje"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Podesite kontrole uređaja"</string>
@@ -1087,6 +1091,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Upari novi uređaj"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Vidžeti za konverzaciju"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Dodirnite konverzaciju da biste je dodali na početni ekran"</string>
+    <string name="timestamp" msgid="6577851592534538533">"Pre <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"Pre manje od <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"Pre više od <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Rođendan"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Rođendan je uskoro"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Godišnjica"</string>
+    <string name="location_status" msgid="1294990572202541812">"Deli se lokacija"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Nova priča"</string>
+    <string name="video_status" msgid="4548544654316843225">"Gleda se"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Sluša se"</string>
+    <string name="game_status" msgid="1340694320630973259">"Igra se"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Prijatelji"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Ćaskamo večeras!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"Propušten poziv"</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="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problem sa očitavanjem merača baterije"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Dodirnite za više informacija"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Alarm nije podešen"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 7fe5fb4..8e7b9ae 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Скасаваць"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Абагуліць"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Запіс экрана скасаваны"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Запіс экрана захаваны"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Націсніце для прагляду"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Памылка выдалення запісу экрана"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Не ўдалося атрымаць дазволы"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Памылка пачатку запісу экрана"</string>
@@ -363,7 +361,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Новы карыстальнік"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Інтэрнэт"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Бяспечныя ў самалёце"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Сеткі даступныя"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Сеткі недаступныя"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Няма падключэння"</string>
@@ -419,7 +416,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Да ўсходу сонца"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Уключана ў <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Да <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Паменшыць яркасць"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC адключаны"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC уключаны"</string>
@@ -474,7 +470,6 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Паказаць профіль"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Дадаць карыстальніка"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Новы карыстальнік"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Завяршыць гасцявы сеанс"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Выдаліць госця?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Усе праграмы і даныя гэтага сеанса будуць выдалены."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Выдаліць"</string>
@@ -489,7 +484,7 @@
     <string name="user_logout_notification_text" msgid="7441286737342997991">"Выканаць выхад бягучага карыстальніка"</string>
     <string name="user_logout_notification_action" msgid="7974458760719361881">"ВЫКАНАЦЬ ВЫХАД КАРЫСТАЛЬНІКА"</string>
     <string name="user_add_user_title" msgid="4172327541504825032">"Дадаць новага карыстальніка?"</string>
-    <string name="user_add_user_message_short" msgid="2599370307878014791">"Пасля стварэння профіля яго трэба наладзіць.\n\nЛюбы карыстальнік прылады можа абнаўляць праграмы ўсіх іншых карыстальнікаў."</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Пасля стварэння профілю яго трэба наладзіць.\n\nЛюбы карыстальнік прылады можа абнаўляць праграмы ўсіх іншых карыстальнікаў."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Дасягнуты ліміт карыстальнікаў"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">Можна дадаць <xliff:g id="COUNT">%d</xliff:g> карыстальніка.</item>
@@ -525,6 +520,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Гэта прылада знаходзіцца пад кантролем вашых бацькоў"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Ваша арганізацыя валодае гэтай прыладай і можа кантраляваць сеткавы трафік"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> валодае гэтай прыладай і можа кантраляваць сеткавы трафік"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Гэта прылада належыць арганізацыі \"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>\""</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Гэта прылада належыць вашай арганізацыі і падключана да праграмы \"<xliff:g id="VPN_APP">%1$s</xliff:g>\""</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Гэта прылада належыць арганізацыі \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\" і падключана да праграмы \"<xliff:g id="VPN_APP">%2$s</xliff:g>\""</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Гэта прылада належыць вашай арганізацыі"</string>
@@ -538,6 +534,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Ваш працоўны профіль падключаны да праграмы \"<xliff:g id="VPN_APP">%1$s</xliff:g>\""</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Ваш асабісты профіль падключаны да праграмы \"<xliff:g id="VPN_APP">%1$s</xliff:g>\""</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Гэта прылада падключана да праграмы \"<xliff:g id="VPN_APP">%1$s</xliff:g>\""</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Гэта прылада належыць арганізацыі \"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>\""</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Кіраванне прыладай"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Маніторынг профіляў"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Маніторынг сеткі"</string>
@@ -549,6 +546,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Праглядзець палітыку"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Праглядзець даныя пра кантроль"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Гэта прылада належыць арганізацыі \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\".\n\nВаш ІТ-адміністратар можа адсочваць налады, карпаратыўны доступ, праграмы, даныя, звязаныя з вашай прыладай, і звесткі пра яе месцазнаходжанне, а таксама кіраваць імі.\n\nПа дадатковую інфармацыю звярніцеся да ІТ-адміністратара."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> зможа кіраваць праграмамі, мець доступ да даных, звязаных з гэтай прыладай, і змяняць яе налады.\n\nКалі ў вас ёсць пытанні, звярніцеся ў арганізацыю \"<xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>\"."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Гэта прылада належыць вашай арганізацыі.\n\nВаш ІТ-адміністратар можа адсочваць налады, карпаратыўны доступ, праграмы, даныя, звязаныя з вашай прыладай, і звесткі пра яе месцазнаходжанне, а таксама кіраваць імі.\n\nПа дадатковую інфармацыю звярніцеся да ІТ-адміністратара."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Ваша арганізацыя ўсталявала на гэтай прыладзе цэнтр сертыфікацыі. Ваш абаронены сеткавы трафік могуць праглядваць ці змяняць."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Ваша арганізацыя ўсталявала ў вашым працоўным профілі цэнтр сертыфікацыі. Ваш абаронены сеткавы трафік могуць праглядваць ці змяняць."</string>
@@ -659,6 +657,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Паказваць дэманстрацыйны рэжым"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Будзільнік"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Кашалёк"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Гатова"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Працоўны профіль"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Рэжым палёту"</string>
     <string name="add_tile" msgid="6239678623873086686">"Дадаць плітку"</string>
@@ -909,11 +909,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Закрыць хуткія налады."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Будзільнік пастаўлены."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Вы ўвайшлі як <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"выбраць карыстальніка"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Няма падключэння да інтэрнэту"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Паказаць падрабязную інфармацыю."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"Прычына недаступнасці: <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Адкрыць налады <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Змяніць парадак налад."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Меню кнопкі сілкавання"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Старонка <xliff:g id="ID_1">%1$d</xliff:g> з <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Экран блакіроўкі"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"З-за перагрэву тэл. выключыўся"</string>
@@ -1021,9 +1023,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Перамясціць улева"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Перамясціць управа"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Пераключальнік павелічэння"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Павялічыць на ўвесь экран"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Павялічыць увесь экран"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Павялічыць частку экрана"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Пераключальнік"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"Замест жэста спецыяльных магчымасцей будзе выкарыстоўвацца кнопка\n\n"<annotation id="link">"Праглядзець налады"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Каб часова схаваць кнопку, перамясціце яе на край"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Элементы кіравання прыладай"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Дадайце элементы кіравання для падключаных прылад"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Наладзіць элементы кіравання прыладай"</string>
@@ -1093,6 +1097,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Спалучыць з новай прыладай"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Віджэты размовы"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Націсніце на размову, каб дадаць яе на галоўны экран"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> таму"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"Менш за <xliff:g id="DURATION">%1$s</xliff:g> таму"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"Больш за <xliff:g id="DURATION">%1$s</xliff:g> таму"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Дзень нараджэння"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Хутка свята"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Гадавіна"</string>
+    <string name="location_status" msgid="1294990572202541812">"Абагульваецца месца"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Новая гісторыя"</string>
+    <string name="video_status" msgid="4548544654316843225">"Ідзе прагляд відэа"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Гаварыце"</string>
+    <string name="game_status" msgid="1340694320630973259">"Ідзе гульня"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Сябры"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Паразмаўляем у чаце!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"Прапушчаны выклік"</string>
+    <string name="people_tile_description" msgid="8154966188085545556">"Глядзець нядаўнія паведамленні, прапушчаныя выклікі і абнаўленні стану"</string>
+    <string name="people_tile_title" msgid="6589377493334871272">"Размова"</string>
     <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Праблема з чытаннем індыкатара зараду акумулятара"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Націсніце, каб убачыць больш"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Няма будзільнікаў"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 4046f0f..1ca2595 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Отказ"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Споделяне"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Записването на екрана е анулирано"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Записът на екрана е запазен"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Докоснете за преглед"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"При изтриването на записа на екрана възникна грешка"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Извличането на разрешенията не бе успешно."</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"При стартирането на записа на екрана възникна грешка"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Нов потребител"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Интернет"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Безопасно в самолети"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Налице са мрежи"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Няма достъпни мрежи"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Няма връзка"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"До изгрев"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Ще се включи в <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"До <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Намаляване на яркостта"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"КБП е деактивирана"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"КБП е активирана"</string>
@@ -470,7 +466,6 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Показване на потребителския профил"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Добавяне на потребител"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Нов потребител"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Прекратяване на сесията като гост"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Да се премахне ли гостът?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Всички приложения и данни в тази сесия ще бъдат изтрити."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Премахване"</string>
@@ -484,7 +479,7 @@
     <string name="user_logout_notification_title" msgid="3644848998053832589">"Излизане на потребителя"</string>
     <string name="user_logout_notification_text" msgid="7441286737342997991">"Излезте от профила на текущия потребител"</string>
     <string name="user_logout_notification_action" msgid="7974458760719361881">"ИЗЛИЗАНЕ НА ПОТРЕБИТЕЛЯ"</string>
-    <string name="user_add_user_title" msgid="4172327541504825032">"Да се добави ли нов потреб.?"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Да се добави ли нов потребител?"</string>
     <string name="user_add_user_message_short" msgid="2599370307878014791">"Когато добавите нов потребител, той трябва да настрои работното си пространство.\n\nВсеки потребител може да актуализира приложенията за всички останали потребители."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Достигнахте огранич. за потребители"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Това устройство се управлява от родителя ви"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Организацията ви притежава това устройство и може да наблюдава трафика в мрежата"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> притежава това устройство и може да наблюдава трафика в мрежата"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Това устройство е предоставено от <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Това устройство принадлежи на организацията ви и е свързано с(ъс) <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Това устройство принадлежи на <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> и е свързано с(ъс) <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Това устройство принадлежи на организацията ви"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Служебният ви потребителски профил е свързан с(ъс) <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Личният ви потребителски профил е свързан с(ъс) <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Това устройство е свързано с(ъс) <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Това устройство е предоставено от <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Управление на устройствата"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Наблюдаване на потр. профил"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Наблюдение на мрежата"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Преглед на правилата"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Преглед на контролите"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Това устройство принадлежи на <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nСистемният ви администратор може да наблюдава и управлява настройките, корпоративния достъп, приложенията, свързаните с устройството данни и информацията за местоположението му.\n\nЗа повече информация се обърнете към него."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> може да има достъп до свързаните с това устройство данни, да управлява приложенията и да променя настройките му.\n\nОбърнете се към <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>, ако имате въпроси."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Това устройство принадлежи на организацията ви.\n\nСистемният ви администратор може да наблюдава и управлява настройките, корпоративния достъп, приложенията, свързаните с устройството данни и информацията за местоположението му.\n\nЗа повече информация се обърнете към него."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Организацията ви е инсталирала сертифициращ орган на това устройство. Трафикът в защитената ви мрежа може да бъде наблюдаван или променян."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Организацията ви е инсталирала сертифициращ орган в служебния ви потребителски профил. Трафикът в защитената ви мрежа може да бъде наблюдаван или променян."</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Показване на демонстрационния режим"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Будилник"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Портфейл"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Готово"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Потребителски профил в Work"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Самолетен режим"</string>
     <string name="add_tile" msgid="6239678623873086686">"Добавяне на плочка"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Затваряне на бързите настройки."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Будилникът е навит."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Влезли сте като <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"изберете потребител"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Няма връзка с интернет"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Отвaряне на страницата с подробности."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"Няма достъп, защото <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Отваряне на настройките за <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Редактиране на подредбата на настройките."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Меню за включване/изключване"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Страница <xliff:g id="ID_1">%1$d</xliff:g> от <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Заключен екран"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"Тел. се изкл. поради загряване"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Преместване наляво"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Преместване надясно"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Превключване на увеличението"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Увеличаване на целия екран"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Увеличаване на целия екран"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Увеличаване на част от екрана"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Превключване"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"Жестът за достъпност бе заменен от бутон\n\n"<annotation id="link">"Преглед на настройките"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Преместете бутона до края, за да го скриете временно"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Контроли за устройството"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Добавяне на контроли за свързаните ви устройства"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Настройване на контролите за устройството"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Сдвояване на ново устройство"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Приспособления за разговор"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Докоснете разговор, за да го добавите към началния си екран"</string>
+    <string name="timestamp" msgid="6577851592534538533">"Преди <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"Преди по-малко от <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"Преди повече от <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Рожден ден"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Предстоящ рожден ден"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Годишнина"</string>
+    <string name="location_status" msgid="1294990572202541812">"Местопол. се споделя"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Нова история"</string>
+    <string name="video_status" msgid="4548544654316843225">"Гледате"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Слуша се"</string>
+    <string name="game_status" msgid="1340694320630973259">"Играете"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Приятели"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Да разговаряме!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"Пропуснато обаждане"</string>
+    <string name="people_tile_description" msgid="8154966188085545556">"Преглеждайте скорошните съобщения, пропуснатите обаждания и актуална информация за състоянието"</string>
+    <string name="people_tile_title" msgid="6589377493334871272">"Разговор"</string>
     <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Възникна проблем при четенето на данните за нивото на батерията"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Докоснете за още информация"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Няма зададен будилник"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index c88b578..2bf9f29 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"বাতিল করুন"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"শেয়ার করুন"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"স্ক্রিন রেকর্ডিং বাতিল করা হয়েছে"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"স্ক্রিন রেকর্ডিং সেভ করা হয়েছে"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"দেখতে ট্যাপ করুন"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"স্ক্রিন রেকডিং মুছে ফেলার সময় সমস্যা হয়েছে"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"অনুমতি পাওয়া যায়নি"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"স্ক্রিন রেকর্ডিং শুরু করার সময় সমস্যা হয়েছে"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"নতুন ব্যবহারকারী"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"ওয়াই-ফাই"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"ইন্টারনেট"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"বিমানের জন্য নিরাপদ"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"নেটওয়ার্ক উপলভ্য"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"নেটওয়ার্ক উপলভ্য নেই"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"সংযুক্ত নয়"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"সূর্যোদয় পর্যন্ত"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g>-এ চালু হবে"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> পর্যন্ত"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"উজ্জ্বলতা কমান"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC অক্ষম করা আছে"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC সক্ষম করা আছে"</string>
@@ -470,14 +466,13 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"প্রোফাইল দেখান"</string>
     <string name="user_add_user" msgid="4336657383006913022">"ব্যবহারকারী জুড়ুন"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"নতুন ব্যবহারকারী"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"গেস্ট সেশন শেষ করুন"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"অতিথি সরাবেন?"</string>
-    <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"এই সেশনের সব অ্যাপ্লিকেশান ও ডেটা মুছে ফেলা হবে।"</string>
+    <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"এই সেশনের সব অ্যাপ ও ডেটা মুছে ফেলা হবে।"</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"সরান"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"অতিথি, আপনি ফিরে আসায় আপনাকে স্বাগত!"</string>
-    <string name="guest_wipe_session_message" msgid="3393823610257065457">"আপনি কি আপনার সেশনটি অবিরত রাখতে চান?"</string>
+    <string name="guest_wipe_session_message" msgid="3393823610257065457">"আপনি কি আপনার সেশনটি চালিয়ে যেতে চান?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"আবার শুরু করুন"</string>
-    <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"হ্যাঁ, অবিরত থাকুন"</string>
+    <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"হ্যাঁ, চালিয়ে যান"</string>
     <string name="guest_notification_title" msgid="4434456703930764167">"অতিথি ব্যবহারকারী"</string>
     <string name="guest_notification_text" msgid="4202692942089571351">"অ্যাপ্লিকেশান এবং ডেটা মুছে ফেলার জন্য অতিথি ব্যবহারকারী সরান।"</string>
     <string name="guest_notification_remove_action" msgid="4153019027696868099">"অতিথি সরান"</string>
@@ -485,7 +480,7 @@
     <string name="user_logout_notification_text" msgid="7441286737342997991">"বর্তমান ব্যবহারকারীকে লগ-আউট করুন"</string>
     <string name="user_logout_notification_action" msgid="7974458760719361881">"ব্যবহারকারীকে লগ-আউট করুন"</string>
     <string name="user_add_user_title" msgid="4172327541504825032">"নতুন ব্যবহারকারীকে যোগ করবেন?"</string>
-    <string name="user_add_user_message_short" msgid="2599370307878014791">"আপনি একজন নতুন ব্যবহারকারী যোগ করলে তাকে তার জায়গা সেট-আপ করে নিতে হবে৷\n\nযেকোনো ব্যবহারকারী অন্য সব ব্যবহারকারীর জন্য অ্যাপ্লিকেশান আপডেট করতে পারবেন৷"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"আপনি একজন নতুন ব্যবহারকারী যোগ করলে তাকে তার জায়গা সেট-আপ করে নিতে হবে৷\n\nযেকোনও ব্যবহারকারী অন্য সব ব্যবহারকারীর জন্য অ্যাপ আপডেট করতে পারবেন৷"</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"আর কোনও প্রোফাইল যোগ করা যাবে না"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">আপনি <xliff:g id="COUNT">%d</xliff:g> জন পর্যন্ত ব্যবহারকারীর প্রোফাইল যোগ করতে পারেন।</item>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"আপনার অভিভাবক এই ডিভাইস ম্যানেজ করেন"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"এই ডিভাইসটি আপনার প্রতিষ্ঠানের এবং এরা ডিভাইসের নেটওয়ার্ক ট্রাফিক মনিটর করতে পারে"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> এই ডিভাইসের মালিক এবং এটির নেটওয়ার্ক ট্রাফিক মনিটর করতে পারে"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"এই ডিভাইস <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> দিয়েছে"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"এই ডিভাইসটি আপনার প্রতিষ্ঠানের এবং <xliff:g id="VPN_APP">%1$s</xliff:g>-এ কানেক্ট করা আছে"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"এই ডিভাইস <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>-এর এবং <xliff:g id="VPN_APP">%2$s</xliff:g>-এ কানেক্ট করা আছে"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"এই ডিভাইসটি আপনার প্রতিষ্ঠানের"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"<xliff:g id="VPN_APP">%1$s</xliff:g>-এ আপনার অফিস প্রোফাইল কানেক্ট করা রয়েছে"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"আপনার ব্যক্তিগত প্রোফাইল <xliff:g id="VPN_APP">%1$s</xliff:g>-এ কানেক্ট করা আছে"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"এই ডিভাইস <xliff:g id="VPN_APP">%1$s</xliff:g>-এ কানেক্ট করা আছে"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"এই ডিভাইস <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> দিয়েছে"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"ডিভাইসের পরিচালনা"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"প্রোফাইল দেখরেখ করা"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"নেটওয়ার্ক নিরীক্ষণ"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"নীতিগুলি দেখুন"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"কন্ট্রোল দেখুন"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"এই ডিভাইসটি <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>-এর।\n\nআপনার আইটি অ্যাডমিন এই ডিভাইসের সেটিংস, কর্পোরেট অ্যাক্সেস, অ্যাপ, ডিভাইসের সাথে সম্পর্কিত ডেটা এবং ডিভাইসের লোকেশন সম্পর্কিত ডেটা মনিটর ও ম্যানেজ করতে পারে।\n\nআরও তথ্যের জন্য আপনার আইটি অ্যাডমিনের সাথে যোগাযোগ করুন।"</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> হয়ত এই ডিভাইস সম্পর্কিত ডেটা ব্যবহার করতে, অ্যাপ ম্যানেজ করতে এবং এই ডিভাইসের সেটিংস পরিবর্তন করতে পারবে।\n\nকোনও প্রশ্ন থাকলে, <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>-এর সাথে যোগাযোগ করুন।"</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"এই ডিভাইসটি আপনার প্রতিষ্ঠানের।\n\nআপনার আইটি অ্যাডমিন এই ডিভাইসের সেটিংস, কর্পোরেট অ্যাক্সেস, অ্যাপ, ডিভাইসের সাথে সম্পর্কিত ডেটা এবং ডিভাইসের লোকেশন সম্পর্কিত ডেটা মনিটর ও ম্যানেজ করতে পারে।\n\nআরও তথ্যের জন্য আপনার আইটি অ্যাডমিনের সাথে যোগাযোগ করুন।"</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"আপনার প্রতিষ্ঠান আপনার অফিস প্রোফাইলে একটি সার্টিফিকেট কর্তৃপক্ষ ইনস্টল করেছে।আপনার সুরক্ষিত নেটওয়ার্ক ট্রাফিক নিরীক্ষণ বা পরিবর্তন করা হতে পারে।"</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"আপনার প্রতিষ্ঠান আপনার অফিস প্রোফাইলে একটি সার্টিফিকেট কর্তৃপক্ষ ইনস্টল করেছে। আপনার নিরাপদ নেটওয়ার্ক ট্রাফিকে নজর রাখা হতে পারে বা তাতে পরিবর্তন করা হতে পারে।"</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"ডেমো মোড দেখান"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"ইথারনেট"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"অ্যালার্ম"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"তৈরি"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"কাজের প্রোফাইল"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"বিমান মোড"</string>
     <string name="add_tile" msgid="6239678623873086686">"টাইল যোগ করুন"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"দ্রুত সেটিংস বন্ধ করুন৷"</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"অ্যালার্ম সেট করা হয়েছে৷"</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"<xliff:g id="ID_1">%s</xliff:g> হিসেবে প্রবেশ করে রয়েছেন"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"ব্যবহারকারী বেছে নিন"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"ইন্টারনেট কানেকশন নেই"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"বিশদ বিবরণ খুলুন৷"</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"<xliff:g id="REASON">%s</xliff:g>-এর জন্য পাওয়া যাবে না"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> সেটিংস খুলুন৷"</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"ক্রম বা সেটিংস সম্পাদনা করুন৷"</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"পাওয়ার মেনু"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g>টির মধ্যে <xliff:g id="ID_1">%1$d</xliff:g> নং পৃষ্ঠা"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"লক স্ক্রিন"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"আপনার ফোন গরম হওয়ার জন্য বন্ধ হয়ে গেছে"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"বাঁদিকে সরান"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"ডানদিকে সরান"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"বড় করে দেখার সুইচ"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"ফুল-স্ক্রিন মোডে দেখুন"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"সম্পূর্ণ স্ক্রিন বড় করে দেখা"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"স্ক্রিনের কিছুটা অংশ বড় করুন"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"বদল করুন"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"অ্যাক্সেসিবিলিটি জেসচার পরিবর্তন করে অ্যাক্সেসেবিলিটি বোতাম করা হয়েছে\n\n"<annotation id="link">"সেটিংস দেখুন"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"এটি অস্থায়ীভাবে লুকাতে বোতামটি কোণে সরান"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"ডিভাইস কন্ট্রোল"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"আপনার কানেক্ট করা ডিভাইসের জন্য কন্ট্রোল যোগ করুন"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"ডিভাইস কন্ট্রোল সেট-আপ করুন"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"নতুন ডিভাইস পেয়ার করুন"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"কথোপকথন উইজেট"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"কোনও কথোপথন আপনার হোম স্ক্রিনে যোগ করার জন্য এতে ট্যাপ করুন"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> ঘণ্টা আগে"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"<xliff:g id="DURATION">%1$s</xliff:g> থেকে কিছু কম সময় আগে"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"<xliff:g id="DURATION">%1$s</xliff:g> সপ্তাহেরও আগে"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"জন্মদিন"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"জন্মদিন শীঘ্রই আসছে"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"বার্ষিকী"</string>
+    <string name="location_status" msgid="1294990572202541812">"লোকেশন শেয়ার করা হচ্ছে"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"নতুন খবর"</string>
+    <string name="video_status" msgid="4548544654316843225">"দেখছি"</string>
+    <string name="audio_status" msgid="4237055636967709208">"অডিও শুনছি"</string>
+    <string name="game_status" msgid="1340694320630973259">"চালানো হচ্ছে"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"বন্ধু"</string>
+    <string name="empty_status" msgid="5938893404951307749">"আজ রাতে চ্যাট করা যাক!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"মিসড কল"</string>
+    <string name="people_tile_description" msgid="8154966188085545556">"সাম্প্রতিক মেসেজ, মিসড কল এবং স্ট্যাটাস সংক্রান্ত আপডেট দেখুন"</string>
+    <string name="people_tile_title" msgid="6589377493334871272">"কথোপকথন"</string>
     <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"ব্যাটারির মিটারের রিডিং নেওয়ার সময় সমস্যা হয়েছে"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"আরও তথ্যের জন্য ট্যাপ করুন"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"কোনও অ্যালার্ম সেট করা নেই"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index ed605d4..67e58dd 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Otkaži"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Dijeli"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Snimanje ekrana je otkazano"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Snimak ekrana je sačuvan"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Dodirnite da vidite"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Greška prilikom brisanja snimka ekrana"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Dobijanje odobrenja nije uspjelo"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Greška pri pokretanju snimanja ekrana"</string>
@@ -362,7 +360,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Novi korisnik"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"WiFi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Internet"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Sigurno za korištenje u avionu"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Mreže su dostupne"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Mreže nisu dostupne"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Nije povezano"</string>
@@ -417,7 +414,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Do svitanja"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Uključuje se u <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Do <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Smanjenje osvjetljenja"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC je onemogućen"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC je omogućen"</string>
@@ -472,9 +468,8 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Pokaži profil"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Dodaj korisnika"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Novi korisnik"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Završi sesiju gosta"</string>
-    <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Želite li ukloniti gosta?"</string>
-    <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Sve aplikacije i svi podaci iz ove sesije bit će izbrisani."</string>
+    <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Ukloniti gosta?"</string>
+    <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Sve aplikacije i podaci iz ove sesije će se izbrisati."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Ukloni"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"Zdravo! Lijepo je opet vidjeti goste."</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Želite li nastaviti sesiju?"</string>
@@ -486,7 +481,7 @@
     <string name="user_logout_notification_title" msgid="3644848998053832589">"Odjavi korisnika"</string>
     <string name="user_logout_notification_text" msgid="7441286737342997991">"Odjavi trenutnog korisnika"</string>
     <string name="user_logout_notification_action" msgid="7974458760719361881">"ODJAVI KORISNIKA"</string>
-    <string name="user_add_user_title" msgid="4172327541504825032">"Želite dodati novog korisnika?"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Dodati novog korisnika?"</string>
     <string name="user_add_user_message_short" msgid="2599370307878014791">"Kada dodate novog korisnika, ta osoba treba postaviti svoj prostor.\n\nSvaki korisnik može ažurirati aplikacije za sve ostale korisnike."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Dostignut limit za broj korisnika"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
@@ -522,6 +517,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Ovim uređajem upravlja tvoj roditelj"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Vaša organizacija je vlasnik ovog uređaja i može nadzirati mrežni saobraćaj"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> upravlja ovim uređajem i može nadzirati mrežni saobraćaj"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Ovaj uređaj pruža <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Ovaj uređaj pripada vašoj organizaciji i povezan je s aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> i povezan je s aplikacijom <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Ovaj uređaj pripada vašoj organizaciji"</string>
@@ -535,6 +531,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Vaš radni profil je povezan s aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Vaš lični profil je povezan s aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Ovaj uređaj je povezan s aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Ovaj uređaj pruža <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Upravljanje uređajem"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Praćenje profila"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Praćenje mreže"</string>
@@ -546,6 +543,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Prikaži pravila"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Prikaži kontrole"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nVaš IT administrator može nadzirati postavke, korporativni pristup, aplikacije, podatke povezane s vašim uređajem i informacije o lokaciji uređaja te njima upravljati.\n\nZa više informacija kontaktirajte IT administratora."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> će moći pristupiti podacima povezanim s ovim uređajem, upravljati aplikacijama i promijeniti postavke uređaja.\n\nAko imate pitanja, kontaktirajte organizaciju <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Ovaj uređaj pripada vašoj organizaciji.\n\nVaš IT administrator može nadzirati postavke, korporativni pristup, aplikacije, podatke povezane s vašim uređajem i informacije o lokaciji uređaja te njima upravljati.\n\nZa više informacija kontaktirajte IT administratora."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Vaša organizacija je instalirala CA certifikat na ovom uređaju. Vaš saobraćaj preko sigurne mreže može se pratiti."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Vaša organizacija je instalirala CA certifikat na vašem radnom profilu. Vaš saobraćaj preko sigurne mreže može se pratiti."</string>
@@ -656,6 +654,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Prikaži način rada za demonstraciju"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Alarm"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Novčanik"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Spremno"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Profil za posao"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Način rada u avionu"</string>
     <string name="add_tile" msgid="6239678623873086686">"Dodaj pločicu"</string>
@@ -904,11 +904,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Zatvoriti brze postavke."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Alarm postavljen."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Prijavljeni ste kao <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"odaberete korisnika"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Nema internetske veze"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Otvori detalje."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"Nije dostupno zbog razloga <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Otvori postavke za: <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Urediti raspored postavki."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Meni napajanja"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Stranica <xliff:g id="ID_1">%1$d</xliff:g> od <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Zaključavanje ekrana"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"Telefon se isključio zbog pregrijavanja"</string>
@@ -1016,9 +1018,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Pomjeranje lijevo"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Pomjeranje desno"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Prekidač za uvećavanje"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Uvećavanje cijelog ekrana"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Uvećavanje prikaza preko cijelog ekrana"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Uvećavanje dijela ekrana"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Prekidač"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"Dugme za pristupačnost je zamijenilo pokret za pristupačnost\n\n"<annotation id="link">"Prikaži postavke"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Premjestite dugme do ivice da ga privremeno sakrijete"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Kontrole uređaja"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Dodajte kontrole za povezane uređaje"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Postavite kontrole uređaja"</string>
@@ -1087,6 +1091,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Uparite novi uređaj"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Vidžeti za razgovor"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Dodirnite razgovor da ga dodate na početni ekran"</string>
+    <string name="timestamp" msgid="6577851592534538533">"Prije <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"Prije manje od <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"Prije više od <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Rođendan"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Rođendan je uskoro"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Godišnjica"</string>
+    <string name="location_status" msgid="1294990572202541812">"Dijeljenje lokacije"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Nova priča"</string>
+    <string name="video_status" msgid="4548544654316843225">"Gleda"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Slušanje"</string>
+    <string name="game_status" msgid="1340694320630973259">"Reproduciranje"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Prijatelji"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Chatajmo večeras!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"Propušteni poziv"</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="battery_state_unknown_notification_title" msgid="8464703640483773454">"Došlo je do problema prilikom očitavanja mjerača stanja baterije"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Dodirnite za više informacija"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nije postavljen alarm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 95775e9..6bdf4de 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Cancel·la"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Comparteix"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"S\'ha cancel·lat la gravació de la pantalla"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"S\'ha desat la gravació de pantalla"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Toca per veure-la"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"S\'ha produït un error en suprimir la gravació de la pantalla"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"No s\'han pogut obtenir els permisos"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"S\'ha produït un error en iniciar la gravació de pantalla"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Usuari nou"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Internet"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Mode d\'avió"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Xarxes disponibles"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Xarxes no disponibles"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Desconnectat"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Fins a l\'alba"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Activat a les <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Fins a les <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Reducció de la brillantor"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"L\'NFC està desactivada"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"L\'NFC està activada"</string>
@@ -470,7 +466,6 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Mostra el perfil"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Afegeix un usuari"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Usuari nou"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Finalitza la sessió de convidat"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Vols suprimir el convidat?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Totes les aplicacions i les dades d\'aquesta sessió se suprimiran."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Suprimeix"</string>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Els teus pares gestionen aquest dispositiu"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"La teva organització és propietària del dispositiu i és possible que supervisi el trànsit de xarxa"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> és propietària d\'aquest dispositiu i és possible que supervisi el trànsit de xarxa"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> proporciona aquest dispositiu"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Aquest dispositiu pertany a la teva organització i està connectat a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Aquest dispositiu pertany a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> i està connectat a <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Aquest dispositiu pertany a la teva organització"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"El teu perfil de treball està connectat a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"El teu perfil personal està connectat a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Aquest dispositiu està connectat a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> proporciona aquest dispositiu"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Gestió del dispositiu"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Supervisió del perfil"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Supervisió de la xarxa"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Consulta les polítiques"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Mostra els controls"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"El dispositiu pertany a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nL\'administrador de TI pot supervisar i gestionar la configuració, l\'accés corporatiu, les aplicacions, les dades associades al dispositiu i la informació d\'ubicació.\n\nPer obtenir més informació, contacta amb l\'administrador de TI."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"És possible que <xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> pugui canviar la configuració d\'aquest dispositiu, accedir a les dades que hi estiguin associades i gestionar les aplicacions.\n\nSi tens cap pregunta, contacta amb <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"El dispositiu pertany a la teva organització.\n\nL\'administrador de TI pot supervisar i gestionar la configuració, l\'accés corporatiu, les aplicacions, les dades associades al dispositiu i la informació d\'ubicació.\n\nPer obtenir més informació, contacta amb l\'administrador de TI."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"La teva organització ha instal·lat una autoritat de certificació en aquest dispositiu. És possible que el trànsit a la xarxa segura se supervisi o es modifiqui."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"La teva organització ha instal·lat una autoritat de certificació al teu perfil de treball. És possible que el trànsit de xarxa segura se supervisi o es modifiqui."</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Mostra el mode de demostració"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Alarma"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"A punt"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Perfil de treball"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Mode d\'avió"</string>
     <string name="add_tile" msgid="6239678623873086686">"Afegeix un mosaic"</string>
@@ -721,7 +721,7 @@
     <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"&lt;b&gt;Estat&lt;/b&gt;: s\'ha disminuït a Silenci"</string>
     <string name="notification_channel_summary_automatic_promoted" msgid="1301710305149590426">"&lt;b&gt;Estat&lt;/b&gt;: s\'ha classificat amb un nivell superior"</string>
     <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" msgid="7952654515769021553">"Es mostra com a bombolla flotant a la part superior de la secció de converses i mostra la foto de perfil a la pantalla de bloqueig"</string>
+    <string name="notification_channel_summary_priority" msgid="7952654515769021553">"Es mostra com a bombolla flotant a la part superior de la secció de converses i la foto de perfil apareix a la pantalla de bloqueig"</string>
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Configuració"</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>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Tanca la configuració ràpida."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"S\'ha configurat l\'alarma."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"S\'ha iniciat la sessió com a <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"triar un usuari"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Sense connexió a Internet"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Obre la informació detallada."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"No està disponible pel motiu següent: <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Obre la configuració per a <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Edita l\'ordre de la configuració."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menú d\'engegada"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Pàgina <xliff:g id="ID_1">%1$d</xliff:g> (<xliff:g id="ID_2">%2$d</xliff:g> en total)"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Pantalla de bloqueig"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"Telèfon apagat per la calor"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Mou cap a l\'esquerra"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Mou cap a la dreta"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Canvia al mode d\'ampliació"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Amplia tota la pantalla"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Amplia la pantalla completa"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Amplia una part de la pantalla"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Canvia"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"El gest d\'accessibilitat s\'ha substituït pel botó d\'accessibilitat\n\n"<annotation id="link">"Mostra la configuració"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Mou el botó a l\'extrem per amagar-lo temporalment"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Controls de dispositius"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Afegeix controls per als teus dispositius connectats"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Configura els controls de dispositius"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Vincula un dispositiu nou"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Widgets de conversa"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Toca una conversa per afegir-la a la teva pantalla d\'inici"</string>
+    <string name="timestamp" msgid="6577851592534538533">"Fa <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"Fa menys de: <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"Fa més de: <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Aniversari"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Aniversari aviat"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Aniversari"</string>
+    <string name="location_status" msgid="1294990572202541812">"Compartint la ubicació"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Història nova"</string>
+    <string name="video_status" msgid="4548544654316843225">"Mirant"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Escoltant"</string>
+    <string name="game_status" msgid="1340694320630973259">"Jugant"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Amics"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Parlem aquesta nit!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"Trucada perduda"</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="battery_state_unknown_notification_title" msgid="8464703640483773454">"Hi ha hagut un problema en llegir el mesurador de la bateria"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Toca per obtenir més informació"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Cap alarma configurada"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 8f86d42..67901a7 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Zrušit"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Sdílet"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Nahrávání obrazovky bylo zrušeno"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Nahrávka obrazovky byla uložena"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Nahrávku zobrazíte klepnutím"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Při mazání záznamu obrazovky došlo k chybě"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Nepodařilo se načíst oprávnění"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Při spouštění nahrávání obrazovky došlo k chybě"</string>
@@ -363,7 +361,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Nový uživatel"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Internet"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Použitelné v letadle"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Dostupné sítě"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Nedostupné sítě"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Nepřipojeno"</string>
@@ -419,7 +416,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Do svítání"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Zapnout v <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Do <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Snížit jas"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC je vypnuto"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC je zapnuto"</string>
@@ -474,7 +470,6 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Zobrazit profil"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Přidat uživatele"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Nový uživatel"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Ukončení relace hosta"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Odstranit hosta?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Veškeré aplikace a data v této relaci budou vymazána."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Odstranit"</string>
@@ -525,6 +520,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Toto zařízení spravuje rodič"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Toto zařízení vlastní vaše organizace, která může sledovat síťový provoz"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Toto zařízení spravuje organizace <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, která může sledovat síťový provoz"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Toto zařízení poskytuje organizace <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Toto zařízení patří vaší organizaci a je připojené k síti <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Toto zařízení patří organizaci <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> a je připojené k síti <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Toto zařízení patří vaší organizaci"</string>
@@ -538,6 +534,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Váš pracovní profil je připojen k síti <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Váš osobní profil je připojený k síti <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Toto zařízení je připojené k síti <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Toto zařízení poskytuje organizace <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Správa zařízení"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Monitoring profilu"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Sledování sítě"</string>
@@ -549,6 +546,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Zobrazit zásady"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Zobrazit ovládací prvky"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Toto zařízení patří organizaci <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nVáš administrátor IT může sledovat a spravovat nastavení, firemní přístup, aplikace, data přidružená k tomuto zařízení a jeho polohu.\n\nDalší informace vám poskytne váš administrátor IT."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"Organizace <xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> může přistupovat k datům spojeným s tímto zařízením, měnit jeho nastavení a spravovat aplikace.\n\nPokud máte nějaké otázky, obraťte se na organizaci <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Toto zařízení patří vaší organizaci\n\nVáš administrátor IT může sledovat a spravovat nastavení, firemní přístup, aplikace, data přidružená k tomuto zařízení a jeho polohu.\n\nDalší informace vám poskytne váš administrátor IT."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Organizace do tohoto zařízení nainstalovala certifikační autoritu. Zabezpečený síťový provoz může být sledován nebo upravován."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Organizace do vašeho pracovního profilu nainstalovala certifikační autoritu. Zabezpečený síťový provoz může být sledován nebo upravován."</string>
@@ -659,6 +657,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Zobrazit ukázkový režim"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Budík"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Peněženka"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Připraveno"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Pracovní profil"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Režim Letadlo"</string>
     <string name="add_tile" msgid="6239678623873086686">"Přidat dlaždici"</string>
@@ -727,7 +727,7 @@
     <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"&lt;b&gt;Stav:&lt;/b&gt; priorita snížena na Tiché"</string>
     <string name="notification_channel_summary_automatic_promoted" msgid="1301710305149590426">"&lt;b&gt;Stav:&lt;/b&gt; zařazeno výše"</string>
     <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" msgid="7952654515769021553">"Zobrazuje se v horní části sekce konverzací a má podobu plovoucí bubliny, zobrazuje profilovou fotku na obrazovce uzamčení"</string>
+    <string name="notification_channel_summary_priority" msgid="7952654515769021553">"Zobrazuje se v horní části sekce konverzací, má podobu plovoucí bubliny, zobrazuje profilovou fotku na obrazovce uzamčení"</string>
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Nastavení"</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>
@@ -909,11 +909,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Zavřít rychlé nastavení."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Budík je nastaven."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Jste přihlášeni jako <xliff:g id="ID_1">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"zvolit uživatele"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Nejste připojeni k internetu"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Otevřít podrobnosti."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"Nedostupné, protože <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Otevřít nastavení aplikace <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Upravit pořadí nastavení."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Nabídka vypínače"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Stránka <xliff:g id="ID_1">%1$d</xliff:g> z <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Obrazovka uzamčení"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"Telefon se vypnul z důvodu zahřátí"</string>
@@ -1021,9 +1023,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Přesunout doleva"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Přesunout doprava"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Přepínač zvětšení"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Zvětšit celou obrazovku"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Zvětšit celou obrazovku"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Zvětšit část obrazovky"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Přepnout"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"Tlačítko přístupnosti bylo nahrazeno gestem přístupnosti\n\n"<annotation id="link">"Zobrazit nastavení"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Přesunutím tlačítka k okraji ho dočasně skryjete"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Ovládání zařízení"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Přidejte ovládací prvky pro připojená zařízení"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Nastavení ovládání zařízení"</string>
@@ -1093,6 +1097,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Spárovat nové zařízení"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Widgety konverzací"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Klepnutím na konverzaci ji přidáte na plochu"</string>
+    <string name="timestamp" msgid="6577851592534538533">"Před <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"Před méně než <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"Před více než <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Narozeniny"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Brzy má narozeniny"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Výročí"</string>
+    <string name="location_status" msgid="1294990572202541812">"Sdílí polohu"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Nový příběh"</string>
+    <string name="video_status" msgid="4548544654316843225">"Sledování"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Poslouchám"</string>
+    <string name="game_status" msgid="1340694320630973259">"Hraje"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Přátelé"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Pojďme chatovat."</string>
+    <string name="missed_call" msgid="4228016077700161689">"Zmeškaný hovor"</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="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problém s načtením měřiče baterie"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Klepnutím zobrazíte další informace"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Budík nenastaven"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index aad5d25..489fb53 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Annuller"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Del"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Skærmoptagelsen er annulleret"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Skærmoptagelsen er gemt"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Tryk for at se"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Der opstod en fejl ved sletning af skærmoptagelsen"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Det lykkedes ikke et hente tilladelserne"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Skærmoptagelsen kunne ikke startes"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Ny bruger"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Internet"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Kan bruges i fly"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Tilgængelige netværk"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Ingen tilgængelige netværk"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Ikke forbundet"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Indtil solopgang"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Tænd kl. <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Indtil kl. <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Reducer lysstyrken"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC er deaktiveret"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC er aktiveret"</string>
@@ -470,7 +466,6 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Vis profil"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Tilføj bruger"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Ny bruger"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Afslut gæstesessionen"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Vil du fjerne gæsten?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle apps og data i denne session slettes."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Fjern"</string>
@@ -484,8 +479,8 @@
     <string name="user_logout_notification_title" msgid="3644848998053832589">"Log brugeren ud"</string>
     <string name="user_logout_notification_text" msgid="7441286737342997991">"Log den aktuelle bruger ud"</string>
     <string name="user_logout_notification_action" msgid="7974458760719361881">"LOG BRUGEREN UD"</string>
-    <string name="user_add_user_title" msgid="4172327541504825032">"Vil du tilføje den nye bruger?"</string>
-    <string name="user_add_user_message_short" msgid="2599370307878014791">"Når du tilføjer en ny bruger, skal personen konfigurere sit område.\n\nEnhver bruger kan opdatere apps for alle andre brugere."</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Vil du tilføje en ny bruger?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Når du tilføjer en ny bruger, skal personen konfigurere sit område.\n\nAlle brugere kan opdatere apps for alle de andre brugere."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Grænsen for antal brugere er nået"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">Du kan tilføje op til <xliff:g id="COUNT">%d</xliff:g> bruger.</item>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Denne enhed administreres af din forælder"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Din organisation ejer denne enhed og overvåger muligvis netværkstrafikken"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ejer denne enhed og overvåger muligvis netværkstrafikken"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Denne enhed er leveret af <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Denne enhed tilhører din organisation og har forbindelse til <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Denne enhed tilhører <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> og har forbindelse til <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Denne enhed tilhører din organisation"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Din arbejdsprofil har forbindelse til <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Din personlige profil har forbindelse til <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Denne enhed har forbindelse til <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Denne enhed er leveret af <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Administration af enheder"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Profilovervågning"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Overvågning af netværk"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Se politikker"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Se styringselementer"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Denne enhed tilhører <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nDin it-administrator kan overvåge og administrere indstillinger, virksomhedsadgang, apps, data, der er tilknyttet din enhed, og din enheds placeringsdata.\n\nKontakt din it-administrator for at få mere at vide."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> kan muligvis administrere apps, få adgang til data, der er tilknyttet denne enhed, og ændre enhedens indstillinger.\n\nKontakt <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>, hvis du har spørgsmål."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Denne enhed tilhører din organisation.\n\nDin it-administrator kan overvåge og administrere indstillinger, virksomhedsadgang, apps, data, der er tilknyttet din enhed, og din enheds placeringsdata.\n\nKontakt din it-administrator for at få mere at vide."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Din organisation har installeret et nøglecenter på denne enhed. Din sikre netværkstrafik kan overvåges eller ændres."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Din organisation har installeret et nøglecenter på din arbejdsprofil. Din sikre netværkstrafik kan overvåges eller ændres."</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Vis Demotilstand"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Alarm"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Klar"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Arbejdsprofil"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Flytilstand"</string>
     <string name="add_tile" msgid="6239678623873086686">"Tilføj et felt"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Luk Kvikmenu."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Alarmen er indstillet."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Logget ind som <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"vælge bruger"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Intet internet"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Åbn oplysninger."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"Ikke tilgængelig på grund af <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Åbn <xliff:g id="ID_1">%s</xliff:g>-indstillinger."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Rediger rækkefølgen af indstillinger."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menu for afbryderknappen"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Side <xliff:g id="ID_1">%1$d</xliff:g> af <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Låseskærm"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"Telefonen slukkede pga. varme"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Flyt til venstre"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Flyt til højre"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Skift forstørrelsestilstand"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Forstør hele skærmen"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Forstør hele skærmen"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Forstør en del af skærmen"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Skift"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"Knappen Hjælpefunktioner har erstattet bevægelsen for hjælpefunktioner\n\n"<annotation id="link">"Se indstillinger"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Flyt knappen til kanten for at skjule den midlertidigt"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Enhedsstyring"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Tilføj styring af dine tilsluttede enheder"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Konfigurer enhedsstyring"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Par ny enhed"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Samtalewidgets"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Tryk på en samtale for at føje den til din startskærm"</string>
+    <string name="timestamp" msgid="6577851592534538533">"For <xliff:g id="DURATION">%1$s</xliff:g> siden"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"For mindre end <xliff:g id="DURATION">%1$s</xliff:g> siden"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"For mere end <xliff:g id="DURATION">%1$s</xliff:g> siden"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Fødselsdag"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Fødselsdag snart"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Årsdag"</string>
+    <string name="location_status" msgid="1294990572202541812">"Deler placering"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Ny historie"</string>
+    <string name="video_status" msgid="4548544654316843225">"Ser"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Lytter"</string>
+    <string name="game_status" msgid="1340694320630973259">"Spiller"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Venner"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Lad os chatte i aften!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"Ubesvaret opkald"</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="battery_state_unknown_notification_title" msgid="8464703640483773454">"Der er problemer med at aflæse dit batteriniveau"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tryk for at få flere oplysninger"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Ingen alarm er indstillet"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 3266954..61e0758 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Abbrechen"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Teilen"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Bildschirmaufzeichnung abgebrochen"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Bildschirmaufzeichnung gespeichert"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Zum Ansehen tippen"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Fehler beim Löschen der Bildschirmaufzeichnung"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Berechtigungen nicht erhalten"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Fehler beim Start der Bildschirmaufzeichnung"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Neuer Nutzer"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"WLAN"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Internet"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Flugsicher"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Netzwerke verfügbar"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Netzwerke nicht verfügbar"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Nicht verbunden"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Bis Sonnenaufgang"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"An um <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Bis <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Helligkeit verringern"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC ist deaktiviert"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC ist aktiviert"</string>
@@ -470,7 +466,6 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Profil öffnen"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Nutzer hinzufügen"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Neuer Nutzer"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Gastsitzung beenden"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Gast entfernen?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle Apps und Daten in dieser Sitzung werden gelöscht."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Entfernen"</string>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Dieses Gerät wird von deinen Eltern verwaltet"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Deine Organisation verwaltet dieses Gerät und kann den Netzwerkverkehr überwachen"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ist der Eigentümer dieses Geräts und kann den Netzwerkverkehr überwachen"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Dieses Gerät wird von <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> zur Verfügung gestellt"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Dieses Gerät gehört deiner Organisation und ist mit <xliff:g id="VPN_APP">%1$s</xliff:g> verbunden"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Dieses Gerät gehört <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> und ist mit <xliff:g id="VPN_APP">%2$s</xliff:g> verbunden"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Dieses Gerät gehört deiner Organisation"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Dein Arbeitsprofil ist mit <xliff:g id="VPN_APP">%1$s</xliff:g> verbunden"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Dein privates Profil ist mit <xliff:g id="VPN_APP">%1$s</xliff:g> verbunden"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Dieses Gerät ist mit <xliff:g id="VPN_APP">%1$s</xliff:g> verbunden"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Dieses Gerät wird von <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> zur Verfügung gestellt"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Geräteverwaltung"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Profilüberwachung"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Netzwerküberwachung"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Richtlinien ansehen"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Jugendschutzeinstellungen"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Dieses Gerät gehört <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nDein IT-Administrator kann Einstellungen, Zugriffsrechte im Unternehmen, Apps, mit diesem Gerät verknüpfte Daten und die Standortdaten deines Geräts sehen und verwalten.\n\nWeitere Informationen erhältst du von deinem IT-Administrator."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> kann möglicherweise auf die Daten zugreifen, die mit diesem Gerät verknüpft sind, Apps verwalten und die Geräteeinstellungen ändern.\n\nFalls du Fragen hast, wende dich an <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Dieses Gerät gehört deiner Organisation.\n\nDein IT-Administrator kann Einstellungen, Zugriffsrechte im Unternehmen, Apps, mit diesem Gerät verknüpfte Daten und die Standortdaten deines Geräts sehen und verwalten.\n\nWeitere Informationen erhältst du von deinem IT-Administrator."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Deine Organisation hat ein Zertifikat einer Zertifizierungsstelle auf deinem Gerät installiert. Eventuell wird dein sicherer Netzwerkverkehr überwacht oder bearbeitet."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Deine Organisation hat ein Zertifikat einer Zertifizierungsstelle in deinem Arbeitsprofil installiert. Eventuell wird dein sicherer Netzwerkverkehr überwacht oder bearbeitet."</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Demomodus anzeigen"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Weckruf"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Bereit"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Arbeitsprofil"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Flugmodus"</string>
     <string name="add_tile" msgid="6239678623873086686">"Kachel hinzufügen"</string>
@@ -721,7 +721,7 @@
     <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"&lt;b&gt;Status&lt;/b&gt;: auf „Lautlos“ herabgestuft"</string>
     <string name="notification_channel_summary_automatic_promoted" msgid="1301710305149590426">"&lt;b&gt;Status&lt;/b&gt;: höher eingestuft"</string>
     <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" msgid="7952654515769021553">"Wird oben im Bereich \"Unterhaltungen\" als unverankerte Bubble mit einem Profilbild auf dem Sperrbildschirm angezeigt"</string>
+    <string name="notification_channel_summary_priority" msgid="7952654515769021553">"Wird oben im Bereich „Unterhaltungen“ als unverankerte Bubble angezeigt und erscheint mit einem Profilbild auf dem Sperrbildschirm"</string>
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Einstellungen"</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>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Schnelleinstellungen schließen."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Weckruf eingerichtet."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Angemeldet als <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"Nutzer auszuwählen"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Kein Internet"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Details öffnen."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"Aus diesem Grund nicht verfügbar: <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Einstellungen für <xliff:g id="ID_1">%s</xliff:g> öffnen."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Reihenfolge der Einstellungen bearbeiten."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Ein-/Aus-Menü"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Seite <xliff:g id="ID_1">%1$d</xliff:g> von <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Sperrbildschirm"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"Ausgeschaltet, da zu heiß"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Nach links bewegen"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Nach rechts bewegen"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Vergrößerungsschalter"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Ganzen Bildschirm vergrößern"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Ganzen Bildschirm vergrößern"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Teil des Bildschirms vergrößern"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Schalter"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"Die Schaltfläche „Bedienungshilfen“ ersetzt die Touch-Geste für Bedienungshilfen\n\n"<annotation id="link">"Einstellungen aufrufen"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Durch Ziehen an den Rand wird die Schaltfläche zeitweise ausgeblendet"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Gerätesteuerung"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Steuerelemente für verbundene Geräte hinzufügen"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Gerätesteuerung einrichten"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Neues Gerät koppeln"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Unterhaltungs-Widgets"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Tippe auf eine Unterhaltung, um sie deinem Startbildschirm hinzuzufügen"</string>
+    <string name="timestamp" msgid="6577851592534538533">"Vor <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"Vor weniger als <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"Vor über <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Geburtstag"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Bald Geburtstag"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Jahrestag"</string>
+    <string name="location_status" msgid="1294990572202541812">"Standort wird geteilt"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Neue Geschichte"</string>
+    <string name="video_status" msgid="4548544654316843225">"Schaut etwas"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Hört etwas"</string>
+    <string name="game_status" msgid="1340694320630973259">"Spielt"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Freunde"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Chat heute Abend!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"Verpasster Anruf"</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="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problem beim Lesen des Akkustands"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Für weitere Informationen tippen"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Kein Wecker gestellt"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 7ba7988..45d3f16 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Ακύρωση"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Κοινοποίηση"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Η εγγραφή οθόνης ακυρώθηκε"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Η εγγραφή οθόνης αποθηκεύτηκε"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Πατήστε για προβολή"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Παρουσιάστηκε σφάλμα κατά τη διαγραφή της εγγραφής οθόνης"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Η λήψη αδειών απέτυχε"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Σφάλμα κατά την έναρξη της εγγραφής οθόνης"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Νέος χρήστης"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Διαδίκτυο"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Ασφαλές για πτήση"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Υπάρχουν διαθέσιμα δίκτυα"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Δεν υπάρχουν διαθέσιμα δίκτυα"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Μη συνδεδεμένο"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Μέχρι την ανατολή"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Ενεργοποίηση στις <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Έως <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Μείωση φωτεινότητας"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"Το NFC είναι απενεργοποιημένο"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"Το NFC είναι ενεργοποιημένο"</string>
@@ -470,11 +466,10 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Εμφάνιση προφίλ"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Προσθήκη χρήστη"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Νέος χρήστης"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Λήξη περιόδου σύνδεσης επισκέπτη"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Κατάργηση επισκέπτη;"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Όλες οι εφαρμογές και τα δεδομένα αυτής της περιόδου σύνδεσης θα διαγραφούν."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Κατάργηση"</string>
-    <string name="guest_wipe_session_title" msgid="7147965814683990944">"Επισκέπτη , καλώς όρισες ξανά!"</string>
+    <string name="guest_wipe_session_title" msgid="7147965814683990944">"Kαλώς ορίσατε ξανά!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Θέλετε να συνεχίσετε την περίοδο σύνδεσής σας;"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Έναρξη από την αρχή"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ναι, συνέχεια"</string>
@@ -485,7 +480,7 @@
     <string name="user_logout_notification_text" msgid="7441286737342997991">"Αποσύνδεση τρέχοντα χρήστη"</string>
     <string name="user_logout_notification_action" msgid="7974458760719361881">"ΑΠΟΣΥΝΔΕΣΗ ΧΡΗΣΤΗ"</string>
     <string name="user_add_user_title" msgid="4172327541504825032">"Προσθήκη νέου χρήστη;"</string>
-    <string name="user_add_user_message_short" msgid="2599370307878014791">"Κατά την προσθήκη ενός νέου χρήστη, αυτός θα πρέπει να ρυθμίσει το χώρο του.\n\nΟποιοσδήποτε χρήστης μπορεί να ενημερώσει τις εφαρμογές για όλους τους άλλους χρήστες."</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Κατά την προσθήκη ενός νέου χρήστη, αυτός θα πρέπει να ρυθμίσει τον χώρο του.\n\nΟποιοσδήποτε χρήστης μπορεί να ενημερώσει τις εφαρμογές για όλους τους άλλους χρήστες."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Συμπληρώθηκε το όριο χρηστών"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Μπορείτε να προσθέσετε έως <xliff:g id="COUNT">%d</xliff:g> χρήστες.</item>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Αυτή η συσκευή είναι διαχειριζόμενη από τον γονέα σου"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Ο οργανισμός σας κατέχει αυτήν τη συσκευή και μπορεί να παρακολουθεί την επισκεψιμότητα δικτύου."</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Ο οργανισμός <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> κατέχει αυτήν τη συσκευή και μπορεί να παρακολουθεί την επισκεψιμότητα δικτύου."</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Αυτή η συσκευή παρέχεται από τον οργανισμό <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Αυτή η συσκευή ανήκει στον οργανισμό σας και είναι συνδεδεμένη στην εφαρμογή <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Αυτή η συσκευή ανήκει στον οργανισμό <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> και είναι συνδεδεμένη στην εφαρμογή <xliff:g id="VPN_APP">%2$s</xliff:g>."</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Αυτή η συσκευή ανήκει στον οργανισμό σας."</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Το προφίλ εργασίας σας είναι συνδεδεμένο στην εφαρμογή <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Το προσωπικό σας προφίλ είναι συνδεδεμένο στην εφαρμογή <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Αυτή η συσκευή είναι συνδεδεμένη στην εφαρμογή <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Αυτή η συσκευή παρέχεται από τον οργανισμό <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Διαχείριση συσκευών"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Παρακολούθηση προφίλ"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Παρακολούθηση δικτύου"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Προβολή πολιτικών"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Προβολή στοιχείων ελέγχου"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Αυτή η συσκευή ανήκει στον οργανισμό <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nΟ διαχειριστής IT μπορεί να παρακολουθεί και να διαχειρίζεται τις ρυθμίσεις, την εταιρική πρόσβαση, τις εφαρμογές, τα δεδομένα που σχετίζονται με τη συσκευή καθώς και τις πληροφορίες τοποθεσίας της συσκευής σας.\n\nΓια περισσότερες πληροφορίες, επικοινωνήστε με τον διαχειριστή IT."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"Ο οργανισμός <xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> ενδέχεται να έχει πρόσβαση σε δεδομένα που σχετίζονται με αυτήν τη συσκευή, να διαχειρίζεται εφαρμογές και να αλλάξει τις ρυθμίσεις της.\n\nΕάν έχετε ερωτήσεις, επικονωνήστε με τον οργανισμό <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Αυτή η συσκευή ανήκει στον οργανισμό σας.\n\nΟ διαχειριστής IT μπορεί να παρακολουθεί και να διαχειρίζεται τις ρυθμίσεις, την εταιρική πρόσβαση, τις εφαρμογές, τα δεδομένα που σχετίζονται με τη συσκευή καθώς και τις πληροφορίες τοποθεσίας της συσκευής σας.\n\nΓια περισσότερες πληροφορίες, επικοινωνήστε με τον διαχειριστή IT."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Ο οργανισμός σας εγκατέστησε μια αρχή έκδοσης πιστοποιητικών σε αυτήν τη συσκευή. Η ασφαλής επισκεψιμότητα δικτύου σας μπορεί να παρακολουθείται ή να τροποποιείται."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Ο οργανισμός σας εγκατέστησε μια αρχή έκδοσης πιστοποιητικών στο προφίλ εργασίας σας. Η ασφαλής επισκεψιμότητα δικτύου σας μπορεί να παρακολουθείται ή να τροποποιείται."</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Εμφάνιση λειτουργίας επίδειξης"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Ξυπνητήρι"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Πορτοφόλι"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Έτοιμο"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Προφίλ εργασίας"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Λειτουργία πτήσης"</string>
     <string name="add_tile" msgid="6239678623873086686">"Προσθήκη πλακιδίου"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Κλείσιμο γρήγορων ρυθμίσεων."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Το ξυπνητήρι ορίστηκε."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Σύνδεση ως <xliff:g id="ID_1">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"επιλογή χρήστη"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Δεν υπάρχει σύνδεση στο διαδίκτυο"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Άνοιγμα λεπτομερειών."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"Μη διαθέσιμα λόγω <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Άνοιγμα ρυθμίσεων <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Επεξεργασία σειράς ρυθμίσεων."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Μενού λειτουργίας"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Σελίδα <xliff:g id="ID_1">%1$d</xliff:g> από <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Οθόνη κλειδώματος"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"Το τηλέφωνο απεν. λόγω ζέστης"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Μετακίνηση αριστερά"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Μετακίνηση δεξιά"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Εναλλαγή μεγιστοποίησης"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Μεγέθυνση ολόκληρης της οθόνης"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Μεγέθυνση πλήρους οθόνης"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Μεγέθυνση μέρους της οθόνης"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Εναλλαγή"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"Το κουμπί προσβασιμότητας αντικατέστησε την κίνηση προσβασιμότητας\n\n"<annotation id="link">"Προβολή ρυθμίσεων"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Μετακινήστε το κουμπί στο άκρο για προσωρινή απόκρυψη"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Στοιχεία ελέγχου συσκευής"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Προσθήκη στοιχείων ελέγχου για τις συνδεδεμένες συσκευές σας."</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Ρύθμιση στοιχείων ελέγχου συσκευής"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Σύζευξη νέας συσκευής"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Γραφικά στοιχεία συνομιλίας"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Πατήστε μια συνομιλία για να την προσθέσετε στην αρχική οθόνη"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> πριν"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"Λιγότερο από <xliff:g id="DURATION">%1$s</xliff:g> πριν"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"Περισσότερο από <xliff:g id="DURATION">%1$s</xliff:g> πριν"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Γενέθλια"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Προσεχώς γενέθλια"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Επέτειος"</string>
+    <string name="location_status" msgid="1294990572202541812">"Κοινοποίηση τοποθ."</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Νέα είδηση"</string>
+    <string name="video_status" msgid="4548544654316843225">"Παρακολούθηση"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Ακρόαση"</string>
+    <string name="game_status" msgid="1340694320630973259">"Παίζει τώρα"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Φίλοι"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Συζήτηση απόψε!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"Αναπάντητη κλήση"</string>
+    <string name="people_tile_description" msgid="8154966188085545556">"Δείτε πρόσφατα μηνύματα, αναπάντητες κλήσεις και ενημερώσεις κατάστασης"</string>
+    <string name="people_tile_title" msgid="6589377493334871272">"Συνομιλία"</string>
     <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Υπάρχει κάποιο πρόβλημα με την ανάγνωση του μετρητή μπαταρίας"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Πατήστε για περισσότερες πληροφορίες."</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Δεν ορίστηκε ξυπνητ."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 5cff3c0..126b172 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Cancel"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Share"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Screen recording cancelled"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Screen recording saved"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Tap to view"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Error deleting screen recording"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Failed to get permissions"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Error starting screen recording"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"New user"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Internet"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Aeroplane-safe"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Networks available"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Networks unavailable"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Not Connected"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Until sunrise"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"On at <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Until <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Reduce brightness"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC is disabled"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC is enabled"</string>
@@ -470,7 +466,6 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Show profile"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Add user"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"New user"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"End Guest session"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Remove guest?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"All apps and data in this session will be deleted."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Remove"</string>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"This device is managed by your parent"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Your organisation owns this device and may monitor network traffic"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> owns this device and may monitor network traffic"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"This device is provided by <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"This device belongs to your organisation and is connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> and is connected to <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"This device belongs to your organisation"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Your work profile is connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Your personal profile is connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"This device is connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"This device is provided by <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Device management"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Profile monitoring"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Network monitoring"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"View Policies"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"View controls"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nYour IT admin can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information.\n\nFor more information, contact your IT admin."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> may be able to access data associated with this device, manage apps and change this device\'s settings.\n\nIf you have questions, contact <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"This device belongs to your organisation.\n\nYour IT admin can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information.\n\nFor more information, contact your IT admin."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Your organisation installed a certificate authority on this device. Your secure network traffic may be monitored or modified."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Your organisation installed a certificate authority in your work profile. Your secure network traffic may be monitored or modified."</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Show demo mode"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Alarm"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Ready"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Work profile"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Aeroplane mode"</string>
     <string name="add_tile" msgid="6239678623873086686">"Add tile"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Close quick settings."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Alarm set."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Signed in as <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"choose user"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"No Internet"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Open details."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"Unvailable due to <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Open <xliff:g id="ID_1">%s</xliff:g> settings."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Edit order of settings."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Power menu"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Page <xliff:g id="ID_1">%1$d</xliff:g> of <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Lock screen"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"Phone turned off due to heat"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Move left"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Move right"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Magnification switch"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Magnify entire screen"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Magnify full screen"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Magnify part of screen"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Switch"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"Accessibility button replaced the accessibility gesture\n\n"<annotation id="link">"View settings"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Move button to the edge to hide it temporarily"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Device controls"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Add controls for your connected devices"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Set up device controls"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Pair new device"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Conversation widgets"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Tap a conversation to add it to your home screen"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> ago"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"Less than <xliff:g id="DURATION">%1$s</xliff:g> ago"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"Over <xliff:g id="DURATION">%1$s</xliff:g> ago"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Birthday"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Birthday soon"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Anniversary"</string>
+    <string name="location_status" msgid="1294990572202541812">"Sharing location"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"New story"</string>
+    <string name="video_status" msgid="4548544654316843225">"Watching"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Listening"</string>
+    <string name="game_status" msgid="1340694320630973259">"Playing"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Friends"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Let’s chat tonight!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"Missed call"</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="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problem reading your battery meter"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tap for more information"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"No alarm set"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 0ee5166..455f498 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Cancel"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Share"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Screen recording cancelled"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Screen recording saved"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Tap to view"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Error deleting screen recording"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Failed to get permissions"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Error starting screen recording"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"New user"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Internet"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Aeroplane-safe"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Networks available"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Networks unavailable"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Not Connected"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Until sunrise"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"On at <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Until <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Reduce brightness"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC is disabled"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC is enabled"</string>
@@ -470,7 +466,6 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Show profile"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Add user"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"New user"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"End Guest session"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Remove guest?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"All apps and data in this session will be deleted."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Remove"</string>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"This device is managed by your parent"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Your organisation owns this device and may monitor network traffic"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> owns this device and may monitor network traffic"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"This device is provided by <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"This device belongs to your organisation and is connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> and is connected to <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"This device belongs to your organisation"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Your work profile is connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Your personal profile is connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"This device is connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"This device is provided by <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Device management"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Profile monitoring"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Network monitoring"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"View Policies"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"View controls"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nYour IT admin can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information.\n\nFor more information, contact your IT admin."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> may be able to access data associated with this device, manage apps and change this device\'s settings.\n\nIf you have questions, contact <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"This device belongs to your organisation.\n\nYour IT admin can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information.\n\nFor more information, contact your IT admin."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Your organisation installed a certificate authority on this device. Your secure network traffic may be monitored or modified."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Your organisation installed a certificate authority in your work profile. Your secure network traffic may be monitored or modified."</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Show demo mode"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Alarm"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Ready"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Work profile"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Airplane mode"</string>
     <string name="add_tile" msgid="6239678623873086686">"Add tile"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Close quick settings."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Alarm set."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Signed in as <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"choose user"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"No Internet"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Open details."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"Unvailable due to <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Open <xliff:g id="ID_1">%s</xliff:g> settings."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Edit order of settings."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Power menu"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Page <xliff:g id="ID_1">%1$d</xliff:g> of <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Lock screen"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"Phone turned off due to heat"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Move left"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Move right"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Magnification switch"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Magnify entire screen"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Magnify full screen"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Magnify part of screen"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Switch"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"Accessibility button replaced the accessibility gesture\n\n"<annotation id="link">"View settings"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Move button to the edge to hide it temporarily"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Device controls"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Add controls for your connected devices"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Set up device controls"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Pair new device"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Conversation widgets"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Tap a conversation to add it to your home screen"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> ago"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"Less than <xliff:g id="DURATION">%1$s</xliff:g> ago"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"Over <xliff:g id="DURATION">%1$s</xliff:g> ago"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Birthday"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Birthday soon"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Anniversary"</string>
+    <string name="location_status" msgid="1294990572202541812">"Sharing location"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"New story"</string>
+    <string name="video_status" msgid="4548544654316843225">"Watching"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Listening"</string>
+    <string name="game_status" msgid="1340694320630973259">"Playing"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Friends"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Let’s chat tonight!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"Missed call"</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="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problem reading your battery meter"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tap for more information"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"No alarm set"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 5cff3c0..126b172 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Cancel"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Share"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Screen recording cancelled"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Screen recording saved"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Tap to view"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Error deleting screen recording"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Failed to get permissions"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Error starting screen recording"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"New user"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Internet"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Aeroplane-safe"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Networks available"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Networks unavailable"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Not Connected"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Until sunrise"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"On at <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Until <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Reduce brightness"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC is disabled"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC is enabled"</string>
@@ -470,7 +466,6 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Show profile"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Add user"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"New user"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"End Guest session"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Remove guest?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"All apps and data in this session will be deleted."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Remove"</string>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"This device is managed by your parent"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Your organisation owns this device and may monitor network traffic"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> owns this device and may monitor network traffic"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"This device is provided by <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"This device belongs to your organisation and is connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> and is connected to <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"This device belongs to your organisation"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Your work profile is connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Your personal profile is connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"This device is connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"This device is provided by <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Device management"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Profile monitoring"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Network monitoring"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"View Policies"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"View controls"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nYour IT admin can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information.\n\nFor more information, contact your IT admin."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> may be able to access data associated with this device, manage apps and change this device\'s settings.\n\nIf you have questions, contact <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"This device belongs to your organisation.\n\nYour IT admin can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information.\n\nFor more information, contact your IT admin."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Your organisation installed a certificate authority on this device. Your secure network traffic may be monitored or modified."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Your organisation installed a certificate authority in your work profile. Your secure network traffic may be monitored or modified."</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Show demo mode"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Alarm"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Ready"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Work profile"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Aeroplane mode"</string>
     <string name="add_tile" msgid="6239678623873086686">"Add tile"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Close quick settings."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Alarm set."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Signed in as <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"choose user"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"No Internet"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Open details."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"Unvailable due to <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Open <xliff:g id="ID_1">%s</xliff:g> settings."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Edit order of settings."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Power menu"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Page <xliff:g id="ID_1">%1$d</xliff:g> of <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Lock screen"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"Phone turned off due to heat"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Move left"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Move right"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Magnification switch"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Magnify entire screen"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Magnify full screen"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Magnify part of screen"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Switch"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"Accessibility button replaced the accessibility gesture\n\n"<annotation id="link">"View settings"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Move button to the edge to hide it temporarily"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Device controls"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Add controls for your connected devices"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Set up device controls"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Pair new device"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Conversation widgets"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Tap a conversation to add it to your home screen"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> ago"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"Less than <xliff:g id="DURATION">%1$s</xliff:g> ago"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"Over <xliff:g id="DURATION">%1$s</xliff:g> ago"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Birthday"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Birthday soon"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Anniversary"</string>
+    <string name="location_status" msgid="1294990572202541812">"Sharing location"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"New story"</string>
+    <string name="video_status" msgid="4548544654316843225">"Watching"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Listening"</string>
+    <string name="game_status" msgid="1340694320630973259">"Playing"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Friends"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Let’s chat tonight!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"Missed call"</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="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problem reading your battery meter"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tap for more information"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"No alarm set"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 5cff3c0..126b172 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Cancel"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Share"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Screen recording cancelled"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Screen recording saved"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Tap to view"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Error deleting screen recording"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Failed to get permissions"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Error starting screen recording"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"New user"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Internet"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Aeroplane-safe"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Networks available"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Networks unavailable"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Not Connected"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Until sunrise"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"On at <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Until <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Reduce brightness"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC is disabled"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC is enabled"</string>
@@ -470,7 +466,6 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Show profile"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Add user"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"New user"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"End Guest session"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Remove guest?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"All apps and data in this session will be deleted."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Remove"</string>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"This device is managed by your parent"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Your organisation owns this device and may monitor network traffic"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> owns this device and may monitor network traffic"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"This device is provided by <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"This device belongs to your organisation and is connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> and is connected to <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"This device belongs to your organisation"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Your work profile is connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Your personal profile is connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"This device is connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"This device is provided by <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Device management"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Profile monitoring"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Network monitoring"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"View Policies"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"View controls"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nYour IT admin can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information.\n\nFor more information, contact your IT admin."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> may be able to access data associated with this device, manage apps and change this device\'s settings.\n\nIf you have questions, contact <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"This device belongs to your organisation.\n\nYour IT admin can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information.\n\nFor more information, contact your IT admin."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Your organisation installed a certificate authority on this device. Your secure network traffic may be monitored or modified."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Your organisation installed a certificate authority in your work profile. Your secure network traffic may be monitored or modified."</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Show demo mode"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Alarm"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Ready"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Work profile"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Aeroplane mode"</string>
     <string name="add_tile" msgid="6239678623873086686">"Add tile"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Close quick settings."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Alarm set."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Signed in as <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"choose user"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"No Internet"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Open details."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"Unvailable due to <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Open <xliff:g id="ID_1">%s</xliff:g> settings."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Edit order of settings."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Power menu"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Page <xliff:g id="ID_1">%1$d</xliff:g> of <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Lock screen"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"Phone turned off due to heat"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Move left"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Move right"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Magnification switch"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Magnify entire screen"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Magnify full screen"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Magnify part of screen"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Switch"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"Accessibility button replaced the accessibility gesture\n\n"<annotation id="link">"View settings"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Move button to the edge to hide it temporarily"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Device controls"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Add controls for your connected devices"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Set up device controls"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Pair new device"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Conversation widgets"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Tap a conversation to add it to your home screen"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> ago"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"Less than <xliff:g id="DURATION">%1$s</xliff:g> ago"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"Over <xliff:g id="DURATION">%1$s</xliff:g> ago"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Birthday"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Birthday soon"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Anniversary"</string>
+    <string name="location_status" msgid="1294990572202541812">"Sharing location"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"New story"</string>
+    <string name="video_status" msgid="4548544654316843225">"Watching"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Listening"</string>
+    <string name="game_status" msgid="1340694320630973259">"Playing"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Friends"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Let’s chat tonight!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"Missed call"</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="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problem reading your battery meter"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tap for more information"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"No alarm set"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index a9e2016..8212a33 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -89,8 +89,10 @@
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‎‎‎‎‎‎‎‎‏‎‎‏‎‎‎‎‎‎‎‎‏‎‎‏‏‎‏‎‎‎‎‏‎‏‏‎‎‏‎‏‏‏‎‎‎‎‎‎‎‏‏‎‏‏‎Taking screenshots isn\'t allowed by the app or your organization‎‏‎‎‏‎"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‎‏‏‏‎‎‎‎‎‎‏‎‏‎‎‎‎‎‎‏‎‏‏‏‏‏‎‎‎‎‏‏‎‏‏‏‎‏‎‎Edit‎‏‎‎‏‎"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‎‎‏‎‎‎‎‎‏‏‎‎‎‎‏‎‏‏‎‏‏‏‏‏‏‎‎‎‎‎‏‎‏‎‏‏‎‎‏‏‏‎‏‏‎‏‎‏‎‎‎‏‎‏‎‏‎‎Edit screenshot‎‏‎‎‏‎"</string>
-    <string name="screenshot_scroll_label" msgid="7682877978685434621">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‎‏‏‏‏‏‎‎‎‏‎‎‎‎‏‏‎‏‎‎‎‎‏‏‏‎‎‏‎‎‎‎‏‏‎‏‏‏‎‏‏‎‏‎‏‎‏‏‏‏‏‏‎‏‎Scroll‎‏‎‎‏‎"</string>
-    <string name="screenshot_scroll_description" msgid="7855773867093272175">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‎‎‎‏‎‏‎‏‎‏‎‎‎‎‏‎‏‏‎‏‎‏‏‏‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‏‎‎‏‏‎‎‏‏‎‏‏‏‏‎Scroll screenshot‎‏‎‎‏‎"</string>
+    <!-- no translation found for screenshot_scroll_label (7682877978685434621) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_description (7855773867093272175) -->
+    <skip />
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‎‎‎‎‏‎‎‎‎‏‎‎‏‎‎‏‏‏‎‎‏‎‏‏‏‏‎‏‏‎‏‎‎‎‎‎‏‎‎‎‎‎‏‏‎‎‎‎‏‏‎‎‏‎‎Dismiss screenshot‎‏‎‎‏‎"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‎‎‏‏‏‏‏‏‎‎‎‎‎‎‏‎‏‎‏‏‎‎‎‎‎‎‎‏‎‏‏‎‏‎‏‎‏‏‎‏‎‏‏‎‎‎‏‏‎‏‏‎‏‎‎Screenshot preview‎‏‎‎‏‎"</string>
     <string name="screenshot_top_boundary" msgid="1500569103321300856">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‏‏‎‏‎‎‏‏‎‎‎‏‎‏‏‏‏‎‏‎‎‏‏‎‎‎‏‎‏‏‎‎‎‏‏‎‎‏‎‎‎‏‏‏‏‏‏‏‎‏‏‏‏‎‎‎‎Top boundary‎‏‎‎‏‎"</string>
@@ -116,10 +118,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‏‏‎‏‎‎‎‎‎‏‏‎‎‎‎‎‎‏‏‏‏‏‎‏‎‏‎‏‎‏‏‎‏‏‎‎‏‏‎‏‎‎‏‎‏‎‎‏‎‏‏‏‏‎‎Cancel‎‏‎‎‏‎"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‏‏‏‏‏‎‎‏‏‏‏‏‎‎‎‎‏‏‎‏‎‏‏‎‏‎‎‏‎‎‏‎‏‎‏‏‏‎‏‏‎‏‏‏‏‏‎‎‎‏‎‎‏‎‎Share‎‏‎‎‏‎"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‏‎‏‎‎‎‏‏‏‎‏‎‏‎‎‏‎‎‏‎‏‏‎‎‏‏‎‏‎‏‎‏‎‏‎‏‏‏‎‎‏‏‎‏‎‏‏‎‏‏‏‎‏‏‎‏‎Screen recording canceled‎‏‎‎‏‎"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‎‎‏‎‏‏‏‎‏‎‏‏‏‏‎‎‏‎‎‎‏‏‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‎‏‎‏‎‏‏‏‏‎‎‏‏‎‏‎‎Screen recording saved‎‏‎‎‏‎"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‏‏‏‎‎‎‎‏‎‎‎‎‎‎‏‎‏‎‎‎‏‎‏‏‏‏‎‎‏‎‎‎‎‎‏‎‏‎‏‎‏‏‏‎‎‎‏‏‏‏‏‏‎‎‎‏‏‎Tap to view‎‏‎‎‏‎"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‏‏‏‎‏‎‏‏‎‎‎‎‏‎‏‏‎‎‎‎‏‏‎‏‏‎‏‏‏‏‎‎‎‏‏‎‏‏‏‏‎‎‎‎‎‎‎‏‎‏‏‎‏‎‏‎‎‎Error deleting screen recording‎‏‎‎‏‎"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‎‎‏‎‎‏‎‎‎‏‏‎‏‏‎‏‏‏‏‎‏‎‎‏‎‎‏‏‎‏‎‏‏‎‎‏‏‏‏‎‎‏‏‏‏‏‏‎‎‏‎‏‏‎‎Failed to get permissions‎‏‎‎‏‎"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‏‎‎‎‏‎‏‎‎‏‎‏‎‎‎‏‎‎‏‏‏‏‎‏‎‏‏‏‏‏‏‎‎‏‏‎‏‎‏‎‏‎‏‎‎‏‏‏‎‏‎‎‎‎‎‎‎Error starting screen recording‎‏‎‎‏‎"</string>
@@ -361,7 +361,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‎‎‏‏‏‎‏‏‎‎‎‏‎‎‏‏‎‏‎‏‎‎‏‏‎‏‏‏‎‏‎‏‎‎‏‏‎‏‏‏‎‎‏‎‏‏‎‏‎‎‎‏‎‎‎‏‎‎New user‎‏‎‎‏‎"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‏‏‏‏‏‎‏‏‎‎‎‎‏‎‎‎‎‏‏‎‏‏‎‎‎‎‏‎‎‏‏‏‏‏‎‎‎‏‎‏‎‏‏‎‎‏‎‏‏‎‎‎‎‏‏‎‎‎Wi-Fi‎‏‎‎‏‎"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‎‏‎‎‎‏‎‏‏‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‏‏‏‎‏‎‎‎‏‎‏‎‏‎‎‎‏‎‎‏‎‏‏‎‎‏‎‎‏‏‏‎Internet‎‏‎‎‏‎"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‏‏‏‏‏‏‏‎‏‎‏‎‏‏‎‏‎‏‎‎‎‏‎‎‏‎‏‎‎‏‎‎‎‎‎‏‏‏‎‎‏‏‎‏‎‎‏‎‎‎‎‎‏‎‏‏‎Airplane-safe‎‏‎‎‏‎"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‎‎‎‎‎‏‎‏‏‏‎‏‎‏‎‎‏‎‏‎‎‎‎‎‏‏‎‎‎‏‏‎‎‎‏‏‏‏‎‎‏‏‏‏‏‎‏‎‎‎‎‏‎‏‏‎‎Networks available‎‏‎‎‏‎"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‎‎‎‏‏‎‏‎‏‎‎‎‎‎‏‏‎‏‎‏‎‏‎‏‏‏‏‎‎‏‏‏‎‎‎‎‎‎‎‏‎‎‏‎‎‎‎‎‎‎‏‏‏‎‎‏‎‎Networks unavailable‎‏‎‎‏‎"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‎‎‏‏‏‏‏‏‏‎‏‏‏‎‎‎‏‏‎‏‎‎‎‎‎‏‎‎‎‎‏‏‎‎‎‏‏‏‏‎‎‏‎‎‎‏‏‎‏‏‎‏‏‏‎‎‎‎Not Connected‎‏‎‎‏‎"</string>
@@ -415,7 +414,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‏‎‎‏‎‎‎‎‏‎‏‎‎‏‎‏‏‏‎‏‎‎‎‏‎‎‎‏‎‎‏‎‎‏‎‏‎‎‏‏‎‎‏‎‎‎‎‎‏‏‎‏‏‏‎‎‎‎Until sunrise‎‏‎‎‏‎"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‎‏‎‏‏‎‏‎‎‎‎‎‎‏‎‏‏‏‏‏‎‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‏‏‎‎‎‎‎‏‏‏‎‏‎‏‏‏‏‏‏‎On at ‎‏‎‎‏‏‎<xliff:g id="TIME">%s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‏‏‎‎‎‏‏‎‏‏‏‎‏‎‎‏‏‏‏‎‎‏‏‏‏‎‎‎‏‎‏‏‏‏‎‎‏‎‏‎‎‏‏‎‏‏‎‏‏‎‎‏‎‏‎‏‎Until ‎‏‎‎‏‏‎<xliff:g id="TIME">%s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‎‎‏‏‎‏‎‎‎‎‎‏‏‎‏‏‏‎‎‏‎‎‎‎‏‎‏‏‏‎‎‏‏‎‎‎‏‏‎‎‏‏‎‏‏‏‏‎‏‏‎‎‏‏‏‎Reduce brightness‎‏‎‎‏‎"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‏‎‏‎‎‎‎‏‏‎‏‏‎‎‎‎‎‎‎‏‏‎‏‎‏‎‏‎‎‎‏‎‎‏‎‏‏‏‏‎‏‏‎‏‎‎‎‏‏‏‎‏‎‏‎‏‎NFC‎‏‎‎‏‎"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‎‎‎‏‎‏‏‎‎‎‏‎‎‏‏‏‎‎‏‏‎‎‎‏‏‏‏‎‎‎‏‎‏‎‎‎‎‏‎‏‎‎‎‎‎‏‎‏‏‎‎‏‎‏‏‏‎NFC is disabled‎‏‎‎‏‎"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‏‏‏‏‏‎‎‏‎‎‏‏‎‎‏‎‎‏‏‏‎‎‏‏‏‎‎‏‏‏‏‏‎‎‏‎‏‎‏‏‏‏‎‏‏‏‏‎‎‏‎‏‏‎‏‏‎‎NFC is enabled‎‏‎‎‏‎"</string>
@@ -470,7 +468,6 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‏‎‎‎‎‎‏‏‎‎‏‏‏‎‏‎‏‏‏‏‏‏‏‎‎‎‎‏‏‎‎‏‏‎‎‎‎‏‎‏‎‏‎‎‏‏‎‏‎‎‎‏‎‎‎‎‎Show profile‎‏‎‎‏‎"</string>
     <string name="user_add_user" msgid="4336657383006913022">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‎‎‎‏‎‏‏‏‎‏‏‏‎‎‏‏‎‏‏‏‎‏‎‎‏‏‏‎‎‏‎‏‎‏‎‏‏‎‎‏‏‏‏‎‎‎‎‎‏‏‏‏‏‏‏‏‎‎Add user‎‏‎‎‏‎"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‎‎‎‎‎‏‎‏‏‎‎‎‎‏‎‏‎‎‎‎‏‎‎‏‎‎‏‏‏‏‏‏‎‎‎‎‎‏‏‏‏‎‎‏‎‎‎‎‏‏‎‎‏‏‎‏‎New user‎‏‎‎‏‎"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‎‏‏‏‎‏‏‎‏‎‏‏‏‏‎‎‏‏‎‎‏‎‎‏‏‏‎‎‏‏‎‏‎‎‏‎‎‎‏‏‎‎‏‏‎‏‎‏‎‎‏‏‎‎‏‎‎End guest session‎‏‎‎‏‎"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‎‏‏‎‏‏‎‏‎‏‎‏‏‎‎‏‎‏‏‎‏‏‏‎‏‎‎‎‏‎‏‏‎‎‏‏‏‎‏‎‎‏‏‏‎‎‏‎‎‎‏‏‏‎‎Remove guest?‎‏‎‎‏‎"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‎‎‏‎‎‎‏‎‏‏‏‎‏‎‏‎‏‎‏‎‎‎‎‎‏‎‎‏‎‏‏‎‎‏‏‎‏‎‎‏‏‏‎‏‏‏‏‎‏‎‏‏‏‎‏‎All apps and data in this session will be deleted.‎‏‎‎‏‎"</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‏‎‏‎‏‎‎‎‎‎‎‏‎‏‎‏‎‏‎‏‎‎‏‏‏‎‏‎‏‎‏‏‏‎‎‏‏‎‎‏‎‎‎‎‏‏‏‎‎‎‏‏‎‏‎Remove‎‏‎‎‏‎"</string>
@@ -519,6 +516,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‏‎‏‎‏‎‏‏‎‏‏‎‎‏‏‎‏‎‏‎‏‏‏‎‎‎‏‎‎‏‏‏‎‏‎‏‏‎‏‎‏‎‏‏‎‏‎‎‎‏‏‏‏‎‎‎‎‎This device is managed by your parent‎‏‎‎‏‎"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‏‎‏‏‏‎‎‏‎‏‎‏‎‏‎‎‎‏‏‎‏‏‏‎‏‏‎‏‏‏‎‏‏‏‎‏‏‏‎‏‏‎‎‏‏‏‏‎‎‏‎‎‎Your organization owns this device and may monitor network traffic‎‏‎‎‏‎"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‏‎‏‎‎‏‎‏‏‎‎‏‏‏‏‎‎‏‏‏‏‎‎‏‏‎‎‏‏‏‎‏‏‎‏‏‎‎‎‎‏‏‏‏‎‎‏‏‎‎‎‎‎‎‏‎‎‎‎‏‎‎‏‏‎<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ owns this device and may monitor network traffic‎‏‎‎‏‎"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‎‎‎‎‎‏‏‎‏‎‎‏‏‏‎‎‎‏‎‏‏‏‎‏‏‎‎‎‎‏‏‏‏‎‎‏‏‎‎‏‏‏‏‎‎‏‏‎‎‎‎‎‎‏‎‎‎This device is provided by ‎‏‎‎‏‏‎<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‎‎‏‏‎‏‏‏‏‏‎‎‎‏‎‎‏‎‎‏‎‏‎‎‎‏‏‏‏‎‏‎‎‎‏‎‏‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‎‎‎This device belongs to your organization and is connected to ‎‏‎‎‏‏‎<xliff:g id="VPN_APP">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‎‎‏‎‏‏‏‎‏‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‏‎‎‏‏‎‎‎‎‏‏‏‎‏‎‎‏‎‏‎‎‎‎‏‎‎‏‎‎‎‎This device belongs to ‎‏‎‎‏‏‎<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ and is connected to ‎‏‎‎‏‏‎<xliff:g id="VPN_APP">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‎‏‎‎‎‏‎‏‎‎‏‎‎‎‏‎‏‎‎‎‎‏‎‎‎‏‏‏‏‎‏‎‎‏‏‏‏‏‎‏‎‎‎‏‎‏‏‎‏‏‎‏‎‎‎‏‎‎This device belongs to your organization‎‏‎‎‏‎"</string>
@@ -532,6 +530,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‎‎‏‏‏‎‏‏‎‎‏‎‏‏‏‎‎‎‎‏‏‏‏‎‏‎‎‎‏‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‎‎‏‎‎‏‎‏‎Your work profile is connected to ‎‏‎‎‏‏‎<xliff:g id="VPN_APP">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‎‎‏‎‎‏‏‎‎‏‎‎‎‏‎‏‏‎‎‏‎‏‏‏‏‎‎‏‎‎‎‏‎‏‏‎‎‎‏‏‎‎‎‎‎‏‏‎‏‏‏‎‏‎‏‎Your personal profile is connected to ‎‏‎‎‏‏‎<xliff:g id="VPN_APP">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‏‎‎‏‏‏‏‏‏‏‎‏‏‎‏‎‏‏‏‎‎‏‏‏‏‎‎‏‏‏‎‏‎‏‏‏‎‎‏‎‎‎‏‎‎‏‎‏‏‎‏‏‎‎‎‏‎This device is connected to ‎‏‎‎‏‏‎<xliff:g id="VPN_APP">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‎‏‏‎‎‏‎‏‎‏‏‎‎‏‏‎‎‎‏‎‏‏‏‏‏‏‎‎‎‏‏‏‎‎‏‎‏‎‏‏‎‎‎‏‎‎‏‏‎‏‎‎‏‏‎‏‏‎This device is provided by ‎‏‎‎‏‏‎<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‎‎‏‏‏‎‎‏‏‏‏‎‏‎‏‏‎‎‏‎‏‏‏‎‏‏‏‏‎‎‏‏‎‏‏‏‏‏‎‎‎‎‏‎‎‏‏‎‏‏‎‏‎‎‎Device management‎‏‎‎‏‎"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‏‏‏‎‎‏‎‎‎‎‏‎‎‏‎‎‎‎‎‎‏‏‎‏‏‏‎‎‎‎‏‎‏‏‎‎‏‏‎‏‎‏‎‎‏‎‏‎‏‏‎‎‎‎‎‎Profile monitoring‎‏‎‎‏‎"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‎‎‏‏‎‎‏‎‏‏‏‎‏‎‏‏‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‎‎‏‏‏‏‏‏‏‎‏‏‏‏‎‏‎‏‏‎‎‎‎Network monitoring‎‏‎‎‏‎"</string>
@@ -543,6 +542,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‏‏‎‏‏‎‏‎‎‎‎‎‎‎‏‏‎‎‎‏‏‏‏‎‎‎‏‎‎‏‎‏‏‏‎‎‎‏‏‏‎‎‎‎‎‎‏‏‏‏‏‎‎‏‎‏‎‎View Policies‎‏‎‎‏‎"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‎‏‎‎‏‏‏‏‎‏‏‏‎‎‏‏‎‏‏‏‎‏‎‎‎‎‎‏‏‏‏‎‎‎‎‏‎‎‏‏‎‏‎‎‏‏‎‏‏‏‏‎‏‎View controls‎‏‎‎‏‎"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‏‎‎‎‎‎‏‎‏‎‎‎‏‎‏‎‎‎‏‏‏‎‎‏‎‏‏‎‏‎‎‏‎‏‏‎‏‎‏‎‏‎‎‎‏‎‏‎‏‎‎‏‎‎‏‎‎‎This device belongs to ‎‏‎‎‏‏‎<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Your IT admin can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎For more information, contact your IT admin.‎‏‎‎‏‎"</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‏‎‎‎‏‎‏‏‎‎‎‏‎‎‏‎‎‎‏‎‏‏‎‏‏‏‏‏‎‏‏‏‎‎‎‎‎‏‏‏‎‎‏‏‏‏‎‎‏‏‎‏‏‎‎‎‎‏‎‎‏‏‎<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g>‎‏‎‎‏‏‏‎ may be able to access data associated with this device, manage apps, and change this devices settings.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎If you have questions, contact ‎‏‎‎‏‏‎<xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>‎‏‎‎‏‏‏‎.‎‏‎‎‏‎"</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‏‏‎‎‏‏‎‎‎‎‏‏‎‏‏‎‏‎‏‎‏‎‎‎‎‎‎‏‏‏‏‎‎‎‏‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‏‎‎This device belongs to your organization.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Your IT admin can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎For more information, contact your IT admin.‎‏‎‎‏‎"</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‎‏‎‎‏‏‏‏‎‏‏‎‎‎‎‏‏‎‎‏‎‎‎‎‏‎‎‎‎‏‎‏‎‎‎‎‎‏‏‎‏‏‎‏‎‏‎‏‏‎‎‏‎‎Your organization installed a certificate authority on this device. Your secure network traffic may be monitored or modified.‎‏‎‎‏‎"</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‏‏‎‎‎‏‏‏‎‎‏‏‎‎‎‏‎‎‎‏‎‎‏‎‏‏‏‏‎‎‎‎‏‎‎‏‏‎‏‏‎‏‎‏‏‏‎‎‏‏‏‏‏‏‎Your organization installed a certificate authority in your work profile. Your secure network traffic may be monitored or modified.‎‏‎‎‏‎"</string>
@@ -653,6 +653,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‏‎‎‎‎‏‎‏‎‏‎‏‏‏‎‎‏‏‏‏‎‏‎‏‎‎‏‏‏‎‎‎‏‎‎‏‎‎‎‏‏‎‏‎‏‏‎‏‏‏‎‎‎‏‏‏‎‎Show demo mode‎‏‎‎‏‎"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‏‏‏‏‏‎‏‎‎‏‏‎‏‎‏‏‏‏‏‏‎‎‎‎‎‏‎‎‏‏‏‎‎‏‏‏‎‏‎‎‏‏‎‏‏‏‎‎‎‎‏‏‏‏‎‎‎Ethernet‎‏‎‎‏‎"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‏‏‎‎‏‏‎‏‎‏‏‎‏‎‏‎‎‎‎‏‎‏‎‏‎‎‎‏‎‎‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‏‏‏‏‏‎‏‏‏‎‎‎‎Alarm‎‏‎‎‏‎"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‎‎‎‎‏‎‏‎‎‏‏‏‏‏‏‎‎‏‏‏‏‏‏‎‎‎‎‏‏‎‎‏‎‎‏‎‏‎‏‏‏‏‏‎‎‎‎‏‎‏‎‎‎‎‏‎Wallet‎‏‎‎‏‎"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‎‎‏‏‏‏‏‎‏‎‏‏‏‏‏‏‏‎‎‏‎‏‎‏‏‏‎‎‏‏‎‏‎‏‎‏‏‎‎‏‏‏‎Ready‎‏‎‎‏‎"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‎‏‏‎‎‏‏‎‏‏‎‎‏‎‏‎‎‎‏‏‎‎‏‎‎‎‎‏‏‎‏‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‏‎‎‎‎‎Work profile‎‏‎‎‏‎"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‏‎‎‏‎‏‎‎‎‎‎‏‏‎‏‎‎‏‏‏‏‎‏‏‏‏‏‏‎‏‏‏‎‏‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‎‎‎‏‎Airplane mode‎‏‎‎‏‎"</string>
     <string name="add_tile" msgid="6239678623873086686">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‎‏‎‏‏‏‏‏‎‎‏‎‏‎‏‎‏‎‎‏‏‎‎‎‏‏‎‎‎‎‏‎‎‎‏‏‎‏‏‎‏‏‎‏‎‎‏‏‎‏‏‏‏‎‎Add tile‎‏‎‎‏‎"</string>
@@ -899,11 +901,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‏‏‎‎‎‎‎‎‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‎‏‏‏‏‎‏‏‎‏‏‎‎‎‎‎‎‎‏‎‎‎‏‏‎‎‏‏‏‏‏‎‎Close quick settings.‎‏‎‎‏‎"</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‏‎‎‏‎‎‏‎‎‎‎‎‎‎‏‎‎‏‏‏‏‎‏‏‎‏‏‏‎‏‏‏‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‏‎‏‎Alarm set.‎‏‎‎‏‎"</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‏‎‎‎‎‎‏‎‏‎‎‎‎‏‎‏‎‎‏‏‎‎‎‎‎‏‎‎‎‏‎‎‏‎‎‎‏‏‏‏‎‏‎‎‏‎‎‎‎‎‏‎‎‏‎‏‏‎Signed in as ‎‏‎‎‏‏‎<xliff:g id="ID_1">%s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‎‏‏‎‏‎‎‎‏‏‏‎‎‎‎‎‎‏‏‎‏‎‏‎‏‏‏‏‎‏‏‏‎‎‎‏‎‎‏‎‎‏‎‎‎‎‎‏‏‎‏‎‏‏‏‎choose user‎‏‎‎‏‎"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‏‎‎‏‎‏‏‏‎‎‏‎‎‎‎‏‏‏‎‎‎‎‎‎‏‎‎‏‏‎‎‏‎‏‎‎‏‏‏‎‏‏‏‎‏‏‎‏‎‏‏‎‎‎‎‎‎No internet‎‏‎‎‏‎"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎‏‏‎‏‏‎‏‎‏‎‏‏‏‏‎‎‏‏‏‎‏‎‏‎‎‏‎‎‎‏‏‎‏‎‎‏‏‎‎‎‎‎‎‏‏‎‏‏‏‎‏‏‏‎‎Open details.‎‏‎‎‏‎"</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‏‎‏‏‎‏‎‏‏‏‎‏‎‎‎‏‏‏‏‎‎‎‎‎‏‎‎‎‏‎‏‎‏‏‎‏‎‎‏‏‏‎‎‏‏‎‎‏‏‏‏‏‎‎Unvailable due to ‎‏‎‎‏‏‎<xliff:g id="REASON">%s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‏‎‏‏‏‎‎‏‏‎‎‏‏‏‎‏‏‏‎‏‎‎‎‎‏‏‎‎‎‎‏‎‏‏‎‏‎‎‎‏‎‏‏‎‎‎‎‏‎‏‏‏‎‏‏‎‏‎Open ‎‏‎‎‏‏‎<xliff:g id="ID_1">%s</xliff:g>‎‏‎‎‏‏‏‎ settings.‎‏‎‎‏‎"</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‏‎‎‏‎‎‏‎‏‎‏‏‎‏‏‏‎‎‎‏‎‏‎‏‏‏‏‎‎‏‏‏‏‏‏‎‎‏‏‏‎‎‎‎‎‎‏‏‎‏‏‏‎‎‏‏‎‎Edit order of settings.‎‏‎‎‏‎"</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‎‏‎‎‏‏‏‎‎‎‎‎‏‎‏‎‏‏‎‏‎‎‎‏‏‎‎‏‎‏‎‎‎‏‎‎‎‎‎‎‏‎‎‏‏‏‏‏‏‎‎‏‏‎‎‎Power menu‎‏‎‎‏‎"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‏‎‏‎‏‏‏‏‎‏‎‎‎‎‏‎‏‎‏‎‎‏‏‏‎‎‏‏‎‎‏‎‏‏‎‏‎‏‎‏‎‏‏‎‎‏‎‏‏‏‎‎‎‏‎Page ‎‏‎‎‏‏‎<xliff:g id="ID_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ of ‎‏‎‎‏‏‎<xliff:g id="ID_2">%2$d</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‏‎‏‏‏‎‏‎‏‏‏‎‏‏‎‎‏‎‎‎‎‏‎‏‎‎‏‎‏‏‎‏‏‎‏‎‏‏‎‎‎‎‏‎‎‏‏‏‎‎‎‎‎‎Lock screen‎‏‎‎‏‎"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‏‎‎‎‎‎‏‎‏‏‎‏‏‏‏‎‎‎‎‏‎‎‎‏‎‏‏‎‎‏‏‎‎‎‎‎‎‎‎‏‏‏‏‎‏‎‎‎‎‏‎‏‏‎‎‎‎Phone turned off due to heat‎‏‎‎‏‎"</string>
@@ -1011,9 +1015,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‏‏‎‎‎‎‏‎‏‎‏‎‏‏‎‎‎‎‏‎‎‎‏‎‎‏‎‏‎‎‏‎‏‏‏‎‏‏‏‏‏‏‎‏‎‎‎‎‎‎‏‎‏‏‎Move left‎‏‎‎‏‎"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‎‏‎‎‏‏‏‎‎‎‎‎‏‏‏‏‏‎‏‎‎‎‎‎‎‏‏‎‏‎‎‎‎‎‏‎‏‎‏‏‏‏‎‎‎‏‎‏‎‎‎‎Move right‎‏‎‎‏‎"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‎‏‏‏‎‎‏‎‏‎‎‎‎‏‎‎‎‎‎‎‏‏‎‏‏‏‏‎‏‎‏‏‏‎‎‏‎‎‎‎‏‏‏‏‎‎‏‎‏‎‎‎‏‏‎‏‎Magnification switch‎‏‎‎‏‎"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‎‎‎‎‎‎‎‎‏‎‏‏‏‎‎‏‎‎‏‎‎‏‎‎‎‏‏‎‏‎‏‎‏‎‏‎‏‏‎‎‏‎‎‎‏‎‎‎‎‎‎‎‏‏‏‎‎Magnify entire screen‎‏‎‎‏‎"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‎‎‏‎‎‏‏‎‏‏‏‎‏‏‎‎‎‏‎‏‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‏‎‏‎‎‏‎‏‎‏‏‏‎‏‎‎‎‎‎‏‎Magnify full screen‎‏‎‎‏‎"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‏‏‏‎‎‎‎‏‎‎‏‎‎‏‎‎‎‎‎‏‎‏‎‏‎‏‏‎‏‏‏‏‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‎‏‎Magnify part of screen‎‏‎‎‏‎"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‎‏‎‏‎‏‎‏‎‏‎‎‏‎‏‎‏‎‏‎‏‎‎‏‏‏‎‎‏‏‎‏‏‏‎‎‎‎‎‏‎‎‎‏‏‎‎‎‏‏‏‎‏‎‏‏‏‎Switch‎‏‎‎‏‎"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‏‎‏‏‏‏‏‏‎‎‎‏‏‏‏‎‏‏‎‏‎‎‏‎‎‎‎‏‏‏‎‎‎‏‏‏‏‎‏‎‏‏‏‎‏‏‏‎‎‏‏‎‎‎‏‎‎‎Accessibility button replaced the accessibility gesture‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎"<annotation id="link">"‎‏‎‎‏‏‏‎View settings‎‏‎‎‏‏‎"</annotation>"‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‎‎‏‎‎‏‏‎‏‏‎‎‎‎‏‎‎‏‎‏‎‏‎‏‎‎‏‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‎‎‏‎‎‎‏‏‎‏‎Move button to the edge to hide it temporarily‎‏‎‎‏‎"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‏‎‏‎‎‏‎‏‏‎‎‏‎‎‎‏‏‏‏‏‏‏‎‎‎‏‏‎‎‎‎‏‎‏‏‏‏‎‏‏‎‏‏‎‎‏‏‎‎‎‎‎‎‏‎Device controls‎‏‎‎‏‎"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‎‎‏‎‎‎‏‏‏‏‎‏‎‎‏‎‏‏‎‏‎‎‏‏‏‎‎‏‏‎‏‎‎‏‎‏‎‎‏‏‏‎‎‏‏‎‎‏‏‏‏‎‎‏‎‏‎Add controls for your connected devices‎‏‎‎‏‎"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‏‎‎‎‎‏‎‎‎‎‎‏‎‏‏‏‏‎‏‎‎‎‎‎‏‏‏‏‎‏‏‎‎‏‎‎‏‎‎‏‎‎‎‎‏‏‎‏‏‏‏‎‎Set up device controls‎‏‎‎‏‎"</string>
@@ -1081,6 +1087,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‏‏‎‎‏‎‏‎‏‏‎‎‏‏‎‎‎‏‎‏‎‎‏‎‎‏‏‏‎‏‏‎‏‎‎‏‏‎‎Pair new device‎‏‎‎‏‎"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‏‎‏‎‏‎‏‎‏‎‎‎‏‏‎‎‏‎‏‎‎‏‎‏‎‎‎‎‏‎‎‏‏‏‏‎‎‏‏‎‎‏‏‏‏‎‏‏‎‏‏‏‏‎Conversation widgets‎‏‎‎‏‎"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‎‏‏‎‏‏‎‏‎‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‏‎‏‎‏‏‎‏‏‏‏‏‏‎‏‎‎‏‏‏‎‏‏‎‏‎Tap a conversation to add it to your Home screen‎‏‎‎‏‎"</string>
+    <string name="timestamp" msgid="6577851592534538533">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‏‎‎‏‎‎‏‎‎‏‏‏‎‎‏‎‎‏‎‏‏‎‎‎‎‏‎‎‏‏‎‎‏‎‎‎‎‏‎‎‎‏‏‏‎‎‏‎‎‏‎‎‏‎‏‎‎‏‎‎‏‏‎<xliff:g id="DURATION">%1$s</xliff:g>‎‏‎‎‏‏‏‎ ago‎‏‎‎‏‎"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‎‎‏‎‏‎‎‎‏‎‎‎‎‏‎‏‏‎‎‏‎‏‎‎‏‏‎‏‎‏‎‎‎‏‏‏‎‏‏‎‏‏‎‏‎‎‎‎‏‏‎‎‏‎‏‎Less than ‎‏‎‎‏‏‎<xliff:g id="DURATION">%1$s</xliff:g>‎‏‎‎‏‏‏‎ ago‎‏‎‎‏‎"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‎‏‎‏‎‏‏‎‎‏‎‏‏‏‏‏‏‎‎‎‏‏‎‏‎‏‎‏‎‎Over ‎‏‎‎‏‏‎<xliff:g id="DURATION">%1$s</xliff:g>‎‏‎‎‏‏‏‎ ago‎‏‎‎‏‎"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‎‎‎‎‏‎‏‎‎‏‎‎‎‎‏‎‏‏‎‏‎‏‏‏‏‎‏‏‏‎‏‏‏‎‎‏‏‎‏‎‏‏‎‎‎‏‏‎‎‎‎‏‏‎‎‏‎Birthday‎‏‎‎‏‎"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‏‏‏‎‏‎‏‎‎‏‏‎‎‏‏‎‎‎‎‏‎‏‏‏‏‏‎‏‎‏‏‏‎‏‏‏‎‏‎‏‎‏‏‎‏‏‏‎‏‏‏‎‎‏‏‏‏‎Birthday soon‎‏‎‎‏‎"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‏‏‎‏‎‏‏‏‎‏‏‏‏‎‏‎‏‎‎‏‎‏‎‏‎‎‎‎‏‏‏‎‎‎‎‎‏‏‏‎‎‎‏‏‏‎‏‎‏‎‏‏‎‏‏‎‎Anniversary‎‏‎‎‏‎"</string>
+    <string name="location_status" msgid="1294990572202541812">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‏‏‏‏‏‏‎‎‎‏‎‏‏‏‎‏‏‎‎‎‏‎‎‎‎‎‏‏‏‎‎‏‏‏‎‎‏‏‏‎‎‏‏‎‎‎‎‏‎‏‏‏‏‎‏‎‎‎Sharing location‎‏‎‎‏‎"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‎‎‎‎‎‏‏‏‏‏‎‎‎‏‏‏‏‎‏‎‎‎‏‎‏‏‏‏‎‏‎New story‎‏‎‎‏‎"</string>
+    <string name="video_status" msgid="4548544654316843225">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‏‎‏‎‎‎‎‏‏‏‎‎‎‏‏‎‏‏‎‎‎‏‏‏‎‏‎‏‏‎‎‎‎‏‏‎‏‏‎‎‏‎Watching‎‏‎‎‏‎"</string>
+    <string name="audio_status" msgid="4237055636967709208">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‎‏‏‎‎‏‏‎‏‎‎‎‎‏‎‏‏‏‎‏‎‎‏‏‏‎‎‏‎‎‏‏‏‎‎‎‎‎‏‏‎‏‏‎‏‏‎‏‎‎‎‎‏‏‎‎‎‎Listening‎‏‎‎‏‎"</string>
+    <string name="game_status" msgid="1340694320630973259">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‎‏‎‎‏‏‎‏‏‎‎‎‏‏‎‏‎‎‏‏‎‎‎‎‏‏‎‎‏‏‏‎‏‏‎‎‏‎‏‏‏‏‏‎‎‎‎‏‏‎‏‎‎‏‎‏‏‎Playing‎‏‎‎‏‎"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‏‎‎‎‎‏‎‎‎‏‎‏‏‎‎‏‏‎‎‏‏‏‎‎‎‏‎‏‏‎‏‏‏‎‏‏‏‎‎‏‎‏‎‎‏‎‏‎‎‎‎‏‏‏‏‎‎‎Friends‎‏‎‎‏‎"</string>
+    <string name="empty_status" msgid="5938893404951307749">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‏‏‎‏‎‏‏‎‎‏‏‎‎‎‎‎‎‎‏‎‏‏‎‎‎‎‏‎‎‎‏‎‎‎‎‏‎‎‎‎‏‏‎‎‏‎‏‏‏‏‎‎‏‎‏‎Let’s chat tonight!‎‏‎‎‏‎"</string>
+    <string name="missed_call" msgid="4228016077700161689">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‎‏‎‏‎‏‏‎‎‏‏‏‎‏‏‏‎‎‎‏‏‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‏‎‎‎‎‎‏‎‎‏‏‎‎‏‎Missed call‎‏‎‎‏‎"</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="battery_state_unknown_notification_title" msgid="8464703640483773454">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‏‏‏‎‎‎‏‎‏‎‏‎‏‏‎‎‎‏‏‏‎‎‏‏‏‏‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‎‎‎‎‎‏‏‏‎‎Problem reading your battery meter‎‏‎‎‏‎"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‎‏‏‎‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‎‎‏‏‏‏‎‏‏‎‎‏‎‎‏‏‏‏‎‏‎‎‎‎‎‎‎‎‎‏‎‎‎‏‎‎‎‏‏‎Tap for more information‎‏‎‎‏‎"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‏‏‏‏‎‏‏‎‎‎‏‎‎‏‎‏‎‏‏‏‎‎‎‎‏‎‏‎‏‏‏‏‏‏‏‏‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‎‎‏‏‎No alarm set‎‏‎‎‏‎"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 4157fca..10079a6 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -58,7 +58,7 @@
     <string name="always_use_device" msgid="210535878779644679">"Abrir siempre <xliff:g id="APPLICATION">%1$s</xliff:g> cuando se conecte <xliff:g id="USB_DEVICE">%2$s</xliff:g>"</string>
     <string name="always_use_accessory" msgid="1977225429341838444">"Abrir siempre <xliff:g id="APPLICATION">%1$s</xliff:g> cuando se conecte <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>"</string>
     <string name="usb_debugging_title" msgid="8274884945238642726">"¿Permitir depuración por USB?"</string>
-    <string name="usb_debugging_message" msgid="5794616114463921773">"La huella dactilar de tu clave RSA es:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+    <string name="usb_debugging_message" msgid="5794616114463921773">"La huella digital de tu clave RSA es:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
     <string name="usb_debugging_always" msgid="4003121804294739548">"Permitir siempre desde esta computadora"</string>
     <string name="usb_debugging_allow" msgid="1722643858015321328">"Permitir"</string>
     <string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"No tienes permitida la depuración por USB"</string>
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Cancelar"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Compartir"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Se canceló la grabación de pantalla"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Se guardó la grabación de pantalla"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Presiona para ver"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"No se pudo borrar la grabación de pantalla"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Error al obtener permisos"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Error al iniciar la grabación de pantalla"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Usuario nuevo"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Internet"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Seguro para aviones"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Redes disponibles"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Redes no disponible"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Sin conexión"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Hasta el amanecer"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"A la(s) <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Hasta la(s) <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Reducir el brillo"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"La tecnología NFC está inhabilitada"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"La tecnología NFC está habilitada"</string>
@@ -470,11 +466,10 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Mostrar perfil"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Agregar usuario"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Usuario nuevo"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Finalizar sesión de invitado"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"¿Eliminar invitado?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Se eliminarán las aplicaciones y los datos de esta sesión."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Eliminar"</string>
-    <string name="guest_wipe_session_title" msgid="7147965814683990944">"Bienvenido nuevamente, invitado."</string>
+    <string name="guest_wipe_session_title" msgid="7147965814683990944">"¡Hola de nuevo, invitado!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"¿Quieres retomar la sesión?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Volver a empezar"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Sí, continuar"</string>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Tu padre o madre administra este dispositivo"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Tu organización es propietaria de este dispositivo y podría controlar el tráfico de red"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> es la organización propietaria de este dispositivo y podría controlar el tráfico de red"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> proporciona este dispositivo"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Este dispositivo pertenece a tu organización y está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Este dispositivo pertenece a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> y está conectado a <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Este dispositivo pertenece a tu organización"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Tu perfil de trabajo está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Tu perfil personal está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Este dispositivo está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> proporciona este dispositivo"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Administración del dispositivo"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Supervisión del perfil"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Supervisión de red"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Ver políticas"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Ver controles"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Este dispositivo pertenece a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nTu administrador de TI puede controlar y administrar la configuración, el acceso corporativo, las apps, los datos asociados al dispositivo y la información de ubicación.\n\nPara obtener más información, comunícate con el administrador de TI."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"Es posible que <xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> pueda acceder a los datos asociados con este dispositivo y administrar las apps y cambiar su configuración. \n\nSi tienes preguntas, comunícate con <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Este dispositivo pertenece a tu organización.\n\nTu administrador de TI puede controlar y administrar la configuración, el acceso corporativo, las apps, los datos asociados al dispositivo y la información de ubicación.\n\nPara obtener más información, comunícate con el administrador de TI."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Tu organización instaló una autoridad de certificación en este dispositivo. Es posible que se controle o modifique el tráfico de tu red segura."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Tu organización instaló una autoridad de certificación en tu perfil de trabajo. Es posible que se controle o modifique el tráfico de tu red segura."</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Ver en modo de demostración"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Alarma"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Listo"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Perfil de trabajo"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Modo de avión"</string>
     <string name="add_tile" msgid="6239678623873086686">"Agregar mosaico"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Cerrar configuración rápida"</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Se estableció la alarma."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Accediste como <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"elegir usuario"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Sin Internet"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Abrir página de detalles"</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"No disponible debido a <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Abrir configuración de <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Editar orden de configuración"</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menú de encendido"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Página <xliff:g id="ID_1">%1$d</xliff:g> de <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Pantalla de bloqueo"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"El teléfono se apagó por calor"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Mover hacia la izquierda"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Mover hacia la derecha"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Botón de ampliación"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Ampliar toda la pantalla"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Ampliar pantalla completa"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Ampliar parte de la pantalla"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Botón"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"El botón de accesibilidad reemplaza el gesto de accesibilidad\n\n"<annotation id="link">"Ver configuración"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Mueve el botón hacia el borde para ocultarlo temporalmente"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Controles de dispositivos"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Agrega controles para los dispositivos conectados"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Configurar controles de dispositivos"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Vincular dispositivo nuevo"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Widgets de conversación"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Presiona una conversación para agregarla a tu pantalla principal"</string>
+    <string name="timestamp" msgid="6577851592534538533">"Hace <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"Hace menos de <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"Hace más de <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Cumpleaños"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Cumpleaños pronto"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Aniversario"</string>
+    <string name="location_status" msgid="1294990572202541812">"Comparte ubicación"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Nueva historia"</string>
+    <string name="video_status" msgid="4548544654316843225">"Mirando"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Escuchando"</string>
+    <string name="game_status" msgid="1340694320630973259">"Jugando"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Amigos"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Charlemos esta noche"</string>
+    <string name="missed_call" msgid="4228016077700161689">"Llamada perdida"</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="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problema al leer el medidor de batería"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Presiona para obtener más información"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"No se estableció alarma"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 8d8f5b5..48353ae 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Cancelar"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Compartir"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Se ha cancelado la grabación de la pantalla"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Grabación de pantalla guardada"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Toca para verla"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"No se ha podido eliminar la grabación de la pantalla"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"No se han podido obtener los permisos"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"No se ha podido empezar a grabar la pantalla"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Nuevo usuario"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Internet"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Modo avión"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Redes disponibles"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Redes no disponibles"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"No conectado"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Hasta el amanecer"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"A las <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Hasta las <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Reducir brillo"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"El NFC está desactivado"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"El NFC está activado"</string>
@@ -470,7 +466,6 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Mostrar perfil"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Añadir usuario"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Nuevo usuario"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Finalizar sesión de invitado"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"¿Quitar invitado?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Se eliminarán todas las aplicaciones y datos de esta sesión."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Quitar"</string>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Este dispositivo lo gestionan tu padre o tu madre"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"El dispositivo pertenece a tu organización, que puede monitorizar su tráfico de red"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"El dispositivo pertenece a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, que puede monitorizar su tráfico de red"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Este dispositivo lo proporciona <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Este dispositivo pertenece a tu organización y está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Este dispositivo pertenece a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> y está conectado a <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Este dispositivo pertenece a tu organización"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Tu perfil de trabajo está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Tu perfil personal está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Este dispositivo está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Este dispositivo lo proporciona <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Administración de dispositivos"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Supervisión del perfil"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Supervisión de red"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Ver políticas"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Ver controles"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"El dispositivo pertenece a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nEl administrador de TI puede monitorizar y gestionar los ajustes, el acceso corporativo, las aplicaciones, la información de ubicación del dispositivo y los datos asociados a él.\n\nPara obtener más información, ponte en contacto con el administrador de TI."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> puede acceder a los datos asociados a este dispositivo, gestionar aplicaciones y cambiar su configuración.\n\nSi tienes alguna pregunta, ponte en contacto con <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"El dispositivo pertenece a tu organización.\n\nEl administrador de TI puede monitorizar y gestionar los ajustes, el acceso corporativo, las aplicaciones, la información de ubicación del dispositivo y los datos asociados a él.\n\nPara obtener más información, ponte en contacto con el administrador de TI."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Tu organización ha instalado una entidad de certificación en este dispositivo. Es posible que se supervise o se modifique tu tráfico de red seguro."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Tu organización ha instalado una entidad de certificación en tu perfil de trabajo. Es posible que se supervise o se modifique tu tráfico de red seguro."</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Mostrar modo de demostración"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Alarma"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Listo"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Perfil de trabajo"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Modo avión"</string>
     <string name="add_tile" msgid="6239678623873086686">"Añadir icono"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Cerrar ajustes rápidos."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Alarma establecida."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Has iniciado sesión como <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"elegir un usuario"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Sin Internet"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Abrir detalles."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"No disponible (<xliff:g id="REASON">%s</xliff:g>)"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Abrir ajustes de <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Cambiar el orden de los ajustes."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menú de encendido"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Página <xliff:g id="ID_1">%1$d</xliff:g> de <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Pantalla de bloqueo"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"Teléfono apagado por calor"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Mover hacia la izquierda"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Mover hacia la derecha"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Botón para cambiar el modo de ampliación"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Ampliar toda la pantalla"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Ampliar pantalla completa"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Ampliar parte de la pantalla"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Cambiar"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"El botón Accesibilidad ha reemplazado al gesto de accesibilidad\n\nVer configuración"<annotation id="link"></annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Mueve el botón hacia el borde para ocultarlo temporalmente"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Control de dispositivos"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Añade controles para tus dispositivos conectados"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Configurar control de dispositivos"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Vincular nuevo dispositivo"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Widgets de conversación"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Toca una conversación para añadirla a la pantalla de inicio"</string>
+    <string name="timestamp" msgid="6577851592534538533">"Hace <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"Hace menos de <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"Hace más de <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Fecha de nacimiento"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Cumpleaños en breve"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Aniversario"</string>
+    <string name="location_status" msgid="1294990572202541812">"Compartiendo ubicación"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Nueva historia"</string>
+    <string name="video_status" msgid="4548544654316843225">"Viendo"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Escuchando"</string>
+    <string name="game_status" msgid="1340694320630973259">"Reproduciendo"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Amigos"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Charlemos esta noche"</string>
+    <string name="missed_call" msgid="4228016077700161689">"Llamada perdida"</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="battery_state_unknown_notification_title" msgid="8464703640483773454">"No se ha podido leer el indicador de batería"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Toca la pantalla para consultar más información"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Ninguna alarma puesta"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 06fcd05..e988c71 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Tühista"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Jaga"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Ekraanikuva salvestamine on tühistatud"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Ekraanisalvestis on salvestatud"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Puudutage kuvamiseks"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Viga ekraanikuva salvestise kustutamisel"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Lubade hankimine ebaõnnestus"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Viga ekraanikuva salvestamise alustamisel"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Uus kasutaja"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"WiFi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Internet"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Lennukikindel"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Võrgud on saadaval"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Võrgud pole saadaval"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Ühendus puudub"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Kuni päikesetõusuni"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Sisse kell <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Kuni <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Ereduse vähendamine"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC on keelatud"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC on lubatud"</string>
@@ -470,7 +466,6 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Kuva profiil"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Lisa kasutaja"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Uus kasutaja"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Lõpeta külastajaseanss"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Kas eemaldada külaline?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Seansi kõik rakendused ja andmed kustutatakse."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Eemalda"</string>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Seda seadet haldab sinu vanem"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Teie organisatsioon on selle seadme omanik ja võib jälgida võrguliiklust"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> on selle seadme omanik ja võib jälgida võrguliiklust"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Selle seadme on andnud <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"See seade kuulub teie organisatsioonile ja on ühendatud rakendusega <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"See seade kuulub organisatsioonile <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ja on ühendatud rakendusega <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"See seade kuulub teie organisatsioonile"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Teie tööprofiil on ühendatud rakendusega <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Teie isiklik profiil on ühendatud rakendusega <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"See seade on ühendatud rakendusega <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Selle seadme on andnud <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Seadmehaldus"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Profiili jälgimine"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Võrgu jälgimine"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Kuva eeskirjad"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Kuva haldusvalikud"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"See seade kuulub organisatsioonile <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nIT-administraator saab jälgida ning hallata seadeid, ettevõttesisest juurdepääsu, rakendusi, seadmega seotud andmeid ja seadme asukohateavet.\n\nLisateabe saamiseks võtke ühendust IT-administraatoriga."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> võib pääseda juurde selle seadmega seostatud andmetele, hallata rakendusi ja muuta selle seadme seadeid.\n\nKui teil on küsimusi, võtke ühendust organisatsiooniga <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"See seade kuulub teie organisatsioonile.\n\nIT-administraator saab jälgida ning hallata seadeid, ettevõttesisest juurdepääsu, rakendusi, seadmega seotud andmeid ja seadme asukohateavet.\n\nLisateabe saamiseks võtke ühendust IT-administraatoriga."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Teie organisatsioon installis sellesse seadmesse sertifikaadi volituse. Teie turvalist võrguliiklust võidakse jälgida ja muuta."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Teie organisatsioon installis teie tööprofiilile sertifikaadi volituse. Teie turvalist võrguliiklust võidakse jälgida ja muuta."</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Kuva demorežiim"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Äratus"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Rahakott"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Valmis"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Tööprofiil"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Lennukirežiim"</string>
     <string name="add_tile" msgid="6239678623873086686">"Paani lisamine"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Sule kiirseaded."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Alarm on määratud."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Sisse logitud kasutajana <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"valige kasutaja"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Interneti-ühendus puudub"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Ava üksikasjad."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"Põhjuse <xliff:g id="REASON">%s</xliff:g> tõttu pole saadaval"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Ava teenuse <xliff:g id="ID_1">%s</xliff:g> seaded."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Muuda seadete järjestust."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Toitemenüü"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Leht <xliff:g id="ID_1">%1$d</xliff:g>/<xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Lukustuskuva"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"Tel. lül. kuumuse tõttu välja"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Teisalda vasakule"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Teisalda paremale"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Suurenduse lüliti"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Kogu ekraanikuva suurendamine"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Täisekraani suurendamine"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Ekraanikuva osa suurendamine"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Vaheta"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"Juurdepääsetavuse nupp asendas juurdepääsuliigutuse\n\n"<annotation id="link">"Vaadake seadeid"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Teisaldage nupp serva, et see ajutiselt peita"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Seadmete juhikud"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Lisage juhtelemendid ühendatud seadmete jaoks"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Seadmete juhtimisvidinate seadistamine"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Uue seadme sidumine"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Vestlusvidinad"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Puudutage vestlust, et lisada see oma avakuvale"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> tagasi"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"Vähem kui <xliff:g id="DURATION">%1$s</xliff:g> tagasi"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"Üle <xliff:g id="DURATION">%1$s</xliff:g> tagasi"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Sünnipäev"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Peagi on sünnipäev"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Aastapäev"</string>
+    <string name="location_status" msgid="1294990572202541812">"Asukoha jagamine"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Uus lugu"</string>
+    <string name="video_status" msgid="4548544654316843225">"Vaatamas"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Kuulamine"</string>
+    <string name="game_status" msgid="1340694320630973259">"Mängimas"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Sõbrad"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Vestleme täna õhtul!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"Vastamata kõne"</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="battery_state_unknown_notification_title" msgid="8464703640483773454">"Probleem akumõõdiku lugemisel"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Puudutage lisateabe saamiseks"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Äratust pole"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 2eab6eb..00443dc 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Utzi"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Partekatu"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Utzi zaio pantaila grabatzeari"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Gorde da pantailaren grabaketa"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Sakatu ikusteko"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Errore bat gertatu da pantailaren grabaketa ezabatzean"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Ezin izan dira lortu baimenak"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Errore bat gertatu da pantaila grabatzen hastean"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Erabiltzaile berria"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wifia"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Internet"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Hegaldietarako segurua"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Erabilgarri daude sareak"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Ez dago sarerik erabilgarri"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Konektatu gabe"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Egunsentira arte"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Aktibatze-ordua: <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Desaktibatze-ordua: <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Murriztu distira"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"Desgaituta dago NFC"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"Gaituta dago NFC"</string>
@@ -470,7 +466,6 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Erakutsi profila"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Gehitu erabiltzailea"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Erabiltzaile berria"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Amaitu gonbidatuentzako saioa"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Gonbidatua kendu nahi duzu?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Saioko aplikazio eta datu guztiak ezabatuko dira."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Kendu"</string>
@@ -485,7 +480,7 @@
     <string name="user_logout_notification_text" msgid="7441286737342997991">"Amaitu erabiltzailearen saioa"</string>
     <string name="user_logout_notification_action" msgid="7974458760719361881">"AMAITU ERABILTZAILEAREN SAIOA"</string>
     <string name="user_add_user_title" msgid="4172327541504825032">"Beste erabiltzaile bat gehitu?"</string>
-    <string name="user_add_user_message_short" msgid="2599370307878014791">"Erabiltzaile bat gehitzen duzunean, horrek bere eremua konfiguratu beharko du.\n\nEdozein erabiltzailek egunera ditzake beste erabiltzaile guztien aplikazioak."</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Erabiltzaile bat gehitzen duzunean, erabiltzaile horrek bere eremua konfiguratu beharko du.\n\nEdozein erabiltzailek egunera ditzake beste erabiltzaile guztien aplikazioak."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Erabiltzaile-mugara iritsi zara"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Gehienez, <xliff:g id="COUNT">%d</xliff:g> erabiltzaile gehi ditzakezu.</item>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Zure gurasoak kudeatzen du gailua"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Gailu hau zure erakundearena da, eta baliteke hark sareko trafikoa gainbegiratzea"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Gailu hau <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> erakundearena da, eta baliteke sareko trafikoa gainbegiratzea"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> erakundeak eman du gailu hau"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Gailu hau zure erakundearena da, eta <xliff:g id="VPN_APP">%1$s</xliff:g> sarera dago konektatuta"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Gailu hau <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> erakundearena da, eta <xliff:g id="VPN_APP">%2$s</xliff:g> sarera dago konektatuta"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Gailu hau zure erakundearena da"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"<xliff:g id="VPN_APP">%1$s</xliff:g> sarera konektatuta daukazu laneko profila"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"<xliff:g id="VPN_APP">%1$s</xliff:g> sarera konektatuta daukazu profil pertsonala"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Gailu hau <xliff:g id="VPN_APP">%1$s</xliff:g> sarera dago konektatuta"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> erakundeak eman du gailu hau"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Gailuaren kudeaketa"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Profila kontrolatzeko aukera"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Sareen kontrola"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Ikusi gidalerroak"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Ikusi kontrolatzeko aukerak"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Gailu hau <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> erakundearena da.\n\nIKT saileko administratzaileak gainbegiratu eta kudeatu egin ditzake ezarpenak, enpresa-sarbidea, aplikazioak, gailuarekin erlazionatutako datuak eta gailuaren kokapen-informazioa.\n\nInformazio gehiago lortzeko, jarri IKT saileko administratzailearekin harremanetan."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"Baliteke <xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> erakundeak gailu honekin erlazionatutako datuak atzitu, aplikazioak kudeatu eta gailuaren ezarpenak aldatu ahal izatea.\n\nGalderarik baduzu, jarri harremanetan <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g> erakundearekin."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Gailu hau zure erakundearena da.\n\nIKT saileko administratzaileak gainbegiratu eta kudeatu egin ditzake ezarpenak, enpresa-sarbidea, aplikazioak, gailuarekin erlazionatutako datuak eta gailuaren kokapen-informazioa.\n\nInformazio gehiago lortzeko, jarri IKT saileko administratzailearekin harremanetan."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Erakundeak ziurtagiri-emaile bat instalatu du gailuan. Baliteke sareko trafiko segurua gainbegiratzea edo aldatzea."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Erakundeak ziurtagiri-emaile bat instalatu dizu laneko profilean. Baliteke sareko trafiko segurua gainbegiratzea edo aldatzea."</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Erakutsi demo modua"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Alarma"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Prest"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Work profila"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Hegaldi modua"</string>
     <string name="add_tile" msgid="6239678623873086686">"Gehitu lauza"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Itxi ezarpen bizkorrak."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Alarma ezarri da."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"<xliff:g id="ID_1">%s</xliff:g> gisa hasi duzu saioa"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"erabiltzailea aukeratzeko"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Ez dago Interneteko konexiorik"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Ireki xehetasunak."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"Ez dago erabilgarri arrazoi honengatik: <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Ireki <xliff:g id="ID_1">%s</xliff:g> ezarpenak."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Editatu ezarpenen ordena."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Itzaltzeko menua"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_1">%1$d</xliff:g>/<xliff:g id="ID_2">%2$d</xliff:g> orria"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Pantaila blokeatua"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"Beroegi egoteagatik itzali da"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Eraman ezkerrera"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Eraman eskuinera"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Lupa aplikatzeko botoia"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Handitu pantaila osoa"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Handitu pantaila osoa"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Handitu pantailaren zati bat"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Botoia"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"Erabilerraztasuna botoiak erabilerraztasun-keinua ordezkatu du\n\n"<annotation id="link">"Ikusi ezarpenak"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Eraman botoia ertzera aldi baterako ezkutatzeko"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Gailuak kontrolatzeko widgetak"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Gehitu konektatutako gailuak kontrolatzeko widgetak"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Konfiguratu gailuak kontrolatzeko widgetak"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Parekatu beste gailu batekin"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Elkarrizketa-widgetak"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Sakatu elkarrizketa bat hasierako pantailan gehitzeko"</string>
+    <string name="timestamp" msgid="6577851592534538533">"Duela <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"Duela <xliff:g id="DURATION">%1$s</xliff:g> baino gutxiago"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"Duela <xliff:g id="DURATION">%1$s</xliff:g> baino gehiago"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Urtebetetzea"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Badator urtebetetzea"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Urteurrena"</string>
+    <string name="location_status" msgid="1294990572202541812">"Kokapena partekatzen"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Istorio berria"</string>
+    <string name="video_status" msgid="4548544654316843225">"Ikusten"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Entzuten"</string>
+    <string name="game_status" msgid="1340694320630973259">"Erreproduzitzen"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Lagunak"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Txatea dezagun gaur gauean!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"Dei galdua"</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="battery_state_unknown_notification_title" msgid="8464703640483773454">"Arazo bat gertatu da bateria-neurgailua irakurtzean"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Informazio gehiago lortzeko, sakatu hau"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Ez da ezarri alarmarik"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index b25f118..4f733c2 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"لغو"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"هم‌رسانی"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"ضبط صفحه‌نمایش لغو شد"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"قطعه ضبط‌شده از صفحه‌نمایش ذخیره شد"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"برای مشاهده ضربه بزنید"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"خطا در حذف فایل ضبط صفحه‌نمایش"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"مجوزها دریافت نشدند"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"خطا هنگام شروع ضبط صفحه‌نمایش"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"کاربر جدید"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"اینترنت"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"ایمن در هواپیما"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"شبکه دردسترس است"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"شبکه دردسترس نیست"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"متصل نیست"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"تا طلوع آفتاب"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"ساعت <xliff:g id="TIME">%s</xliff:g> روشن می‌شود"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"تا<xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"کاهش روشنایی"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"‏ارتباط میدان نزدیک (NFC)"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"‏«ارتباط میدان نزدیک» (NFC) غیرفعال است"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"‏«ارتباط میدان نزدیک» (NFC) فعال است"</string>
@@ -470,7 +466,6 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"نمایش نمایه"</string>
     <string name="user_add_user" msgid="4336657383006913022">"افزودن کاربر"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"کاربر جدید"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"پایان دادن به جلسه مهمان"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"مهمان حذف شود؟"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"همه برنامه‌ها و داده‌های این جلسه حذف خواهد شد."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"حذف"</string>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"این دستگاه را ولی‌تان مدیریت می‌کند"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"مالک این دستگاه سازمان شما است و ممکن است ترافیک شبکه را پایش کند"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"مالک این دستگاه <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> است و ممکن است ترافیک شبکه را پایش کند"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"این دستگاه ازسوی <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> تأمین شده است"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"این دستگاه به سازمان شما تعلق دارد و به <xliff:g id="VPN_APP">%1$s</xliff:g> متصل است"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"این دستگاه به <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> تعلق دارد و به <xliff:g id="VPN_APP">%2$s</xliff:g> متصل است"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"این دستگاه به سازمان شما تعلق دارد"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"نمایه کاری به <xliff:g id="VPN_APP">%1$s</xliff:g> متصل است"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"نمایه شخصی شما به <xliff:g id="VPN_APP">%1$s</xliff:g> متصل است"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"این دستگاه به <xliff:g id="VPN_APP">%1$s</xliff:g> متصل است"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"این دستگاه ازسوی <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> تأمین شده است"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"مدیریت دستگاه"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"کنترل نمایه"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"کنترل شبکه"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"مشاهده خط‌مشی‌ها"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"مشاهده کنترل‌ها"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"این دستگاه به <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> تعلق دارد.\n\nسرپرست فناوری اطلاعات می‌تواند تنظیمات، دسترسی شرکتی، برنامه‌ها، داده‌های مرتبط با دستگاه، و اطلاعات مکان دستگاهتان را کنترل و مدیریت کند.\n\nبرای اطلاعات بیشتر، با سرپرست فناوری و اطلاعات تماس بگیرید."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"ممکن است <xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> بتواند به داده‌های مرتبط با این دستگاه دسترسی یابد، برنامه‌ها را مدیریت کند، و تنظیمات این دستگاه‌ها را تغییر دهد.\n\nاگر سؤالی دارید، با <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g> تماس بگیرید."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"این دستگاه به سازمان شما تعلق دارد.\n\nسرپرست فناوری اطلاعات می‌تواند تنظیمات، دسترسی شرکتی، برنامه‌ها، و داده‌های مرتبط با دستگاه و اطلاعات مکان دستگاهتان را کنترل و مدیریت کند.\n\nبرای اطلاعات بیشتر، با سرپرست فناوری و اطلاعات تماس بگیرید."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"سازمان شما مرجع گواهینامه‌ای در این دستگاه نصب کرده است. ممکن است ترافیک امن شبکه شما پایش یا تغییر داده شود."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"سازمان شما مرجع گواهینامه‌ای در نمایه کاری شما نصب کرده است. ممکن است ترافیک امن شبکه شما پایش یا تغییر داده شود."</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"نمایش حالت نمایشی"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"اترنت"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"زنگ"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"کیف‌پول"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"آماده"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"نمایه کاری"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"حالت هواپیما"</string>
     <string name="add_tile" msgid="6239678623873086686">"افزودن کاشی"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"بستن تنظیمات سریع."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"تنظیم زنگ ساعت."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"به‌عنوان <xliff:g id="ID_1">%s</xliff:g> به سیستم وارد شده‌اید"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"انتخاب کاربر"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"عدم اتصال به اینترنت"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"باز کردن جزئیات."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"به‌دلیل <xliff:g id="REASON">%s</xliff:g> دردسترس نیست"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"باز کردن تنظیمات <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"ویرایش ترتیب تنظیمات."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"منوی روشن/خاموش"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"صفحه <xliff:g id="ID_1">%1$d</xliff:g> از <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"صفحه قفل"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"تلفن به علت گرم شدن خاموش شد"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"انتقال به راست"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"انتقال به چپ"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"کلید درشت‌نمایی"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"درشت‌نمایی تمام صفحه"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"درشت‌نمایی تمام‌صفحه"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"درشت‌نمایی بخشی از صفحه"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"کلید"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"دکمه دسترس‌پذیری جایگزین اشاره دسترس‌پذیری شد\n\n"<annotation id="link">"مشاهده تنظیمات"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"برای پنهان کردن موقتی دکمه، آن را به لبه ببرید"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"کنترل‌های دستگاه"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"افزودن کنترل‌ها برای دستگاه‌های متصل"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"تنظیم کنترل‌های دستگاه"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"مرتبط کردن دستگاه جدید"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"ابزارک‌های مکالمه"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"روی مکالمه‌ای ضربه بزنید تا به «صفحه اصلی» اضافه شود"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> قبل"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"کمتر از <xliff:g id="DURATION">%1$s</xliff:g> قبل"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"بیش‌از <xliff:g id="DURATION">%1$s</xliff:g> قبل"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"تاریخ تولد"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"تاریخ تولد نزدیک است"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"سالگرد"</string>
+    <string name="location_status" msgid="1294990572202541812">"درحال هم‌رسانی مکان"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"داستان جدید"</string>
+    <string name="video_status" msgid="4548544654316843225">"درحال تماشا"</string>
+    <string name="audio_status" msgid="4237055636967709208">"درحال گوش کردن"</string>
+    <string name="game_status" msgid="1340694320630973259">"درحال پخش"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"دوستان"</string>
+    <string name="empty_status" msgid="5938893404951307749">"بیایید امشب گپ بزنیم!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"تماس بی‌پاسخ"</string>
+    <string name="people_tile_description" msgid="8154966188085545556">"دیدن به‌روزرسانی‌های وضعیت، تماس‌های بی‌پاسخ، و پیام‌های اخیر"</string>
+    <string name="people_tile_title" msgid="6589377493334871272">"مکالمه"</string>
     <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"مشکلی در خواندن میزان باتری وجود دارد"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"برای اطلاعات بیشتر ضربه بزنید"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"هشداری تنظیم نشده است"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index c9043d1..47b716e 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Peruuta"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Jaa"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Näytön tallennus peruutettu"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Näyttötallenne tallennettu"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Napauta näyttääksesi"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Virhe poistettaessa näyttötallennetta"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Käyttöoikeuksien hakeminen epäonnistui."</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Virhe näytön tallennuksen aloituksessa"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Uusi käyttäjä"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Internet"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Lentokoneturvallinen"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Verkkoja käytettävissä"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Ei verkkoja käytettävissä"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Ei yhteyttä"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Auringonnousuun"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Päälle klo <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> asti"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Vähennä kirkkautta"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC on poistettu käytöstä"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC on käytössä"</string>
@@ -470,7 +466,6 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Näytä profiili"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Lisää käyttäjä"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Uusi käyttäjä"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Lopeta Vierailija-käyttökerta"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Poistetaaanko vieras?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Kaikki sovellukset ja tämän istunnon tiedot poistetaan."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Poista"</string>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Vanhempasi ylläpitää tätä laitetta"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Organisaatiosi omistaa laitteen ja voi valvoa verkkoliikennettä"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> omistaa laitteen ja voi valvoa verkkoliikennettä"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> tarjoaa tämän laitteen"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Organisaatiosi omistaa laitteen, joka on yhdistetty tähän: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> omistaa laitteen, joka on yhdistetty tähän: <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Organisaatiosi omistaa tämän laitteen"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Työprofiilisi on yhdistetty tähän: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Henkilökohtainen profiilisi on yhdistetty tähän: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Laite on yhdistetty tähän: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> tarjoaa tämän laitteen"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Laitehallinta"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Profiilin valvonta"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Verkon valvonta"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Näytä säännöt"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Katso asetukset"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> omistaa tämän laitteen.\n\nJärjestelmänvalvoja voi valvoa ja muuttaa asetuksia, yrityskäyttöä, sovelluksia sekä laitteeseen yhdistettyjä tietoja ja sen sijaintitietoja.\n\nSaat lisätietoja järjestelmänvalvojalta."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> voi saada pääsyn tähän laitteeseen liittyvään dataan, ylläpitää sovelluksia ja muuttaa laitteen asetuksia.\n\nJos sinulla on kysyttävää, ota yhteyttä: <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Organisaatiosi omistaa tämän laitteen.\n\nJärjestelmänvalvoja voi valvoa ja muuttaa asetuksia, yrityskäyttöä, sovelluksia sekä laitteeseen yhdistettyjä tietoja ja sen sijaintitietoja.\n\nSaat lisätietoja järjestelmänvalvojalta."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Organisaatiosi asensi laitteeseen varmenteen myöntäjän. Suojattua verkkoliikennettäsi voidaan valvoa tai muuttaa."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Organisaatiosi lisäsi työprofiiliin varmenteen myöntäjän. Suojattua verkkoliikennettäsi voidaan valvoa tai muuttaa."</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Näytä esittelytila"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Herätys"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Valmis"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Työprofiili"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Lentokonetila"</string>
     <string name="add_tile" msgid="6239678623873086686">"Lisää ruutu"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Sulje pika-asetukset."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Herätys asetettu"</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Kirjautunut tilillä <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"valitse käyttäjä"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Ei internetyhteyttä"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Avaa tiedot."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"Ei käytettävissä, koska <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Avaa kohteen <xliff:g id="ID_1">%s</xliff:g> asetukset."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Muokkaa asetusten järjestystä."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Virtavalikko"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Sivu <xliff:g id="ID_1">%1$d</xliff:g>/<xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Lukitusnäyttö"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"Puhelin sammui kuumuuden takia"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Siirrä vasemmalle"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Siirrä oikealle"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Suurennusvalinta"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Suurenna koko näyttö"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Koko näytön suurennus"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Suurenna osa näytöstä"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Vaihda"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"Esteettömyyspainike on korvannut esteettömyyseleen\n\n"<annotation id="link">"Katso asetukset"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Piilota painike tilapäisesti siirtämällä se reunaan"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Laitteiden hallinta"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Lisää ohjaimia yhdistettyjä laitteita varten"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Laitteiden hallinnan käyttöönotto"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Muodosta uusi laitepari"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Keskusteluwidgetit"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Lisää keskustelu aloitusnäytölle napauttamalla sitä"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> sitten"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"Alle <xliff:g id="DURATION">%1$s</xliff:g> sitten"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"Yli <xliff:g id="DURATION">%1$s</xliff:g> sitten"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Syntymäpäivä"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Syntymäpäivä pian"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Vuosipäivä"</string>
+    <string name="location_status" msgid="1294990572202541812">"Sijaintia jaetaan"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Uusi juttu"</string>
+    <string name="video_status" msgid="4548544654316843225">"Katsotaan"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Kuunnellaan"</string>
+    <string name="game_status" msgid="1340694320630973259">"Toistetaan"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Kaverit"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Jutellaan illalla!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"Vastaamaton puhelu"</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="battery_state_unknown_notification_title" msgid="8464703640483773454">"Ongelma akkumittarin lukemisessa"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Saat lisätietoja napauttamalla"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Ei herätyksiä"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 8e6c39c..812bee7 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Annuler"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Partager"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"L\'enregistrement d\'écran a été annulé"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Enregistrement de l\'écran sauvegardé"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Touchez pour afficher"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Une erreur s\'est produite lors de la suppression de l\'enregistrement d\'écran"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Impossible d\'obtenir les autorisations"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Une erreur s\'est produite lors du démarrage de l\'enregistrement d\'écran"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Nouvel utilisateur"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Internet"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Sécuritaire pour les avions"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Réseaux accessibles"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Aucun réseau accessible"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Non connecté"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Jusqu\'à l\'aube"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Actif à <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Jusqu\'à <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Réduire la luminosité"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC désactivée"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC activée"</string>
@@ -470,7 +466,6 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Afficher le profil"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Ajouter un utilisateur"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Nouvel utilisateur"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Mettre fin à la session d\'invité"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Supprimer l\'invité?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Toutes les applications et les données de cette session seront supprimées."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Supprimer"</string>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Cet appareil est géré par ton parent"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Votre organisation possède cet appareil et peut contrôler le trafic réseau"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> possède cet appareil et peut contrôler le trafic réseau"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Cet appareil est fourni par <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Cet appareil appartient à votre organisation et est connecté à <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Cet appareil appartient à <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> et est connecté à <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Cet appareil appartient à votre organisation"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Votre profil professionnel est connecté à <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Votre profil personnel est connecté à <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Cet appareil est connecté à <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Cet appareil est fourni par <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Gestion d\'appareils"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Contrôle de profil"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Surveillance réseau"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Afficher les politiques"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Afficher les commandes"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Votre appareil appartient à <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nVotre administrateur informatique peut contrôler et gérer les paramètres, l\'accès aux données d\'entreprise, les applications, les données associées à l\'appareil et les renseignements sur sa position.\n\nPour obtenir plus d\'information, communiquez avec votre administrateur informatique."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> pourrait être en mesure d\'accéder aux données associées à cet appareil, de modifier ses paramètres et de gérer des applications.\n\nSi vous avez des questions, communiquez avec <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Cet appareil appartient à votre organisation.\n\nVotre administrateur informatique peut contrôler et gérer les paramètres, l\'accès aux données d\'entreprise, les applications, les données associées à votre appareil et les renseignements sur sa position.\n\nPour obtenir plus d\'information, communiquez avec votre administrateur informatique."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Votre entreprise a installé une autorité de certification sur cet appareil. Votre trafic sur le réseau sécurisé peut être contrôlé ou modifié."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Votre entreprise a installé une autorité de certification dans votre profil professionnel. Votre trafic sur le réseau sécurisé peut être contrôlé ou modifié."</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Afficher le mode Démonstration"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Alarme"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Prêt"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Profil professionnel"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Mode Avion"</string>
     <string name="add_tile" msgid="6239678623873086686">"Ajouter la tuile"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Fermer les réglages rapides."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Alarme activée."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Connecté comme <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"choisir un utilisateur"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Aucune connexion Internet"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Ouvrir les détails."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"Non disponible pour la raison suivante : <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Ouvrir les paramètres <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Modifier l\'ordre des paramètres."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menu de l\'interrupteur"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Page <xliff:g id="ID_1">%1$d</xliff:g> sur <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Écran de verrouillage"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"Tél. éteint car il surchauffait"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Déplacer vers la gauche"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Déplacer vers la droite"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Commutateur d\'agrandissement"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Agrandir l\'écran entier"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Agrandir la totalité de l\'écran"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Agrandir une partie de l\'écran"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Commutateur"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"Le bouton d\'accessibilité a remplacé le geste d\'accessibilité\n\n"<annotation id="link">"Voir les paramètres"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Déplacez le bouton vers le bord pour le masquer temporairement"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Commandes des appareils"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Ajoutez des commandes pour vos appareils connectés"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Configurer les commandes des appareils"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Associer un autre appareil"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Widgets de conversation"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Touchez une conversation pour l\'ajouter à votre écran d\'accueil"</string>
+    <string name="timestamp" msgid="6577851592534538533">"Il y a <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"Il y a moins de <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"Il y a plus de <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Anniversaire"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Anniversaire proche"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Anniversaire"</string>
+    <string name="location_status" msgid="1294990572202541812">"Partage de position"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Nouvel article"</string>
+    <string name="video_status" msgid="4548544654316843225">"En train de regarder…"</string>
+    <string name="audio_status" msgid="4237055636967709208">"En train d\'écouter…"</string>
+    <string name="game_status" msgid="1340694320630973259">"En train de jouer…"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Amis"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Clavardons ce soir!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"Appel manqué"</string>
+    <string name="people_tile_description" msgid="8154966188085545556">"Afficher 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="battery_state_unknown_notification_title" msgid="8464703640483773454">"Un problème est survenu lors de la lecture du niveau de charge de la pile"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Touchez pour en savoir plus"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Aucune alarme définie"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 837a424..8c3854e 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Annuler"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Partager"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Enregistrement de l\'écran annulé"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Enregistrement de l\'écran sauvegardé"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Appuyez pour afficher"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Erreur lors de la suppression de l\'enregistrement de l\'écran"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Échec d\'obtention des autorisations"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Erreur lors du démarrage de l\'enregistrement de l\'écran"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Nouvel utilisateur"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Internet"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Acceptés dans les avions"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Réseaux disponibles"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Réseaux non disponibles"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Non connecté"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Jusqu\'à l\'aube"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"À partir de <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Jusqu\'à <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Réduire la luminosité"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC désactivée"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"La technologie NFC est activée"</string>
@@ -470,7 +466,6 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Afficher le profil"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Ajouter un utilisateur"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Nouvel utilisateur"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Fermer la session Invité"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Supprimer l\'invité ?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Toutes les applications et les données de cette session seront supprimées."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Supprimer"</string>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Cet appareil est géré par tes parents"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Cet appareil appartient à votre organisation, qui peut contrôler votre trafic réseau"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Cet appareil appartient à <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, qui peut contrôler votre trafic réseau"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Cet appareil est fourni par <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Cet appareil appartient à votre organisation et il est connecté à <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Cet appareil appartient à <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> et il est connecté à <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Cet appareil appartient à votre organisation"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Votre profil professionnel est connecté à <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Votre profil personnel est connecté à <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Cet appareil est connecté à <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Cet appareil est fourni par <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Gestion des appareils"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Contrôle du profil"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Contrôle du réseau"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Afficher les règles"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Afficher les commandes"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Cet appareil appartient à <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nVotre administrateur informatique peut contrôler et gérer les paramètres, l\'accès aux données d\'entreprise, les applications, les données associées à l\'appareil et les informations sur sa localisation.\n\nPour plus d\'informations, contactez votre administrateur informatique."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"Il est possible que <xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> puisse accéder aux données associées à cet appareil, modifier ses paramètres et gérer les applis.\n\nSi vous avez des questions, contactez <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Cet appareil appartient à votre organisation.\n\nVotre administrateur informatique peut contrôler et gérer les paramètres, l\'accès aux données d\'entreprise, les applications, les données associées à l\'appareil et les informations sur sa localisation.\n\nPour plus d\'informations, contactez votre administrateur informatique."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Votre entreprise a installé une autorité de certification sur cet appareil. Votre trafic sur le réseau sécurisé peut être contrôlé ou modifié."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Votre entreprise a installé une autorité de certification dans votre profil professionnel. Votre trafic sur le réseau sécurisé peut être contrôlé ou modifié."</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Afficher le mode de démonstration"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Alarme"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Prêt"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Profil professionnel"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Mode Avion"</string>
     <string name="add_tile" msgid="6239678623873086686">"Ajouter un bloc"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Fermer les Réglages rapides."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Alarme définie."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Connecté en tant que <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"choisir un utilisateur"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Aucun accès à Internet"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Ouvrir les détails."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"Indisponible pour la raison suivante : <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Ouvrir les paramètres <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Modifier l\'ordre des paramètres."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menu Marche/Arrêt"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Page <xliff:g id="ID_1">%1$d</xliff:g> sur <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Écran de verrouillage"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"Tél. éteint car il surchauffait"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Déplacer vers la gauche"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Déplacer vers la droite"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Changer de mode d\'agrandissement"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Agrandir tout l\'écran"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Agrandir tout l\'écran"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Agrandir une partie de l\'écran"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Changer"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"Le bouton Accessibilité a remplacé le geste d\'accessibilité\n\n"<annotation id="link">"Afficher les paramètres"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Déplacer le bouton vers le bord pour le masquer temporairement"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Commandes des appareils"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Ajouter des commandes pour vos appareils connectés"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Configurer les commandes des appareils"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Associer un nouvel appareil"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Widgets de conversation"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Appuyez sur une conversation pour l\'ajouter à votre écran d\'accueil"</string>
+    <string name="timestamp" msgid="6577851592534538533">"Il y a <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"Il y a moins de <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"Il y a plus de <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Anniversaire"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Anniversaire à venir"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Fête"</string>
+    <string name="location_status" msgid="1294990572202541812">"Partage sa position"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Nouvelle story"</string>
+    <string name="video_status" msgid="4548544654316843225">"Regarde une vidéo"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Écoute"</string>
+    <string name="game_status" msgid="1340694320630973259">"Joue"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Amis"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Chattez ce soir !"</string>
+    <string name="missed_call" msgid="4228016077700161689">"Appel manqué"</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="battery_state_unknown_notification_title" msgid="8464703640483773454">"Un problème est survenu au niveau de la lecture de votre outil de mesure de batterie"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Appuyer pour en savoir plus"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Pas d\'alarme définie"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 199dd54..334da91 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Cancelar"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Compartir"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Cancelouse a gravación de pantalla"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Gardouse a gravación da pantalla"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Toca para ver o contido"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Produciuse un erro ao eliminar a gravación de pantalla"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Produciuse un erro ao obter os permisos"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Produciuse un erro ao iniciar a gravación da pantalla"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Novo usuario"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wifi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Internet"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Redes seguras para os avións"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Redes dispoñibles"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Non hai redes dispoñibles"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Non conectada"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Ata o amencer"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Activarase ás: <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Utilizarase ata as: <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Reducir brillo"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"A opción NFC está desactivada"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"A opción NFC está activada"</string>
@@ -470,11 +466,10 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Mostrar perfil"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Engadir usuario"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Novo usuario"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Finalizar sesión de invitado"</string>
-    <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Queres eliminar o invitado?"</string>
+    <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Queres quitar o convidado?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Eliminaranse todas as aplicacións e datos desta sesión."</string>
-    <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Eliminar"</string>
-    <string name="guest_wipe_session_title" msgid="7147965814683990944">"Benvido de novo, convidado."</string>
+    <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Quitar"</string>
+    <string name="guest_wipe_session_title" msgid="7147965814683990944">"Benvido de novo, convidado"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Queres continuar coa túa sesión?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Comezar de novo"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Si, continuar"</string>
@@ -485,7 +480,7 @@
     <string name="user_logout_notification_text" msgid="7441286737342997991">"Pechar sesión do usuario actual"</string>
     <string name="user_logout_notification_action" msgid="7974458760719361881">"PECHAR SESIÓN DO USUARIO"</string>
     <string name="user_add_user_title" msgid="4172327541504825032">"Engadir un usuario novo?"</string>
-    <string name="user_add_user_message_short" msgid="2599370307878014791">"Cando engadas un usuario novo, este deberá configurar o seu espazo\n\nCalquera usuario pode actualizar as aplicacións para todos os demais usuarios."</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Cando engadas un usuario novo, este deberá configurar o seu espazo.\n\nCalquera usuario pode actualizar as aplicacións para todos os demais usuarios."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Alcanzouse o límite de usuarios"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Podes engadir ata <xliff:g id="COUNT">%d</xliff:g> usuarios.</item>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"O teu pai ou nai xestiona este dispositivo"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"A túa organización é propietaria deste dispositivo e pode controlar o tráfico de rede"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> é a organización propietaria deste dispositivo e pode controlar o tráfico de rede"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> proporciona este dispositivo"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Este dispositivo pertence á túa organización e está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Este dispositivo pertence a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> e está conectado a <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Este dispositivo pertence á túa organización"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"O teu perfil de traballo está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"O teu perfil persoal está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Este dispositivo está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> proporciona este dispositivo"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Xestión de dispositivos"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Supervisión do perfil"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Supervisión de rede"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Ver políticas"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Ver controis"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Este dispositivo pertence a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nO teu administrador de TI pode supervisar e xestionar a configuración, o acceso corporativo, as aplicacións, os datos asociados co teu dispositivo e a información de localización deste último.\n\nPara obter máis información, contacta co teu administrador de TI."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"É posible que <xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> poida modificar a configuración deste dispositivo, acceder aos datos asociados a el e xestionar as aplicacións.\n\nSe tes preguntas, ponte en contacto con <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Este dispositivo pertence á túa organización.\n\nO teu administrador de TI pode supervisar e xestionar a configuración, o acceso corporativo, as aplicacións, os datos asociados co teu dispositivo e a información de localización deste último.\n\nPara obter máis información, contacta co teu administrador de TI."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"A túa organización instalou unha autoridade de certificación neste dispositivo. É posible que se controle ou se modifique o teu tráfico de rede segura."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"A túa organización instalou unha autoridade de certificación no teu perfil de traballo. É posible que se controle ou se modifique o teu tráfico de rede segura."</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Mostrar modo de demostración"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Alarma"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Listo"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Perfil de traballo"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Modo avión"</string>
     <string name="add_tile" msgid="6239678623873086686">"Engade un atallo"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Pechar a configuración rápida."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Alarma definida."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Sesión iniciada como <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"escoller usuario"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Non hai conexión a Internet"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Abrir detalles."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"Opcións non-dispoñibles polo seguinte motivo: <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Abrir configuración de <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Editar a orde das opcións de configuración."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menú de acendido"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Páxina <xliff:g id="ID_1">%1$d</xliff:g> de <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Pantalla de bloqueo"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"O teléfono apagouse pola calor"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Mover cara á esquerda"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Mover cara á dereita"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Interruptor do modo de ampliación"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Amplía toda a pantalla"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Ampliar pantalla completa"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Amplía parte da pantalla"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Cambiar"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"O botón de accesibilidade substituíu o xesto de accesibilidade\n\n"<annotation id="link">"Ver configuración"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Para ocultar temporalmente o botón, móveo ata o bordo"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Control de dispositivos"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Engade controis para os dispositivos conectados"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Configurar o control de dispositivos"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Vincular dispositivo novo"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Widgets de conversa"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Toca unha conversa para engadila á pantalla de inicio"</string>
+    <string name="timestamp" msgid="6577851592534538533">"Hai <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"Hai menos de <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"Hai máis de <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Aniversario"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Aniversario a caer"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Aniversario"</string>
+    <string name="location_status" msgid="1294990572202541812">"Compartindo localiz."</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Nova historia"</string>
+    <string name="video_status" msgid="4548544654316843225">"Vendo vídeo"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Escoitando"</string>
+    <string name="game_status" msgid="1340694320630973259">"Xogando"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Amigos"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Chateamos á noite?"</string>
+    <string name="missed_call" msgid="4228016077700161689">"Chamada perdida"</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="battery_state_unknown_notification_title" msgid="8464703640483773454">"Produciuse un problema ao ler o medidor da batería"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Toca para obter máis información"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Sen alarmas postas"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index d19c341..c8cdff6 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"રદ કરો"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"શેર કરો"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"સ્ક્રીન રેકોર્ડિંગ રદ કર્યું"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"સ્ક્રીન રેકોર્ડિંગ સાચવ્યું"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"જોવા માટે ટૅપ કરો"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"સ્ક્રીન રેકોર્ડિંગ ડિલીટ કરવામાં ભૂલ આવી"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"પરવાનગીઓ મેળવવામાં નિષ્ફળ રહ્યાં"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"સ્ક્રીનને રેકૉર્ડ કરવાનું શરૂ કરવામાં ભૂલ"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"નવો વપરાશકર્તા"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"વાઇ-ફાઇ"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"ઇન્ટરનેટ"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"એરપ્લેન મોડમાં ઉપયોગ માટે સુરક્ષિત"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"નેટવર્ક ઉપલબ્ધ છે"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"નેટવર્ક અનુપલબ્ધ છે"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"કનેક્ટ થયેલ નથી"</string>
@@ -380,7 +377,7 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="2325362583903258677">"સ્વતઃ"</string>
     <string name="quick_settings_inversion_label" msgid="5078769633069667698">"રંગોને ઉલટાવો"</string>
     <string name="quick_settings_color_space_label" msgid="537528291083575559">"રંગ સુધારણા મોડ"</string>
-    <string name="quick_settings_more_settings" msgid="2878235926753776694">"વધુ સેટિંગ્સ"</string>
+    <string name="quick_settings_more_settings" msgid="2878235926753776694">"વધુ સેટિંગ"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"થઈ ગયું"</string>
     <string name="quick_settings_connected" msgid="3873605509184830379">"કનેક્ટ થયેલ"</string>
     <string name="quick_settings_connected_battery_level" msgid="1322075669498906959">"કનેક્ટ કરેલ, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> બૅટરી"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"સૂર્યોદય સુધી"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g> વાગ્યે ચાલુ"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> વાગ્યા સુધી"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"બ્રાઇટનેસ ઘટાડો"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC અક્ષમ કરેલ છે"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC સક્ષમ કરેલ છે"</string>
@@ -470,12 +466,11 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"પ્રોફાઇલ બતાવો"</string>
     <string name="user_add_user" msgid="4336657383006913022">"વપરાશકર્તા ઉમેરો"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"નવો વપરાશકર્તા"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"અતિથિ સત્ર સમાપ્ત કરો"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"અતિથિ દૂર કરીએ?"</string>
-    <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"આ સત્રમાંની તમામ ઍપ્લિકેશનો અને ડેટા કાઢી નાખવામાં આવશે."</string>
+    <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"આ સત્રમાંની તમામ ઍપ અને ડેટા કાઢી નાખવામાં આવશે."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"દૂર કરો"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"ફરી સ્વાગત છે, અતિથિ!"</string>
-    <string name="guest_wipe_session_message" msgid="3393823610257065457">"શું તમે તમારું સત્ર ચાલુ કરવા માંગો છો?"</string>
+    <string name="guest_wipe_session_message" msgid="3393823610257065457">"શું તમે તમારું સત્ર ચાલુ રાખવા માંગો છો?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"શરૂ કરો"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"હા, ચાલુ રાખો"</string>
     <string name="guest_notification_title" msgid="4434456703930764167">"અતિથિ વપરાશકર્તા"</string>
@@ -485,7 +480,7 @@
     <string name="user_logout_notification_text" msgid="7441286737342997991">"વર્તમાન વપરાશકર્તાને લૉગઆઉટ કરો"</string>
     <string name="user_logout_notification_action" msgid="7974458760719361881">"વપરાશકર્તાને લૉગઆઉટ કરો"</string>
     <string name="user_add_user_title" msgid="4172327541504825032">"નવા વપરાશકર્તાને ઉમેરીએ?"</string>
-    <string name="user_add_user_message_short" msgid="2599370307878014791">"જ્યારે તમે કોઈ નવા વપરાશકર્તાને ઉમેરો છો, ત્યારે તે વ્યક્તિને તેમનું સ્થાન સેટ કરવાની જરૂર પડે છે.\n\nકોઈપણ વપરાશકર્તા બધા અન્ય વપરાશકર્તાઓ માટે એપ્લિકેશન્સને અપડેટ કરી શકે છે."</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"જ્યારે તમે કોઈ નવા વપરાશકર્તાને ઉમેરો છો, ત્યારે તે વ્યક્તિને તેમનું સ્થાન સેટ કરવાની જરૂર પડે છે.\n\nકોઈપણ વપરાશકર્તા બધા અન્ય વપરાશકર્તાઓ માટે ઍપને અપડેટ કરી શકે છે."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"વપરાશકર્તા સંખ્યાની મર્યાદા"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">તમે <xliff:g id="COUNT">%d</xliff:g> વપરાશકર્તા સુધી ઉમેરી શકો છો.</item>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"આ ડિવાઇસ તમારા માતાપિતા દ્વારા મેનેજ કરવામાં આવે છે"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"તમારી સંસ્થા આ ડિવાઇસની માલિકી ધરાવે છે અને નેટવર્ક ટ્રાફિકનું નિરીક્ષણ કરી શકે છે"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"આ ડિવાઇસ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>ની માલિકીનું છે અને નેટવર્ક ટ્રાફિકનું નિરીક્ષણ કરી શકે છે"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"આ ડિવાઇસ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> દ્વારા પ્રદાન કરવામાં આવેલું છે"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"આ ડિવાઇસ તમારી સંસ્થાની માલિકીનું છે અને <xliff:g id="VPN_APP">%1$s</xliff:g>થી કનેક્ટ કરેલું છે"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"આ ડિવાઇસ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>ની માલિકીનું છે અને <xliff:g id="VPN_APP">%2$s</xliff:g>થી કનેક્ટ કરેલું છે"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"આ ડિવાઇસ તમારી સંસ્થાની માલિકીનું છે"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"તમારી ઑફિસની પ્રોફાઇલ <xliff:g id="VPN_APP">%1$s</xliff:g>થી કનેક્ટ કરેલી છે"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"તમારી વ્યક્તિગત પ્રોફાઇલ <xliff:g id="VPN_APP">%1$s</xliff:g>થી કનેક્ટ કરેલી છે"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"આ ડિવાઇસ <xliff:g id="VPN_APP">%1$s</xliff:g>થી કનેક્ટ કરેલું છે"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"આ ડિવાઇસ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> દ્વારા પ્રદાન કરવામાં આવેલું છે"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"ઉપકરણનું સંચાલન"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"પ્રોફાઇલ નિરીક્ષણ"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"નેટવર્ક મૉનિટરિંગ"</string>
@@ -540,9 +537,10 @@
     <string name="monitoring_subtitle_ca_certificate" msgid="8588092029755175800">"CA પ્રમાણપત્રો"</string>
     <string name="disable_vpn" msgid="482685974985502922">"VPN અક્ષમ કરો"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"VPN ડિસ્કનેક્ટ કરો"</string>
-    <string name="monitoring_button_view_policies" msgid="3869724835853502410">"નીતિઓ જુઓ"</string>
+    <string name="monitoring_button_view_policies" msgid="3869724835853502410">"પૉલિસીઓ જુઓ"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"નિયંત્રણો જુઓ"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"આ ડિવાઇસ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>ની માલિકીનું છે.\n\nતમારા IT વ્યવસ્થાપક સેટિંગ, કૉર્પોરેટ ઍક્સેસ, ઍપ, તમારા ડિવાઇસ સાથે સંકળાયેલો ડેટા અને તમારા ડિવાઇસની સ્થાન માહિતીનું નિરીક્ષણ તેમજ તેને મેનેજ કરી શકે છે.\n\nવધુ માહિતી માટે, તમારા IT વ્યવસ્થાપકનો સંપર્ક કરો."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> આ ડિવાઇસ સાથે સંકળાયેલો ડેટા ઍક્સેસ કરી શકશે અને ઍપ મેનેજ કરી શકશે તેમજ આ ડિવાઇસના સેટિંગ બદલી શકશે.\n\nજો તમને કોઈ પ્રશ્ન હોય, તો <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>નો સંપર્ક કરો."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"આ ડિવાઇસ તમારી સંસ્થાની માલિકીનું છે.\n\nતમારા IT વ્યવસ્થાપક સેટિંગ, કૉર્પોરેટ ઍક્સેસ, ઍપ, તમારા ડિવાઇસ સાથે સંકળાયેલો ડેટા અને તમારા ડિવાઇસની સ્થાન માહિતીનું નિરીક્ષણ તેમજ તેને મેનેજ કરી શકે છે.\n\nવધુ માહિતી માટે, તમારા IT વ્યવસ્થાપકનો સંપર્ક કરો."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"તમારી સંસ્થાએ આ ઉપકરણ પર પ્રમાણપત્ર સત્તાધિકારી ઇન્સ્ટૉલ કર્યું છે. તમારા સુરક્ષિત નેટવર્ક ટ્રાફિકનું નિયમન થઈ શકે છે અથવા તેમાં ફેરફાર કરવામાં આવી શકે છે."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"તમારી સંસ્થાએ તમારી કાર્ય પ્રોફાઇલમાં પ્રમાણપત્ર સત્તાધિકારી ઇન્સ્ટૉલ કર્યું છે. તમારા સુરક્ષિત નેટવર્ક ટ્રાફિકનું નિયમન થઈ શકે છે અથવા તેમાં ફેરફાર કરવામાં આવી શકે છે."</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"ડેમો મોડ બતાવો"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"ઇથરનેટ"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"એલાર્મ"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"વૉલેટ"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"તૈયાર છે"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"ઑફિસની પ્રોફાઇલ"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"એરપ્લેન મોડ"</string>
     <string name="add_tile" msgid="6239678623873086686">"ટાઇલ ઉમેરો"</string>
@@ -749,7 +749,7 @@
     <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"<xliff:g id="APP_NAME">%1$s</xliff:g> માટે સૂચના નિયંત્રણો ચાલુ છે"</string>
     <string name="notification_channel_controls_closed_accessibility" msgid="1561909368876911701">"<xliff:g id="APP_NAME">%1$s</xliff:g> માટે સૂચના નિયંત્રણો બંધ છે"</string>
     <string name="notification_channel_switch_accessibility" msgid="8979885820432540252">"આ ચૅનલની સૂચનાઓને મંજૂરી આપો"</string>
-    <string name="notification_more_settings" msgid="4936228656989201793">"વધુ સેટિંગ્સ"</string>
+    <string name="notification_more_settings" msgid="4936228656989201793">"વધુ સેટિંગ"</string>
     <string name="notification_app_settings" msgid="8963648463858039377">"કસ્ટમાઇઝ કરો"</string>
     <string name="notification_done" msgid="6215117625922713976">"થઈ ગયું"</string>
     <string name="inline_undo" msgid="9026953267645116526">"રદ કરો"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"ઝડપી સેટિંગ્સ બંધ કરો."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"એલાર્મ સેટ કર્યો."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"<xliff:g id="ID_1">%s</xliff:g> તરીકે સાઇન ઇન કર્યું"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"વપરાશકર્તા પસંદ કરો"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"કોઈ ઇન્ટરનેટ નથી"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"વિગતો ખોલો."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"<xliff:g id="REASON">%s</xliff:g>ને કારણે અનુપલબ્ધ છે"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> સેટિંગ્સ ખોલો."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"સેટિંગ્સનો ક્રમ સંપાદિત કરો."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"પાવર મેનૂ"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g> માંથી <xliff:g id="ID_1">%1$d</xliff:g> પૃષ્ઠ"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"લૉક સ્ક્રીન"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"ફોન વધુ પડતી ગરમીને લીધે બંધ થઇ ગયો છે"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"ડાબી બાજુ ખસેડો"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"જમણી બાજુ ખસેડો"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"મોટું કરવાની સુવિધાવાળી સ્વિચ"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"સંપૂર્ણ સ્ક્રીન મોટી કરો"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"પૂર્ણ સ્ક્રીનને મોટી કરો"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"સ્ક્રીનનો કોઈ ભાગ મોટો કરો"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"સ્વિચ"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"ઍક્સેસિબિલિટી સંકેતને ઍક્સેસિબિલિટી બટન વડે બદલવામાં આવ્યા છે\n\n"<annotation id="link">"સેટિંગ જુઓ"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"તેને હંગામી રૂપે ખસેડવા માટે બટનને કિનારી પર ખસેડો"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"ડિવાઇસનાં નિયંત્રણો"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"તમારા કનેક્ટ કરેલા ડિવાઇસ માટે નિયંત્રણો ઉમેરો"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"ડિવાઇસનાં નિયંત્રણો સેટઅપ કરો"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"નવા ડિવાઇસ સાથે જોડાણ કરો"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"વાતચીતના વિજેટ"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"તમારી હોમ સ્ક્રીનમાં વાતચીત ઉમેરવા માટે તેના પર ટૅપ કરો"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> પહેલાં"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"<xliff:g id="DURATION">%1$s</xliff:g>થી ઓછા સમય પહેલાં"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"<xliff:g id="DURATION">%1$s</xliff:g> કરતાં વધુ સમય પહેલાં"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"જન્મદિવસ"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"જલ્દી જ જન્મદિવસ છે"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"વર્ષગાંઠ"</string>
+    <string name="location_status" msgid="1294990572202541812">"સ્થાન શેર કરીએ છીએ"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"નવી સ્ટોરી"</string>
+    <string name="video_status" msgid="4548544654316843225">"જોઈ રહ્યાં છે"</string>
+    <string name="audio_status" msgid="4237055636967709208">"સાંભળી રહ્યાં છીએ"</string>
+    <string name="game_status" msgid="1340694320630973259">"રમી રહ્યાં છે"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"મિત્રો"</string>
+    <string name="empty_status" msgid="5938893404951307749">"આજે રાતે ચૅટ કરીએ!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"ચૂકી ગયેલો કૉલ"</string>
+    <string name="people_tile_description" msgid="8154966188085545556">"તાજેતરના મેસેજ, ચૂકી ગયેલા કૉલ અને સ્ટેટસ અપડેટ જુઓ"</string>
+    <string name="people_tile_title" msgid="6589377493334871272">"વાતચીત"</string>
     <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"તમારું બૅટરી મીટર વાંચવામાં સમસ્યા આવી"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"વધુ માહિતી માટે ટૅપ કરો"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"કોઈ અલાર્મ સેટ નથી"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 764acad..3126959 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"रद्द करें"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"शेयर करें"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"स्क्रीन रिकॉर्डिंग रद्द कर दी गई"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"स्क्रीन रिकॉर्डिंग सेव की गई"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"देखने के लिए टैप करें"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"स्क्रीन रिकॉर्डिंग मिटाने में गड़बड़ी हुई"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"मंज़ूरी नहीं मिल सकी"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"स्क्रीन को रिकॉर्ड करने में गड़बड़ी आ रही है"</string>
@@ -225,9 +223,7 @@
     <string name="accessibility_battery_details" msgid="6184390274150865789">"बैटरी का विवरण खोलें"</string>
     <string name="accessibility_battery_level" msgid="5143715405241138822">"<xliff:g id="NUMBER">%d</xliff:g> प्रति‍शत बैटरी."</string>
     <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> प्रतिशत बैटरी बची है और आपके इस्तेमाल के हिसाब से यह <xliff:g id="TIME">%2$s</xliff:g> में खत्म हो जाएगी"</string>
-    <!-- String.format failed for translation -->
-    <!-- no translation found for accessibility_battery_level_charging (8892191177774027364) -->
-    <skip />
+    <string name="accessibility_battery_level_charging" msgid="8892191177774027364">"बैटरी चार्ज हो रही है, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> प्रतिशत."</string>
     <string name="accessibility_settings_button" msgid="2197034218538913880">"सिस्टम सेटिंग."</string>
     <string name="accessibility_notifications_button" msgid="3960913924189228831">"सूचनाएं."</string>
     <string name="accessibility_overflow_action" msgid="8555835828182509104">"पूरी सूचनाएं देखें"</string>
@@ -363,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"नया उपयोगकर्ता"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"वाई-फ़ाई"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"इंटरनेट"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"हवाई जहाज़ मोड पर, काम करने वाले सुरक्षित नेटवर्क"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"नेटवर्क उपलब्ध हैं"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"नेटवर्क उपलब्ध नहीं हैं"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"कनेक्ट नहीं है"</string>
@@ -417,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"सुबह तक चालू रहेगी"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g> पर चालू हाेगी"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> तक चालू रहेगी"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"स्क्रीन की चमक कम करें"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"एनएफ़सी"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC बंद है"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC चालू है"</string>
@@ -472,11 +466,10 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"प्रोफ़ाइल दिखाएं"</string>
     <string name="user_add_user" msgid="4336657383006913022">"उपयोगकर्ता जोड़ें"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"नया उपयोगकर्ता"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"मेहमान के तौर पर ब्राउज़ करने का सेशन खत्म करें"</string>
-    <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"अतिथि को निकालें?"</string>
-    <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"इस सत्र के सभी ऐप्स और डेटा को हटा दिया जाएगा."</string>
+    <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"क्या आप मेहमान को हटाना चाहते हैं?"</string>
+    <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"इस सत्र के सभी ऐप्लिकेशन और डेटा को हटा दिया जाएगा."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"निकालें"</string>
-    <string name="guest_wipe_session_title" msgid="7147965814683990944">"अतिथि, आपका फिर से स्वागत है!"</string>
+    <string name="guest_wipe_session_title" msgid="7147965814683990944">"मेहमान, आपका फिर से स्वागत है!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"क्‍या आप अपना सत्र जारी रखना चाहते हैं?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"फिर से शुरू करें"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"हां, जारी रखें"</string>
@@ -495,7 +488,7 @@
     </plurals>
     <string name="user_remove_user_title" msgid="9124124694835811874">"उपयोगकर्ता निकालें?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"इस उपयोगकर्ता के सभी ऐप और डेटा को हटा दिया जाएगा."</string>
-    <string name="user_remove_user_remove" msgid="8387386066949061256">"निकालें"</string>
+    <string name="user_remove_user_remove" msgid="8387386066949061256">"हटाएं"</string>
     <string name="battery_saver_notification_title" msgid="8419266546034372562">"बैटरी सेवर चालू है"</string>
     <string name="battery_saver_notification_text" msgid="2617841636449016951">"निष्‍पादन और पृष्ठभूमि डेटा को कम करता है"</string>
     <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"बैटरी सेवर बंद करें"</string>
@@ -521,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"इस डिवाइस का प्रबंधन आपके अभिभावक करते हैं"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"इस डिवाइस का मालिकाना हक आपके संगठन के पास है. आपका संगठन, नेटवर्क के ट्रैफ़िक की निगरानी कर सकता है"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"इस डिवाइस का मालिकाना हक <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> के पास है. आपका संगठन, नेटवर्क के ट्रैफ़िक की निगरानी कर सकता है"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"यह डिवाइस <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ने दिया है"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"इस डिवाइस का मालिकाना हक आपके संगठन के पास है. इस डिवाइस को <xliff:g id="VPN_APP">%1$s</xliff:g> से कनेक्ट किया गया है"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"इस डिवाइस का मालिकाना हक <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> के पास है. इस डिवाइस को <xliff:g id="VPN_APP">%2$s</xliff:g> से कनेक्ट किया गया है"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"इस डिवाइस का मालिकाना हक आपके संगठन के पास है"</string>
@@ -534,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"आपकी वर्क प्रोफ़ाइल <xliff:g id="VPN_APP">%1$s</xliff:g> से कनेक्ट की गई है"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"आपकी निजी प्रोफ़ाइल <xliff:g id="VPN_APP">%1$s</xliff:g> से कनेक्ट की गई है"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"इस डिवाइस को <xliff:g id="VPN_APP">%1$s</xliff:g> से कनेक्ट किया गया है"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"यह डिवाइस <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ने दिया है"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"डिवाइस प्रबंधन"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"प्रोफ़ाइल को मॉनीटर करना"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"नेटवर्क को मॉनीटर करना"</string>
@@ -545,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"नीतियां देखें"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"कंट्रोल देखें"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"इस डिवाइस का मालिकाना हक <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> के पास है.\n\nआपके संगठन का आईटी एडमिन कुछ चीज़ों की निगरानी और उन्हें प्रबंधित कर सकता है, जैसे कि सेटिंग, कॉर्पोरेट ऐक्सेस, ऐप्लिकेशन, आपके डिवाइस से जुड़ा डेटा, और आपके डिवाइस की जगह की जानकारी.\n\nज़्यादा जानकारी के लिए, अपने आईटी एडमिन से संपर्क करें."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> इस डिवाइस के डेटा को ऐक्सेस कर सकता है, ऐप्लिकेशन मैनेज कर सकता है, और इसकी सेटिंग में बदलाव कर सकता है.\n\nअगर आपके पास कोई सवाल है, तो <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g> से संपर्क करें."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"इस डिवाइस का मालिकाना हक आपके संगठन के पास है.\n\nआपके संगठन का आईटी एडमिन कुछ चीज़ों की निगरानी और उन्हें प्रबंधित कर सकता है, जैसे कि सेटिंग, कॉर्पोरेट ऐक्सेस, ऐप्लिकेशन, आपके डिवाइस से जुड़ा डेटा, और आपके डिवाइस की जगह की जानकारी.\n\nज़्यादा जानकारी के लिए, अपने आईटी एडमिन से संपर्क करें."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"आपके संगठन ने इस डिवाइस पर एक प्रमाणपत्र अनुमति इंस्टॉल की है. आपके सुरक्षित नेटवर्क पर ट्रेफ़िक की निगरानी या उसमें बदलाव किया जा सकता है."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"आपके संगठन ने आपकी वर्क प्रोफ़ाइल में एक प्रमाणपत्र अनुमति इंस्टॉल की है. आपके सुरक्षित नेटवर्क ट्रैफ़िक की निगरानी या उसमें बदलाव किया जा सकता है."</string>
@@ -655,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"डेमो मोड दिखाएं"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"ईथरनेट"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"अलार्म"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"वॉलेट"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"तैयार"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"वर्क प्रोफ़ाइल"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"हवाई जहाज़ मोड"</string>
     <string name="add_tile" msgid="6239678623873086686">"टाइल जोड़ें"</string>
@@ -723,7 +721,7 @@
     <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"&lt;b&gt;स्थिति:&lt;/b&gt; लेवल घटाकर, साइलेंट पर सेट किया गया"</string>
     <string name="notification_channel_summary_automatic_promoted" msgid="1301710305149590426">"&lt;b&gt;स्थिति:&lt;/b&gt; रैंकिंग में ऊपर किया गया"</string>
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;स्थिति:&lt;/b&gt; रैंकिंग में नीचे किया गया"</string>
-    <string name="notification_channel_summary_priority" msgid="7952654515769021553">"इससे बातचीत, सेक्शन में सबसे ऊपर और फ़्लोटिंग बबल के तौर पर दिखती है. साथ ही, लॉक स्क्रीन पर प्रोफ़ाइल फ़ोटो दिखती है"</string>
+    <string name="notification_channel_summary_priority" msgid="7952654515769021553">"इससे चैट, बातचीत सेक्शन में सबसे ऊपर फ़्लोटिंग बबल के तौर पर दिखती है. साथ ही, लॉक स्क्रीन पर प्रोफ़ाइल फ़ोटो दिखती है"</string>
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"सेटिंग"</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>
@@ -901,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"त्वरित सेटिंग बंद करें."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"अलार्म सेट."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"<xliff:g id="ID_1">%s</xliff:g> के रूप में प्रवेश किया हुआ है"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"उपयोगकर्ता चुनें"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"इंटरनेट कनेक्शन नहीं है"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"विवरण खोलें."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"<xliff:g id="REASON">%s</xliff:g> की वजह से मौजूद नहीं है"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> सेटिंग खोलें."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"सेटिंग के क्रम को बदलें"</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"पावर मेन्यू"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"पेज <xliff:g id="ID_2">%2$d</xliff:g> में से <xliff:g id="ID_1">%1$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"लॉक स्‍क्रीन"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"गर्म होने की वजह से फ़ोन बंद हुआ"</string>
@@ -1013,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"बाईं ओर ले जाएं"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"दाईं ओर ले जाएं"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"ज़ूम करने की सुविधा वाला स्विच"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"पूरी स्क्रीन को ज़ूम करें"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"फ़ुल स्क्रीन को ज़ूम करें"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"स्क्रीन के किसी हिस्से को ज़ूम करें"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"स्विच"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"सुलभता वाले हाथ के जेस्चर (हाव-भाव) को सुलभता बटन से बदल दिया गया है\n\n"<annotation id="link">"सेटिंग देखें"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"बटन को कुछ समय छिपाने के लिए, उसे किनारे पर ले जाएं"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"डिवाइस कंट्रोल"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"कनेक्ट किए गए डिवाइस के लिए कंट्रोल जोड़ें"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"डिवाइस कंट्रोल सेट अप करें"</string>
@@ -1083,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"नया डिवाइस जोड़ें"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"बातचीत विजेट"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"किसी बातचीत को होम स्क्रीन पर जोड़ने के लिए, उस बातचीत पर टैप करें"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> पहले"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"<xliff:g id="DURATION">%1$s</xliff:g> से थोड़ा पहले"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"करीब <xliff:g id="DURATION">%1$s</xliff:g> से ज़्यादा"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"जन्मदिन"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"जन्मदिन आने वाला है"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"सालगिरह"</string>
+    <string name="location_status" msgid="1294990572202541812">"जगह की जानकारी शेयर की जा रही है"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"नई स्टोरी"</string>
+    <string name="video_status" msgid="4548544654316843225">"देख रहे हैं"</string>
+    <string name="audio_status" msgid="4237055636967709208">"सुना जा रहा है"</string>
+    <string name="game_status" msgid="1340694320630973259">"खेला जा रहा है"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"दोस्त"</string>
+    <string name="empty_status" msgid="5938893404951307749">"आज रात चैट करते हैं!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"मिस्ड कॉल"</string>
+    <string name="people_tile_description" msgid="8154966188085545556">"हाल के मैसेज, मिस्ड कॉल, और स्टेटस अपडेट देखें"</string>
+    <string name="people_tile_title" msgid="6589377493334871272">"बातचीत"</string>
     <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"आपके डिवाइस के बैटरी मीटर की रीडिंग लेने में समस्या आ रही है"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"ज़्यादा जानकारी के लिए टैप करें"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"कोई अलार्म सेट नहीं है"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 55970a0..0d4c079 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Odustani"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Dijeli"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Snimanje zaslona otkazano"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Snimanje zaslona spremljeno"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Dodirnite za prikaz"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Pogreška prilikom brisanja snimanja zaslona"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Dohvaćanje dopuštenja nije uspjelo"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Pogreška prilikom pokretanja snimanja zaslona"</string>
@@ -362,7 +360,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Novi korisnik"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Internet"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Sigurno za rad u zrakoplovu"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Mreže su dostupne"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Mreže nisu dostupne"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Nije povezano"</string>
@@ -417,7 +414,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Do izlaska sunca"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Uključuje se u <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Do <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Smanjenje svjetline"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC je onemogućen"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC je omogućen"</string>
@@ -472,7 +468,6 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Prikaz profila"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Dodavanje korisnika"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Novi korisnik"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Završi gostujuću sesiju"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Ukloniti gosta?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Sve aplikacije i podaci u ovoj sesiji bit će izbrisani."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Ukloni"</string>
@@ -522,6 +517,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Ovim uređajem upravlja tvoj roditelj"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Vaša je organizacija vlasnik ovog uređaja i može nadzirati mrežni promet"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Organizacija <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> vlasnik je ovog uređaja i može nadzirati mrežni promet"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Ovaj uređaj pruža organizacija <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Ovaj uređaj pripada vašoj organizaciji i povezan je s mrežom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> i povezan je s mrežom <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Ovaj uređaj pripada vašoj organizaciji"</string>
@@ -535,6 +531,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Vaš poslovni profil povezan je s mrežom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Vaš osobni profil povezan je s mrežom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Ovaj uređaj povezan je s mrežom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Ovaj uređaj pruža organizacija <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Upravljanje uređajem"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Nadzor profila"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Nadzor mreže"</string>
@@ -546,6 +543,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Prikaži pravila"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Prikaz kontrola"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nVaš IT administrator može nadzirati postavke, korporacijski pristup, aplikacije, podatke o uređaju i lokaciji uređaja te upravljati njima.\n\nZa više informacija obratite se IT administratoru."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> možda može pristupiti podacima povezanim s ovim uređajem, upravljati aplikacijama i promijeniti postavke uređaja.\n\nAko imate pitanja, obratite se organizaciji <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Ovaj uređaj pripada vašoj organizaciji.\n\nVaš IT administrator može nadzirati postavke, korporacijski pristup, aplikacije, podatke o uređaju i lokaciji uređaja te upravljati njima.\n\nZa više informacija obratite se IT administratoru."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Vaša je organizacija instalirala izdavač certifikata na ovom uređaju. Vaš sigurni mrežni promet možda se nadzire ili modificira."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Vaša je organizacija instalirala izdavač certifikata na vašem radnom profilu. Vaš sigurni mrežni promet možda se nadzire ili modificira."</string>
@@ -656,6 +654,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Prikaži demo način"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Alarm"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Novčanik"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Spremno"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Poslovni profil"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Način rada u zrakoplovu"</string>
     <string name="add_tile" msgid="6239678623873086686">"Dodavanje pločice"</string>
@@ -904,11 +904,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Zatvaranje brzih postavki."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Alarm je postavljen."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Prijavljeni ste kao <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"odaberi korisnika"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Nema interneta"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Otvaranje pojedinosti."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"Nije dostupno jer <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Otvaranje postavki za <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Uređivanje redoslijeda postavki."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Izbornik tipke za uključivanje (/isključivanje)"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Stranica <xliff:g id="ID_1">%1$d</xliff:g> od <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Zaključan zaslon"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"Telefon se isključio zbog vrućine"</string>
@@ -953,10 +955,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 ometaj isključen"</string>
-    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Način Ne ometaj 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 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 Ne ometaj uključilo je automatsko pravilo ili aplikacija."</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="qs_dnd_until" msgid="7844269319043747955">"Do <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="qs_dnd_keep" msgid="3829697305432866434">"Zadrži"</string>
     <string name="qs_dnd_replace" msgid="7712119051407052689">"Zamijeni"</string>
@@ -1016,9 +1018,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Premjesti ulijevo"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Premjesti udesno"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Prebacivanje povećavanja"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Povećaj cijeli zaslon"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Povećajte cijeli zaslon"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Povećaj dio zaslona"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Prebacivanje"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"Gumb za Pristupačnost zamijenio je pokret pristupačnosti\n\n"<annotation id="link">"Prikaz postavki"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Pomaknite gumb do ruba da biste ga privremeno sakrili"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Kontrole uređaja"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Dodavanje kontrola za povezane uređaje"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Postavljanje kontrola uređaja"</string>
@@ -1087,6 +1091,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Upari novi uređaj"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Widgeti razgovora"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Dodirnite razgovor da biste ga dodali na početni zaslon"</string>
+    <string name="timestamp" msgid="6577851592534538533">"Prije <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"Prije manje od <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"Prije više od <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Rođendan"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Rođendan uskoro"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Godišnjica"</string>
+    <string name="location_status" msgid="1294990572202541812">"Dijeljenje lokacije"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Novi članak"</string>
+    <string name="video_status" msgid="4548544654316843225">"Gledanje"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Slušanje"</string>
+    <string name="game_status" msgid="1340694320630973259">"Igranje"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Prijatelji"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Može chat večeras?"</string>
+    <string name="missed_call" msgid="4228016077700161689">"Propušteni poziv"</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="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problem s očitavanjem mjerača baterije"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Dodirnite za više informacija"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nema nijednog alarma"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index ee3f45d..51651ac 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Mégse"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Megosztás"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"A képernyő rögzítése megszakítva"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Képernyőfelvétel elmentve"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Koppints a megtekintéshez"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Hiba történt a képernyőről készült felvétel törlésekor"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Nincs engedély"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Hiba a képernyőrögzítés indításakor"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Új felhasználó"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Internet"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Repülőgépen használható"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Használhatók hálózatok"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Nem használhatók hálózatok"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Nincs kapcsolat"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Napfelkeltéig"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Be: <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Eddig: <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Fényerő csökkentése"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"Az NFC ki van kapcsolva"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"Az NFC be van kapcsolva"</string>
@@ -470,7 +466,6 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Profil megjelenítése"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Felhasználó hozzáadása"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Új felhasználó"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"A vendég munkamenet befejezése"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Eltávolítja a vendég munkamenetet?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"A munkamenetben található összes alkalmazás és adat törlődni fog."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Eltávolítás"</string>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Az eszközt a szülőd felügyeli"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Az eszköz az Ön szervezetének tulajdonában van, és lehetséges, hogy a hálózati forgalmat is figyelik"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Az eszköz a(z) <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> tulajdonában van, és lehetséges, hogy a hálózati forgalmat is figyelik"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Ezt az eszközt a(z) <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> szervezet biztosítja"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Ez az eszköz az Ön szervezetének tulajdonában van, és össze van kapcsolva a(z) <xliff:g id="VPN_APP">%1$s</xliff:g> alkalmazással"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Ez az eszköz a(z) <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> tulajdonában van, és össze van kapcsolva a(z) <xliff:g id="VPN_APP">%2$s</xliff:g> alkalmazással"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Ez az eszköz az Ön szervezetének tulajdonában van"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Munkaprofilja össze van kapcsolva a(z) <xliff:g id="VPN_APP">%1$s</xliff:g> alkalmazással"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Személyes profilja össze van kapcsolva a(z) <xliff:g id="VPN_APP">%1$s</xliff:g> alkalmazással"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Ez az eszköz össze van kapcsolva a(z) <xliff:g id="VPN_APP">%1$s</xliff:g> alkalmazással"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Ezt az eszközt a(z) <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> szervezet biztosítja"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Eszközkezelés"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Profilfelügyelet"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Hálózatfigyelés"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Házirendek megtekintése"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Vezérlők megtekintése"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Ez az eszköz a(z) <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> tulajdonában van.\n\nA rendszergazda figyelheti és kezelheti az eszköz beállításait, vállalati hozzáférését, alkalmazásait, adatait és helyadatait.\n\nHa további információra van szüksége, vegye fel a kapcsolatot a rendszergazdával."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"A(z) <xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> hozzáférhet az ehhez az eszközhöz tartozó adatokhoz, és módosíthatja az eszköz beállításait.\n\nHa kérdései vannak, forduljon a következőhöz: <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Ez az eszköz az Ön szervezetének tulajdonában van.\n\nA rendszergazda figyelheti és kezelheti az eszköz beállításait, vállalati hozzáférését, alkalmazásait, adatait és helyadatait.\n\nHa további információra van szüksége, vegye fel a kapcsolatot a rendszergazdával."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Szervezete tanúsítványkibocsátót telepített az eszközre. Ezáltal figyelhetik és befolyásolhatják az Ön biztonságos hálózati forgalmát."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Szervezete tanúsítványkibocsátót telepített a munkaprofilba. Ezáltal figyelhetik és befolyásolhatják az Ön biztonságos hálózati forgalmát."</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Demó mód megjelenítése"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Ébresztés"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Kész"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Munkahelyi profil"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Repülős üzemmód"</string>
     <string name="add_tile" msgid="6239678623873086686">"Mozaik hozzáadása"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Gyorsbeállítások bezárása"</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Ébresztő beállítva"</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Bejelentkezve mint <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"felhasználó kiválasztása"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Nincs internetkapcsolat"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"A részletek megnyitása."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"Nem áll rendelkezésre a következő ok miatt: <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"A(z) <xliff:g id="ID_1">%s</xliff:g> beállításainak megnyitása."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Beállítások sorrendjének szerkesztése."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Bekapcsológombhoz tartozó menü"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_1">%1$d</xliff:g>. oldal, összesen: <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Lezárási képernyő"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"A meleg miatt kikapcsolt"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Mozgatás balra"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Mozgatás jobbra"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Nagyításváltó"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Teljes képernyő nagyítása"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"A teljes képernyő felnagyítása"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Képernyő bizonyos részének nagyítása"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Váltás"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"A kisegítő kézmozdulat helyébe a Kisegítő lehetőségek gomb lépett\n\n"<annotation id="link">"Beállítások megtekintése"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"A gombot a szélre áthelyezve ideiglenesen elrejtheti"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Eszközvezérlők"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Vezérlők hozzáadása a csatlakoztatott eszközökhöz"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Eszközvezérlők beállítása"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Új eszköz párosítása"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Beszélgetési modulok"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Koppintson a kívánt beszélgetésre a kezdőképernyőre való felvételhez"</string>
+    <string name="timestamp" msgid="6577851592534538533">"Ennyi ideje: <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"Kevesebb, mint ennyi ideje: <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"Több, mint ennyi ideje: <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Születésnap"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Közelgő születésnap"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Évforduló"</string>
+    <string name="location_status" msgid="1294990572202541812">"Hely megosztása"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Új történet"</string>
+    <string name="video_status" msgid="4548544654316843225">"Lejátszás"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Figyelés"</string>
+    <string name="game_status" msgid="1340694320630973259">"Játékban"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Ismerősök"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Beszélgessünk egyet!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"Nem fogadott hívás"</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="battery_state_unknown_notification_title" msgid="8464703640483773454">"Probléma merült fel az akkumulátor-töltésmérő olvasásakor"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Koppintással további információkat érhet el."</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nincs ébresztés"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 84451eb..1d64b95 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Չեղարկել"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Կիսվել"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Էկրանի տեսագրումը չեղարկվեց"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Էկրանի տեսագրությունը պահվեց"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Հպեք՝ դիտելու համար"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Չհաջողվեց ջնջել տեսագրությունը"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Չհաջողվեց ստանալ անհրաժեշտ թույլտվությունները"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Չհաջողվեց սկսել տեսագրումը"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Նոր օգտատեր"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Ինտերնետ"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Ինքնաթիռում անվտանգ"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Հասանելի ցանցեր"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Անհասանելի ցանցեր"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Միացված չէ"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Մինչև լուսաբաց"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Կմիանա՝ <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Մինչև <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Պայծառության նվազեցում"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC-ն անջատված է"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC-ն միացված է"</string>
@@ -470,13 +466,12 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Ցույց տալ դիտարկումը"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Ավելացնել օգտատեր"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Նոր օգտատեր"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Ավարտել հյուրի աշխատաշրջանը"</string>
-    <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Հեռացնե՞լ հյուրին:"</string>
+    <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Հեռացնե՞լ հյուրին"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Այս աշխատաշրջանի բոլոր ծրագրերն ու տվյալները կջնջվեն:"</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Հեռացնել"</string>
-    <string name="guest_wipe_session_title" msgid="7147965814683990944">"Բարի վերադարձ, հյուր:"</string>
-    <string name="guest_wipe_session_message" msgid="3393823610257065457">"Դուք ցանկանու՞մ եք շարունակել ձեր գործողությունը:"</string>
-    <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Սկսել"</string>
+    <string name="guest_wipe_session_title" msgid="7147965814683990944">"Բարի վերադարձ, հյուր"</string>
+    <string name="guest_wipe_session_message" msgid="3393823610257065457">"Շարունակե՞լ աշխատաշրջանը։"</string>
+    <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Վերսկսել"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Այո, շարունակել"</string>
     <string name="guest_notification_title" msgid="4434456703930764167">"Հյուր"</string>
     <string name="guest_notification_text" msgid="4202692942089571351">"Հավելվածները և տվյալները ջնջելու համար հեռացրեք հյուրին"</string>
@@ -484,7 +479,7 @@
     <string name="user_logout_notification_title" msgid="3644848998053832589">"Ընթացիկ օգտատիրոջ դուրս գրում"</string>
     <string name="user_logout_notification_text" msgid="7441286737342997991">"Ընթացիկ օգտատիրոջ դուրս գրում"</string>
     <string name="user_logout_notification_action" msgid="7974458760719361881">"ԸՆԹԱՑԻԿ ՕԳՏՎՈՂԻ ԴՈՒՐՍ ԳՐՈՒՄ"</string>
-    <string name="user_add_user_title" msgid="4172327541504825032">"Ավելացնե՞լ նոր պրոֆիլ:"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Ավելացնե՞լ նոր օգտատեր"</string>
     <string name="user_add_user_message_short" msgid="2599370307878014791">"Երբ նոր օգտատեր եք ավելացնում, նա պետք է կարգավորի իր պրոֆիլը:\n\nՑանկացած օգտատեր կարող է թարմացնել հավելվածները մյուս բոլոր հաշիվների համար:"</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Սահմանաչափը սպառված է"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Այս սարքը կառավարում է ձեր ծնողը"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Ձեր կազմակերպությունը այս սարքի սեփականատերն է և կարող է վերահսկել ցանցային թրաֆիկը"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"«<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>» կազմակերպությունը այս սարքի սեփականատերն է և կարող է վերահսկել ցանցային թրաֆիկը"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Այս սարքը տրամադրվել է <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> կազմակերպության կողմից"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Այս սարքը պատկանում է ձեր կազմակերպությանը և միացված է <xliff:g id="VPN_APP">%1$s</xliff:g> ցանցին"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Այս սարքը պատկանում է «<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>» կազմակերպությանը և միացված է <xliff:g id="VPN_APP">%2$s</xliff:g> ցանցին"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Այս սարքը պատկանում է ձեր կազմակերպությանը"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Ձեր աշխատանքային պրոֆիլը միացված է <xliff:g id="VPN_APP">%1$s</xliff:g> ցանցին"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Ձեր անձնական պրոֆիլը միացված է <xliff:g id="VPN_APP">%1$s</xliff:g> ցանցին"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Այս սարքը միացված է <xliff:g id="VPN_APP">%1$s</xliff:g> ցանցին"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Այս սարքը տրամադրվել է <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> կազմակերպության կողմից"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Սարքերի կառավարում"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Պրոֆիլի վերահսկում"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Ցանցի մշտադիտարկում"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Դիտել քաղաքականությունները"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Դիտել կառավարման տարրերը"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Այս սարքը պատկանում է «<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>» կազմակերպությանը։\n\nՁեր ՏՏ ադմինիստրատորը կարող է վերահսկել և կառավարել կարգավորումները, կորպորատիվ ռեսուրսներից օգտվելու թույլտվությունները, հավելվածները, սարքի հետ կապված տվյալները և սարքի տեղադրության տվյալները։\n\nԼրացուցիչ տեղեկությունների համար դիմեք ձեր ՏՏ ադմինիստրատորին։"</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> կազմակերպությունը կարող է ստանալ այս սարքի հետ կապված տվյալների օգտագործման թույլտվություն, փոփոխել դրա կարգավորումներն ու կառավարել հավելվածները։\n\nԱվելին իմանալու համար դիմեք <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g> ընկերությանը։"</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Այս սարքը պատկանում է ձեր կազմակերպությանը։\n\nՁեր ՏՏ ադմինիստրատորը կարող է վերահսկել և կառավարել կարգավորումները, կորպորատիվ ռեսուրսներից օգտվելու թույլտվությունները, հավելվածները, սարքի հետ կապված տվյալները և սարքի տեղադրության տվյալները։\n\nԼրացուցիչ տեղեկությունների համար դիմեք ձեր ՏՏ ադմինիստրատորին։"</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Ձեր կազմակերպությունը այս սարքում տեղադրել է վկայագրման կենտրոն։ Ձեր ցանցի ապահով թրաֆիկը կարող է վերահսկվել կամ փոփոխվել։"</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Ձեր կազմակերպությունը ձեր աշխատանքային պրոֆիլում տեղադրել է վկայագրման կենտրոն։ Ձեր ցանցի ապահով թրաֆիկը կարող է վերահսկվել կամ փոփոխվել։"</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Ցուցադրական ռեժիմի ցուցադրում"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Զարթուցիչ"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Դրամապանակ"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Պատրաստ է"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Android for Work-ի պրոֆիլ"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Ավիառեժիմ"</string>
     <string name="add_tile" msgid="6239678623873086686">"Սալիկի ավելացում"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Փակել արագ կարգավորումները:"</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Զարթուցիչը դրված է:"</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Մուտք է գործել որպես <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"ընտրել օգտատեր"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Ինտերնետ կապ չկա"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Բացել մանրամասները:"</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"Անհասանելի է, քանի որ <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Բացել <xliff:g id="ID_1">%s</xliff:g> կարգավորումները:"</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Խմբագրել կարգավորումների հերթականությունը:"</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Սնուցման կոճակի ընտրացանկ"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Էջ <xliff:g id="ID_1">%1$d</xliff:g> / <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Կողպէկրան"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"Հեռախոսն անջատվել էր տաքանալու պատճառով"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Տեղափոխել ձախ"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Տեղափոխել աջ"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Խոշորացման փոփոխություն"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Խոշորացնել ամբողջ էկրանը"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Խոշորացնել ամբողջ էկրանը"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Խոշորացնել էկրանի որոշակի հատվածը"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Փոխել"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"Հատուկ գործառույթների ժեստը փոխարինվել է կոճակով\n\n"<annotation id="link">"Բացել կարգավորումները"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Կոճակը ժամանակավորապես թաքցնելու համար այն տեղափոխեք էկրանի եզր"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Սարքերի կառավարման տարրեր"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Ավելացրեք կառավարման տարրեր ձեր միացված սարքերի համար"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Սարքերի կառավարման տարրերի կարգավորում"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Նոր սարքի զուգակցում"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Զրույցի վիջեթներ"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Հպեք զրույցին՝ այն հիմնական էկրանին ավելացնելու համար"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> առաջ"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"Առավելագույնը <xliff:g id="DURATION">%1$s</xliff:g> առաջ"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"Ավելի քան <xliff:g id="DURATION">%1$s</xliff:g> առաջ"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Ծննդյան օր"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Շուտով ծննդյանս օրն է"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Տարեդարձ"</string>
+    <string name="location_status" msgid="1294990572202541812">"Տեղադրության ցուցադրում"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Նոր հոդված"</string>
+    <string name="video_status" msgid="4548544654316843225">"Տեսանյութ եմ դիտում"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Բան եմ լսում"</string>
+    <string name="game_status" msgid="1340694320630973259">"Խաղ եմ խաղում"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Ընկերներ"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Արի այսօր զրուցենք"</string>
+    <string name="missed_call" msgid="4228016077700161689">"Բաց թողնված զանգ"</string>
+    <string name="people_tile_description" msgid="8154966188085545556">"Տեսեք վերջին հաղորդագրությունները, բաց թողնված զանգերը և կարգավիճակի մասին թարմացումները"</string>
+    <string name="people_tile_title" msgid="6589377493334871272">"Զրույց"</string>
     <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Մարտկոցի ցուցիչի ցուցմունքը կարդալու հետ կապված խնդիր կա"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Հպեք՝ ավելին իմանալու համար"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Զարթուցիչ դրված չէ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index f694e1d..21851ce 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Batal"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Bagikan"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Rekaman layar dibatalkan"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Perekaman layar disimpan"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Ketuk untuk melihat"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Error saat menghapus rekaman layar"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Gagal mendapatkan izin"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Terjadi error saat memulai perekaman layar"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Pengguna baru"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Internet"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Aman di pesawat"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Jaringan tersedia"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Jaringan tidak tersedia"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Tidak Terhubung"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Sampai pagi"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Aktif pada <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Sampai <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Kurangi kecerahan"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC dinonaktifkan"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC diaktifkan"</string>
@@ -470,7 +466,6 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Tampilkan profil"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Tambahkan pengguna"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Pengguna baru"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Akhiri sesi tamu"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Hapus tamu?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Semua aplikasi dan data di sesi ini akan dihapus."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Hapus"</string>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Perangkat ini dikelola oleh orang tua"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Organisasi Anda memiliki perangkat ini dan mungkin memantau traffic jaringan"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> memiliki perangkat ini dan mungkin memantau traffic jaringan"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Perangkat ini disediakan oleh <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Perangkat ini milik organisasi Anda dan terhubung ke <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Perangkat ini milik <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> dan terhubung ke <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Perangkat ini milik organisasi Anda"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Profil kerja Anda terhubung ke <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Profil pribadi Anda terhubung ke <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Perangkat ini terhubung ke <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Perangkat ini disediakan oleh <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Pengelolaan perangkat"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Pemantauan profil"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Pemantauan jaringan"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Lihat Kebijakan"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Lihat kontrol"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Perangkat ini milik <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nAdmin IT Anda dapat memantau dan mengelola setelan, akses perusahaan, aplikasi, data yang terkait dengan perangkat, dan informasi lokasi perangkat.\n\nUntuk informasi selengkapnya, hubungi admin IT Anda."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> mungkin dapat mengakses data yang dikaitkan dengan perangkat ini, mengelola aplikasi, dan mengubah setelan perangkat ini.\n\nJika Anda memiliki pertanyaan, hubungi <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Perangkat ini milik organisasi Anda.\n\nAdmin IT Anda dapat memantau dan mengelola setelan, akses perusahaan, aplikasi, data yang terkait dengan perangkat, dan informasi lokasi perangkat.\n\nUntuk informasi selengkapnya, hubungi admin IT Anda."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Organisasi Anda menginstal otoritas sertifikat di perangkat ini. Traffic jaringan aman Anda mungkin dipantau atau diubah."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Organisasi Anda menginstal otoritas sertifikat di profil kerja. Traffic jaringan aman Anda mungkin dipantau atau diubah."</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Tampilkan mode demo"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Alarm"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Siap"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Profil kerja"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Mode pesawat"</string>
     <string name="add_tile" msgid="6239678623873086686">"Tambahkan ubin"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Tutup setelan cepat."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Alarm disetel."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Login sebagai <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"memilih pengguna"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Tidak ada internet"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Buka detail."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"Tidak tersedia karena <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Buka setelan <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Edit urutan setelan."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menu daya"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Halaman <xliff:g id="ID_1">%1$d</xliff:g> dari <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Layar kunci"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"Ponsel dimatikan karena panas"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Pindahkan ke kiri"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Pindahkan ke kanan"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Tombol pembesaran"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Perbesar seluruh layar"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Memperbesar tampilan layar penuh"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Perbesar sebagian layar"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Alihkan"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"Tombol aksesibilitas menggantikan gestur aksesibilitas\n\n"<annotation id="link">"Tampilkan setelan"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Pindahkan tombol ke tepi agar tersembunyi untuk sementara"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Kontrol perangkat"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Tambahkan kontrol untuk perangkat terhubung"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Siapkan kontrol perangkat"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Sambungkan perangkat baru"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Nomor versi"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Widget Percakapan"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Ketuk percakapan untuk menambahkannya ke Layar utama"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> yang lalu"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"Kurang dari <xliff:g id="DURATION">%1$s</xliff:g> yang lalu"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"Lebih dari <xliff:g id="DURATION">%1$s</xliff:g> yang lalu"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Ulang Tahun"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Ulang tahun segera"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Hari Peringatan"</string>
+    <string name="location_status" msgid="1294990572202541812">"Berbagi lokasi"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Story baru"</string>
+    <string name="video_status" msgid="4548544654316843225">"Menonton"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Mendengarkan"</string>
+    <string name="game_status" msgid="1340694320630973259">"Bermain"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Teman"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Ayo chat malam ini."</string>
+    <string name="missed_call" msgid="4228016077700161689">"Panggilan tak terjawab"</string>
+    <string name="people_tile_description" msgid="8154966188085545556">"Melihat pesan terbaru, panggilan tak terjawab, dan pembaruan status"</string>
+    <string name="people_tile_title" msgid="6589377493334871272">"Percakapan"</string>
     <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Terjadi masalah saat membaca indikator baterai"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Ketuk untuk informasi selengkapnya"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Alarm tidak disetel"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index 08210ef..21ef9cd 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Hætta við"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Deila"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Hætt við skjáupptöku"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Skjáupptaka vistuð"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Ýttu til að skoða"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Villa við að eyða skjáupptöku"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Ekki tókst að fá heimildir"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Villa við að hefja upptöku skjás"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Nýr notandi"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Internet"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Öruggt í flugi"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Net í boði"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Net er ekki tiltækt"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Engin tenging"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Til sólarupprásar"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Virkt kl. <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Til <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Minnka birtu"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"Slökkt á NFC"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"Kveikt á NFC"</string>
@@ -470,7 +466,6 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Sýna snið"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Bæta notanda við"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Nýr notandi"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Ljúka gestalotu"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Fjarlægja gest?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Öllum forritum og gögnum í þessari lotu verður eytt."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Fjarlægja"</string>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Foreldri þitt stjórnar þessu tæki"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Fyrirtækið þitt á þetta tæki og fylgist hugsanlega með netumferð"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> á þetta tæki og fylgist hugsanlega með netumferð"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Þetta tæki er frá <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Þetta tæki tilheyrir fyrirtækinu þínu og er tengt við <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Þetta tæki tilheyrir <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> og er tengt við <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Þetta tæki tilheyrir fyrirtækinu þínu"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Vinnusniðið þitt er tengt við <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Einkaprófíllinn þinn er tengdur við <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Þetta tæki er tengt við <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Þetta tæki er frá <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Tækjastjórnun"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Fylgst með sniði"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Neteftirlit"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Skoða stefnur"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Skoða stýringar"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Þetta tæki tilheyrir <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nKerfisstjórinn getur fylgst með og breytt stillingum, fyrirtækjaaðgangi, forritum, gögnum sem tengjast tækinu þínu og staðsetningarupplýsingum tækisins.\n\nHafðu samband við kerfisstjórann til að fá frekari upplýsingar."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"Mögulegt er að <xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> fái aðgang að gögnum sem tengjast þessu tæki, geti stjórnað forritum og breytt stillingum tækisins.\n\nEf spurningar vakna skaltu hafa samband við <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Þetta tæki tilheyrir fyrirtækinu þínu.\n\nKerfisstjórinn getur fylgst með og breytt stillingum, fyrirtækjaaðgangi, forritum, gögnum sem tengjast tækinu þínu og staðsetningarupplýsingum tækisins.\n\nHafðu samband við kerfisstjórann til að fá frekari upplýsingar."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Fyrirtækið þitt setti upp CA-vottorð á þessu tæki. Eftirlit kann að vera haft með öruggri netnotkun þinni eða henni kann að vera breytt."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Fyrirtækið þitt setti upp CA-vottorð á vinnusniðinu þínu. Eftirlit kann að vera haft með öruggri netnotkun þinni eða henni kann að vera breytt."</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Sýna prufustillingu"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Vekjari"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Veski"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Tilbúið"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Vinnusnið"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Flugstilling"</string>
     <string name="add_tile" msgid="6239678623873086686">"Bæta reit við"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Loka flýtistillingum."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Vekjari stilltur."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Skráð(ur) inn sem <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"velja notanda"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Engin nettenging"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Opna upplýsingasíðu."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"Ekki tiltækt vegna <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Opna <xliff:g id="ID_1">%s</xliff:g> stillingar."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Breyta röð stillinga."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Aflrofavalmynd"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Blaðsíða <xliff:g id="ID_1">%1$d</xliff:g> af <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Lásskjár"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"Slökkt var á símanum vegna hita"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Færa til vinstri"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Færa til hægri"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Stækkunarrofi"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Stækka allan skjáinn"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Stækka allan skjáinn"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Stækka hluta skjásins"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Rofi"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"Aðgengishnappur kom í stað aðgengisbendingar\n\n"<annotation id="link">"Skoða stillingar"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Færðu hnappinn að brúninni til að fela hann tímabundið"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Tækjastjórnun"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Bæta við stýringum fyrir tengd tæki"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Setja upp tækjastjórnun"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Para nýtt tæki"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Samtalsgræjur"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Ýttu á samtal til að bæta því á heimaskjáinn"</string>
+    <string name="timestamp" msgid="6577851592534538533">"Fyrir <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"Fyrir minna en <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"Fyrir meira en <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Afmæli"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Afmæli á næstunni"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Brúðkaupsafmæli"</string>
+    <string name="location_status" msgid="1294990572202541812">"Deilir staðsetningu"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Ný frétt"</string>
+    <string name="video_status" msgid="4548544654316843225">"Að horfa"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Hlustar"</string>
+    <string name="game_status" msgid="1340694320630973259">"Spilar"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Vinir"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Spjöllum í kvöld!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"Ósvarað símtal"</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="battery_state_unknown_notification_title" msgid="8464703640483773454">"Vandamál við að lesa stöðu rafhlöðu"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Ýttu til að fá frekari upplýsingar"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Enginn vekjari"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index d47a454..5b1855b 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Annulla"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Condividi"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Registrazione dello schermo annullata"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Registrazione dello schermo salvata"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Tocca per visualizzare"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Errore durante l\'eliminazione della registrazione dello schermo"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Impossibile ottenere le autorizzazioni"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Errore durante l\'avvio della registrazione dello schermo"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Nuovo utente"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Internet"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Utilizzabili in aereo"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Reti disponibili"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Reti non disponibili"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Non connessa"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Fino all\'alba"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Attivazione alle <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Fino alle <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Riduci la luminosità"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC non attiva"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC attiva"</string>
@@ -470,11 +466,10 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Mostra profilo"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Aggiungi utente"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Nuovo utente"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Termina sessione Ospite"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Rimuovere l\'ospite?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Tutte le app e i dati di questa sessione verranno eliminati."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Rimuovi"</string>
-    <string name="guest_wipe_session_title" msgid="7147965814683990944">"Bentornato, ospite."</string>
+    <string name="guest_wipe_session_title" msgid="7147965814683990944">"Ti ridiamo il benvenuto alla sessione Ospite."</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Vuoi continuare la sessione?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Ricomincia"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Sì, continua"</string>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Questo dispositivo è gestito dai tuoi genitori"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Questo dispositivo appartiene alla tua organizzazione, che potrebbe monitorare il traffico di rete"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Questo dispositivo appartiene a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, che potrebbe monitorare il traffico di rete"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Questo dispositivo è fornito da <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Questo dispositivo appartiene alla tua organizzazione ed è collegato a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Questo dispositivo appartiene a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ed è collegato a <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Questo dispositivo appartiene alla tua organizzazione"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Il tuo profilo di lavoro è collegato a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Il tuo profilo personale è collegato a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Questo dispositivo è collegato a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Questo dispositivo è fornito da <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Gestione dei dispositivi"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Monitoraggio del profilo"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Monitoraggio rete"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Visualizza le norme"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Visualizza controlli"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Questo dispositivo appartiene a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nIl tuo amministratore IT può monitorare e gestire impostazioni, accesso aziendale, app, dati associati al dispositivo e informazioni sulla posizione del dispositivo.\n\nPer ulteriori informazioni, contatta il tuo amministratore IT."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> potrebbe riuscire ad accedere ai dati associati a questo dispositivo, a gestire app e a modificare le impostazioni del dispositivo.\n\nPer eventuali domande, contatta <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Questo dispositivo appartiene alla tua organizzazione.\n\nIl tuo amministratore IT può monitorare e gestire impostazioni, accesso aziendale, app, dati associati al dispositivo e informazioni sulla posizione del dispositivo.\n\nPer ulteriori informazioni, contatta il tuo amministratore IT."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"La tua organizzazione ha installato un\'autorità di certificazione sul dispositivo. Il tuo traffico di rete protetto potrebbe essere monitorato o modificato."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"La tua organizzazione ha installato un\'autorità di certificazione nel tuo profilo di lavoro. Il tuo traffico di rete protetto potrebbe essere monitorato o modificato."</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Mostra modalità demo"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Sveglia"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Pronto"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Profilo di lavoro"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Modalità aereo"</string>
     <string name="add_tile" msgid="6239678623873086686">"Aggiungi riquadro"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Chiudi le impostazioni rapide."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Sveglia impostata."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Accesso eseguito come <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"selezionare l\'utente"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Nessuna connessione a Internet"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Apri i dettagli."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"Non disponibile a causa di un problema <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Apri le impostazioni <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Modifica l\'ordine delle impostazioni."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menu del tasto di accensione"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Pagina <xliff:g id="ID_1">%1$d</xliff:g> di <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Schermata di blocco"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"Il telefono si è spento perché surriscaldato"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Sposta a sinistra"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Sposta a destra"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Opzione Ingrandimento"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Ingrandisci l\'intero schermo"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Ingrandisci l\'intero schermo"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Ingrandisci parte dello schermo"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Opzione"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"Il pulsante Accessibilità ha sostituito il gesto di accessibilità\n\n"<annotation id="link">"Visualizza le impostazioni"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Sposta il pulsante fino al bordo per nasconderlo temporaneamente"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Controllo dei dispositivi"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Aggiungi controlli per i dispositivi connessi"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Configura il controllo dei dispositivi"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Accoppia nuovo dispositivo"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Widget Conversazione"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Tocca una conversazione per aggiungerla alla schermata Home"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> fa"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"Meno di <xliff:g id="DURATION">%1$s</xliff:g> fa"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"Più di <xliff:g id="DURATION">%1$s</xliff:g> fa"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Compleanno"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Compleanno imminente"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Anniversario"</string>
+    <string name="location_status" msgid="1294990572202541812">"Condivis. posizione"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Nuova notizia"</string>
+    <string name="video_status" msgid="4548544654316843225">"Visione in corso"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Ascolto in corso"</string>
+    <string name="game_status" msgid="1340694320630973259">"Gioco in corso"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Amici"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Chattiamo stasera."</string>
+    <string name="missed_call" msgid="4228016077700161689">"Chiamata persa"</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="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problema durante la lettura dell\'indicatore di livello della batteria"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tocca per ulteriori informazioni"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nessuna sveglia"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index e937a5a..8e4390e 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -28,7 +28,7 @@
     <string name="battery_low_percent_format" msgid="4276661262843170964">"נותרו <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
     <string name="battery_low_percent_format_hybrid" msgid="3985614339605686167">"נותרו <xliff:g id="PERCENTAGE">%1$s</xliff:g>, נשארו בערך <xliff:g id="TIME">%2$s</xliff:g> על סמך השימוש במכשיר"</string>
     <string name="battery_low_percent_format_hybrid_short" msgid="5917433188456218857">"נותרו <xliff:g id="PERCENTAGE">%1$s</xliff:g>, נשארו בערך <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <string name="battery_low_percent_format_saver_started" msgid="4968468824040940688">"נותרו <xliff:g id="PERCENTAGE">%s</xliff:g>. הופעלה תכונת החיסכון בסוללה."</string>
+    <string name="battery_low_percent_format_saver_started" msgid="4968468824040940688">"נותרו <xliff:g id="PERCENTAGE">%s</xliff:g>. התכונה \'חיסכון בסוללה\' הופעלה."</string>
     <string name="invalid_charger" msgid="4370074072117767416">"‏לא ניתן לטעון באמצעות USB. ניתן להשתמש במטען שצורף למכשיר שלך."</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"‏לא ניתן לטעון באמצעות USB"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"שימוש במטען שסופק עם המכשיר"</string>
@@ -40,7 +40,7 @@
     <string name="status_bar_settings_settings_button" msgid="534331565185171556">"הגדרות"</string>
     <string name="status_bar_settings_wifi_button" msgid="7243072479837270946">"Wi-Fi"</string>
     <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"סיבוב אוטומטי של המסך"</string>
-    <string name="status_bar_settings_mute_label" msgid="914392730086057522">"השתק"</string>
+    <string name="status_bar_settings_mute_label" msgid="914392730086057522">"השתקה"</string>
     <string name="status_bar_settings_auto_brightness_label" msgid="2151934479226017725">"אוטומטי"</string>
     <string name="status_bar_settings_notifications" msgid="5285316949980621438">"התראות"</string>
     <string name="bluetooth_tethered" msgid="4171071193052799041">"‏Bluetooth קשור"</string>
@@ -116,17 +116,15 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"ביטול"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"שיתוף"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"הקלטת המסך בוטלה"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"הקלטת המסך נשמרה"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"יש להקיש כדי להציג"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"שגיאה במחיקת הקלטת המסך"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"קבלת ההרשאות נכשלה"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"שגיאה בהפעלה של הקלטת המסך"</string>
     <string name="usb_preference_title" msgid="1439924437558480718">"‏אפשרויות העברת קבצים ב-USB"</string>
     <string name="use_mtp_button_title" msgid="5036082897886518086">"‏טען כנגן מדיה (MTP)"</string>
-    <string name="use_ptp_button_title" msgid="7676427598943446826">"‏טען כמצלמה (PTP)"</string>
-    <string name="installer_cd_button_title" msgid="5499998592841984743">"‏התקן את אפליקציית העברת הקבצים של Android עבור Mac"</string>
+    <string name="use_ptp_button_title" msgid="7676427598943446826">"‏טעינה כמצלמה (PTP)"</string>
+    <string name="installer_cd_button_title" msgid="5499998592841984743">"‏התקנת האפליקציה \'העברת קבצים ב-Android\' עבור Mac"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"הקודם"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"בית"</string>
     <string name="accessibility_menu" msgid="2701163794470513040">"תפריט"</string>
@@ -144,7 +142,7 @@
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"שליחה"</string>
     <string name="accessibility_manage_notification" msgid="582215815790143983">"ניהול התראות"</string>
     <string name="phone_label" msgid="5715229948920451352">"פתח את הטלפון"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"פתח את המסייע הקולי"</string>
+    <string name="voice_assist_label" msgid="3725967093735929020">"פתיחת האסיסטנט"</string>
     <string name="camera_label" msgid="8253821920931143699">"פתח את המצלמה"</string>
     <string name="cancel" msgid="1089011503403416730">"ביטול"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"אישור"</string>
@@ -166,13 +164,13 @@
     <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"יש לנסות שוב. ניסיון <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> מתוך <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string>
     <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"הנתונים שלך יימחקו"</string>
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"הזנת קו ביטול נעילה שגוי בניסיון הבא תגרום למחיקת הנתונים במכשיר."</string>
-    <string name="biometric_dialog_last_pin_attempt_before_wipe_device" msgid="9151756675698215723">"הזנת קוד גישה שגוי בניסיון הבא תגרום למחיקת הנתונים במכשיר."</string>
+    <string name="biometric_dialog_last_pin_attempt_before_wipe_device" msgid="9151756675698215723">"הזנת קוד אימות שגוי בניסיון הבא תגרום למחיקת הנתונים במכשיר."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_device" msgid="2363778585575998317">"הזנת סיסמה שגויה בניסיון הבא תגרום למחיקת הנתונים במכשיר."</string>
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_user" msgid="8400180746043407270">"הזנת קו ביטול נעילה שגוי בניסיון הבא תגרום למחיקת המשתמש הזה."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_user" msgid="4159878829962411168">"הזנת קוד גישה שגוי בניסיון הבא תגרום למחיקת המשתמש הזה."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_user" msgid="4695682515465063885">"הזנת סיסמה שגויה בניסיון הבא תגרום למחיקת המשתמש הזה."</string>
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"הזנת קו ביטול נעילה שגוי בניסיון הבא תגרום למחיקת פרופיל העבודה והנתונים המשויכים אליו."</string>
-    <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"הזנת קוד גישה שגוי בניסיון הבא תגרום למחיקת פרופיל העבודה והנתונים המשויכים אליו."</string>
+    <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"הזנה של קוד אימות שגוי בניסיון הבא תגרום למחיקת פרופיל העבודה והנתונים המשויכים אליו."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"הזנת סיסמה שגויה בניסיון הבא תגרום למחיקת פרופיל העבודה והנתונים המשויכים אליו."</string>
     <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"נעשו יותר מדי ניסיונות שגויים. הנתונים במכשיר יימחקו."</string>
     <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"נעשו יותר מדי ניסיונות שגויים. המשתמש הזה יימחק."</string>
@@ -210,7 +208,7 @@
     <string name="accessibility_desc_on" msgid="2899626845061427845">"פועל."</string>
     <string name="accessibility_desc_off" msgid="8055389500285421408">"כבוי."</string>
     <string name="accessibility_desc_connected" msgid="3082590384032624233">"מחובר."</string>
-    <string name="accessibility_desc_connecting" msgid="8011433412112903614">"מתחבר."</string>
+    <string name="accessibility_desc_connecting" msgid="8011433412112903614">"מתבצע חיבור."</string>
     <string name="data_connection_hspa" msgid="6096234094857660873">"HSPA"</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"נדידה"</string>
     <string name="accessibility_data_connection_wifi" msgid="4422160347472742434">"Wi-Fi"</string>
@@ -269,11 +267,11 @@
     <string name="accessibility_quick_settings_bluetooth_changed_off" msgid="3344226652293797283">"‏Bluetooth נכבה."</string>
     <string name="accessibility_quick_settings_bluetooth_changed_on" msgid="1263282011749437549">"‏Bluetooth הופעל."</string>
     <string name="accessibility_quick_settings_location_off" msgid="6122523378294740598">"דיווח מיקום כבוי."</string>
-    <string name="accessibility_quick_settings_location_on" msgid="6869947200325467243">"דיווח מיקום מופעל."</string>
+    <string name="accessibility_quick_settings_location_on" msgid="6869947200325467243">"התכונה \'דיווח מיקום\' מופעלת."</string>
     <string name="accessibility_quick_settings_location_changed_off" msgid="5132776369388699133">"דיווח מיקום נכבה."</string>
     <string name="accessibility_quick_settings_location_changed_on" msgid="7159115433070112154">"דיווח מיקום הופעל."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"ההתראה נקבעה ל-<xliff:g id="TIME">%s</xliff:g>."</string>
-    <string name="accessibility_quick_settings_close" msgid="2974895537860082341">"סגור לוח."</string>
+    <string name="accessibility_quick_settings_close" msgid="2974895537860082341">"סגירת הלוח."</string>
     <string name="accessibility_quick_settings_more_time" msgid="7646479831704665284">"יותר זמן."</string>
     <string name="accessibility_quick_settings_less_time" msgid="9110364286464977870">"פחות זמן."</string>
     <string name="accessibility_quick_settings_flashlight_off" msgid="7606563260714825190">"הפנס כבוי."</string>
@@ -303,7 +301,7 @@
     <string name="data_usage_disabled_dialog" msgid="7933201635215099780">"הגעת למגבלת הנתונים שהגדרת. אתה כבר לא משתמש בחבילת גלישה.\n\nאם תמשיך, ייתכנו חיובים על שימוש בנתונים."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="2796648546086408937">"המשך"</string>
     <string name="gps_notification_searching_text" msgid="231304732649348313">"‏מחפש GPS"</string>
-    <string name="gps_notification_found_text" msgid="3145873880174658526">"‏מיקום מוגדר על ידי GPS"</string>
+    <string name="gps_notification_found_text" msgid="3145873880174658526">"‏המיקום מוגדר על ידי GPS"</string>
     <string name="accessibility_location_active" msgid="2845747916764660369">"בקשות מיקום פעילות"</string>
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"ההגדרה \'חיישנים כבויים\' פעילה"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"הסרת כל ההתראות."</string>
@@ -320,7 +318,7 @@
     <string name="accessibility_rotation_lock_off" msgid="3880436123632448930">"המסך יסתובב באופן אוטומטי."</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"המסך נעול כעת לרוחב."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"המסך נעול כעת לאורך."</string>
-    <string name="accessibility_rotation_lock_off_changed" msgid="5772498370935088261">"המסך יסתובב כעת באופן אוטומטי."</string>
+    <string name="accessibility_rotation_lock_off_changed" msgid="5772498370935088261">"המסך יסתובב עכשיו באופן אוטומטי."</string>
     <string name="accessibility_rotation_lock_on_landscape_changed" msgid="5785739044300729592">"המסך נעול כעת לרוחב."</string>
     <string name="accessibility_rotation_lock_on_portrait_changed" msgid="5580170829728987989">"המסך נעול כעת לאורך."</string>
     <string name="dessert_case" msgid="9104973640704357717">"מזנון קינוחים"</string>
@@ -345,12 +343,12 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"סיבוב אוטומטי"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"סיבוב אוטומטי של המסך"</string>
     <string name="accessibility_quick_settings_rotation_value" msgid="2916484894750819251">"מצב <xliff:g id="ID_1">%s</xliff:g>"</string>
-    <string name="quick_settings_rotation_locked_label" msgid="4420863550666310319">"סיבוב נעול"</string>
+    <string name="quick_settings_rotation_locked_label" msgid="4420863550666310319">"סיבוב המסך נעול"</string>
     <string name="quick_settings_rotation_locked_portrait_label" msgid="1194988975270484482">"לאורך"</string>
     <string name="quick_settings_rotation_locked_landscape_label" msgid="2000295772687238645">"לרוחב"</string>
     <string name="quick_settings_ime_label" msgid="3351174938144332051">"שיטת קלט"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"מיקום"</string>
-    <string name="quick_settings_location_off_label" msgid="7923929131443915919">"מיקום כבוי"</string>
+    <string name="quick_settings_location_off_label" msgid="7923929131443915919">"המיקום מושבת"</string>
     <string name="quick_settings_camera_label" msgid="1367149596242401934">"חסימת המצלמה"</string>
     <string name="quick_settings_mic_label" msgid="8245831073612564953">"השתקת המיקרופון"</string>
     <string name="quick_settings_media_device_label" msgid="8034019242363789941">"מכשיר מדיה"</string>
@@ -363,7 +361,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"משתמש חדש"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"אינטרנט"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"רשתות בטוחות לטיסה"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"רשתות זמינות"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"אין רשתות זמינות"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"אין חיבור"</string>
@@ -371,7 +368,7 @@
     <string name="quick_settings_wifi_off_label" msgid="4003379736176547594">"‏Wi-Fi כבוי"</string>
     <string name="quick_settings_wifi_on_label" msgid="2489928193654318511">"‏Wi-Fi פועל"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="483130889414601732">"‏אין רשתות Wi-Fi זמינות"</string>
-    <string name="quick_settings_wifi_secondary_label_transient" msgid="7501659015509357887">"ההפעלה מתבצעת…"</string>
+    <string name="quick_settings_wifi_secondary_label_transient" msgid="7501659015509357887">"בתהליך הפעלה…"</string>
     <string name="quick_settings_cast_title" msgid="2279220930629235211">"העברת מסך"</string>
     <string name="quick_settings_casting" msgid="1435880708719268055">"מעביר"</string>
     <string name="quick_settings_cast_device_default_name" msgid="6988469571141331700">"מכשיר ללא שם"</string>
@@ -403,13 +400,13 @@
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"חבילת גלישה"</string>
     <string name="quick_settings_cellular_detail_data_usage" msgid="6105969068871138427">"שימוש בנתונים"</string>
     <string name="quick_settings_cellular_detail_remaining_data" msgid="1136599216568805644">"מכסת נתונים נותרת"</string>
-    <string name="quick_settings_cellular_detail_over_limit" msgid="4561921367680636235">"חריגה מההגבלה"</string>
+    <string name="quick_settings_cellular_detail_over_limit" msgid="4561921367680636235">"חריגה מהמגבלה"</string>
     <string name="quick_settings_cellular_detail_data_used" msgid="6798849610647988987">"<xliff:g id="DATA_USED">%s</xliff:g> בשימוש"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="1791389609409211628">"הגבלה של <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="7957253810481086455">"אזהרה - <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_work_mode_label" msgid="2754212289804324685">"פרופיל עבודה"</string>
     <string name="quick_settings_night_display_label" msgid="8180030659141778180">"תאורת לילה"</string>
-    <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"מופעל בשקיעה"</string>
+    <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"התכונה מופעלת בשקיעה"</string>
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4063448287758262485">"עד הזריחה"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="3584738542293528235">"מופעל בשעה <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="1883981263191927372">"עד <xliff:g id="TIME">%s</xliff:g>"</string>
@@ -419,7 +416,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"עד הזריחה"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"יתחיל בשעה <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"עד <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"הפחתה של עוצמת הבהירות"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"‏NFC מושבת"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"‏NFC מופעל"</string>
@@ -444,10 +440,10 @@
     <string name="zen_alarms_introduction" msgid="3987266042682300470">"כדי לא להפריע לך, המכשיר לא ירטוט ולא ישמיע שום צליל, חוץ מהתראות. המצב הזה לא ישפיע על צלילים שהם חלק מתוכן שבחרת להפעיל, כמו מוזיקה, סרטונים ומשחקים."</string>
     <string name="zen_priority_customize_button" msgid="4119213187257195047">"התאמה אישית"</string>
     <string name="zen_silence_introduction_voice" msgid="853573681302712348">"פעולה זו מבטלת את כל הצלילים והרטט, כולל צלילים ורטט שמקורם בהתראות, מוזיקה, סרטונים ומשחקים. בכל מקרה, עדיין אפשר להתקשר."</string>
-    <string name="zen_silence_introduction" msgid="6117517737057344014">"פעולה זו מבטלת את כל הצלילים והרטט, כולל בהתראות, מוזיקה, סרטונים ומשחקים."</string>
+    <string name="zen_silence_introduction" msgid="6117517737057344014">"הפעולה הזו מבטלת את כל הצלילים והרטט, כולל בהתראות, מוזיקה, סרטונים ומשחקים."</string>
     <string name="keyguard_more_overflow_text" msgid="5819512373606638727">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="7248696377626341060">"התראות בדחיפות נמוכה יותר בהמשך"</string>
-    <string name="notification_tap_again" msgid="4477318164947497249">"הקש שוב כדי לפתוח"</string>
+    <string name="notification_tap_again" msgid="4477318164947497249">"יש להקיש שוב כדי לפתוח את ההתראה"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"צריך להחליק כדי לפתוח"</string>
     <string name="keyguard_retry" msgid="886802522584053523">"יש להחליק למעלה כדי לנסות שוב"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"‏יש לבטל את הנעילה כדי להשתמש ב-NFC"</string>
@@ -474,10 +470,9 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"הצג פרופיל"</string>
     <string name="user_add_user" msgid="4336657383006913022">"הוספת משתמש"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"משתמש חדש"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"הפסקת הגלישה כאורח"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"להסיר אורח?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"כל האפליקציות והנתונים בפעילות זו באתר יימחקו."</string>
-    <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"הסר"</string>
+    <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"הסרה"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"שמחים לראותך שוב!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"האם ברצונך להמשיך בפעילות באתר?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ברצוני להתחיל מחדש"</string>
@@ -488,7 +483,7 @@
     <string name="user_logout_notification_title" msgid="3644848998053832589">"ניתוק משתמש"</string>
     <string name="user_logout_notification_text" msgid="7441286737342997991">"צא מהמשתמש הנוכחי"</string>
     <string name="user_logout_notification_action" msgid="7974458760719361881">"נתק משתמש"</string>
-    <string name="user_add_user_title" msgid="4172327541504825032">"האם להוסיף משתמש חדש?"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"להוסיף משתמש חדש?"</string>
     <string name="user_add_user_message_short" msgid="2599370307878014791">"בעת הוספת משתמש חדש, על משתמש זה להגדיר את השטח שלו.\n\nכל משתמש יכול לעדכן אפליקציות עבור כל המשתמשים האחרים."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"הגעת למגבלת המשתמשים שניתן להוסיף"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
@@ -499,16 +494,16 @@
     </plurals>
     <string name="user_remove_user_title" msgid="9124124694835811874">"האם להסיר את המשתמש?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"כל האפליקציות והנתונים של המשתמש הזה יימחקו."</string>
-    <string name="user_remove_user_remove" msgid="8387386066949061256">"הסר"</string>
+    <string name="user_remove_user_remove" msgid="8387386066949061256">"הסרה"</string>
     <string name="battery_saver_notification_title" msgid="8419266546034372562">"תכונת החיסכון בסוללה פועלת"</string>
     <string name="battery_saver_notification_text" msgid="2617841636449016951">"מפחית את הביצועים ונתונים ברקע"</string>
-    <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"כיבוי תכונת החיסכון בסוללה"</string>
+    <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"השבתת התכונה \'חיסכון בסוללה\'"</string>
     <string name="media_projection_dialog_text" msgid="1755705274910034772">"‏לאפליקציית <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> תהיה גישה לכל המידע הגלוי במסך שלך ולכל תוכן שמופעל במכשיר שלך בזמן הקלטה או העברה (casting). המידע הזה כולל פרטים כמו סיסמאות, פרטי תשלום, תמונות, הודעות ואודיו שמושמע מהמכשיר."</string>
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"‏לשירות שמספק את הפונקציה הזו תהיה גישה לכל הפרטים שגלויים במסך שלך או מופעלים מהמכשיר שלך בזמן הקלטה או העברה (cast). זה כולל פרטים כמו סיסמאות, פרטי תשלום, תמונות, הודעות ואודיו שמושמע מהמכשיר."</string>
     <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"‏להתחיל להקליט או להעביר (cast)?"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"‏להתחיל להקליט או להעביר (cast) באמצעות <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
     <string name="media_projection_remember_text" msgid="6896767327140422951">"אל תציג שוב"</string>
-    <string name="clear_all_notifications_text" msgid="348312370303046130">"ניקוי הכל"</string>
+    <string name="clear_all_notifications_text" msgid="348312370303046130">"ניקוי הכול"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"ניהול"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"היסטוריה"</string>
     <string name="notification_section_header_incoming" msgid="850925217908095197">"התראות חדשות"</string>
@@ -522,9 +517,10 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"ייתכן שהפרופיל נתון למעקב"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"ייתכן שהרשת נמצאת במעקב"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"ייתכן שהרשת מנוטרת"</string>
-    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"מכשיר זה מנוהל על ידי ההורה שלך"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"המכשיר הזה מנוהל על ידי ההורה שלך"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"הארגון שלך הוא הבעלים של מכשיר זה והוא עשוי לנטר את התנועה ברשת"</string>
-    <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"הארגון <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> הוא הבעלים של מכשיר זה והוא עשוי לנטר את התנועה ברשת"</string>
+    <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"הארגון <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> הוא הבעלים של המכשיר הזה והוא עשוי לנטר את התנועה ברשת"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"המכשיר הזה התקבל מ-<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"המכשיר הזה שייך לארגון שלך, והוא מחובר ל-<xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"המכשיר הזה שייך לארגון <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> והוא מחובר ל-<xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"המכשיר הזה שייך לארגון שלך"</string>
@@ -538,6 +534,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"פרופיל העבודה שלך מחובר ל-<xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"הפרופיל האישי שלך מחובר ל-<xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"המכשיר הזה מחובר ל-<xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"המכשיר הזה התקבל מ-<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"ניהול מכשירים"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"מעקב אחר פרופיל"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"מעקב אחר פעילות ברשת"</string>
@@ -545,17 +542,18 @@
     <string name="monitoring_subtitle_network_logging" msgid="2444199331891219596">"רישום התנועה ברשת"</string>
     <string name="monitoring_subtitle_ca_certificate" msgid="8588092029755175800">"‏אישורי CA"</string>
     <string name="disable_vpn" msgid="482685974985502922">"‏השבת VPN"</string>
-    <string name="disconnect_vpn" msgid="26286850045344557">"‏נתק את ה-VPN"</string>
+    <string name="disconnect_vpn" msgid="26286850045344557">"‏ניתוק ה-VPN"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"הצג מדיניות"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"לצפייה באמצעי בקרת ההורים"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"‏המכשיר הזה שייך לארגון <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nמנהל ה-IT יכול לנטר ולנהל הגדרות, גישה ארגונית, אפליקציות, נתונים המשויכים למכשיר ומידע על מיקום המכשיר.\n\nלמידע נוסף, יש לפנות למנהל ה-IT."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"ל-<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> תהיה אפשרות לגשת לנתונים המשויכים למכשיר הזה, לנהל אפליקציות ולשנות את הגדרות המכשיר.\n\nאם יש לך שאלות, ניתן ליצור קשר עם <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"‏המכשיר הזה שייך לארגון שלך.\n\nמנהל ה-IT יכול לנטר ולנהל הגדרות, גישה ארגונית, אפליקציות, נתונים המשויכים למכשיר ומידע על מיקום המכשיר.\n\nלמידע נוסף, יש לפנות למנהל ה-IT."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"הארגון שלך התקין רשות אישורים במכשיר. ניתן לעקוב אחר התנועה ברשת המאובטחת או לשנות אותה."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"הארגון שלך התקין רשות אישורים בפרופיל העבודה. ניתן לעקוב אחר התנועה ברשת המאובטחת או לשנות אותה."</string>
     <string name="monitoring_description_ca_certificate" msgid="448923057059097497">"במכשיר זה מותקנת רשות אישורים. ניתן לעקוב אחר התנועה ברשת המאובטחת או לשנות אותה."</string>
     <string name="monitoring_description_management_network_logging" msgid="216983105036994771">"מנהל המערכת הפעיל את התכונה \'רישום התנועה ברשת\', שמנטרת את תנועת הנתונים במכשיר."</string>
     <string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"מנהל המערכת הפעיל את תכונת רישום התנועה ברשת, שמנטרת את תנועת הנתונים בפרופיל העבודה, אבל לא בפרופיל האישי."</string>
-    <string name="monitoring_description_named_vpn" msgid="5749932930634037027">"אתה מחובר לאפליקציה <xliff:g id="VPN_APP">%1$s</xliff:g>, שיכולה לעקוב אחר הפעילות שלך ברשת, כולל הודעות אימייל, אפליקציות ואתרים."</string>
+    <string name="monitoring_description_named_vpn" msgid="5749932930634037027">"התחברת לאפליקציה <xliff:g id="VPN_APP">%1$s</xliff:g>, שיכולה לעקוב אחר הפעילות שלך ברשת, כולל הודעות אימייל, אפליקציות ואתרים."</string>
     <string name="monitoring_description_two_named_vpns" msgid="3516830755681229463">"אתה מחובר לאפליקציות <xliff:g id="VPN_APP_0">%1$s</xliff:g> ו-<xliff:g id="VPN_APP_1">%2$s</xliff:g>, שיכולות לעקוב אחר הפעילות שלך ברשת, כולל הודעות אימייל, אפליקציות ואתרים."</string>
     <string name="monitoring_description_managed_profile_named_vpn" msgid="368812367182387320">"פרופיל העבודה שלך מחובר לאפליקציה <xliff:g id="VPN_APP">%1$s</xliff:g>, שיכולה לעקוב אחר הפעילות שלך ברשת, כולל הודעות אימייל, אפליקציות ואתרים."</string>
     <string name="monitoring_description_personal_profile_named_vpn" msgid="8179722332380953673">"הפרופיל האישי שלך מחובר לאפליקציה <xliff:g id="VPN_APP">%1$s</xliff:g>, שיכולה לעקוב אחר הפעילות שלך ברשת, כולל הודעות אימייל, אפליקציות ואתרים."</string>
@@ -564,23 +562,23 @@
     <string name="monitoring_description_do_body" msgid="7700878065625769970">"מנהל המערכת יכול לנטר ולנהל הגדרות, גישה ארגונית, אפליקציות, נתונים המשויכים למכשיר ומידע על מיקום המכשיר."</string>
     <string name="monitoring_description_do_learn_more_separator" msgid="1467280496376492558">" "</string>
     <string name="monitoring_description_do_learn_more" msgid="645149183455573790">"למידע נוסף"</string>
-    <string name="monitoring_description_do_body_vpn" msgid="7699280130070502303">"אתה מחובר לאפליקציה <xliff:g id="VPN_APP">%1$s</xliff:g>, שיכולה לעקוב אחר הפעילות שלך ברשת, כולל הודעות אימייל, אפליקציות ואתרים."</string>
+    <string name="monitoring_description_do_body_vpn" msgid="7699280130070502303">"התחברת לאפליקציה <xliff:g id="VPN_APP">%1$s</xliff:g>, שיכולה לעקוב אחר הפעילות שלך ברשת, כולל הודעות אימייל, אפליקציות ואתרים."</string>
     <string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
     <string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"‏להגדרות ה-VPN"</string>
     <string name="monitoring_description_ca_cert_settings_separator" msgid="7107390013344435439">" "</string>
-    <string name="monitoring_description_ca_cert_settings" msgid="8329781950135541003">"פתח את פרטי הכניסה המהימנים"</string>
+    <string name="monitoring_description_ca_cert_settings" msgid="8329781950135541003">"פתיחה של פרטי הכניסה המהימנים"</string>
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"מנהל המערכת הפעיל את תכונת רישום התנועה ברשת, שמנטרת את תנועת הנתונים במכשיר.\n\nלמידע נוסף, צור קשר עם מנהל המערכת."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"‏נתת לאפליקציה כלשהי הרשאה להגדיר חיבור ‏VPN‏.\n\nהאפליקציה הזו יכולה לעקוב אחר הפעילות שלך ברשת ובמכשיר, כולל הודעות אימייל, אפליקציות ואתרים."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"‏פרופיל העבודה שלך מנוהל על-ידי <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\n מנהל המערכת שלך יכול לעקוב אחרי הפעילות שלך ברשת, כולל פעילות באימייל, באפליקציות ובאתרים.\n\n למידע נוסף, צור קשר עם מנהל המערכת.\n\nבנוסף, אתה מחובר ל-VPN, שגם באמצעותו ניתן לעקוב אחרי הפעילות שלך ברשת."</string>
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"מכשיר זה מנוהל על ידי ההורה שלך. להורה שלך יש אפשרות לצפות בפרטים כמו האפליקציות שבשימוש, המיקום וזמן המסך שלך, ולנהל אותם."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"אתה מחובר לאפליקציה <xliff:g id="APPLICATION">%1$s</xliff:g>, שיכולה לעקוב אחר הפעילות שלך ברשת, כולל הודעות אימייל, אפליקציות ואתרים."</string>
-    <string name="monitoring_description_app_personal" msgid="1970094872688265987">"אתה מחובר לאפליקציה <xliff:g id="APPLICATION">%1$s</xliff:g>, שיכולה לעקוב אחר הפעילות שלך ברשת הפרטית, כולל הודעות אימייל, אפליקציות ואתרים."</string>
+    <string name="monitoring_description_app_personal" msgid="1970094872688265987">"התחברת לאפליקציית <xliff:g id="APPLICATION">%1$s</xliff:g>, שיכולה לעקוב אחר הפעילות שלך ברשת, כולל הודעות אימייל, אפליקציות ואתרים."</string>
     <string name="branded_monitoring_description_app_personal" msgid="1703511985892688885">"אתה מחובר לאפליקציה <xliff:g id="APPLICATION">%1$s</xliff:g>, שיכולה לעקוב אחר הפעילות שלך ברשת הפרטית, כולל הודעות אימייל, אפליקציות ואתרים."</string>
     <string name="monitoring_description_app_work" msgid="3713084153786663662">"פרופיל העבודה שלך מנוהל על ידי <xliff:g id="ORGANIZATION">%1$s</xliff:g>. הפרופיל מחובר לאפליקציה <xliff:g id="APPLICATION">%2$s</xliff:g>, שיכולה לעקוב אחר הפעילות שלך ברשת, כולל הודעות אימייל, אפליקציות ואתרים.\n\nלמידע נוסף, פנה למנהל המערכת."</string>
     <string name="monitoring_description_app_personal_work" msgid="6175816356939166101">"פרופיל העבודה שלך מנוהל על ידי <xliff:g id="ORGANIZATION">%1$s</xliff:g>. הפרופיל מחובר לאפליקציה <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, שיכולה לעקוב אחר הפעילות שלך ברשת, כולל הודעות אימייל, אפליקציות ואתרים.\n\nהפרופיל מחובר גם לאפליקציה <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, שיכולה לעקוב אחר הפעילות שלך ברשת."</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"הנעילה נמנעת על ידי סביבה אמינה"</string>
-    <string name="keyguard_indication_trust_disabled" msgid="6820793704816727918">"המכשיר יישאר נעול עד שתבטל את נעילתו באופן ידני"</string>
+    <string name="keyguard_indication_trust_disabled" msgid="6820793704816727918">"המכשיר יישאר נעול עד שהנעילה שלו תבוטל באופן ידני"</string>
     <string name="keyguard_indication_trust_unlocked_plugged_in" msgid="2323452175329362855">"<xliff:g id="KEYGUARD_INDICATION">%1$s</xliff:g>\n<xliff:g id="POWER_INDICATION">%2$s</xliff:g>"</string>
     <string name="hidden_notifications_title" msgid="1782412844777612795">"קבלה מהירה של התראות"</string>
     <string name="hidden_notifications_text" msgid="5899627470450792578">"צפה בהן לפני שתבטל נעילה"</string>
@@ -589,7 +587,7 @@
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>‏. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="volume_zen_end_now" msgid="5901885672973736563">"כבה עכשיו"</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"הגדרות צליל"</string>
-    <string name="accessibility_volume_expand" msgid="7653070939304433603">"הרחב"</string>
+    <string name="accessibility_volume_expand" msgid="7653070939304433603">"הרחבה"</string>
     <string name="accessibility_volume_collapse" msgid="2746845391013829996">"כווץ"</string>
     <string name="volume_odi_captions_tip" msgid="8825655463280990941">"הוספת כתוביות אוטומטית למדיה"</string>
     <string name="accessibility_volume_close_odi_captions_tip" msgid="8924753283621160480">"סגירת הטיפ לגבי כתוביות"</string>
@@ -613,7 +611,7 @@
     <string name="screen_pinning_start" msgid="7483998671383371313">"האפליקציה הוצמדה"</string>
     <string name="screen_pinning_exit" msgid="4553787518387346893">"הצמדת האפליקציה בוטלה"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="463533331480997595">"להסתיר<xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
-    <string name="quick_settings_reset_confirmation_message" msgid="2320586180785674186">"יופיע מחדש בפעם הבאה שתפעיל את האפשרות בהגדרות."</string>
+    <string name="quick_settings_reset_confirmation_message" msgid="2320586180785674186">"יופיע מחדש בפעם הבאה שהאפשרות הזו תופעל בהגדרות."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="3341477479055016776">"הסתר"</string>
     <string name="stream_voice_call" msgid="7468348170702375660">"שיחה"</string>
     <string name="stream_system" msgid="7663148785370565134">"מערכת"</string>
@@ -631,15 +629,15 @@
     <string name="qs_status_phone_vibrate" msgid="7055409506885541979">"הטלפון במצב רטט"</string>
     <string name="qs_status_phone_muted" msgid="3763664791309544103">"הטלפון מושתק"</string>
     <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"‏%1$s. הקש כדי לבטל את ההשתקה."</string>
-    <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"‏%1$s. הקש כדי להגדיר רטט. ייתכן ששירותי הנגישות מושתקים."</string>
+    <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"‏%1$s. צריך להקיש כדי להגדיר רטט. ייתכן ששירותי הנגישות מושתקים."</string>
     <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"‏%1$s. הקש כדי להשתיק. ייתכן ששירותי הנגישות מושתקים."</string>
-    <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"‏%1$s. הקש כדי להעביר למצב רטט."</string>
-    <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"‏%1$s. הקש כדי להשתיק."</string>
+    <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"‏%1$s. יש להקיש כדי להעביר למצב רטט."</string>
+    <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"‏%1$s. יש להקיש כדי להשתיק."</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"יש להקיש כדי לשנות את מצב תוכנת הצלצול"</string>
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"השתקה"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ביטול ההשתקה"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"רטט"</string>
-    <string name="volume_dialog_title" msgid="6502703403483577940">"‏בקרי עוצמת שמע של %s"</string>
+    <string name="volume_dialog_title" msgid="6502703403483577940">"‏בקרי עוצמת קול של %s"</string>
     <string name="volume_dialog_ringer_guidance_ring" msgid="9143194270463146858">"הטלפון יצלצל כשמתקבלות שיחות והתראות (<xliff:g id="VOLUME_LEVEL">%1$s</xliff:g>)"</string>
     <string name="output_title" msgid="3938776561655668350">"פלט מדיה"</string>
     <string name="output_calls_title" msgid="7085583034267889109">"פלט שיחת טלפון"</string>
@@ -655,16 +653,18 @@
     <string name="status_bar" msgid="4357390266055077437">"שורת סטטוס"</string>
     <string name="overview" msgid="3522318590458536816">"סקירה"</string>
     <string name="demo_mode" msgid="263484519766901593">"מצב הדגמה בממשק המשתמש של המערכת"</string>
-    <string name="enable_demo_mode" msgid="3180345364745966431">"הפעל מצב הדגמה"</string>
-    <string name="show_demo_mode" msgid="3677956462273059726">"הצג מצב הדגמה"</string>
+    <string name="enable_demo_mode" msgid="3180345364745966431">"הפעלת מצב הדגמה"</string>
+    <string name="show_demo_mode" msgid="3677956462273059726">"הצגת מצב הדגמה"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"אתרנט"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"התראה"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"ארנק"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"מוכן"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"פרופיל עבודה"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"מצב טיסה"</string>
-    <string name="add_tile" msgid="6239678623873086686">"הוסף אריח"</string>
+    <string name="add_tile" msgid="6239678623873086686">"הוספת אריח"</string>
     <string name="broadcast_tile" msgid="5224010633596487481">"אריח שידור"</string>
-    <string name="zen_alarm_warning_indef" msgid="5252866591716504287">"לא תשמע את ההתראה הבאה שלך <xliff:g id="WHEN">%1$s</xliff:g>, אלא אם תשבית קודם את ההגדרה הזו"</string>
-    <string name="zen_alarm_warning" msgid="7844303238486849503">"לא תשמע את ההתראה הבאה שלך <xliff:g id="WHEN">%1$s</xliff:g>"</string>
+    <string name="zen_alarm_warning_indef" msgid="5252866591716504287">"כדי לשמוע את ההתראה הבאה שלך <xliff:g id="WHEN">%1$s</xliff:g>, עליך להשבית את התכונה הזו"</string>
+    <string name="zen_alarm_warning" msgid="7844303238486849503">"לא ניתן יהיה לשמוע את ההתראה הבאה שלך <xliff:g id="WHEN">%1$s</xliff:g>"</string>
     <string name="alarm_template" msgid="2234991538018805736">"בשעה <xliff:g id="WHEN">%1$s</xliff:g>"</string>
     <string name="alarm_template_far" msgid="3561752195856839456">"ב-<xliff:g id="WHEN">%1$s</xliff:g>"</string>
     <string name="accessibility_quick_settings_detail" msgid="544463655956179791">"הגדרות מהירות, <xliff:g id="TITLE">%s</xliff:g>."</string>
@@ -678,11 +678,11 @@
     <string name="remove_from_settings" msgid="633775561782209994">"הסר מההגדרות"</string>
     <string name="remove_from_settings_prompt" msgid="551565437265615426">"‏האם להסיר את System UI Tuner ולהפסיק להשתמש בכל התכונות שלו?"</string>
     <string name="activity_not_found" msgid="8711661533828200293">"האפליקציה אינה מותקנת במכשיר"</string>
-    <string name="clock_seconds" msgid="8709189470828542071">"הצג שניות בשעון"</string>
+    <string name="clock_seconds" msgid="8709189470828542071">"הצגת שניות בשעון"</string>
     <string name="clock_seconds_desc" msgid="2415312788902144817">"הצג שניות בשעון בשורת הסטטוס. פעולה זו עשויה להשפיע על אורך חיי הסוללה."</string>
     <string name="qs_rearrange" msgid="484816665478662911">"סידור מחדש של הגדרות מהירות"</string>
     <string name="show_brightness" msgid="6700267491672470007">"הצג בהירות בהגדרות מהירות"</string>
-    <string name="experimental" msgid="3549865454812314826">"ניסיוני"</string>
+    <string name="experimental" msgid="3549865454812314826">"ניסיוניות"</string>
     <string name="enable_bluetooth_title" msgid="866883307336662596">"‏האם להפעיל את ה-Bluetooth?"</string>
     <string name="enable_bluetooth_message" msgid="6740938333772779717">"‏כדי לחבר את המקלדת לטאבלט, תחילה עליך להפעיל את ה-Bluetooth."</string>
     <string name="enable_bluetooth_confirmation_ok" msgid="2866408183324184876">"הפעלה"</string>
@@ -789,7 +789,7 @@
     <string name="battery_panel_title" msgid="5931157246673665963">"שימוש בסוללה"</string>
     <string name="battery_detail_charging_summary" msgid="8821202155297559706">"תכונת החיסכון בסוללה אינה זמינה בעת טעינת המכשיר"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"חיסכון בסוללה"</string>
-    <string name="battery_detail_switch_summary" msgid="3668748557848025990">"מפחית את רמת הביצועים ואת נתוני הרקע"</string>
+    <string name="battery_detail_switch_summary" msgid="3668748557848025990">"מפחיתה את רמת הביצועים ואת נתוני הרקע"</string>
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"לחצן <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"דף הבית"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"הקודם"</string>
@@ -884,7 +884,7 @@
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"הצג שעות, דקות ושניות"</item>
     <item msgid="1271006222031257266">"הצג שעות ודקות (ברירת מחדל)"</item>
-    <item msgid="6135970080453877218">"אל תציג את הסמל הזה"</item>
+    <item msgid="6135970080453877218">"לא להציג את הסמל הזה"</item>
   </string-array>
   <string-array name="battery_options">
     <item msgid="7714004721411852551">"הצג תמיד באחוזים"</item>
@@ -908,17 +908,19 @@
     <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"פתיחה של \'הגדרות מהירות\'."</string>
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"סגירה של \'הגדרות מהירות\'."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"הגדרת התראה."</string>
-    <string name="accessibility_quick_settings_user" msgid="505821942882668619">"מחובר בתור <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_user" msgid="505821942882668619">"בוצעה כניסה בתור <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"בחירת משתמש"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"אין אינטרנט"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"פתיחת פרטים."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"לא זמין כי <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"פתיחת הגדרות של <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"עריכת סדר ההגדרות."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"תפריט הפעלה"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"דף <xliff:g id="ID_1">%1$d</xliff:g> מתוך <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"מסך נעילה"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"הטלפון כבה עקב התחממות"</string>
     <string name="thermal_shutdown_message" msgid="6142269839066172984">"הטלפון פועל כרגיל עכשיו.\nיש להקיש כדי להציג מידע נוסף"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"הטלפון שלך התחמם יותר מדי וכבה כדי להתקרר. הטלפון פועל כרגיל עכשיו.\n\nייתכן שהטלפון יתחמם יותר מדי אם:\n	• תשתמש באפליקציות עתירות משאבים (כגון משחקים, אפליקציות וידאו או אפליקציות ניווט)\n	• תוריד או תעלה קבצים גדולים\n	• תשתמש בטלפון בטמפרטורות גבוהות"</string>
+    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"הטלפון שלך התחמם יותר מדי וכבה כדי להתקרר. הטלפון פועל כרגיל עכשיו.\n\nייתכן שהטלפון יתחמם יותר מדי אם:\n	• משתמשים באפליקציות עתירות משאבים (כגון משחקים, אפליקציות וידאו או אפליקציות ניווט)\n	• מורידים או מעלים קבצים גדולים\n	• משתמשים בטלפון בסביבה עם טמפרטורות גבוהות"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"לצפייה בשלבי הטיפול"</string>
     <string name="high_temp_title" msgid="2218333576838496100">"הטלפון מתחמם"</string>
     <string name="high_temp_notif_message" msgid="1277346543068257549">"חלק מהתכונות מוגבלות כל עוד הטלפון מתקרר.\nיש להקיש כדי להציג מידע נוסף"</string>
@@ -972,7 +974,7 @@
     <string name="mobile_data_disable_message_default_carrier" msgid="6496033312431658238">"הספק שלך"</string>
     <string name="touch_filtered_warning" msgid="8119511393338714836">"יש אפליקציה שמסתירה את בקשת ההרשאה, ולכן להגדרות אין אפשרות לאמת את התשובה."</string>
     <string name="slice_permission_title" msgid="3262615140094151017">"האם לאפשר ל-<xliff:g id="APP_0">%1$s</xliff:g> להציג חלקים מ-<xliff:g id="APP_2">%2$s</xliff:g>?"</string>
-    <string name="slice_permission_text_1" msgid="6675965177075443714">"- תהיה לה אפשרות לקרוא מידע מ-<xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="slice_permission_text_1" msgid="6675965177075443714">"- תהיה לה אפשרות לקרוא מידע מאפליקציית <xliff:g id="APP">%1$s</xliff:g>"</string>
     <string name="slice_permission_text_2" msgid="6758906940360746983">"- תהיה לה יכולת לנקוט פעולה בתוך <xliff:g id="APP">%1$s</xliff:g>"</string>
     <string name="slice_permission_checkbox" msgid="4242888137592298523">"יש לאשר ל-<xliff:g id="APP">%1$s</xliff:g> להראות חלקים מכל אפליציה שהיא"</string>
     <string name="slice_permission_allow" msgid="6340449521277951123">"אני רוצה לאשר"</string>
@@ -1021,9 +1023,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"הזזה שמאלה"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"הזזה ימינה"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"מעבר למצב הגדלה"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"הגדלת כל המסך"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"הגדלה של המסך המלא"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"הגדלת חלק מהמסך"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"מעבר"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"לחצן הנגישות החליף את תנועת הנגישות\n\n"<annotation id="link">"להצגת ההגדרות"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"כדי להסתיר זמנית את הלחצן, יש להזיז אותו לקצה"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"פקדי מכשירים"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"יש להוסיף פקדים למכשירים המחוברים"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"הגדרה של פקדי מכשירים"</string>
@@ -1040,7 +1044,7 @@
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"סומן כהעדפה, במיקום <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"הוסר מהמועדפים"</string>
     <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"להוסיף למועדפים"</string>
-    <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"להוסיף למועדפים"</string>
+    <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"להסיר מהמועדפים"</string>
     <string name="accessibility_control_move" msgid="8980344493796647792">"העברה למיקום <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="controls_favorite_default_title" msgid="967742178688938137">"פקדים"</string>
     <string name="controls_favorite_subtitle" msgid="6604402232298443956">"יש לבחור פקדים לגישה מתפריט ההפעלה"</string>
@@ -1093,6 +1097,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"התאמה של מכשיר חדש"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"ווידג\'טים של שיחות"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"יש להקיש על שיחה כדי להוסיף אותה למסך הבית"</string>
+    <string name="timestamp" msgid="6577851592534538533">"לפני <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"לפני פחות מ-<xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"לפני יותר מ-<xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"יום הולדת"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"יום הולדת יחול בקרוב"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"יום השנה"</string>
+    <string name="location_status" msgid="1294990572202541812">"המיקום משותף"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"סטורי חדש"</string>
+    <string name="video_status" msgid="4548544654316843225">"צפייה"</string>
+    <string name="audio_status" msgid="4237055636967709208">"מתבצעת האזנה"</string>
+    <string name="game_status" msgid="1340694320630973259">"במשחק פעיל"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"חברים"</string>
+    <string name="empty_status" msgid="5938893404951307749">"אפשר לצ\'וטט הערב!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"שיחה שלא נענתה"</string>
+    <string name="people_tile_description" msgid="8154966188085545556">"ההודעות האחרונות, שיחות שלא נענו ועדכוני סטטוס"</string>
+    <string name="people_tile_title" msgid="6589377493334871272">"שיחה"</string>
     <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"בעיה בקריאת מדדי הסוללה"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"יש להקיש כדי להציג מידע נוסף"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"לא הוגדרה התראה"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 802e160..44fed70 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"キャンセル"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"共有"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"画面の録画をキャンセルしました"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"画面の録画を保存しました"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"タップすると表示されます"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"画面の録画の削除中にエラーが発生しました"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"権限を取得できませんでした"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"画面の録画中にエラーが発生しました"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"新しいユーザー"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"インターネット"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"機内モードで利用可能"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"ネットワークが利用できます"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"ネットワークは利用できません"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"接続されていません"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"日の出まで"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g>にオン"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g>まで"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"明るさを下げる"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC は無効です"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC は有効です"</string>
@@ -470,7 +466,6 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"プロファイルを表示"</string>
     <string name="user_add_user" msgid="4336657383006913022">"ユーザーを追加"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"新しいユーザー"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"ゲスト セッションを終了する"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"ゲストを削除しますか?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"このセッションでのアプリとデータはすべて削除されます。"</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"削除"</string>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"このデバイスは保護者によって管理されています"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"これは組織が所有するデバイスで、ネットワーク トラフィックが監視されることもあります"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"これは <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> が所有するデバイスで、ネットワーク トラフィックが監視されることもあります"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"このデバイスは <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> から提供されています"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"これは組織が所有するデバイスで、<xliff:g id="VPN_APP">%1$s</xliff:g> に接続しています"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"これは <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> が所有するデバイスで、<xliff:g id="VPN_APP">%2$s</xliff:g> に接続しています"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"これは組織が所有するデバイスです"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"この仕事用プロファイルは <xliff:g id="VPN_APP">%1$s</xliff:g> に接続しています"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"この個人用プロファイルは <xliff:g id="VPN_APP">%1$s</xliff:g> に接続しています"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"このデバイスは <xliff:g id="VPN_APP">%1$s</xliff:g> に接続しています"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"このデバイスは <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> から提供されています"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"デバイス管理"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"プロファイルの監視"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"ネットワーク監視"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"ポリシーを見る"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"使用制限を表示"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"これは <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> が所有するデバイスです。\n\nIT 管理者が、このデバイスに関連付けられている設定、コーポレート アクセス、アプリ、データのほか、デバイスの位置情報を監視、管理できます。\n\n詳しくは、IT 管理者にお問い合わせください。"</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> がこのデバイスに関連するデータにアクセスし、アプリを管理し、デバイスの設定を変更できる可能性があります。\n\nご不明な点がある場合は、<xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g> にお問い合わせください。"</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"これは組織が所有するデバイスです。\n\nIT 管理者が、このデバイスに関連付けられている設定、コーポレート アクセス、アプリ、データのほか、デバイスの位置情報を監視、管理できます。\n\n詳しくは、IT 管理者にお問い合わせください。"</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"組織によってこのデバイスに認証局がインストールされました。保護されたネットワーク トラフィックが監視、変更される場合があります。"</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"組織によって、あなたの仕事用プロファイルに認証局がインストールされました。保護されたネットワーク トラフィックが監視、変更される場合があります。"</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"デモモードを表示"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"イーサネット"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"アラーム"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"ウォレット"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"準備完了"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"仕事用プロファイル"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"機内モード"</string>
     <string name="add_tile" msgid="6239678623873086686">"タイルを追加"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"クイック設定を閉じます。"</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"アラームを設定しました。"</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"<xliff:g id="ID_1">%s</xliff:g> としてログインします"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"ユーザーを選択"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"インターネットに接続されていません"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"詳細情報を開きます。"</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"利用できない理由: <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> の設定を開きます。"</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"設定の順序を編集します。"</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"電源ボタン メニュー"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"ページ <xliff:g id="ID_1">%1$d</xliff:g>/<xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"ロック画面"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"高熱で電源が OFF になりました"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"左に移動"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"右に移動"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"拡大スイッチ"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"画面全体を拡大します"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"画面全体を拡大します"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"画面の一部を拡大します"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"スイッチ"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"ユーザー補助ジェスチャーに代わって、ユーザー補助機能ボタンが導入されました\n\n"<annotation id="link">"設定を表示"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"ボタンを一時的に非表示にするには端に移動させてください"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"デバイス コントロール"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"接続済みデバイスのコントロールを追加します"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"デバイス コントロールの設定"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"新しいデバイスとのペア設定"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"会話ウィジェット"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"会話をタップするとホーム画面に追加されます"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g>前"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"<xliff:g id="DURATION">%1$s</xliff:g>前まで"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"<xliff:g id="DURATION">%1$s</xliff:g>以上前"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"誕生日"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"もうすぐ誕生日"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"記念日"</string>
+    <string name="location_status" msgid="1294990572202541812">"現在地を共有中"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"新しいストーリー"</string>
+    <string name="video_status" msgid="4548544654316843225">"視聴中"</string>
+    <string name="audio_status" msgid="4237055636967709208">"再生中"</string>
+    <string name="game_status" msgid="1340694320630973259">"プレイ中"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"友だち"</string>
+    <string name="empty_status" msgid="5938893404951307749">"今夜、チャットしよう"</string>
+    <string name="missed_call" msgid="4228016077700161689">"不在着信"</string>
+    <string name="people_tile_description" msgid="8154966188085545556">"最近のメッセージ、不在着信、最新のステータスが表示されます"</string>
+    <string name="people_tile_title" msgid="6589377493334871272">"会話"</string>
     <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"電池残量の読み込み中に問題が発生しました"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"タップすると詳細が表示されます"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"アラーム未設定"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 53cf03e..cbed6a8 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"გაუქმება"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"გაზიარება"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"ეკრანის ჩაწერა გაუქმდა"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"ეკრანის ჩაწერა შეინახა"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"შეეხეთ სანახავად"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"ეკრანის ჩანაწერის წაშლისას წარმოიშვა შეცდომა"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"ნებართვების მიღება ვერ მოხერხდა"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"ეკრანის ჩაწერის დაწყებისას წარმოიქმნა შეცდომა"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"ახალი მომხმარებელი"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"ინტერნეტი"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"თვითმფრინავისთვის უსაფრთხო"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"ქსელები ხელმისაწვდომია"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"ქსელები მიუწვდომელია"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"არ არის დაკავშირებული."</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"მზის ამოსვლამდე"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"ჩაირთოს <xliff:g id="TIME">%s</xliff:g>-ზე"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g>-მდე"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"სიკაშკაშის შემცირება"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC გათიშულია"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC ჩართულია"</string>
@@ -470,7 +466,6 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"პროფილის ჩვენება"</string>
     <string name="user_add_user" msgid="4336657383006913022">"მომხმარებლის დამატება"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"ახალი მომხმარებელი"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"სტუმრის სესიის დასრულება"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"სტუმრის ამოშლა?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ამ სესიის ყველა აპი და მონაცემი წაიშლება."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"ამოშლა"</string>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"მოწყობილობას თქვენი მშობელი მართავს"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ამ მოწყობილობას ფლობს თქვენი ორგანიზაცია და მას ქსელის ტრაფიკის მონიტორინგი შეუძლია"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"ამ მოწყობილობას ფლობს <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> და მას ქსელის ტრაფიკის მონიტორინგი შეუძლია"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"ამ მოწყობილობის მომწოდებელია <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"ამ მოწყობილობას ფლობს თქვენი ორგანიზაცია და ის დაკავშირებულია <xliff:g id="VPN_APP">%1$s</xliff:g>-თან"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"ამ მოწყობილობას ფლობს <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> და ის დაკავშირებულია <xliff:g id="VPN_APP">%2$s</xliff:g>-თან"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"ამ მოწყობილობას ფლობს თქვენი ორგანიზაცია"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"თქვენი სამსახურის პროფილი დაკავშირებულია <xliff:g id="VPN_APP">%1$s</xliff:g>-თან"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"თქვენი პერსონალური პროფილი დაკავშირებულია <xliff:g id="VPN_APP">%1$s</xliff:g>-თან"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"ეს მოწყობილობა დაკავშირებულია <xliff:g id="VPN_APP">%1$s</xliff:g>-თან"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"ამ მოწყობილობის მომწოდებელია <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"მოწყობილობის მართვა"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"პროფილის მონიტორინგი"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"ქსელის მონიტორინგი"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"წესების ნახვა"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"მართვის საშუალებების ნახვა"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"ეს მოწყობილობას ფლობს <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nთქვენს IT ადმინისტრატორს შეუძლია მოწყობილობასთან დაკავშირებული პარამეტრების, კორპორაციული წვდომის, აპებისა და მონაცემების (მათ შორის, თქვენი მოწყობილობის მდებარეობის ინფორმაციის) მონიტორინგი და მართვა.\n\nდამატებითი ინფორმაციისთვის დაუკავშირდით თქვენს IT ადმინისტრატორს."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g>-მა შეიძლება მოახერხოს ამ მოწყობილობასთან დაკავშირებულ მონაცემებზე წვდომა, მართოს აპები და შეცვალოს ამ მოწყობილობის პარამეტრები.\n\nთუ გაქვთ შეკითხვები, დაუკავშირდით <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>-ს."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"ამ მოწყობილობას ფლობს თქვენი ორგანიზაცია.\n\nთქვენს IT ადმინისტრატორს შეუძლია მოწყობილობასთან დაკავშირებული პარამეტრების, კორპორაციული წვდომის, აპებისა და მონაცემების (მათ შორის, თქვენი მოწყობილობის მდებარეობის ინფორმაციის) მონიტორინგი და მართვა.\n\nდამატებითი ინფორმაციისთვის დაუკავშირდით თქვენს IT ადმინისტრატორს."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"თქვენმა ორგანიზაციამ ამ მოწყობილობაზე სერტიფიცირების ორგანო დააინსტალირა. თქვენი ქსელის დაცული ტრაფიკი შეიძლება შეიცვალოს, ან მასზე მონიტორინგი განხორციელდეს."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"თქვენმა ორგანიზაციამ სამსახურის პროფილში სერტიფიცირების ორგანო დააინსტალირა. თქვენი ქსელის დაცული ტრაფიკი შეიძლება შეიცვალოს, ან მასზე მონიტორინგი განხორციელდეს."</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"დემო-რეჟიმის ჩვენება"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"ეთერნეტი"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"მაღვიძარა"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"მზადაა"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"სამსახურის პროფილი"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"თვითმფრინავის რეჟიმი"</string>
     <string name="add_tile" msgid="6239678623873086686">"მოზაიკის დამატება"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"სწრაფი პარამეტრების დახურვა."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"მაღვიძარა დაყენებულია."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"შესული ხართ, როგორც <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"მომხმარებლის არჩევა"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"ინტერნეტ-კავშირი არ არის"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"დეტალების გახსნა."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"მიუწვდომელია, რადგან <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> პარამეტრების გახსნა."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"პარამეტრების მიმდევრობის რედაქტირება."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"ჩართვის მენიუ"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"გვერდი <xliff:g id="ID_1">%1$d</xliff:g> / <xliff:g id="ID_2">%2$d</xliff:g>-დან"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"ჩაკეტილი ეკრანი"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"ტელეფონი გამოირთო გაცხელების გამო"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"მარცხნივ გადატანა"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"მარჯვნივ გადატანა"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"გადიდების გადართვა"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"მთლიანი ეკრანის გადიდება"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"გაადიდეთ სრულ ეკრანზე"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"ეკრანის ნაწილის გადიდება"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"გადართვა"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"მარტივი წვდომის ღილაკმა ჩაანაცვლა მარტივი წვდომის ჟესტი\n\n"<annotation id="link">"პარამეტრების ნახვა"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"გადაიტანეთ ღილაკი კიდეში, რათა დროებით დამალოთ ის"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"მოწყობილ. მართვის საშუალებები"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"მართვის საშუალებების დამატება თქვენს დაკავშირებულ მოწყობილობებზე"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"მოწყობილობის მართვის საშუალებების დაყენება"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"ახალი მოწყობილობის დაწყვილება"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"საუბრის ვიჯეტები"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"შეეხეთ საუბარს მის თქვენს მთავარ ეკრანზე დასამატებლად"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g>-ს წინ"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"<xliff:g id="DURATION">%1$s</xliff:g>-ზე ნაკლები ხნის წინ"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"<xliff:g id="DURATION">%1$s</xliff:g>-ზე მეტი ხნის წინ"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"დაბადების დღე"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"მალე დაბადების დღეა"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"იუბილე"</string>
+    <string name="location_status" msgid="1294990572202541812">"მდებარეობა ზიარდება"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"ახალი ამბავი"</string>
+    <string name="video_status" msgid="4548544654316843225">"უყურებს"</string>
+    <string name="audio_status" msgid="4237055636967709208">"მიმდინარეობს მოსმენა"</string>
+    <string name="game_status" msgid="1340694320630973259">"იკვრება"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"მეგობრები"</string>
+    <string name="empty_status" msgid="5938893404951307749">"მოდით, ვისაუბროთ ამაღამ!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"გამოტოვებული ზარი"</string>
+    <string name="people_tile_description" msgid="8154966188085545556">"ბოლოდროინდელი შეტყობინებების, გამოტოვებული ზარების და სტატუსის განახლებების ნახვა"</string>
+    <string name="people_tile_title" msgid="6589377493334871272">"მიმოწერა"</string>
     <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"თქვენი ბატარეის მზომის წაკითხვასთან დაკავშირებით პრობლემა დაფიქსირდა"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"შეეხეთ მეტი ინფორმაციისთვის"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"მაღვიძარა არ არის"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 6851942..20a326f 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Бас тарту"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Бөлісу"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Экранды бейнеге жазудан бас тартылды"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Экран жазғыш бейнесі сақталды."</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Көру үшін түртіңіз."</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Экран бейне жазбасын жою кезінде қате кетті"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Рұқсаттар алынбады"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Экрандағы бейнені жазу кезінде қате шықты."</string>
@@ -259,8 +257,8 @@
     <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_dnd_changed_off" msgid="1457150026842505799">"\"Мазаламау\" режимі өшірілді."</string>
-    <string name="accessibility_quick_settings_dnd_changed_on" msgid="186315911607486129">"\"Мазаламау\" режимі қосылды."</string>
+    <string name="accessibility_quick_settings_dnd_changed_off" msgid="1457150026842505799">"Мазаламау режимі өшірілді."</string>
+    <string name="accessibility_quick_settings_dnd_changed_on" msgid="186315911607486129">"Мазаламау режимі қосылды."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
     <string name="accessibility_quick_settings_bluetooth_off" msgid="3795983516942423240">"Bluetooth өшірулі."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth қосулы."</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Жаңа пайдаланушы"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Интернет"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Ұшақта пайдалануға болатын"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Желілер қолжетімді."</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Желілер қолжетімді емес."</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Жалғанбаған"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Күн шыққанға дейін"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Қосылу уақыты: <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> дейін"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Жарықтығын азайту"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC өшірулі"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC қосулы"</string>
@@ -470,11 +466,10 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Профильді көрсету"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Пайдаланушы қосу"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Жаңа пайдаланушы"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Қонақ сеансын аяқтау"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Қонақты жою керек пе?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Осы сеанстағы барлық қолданбалар мен деректер жойылады."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Алып тастау"</string>
-    <string name="guest_wipe_session_title" msgid="7147965814683990944">"Қош келдіңіз, қонақ"</string>
+    <string name="guest_wipe_session_title" msgid="7147965814683990944">"Қош келдіңіз, қонақ!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Сеансты жалғастыру керек пе?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Қайта бастау"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Иә, жалғастыру"</string>
@@ -510,7 +505,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="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="profile_owned_footer" msgid="2756770645766113964">"Профиль бақылануы мүмкін"</string>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Бұл құрылғыны ата-анаңыз басқарады."</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Ұйымыңыз осы құрылғыны басқарады және желі трафигін бақылауы мүмкін."</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> осы құрылғыны басқарады және желі трафигін бақылауы мүмкін."</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Бұл құрылғыны <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ұсынады."</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Бұл құрылғы ұйымыңызға тиесілі және <xliff:g id="VPN_APP">%1$s</xliff:g> қолданбасына қосылған."</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Бұл құрылғы <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ұйымына тиесілі және <xliff:g id="VPN_APP">%2$s</xliff:g> қолданбасына қосылған."</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Бұл құрылғы ұйымыңызға тиесілі."</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Жұмыс профиліңіз <xliff:g id="VPN_APP">%1$s</xliff:g> қолданбасына қосылған."</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Жеке профиліңіз <xliff:g id="VPN_APP">%1$s</xliff:g> қолданбасына қосылған."</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Бұл құрылғы <xliff:g id="VPN_APP">%1$s</xliff:g> қолданбасына қосылған."</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Бұл құрылғыны <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ұсынады"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Құрылғыны басқару"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Профильді бақылау"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Желіні бақылау"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Саясаттарды көру"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Басқару элементтерін көру"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Бұл құрылғы <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ұйымына тиесілі.\n\nӘкімші параметрлерді, корпоративтік кіру құқығын, қолданбаларды, құрылғыңызбен байланысты деректерді және құрылғыңыздың орналасқан жері туралы ақпаратты бақылай және басқара алады.\n\nҚосымша ақпарат алу үшін әкімшіге хабарласыңыз."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> осы құрылғымен байланыстырылған деректерді пайдалана, қолданбаларды басқара және құрылғы параметрлерін өзгерте алады.\n\nСұрақтарыңыз болса, <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g> ұйымына хабарласыңыз."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Бұл құрылғы ұйымыңызға тиесілі.\n\nӘкімші параметрлерді, корпоративтік кіру құқығын, қолданбаларды, құрылғыңызбен байланысты деректерді және құрылғыңыздың орналасқан жері туралы ақпаратты бақылай және басқара алады.\n\nҚосымша ақпарат алу үшін әкімшіге хабарласыңыз."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Ұйымыңыз осы құрылғыда сертификат орнатқан. Қорғалған желі трафигіңіз бақылануы немесе өзгертілуі мүмкін."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Ұйымыңыз жұмыс профиліңізде сертификат орнатқан. Қорғалған желі трафигіңіз бақылануы немесе өзгертілуі мүмкін."</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Демо режимін көрсету"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Дабыл"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Әмиян"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Дайын"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Жұмыс профилі"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Ұшақ режимі"</string>
     <string name="add_tile" msgid="6239678623873086686">"Тақтайша қосу"</string>
@@ -825,7 +825,7 @@
     <string name="tuner_full_zen_title" msgid="5120366354224404511">"Дыбыс деңгейін басқару элементтерімен бірге көрсету"</string>
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Мазаламау"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Дыбыс деңгейі түймелерінің төте жолы"</string>
-    <string name="volume_up_silent" msgid="1035180298885717790">"Дыбысы арттырылған кезде, \"Мазаламау\" режимінен шығу"</string>
+    <string name="volume_up_silent" msgid="1035180298885717790">"Дыбысы арттырылған кезде, Мазаламау режимінен шығу"</string>
     <string name="battery" msgid="769686279459897127">"Батарея"</string>
     <string name="clock" msgid="8978017607326790204">"Сағат"</string>
     <string name="headset" msgid="4485892374984466437">"Құлақаспап жинағы"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Жылдам параметрлерді жабу."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Дабыл орнатылды."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"<xliff:g id="ID_1">%s</xliff:g> ретінде кірдіңіз"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"пайдаланушыны таңдаңыз"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Интернетпен байланыс жоқ"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Мәліметтерді ашу."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"Қолжетімді емес, өйткені <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> параметрлерін ашу."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Параметрлер тәртібін өзгерту."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Қуат мәзірі"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g> ішінен <xliff:g id="ID_1">%1$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Құлыпталған экран"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"Телефон қызып кеткендіктен өшірілді"</string>
@@ -948,10 +950,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="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="qs_dnd_until" msgid="7844269319043747955">"<xliff:g id="ID_1">%s</xliff:g> дейін"</string>
     <string name="qs_dnd_keep" msgid="3829697305432866434">"Қалсын"</string>
     <string name="qs_dnd_replace" msgid="7712119051407052689">"Ауыстыру"</string>
@@ -999,7 +1001,7 @@
     <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Әңгімелер бөлімінің жоғарғы жағында көрсетіледі."</string>
     <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Профиль суреті құлыптаулы экранда көрсетіледі."</string>
     <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Қолданбалар терезесінің бергі жағынан қалқыма хабарлар түрінде көрсетіледі."</string>
-    <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"\"Мазаламау\" режимінде көрсетіледі."</string>
+    <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Мазаламау режимінде көрсетіледі."</string>
     <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Түсінікті"</string>
     <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Параметрлер"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Ұлғайту терезесі"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Солға жылжыту"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Оңға жылжыту"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Ұлғайту режиміне ауыстырғыш"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Толық экранды ұлғайту"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Толық экранды ұлғайту"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Экранның бөлігін ұлғайту"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Ауысу"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"\"Арнайы мүмкіндіктер\" түймесінің орнына арнайы мүмкіндіктер қимылы болады.\n\n"<annotation id="link">"Параметрлерді көру"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Түймені уақытша жасыру үшін оны шетке қарай жылжытыңыз."</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Құрылғыны басқару элементтері"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Жалғанған құрылғылар үшін басқару виджеттерін қосу"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Құрылғыны басқару элементтерін реттеу"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Жаңа құрылғымен жұптау"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Әңгіме виджеттері"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Негізгі экранға қосқыңыз келетін әңгімені түртіңіз."</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> бұрын"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"Максимум <xliff:g id="DURATION">%1$s</xliff:g> бұрын"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"Кемінде <xliff:g id="DURATION">%1$s</xliff:g> бұрын"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Туған күн"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Жақында туған күн"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Мерейтой"</string>
+    <string name="location_status" msgid="1294990572202541812">"Геодеректер жіберілуде"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Жаңа сюжет"</string>
+    <string name="video_status" msgid="4548544654316843225">"Көрілуде"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Тыңдалуда"</string>
+    <string name="game_status" msgid="1340694320630973259">"Ойнатылуда"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Достар"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Кешке чатта сөйлесейік!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"Өткізіп алған қоңырау"</string>
+    <string name="people_tile_description" msgid="8154966188085545556">"Соңғы хабарларды, өткізіп алған қоңыраулар мен жаңартылған күйлерді көруге болады."</string>
+    <string name="people_tile_title" msgid="6589377493334871272">"Әңгіме"</string>
     <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Батарея зарядының дерегі алынбай жатыр"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Толығырақ ақпарат алу үшін түртіңіз."</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Ешқандай оятқыш орнатылмаған."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index d7faeec..93715e2 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"បោះបង់"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"ចែករំលែក"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"បាន​បោះបង់​ការថត​សកម្មភាព​អេក្រង់"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"បានរក្សាទុក​ការថតវីដេអូអេក្រង់"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"ចុចដើម្បីមើល"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"មានបញ្ហា​ក្នុងការ​លុបការថត​សកម្មភាព​អេក្រង់"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"មិនអាច​ទទួលបាន​ការអនុញ្ញាត​ទេ"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"មានបញ្ហា​ក្នុងការ​ចាប់ផ្ដើម​ថត​អេក្រង់"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"អ្នកប្រើ​ថ្មី"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"អ៊ីនធឺណិត"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"សុវត្ថិភាព​ពេលជិះ​យន្តហោះ"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"បណ្ដាញ​ដែលអាច​ប្រើបាន"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"​មិនអាចប្រើ​បណ្តាញ​បានទេ"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"មិន​បាន​តភ្ជាប់"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"រហូត​ដល់​ពេល​ថ្ងៃរះ"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"បើកនៅម៉ោង <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"រហូតដល់ម៉ោង <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"បន្ថយ​ពន្លឺ"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"បាន​បិទ NFC"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"បាន​បើក NFC"</string>
@@ -468,24 +464,23 @@
     <string name="accessibility_multi_user_switch_switcher_with_current" msgid="5759855008166759399">"ប្ដូរ​អ្នកប្រើ ​អ្នកប្រើ​បច្ចុប្បន្ន <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
     <string name="accessibility_multi_user_switch_inactive" msgid="383168614528618402">"អ្នកប្រើបច្ចុប្បន្ន <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"បង្ហាញ​ប្រវត្តិរូប"</string>
-    <string name="user_add_user" msgid="4336657383006913022">"បន្ថែម​អ្នកប្រើ"</string>
+    <string name="user_add_user" msgid="4336657383006913022">"បញ្ចូល​អ្នកប្រើ"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"អ្នកប្រើ​ថ្មី"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"បញ្ចប់វគ្គភ្ញៀវ"</string>
-    <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"លុប​ភ្ញៀវ​?"</string>
-    <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ទិន្នន័យ និង​កម្មវិធី​ទាំងអស់​ក្នុង​សម័យ​នេះ​នឹង​ត្រូវ​បាន​លុប។"</string>
-    <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"លុបចេញ"</string>
+    <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"ដកភ្ញៀវចេញឬ?"</string>
+    <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"កម្មវិធី និងទិន្នន័យ​ទាំងអស់​ក្នុង​វគ្គ​នេះ​នឹង​ត្រូវ​លុប។"</string>
+    <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"ដកចេញ"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"សូម​ស្វាគមន៍​ការ​ត្រឡប់​មកវិញ, ភ្ញៀវ!"</string>
-    <string name="guest_wipe_session_message" msgid="3393823610257065457">"តើ​អ្នក​ចង់​បន្ត​សម័យ​របស់​អ្នក​?"</string>
-    <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ចាប់ផ្ដើម"</string>
+    <string name="guest_wipe_session_message" msgid="3393823610257065457">"តើ​អ្នក​ចង់​បន្ត​វគ្គ​របស់​អ្នក​ទេ?"</string>
+    <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ចាប់ផ្ដើមសាជាថ្មី"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"បាទ​/ចាស ​បន្ត"</string>
     <string name="guest_notification_title" msgid="4434456703930764167">"អ្នកប្រើភ្ញៀវ"</string>
     <string name="guest_notification_text" msgid="4202692942089571351">"ដើម្បីលុបកម្មវិធី និងទិន្នន័យ សូមយកអ្នកប្រើជាភ្ញៀវចេញ"</string>
-    <string name="guest_notification_remove_action" msgid="4153019027696868099">"យកភ្ញៀវចេញ"</string>
+    <string name="guest_notification_remove_action" msgid="4153019027696868099">"ដកភ្ញៀវចេញ"</string>
     <string name="user_logout_notification_title" msgid="3644848998053832589">"ចុះឈ្មោះអ្នកប្រើចេញ"</string>
     <string name="user_logout_notification_text" msgid="7441286737342997991">"ចុះឈ្មោះអ្នកប្រើបច្ចុប្បន្នចេញ"</string>
     <string name="user_logout_notification_action" msgid="7974458760719361881">"ចុះឈ្មោះអ្នកប្រើចេញ"</string>
-    <string name="user_add_user_title" msgid="4172327541504825032">"បន្ថែម​អ្នកប្រើ​ថ្មី?"</string>
-    <string name="user_add_user_message_short" msgid="2599370307878014791">"ពេល​អ្នក​បន្ថែម​អ្នកប្រើ​ថ្មី អ្នកប្រើ​នោះ​ត្រូវ​កំណត់​ទំហំ​ផ្ទាល់​របស់​គេ។\n\nអ្នក​ប្រើ​ណាមួយ​ក៏​អាច​ធ្វើ​បច្ចុប្បន្នភាព​កម្មវិធី​សម្រាប់​អ្នកប្រើ​ផ្សេង​បាន​ដែរ។"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"បញ្ចូល​អ្នកប្រើ​ថ្មីឬ?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"នៅពេល​អ្នក​បញ្ចូល​អ្នកប្រើ​ថ្មី អ្នកប្រើ​នោះ​ត្រូវ​រៀបចំកន្លែងរបស់​គេ។\n\nអ្នក​ប្រើ​ណា​ក៏​អាច​ដំឡើងកំណែ​កម្មវិធី​សម្រាប់​អ្នកប្រើទាំងអស់ផ្សេងទៀត​បាន​ដែរ។"</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"​បាន​ឈាន​ដល់ចំនួន​កំណត់អ្នកប្រើប្រាស់"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">អ្នកអាចបញ្ចូល​អ្នក​ប្រើប្រាស់បាន​រហូតដល់ <xliff:g id="COUNT">%d</xliff:g> នាក់។</item>
@@ -493,7 +488,7 @@
     </plurals>
     <string name="user_remove_user_title" msgid="9124124694835811874">"យកអ្នកប្រើចេញ?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"កម្មវិធី និងទិន្នន័យទាំងអស់របស់អ្នកប្រើនេះនឹងត្រូវបានលុប។"</string>
-    <string name="user_remove_user_remove" msgid="8387386066949061256">"យកចេញ"</string>
+    <string name="user_remove_user_remove" msgid="8387386066949061256">"ដកចេញ"</string>
     <string name="battery_saver_notification_title" msgid="8419266546034372562">"មុខងារ​សន្សំ​ថ្មបានបើក"</string>
     <string name="battery_saver_notification_text" msgid="2617841636449016951">"ការ​បន្ថយ​ការ​ប្រតិបត្តិ និង​ទិន្នន័យ​ផ្ទៃ​ខាងក្រោយ"</string>
     <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"បិទ​មុខងារ​សន្សំ​ថ្ម"</string>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ឧបករណ៍​នេះ​ស្ថិត​ក្រោម​ការ​គ្រប់គ្រង​របស់មាតាបិតាអ្នក"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ស្ថាប័ន​របស់អ្នក​ជាម្ចាស់​ឧបករណ៍​នេះ ហើយ​អាចនឹង​តាមដាន​ចរាចរណ៍បណ្តាញ"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ជាម្ចាស់​ឧបករណ៍​នេះ ហើយ​អាចនឹង​តាមដាន​ចរាចរណ៍​បណ្តាញ"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"ឧបករណ៍នេះត្រូវបានផ្ដល់ដោយ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"ឧបករណ៍​នេះគឺជា​កម្មសិទ្ធិរបស់​ស្ថាប័នអ្នក និងត្រូវបានភ្ជាប់ទៅ <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"ឧបករណ៍​នេះគឺជា​កម្មសិទ្ធិរបស់ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> និងត្រូវបានភ្ជាប់ទៅ <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"ឧបករណ៍​នេះគឺជា​កម្មសិទ្ធិរបស់​ស្ថាប័ន​អ្នក"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"កម្រងព័ត៌មានការងារ​របស់អ្នក​ត្រូវបានភ្ជាប់ទៅ <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"កម្រងព័ត៌មាន​ផ្ទាល់ខ្លួន​របស់អ្នក​ត្រូវបានភ្ជាប់ទៅ <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"ឧបករណ៍នេះ​ត្រូវបានភ្ជាប់ទៅ <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"ឧបករណ៍នេះត្រូវបានផ្ដល់ដោយ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"ការ​គ្រប់គ្រង​ឧបករណ៍"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"តាមដានប្រវត្ថិរូប"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"ការ​ត្រួតពិនិត្យ​បណ្ដាញ"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"មើល​គោលការណ៍"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"មើលការគ្រប់គ្រង"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"ឧបករណ៍នេះ​ជាគឺកម្មសិទ្ធិ​របស់ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>។\n\nអ្នកគ្រប់គ្រង​ផ្នែកព័ត៌មានវិទ្យា​របស់អ្នក​អាចតាមដាន និងគ្រប់គ្រង​ការកំណត់ ការចូលប្រើជាលក្ខណៈក្រុមហ៊ុន កម្មវិធី ទិន្នន័យដែលពាក់ព័ន្ធ​នឹង​ឧបករណ៍​របស់អ្នក និងព័ត៌មាន​ទីតាំង​របស់​ឧបករណ៍​អ្នក។\n\nសម្រាប់​ព័ត៌មាន​បន្ថែម សូម​ទាក់ទង​អ្នកគ្រប់គ្រង​ផ្នែកព័ត៌មានវិទ្យា​របស់អ្នក។"</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> ប្រហែលជាអាច​ចូលប្រើ​ទិន្នន័យដែល​ពាក់ព័ន្ធនឹង​ឧបករណ៍នេះ គ្រប់គ្រងកម្មវិធី និងប្ដូរ​ការកំណត់​ឧបករណ៍នេះ។\n\nប្រសិនបើអ្នក​មានសំណួរ សូមទាក់ទង <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>។"</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"ឧបករណ៍នេះ​គឺជាកម្មសិទ្ធិ​របស់ស្ថាប័នអ្នក។\n\nអ្នកគ្រប់គ្រង​ផ្នែកព័ត៌មានវិទ្យា​របស់អ្នក​អាចតាមដាន និងគ្រប់គ្រង​ការកំណត់ ការចូលប្រើជាលក្ខណៈក្រុមហ៊ុន កម្មវិធី ទិន្នន័យដែលពាក់ព័ន្ធ​នឹង​ឧបករណ៍​របស់អ្នក និងព័ត៌មាន​ទីតាំង​របស់ឧបករណ៍​អ្នក។\n\nសម្រាប់​ព័ត៌មាន​បន្ថែម សូម​ទាក់ទង​អ្នកគ្រប់គ្រង​ផ្នែកព័ត៌មានវិទ្យា​របស់អ្នក។"</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"ស្ថាប័ន​របស់អ្នក​បានដំឡើង​អាជ្ញាធរវិញ្ញាបនបត្រនៅលើ​ឧបករណ៍​នេះ។ ចរាចរណ៍​បណ្តាញដែលមាន​សុវត្ថិភាព​របស់អ្នក​អាច​ត្រូវបាន​តាមដាន ឬ​កែសម្រួល។"</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"ស្ថាប័នរបស់អ្នក​បានដំឡើង​អាជ្ញាធរវិញ្ញាបនបត្រ​នៅក្នុង​កម្រងព័ត៌មាន​ការងារ។ ចរាចរណ៍​បណ្តាញដែលមាន​សុវត្ថិភាព​របស់អ្នក​អាច​ត្រូវបាន​តាមដាន ឬ​កែសម្រួល។"</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"បង្ហាញរបៀបសាកល្បង"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"អ៊ីសឺរណិត"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"ម៉ោងរោទ៍"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"កាបូប"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"រួចរាល់"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"ប្រវត្តិរូបការងារ"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"របៀបក្នុងយន្តហោះ"</string>
     <string name="add_tile" msgid="6239678623873086686">"បន្ថែមក្រឡាល្អិត"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"បិទការកំណត់រហ័ស"</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"បានកំណត់ម៉ោងរោទិ៍"</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"បានចូលជា <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"ជ្រើសរើស​អ្នកប្រើប្រាស់"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"គ្មាន​អ៊ីនធឺណិតទេ"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"បើកព័ត៌មានលម្អិត"</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"មិនអាច​ប្រើបានទេ ដោយសារ <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"បើការកំណត់ <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"កែលំដាប់ការកំណត់"</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"ម៉ឺនុយ​ថាមពល"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"ទំព័រ <xliff:g id="ID_1">%1$d</xliff:g> នៃ <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"អេក្រង់​ចាក់សោ"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"ទូរសព្ទ​បាន​បិទដោយសារ​វា​ឡើងកម្តៅ"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"ផ្លាស់ទី​ទៅ​ឆ្វេង"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"ផ្លាស់ទីទៅ​ស្តាំ"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"ប៊ូតុងបិទបើកការ​ពង្រីក"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"ពង្រីក​អេក្រង់​ទាំងមូល"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"ពង្រីក​ពេញអេក្រង់"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"ពង្រីក​ផ្នែកនៃ​អេក្រង់"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"ប៊ូតុងបិទបើក"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"ប៊ូតុង​ភាពងាយស្រួល​បានជំនួស​ចលនាភាពងាយស្រួល\n\n"<annotation id="link">"មើល​ការកំណត់"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"ផ្លាស់ទី​ប៊ូតុង​ទៅគែម ដើម្បីលាក់វា​ជាបណ្ដោះអាសន្ន"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"ផ្ទាំងគ្រប់គ្រងឧបករណ៍"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"បញ្ចូល​ផ្ទាំងគ្រប់គ្រង​សម្រាប់​ឧបករណ៍​ដែលអ្នកបានភ្ជាប់"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"រៀបចំ​ផ្ទាំងគ្រប់គ្រងឧបករណ៍"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"ផ្គូផ្គង​ឧបករណ៍ថ្មី"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"ធាតុ​ក្រាហ្វិកនៃការសន្ទនា"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"ចុចការសន្ទនា ដើម្បីបញ្ចូលវាទៅក្នុងអេក្រង់ដើមរបស់អ្នក"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> មុន"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"តិចជាង <xliff:g id="DURATION">%1$s</xliff:g> មុន"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"ជាង <xliff:g id="DURATION">%1$s</xliff:g> មុន"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"ថ្ងៃកំណើត"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"ថ្ងៃកំណើតឆាប់ៗនេះ"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"គម្រប់ខួប"</string>
+    <string name="location_status" msgid="1294990572202541812">"កំពុងចែករំលែកទីតាំង"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"រឿងថ្មី"</string>
+    <string name="video_status" msgid="4548544654316843225">"កំពុង​មើល"</string>
+    <string name="audio_status" msgid="4237055636967709208">"កំពុងស្តាប់"</string>
+    <string name="game_status" msgid="1340694320630973259">"កំពុងលេង"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"មិត្តភ័ក្ដិ"</string>
+    <string name="empty_status" msgid="5938893404951307749">"តោះជជែកគ្នាយប់នេះ!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"ខកខាន​ទទួល"</string>
+    <string name="people_tile_description" msgid="8154966188085545556">"មើលព័ត៌មាន​ថ្មីៗ​អំពីស្ថានភាព ការខកខាន​ទទួល និងសារថ្មីៗ"</string>
+    <string name="people_tile_title" msgid="6589377493334871272">"ការ​សន្ទនា"</string>
     <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"មានបញ្ហាក្នុង​ការអាន​ឧបករណ៍រង្វាស់កម្រិតថ្មរបស់អ្នក"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"ចុចដើម្បីទទួលបាន​ព័ត៌មានបន្ថែម"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"មិនបាន​កំណត់​ម៉ោងរោទ៍​ទេ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index 851039f..ba058f8 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"ರದ್ದುಮಾಡಿ"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"ಹಂಚಿಕೊಳ್ಳಿ"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಅನ್ನು ರದ್ದುಮಾಡಲಾಗಿದೆ"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಉಳಿಸಲಾಗಿದೆ"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"ವೀಕ್ಷಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಅಳಿಸುವಾಗ ದೋಷ ಕಂಡುಬಂದಿದೆ"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"ಅನುಮತಿಗಳನ್ನು ಪಡೆಯುವಲ್ಲಿ ವಿಫಲವಾಗಿದೆ"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಪ್ರಾರಂಭಿಸುವಾಗ ದೋಷ ಕಂಡುಬಂದಿದೆ"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"ಹೊಸ ಬಳಕೆದಾರರು"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"ವೈ-ಫೈ"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"ಇಂಟರ್ನೆಟ್"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"ಏರ್‌ಪ್ಲೇನ್ ಮೋಡ್‌ನಲ್ಲಿ ಬಳಸಲು ಸುರಕ್ಷಿತವಾಗಿದೆ"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"ನೆಟ್‌ವರ್ಕ್‌ಗಳು ಲಭ್ಯವಿವೆ"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"ನೆಟ್‌ವರ್ಕ್‌ಗಳು ಲಭ್ಯವಿಲ್ಲ"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"ಸಂಪರ್ಕಗೊಂಡಿಲ್ಲ"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"ಸೂರ್ಯೋದಯದವರೆಗೆ"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g> ಸಮಯದಲ್ಲಿ"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> ವರೆಗೂ"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"ಪ್ರಖರತೆಯನ್ನು ಕಡಿಮೆ ಮಾಡಿ"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC ನಿಷ್ಕ್ರಿಯಗೊಂಡಿದೆ"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC ಸಕ್ರಿಯಗೊಂಡಿದೆ"</string>
@@ -470,14 +466,13 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"ಪ್ರೊಫೈಲ್‌ ತೋರಿಸು"</string>
     <string name="user_add_user" msgid="4336657383006913022">"ಬಳಕೆದಾರರನ್ನು ಸೇರಿಸಿ"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"ಹೊಸ ಬಳಕೆದಾರರು"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"ಅತಿಥಿ ಸೆಷನ್ ಕೊನೆಗೊಳಿಸಿ"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"ಅತಿಥಿಯನ್ನು ತೆಗೆದುಹಾಕುವುದೇ?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ಈ ಸೆಷನ್‌ನಲ್ಲಿನ ಎಲ್ಲ ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ಮತ್ತು ಡೇಟಾವನ್ನು ಅಳಿಸಲಾಗುತ್ತದೆ."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"ತೆಗೆದುಹಾಕಿ"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"ಮತ್ತೆ ಸುಸ್ವಾಗತ, ಅತಿಥಿ!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"ನಿಮ್ಮ ಸೆಷನ್‌ ಮುಂದುವರಿಸಲು ಇಚ್ಚಿಸುವಿರಾ?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ಪ್ರಾರಂಭಿಸಿ"</string>
-    <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"ಹೌದು, ಮುಂದುವರಿ"</string>
+    <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"ಹೌದು, ಮುಂದುವರಿಸಿ"</string>
     <string name="guest_notification_title" msgid="4434456703930764167">"ಅತಿಥಿ ಬಳಕೆದಾರ"</string>
     <string name="guest_notification_text" msgid="4202692942089571351">"ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ಮತ್ತು ಡೇಟಾ ಅಳಿಸಲು, ಅತಿಥಿ ಬಳಕೆದಾರರನ್ನು ತೆಗೆದುಹಾಕಿ"</string>
     <string name="guest_notification_remove_action" msgid="4153019027696868099">"ಅತಿಥಿಯನ್ನು ತೆಗೆದುಹಾಕಿ"</string>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ಈ ಸಾಧನವನ್ನು ನಿಮ್ಮ ಪೋಷಕರು ನಿರ್ವಹಿಸುತ್ತಿದ್ದಾರೆ"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ನಿಮ್ಮ ಸಂಸ್ಥೆಯು ಈ ಸಾಧನದ ಮಾಲೀಕತ್ವವನ್ನು ಹೊಂದಿದೆ ಮತ್ತು ಅದು ನೆಟ್‌ವರ್ಕ್ ಟ್ರಾಫಿಕ್‌ನ ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಬಹುದು"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ಈ ಸಾಧನದ ಮಾಲೀಕತ್ವವನ್ನು ಹೊಂದಿದೆ ಮತ್ತು ಅದು ನೆಟ್‌ವರ್ಕ್ ಟ್ರಾಫಿಕ್‌ನ ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಬಹುದು"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"ಈ ಸಾಧನವನ್ನು <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ಒದಗಿಸಿದ್ದಾರೆ"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"ಈ ಸಾಧನವು ನಿಮ್ಮ ಸಂಸ್ಥೆಗೆ ಸೇರಿದೆ ಮತ್ತು <xliff:g id="VPN_APP">%1$s</xliff:g> ಗೆ ಕನೆಕ್ಟ್ ಆಗಿದೆ"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"ಈ ಸಾಧನವು <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ಗೆ ಸೇರಿದೆ ಮತ್ತು <xliff:g id="VPN_APP">%2$s</xliff:g> ಗೆ ಕನೆಕ್ಟ್ ಆಗಿದೆ"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"ಈ ಸಾಧನವು ನಿಮ್ಮ ಸಂಸ್ಥೆಗೆ ಸೇರಿದೆ"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"ನಿಮ್ಮ ಉದ್ಯೋಗದ ಪ್ರೊಫೈಲ್ <xliff:g id="VPN_APP">%1$s</xliff:g> ಗೆ ಕನೆಕ್ಟ್ ಆಗಿದೆ"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"ನಿಮ್ಮ ವೈಯಕ್ತಿಕ ಪ್ರೊಫೈಲ್ <xliff:g id="VPN_APP">%1$s</xliff:g> ಗೆ ಕನೆಕ್ಟ್ ಆಗಿದೆ"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"ಈ ಸಾಧನವು <xliff:g id="VPN_APP">%1$s</xliff:g> ಗೆ ಕನೆಕ್ಟ್ ಆಗಿದೆ"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"ಈ ಸಾಧನವನ್ನು <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ಒದಗಿಸಿದ್ದಾರೆ"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"ಸಾಧನ ನಿರ್ವಹಣೆ"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"ಪ್ರೊಫೈಲ್ ಮೇಲ್ವಿಚಾರಣೆ"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"ನೆಟ್‌ವರ್ಕ್‌ ಪರಿವೀಕ್ಷಣೆ"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"ಕಾರ್ಯನೀತಿಗಳನ್ನು ವೀಕ್ಷಿಸಿ"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"ನಿಯಂತ್ರಣಗಳನ್ನು ವೀಕ್ಷಿಸಿ"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"ಈ ಸಾಧನವು <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ಗೆ ಸೇರಿದೆ.\n\nಸೆಟ್ಟಿಂಗ್‌ಗಳು, ಕಾರ್ಪೊರೇಟ್ ಪ್ರವೇಶ, ಆ್ಯಪ್‌ಗಳು, ನಿಮ್ಮ ಸಾಧನಕ್ಕೆ ಸಂಬಂಧಿಸಿದ ಡೇಟಾ ಮತ್ತು ನಿಮ್ಮ ಸಾಧನದ ಸ್ಥಳದ ಮಾಹಿತಿಯನ್ನು ನಿಮ್ಮ IT ನಿರ್ವಾಹಕರು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಬಹುದು ಮತ್ತು ನಿರ್ವಹಿಸಬಹುದು.\n\nಹೆಚ್ಚಿನ ಮಾಹಿತಿಗಾಗಿ ನಿಮ್ಮ IT ನಿರ್ವಾಹಕರನ್ನು ಸಂಪರ್ಕಿಸಿ."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> ಗೆ ಈ ಸಾಧನದ ಜೊತೆಗೆ ಸಂಯೋಜಿತವಾಗಿರುವ ಡೇಟಾವನ್ನು ಪ್ರವೇಶಿಸಲು, ಆ್ಯಪ್‌ಗಳನ್ನು ನಿರ್ವಹಿಸಲು ಮತ್ತು ಈ ಸಾಧನಗಳ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಬದಲಾಯಿಸಲು ಸಾಧ್ಯವಾಗುತ್ತದೆ.\n\nನಿಮ್ಮ ಬಳಿ ಪ್ರಶ್ನೆಗಳಿದ್ದರೆ, <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g> ಅನ್ನು ಸಂಪರ್ಕಿಸಿ."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"ಈ ಸಾಧನವು ನಿಮ್ಮ ಸಂಸ್ಥೆಗೆ ಸೇರಿದೆ.\n\nಸೆಟ್ಟಿಂಗ್‌ಗಳು, ಕಾರ್ಪೊರೇಟ್ ಪ್ರವೇಶ, ಆ್ಯಪ್‌ಗಳು, ನಿಮ್ಮ ಸಾಧನಕ್ಕೆ ಸಂಬಂಧಿಸಿದ ಡೇಟಾ ಮತ್ತು ನಿಮ್ಮ ಸಾಧನದ ಸ್ಥಳದ ಮಾಹಿತಿಯನ್ನು ನಿಮ್ಮ IT ನಿರ್ವಾಹಕರು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಬಹುದು ಮತ್ತು ನಿರ್ವಹಿಸಬಹುದು.\n\nಹೆಚ್ಚಿನ ಮಾಹಿತಿಗಾಗಿ ನಿಮ್ಮ IT ನಿರ್ವಾಹಕರನ್ನು ಸಂಪರ್ಕಿಸಿ."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"ನಿಮ್ಮ ಸಂಸ್ಥೆಯು ಈ ಸಾಧನದಲ್ಲಿ ಪ್ರಮಾಣಪತ್ರ ಅಂಗೀಕಾರವನ್ನು ಸ್ಥಾಪಿಸಿದೆ. ನಿಮ್ಮ ಸುರಕ್ಷಿತ ನೆಟ್‌ವರ್ಕ್ ಟ್ರಾಫಿಕ್ ಅನ್ನು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಬಹುದು ಅಥವಾ ಮಾರ್ಪಡಿಸಬಹುದು."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"ನಿಮ್ಮ ಸಂಸ್ಥೆಯು ನಿಮ್ಮ ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್‌ನಲ್ಲಿ ಪ್ರಮಾಣಪತ್ರ ಅಂಗೀಕಾರವನ್ನು ಸ್ಥಾಪಿಸಿದೆ. ನಿಮ್ಮ ಸುರಕ್ಷಿತ ನೆಟ್‌ವರ್ಕ್ ಟ್ರಾಫಿಕ್ ಅನ್ನು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಬಹುದು ಅಥವಾ ಮಾರ್ಪಡಿಸಬಹುದು."</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"ಡೆಮೊ ಮೋಡ್ ತೋರಿಸು"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"ಇಥರ್ನೆಟ್"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"ಅಲಾರಮ್"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"ವಾಲೆಟ್"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"ಸಿದ್ಧವಾಗಿದೆ"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"ಕೆಲಸದ ಪ್ರೊಫೈಲ್"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"ಏರ್‌ಪ್ಲೇನ್ ಮೋಡ್"</string>
     <string name="add_tile" msgid="6239678623873086686">"ಟೈಲ್ ಸೇರಿಸಿ"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"ತ್ವರಿತ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಮುಚ್ಚಿ."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"ಅಲಾರಾಂ ಹೊಂದಿಸಲಾಗಿದೆ."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"<xliff:g id="ID_1">%s</xliff:g> ಅವರಂತೆ ಸೈನ್ ಇನ್ ಮಾಡಲಾಗಿದೆ"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"ಬಳಕೆದಾರರನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"ಇಂಟರ್ನೆಟ್ ಇಲ್ಲ"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"ವಿವರಗಳನ್ನು ತೆರೆಯಿರಿ."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"<xliff:g id="REASON">%s</xliff:g> ಕಾರಣದಿಂದಾಗಿ ಲಭ್ಯವಿಲ್ಲ"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ತೆರೆಯಿರಿ."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"ಸೆಟ್ಟಿಂಗ್‌ಗಳ ಕ್ರಮವನ್ನು ಎಡಿಟ್ ಮಾಡಿ."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"ಪವರ್ ಮೆನು"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g> ರಲ್ಲಿ <xliff:g id="ID_1">%1$d</xliff:g> ಪುಟ"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"ಲಾಕ್ ಪರದೆ"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"ಫೋನ್ ಬಿಸಿಯಾಗಿದ್ದರಿಂದ ಆಫ್ ಆಗಿದೆ"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"ಎಡಕ್ಕೆ ಸರಿಸಿ"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"ಬಲಕ್ಕೆ ಸರಿಸಿ"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"ಝೂಮ್ ಮಾಡುವ ಸ್ವಿಚ್"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"ಸ್ಕ್ರೀನ್‌ನ ಸಂಪೂರ್ಣ ಭಾಗವನ್ನು ಝೂಮ್ ಮಾಡಿ"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"ಪೂರ್ಣ ಸ್ಕ್ರೀನ್‌ ಅನ್ನು ಹಿಗ್ಗಿಸಿ"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"ಸ್ಕ್ರೀನ್‌ನ ಅರ್ಧಭಾಗವನ್ನು ಝೂಮ್ ಮಾಡಿ"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"ಸ್ವಿಚ್"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"ಪ್ರವೇಶಿಸುವಿಕೆ ಬಟನ್ ಅಕ್ಸೆಸಿಬಿಲಿಟಿ ಗೆಸ್ಚರ್ ಅನ್ನು ಬದಲಾಯಿಸಿದೆ\n\n"<annotation id="link">"ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ವೀಕ್ಷಿಸಿ"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"ಅದನ್ನು ತಾತ್ಕಾಲಿಕವಾಗಿ ಮರೆಮಾಡಲು ಅಂಚಿಗೆ ಬಟನ್ ಸರಿಸಿ"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"ಸಾಧನ ನಿಯಂತ್ರಣಗಳು"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"ನಿಮ್ಮ ಸಂಪರ್ಕಿತ ಸಾಧನಗಳಿಗೆ ನಿಯಂತ್ರಣಗಳನ್ನು ಸೇರಿಸಿ"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"ಸಾಧನ ನಿಯಂತ್ರಣಗಳನ್ನು ಸೆಟಪ್ ಮಾಡಿ"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"ಹೊಸ ಸಾಧನವನ್ನು ಜೋಡಿಸಿ"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"ಸಂಭಾಷಣೆ ವಿಜೆಟ್‌ಗಳು"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"ಸಂಭಾಷಣೆಯನ್ನು ಹೋಮ್ ಸ್ಕ್ರೀನ್‌ಗೆ ಸೇರಿಸಲು ಅದನ್ನು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> ಸಮಯದ ಹಿಂದೆ"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"<xliff:g id="DURATION">%1$s</xliff:g> ಗಿಂತ ಕಡಿಮೆ ಅವಧಿಯ ಹಿಂದೆ"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"<xliff:g id="DURATION">%1$s</xliff:g> ಗಿಂತ ಹೆಚ್ಚಿನ ಅವಧಿಯ ಹಿಂದೆ"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"ಜನ್ಮದಿನ"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"ಶೀಘ್ರದಲ್ಲಿ ಜನ್ಮದಿನವಿದೆ"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"ವಾರ್ಷಿಕೋತ್ಸವ"</string>
+    <string name="location_status" msgid="1294990572202541812">"ಸ್ಥಳ ಹಂಚಿಕೊಳ್ಳಲಾಗುತ್ತಿದೆ"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"ಹೊಸ ಸುದ್ದಿ"</string>
+    <string name="video_status" msgid="4548544654316843225">"ವೀಕ್ಷಿಸುತ್ತಿರುವವರು"</string>
+    <string name="audio_status" msgid="4237055636967709208">"ಆಲಿಸಲಾಗುತ್ತಿದೆ"</string>
+    <string name="game_status" msgid="1340694320630973259">"ಪ್ಲೇ ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"ಸ್ನೇಹಿತರು"</string>
+    <string name="empty_status" msgid="5938893404951307749">"ಈ ರಾತ್ರಿ ಚಾಟ್ ಮಾಡೋಣ!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"ಮಿಸ್ಡ್ ಕಾಲ್"</string>
+    <string name="people_tile_description" msgid="8154966188085545556">"ಇತ್ತೀಚಿನ ಸಂದೇಶಗಳು, ಮಿಸ್ಡ್ ಕಾಲ್‌ಗಳು ಮತ್ತು ಸ್ಥಿತಿ ಅಪ್‌ಡೇಟ್‌ಗಳು"</string>
+    <string name="people_tile_title" msgid="6589377493334871272">"ಸಂಭಾಷಣೆ"</string>
     <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"ನಿಮ್ಮ ಬ್ಯಾಟರಿ ಮೀಟರ್ ಓದುವಾಗ ಸಮಸ್ಯೆ ಎದುರಾಗಿದೆ"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"ಇನ್ನಷ್ಟು ಮಾಹಿತಿಗಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"ಅಲಾರಾಂ ಸೆಟ್ ಆಗಿಲ್ಲ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index d4289925..3a519e5 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"취소"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"공유"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"화면 녹화가 취소되었습니다."</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"화면 녹화 저장됨"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"탭하여 보기"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"화면 녹화는 삭제하는 중에 오류가 발생했습니다."</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"권한을 확보하지 못했습니다."</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"화면 녹화 시작 중 오류 발생"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"신규 사용자"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"인터넷"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"항공 안전"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"네트워크 사용 가능"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"네트워크 사용 불가"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"연결되어 있지 않음"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"일출까지"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g>에 켜짐"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g>까지"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"밝기 낮추기"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC 사용 중지됨"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC 사용 설정됨"</string>
@@ -470,14 +466,13 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"프로필 표시"</string>
     <string name="user_add_user" msgid="4336657383006913022">"사용자 추가"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"신규 사용자"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"게스트 세션 종료"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"게스트를 삭제하시겠습니까?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"이 세션에 있는 모든 앱과 데이터가 삭제됩니다."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"삭제"</string>
-    <string name="guest_wipe_session_title" msgid="7147965814683990944">"게스트 세션 다시 시작"</string>
+    <string name="guest_wipe_session_title" msgid="7147965814683990944">"게스트 세션 진행"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"세션을 계속 진행하시겠습니까?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"다시 시작"</string>
-    <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"예, 계속합니다."</string>
+    <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"계속 진행"</string>
     <string name="guest_notification_title" msgid="4434456703930764167">"게스트 사용자"</string>
     <string name="guest_notification_text" msgid="4202692942089571351">"앱 및 데이터를 삭제하려면 게스트 사용자를 삭제하세요."</string>
     <string name="guest_notification_remove_action" msgid="4153019027696868099">"게스트 삭제"</string>
@@ -485,7 +480,7 @@
     <string name="user_logout_notification_text" msgid="7441286737342997991">"현재 사용자 로그아웃"</string>
     <string name="user_logout_notification_action" msgid="7974458760719361881">"사용자 로그아웃"</string>
     <string name="user_add_user_title" msgid="4172327541504825032">"신규 사용자를 추가할까요?"</string>
-    <string name="user_add_user_message_short" msgid="2599370307878014791">"추가된 새로운 사용자는 자신의 공간을 설정해야 합니다.\n\n모든 사용자는 다른 사용자들을 위하여 앱을 업데이트할 수 있습니다."</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"추가된 새로운 사용자는 자신의 공간을 설정해야 합니다.\n\n사용자라면 누구든 다른 사용자를 위해 앱을 업데이트할 수 있습니다."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"사용자 제한 도달"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">사용자를 <xliff:g id="COUNT">%d</xliff:g>명까지 추가할 수 있습니다.</item>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"부모님이 관리하는 기기입니다."</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"내 조직에서 이 기기를 소유하며 네트워크 트래픽을 모니터링할 수 있습니다."</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>에서 이 기기를 소유하며 네트워크 트래픽을 모니터링할 수 있습니다."</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>에서 제공하는 기기"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"내 조직에 속한 기기이며 <xliff:g id="VPN_APP">%1$s</xliff:g>에 연결되었습니다."</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>에 속한 기기이며 <xliff:g id="VPN_APP">%2$s</xliff:g>에 연결되었습니다."</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"내 조직에 속한 기기입니다."</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"직장 프로필이 <xliff:g id="VPN_APP">%1$s</xliff:g>에 연결되었습니다."</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"개인 프로필이 <xliff:g id="VPN_APP">%1$s</xliff:g>에 연결되었습니다."</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"기기가 <xliff:g id="VPN_APP">%1$s</xliff:g>에 연결되었습니다."</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>에서 제공하는 기기"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"기기 관리"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"프로필 모니터링"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"네트워크 모니터링"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"정책 보기"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"제어 기능 보기"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>에 속한 기기입니다.\n\nIT 관리자가 설정, 기업 액세스, 앱, 기기와 연결된 데이터, 기기 위치 정보를 모니터링 및 관리할 수 있습니다.\n\n자세한 정보를 확인하려면 IT 관리자에게 문의하세요."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g>에서 이 기기와 연결된 데이터에 액세스하고 앱을 관리하며 기기 설정을 변경할 수 있습니다.\n\n궁금한 점이 있으면 <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>에 문의하세요."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"내 조직에 속한 기기입니다.\n\nIT 관리자가 설정, 기업 액세스, 앱, 기기와 연결된 데이터, 기기 위치 정보를 모니터링 및 관리할 수 있습니다.\n\n자세한 정보를 확인하려면 IT 관리자에게 문의하세요."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"조직에서 이 기기에 인증기관을 설치했습니다. 보안 네트워크 트래픽을 모니터링 또는 수정할 수 있습니다."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"조직에서 직장 프로필에 인증기관을 설치했습니다. 보안 네트워크 트래픽을 모니터링 또는 수정할 수 있습니다."</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"데모 모드 표시"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"이더넷"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"알람"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"준비됨"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"직장 프로필"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"비행기 모드"</string>
     <string name="add_tile" msgid="6239678623873086686">"타일 추가"</string>
@@ -721,7 +721,7 @@
     <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"&lt;b&gt;상태:&lt;/b&gt; 무음으로 낮춤"</string>
     <string name="notification_channel_summary_automatic_promoted" msgid="1301710305149590426">"&lt;b&gt;상태:&lt;/b&gt; 순위 높임"</string>
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;상태:&lt;/b&gt; 순위 낮춤"</string>
-    <string name="notification_channel_summary_priority" msgid="7952654515769021553">"대화 섹션 상단에 표시, 플로팅 대화창으로 표시, 그리고 잠금 화면에 프로필 사진이 표시됨"</string>
+    <string name="notification_channel_summary_priority" msgid="7952654515769021553">"대화 섹션 상단에 표시, 플로팅 대화창으로 표시, 잠금 화면에 프로필 사진이 표시됨"</string>
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"설정"</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>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"빠른 설정 닫기"</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"알람이 설정됨"</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"<xliff:g id="ID_1">%s</xliff:g>(으)로 로그인됨"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"사용자 선택"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"인터넷 연결 없음"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"세부정보 열기"</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"다음 이유로 사용할 수 없음: <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> 설정 열기"</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"설정 순서 수정"</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"전원 메뉴"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g>페이지 중 <xliff:g id="ID_1">%1$d</xliff:g>페이지"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"잠금 화면"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"발열로 인해 휴대전화 전원이 종료됨"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"왼쪽으로 이동"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"오른쪽으로 이동"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"확대 전환"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"전체 화면 확대"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"전체 화면 확대"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"화면 일부 확대"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"전환"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"접근성 동작이 접근성 버튼으로 대체되었습니다\n\n"<annotation id="link">"설정 보기"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"버튼을 가장자리로 옮겨서 일시적으로 숨기세요"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"기기 컨트롤"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"연결된 기기의 컨트롤을 추가하세요."</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"기기 컨트롤 설정"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"새 기기와 페어링"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"대화 위젯"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"대화를 탭하여 홈 화면에 추가하세요."</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> 전"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"<xliff:g id="DURATION">%1$s</xliff:g> 이내"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"<xliff:g id="DURATION">%1$s</xliff:g> 이상 경과"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"생일"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"다가오는 생일"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"기념일"</string>
+    <string name="location_status" msgid="1294990572202541812">"위치 공유 중"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"새 스토리"</string>
+    <string name="video_status" msgid="4548544654316843225">"시청 중"</string>
+    <string name="audio_status" msgid="4237055636967709208">"듣는 중"</string>
+    <string name="game_status" msgid="1340694320630973259">"플레이 중"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"친구"</string>
+    <string name="empty_status" msgid="5938893404951307749">"오늘 밤에 채팅"</string>
+    <string name="missed_call" msgid="4228016077700161689">"부재중 전화"</string>
+    <string name="people_tile_description" msgid="8154966188085545556">"최근 메시지, 부재중 전화, 상태 업데이트 보기"</string>
+    <string name="people_tile_title" msgid="6589377493334871272">"대화"</string>
     <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"배터리 수준을 읽는 중에 문제가 발생함"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"탭하여 자세한 정보를 확인하세요."</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"설정된 알람 없음"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index d726d55..f637222 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Жокко чыгаруу"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Бөлүшүү"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Экранды жаздыруу жокко чыгарылды"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Экрандан жаздырылган нерсе сакталды"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Көрүү үчүн таптаңыз"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Экранды жаздырууну өчүрүүдө ката кетти"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Уруксаттар алынбай калды"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Экранды жаздырууну баштоодо ката кетти"</string>
@@ -191,9 +189,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Эки таякча батарея."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Үч таякча батарея."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Батарея толук."</string>
-    <!-- String.format failed for translation -->
-    <!-- no translation found for accessibility_battery_unknown (1807789554617976440) -->
-    <skip />
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Батарея кубатынын деңгээли белгисиз."</string>
     <string name="accessibility_wifi_name" msgid="4863440268606851734">"<xliff:g id="WIFI">%s</xliff:g> менен туташкан."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g> менен туташкан."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> менен туташты."</string>
@@ -363,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Жаңы колдонуучу"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Интернет"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Учак режимине ылайыктуу"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Тармактар жеткиликтүү"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Тармактар жеткиликсиз"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Байланышкан жок"</string>
@@ -417,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Күн чыкканга чейин"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Саат <xliff:g id="TIME">%s</xliff:g> күйөт"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> чейин"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Экрандын жарыктыгын төмөндөтүү"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC өчүрүлгөн"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC иштетилген"</string>
@@ -472,11 +466,10 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Профилди көрсөтүү"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Колдонуучу кошуу"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Жаңы колдонуучу"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Конок сеансын бүтүрүү"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Конокту алып саласызбы?"</string>
-    <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Бул сеанстагы бардык колдонмолор жана дайындар өчүрүлөт."</string>
+    <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Бул сеанстагы бардык колдонмолор жана маалыматтар өчүрүлөт."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Алып салуу"</string>
-    <string name="guest_wipe_session_title" msgid="7147965814683990944">"Кайтып келишиңиз менен, конок!"</string>
+    <string name="guest_wipe_session_title" msgid="7147965814683990944">"Кайтып келишиңиз менен!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Сеансыңызды улантасызбы?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Кайра баштоо"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ооба, уланта берели"</string>
@@ -521,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Бул түзмөктү ата-энең башкарат"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Бул түзмөк уюмуңузга таандык. Уюмуңуз тармактын трафигин көзөмөлдөй алат"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Бул түзмөк <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> уюмуна таандык. Уюм тармактын трафигин көзөмөлдөй алат"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Бул түзмөктү <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> камсыздады."</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Бул түзмөк уюмуңузга таандык жана <xliff:g id="VPN_APP">%1$s</xliff:g> колдонмосуна туташтырылган"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Бул түзмөк <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> уюмуна таандык жана <xliff:g id="VPN_APP">%2$s</xliff:g> колдонмосуна туташтырылган"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Бул түзмөк уюмуңузга таандык"</string>
@@ -534,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Жумуш профилиңиз <xliff:g id="VPN_APP">%1$s</xliff:g> колдонмосуна туташып турат"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Жеке профилиңиз <xliff:g id="VPN_APP">%1$s</xliff:g> колдонмосуна туташтырылган"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Бул түзмөк <xliff:g id="VPN_APP">%1$s</xliff:g> колдонмосуна туташтырылган"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Бул түзмөктү <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> камсыздады."</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Түзмөктү башкаруу"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Профилди көзөмөлдөө"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Тармакка көз салуу"</string>
@@ -545,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Саясаттарды карап көрүү"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Башкаруу элементтерин көрүү"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Бул түзмөк <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> уюмуна таандык.\n\nIT администраторуңуз жөндөөлөрдү, корпоративдик мүмкүнчүлүктү, колдонмолорду, түзмөгүңүзгө байланыштуу дайын-даректерди жана түзмөгүңүздүн жайгашкан жери тууралуу маалыматты көзөмөлдөп жана башкара алат.\n\nТолугураак маалымат алуу үчүн, IT администраторуңузга кайрылыңыз."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> бул түзмөк менен байланышкан маалыматты көрүп, колдонмолорду башкарып, анын жөндөөлөрүн өзгөртө алат.\n\nЭгер суроолоруңуз болсо, <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g> уюмуна кайрылыңыз."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Бул түзмөк уюмуңузга таандык.\n\nIT администраторуңуз жөндөөлөрдү, корпоративдик мүмкүнчүлүктү, колдонмолорду, түзмөгүңүзгө байланыштуу дайын-даректерди жана түзмөгүңүздүн жайгашкан жери тууралуу маалыматты көзөмөлдөп жана башкара алат.\n\nТолугураак маалымат алуу үчүн, IT администраторуңузга кайрылыңыз."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Ишканаңыз бул түзмөккө тастыктоочу борборду орнотту. Коопсуз тармагыңыздын трафиги көзөмөлдөнүп же өзгөртүлүшү мүмкүн."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Ишканаңыз жумуш профилиңизге тастыктоочу борборду орнотту. Коопсуз тармагыңыздын трафиги көзөмөлдөнүп же өзгөртүлүшү мүмкүн."</string>
@@ -655,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Демо режимин көрсөтүү"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Ойготкуч"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Даяр"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Жумуш профили"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Учак режими"</string>
     <string name="add_tile" msgid="6239678623873086686">"Тайл кошуу"</string>
@@ -674,8 +672,8 @@
     <string name="remove_from_settings" msgid="633775561782209994">"Жөндөөлөрдөн алып салуу"</string>
     <string name="remove_from_settings_prompt" msgid="551565437265615426">"System UI Tuner Жөндөөлөрдөн өчүрүлүп, анын бардык функциялары токтотулсунбу?"</string>
     <string name="activity_not_found" msgid="8711661533828200293">"Колдонмо сиздин түзмөгүңүздө орнотулган эмес"</string>
-    <string name="clock_seconds" msgid="8709189470828542071">"Сааттын секунддары көрсөтүлсүн"</string>
-    <string name="clock_seconds_desc" msgid="2415312788902144817">"Абал тилкесинен сааттын секунддары көрсөтүлсүн. Батареянын кубаты көбүрөөк сарпталышы мүмкүн."</string>
+    <string name="clock_seconds" msgid="8709189470828542071">"Сааттын секунддары көрүнсүн"</string>
+    <string name="clock_seconds_desc" msgid="2415312788902144817">"Абал тилкесинен сааттын секунддары көрүнсүн. Батареянын кубаты көбүрөөк сарпталышы мүмкүн."</string>
     <string name="qs_rearrange" msgid="484816665478662911">"Ыкчам жөндөөлөрдү кайра коюу"</string>
     <string name="show_brightness" msgid="6700267491672470007">"Ыкчам жөндөөлөрдөн жарык деңгээлин көрсөтүү"</string>
     <string name="experimental" msgid="3549865454812314826">"Сынамык"</string>
@@ -684,7 +682,7 @@
     <string name="enable_bluetooth_confirmation_ok" msgid="2866408183324184876">"Күйгүзүү"</string>
     <string name="show_silently" msgid="5629369640872236299">"Үнсүз көрүнөт"</string>
     <string name="block" msgid="188483833983476566">"Бардык билдирмелерди бөгөттөө"</string>
-    <string name="do_not_silence" msgid="4982217934250511227">"Үнү менен көрсөтүлсүн"</string>
+    <string name="do_not_silence" msgid="4982217934250511227">"Үнү менен көрүнсүн"</string>
     <string name="do_not_silence_block" msgid="4361847809775811849">"Үнү менен көрсөтүлүп бөгөттөлбөсүн"</string>
     <string name="tuner_full_importance_settings" msgid="1388025816553459059">"Эскертмелерди башкаруу каражаттары"</string>
     <string name="tuner_full_importance_settings_on" msgid="917981436602311547">"Күйүк"</string>
@@ -723,7 +721,7 @@
     <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"&lt;b&gt;Абалы:&lt;/b&gt; Үнсүз абалга төмөндөдү"</string>
     <string name="notification_channel_summary_automatic_promoted" msgid="1301710305149590426">"&lt;b&gt;Абалы:&lt;/b&gt; Жогорулады"</string>
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Абалы:&lt;/b&gt; Төмөндөдү"</string>
-    <string name="notification_channel_summary_priority" msgid="7952654515769021553">"Жазышуулар тизмесинин өйдө жагында калкып чыкма билдирме түрүндө көрүнүп, профиль сүрөтү кулпуланган экрандан чагылдырылат"</string>
+    <string name="notification_channel_summary_priority" msgid="7952654515769021553">"Жазышуулар тизмесинин өйдө жагында калкып чыкма билдирме түрүндө көрүнсө, профиль сүрөтү кулпуланган экранда көрүнөт"</string>
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Жөндөөлөр"</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>
@@ -824,7 +822,7 @@
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Музыка"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="5078136084632450333">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Жылнаама"</string>
-    <string name="tuner_full_zen_title" msgid="5120366354224404511">"Үн көзөмөлдөгүчтөрү менен көрсөтүлсүн"</string>
+    <string name="tuner_full_zen_title" msgid="5120366354224404511">"Үн көзөмөлдөгүчтөрү менен көрүнсүн"</string>
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Тынчымды алба"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Үндү көзөмөлдөөчү баскычтардын кыска жолдору"</string>
     <string name="volume_up_silent" msgid="1035180298885717790">"Үн катуулатылганда \"Тынчымды алба\" режиминен чыгуу"</string>
@@ -879,8 +877,8 @@
     <item msgid="6135970080453877218">"Бул сүрөтчө көрүнбөсүн"</item>
   </string-array>
   <string-array name="battery_options">
-    <item msgid="7714004721411852551">"Ар дайым пайызы көрсөтүлсүн"</item>
-    <item msgid="3805744470661798712">"Кубаттоо учурунда пайызы көрсөтүлсүн (демейки)"</item>
+    <item msgid="7714004721411852551">"Ар дайым пайызы көрүнсүн"</item>
+    <item msgid="3805744470661798712">"Кубаттоо учурунда пайызы көрүнсүн (демейки)"</item>
     <item msgid="8619482474544321778">"Бул сүрөтчө көрүнбөсүн"</item>
   </string-array>
     <string name="tuner_low_priority" msgid="8412666814123009820">"Анча маанилүү эмес билдирменин сүрөтчөлөрүн көрсөтүү"</string>
@@ -901,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Ыкчам жөндөөлөрдү жабуу."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Ойготкуч коюлду."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"<xliff:g id="ID_1">%s</xliff:g> аккаунту менен кирди"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"колдонуучуну тандоо"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Интернет жок"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Чоо-жайын ачуу."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"<xliff:g id="REASON">%s</xliff:g> себебине байланыштуу жеткиликсиз"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> жөндөөлөрүн ачуу."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Жөндөөлөрдүн иретин өзгөртүү."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Күйгүзүү/өчүрүү баскычынын менюсу"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g> ичинен <xliff:g id="ID_1">%1$d</xliff:g>-бет"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Кулпуланган экран"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"Телефон ысыгандыктан өчүрүлдү"</string>
@@ -1013,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Солго жылдыруу"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Оңго жылдыруу"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Чоңойтуу режимине которулуу"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Толук экранды чоңойтуу"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Толук экранда ачуу"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Экрандын бир бөлүгүн чоңойтуу"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Которулуу"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"Атайын мүмкүнчүлүктөр баскычы атайын мүмкүнчүлүктөр жаңсоосун алмаштырды\n\n"<annotation id="link">"Жөндөөлөрдү көрүү"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Убактылуу жашыруу үчүн баскычты четине жылдырыңыз"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Түзмөктү башкаруу элементтери"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Байланышкан түзмөктөрүңүздү башкаруу элементтерин кошосуз"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Түзмөктү башкаруу элементтерин жөндөө"</string>
@@ -1083,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Жаңы түзмөктү жупташтыруу"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Маек виджеттери"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Маекти Башкы экранга кошуу үчүн таптап коюңуз"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> мурда"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"<xliff:g id="DURATION">%1$s</xliff:g> жетпеген убакыт мурда"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"<xliff:g id="DURATION">%1$s</xliff:g> ашуун мурда"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Туулган күн"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Алдыдагы туулган күн"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Маараке"</string>
+    <string name="location_status" msgid="1294990572202541812">"Кайда жүргөнүмдү көрсөтүү"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Жаңы окуя"</string>
+    <string name="video_status" msgid="4548544654316843225">"Көрүүдө"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Угуп жатат"</string>
+    <string name="game_status" msgid="1340694320630973259">"Ойнотулууда"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Достор"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Келиңиз, баарлашалы!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"Жооп берилбеген чалуу"</string>
+    <string name="people_tile_description" msgid="8154966188085545556">"Акыркы билдирүүлөрдү, жооп берилбеген чалууларды жана статус жаңыртууларын көрүү"</string>
+    <string name="people_tile_title" msgid="6589377493334871272">"Сүйлөшүү"</string>
     <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Батареяңыздын кубаты аныкталбай жатат"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Кеңири маалымат алуу үчүн таптап коюңуз"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Ойготкуч коюлган жок"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-land-television/dimens.xml b/packages/SystemUI/res/values-land-television/dimens.xml
index 95ff59b..8c90573 100644
--- a/packages/SystemUI/res/values-land-television/dimens.xml
+++ b/packages/SystemUI/res/values-land-television/dimens.xml
@@ -16,14 +16,17 @@
 
 <resources>
   <!-- Height of volume bar -->
-  <dimen name="volume_dialog_row_height">190dp</dimen>
-  <dimen name="volume_dialog_row_width">48dp</dimen>
+  <dimen name="volume_dialog_panel_height">190dp</dimen>
+  <dimen name="volume_dialog_panel_width">48dp</dimen>
+  <dimen name="volume_dialog_panel_width_half">24dp</dimen>
   <dimen name="volume_dialog_panel_transparent_padding">24dp</dimen>
+  <dimen name="volume_dialog_slider_width">4dp</dimen>
+  <dimen name="volume_dialog_slider_corner_radius">@dimen/volume_dialog_slider_width</dimen>
+
   <dimen name="tv_volume_dialog_bubble_size">36dp</dimen>
   <dimen name="tv_volume_dialog_corner_radius">36dp</dimen>
   <dimen name="tv_volume_dialog_row_padding">6dp</dimen>
   <dimen name="tv_volume_number_text_size">16sp</dimen>
-  <dimen name="tv_volume_seek_bar_width">4dp</dimen>
   <dimen name="tv_volume_seek_bar_thumb_diameter">24dp</dimen>
   <dimen name="tv_volume_seek_bar_thumb_focus_ring_width">8dp</dimen>
   <dimen name="tv_volume_icons_size">20dp</dimen>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 23df8bc..4c2a5cb 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"ຍົກເລີກ"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"ແບ່ງປັນ"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"ຍົກເລີກການບັນທຶກໜ້າຈໍແລ້ວ"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"ຈັດເກັບການບັນທຶກໜ້າຈໍແລ້ວ"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"ແຕະເພື່ອເບິ່ງ"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"ເກີດຄວາມຜິດພາດໃນການລຶບການບັນທຶກໜ້າຈໍ"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"ໂຫຼດສິດອະນຸຍາດບໍ່ສຳເລັດ"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"ເກີດຄວາມຜິດພາດໃນການບັນທຶກໜ້າຈໍ"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"ຜູ່ໃຊ້ໃໝ່"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi​-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"ອິນເຕີເນັດ"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"ປອດໄພກັບໃນຍົນ"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"ມີເຄືອຂ່າຍທີ່ສາມາດໃຊ້ໄດ້"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"ບໍ່ມີເຄືອຂ່າຍທີ່ສາມາດໃຊ້ໄດ້"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"ບໍ່ໄດ້ເຊື່ອມຕໍ່"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"ຈົນກວ່າຕາເວັນຂຶ້ນ"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"ເປີດເວລາ <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"ຈົນຮອດ <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"ຫຼຸດຄວາມສະຫວ່າງລົງ"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC is disabled"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC is enabled"</string>
@@ -470,11 +466,10 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"​ສະ​ແດງ​ໂປຣ​ໄຟລ໌"</string>
     <string name="user_add_user" msgid="4336657383006913022">"ເພີ່ມຜູ້ໃຊ້"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"ຜູ່ໃຊ້ໃໝ່"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"ສິ້ນສຸດເຊດຊັນແຂກ"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"ລຶບ​ແຂກ​ບໍ?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ແອັບຯ​ແລະ​ຂໍ້​ມູນ​ທັງ​ໝົດ​ໃນ​ເຊດ​ຊັນ​ນີ້​ຈະ​ຖືກ​ລຶບ​ອອກ."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"ລຶບ​"</string>
-    <string name="guest_wipe_session_title" msgid="7147965814683990944">"ຍິນ​ດີ​ຕ້ອນ​ຮັບ​ກັບ​ມາ, ຜູ່​ຢ້ຽມ​ຢາມ!"</string>
+    <string name="guest_wipe_session_title" msgid="7147965814683990944">"ຍິນ​ດີ​ຕ້ອນ​ຮັບ​ກັບ​ມາ, ຜູ້ຢ້ຽມຢາມ!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"ທ່ານ​ຕ້ອງ​ການ​ສືບ​ຕໍ່​ເຊດ​ຊັນ​ຂອງ​ທ່ານບໍ່?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ເລີ່ມຕົ້ນໃຫມ່"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"​ຕົກ​ລົງ, ດຳ​ເນີນ​ການ​ຕໍ່"</string>
@@ -485,7 +480,7 @@
     <string name="user_logout_notification_text" msgid="7441286737342997991">"ອອກ​ຈາກ​ຜູ້​ໃຊ້​ປະ​ຈຸ​ບັນ"</string>
     <string name="user_logout_notification_action" msgid="7974458760719361881">"ເອົາຜູ້ໃຊ້ອອກຈາກລະບົບ"</string>
     <string name="user_add_user_title" msgid="4172327541504825032">"ເພີ່ມຜູ້ໃຊ້ໃໝ່ບໍ?"</string>
-    <string name="user_add_user_message_short" msgid="2599370307878014791">"ເມື່ອ​ທ່ານ​ເພີ່ມ​ຜູ້ໃຊ້​ໃໝ່, ຜູ້ໃຊ້​ນັ້ນ​ຈະ​ຕ້ອງ​ຕັ້ງ​ຄ່າ​ພື້ນ​ທີ່​ບ່ອນ​ຈັດ​ເກັບ​ຂໍ້​ມູນ​ຂອງ​ລາວ.\n\nຜູ້ໃຊ້​ທຸກ​ຄົນ​ສາ​ມາດ​ອັບ​ເດດ​ແອັບຯຂອງ​ຜູ້​ໃຊ້​ຄົນ​ອື່ນ​ທັງ​ໝົດ​ໄດ້."</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"ເມື່ອ​ທ່ານ​ເພີ່ມ​ຜູ້ໃຊ້​ໃໝ່, ຜູ້ໃຊ້​ນັ້ນ​ຈະ​ຕ້ອງ​ຕັ້ງ​ຄ່າ​ພື້ນ​ທີ່​ບ່ອນ​ຈັດ​ເກັບ​ຂໍ້​ມູນ​ຂອງ​ລາວ.\n\nຜູ້ໃຊ້​ທຸກ​ຄົນ​ສາ​ມາດ​ອັບ​ເດດ​ແອັບຂອງ​ຜູ້​ໃຊ້​ຄົນ​ອື່ນ​ທັງ​ໝົດ​ໄດ້."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"ຮອດຂີດຈຳກັດຜູ້ໃຊ້ແລ້ວ"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">ທ່ານສາມາດເພີ່ມໄດ້ສູງສຸດ <xliff:g id="COUNT">%d</xliff:g> ຄົນ.</item>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ອຸປະກອນນີ້ແມ່ນຈັດການໂດຍພໍ່ແມ່ຂອງທ່ານ"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ອົງການຂອງທ່ານເປັນເຈົ້າຂອງອຸປະກອນນີ້ ແລະ ສາມາດຕິດຕາມທຣາບຟິກເຄືອຂ່າຍໄດ້"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ເປັນເຈົ້າຂອງອຸປະກອນນີ້ ແລະ ສາມາດຕິດຕາມທຣາບຟິກເຄືອຂ່າຍໄດ້"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"ອຸປະກອນນີ້ແມ່ນສະໜອງໃຫ້ໂດຍ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"ອຸປະກອນນີ້ເປັນຂອງອົງການທ່ານ ແລະ ເຊື່ອມຕໍ່ຫາ <xliff:g id="VPN_APP">%1$s</xliff:g> ແລ້ວ"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"ອຸປະກອນນີ້ເປັນຂອງ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ແລະ ເຊື່ອມຕໍ່ຫາ <xliff:g id="VPN_APP">%2$s</xliff:g> ແລ້ວ"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"ອຸປະກອນນີ້ເປັນຂອງອົງການທ່ານ"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກຂອງທ່ານເຊື່ອມຕໍ່ຫາ <xliff:g id="VPN_APP">%1$s</xliff:g> ແລ້ວ"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"ໂປຣໄຟລ໌ສ່ວນຕົວຂອງທ່ານເຊື່ອມຕໍ່ຫາ <xliff:g id="VPN_APP">%1$s</xliff:g> ແລ້ວ"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"ອຸປະກອນນີ້ເຊື່ອມຕໍ່ຫາ <xliff:g id="VPN_APP">%1$s</xliff:g> ແລ້ວ"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"ອຸປະກອນນີ້ແມ່ນສະໜອງໃຫ້ໂດຍ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"ການຈັດການອຸປະກອນ"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"ການ​ຕິດ​ຕາມ​ໂປຣ​ໄຟລ໌"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"ການກວດ​ສອບ​ຕິດ​ຕາມ​ເຄືອ​ຂ່າຍ"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"ເບິ່ງນະໂຍບາຍ"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"ເບິ່ງການຄວບຄຸມ"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"ອຸປະກອນນີ້ເປັນຂອງ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nຜູ້ເບິ່ງແຍງໄອທີຂອງທ່ານສາມາດເຝົ້າຕິດຕາມ ແລະ ຈັດການການຕັ້ງຄ່າ, ສິດເຂົ້າເຖິງອົງກອນ, ແອັບ, ຂໍ້ມູນທີ່ເຊື່ອມໂຍງກັບອຸປະກອນຂອງທ່ານໄດ້.\n\nສຳລັບຂໍ້ມູນເພີ່ມເຕີມ, ກະລຸນາຕິດຕໍ່ຜູ້ເບິ່ງແຍງໄອທີຂອງທ່ານ."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> ອາດສາມາດເຂົ້າເຖິງຂໍ້ມູນທີ່ເຊື່ອມໂຍງກັບອຸປະກອນນີ້, ຈັດການແອັບ ແລະ ປ່ຽນການຕັ້ງຄ່າອຸປະກອນນີ້ໄດ້.\n\nຫາກທ່ານມີຄຳຖາມ, ກະລຸນາຕິດຕໍ່ <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"ອຸປະກອນນີ້ເປັນຂອງອົງການທ່ານ.\n\nຜູ້ເບິ່ງແຍງໄອທີຂອງທ່ານສາມາດເຝົ້າຕິດຕາມ ແລະ ຈັດການການຕັ້ງຄ່າ, ສິດເຂົ້າເຖິງອົງກອນ, ແອັບ, ຂໍ້ມູນທີ່ເຊື່ອມໂຍງກັບອຸປະກອນຂອງທ່ານໄດ້.\n\nສຳລັບຂໍ້ມູນເພີ່ມເຕີມ, ກະລຸນາຕິດຕໍ່ຜູ້ເບິ່ງແຍງໄອທີຂອງທ່ານ."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"ອົງກອນຂອງທ່ານຕິດຕັ້ງອຳນາດໃບຮັບຮອງໄວ້ໃນອຸປະກອນນີ້. ທຣາບຟິກເຄືອຂ່າຍທີ່ເຂົ້າລະຫັດໄວ້ຂອງທ່ານອາດຖືກຕິດຕາມ ຫຼື ແກ້ໄຂໄດ້."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"ອົງກອນຂອງທ່ານຕິດຕັ້ງອຳນາດໃບຮັບຮອງໄວ້ໃນໂປຣໄຟລ໌ບ່ອນເຮັດວຽກນີ້. ທຣາບຟິກເຄືອຂ່າຍທີ່ເຂົ້າລະຫັດໄວ້ຂອງທ່ານອາດຖືກຕິດຕາມ ຫຼື ແກ້ໄຂໄດ້."</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"ສະ​ແດງ​ໂຫມດ​ສາ​ທິດ"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"ອີ​ເທ​ເນັດ"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"ໂມງປຸກ"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"ກະເປົາ"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"ພ້ອມແລ້ວ"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"​ໂປຣ​ໄຟລ໌​ບ່ອນ​ເຮັດ​ວຽກ"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"ໂໝດເຮືອ​ບິນ"</string>
     <string name="add_tile" msgid="6239678623873086686">"ເພີ່ມ​ລາຍ​ຕາ​ກະ​ໂລ່"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"ປິດການຕັ້ງຄ່າດ່ວນ."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"ຕັ້ງໂມງປຸກແລ້ວ."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"ເຂົ້າສູ່ລະບົບເປັນ <xliff:g id="ID_1">%s</xliff:g> ແລ້ວ"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"ເລືອກຜູ້ໃຊ້"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"ບໍ່ມີອິນເຕີເນັດ"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"ເປີດລາຍລະອຽດ."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"ບໍ່ສາມາດໃຊ້ໄດ້ເນື່ອງຈາກ <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"ເປີດການຕັ້ງຄ່າ <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"ແກ້ໄຂລຳດັບການຕັ້ງຄ່າ."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"ເມນູເປີດປິດ"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_1">%1$d</xliff:g> ຈາກທັງໝົດ <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"ໜ້າຈໍລັອກ"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"ປິດໂທລະສັບເນື່ອງຈາກຮ້ອນເກີນໄປ"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"ຍ້າຍໄປຊ້າຍ"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"ຍ້າຍໄປຂວາ"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"ສະຫຼັບການຂະຫຍາຍ"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"ຂະຫຍາຍທັງໜ້າຈໍ"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"ຂະຫຍາຍເຕັມຈໍ"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"ຂະຫຍາຍບາງສ່ວນຂອງໜ້າຈໍ"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"ສະຫຼັບ"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"ປຸ່ມການຊ່ວຍເຂົ້າເຖິງຖືກແທນທີ່ທ່າທາງຊ່ວຍເຂົ້າເຖິງແລ້ວ\n\n"<annotation id="link">"ເບິ່ງການຕັ້ງຄ່າ"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"ຍ້າຍປຸ່ມໄປໃສ່ຂອບເພື່ອເຊື່ອງມັນຊົ່ວຄາວ"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"ການຄວບຄຸມອຸປະກອນ"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"ເພີ່ມການຄວບຄຸມສຳລັບອຸປະກອນທີ່ເຊື່ອມຕໍ່ແລ້ວຂອງທ່ານ"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"ຕັ້ງຄ່າການຄວບຄຸມອຸປະກອນ"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"ຈັບຄູ່ອຸປະກອນໃໝ່"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"ວິດເຈັດການສົນທະນາ"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"ແຕະໃສ່ການສົນທະນາໃດໜຶ່ງເພື່ອເພີ່ມມັນໃສ່ໂຮມສະກຣີນຂອງທ່ານ"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> ກ່ອນ"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"ບໍ່ຮອດ <xliff:g id="DURATION">%1$s</xliff:g> ກ່ອນ"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"ເກີນ <xliff:g id="DURATION">%1$s</xliff:g> ມາແລ້ວ"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"ວັນເກີດ"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"ວັນເກີດໃນໄວໆນີ້"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"ວັນຄົບຮອບ"</string>
+    <string name="location_status" msgid="1294990572202541812">"ກຳລັງແບ່ງປັນສະຖານທີ່"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"ເລື່ອງໃໝ່"</string>
+    <string name="video_status" msgid="4548544654316843225">"ຄົນກຳລັງເບິ່ງ"</string>
+    <string name="audio_status" msgid="4237055636967709208">"ກຳລັງຟັງ"</string>
+    <string name="game_status" msgid="1340694320630973259">"ກຳລັງຫຼິ້ນ"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"ໝູ່"</string>
+    <string name="empty_status" msgid="5938893404951307749">"ມາລົມກັນຄືນນີ້!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"ສາຍບໍ່ໄດ້ຮັບ"</string>
+    <string name="people_tile_description" msgid="8154966188085545556">"ເບິ່ງຂໍ້ຄວາມຫຼ້າສຸດ, ສາຍບໍ່ໄດ້ຮັບ ແລະ ອັບເດດສະຖານະ"</string>
+    <string name="people_tile_title" msgid="6589377493334871272">"ການສົນທະນາ"</string>
     <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"ເກີດບັນຫາໃນການອ່ານຕົວວັດແທກແບັດເຕີຣີຂອງທ່ານ"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"ແຕະເພື່ອເບິ່ງຂໍ້ມູນເພີ່ມເຕີມ"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"ບໍ່ໄດ້ຕັ້ງໂມງປຸກ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 64b4d6d..ca02dc8 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Atšaukti"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Bendrinti"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Ekrano įrašymas atšauktas"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Ekrano vaizdo įrašas išsaugotas"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Palieskite, kad peržiūrėtumėte"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Ištrinant ekrano įrašą įvyko klaida"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Nepavyko gauti leidimų"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Pradedant ekrano vaizdo įrašymą iškilo problema"</string>
@@ -363,7 +361,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Naujas naudotojas"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Internetas"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Saugu naudotis lėktuvuose"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Tinklai pasiekiami"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Tinklai nepasiekiami"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Neprisijungta"</string>
@@ -419,7 +416,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Iki saulėtekio"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Iki <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Šviesumo mažinimas"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"ALR"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"ALR išjungtas"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"ALR įjungtas"</string>
@@ -474,7 +470,6 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Rodyti profilį"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Pridėti naudotoją"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Naujas naudotojas"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Baigti svečio sesiją"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Pašalinti svečią?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Bus ištrintos visos šios sesijos programos ir duomenys."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Pašalinti"</string>
@@ -512,7 +507,7 @@
     <string name="manage_notifications_text" msgid="6885645344647733116">"Tvarkyti"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"Istorija"</string>
     <string name="notification_section_header_incoming" msgid="850925217908095197">"Nauja"</string>
-    <string name="notification_section_header_gentle" msgid="6804099527336337197">"Tylūs"</string>
+    <string name="notification_section_header_gentle" msgid="6804099527336337197">"Tylus"</string>
     <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>
@@ -525,6 +520,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Šį įrenginį tvarko vienas iš tavo tėvų"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Šis įrenginys priklauso jūsų organizacijai ir ji gali stebėti tinklo srautą"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Šis įrenginys priklauso „<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>“ ir ji gali stebėti tinklo srautą"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Šį įrenginį teikia „<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>“"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Šis įrenginys priklauso jūsų organizacijai ir yra susietas su „<xliff:g id="VPN_APP">%1$s</xliff:g>“"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Šis įrenginys priklauso „<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>“ ir yra susietas su „<xliff:g id="VPN_APP">%2$s</xliff:g>“"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Šis įrenginys priklauso jūsų organizacijai"</string>
@@ -538,6 +534,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Darbo profilis susietas su „<xliff:g id="VPN_APP">%1$s</xliff:g>“"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Asmeninis profilis susietas su „<xliff:g id="VPN_APP">%1$s</xliff:g>“"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Šis įrenginys susietas su „<xliff:g id="VPN_APP">%1$s</xliff:g>“"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Šį įrenginį teikia „<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>“"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Įrenginio tvarkymas"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Profilio stebėjimas"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Tinklo stebėjimas"</string>
@@ -549,6 +546,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Žr. politiką"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Peržiūrėti valdiklius"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Šis įrenginys priklauso „<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>“.\n\nIT administratorius gali stebėti ir tvarkyti nustatymus, įmonės prieigą, programas, su įrenginiu susietus duomenis ir įrenginio vietovės informaciją.\n\nDaugiau informacijos galite gauti susisiekę su IT administratoriumi."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"„<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g>“ gali pasiekti duomenis, susietus su šiuo įrenginiu, tvarkyti programas ir pakeisti šio įrenginio nustatymus.\n\nJei kyla klausimų, susisiekite su „<xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>“."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Šis įrenginys priklauso jūsų organizacijai.\n\nIT administratorius gali stebėti ir tvarkyti nustatymus, įmonės prieigą, programas, su įrenginiu susietus duomenis ir įrenginio vietovės informaciją.\n\nDaugiau informacijos galite gauti susisiekę su IT administratoriumi."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Jūsų organizacija įdiegė šiame įrenginyje sertifikato įgaliojimą. Jūsų saugaus tinklo srautas gali būti stebimas arba keičiamas."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Jūsų organizacija įdiegė darbo profilyje sertifikato įgaliojimą. Jūsų saugaus tinklo srautas gali būti stebimas arba keičiamas."</string>
@@ -659,6 +657,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Rodyti demonstraciniu režimu"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Eternetas"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Signalas"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Piniginė"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Paruošta"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Darbo profilis"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Lėktuvo režimas"</string>
     <string name="add_tile" msgid="6239678623873086686">"Pridėti išklotinės elementą"</string>
@@ -909,11 +909,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Uždaryti sparčiuosius nustatymus."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Signalas nustatytas."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Prisijungta kaip <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"pasirinktumėte naudotoją"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Nėra interneto ryšio"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Atidaryti išsamią informaciją."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"Nepasiekiama dėl <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Atidaryti „<xliff:g id="ID_1">%s</xliff:g>“ nustatymus."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Redaguoti nustatymų tvarką."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Įjungimo meniu"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_1">%1$d</xliff:g> psl. iš <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Užrakinimo ekranas"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"Telefonas išjungt., nes įkaito"</string>
@@ -1021,9 +1023,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Perkelti kairėn"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Perkelti dešinėn"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Didinimo jungiklis"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Didinti visą ekraną"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Viso ekrano didinimas"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Didinti ekrano dalį"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Perjungti"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"Pritaikomumo gestas pakeistas pritaikomumo mygtuku\n\n"<annotation id="link">"Žr. nustatymus"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Perkelkite mygtuką prie krašto, kad laikinai jį paslėptumėte"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Įrenginio valdikliai"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Pridėkite prijungtų įrenginių valdiklių"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Įrenginio valdiklių nustatymas"</string>
@@ -1093,6 +1097,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Naujo įrenginio susiejimas"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Pokalbio valdikliai"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Palieskite pokalbį, kad pridėtumėte jį prie pagrindinio ekrano"</string>
+    <string name="timestamp" msgid="6577851592534538533">"Prieš <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"Mažiau nei prieš <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"Daugiau nei prieš <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Gimimo diena"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Netrukus gimtadienis"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Sukaktis"</string>
+    <string name="location_status" msgid="1294990572202541812">"Vieta bendrinama"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Nauja istorija"</string>
+    <string name="video_status" msgid="4548544654316843225">"Žiūri"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Klausoma"</string>
+    <string name="game_status" msgid="1340694320630973259">"Leidžiama"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Draugai"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Pakalbėkime šįvakar!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"Praleistas skambutis"</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="battery_state_unknown_notification_title" msgid="8464703640483773454">"Nuskaitant akumuliatoriaus skaitiklį iškilo problema"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Palieskite, kad sužinotumėte daugiau informacijos"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nenustatyta signalų"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 225b9aa..c355784 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Atcelt"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Kopīgot"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Ekrāna ierakstīšana ir atcelta."</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Ekrāna ieraksts ir saglabāts"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Pieskarieties, lai skatītu"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Dzēšot ekrāna ierakstu, radās kļūda."</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Neizdevās iegūt atļaujas."</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Sākot ierakstīt ekrāna saturu, radās kļūda."</string>
@@ -362,7 +360,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Jauns lietotājs"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Internets"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Var izmantot lidojuma režīmā"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Tīkli ir pieejami"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Tīkli nav pieejami"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Nav izveidots savienojums"</string>
@@ -417,7 +414,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Līdz saullēktam"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Plkst. <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Līdz plkst. <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Samazināt spilgtumu"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC ir atspējoti"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC ir iespējoti"</string>
@@ -472,7 +468,6 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Parādīt profilu"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Lietotāja pievienošana"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Jauns lietotājs"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Beigt viesa sesiju"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Vai noņemt viesi?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Tiks dzēstas visas šīs sesijas lietotnes un dati."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Noņemt"</string>
@@ -522,6 +517,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Šo ierīci pārvalda viens no jūsu vecākiem."</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Šī ierīce pieder jūsu organizācijai, un jūsu organizācija var uzraudzīt tīkla datplūsmu."</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Šī ierīce pieder organizācijai<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, un šī organizācija var uzraudzīt tīkla datplūsmu."</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Šo ierīci nodrošina <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Šī ierīce pieder jūsu organizācijai un ir saistīta ar: <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Šī ierīce pieder organizācijai <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> un ir savienota ar: <xliff:g id="VPN_APP">%2$s</xliff:g>."</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Šī ierīce pieder jūsu organizācijai."</string>
@@ -535,6 +531,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Jūsu darba profils ir savienots ar: <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Jūsu personīgais profils ir saistīts ar: <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Šī ierīce ir savienota ar: <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Šo ierīci nodrošina <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Ierīces pārvaldība"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Profila pārraudzība"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Tīkla pārraudzība"</string>
@@ -546,6 +543,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Skatīt politikas"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Skatīt vadīklas"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Šī ierīce pieder organizācijai <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nJūsu IT administrators var pārraudzīt un pārvaldīt iestatījumus, korporatīvo piekļuvi, lietotnes, ar ierīci saistītos datus un ierīces atrašanās vietas informāciju.\n\nLai iegūtu plašāku informāciju, sazinieties ar IT administratoru."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"Iespējams, organizācija <xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> var piekļūt ar šo ierīci saistītajiem datiem, pārvaldīt lietotnes un mainīt šīs ierīces iestatījumus.\n\nJa jums ir jautājumi, sazinieties ar organizāciju <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Šī ierīce pieder jūsu organizācijai.\n\nJūsu IT administrators var pārraudzīt un pārvaldīt iestatījumus, korporatīvo piekļuvi, lietotnes, ar ierīci saistītos datus un ierīces atrašanās vietas informāciju.\n\nLai iegūtu plašāku informāciju, sazinieties ar IT administratoru."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Jūsu organizācija instalēja sertifikātu šajā ierīcē. Jūsu drošā tīkla datplūsma var tikt uzraudzīta."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Jūsu organizācija instalēja sertifikātu jūsu darba profilā. Jūsu drošā tīkla datplūsma var tikt uzraudzīta."</string>
@@ -656,6 +654,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Rādīt demonstrācijas režīmu"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Tīkls Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Signāls"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Maks"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Gatavs"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Darba profils"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Lidojuma režīms"</string>
     <string name="add_tile" msgid="6239678623873086686">"Pievienot elementu"</string>
@@ -724,7 +724,7 @@
     <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"&lt;b&gt;Statuss:&lt;/b&gt; svarīgums pazemināts, un paziņojums tiks rādīts bez skaņas"</string>
     <string name="notification_channel_summary_automatic_promoted" msgid="1301710305149590426">"&lt;b&gt;Statuss:&lt;/b&gt; rangs paaugstināts"</string>
     <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" msgid="7952654515769021553">"Parādās sarunu sadaļas augšdaļā un kā peldošs burbulis, kā arī bloķēšanas ekrānā tiek rādīts profila attēls"</string>
+    <string name="notification_channel_summary_priority" msgid="7952654515769021553">"Parādās sarunu sadaļas augšdaļā, arī kā peldošs burbulis, profila attēls parādās bloķēšanas ekrānā"</string>
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Iestatījumi"</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>
@@ -904,11 +904,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Aizvērt ātros iestatījumus."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Signāls ir iestatīts."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Pierakstījies kā <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"izvēlēties lietotāju"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Nav piekļuves internetam"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Atvērt detalizēto informāciju."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"Nav pieejams šāda iemesla dēļ: <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Atvērt <xliff:g id="ID_1">%s</xliff:g> iestatījumus."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Rediģēt iestatījumu secību."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Barošanas izvēlne"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_1">%1$d</xliff:g>. lpp. no <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Bloķēšanas ekrāns"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"Tālrunis izslēgts karstuma dēļ"</string>
@@ -1016,9 +1018,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Pārvietot pa kreisi"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Pārvietot pa labi"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Palielinājuma slēdzis"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Palielināt visu ekrānu"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Palielināt visu ekrānu"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Palielināt ekrāna daļu"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Pārslēgt"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"Pieejamības žests ir aizstāts ar pieejamības pogu\n\n"<annotation id="link">"Skatīt iestatījumus"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Lai īslaicīgi paslēptu pogu, pārvietojiet to uz malu"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Ierīču vadīklas"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Pievienojiet vadīklas pievienotajām ierīcēm"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Ierīču vadīklu iestatīšana"</string>
@@ -1087,6 +1091,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Savienošana pārī ar jaunu ierīci"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Sarunu logrīki"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Pieskarieties kādai sarunai, lai pievienotu to savam sākuma ekrānam."</string>
+    <string name="timestamp" msgid="6577851592534538533">"Pirms šāda laika: <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"Pirms mazāk nekā: <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"Pirms vairāk nekā: <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Dzimšanas diena"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Gaidāma dzimšanas diena"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Gadadiena"</string>
+    <string name="location_status" msgid="1294990572202541812">"Tiek kopīgota vieta…"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Jauns raksts"</string>
+    <string name="video_status" msgid="4548544654316843225">"Notiek skatīšanās…"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Notiek klausīšanās…"</string>
+    <string name="game_status" msgid="1340694320630973259">"Tiek spēlēta spēle…"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Draugi"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Patērzēsim šovakar!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"Neatbildēts zvans"</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="battery_state_unknown_notification_title" msgid="8464703640483773454">"Nevar iegūt informāciju par akumulatora uzlādes līmeni."</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Pieskarieties, lai iegūtu plašāku informāciju."</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nav iestatīts signāls"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index c74786e..06718c1 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Откажи"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Сподели"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Снимањето екран е откажано"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Снимката од екранот е зачувана"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Допрете за да прегледате"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Грешка при бришењето на снимката од екранот"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Не успеаја да се добијат дозволи"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Грешка при почетокот на снимањето на екранот"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Нов корисник"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Интернет"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Безбедно за во авион"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Мрежите се достапни"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Мрежите се недостапни"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Не е поврзано"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"До изгрејсонце"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Се вклучува во <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"До <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Намалување на осветленоста"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC е оневозможено"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC е овозможено"</string>
@@ -470,7 +466,6 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Прикажи го профилот"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Додај корисник"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Нов корисник"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Заврши ја гостинската сесија"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Да се отстрани гостинот?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Сите апликации и податоци во сесијата ќе се избришат."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Отстрани"</string>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Родителот управува со уредов"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Организацијата е сопственик на уредов и може да го следи мрежниот сообраќај"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> е сопственик на уредов и може да го следи мрежниот сообраќај"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> го обезбедува уредов"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Уредов е во сопственост на организацијата и е поврзан со <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Уредов е во сопственост на <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> и е поврзан со <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Уредов е во сопственост на организацијата"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Вашиот работен профил е поврзан со <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Вашиот личен профил е поврзан со <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Уредов е поврзан со <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> го обезбедува уредов"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Управување со уреди"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Следење профил"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Следење на мрежата"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Прикажи „Политики“"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Прикажи ги контролите"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Уредов е во сопственост на <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nIT-администраторот може да ги следи и да управува со поставките, корпоративниот пристап, апликациите, податоците поврзани со уредот и податоците за локацијата на уредот.\n\nЗа повеќе информации, контактирајте со IT-администраторот."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> можеби ќе може да пристапува до податоците поврзани со уредов, да управува со апликациите и да ги менува поставките на уредов.\n\nАко имате прашања, контактирајте со <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Уредов е во сопственост на организацијата.\n\nIT-администраторот може да ги следи и да управува со поставките, корпоративниот пристап, апликациите, податоците поврзани со уредот и податоците за локацијата на уредот.\n\nЗа повеќе информации, контактирајте со IT-администраторот."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Вашата организација инсталираше авторитет за сертификат на уредов. Сообраќајот на вашата безбедна мрежа можно е да се следи или изменува."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Вашата организација инсталираше авторитет за сертификат на вашиот работен профил. Вашиот безбеден мрежен сообраќај можно е да се следи или изменува."</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Прикажи демо-режим"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Етернет"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Аларм"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Паричник"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Подготвено"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Работен профил"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Авионски режим"</string>
     <string name="add_tile" msgid="6239678623873086686">"Додај плочка"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Затворете ги брзите поставки."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Поставен е аларм."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Најавени сте како <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"изберете корисник"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Нема интернет"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Отворете ги деталите."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"Недостапно бидејќи <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Отворете ги поставките на <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Уредете го редоследот на поставките."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Мени на копчето за вклучување"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Страница <xliff:g id="ID_1">%1$d</xliff:g> од <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Заклучен екран"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"Телефонот се исклучи поради загреаност"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Премести налево"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Премести надесно"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Прекинувач за зголемување"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Зголеми цел екран"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Зголемете го целиот екран"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Зголеми дел од екранот"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Префрли"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"Копчето за пристапност го замени движењето за пристапност\n\n"<annotation id="link">"Прикажи поставки"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Преместете го копчето до работ за да го сокриете привремено"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Контроли за уредите"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Додајте контроли за поврзаните уреди"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Поставете ги контролите за уредите"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Спарете нов уред"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Виџети за разговор"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Допрете на разговор за да го додадете на вашиот почетен екран"</string>
+    <string name="timestamp" msgid="6577851592534538533">"Пред <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"Пред помалку од <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"Пред повеќе од <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Роденден"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Претстоен роденден"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Годишнина"</string>
+    <string name="location_status" msgid="1294990572202541812">"Споделување локација"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Нова приказна"</string>
+    <string name="video_status" msgid="4548544654316843225">"Гледање видео"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Слушам"</string>
+    <string name="game_status" msgid="1340694320630973259">"Играње игра"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Пријатели"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Разговарај вечерва!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"Пропуштен повик"</string>
+    <string name="people_tile_description" msgid="8154966188085545556">"Видете ги неодамнешните пораки, пропуштени повици и промени на статусот"</string>
+    <string name="people_tile_title" msgid="6589377493334871272">"Разговор"</string>
     <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Проблем при читањето на мерачот на батеријата"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Допрете за повеќе информации"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Нема поставен аларм"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index b54c6b0..36a8a54 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"റദ്ദാക്കുക"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"പങ്കിടുക"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"സ്ക്രീൻ റെക്കോർഡിംഗ് റദ്ദാക്കി"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"സ്ക്രീൻ റെക്കോർഡിംഗ് സംരക്ഷിച്ചു"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"കാണാൻ ടാപ്പ് ചെയ്യുക"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"സ്ക്രീൻ റെക്കോർഡിംഗ് ഇല്ലാതാക്കുന്നതിൽ പിശക്"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"അനുമതികൾ ലഭിച്ചില്ല"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"സ്ക്രീൻ റെക്കോർഡിംഗ് ആരംഭിക്കുന്നതിൽ പിശക്"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"പുതിയ ഉപയോക്താവ്"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"വൈഫൈ"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"ഇന്റർനെറ്റ്"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"വിമാന-സുരക്ഷിതം"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"നെറ്റ്‌വർക്കുകൾ ലഭ്യമാണ്"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"നെറ്റ്‌വർക്കുകൾ ലഭ്യമല്ല"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"കണ‌ക്റ്റ് ചെയ്‌തിട്ടില്ല"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"സൂര്യോദയം വരെ"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g>-ന്"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> വരെ"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"തെളിച്ചം കുറയ്ക്കുക"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC പ്രവർത്തനരഹിതമാക്കി"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC പ്രവർത്തനക്ഷമമാക്കി"</string>
@@ -470,11 +466,10 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"പ്രൊഫൈൽ കാണിക്കുക"</string>
     <string name="user_add_user" msgid="4336657383006913022">"ഉപയോക്താവിനെ ചേര്‍ക്കുക"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"പുതിയ ഉപയോക്താവ്"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"അതിഥി സെഷൻ അവസാനിപ്പിക്കുക"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"അതിഥിയെ നീക്കംചെയ്യണോ?"</string>
-    <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ഈ സെഷനിലെ എല്ലാ അപ്ലിക്കേഷനുകളും ഡാറ്റയും ഇല്ലാതാക്കും."</string>
+    <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ഈ സെഷനിലെ എല്ലാ ആപ്പുകളും ഡാറ്റയും ഇല്ലാതാക്കും."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"നീക്കംചെയ്യുക"</string>
-    <string name="guest_wipe_session_title" msgid="7147965814683990944">"അതിഥിയ്‌ക്ക് വീണ്ടും സ്വാഗതം!"</string>
+    <string name="guest_wipe_session_title" msgid="7147965814683990944">"അതിഥി, വീണ്ടും സ്വാഗതം!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"നിങ്ങളുടെ സെഷൻ തുടരണോ?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"പുനരാംരംഭിക്കുക"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"അതെ, തുടരുക"</string>
@@ -485,7 +480,7 @@
     <string name="user_logout_notification_text" msgid="7441286737342997991">"നിലവിലെ ഉപയോക്താവിനെ ലോഗൗട്ട് ചെയ്യുക"</string>
     <string name="user_logout_notification_action" msgid="7974458760719361881">"ഉപയോക്താവിനെ ലോഗൗട്ട് ചെയ്യുക"</string>
     <string name="user_add_user_title" msgid="4172327541504825032">"പുതിയ ഉപയോക്താവിനെ ചേർക്കണോ?"</string>
-    <string name="user_add_user_message_short" msgid="2599370307878014791">"നിങ്ങൾ ഒരു പുതിയ ഉപയോക്താവിനെ ചേർക്കുമ്പോൾ, ആ വ്യക്തിക്ക് അവരുടെ ഇടം സജ്ജീകരിക്കേണ്ടതുണ്ട്.\n\nമറ്റ് എല്ലാ ഉപയോക്താക്കൾക്കുമായി ഏതൊരു ഉപയോക്താവിനും അപ്ലിക്കേഷനുകൾ അപ്‌ഡേറ്റ് ചെയ്യാനാവും."</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"നിങ്ങൾ പുതിയൊരു ഉപയോക്താവിനെ ചേർക്കുമ്പോൾ, ആ വ്യക്തിക്ക് അവരുടെ ഇടം സജ്ജീകരിക്കേണ്ടതുണ്ട്.\n\nമറ്റ് എല്ലാ ഉപയോക്താക്കൾക്കുമായി ഏതൊരു ഉപയോക്താവിനും ആപ്പുകൾ അപ്‌ഡേറ്റ് ചെയ്യാനാവും."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"ഉപയോക്തൃ പരിധി എത്തി"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">നിങ്ങൾക്ക് <xliff:g id="COUNT">%d</xliff:g> ഉപയോക്താക്കളെ വരെ ചേർക്കാനാവും.</item>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ഈ ഉപകരണം മാനേജ് ചെയ്യുന്നത് നിങ്ങളുടെ രക്ഷിതാവാണ്"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ഈ ഉപകരണം നിങ്ങളുടെ സ്ഥാപനത്തിന്റെ ഉടമസ്ഥതയിലായതിനാൽ നെറ്റ്‌വർക്ക് ട്രാഫിക്ക് നിരീക്ഷിച്ചേക്കാം"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"ഈ ഉപകരണം <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> എന്ന സ്ഥാപനത്തിന്റെ ഉടമസ്ഥതയിലായതിനാൽ നെറ്റ്‌വർക്ക് ട്രാഫിക്ക് നിരീക്ഷിച്ചേക്കാം"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> നൽകിയ ഉപകരണമാണിത്"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"ഈ ഉപകരണം നിങ്ങളുടെ സ്ഥാപനത്തിന്റേതാണ്, കൂടാതെ <xliff:g id="VPN_APP">%1$s</xliff:g> എന്നതിലേക്ക് കണക്റ്റ് ചെയ്‌തിരിക്കുന്നു"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"ഈ ഉപകരണം <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> എന്ന സ്ഥാപനത്തിന്റേതാണ്, കൂടാതെ <xliff:g id="VPN_APP">%2$s</xliff:g> എന്നതിലേക്ക് കണക്റ്റ് ചെയ്തിരിക്കുന്നു"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"ഈ ഉപകരണം നിങ്ങളുടെ സ്ഥാപനത്തിന്റേതാണ്"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"<xliff:g id="VPN_APP">%1$s</xliff:g> എന്നതിലേക്ക് നിങ്ങളുടെ ഔദ്യോഗിക പ്രൊഫൈൽ കണക്റ്റ് ചെയ്‌തിരിക്കുന്നു"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"നിങ്ങളുടെ വ്യക്തിപരമായ പ്രൊഫൈൽ <xliff:g id="VPN_APP">%1$s</xliff:g> ആപ്പിലേക്ക് കണക്റ്റ് ചെയ്‌തിരിക്കുന്നു"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"ഈ ഉപകരണം <xliff:g id="VPN_APP">%1$s</xliff:g> എന്നതിലേക്ക് കണക്റ്റ് ചെയ്തിരിക്കുന്നു"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> നൽകിയ ഉപകരണമാണിത്"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"ഉപകരണ മാനേജ്‌മെന്റ്"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"പ്രൊഫൈൽ നിരീക്ഷിക്കൽ"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"നെറ്റ്‌വർക്ക് നിരീക്ഷിക്കൽ"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"നയങ്ങൾ കാണുക"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"നിയന്ത്രണങ്ങൾ കാണുക"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"ഈ ഉപകരണം <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>എന്ന സ്ഥാപനത്തിന്റേതാണ്.\n\nക്രമീകരണം, കോർപ്പറേറ്റ് ആക്‌സസ്, ആപ്പുകൾ, നിങ്ങളുടെ ഉപകരണവുമായി ബന്ധപ്പെട്ട ഡാറ്റ, ഉപകരണത്തിന്റെ ലൊക്കേഷൻ ‌വിവരങ്ങൾ എന്നിവ നിരീക്ഷിക്കാനും മാനേജ് ചെയ്യാനും നിങ്ങളുടെ ഐടി അഡ്‌മിന് കഴിയും.\n\nകൂടുതൽ വിവരങ്ങൾക്ക് നിങ്ങളുടെ ഐടി അഡ്‌മിനെ ബന്ധപ്പെടുക."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"ഈ ഉപകരണവുമായി ബന്ധപ്പെട്ട ഡാറ്റ ആക്‌സസ് ചെയ്യാനും ആപ്പുകൾ മാനേജ് ചെയ്യാനും ഈ ഉപകരണത്തിന്റെ ക്രമീകരണം മാറ്റാനും <xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> എന്നതിന് കഴിഞ്ഞേക്കാം.\n\nനിങ്ങൾക്ക് ചോദ്യങ്ങളുണ്ടെങ്കിൽ <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g> എന്നതുമായി ബന്ധപ്പെടുക."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"ഈ ഉപകരണം നിങ്ങളുടെ സ്ഥാപനത്തിന്റേതാണ്.\n\nക്രമീകരണം, കോർപ്പറേറ്റ് ആക്‌സസ്, ആപ്പുകൾ, നിങ്ങളുടെ ഉപകരണവുമായി ബന്ധപ്പെട്ട ഡാറ്റ, ഉപകരണത്തിന്റെ ലൊക്കേഷൻ ‌വിവരങ്ങൾ എന്നിവ നിരീക്ഷിക്കാനും മാനേജ് ചെയ്യാനും നിങ്ങളുടെ ഐടി അഡ്‌മിന് കഴിയും.\n\nകൂടുതൽ വിവരങ്ങൾക്ക് നിങ്ങളുടെ ഐടി അഡ്‌മിനെ ബന്ധപ്പെടുക."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"ഈ ഉപകരണത്തിൽ നിങ്ങളുടെ സ്ഥാപനമൊരു സർട്ടിഫിക്കറ്റ് അതോറിറ്റി ഇൻസ്റ്റാൾ ചെയ്തിരിക്കുന്നു. നിങ്ങളുടെ സുരക്ഷിത നെറ്റ്‌വർക്ക് ട്രാഫിക്ക് നിരീക്ഷിക്കപ്പെടുകയോ പരിഷ്കരിക്കപ്പെടുയോ ചെയ്തേക്കാം."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"നിങ്ങളുടെ ഔദ്യോഗിക പ്രൊഫൈലിൽ നിങ്ങളുടെ സ്ഥാപനമൊരു സർട്ടിഫിക്കറ്റ് അതോറിറ്റി ഇൻസ്റ്റാൾ ചെയ്തിരിക്കുന്നു. നിങ്ങളുടെ സുരക്ഷിത നെറ്റ്‌വർക്ക് ട്രാഫിക്ക് നിരീക്ഷിക്കപ്പെടുകയോ പരിഷ്കരിക്കപ്പെടുയോ ചെയ്തേക്കാം."</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"ഡെമോ മോഡ് കാണിക്കുക"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"ഇതർനെറ്റ്"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"അലാറം"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"തയ്യാറാണ്"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"ഔദ്യോഗിക പ്രൊഫൈൽ"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"ഫ്ലൈറ്റ് മോഡ്"</string>
     <string name="add_tile" msgid="6239678623873086686">"ടൈൽ ചേർക്കുക"</string>
@@ -713,7 +713,7 @@
     <string name="notification_automatic_title" msgid="3745465364578762652">"സ്വയമേവ"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"ശബ്ദമോ വൈബ്രേഷനോ ഇല്ല"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"ശബ്‌ദമോ വൈബ്രേഷനോ ഇല്ല, സംഭാഷണ വിഭാഗത്തിന് താഴെയായി ദൃശ്യമാകും"</string>
-    <string name="notification_channel_summary_default" msgid="3282930979307248890">"ഫോൺ ക്രമീകരണം അടിസ്ഥാനമാക്കി റിംഗ് ചെയ്‌തേക്കാം അല്ലെങ്കിൽ വൈബ്രേറ്റ് ചെയ്‌തേക്കാം"</string>
+    <string name="notification_channel_summary_default" msgid="3282930979307248890">"ഫോൺ ക്രമീകരണം അടിസ്ഥാനമാക്കി റിംഗ്/വൈബ്രേറ്റ് ചെയ്യും"</string>
     <string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"ഫോൺ ക്രമീകരണം അടിസ്ഥാനമാക്കി റിംഗ് ചെയ്‌തേക്കാം അല്ലെങ്കിൽ വൈബ്രേറ്റ് ചെയ്‌തേക്കാം. <xliff:g id="APP_NAME">%1$s</xliff:g>-ൽ നിന്നുള്ള സംഭാഷണങ്ങൾ ഡിഫോൾട്ടായി ബബ്ൾ ആവുന്നു."</string>
     <string name="notification_channel_summary_bubble" msgid="7235935211580860537">"ഈ ഉള്ളടക്കത്തിലേക്ക് ഒരു ഫ്ലോട്ടിംഗ് കുറുക്കുവഴി ഉപയോഗിച്ച് നിങ്ങളുടെ ശ്രദ്ധ നിലനിർത്തുന്നു."</string>
     <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"ഈ അറിയിപ്പ് വരുമ്പോൾ ശബ്‌ദിക്കുകയാണോ വൈബ്രേറ്റ് ചെയ്യുകയാണോ വേണ്ടതെന്ന് നിർണ്ണയിക്കാൻ സിസ്‌റ്റത്തെ അനുവദിക്കുക"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"ദ്രുത ക്രമീകരണം അടയ്ക്കുക."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"അലാറം സജ്ജമാക്കി."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"<xliff:g id="ID_1">%s</xliff:g> ആയി സൈൻ ഇൻ ചെയ്‌തു"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"ഉപയോക്താവിനെ തിരഞ്ഞെടുക്കുക"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"ഇന്റർനെറ്റ് ഇല്ല"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"വിശദാംശങ്ങൾ തുറക്കുക."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"<xliff:g id="REASON">%s</xliff:g> എന്ന കാരണത്താൽ ലഭ്യമല്ല"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> ക്രമീകരണം തുറക്കുക."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"ക്രമീകരണ ക്രമം എഡിറ്റുചെയ്യുക."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"പവർ മെനു"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"പേജ് <xliff:g id="ID_1">%1$d</xliff:g> / <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"ലോക്ക് സ്‌ക്രീൻ"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"ചൂട് കൂടിയതിനാൽ ഫോൺ ഓഫാക്കി"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"ഇടത്തേക്ക് നീക്കുക"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"വലത്തേക്ക് നീക്കുക"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"മാഗ്നിഫിക്കേഷൻ മോഡ് മാറുക"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"മുഴുവൻ സ്‌ക്രീനും മാഗ്നിഫൈ ചെയ്യുക"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"സ്ക്രീൻ പൂർണ്ണമായും മാഗ്നിഫൈ ചെയ്യുക"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"സ്‌ക്രീനിന്റെ ഭാഗം മാഗ്നിഫൈ ചെയ്യുക"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"മാറുക"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"ഉപയോഗസഹായി വിരൽചലനത്തെ മാറ്റി പകരം ഉപയോഗസഹായി ബട്ടൺ വന്നു\n\n"<annotation id="link">"ക്രമീകരണം കാണുക"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"തൽക്കാലം മറയ്‌ക്കുന്നതിന് ബട്ടൺ അരുകിലേക്ക് നീക്കുക"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"ഉപകരണ നിയന്ത്രണങ്ങൾ"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"കണക്റ്റ് ചെയ്ത ഉപകരണങ്ങൾക്ക് നിയന്ത്രണങ്ങൾ ചേർക്കുക"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"ഉപകരണ നിയന്ത്രണങ്ങൾ സജ്ജീകരിക്കുക"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"പുതിയ ഉപകരണവുമായി ജോടിയാക്കുക"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"സംഭാഷണ വിജറ്റുകൾ"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"നിങ്ങളുടെ ഹോം സ്‌ക്രീനിൽ ചേർക്കാൻ സംഭാഷണത്തിൽ ടാപ്പ് ചെയ്യുക"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> മുമ്പ്"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"<xliff:g id="DURATION">%1$s</xliff:g> എന്നതിൽ കുറവ്"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"<xliff:g id="DURATION">%1$s</xliff:g> മുമ്പ്"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"ജന്മദിനം"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"ഉടൻ വരുന്ന ജന്മദിനം"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"വാര്‍‌ഷികം"</string>
+    <string name="location_status" msgid="1294990572202541812">"ലൊക്കേഷൻ പങ്കിടുന്നു"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"പുതിയ വാർത്ത"</string>
+    <string name="video_status" msgid="4548544654316843225">"കാണുന്നു"</string>
+    <string name="audio_status" msgid="4237055636967709208">"കേൾക്കുന്നു"</string>
+    <string name="game_status" msgid="1340694320630973259">"കളിക്കുന്നു"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"സുഹൃത്തുക്കൾ"</string>
+    <string name="empty_status" msgid="5938893404951307749">"ഇന്നുരാത്രി ചാറ്റുചെയ്യാം!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"മിസ്‌ഡ് കോൾ"</string>
+    <string name="people_tile_description" msgid="8154966188085545556">"അടുത്തിടെയുള്ള സന്ദേശങ്ങൾ, മിസ്‌ഡ് കോളുകൾ, സ്റ്റാറ്റസ് അപ്‌ഡേറ്റുകൾ എന്നിവ കാണുക"</string>
+    <string name="people_tile_title" msgid="6589377493334871272">"സംഭാഷണം"</string>
     <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"നിങ്ങളുടെ ബാറ്ററി മീറ്റർ വായിക്കുന്നതിൽ പ്രശ്‌നമുണ്ട്"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"കൂടുതൽ വിവരങ്ങൾക്ക് ടാപ്പ് ചെയ്യുക"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"അലാറം സജ്ജീകരിച്ചിട്ടില്ല"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 93d66f4..fdf0eab 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Цуцлах"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Хуваалцах"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Дэлгэцийн бичлэгийг цуцалсан"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Дэлгэцийн бичлэгийг хадгалсан"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Харахын тулд товшино уу"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Дэлгэцийн бичлэгийг устгахад алдаа гарлаа"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Зөвшөөрөл авч чадсангүй"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Дэлгэцийн бичлэгийг эхлүүлэхэд алдаа гарлаа"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Шинэ хэрэглэгч"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Интернэт"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Аюулгүй нислэг"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Сүлжээ боломжтой"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Сүлжээ боломжгүй"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Холбогдоогүй"</string>
@@ -380,7 +377,7 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="2325362583903258677">"АВТОМАТ"</string>
     <string name="quick_settings_inversion_label" msgid="5078769633069667698">"Өнгийг урвуулах"</string>
     <string name="quick_settings_color_space_label" msgid="537528291083575559">"Өнгө залруулах горим"</string>
-    <string name="quick_settings_more_settings" msgid="2878235926753776694">"Өөр тохиргоо"</string>
+    <string name="quick_settings_more_settings" msgid="2878235926753776694">"Бусад тохиргоо"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Дууссан"</string>
     <string name="quick_settings_connected" msgid="3873605509184830379">"Холбогдсон"</string>
     <string name="quick_settings_connected_battery_level" msgid="1322075669498906959">"Холбогдсон, батерей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Нар мандах хүртэл"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g>-д"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> хүртэл"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Гэрэлтүүлгийг багасгах"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC-г цуцалсан"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC-г идэвхжүүлсэн"</string>
@@ -470,11 +466,10 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Профайлыг харуулах"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Хэрэглэгч нэмэх"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Шинэ хэрэглэгч"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Зочны сургалтыг дуусгах"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Зочныг хасах уу?"</string>
-    <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Энэ сешний бүх апп болон дата устах болно."</string>
+    <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Энэ харилцан үйлдлийн бүх апп болон дата устах болно."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Хасах"</string>
-    <string name="guest_wipe_session_title" msgid="7147965814683990944">"Тавтай морилно уу!"</string>
+    <string name="guest_wipe_session_title" msgid="7147965814683990944">"Эргэн тавтай морилно уу!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Та үргэлжлүүлэхийг хүсэж байна уу?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Дахин эхлүүлэх"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Тийм, үргэлжлүүлэх"</string>
@@ -485,7 +480,7 @@
     <string name="user_logout_notification_text" msgid="7441286737342997991">"Одоогийн хэрэглэгчийг гаргах"</string>
     <string name="user_logout_notification_action" msgid="7974458760719361881">"ХЭРЭГЛЭГЧЭЭС ГАРАХ"</string>
     <string name="user_add_user_title" msgid="4172327541504825032">"Шинэ хэрэглэгч нэмэх үү?"</string>
-    <string name="user_add_user_message_short" msgid="2599370307878014791">"Та шинэ хэрэглэгч нэмбэл тухайн хүн өөрийн профайлыг тохируулах шаардлагатай.\n\nАль ч хэрэглэгч бүх хэрэглэгчийн апп-уудыг шинэчлэх боломжтой."</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Та шинэ хэрэглэгч нэмбэл тухайн хүн өөрийн профайлыг тохируулах шаардлагатай.\n\nАль ч хэрэглэгч бүх хэрэглэгчийн аппуудыг шинэчлэх боломжтой."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Хэрэглэгчийн хязгаарт хүрсэн"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Та <xliff:g id="COUNT">%d</xliff:g> хүртэлх хэрэглэгч нэмэх боломжтой.</item>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Энэ төхөөрөмжийг таны эцэг эх удирддаг"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Танай байгууллага энэ төхөөрөмжийг эзэмшдэг бөгөөд сүлжээний ачааллыг хянаж болно"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> энэ төхөөрөмжийг эзэмшдэг бөгөөд сүлжээний ачааллыг хянаж болно"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Энэ төхөөрөмжийг <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>-с нийлүүлдэг"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Энэ төхөөрөмж танай байгууллагад харьяалагддаг бөгөөд <xliff:g id="VPN_APP">%1$s</xliff:g>-д холбогдсон байна"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Энэ төхөөрөмж <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>-д харьяалагддаг бөгөөд <xliff:g id="VPN_APP">%2$s</xliff:g>-д холбогдсон байна"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Энэ төхөөрөмж танай байгууллагад харьяалагддаг"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Таны ажлын профайл <xliff:g id="VPN_APP">%1$s</xliff:g>-д холбогдсон байна"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Таны хувийн профайл <xliff:g id="VPN_APP">%1$s</xliff:g>-д холбогдсон байна"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Энэ төхөөрөмж <xliff:g id="VPN_APP">%1$s</xliff:g>-д холбогдсон байна"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Энэ төхөөрөмжийг <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>-с нийлүүлдэг"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Төхөөрөмжийн удирдлага"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Профайл хяналт"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Сүлжээний хяналт"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Удирдамж харах"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Хяналтыг харах"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Энэ төхөөрөмж <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>-д харьяалагддаг.\n\nТанай IT админ тохиргоо, байгууллагын хандалт, аппууд, таны төхөөрөмжтэй холбоотой өгөгдөл, таны төхөөрөмжийн байршлын мэдээллийг хянах, удирдах боломжтой.\n\nНэмэлт мэдээлэл авахын тулд IT админтайгаа холбогдоно уу."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> нь энэ төхөөрөмжтэй холбоотой өгөгдөлд хандаж, аппуудыг удирдаж, энэ төхөөрөмжийн тохиргоог өөрчлөх боломжтой байж болзошгүй.\n\nХэрэв танд асуух зүйл байвал <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>-тай холбогдоно уу."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Энэ төхөөрөмж танай байгууллагад харьяалагддаг.\n\nТанай IT админ тохиргоо, байгууллагын хандалт, аппууд, таны төхөөрөмжтэй холбоотой өгөгдөл, таны төхөөрөмжийн байршлын мэдээллийг хянах, удирдах боломжтой.\n\nНэмэлт мэдээлэл авахын тулд IT админтайгаа холбогдоно уу."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Таны байгууллага энэ төхөөрөмжид сертификатын зөвшөөрлийг суулгасан байна. Таны аюулгүй сүлжээний ачааллыг өөрчлөх эсвэл хянах боломжтой."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Таны байгууллага таны ажлын профайлд сертификатын зөвшөөрөл суулгасан байна. Таны аюулгүй сүлжээний ачааллыг өөрчлөх эсвэл хянах боломжтой."</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Демо горимыг харуулах"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Этернет"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Сэрүүлэг"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Түрийвч"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Бэлэн"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Ажлын профайл"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Нислэгийн горим"</string>
     <string name="add_tile" msgid="6239678623873086686">"Вебсайтын цонх нэмэх"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Хурдан тохиргоог хаана уу."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Сэрүүлэг тавьсан."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"<xliff:g id="ID_1">%s</xliff:g>-р нэвтэрсэн"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"хэрэглэгчийг сонгох"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Интернэт алга"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Дэлгэрэнгүй мэдээллийг нээнэ үү."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"<xliff:g id="REASON">%s</xliff:g>-н улмаас боломжгүй байна"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> тохиргоог нээнэ үү."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Тохиргооны дарааллыг өөрчилнө үү."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Асаах/унтраах цэс"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g>-н <xliff:g id="ID_1">%1$d</xliff:g>-р хуудас"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Түгжигдсэн дэлгэц"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"Халснаас үүдэн утас унтарсан"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Зүүн тийш зөөх"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Баруун тийш зөөх"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Томруулах сэлгэлт"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Дэлгэцийг бүхэлд нь томруулах"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Бүтэн дэлгэцийг томруулах"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Дэлгэцийн нэг хэсгийг томруулах"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Сэлгэх"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"Хандалтын товчлуурыг хандалтын зангаагаар сольсон\n\n"<annotation id="link">"Тохиргоо харах"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Үүнийг түр нуухын тулд товчлуурыг зах руу зөөнө үү"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Төхөөрөмжийн хяналт"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Холбогдсон төхөөрөмжүүд дээрээ хяналт нэмэх"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Төхөөрөмжийн хяналтыг тохируулах"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Шинэ төхөөрөмж хослуулах"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Харилцан ярианы жижиг хэрэгслүүд"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Үндсэн нүүрэндээ нэмэх харилцан яриаг товшино уу"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g>-н өмнө"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"<xliff:g id="DURATION">%1$s</xliff:g>-с бага хугацааны өмнө"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"<xliff:g id="DURATION">%1$s</xliff:g>-с дээш хугацааны өмнө"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Төрсөн өдөр"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Удахгүй болох төрсөн өдөр"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Тэмдэглэлт ой"</string>
+    <string name="location_status" msgid="1294990572202541812">"Байршил хуваалцаж байна"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Шинэ стори"</string>
+    <string name="video_status" msgid="4548544654316843225">"Үзэж байна"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Сонсож байна"</string>
+    <string name="game_status" msgid="1340694320630973259">"Тоглож байна"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Найзууд"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Өнөө орой чаталъя!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"Аваагүй дуудлага"</string>
+    <string name="people_tile_description" msgid="8154966188085545556">"Саяхны мессеж, аваагүй дуудлага болон төлөвийн шинэчлэлтийг харах"</string>
+    <string name="people_tile_title" msgid="6589377493334871272">"Харилцан яриа"</string>
     <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Таны батарей хэмжигчийг уншихад асуудал гарлаа"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Нэмэлт мэдээлэл авахын тулд товшино уу"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Сэрүүлэг тавиагүй"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 093a03b..8de7c96 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"रद्द करा"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"शेअर करा"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"स्क्रीन रेकॉर्डिंग रद्द केले"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"स्क्रीन रेकॉर्डिंग सेव्ह केली"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"पाहण्यासाठी टॅप करा"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"स्क्रीन रेकॉर्डिंग हटवताना एरर आली"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"परवानग्या मिळवता आल्या नाहीत"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"स्क्रीन रेकॉर्डिंग सुरू करताना एरर आली"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"नवीन वापरकर्ता"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"वाय-फाय"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"इंटरनेट"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"विमानासाठी सुरक्षित"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"नेटवर्क उपलब्ध आहेत"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"नेटवर्क उपलब्ध नाहीत"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"कनेक्ट केले नाही"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"सूर्योदयापर्यंत"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g> वाजता सुरू होते"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> पर्यंत"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"ब्राइटनेस कमी करा"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC अक्षम केले आहे"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC सक्षम केले आहे"</string>
@@ -470,7 +466,6 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"प्रोफाईल दर्शवा"</string>
     <string name="user_add_user" msgid="4336657383006913022">"वापरकर्ता जोडा"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"नवीन वापरकर्ता"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"अतिथी सत्र संपवा"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"अतिथी काढायचे?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"या सत्रातील सर्व अ‍ॅप्स आणि डेटा हटवला जाईल."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"काढा"</string>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"हे डिव्हाइस तुमच्या पालकाने व्यवस्थापित केले आहे"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"तुमच्‍या संस्‍थेकडे या डिव्हाइसची मालकी आहे आणि ती नेटवर्क ट्रॅफिकचे परीक्षण करू शकते"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"हे डिव्हाइस <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> च्या मालकीचे आहे आणि ती नेटवर्क ट्रॅफिकचे परीक्षण करू शकते"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"हे डिव्हाइस <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> द्वारे पुरवले गेले आहे"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"हे डिव्हाइस तुमच्या संस्थेचे आहे आणि ते <xliff:g id="VPN_APP">%1$s</xliff:g> ला कनेक्ट केले आहे"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"हे डिव्हाइस <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> चे आहे आणि ते <xliff:g id="VPN_APP">%2$s</xliff:g> ला कनेक्ट केले आहे"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"हे डिव्हाइस तुमच्या संस्थेचे आहे"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"तुमची कार्य प्रोफाइल <xliff:g id="VPN_APP">%1$s</xliff:g> ला कनेक्ट केली"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"तुमची वैयक्‍तिक प्रोफाइल <xliff:g id="VPN_APP">%1$s</xliff:g> ला कनेक्‍ट केली आहे"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"हे डिव्हाइस <xliff:g id="VPN_APP">%1$s</xliff:g> ला कनेक्ट केले आहे"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"हे डिव्हाइस <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> द्वारे पुरवले गेले आहे"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"डिव्हाइस व्‍यवस्‍थापन"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"प्रोफाईल परीक्षण"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"नेटवर्क परीक्षण"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"धोरणे पहा"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"नियंत्रणे पाहा"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"हे डिव्हाइस <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> चे आहे.\n\nतुमचा आयटी ॲडमिन सेटिंग्ज, कॉर्पोरेट अ‍ॅक्सेस, ॲप्‍स, तुमच्‍या डिव्‍हाइसशी संबंधित डेटा आणि तुमच्‍या डिव्‍हाइसच्‍या स्‍थानाची माहिती यांचे परीक्षण व व्‍यवस्‍थापन करू शकतो.\n\nअधिक माहितीसाठी तुमच्‍या आयटी ॲडमिनशी संपर्क साधा."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> कदाचित या डिव्हाइसशी संलग्न असलेला डेटा अ‍ॅक्सेस करू शकते, ॲप्सचे व्यवस्थापन करू शकते आणि ही डिव्हाइस सेटिंग्ज बदलू शकते.\n\nतुम्हाला प्रश्न असल्यास, <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g> शी संपर्क साधा."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"हे डिव्हाइस तुमच्या संस्थेचे आहे.\n\nतुमचा आयटी ॲडमिन सेटिंग्ज, कॉर्पोरेट अ‍ॅक्सेस, ॲप्‍स, तुमच्‍या डिव्‍हाइसशी संबंधित डेटा आणि तुमच्‍या डिव्‍हाइसच्‍या स्‍थानाची माहिती यांचे परीक्षण व व्‍यवस्‍थापन करू शकतो.\n\nअधिक माहितीसाठी तुमच्‍या आयटी ॲडमिनशी संपर्क साधा."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"आपल्या संस्थेने या डिव्हाइसवर प्रमाणपत्र अधिकार इंस्टॉल केला आहे. आपल्या सुरक्षित नेटवर्क रहदारीचे परीक्षण केले जाऊ शकते किंवा ती सुधारली जाऊ शकते."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"आपल्या संस्थेने आपल्या कार्य प्रोफाइलवर प्रमाणपत्र अधिकार इंस्टॉल केला आहे. आपल्या सुरक्षित नेटवर्क रहदारीचे परीक्षण केले जाऊ शकते किंवा ती सुधारली जाऊ शकते."</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"डेमो मोड दर्शवा"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"इथरनेट"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"अलार्म"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"तयार आहे"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"कार्य प्रोफाईल"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"विमान मोड"</string>
     <string name="add_tile" msgid="6239678623873086686">"टाइल जोडा"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"जलद सेटिंग्ज बंद करा."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"अलार्म सेट केला."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"<xliff:g id="ID_1">%s</xliff:g> म्हणून साइन इन केले"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"वापरकर्ता निवडा"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"इंटरनेट नाही"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"तपशील उघडा."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"<xliff:g id="REASON">%s</xliff:g> मुळे उपलब्ध नाही"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> सेटिंग्ज उघडा."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"सेटिंग्जचा क्रम संपादित करा."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"पॉवर मेनू"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"पृष्ठ <xliff:g id="ID_2">%2$d</xliff:g> पैकी <xliff:g id="ID_1">%1$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"लॉक स्‍क्रीन"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"तापल्‍यामुळे फोन बंद झाला"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"डावीकडे हलवा"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"उजवीकडे हलवा"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"मॅग्निफिकेशन स्विच"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"संपूर्ण स्क्रीन मॅग्निफाय करा"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"फुल स्क्रीन मॅग्निफाय करा"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"स्क्रीनचा काही भाग मॅग्निफाय करा"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"स्विच करा"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"अ‍ॅक्सेसिबिलिटी जेश्चर हे आता अ‍ॅक्सेसिबिलिटी बटण आहे \n\n"<annotation id="link">"सेटिंग्ज पाहा"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"बटण तात्पुरते लपवण्यासाठी ते कोपर्‍यामध्ये हलवा"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"डिव्हाइस नियंत्रणे"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"तुमच्या कनेक्ट केलेल्या डिव्हाइससाठी नियंत्रणे जोडा"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"डिव्हाइस नियंत्रणे सेट करा"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"नवीन डिव्हाइससोबत पेअर करा"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"संभाषण विजेट"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"तुमच्या होम स्क्रीन वर संभाषण जोडण्यासाठी त्यावर टॅप करा"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> पूर्वी"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"<xliff:g id="DURATION">%1$s</xliff:g> पेक्षा कमी"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"<xliff:g id="DURATION">%1$s</xliff:g> पेक्षा आधी"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"वाढदिवस"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"वाढदिवस लवकरच आहे"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"वर्धापन दिन"</string>
+    <string name="location_status" msgid="1294990572202541812">"स्थान शेअर करत आहे"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"नवीन स्टोरी"</string>
+    <string name="video_status" msgid="4548544654316843225">"पाहत आहे"</string>
+    <string name="audio_status" msgid="4237055636967709208">"ऐकत आहे"</string>
+    <string name="game_status" msgid="1340694320630973259">"प्ले करत आहे"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"मित्रमैत्रिणी"</string>
+    <string name="empty_status" msgid="5938893404951307749">"चला, आज रात्री चॅट करूया!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"मिस्ड कॉल"</string>
+    <string name="people_tile_description" msgid="8154966188085545556">"अलीकडील मेसेज, मिस्ड कॉल आणि स्टेटस अपडेट पाहा"</string>
+    <string name="people_tile_title" msgid="6589377493334871272">"संभाषण"</string>
     <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"तुमचे बॅटरी मीटर वाचताना समस्या आली"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"अधिक माहितीसाठी टॅप करा"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"अलार्म सेट केला नाही"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index ca5c6cf..50c5e0d 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Batal"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Kongsi"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Rakaman skrin dibatalkan"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Rakaman skrin disimpan"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Ketik untuk lihat"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Ralat semasa memadamkan rakaman skrin"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Gagal mendapatkan kebenaran"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Ralat semasa memulakan rakaman skrin"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Pengguna baharu"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Internet"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Selamat pesawat"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Rangkaian tersedia"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Rangkaian tidak tersedia"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Tidak Disambungkan"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Hingga matahari trbt"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Dihidupkan pada <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Hingga <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Kurangkan kecerahan"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC dilumpuhkan"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC didayakan"</string>
@@ -470,7 +466,6 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Tunjuk profil"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Tambah pengguna"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Pengguna baharu"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Tamatkan sesi tetamu"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Alih keluar tetamu?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Semua apl dan data dalam sesi ini akan dipadam."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Alih keluar"</string>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Peranti ini diurus oleh ibu bapa anda"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Organisasi anda memiliki peranti ini dan mungkin memantau trafik rangkaian"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> memiliki peranti ini dan mungkin memantau trafik rangkaian"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Peranti ini disediakan oleh <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Peranti ini milik organisasi anda dan dihubungkan dengan <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Peranti ini milik <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> dan dihubungkan dengan <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Peranti ini milik organisasi anda"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Profil kerja anda dihubungkan dengan <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Profil peribadi anda dihubungkan dengan <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Peranti ini dihubungkan dengan <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Peranti ini disediakan oleh <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Pengurusan peranti"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Pemantauan profil"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Pemantauan rangkaian"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Lihat Dasar"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Lihat kawalan"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Peranti ini milik <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nPentadbir IT anda boleh memantau dan mengurus tetapan, akses korporat, apl, data yang dikaitkan dengan peranti anda dan maklumat lokasi peranti anda.\n\nUntuk maklumat lanjut, hubungi pentadbir IT anda."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> mungkin dapat mengakses data yang dikaitkan dengan peranti ini, apl terurus dan menukar tetapan peranti ini.\n\nJika anda mempunyai pertanyaan, hubungi <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Peranti ini milik organisasi anda.\n\nPentadbir IT anda boleh memantau dan mengurus tetapan, akses korporat, apl, data yang dikaitkan dengan peranti anda dan maklumat lokasi peranti anda.\n\nUntuk maklumat lanjut, hubungi pentadbir IT anda."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Organisasi anda memasang sijil kuasa pada peranti ini. Trafik rangkaian selamat anda mungkin dipantau atau diubah suai."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Organisasi anda memasang sijil kuasa dalam profil kerja anda. Trafik rangkaian selamat anda mungkin dipantau atau diubah suai."</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Tunjukkan mod tunjuk cara"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Penggera"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Sedia"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Profil kerja"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Mod pesawat"</string>
     <string name="add_tile" msgid="6239678623873086686">"Tambahkan jubin"</string>
@@ -721,7 +721,7 @@
     <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"&lt;b&gt;Status:&lt;/b&gt; Diturunkan Taraf kepada Senyap"</string>
     <string name="notification_channel_summary_automatic_promoted" msgid="1301710305149590426">"&lt;b&gt;Status:&lt;/b&gt; Dinilai Lebih Tinggi"</string>
     <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" msgid="7952654515769021553">"Ditunjukkan di sebelah atas bahagian perbualan, muncul sebagai gelembung terapung, memaparkan gambar profil pada skrin kunci"</string>
+    <string name="notification_channel_summary_priority" msgid="7952654515769021553">"Ditunjukkan di sebelah atas bahagian perbualan, terpapar sebagai gelembung terapung, gambar profil dipaparkan pada skrin kunci"</string>
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Tetapan"</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>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Tutup tetapan pantas."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Penggera ditetapkan."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Dilog masuk sebagai <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"pilih pengguna"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Tiada Internet"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Buka butiran."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"Tidak tersedia disebabkan <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Buka tetapan <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Edit susunan tetapan."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menu kuasa"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Halaman <xliff:g id="ID_1">%1$d</xliff:g> daripada <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Kunci skrin"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"Telefon dimatikan kerana panas"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Alih ke kiri"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Alih ke kanan"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Suis pembesaran"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Besarkan seluruh skrin"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Besarkan skrin penuh"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Besarkan sebahagian skrin"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Tukar"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"Butang kebolehaksesan menggantikan gerak isyarat kebolehaksesan\n\n"<annotation id="link">"Lihat tetapan"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Gerakkan butang ke tepi untuk menyembunyikannya buat sementara waktu"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Kawalan peranti"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Tambah kawalan untuk peranti yang disambungkan"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Sediakan kawalan peranti"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Gandingkan peranti baharu"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Widget perbualan"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Ketik perbualan untuk menambahkan perbualan itu pada skrin Utama anda"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> yang lalu"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"Kurang daripada <xliff:g id="DURATION">%1$s</xliff:g> lalu"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"Lebih <xliff:g id="DURATION">%1$s</xliff:g> yang lalu"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Hari Lahir"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Hari lahir tak lama lagi"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Ulang tahun"</string>
+    <string name="location_status" msgid="1294990572202541812">"Berkongsi lokasi"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Cerita baharu"</string>
+    <string name="video_status" msgid="4548544654316843225">"Menonton"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Mendengar"</string>
+    <string name="game_status" msgid="1340694320630973259">"Memainkan"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Rakan"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Mari bersembang!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"Panggilan terlepas"</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="battery_state_unknown_notification_title" msgid="8464703640483773454">"Masalah membaca meter bateri anda"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Ketik untuk mendapatkan maklumat lanjut"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Tiada penggera"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index cd4d590..9e67f1c 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"မလုပ်တော့"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"မျှဝေရန်"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"ဖန်သားပြင် ရိုက်ကူးမှု ပယ်ဖျက်လိုက်ပါပြီ"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"ဖန်သားပြင် ရိုက်ကူးမှုကို သိမ်းပြီးပါပြီ"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"ကြည့်ရှုရန် တို့ပါ"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"ဖန်သားပြင် ရိုက်ကူးမှု ဖျက်ရာတွင် အမှားအယွင်းရှိနေသည်"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"ခွင့်ပြုချက် မရယူနိုင်ပါ"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"ဖန်သားပြင် ရိုက်ကူးမှု စတင်ရာတွင် အမှားအယွင်းရှိနေသည်"</string>
@@ -212,7 +210,7 @@
     <string name="accessibility_desc_connected" msgid="3082590384032624233">"ချိတ်ဆက်ထားသည်"</string>
     <string name="accessibility_desc_connecting" msgid="8011433412112903614">"ချိတ်ဆက်နေ။"</string>
     <string name="data_connection_hspa" msgid="6096234094857660873">"HSPA"</string>
-    <string name="data_connection_roaming" msgid="375650836665414797">"ပြင်ပကွန်ရက်နှင့် ချိတ်ဆက်ခြင်း"</string>
+    <string name="data_connection_roaming" msgid="375650836665414797">"ပြင်ပကွန်ရက်သုံးခြင်း"</string>
     <string name="accessibility_data_connection_wifi" msgid="4422160347472742434">"Wi-Fi"</string>
     <string name="accessibility_no_sim" msgid="1140839832913084973">"ဆင်းကဒ်မရှိပါ။"</string>
     <string name="accessibility_cell_data" msgid="172950885786007392">"မိုဘိုင်းဒေတာ"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"အသုံးပြုသူ အသစ်"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"အင်တာနက်"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"လေယာဉ်ပျံလုံခြုံရေး"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"ကွန်ရက်များ ရနိုင်သည်"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"ကွန်ရက်များ မရနိုင်ပါ"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"ချိတ်ဆက်မထားပါ"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"နေထွက်ချိန် အထိ"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g> တွင် ဖွင့်မည်"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> အထိ"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"တောက်ပမှုကို လျှော့ခြင်း"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC ကို ပိတ်ထားသည်"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC ကို ဖွင့်ထားသည်"</string>
@@ -470,13 +466,12 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"ပရိုဖိုင်ကို ပြရန်"</string>
     <string name="user_add_user" msgid="4336657383006913022">"အသုံးပြုသူ ထည့်ရန်"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"အသုံးပြုသူ အသစ်"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"ဧည့်သည်ဆက်ရှင်ကို အဆုံးသတ်ရန်"</string>
-    <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"ဧည့်သည်ကို ဖယ်ထုတ်လိုက်ရမလား?"</string>
+    <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"ဧည့်သည်ကို ဖယ်မလား။"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ဒီချိတ်ဆက်မှု ထဲက အက်ပ်များ အားလုံး နှင့် ဒေတာကို ဖျက်ပစ်မည်။"</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"ဖယ်ထုတ်ပါ"</string>
-    <string name="guest_wipe_session_title" msgid="7147965814683990944">"ပြန်လာတာ ကြိုဆိုပါသည်၊ ဧည့်သည်!"</string>
-    <string name="guest_wipe_session_message" msgid="3393823610257065457">"သင်သည် သင်၏ ချိတ်ဆက်မှုကို ဆက်ပြုလုပ် လိုပါသလား?"</string>
-    <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"အစမှ ပြန်စပါ"</string>
+    <string name="guest_wipe_session_title" msgid="7147965814683990944">"ဧည့်သည်ကို ပြန်လည် ကြိုဆိုပါသည်။"</string>
+    <string name="guest_wipe_session_message" msgid="3393823610257065457">"သင်၏ စက်ရှင်ကို ဆက်လုပ်လိုပါသလား။"</string>
+    <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ပြန်စပါ"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"ဆက်လုပ်ပါ"</string>
     <string name="guest_notification_title" msgid="4434456703930764167">"ဧည့်သည် အသုံးပြုသူ"</string>
     <string name="guest_notification_text" msgid="4202692942089571351">"အက်ပ်များနှင့် ဒေတာအား ဖျက်ရန်၊ တခဏသုံးစွဲသူအား ဖယ်ရှားပါ"</string>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ဤစက်ပစ္စည်းကို သင့်မိဘက စီမံခန့်ခွဲသည်"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ဤစက်ကို သင့်အဖွဲ့အစည်းကပိုင်ဆိုင်ပြီး ကွန်ရက်ဒေတာ စီးဆင်းမှုကို စောင့်ကြည့်နိုင်ပါသည်"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"ဤစက်ကို <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> က ပိုင်ဆိုင်ပြီး ကွန်ရက်ဒေတာ စီးဆင်းမှုကို စောင့်ကြည့်နိုင်ပါသည်"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"ဤစက်ပစ္စည်းကို <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> က ပံ့ပိုးထားသည်"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"ဤစက်ကို သင့်အဖွဲ့အစည်းကပိုင်ဆိုင်ပြီး <xliff:g id="VPN_APP">%1$s</xliff:g> သို့ ချိတ်ဆက်ထားပါသည်"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"ဤစက်ကို <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> က ပိုင်ဆိုင်ပြီး <xliff:g id="VPN_APP">%2$s</xliff:g> သို့ ချိတ်ဆက်ထားပါသည်"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"ဤစက်ကို သင့်အဖွဲ့အစည်းက ပိုင်ဆိုင်သည်"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"သင်၏အလုပ်ပရိုဖိုင်သည် <xliff:g id="VPN_APP">%1$s</xliff:g> ကို ချိတ်ဆက်ထားပါသည်"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"သင်၏ ကိုယ်ပိုင်ပရိုဖိုင်ကို <xliff:g id="VPN_APP">%1$s</xliff:g> သို့ ချိတ်ဆက်ထားပါသည်"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"ဤစက်ကို <xliff:g id="VPN_APP">%1$s</xliff:g> သို့ ချိတ်ဆက်ထားပါသည်"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"ဤစက်ပစ္စည်းကို <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> က ပံ့ပိုးထားသည်"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"စက်ပစ္စည်း စီမံခန့်ခွဲမှု"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"ပရိုဖိုင် စောင့်ကြပ်မှု"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"ကွန်ရက်ကို စောင့်ကြပ်ခြင်း"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"မူဝါဒများကို ကြည့်ရန်"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"ထိန်းချုပ်မှုများကို ကြည့်ရန်"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"ဤစက်ကို <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> က ပိုင်ဆိုင်ပါသည်။\n\nဆက်တင်များ၊ ကော်ပိုရိတ် သုံးခွင့်၊ အက်ပ်များ၊ သင့်စက်နှင့် ဆက်စပ်နေသော ဒေတာများနှင့် သင့်စက်တည်နေရာတို့ကို သင်၏ IT စီမံခန့်ခွဲသူက စောင့်ကြည့် စီမံနိုင်သည်။\n\nနောက်ထပ်အချက်အလက်များအတွက် သင်၏ IT စီမံခန့်ခွဲသူကို ဆက်သွယ်ပါ။"</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> က ဤစက်ပစ္စည်းနှင့် ဆက်စပ်နေသည့်ဒေတာကို သုံးနိုင်ပြီး အက်ပ်များကို စီမံနိုင်သလို ဤစက်ပစ္စည်း၏ဆက်တင်များကို ပြောင်းနိုင်သည်။\n\nမေးစရာများရှိပါက <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g> ကို ဆက်သွယ်ပါ။"</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"ဤစက်ကို သင့်အဖွဲ့အစည်းက ပိုင်ဆိုင်သည်။\n\nဆက်တင်များ၊ ကော်ပိုရိတ် သုံးခွင့်၊ အက်ပ်များ၊ သင့်စက်နှင့် ဆက်စပ်နေသော ဒေတာများနှင့် သင့်စက်တည်နေရာတို့ကို သင်၏ IT စီမံခန့်ခွဲသူက စောင့်ကြည့် စီမံနိုင်သည်။\n\nနောက်ထပ်အချက်အလက်များအတွက် သင်၏ IT စီမံခန့်ခွဲသူကို ဆက်သွယ်ပါ။"</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"သင်၏ အဖွဲ့အစည်းက ဤစက်ပစ္စည်းတွင် စီမံခန့်ခွဲမှုဆိုင်ရာ အသိအမှတ်ပြုလက်မှတ်ကို ထည့်သွင်းထားပါသည်။ လုံခြုံမှုရှိသော ကွန်ရက်ဒေတာစီးဆင်းမှုကို စောင့်ကြည့်ခြင်း သို့မဟုတ် ပြုပြင်ခြင်းများ ပြုလုပ်နိုင်ပါသည်။"</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"သင်၏ အဖွဲ့အစည်းသည် သင်၏ အလုပ်ပရိုဖိုင်တွင် စီမံခန့်ခွဲမှုဆိုင်ရာ အသိအမှတ်ပြုလက်မှတ်ကို ထည့်သွင်းထားပါသည်။ လုံခြုံမှုရှိသော ကွန်ရက်ဒေတာစီးဆင်းမှုကို စောင့်ကြည့်ခြင်း သို့မဟုတ် ပြုပြင်ခြင်းများ ပြုလုပ်နိုင်ပါသည်။"</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"သရုပ်ပြမုဒ် ပြရန်"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"အီသာနက်"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"နှိုးစက်"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"အဆင်သင့်"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"အလုပ် ပရိုဖိုင်"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"လေယာဉ်ပျံမုဒ်"</string>
     <string name="add_tile" msgid="6239678623873086686">"လေးထောင့်ကွက် ထည့်ရန်"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"အမြန်ဆက်တင်များကို ပိတ်ပါ။"</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"နိုးစက် သတ်မှတ်ပြီးပါပြီ။"</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"<xliff:g id="ID_1">%s</xliff:g> အဖြစ် လက်မှတ်ထိုးဝင်ထားသည်။"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"အသုံးပြုသူရွေးရန်"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"အင်တာနက် မရှိပါ"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"အသေးစိတ်များကို ဖွင့်ပါ။"</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"<xliff:g id="REASON">%s</xliff:g> ကြောင့် မရနိုင်ပါ"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> ဆက်တင်များကို ဖွင့်ပါ။"</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"ဆက်တင်များ၏ အစီအစဉ်ကို တည်းဖြတ်ပါ။"</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"ပါဝါမီနူး"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"စာမျက်နှာ <xliff:g id="ID_2">%2$d</xliff:g> အနက်မှ စာမျက်နှာ <xliff:g id="ID_1">%1$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"လော့ခ်ချထားချိန် မျက်နှာပြင်"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"အပူရှိန်ကြောင့်ဖုန်းပိတ်ထားသည်"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"ဘယ်ဘက်သို့ရွှေ့ရန်"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"ညာဘက်သို့ရွှေ့ရန်"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"ချဲ့ရန် ခလုတ်"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"ဖန်သားပြင် တစ်ခုလုံးကို ချဲ့ပါ"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"ဖန်သားပြင်အပြည့် ချဲ့သည်"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"ဖန်သားပြင် တစ်စိတ်တစ်ပိုင်းကို ချဲ့ပါ"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"ခလုတ်"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"အများသုံးစွဲနိုင်မှုခလုတ်က အများသုံးစွဲနိုင်မှုလက်ဟန်ကို အစားထိုးသည်\n\n"<annotation id="link">"ဆက်တင်များကို ကြည့်ပါ"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"ခလုတ်ကို ယာယီဝှက်ရန် အစွန်းသို့ရွှေ့ပါ"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"စက်ထိန်းစနစ်"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"ချိတ်ဆက်စက်များအတွက် ထိန်းချုပ်မှုများထည့်ပါ"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"စက်ထိန်းစနစ် ထည့်သွင်းခြင်း"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"စက်အသစ် တွဲချိတ်ရန်"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"စကားဝိုင်း ဝိဂျက်များ"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"စကားဝိုင်းကို သင်၏ ‘ပင်မစာမျက်နှာ’ သို့ထည့်ရန် တို့ပါ"</string>
+    <string name="timestamp" msgid="6577851592534538533">"ပြီးခဲ့သည့် <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"ပြီးခဲ့သော <xliff:g id="DURATION">%1$s</xliff:g> မပြည့်ခင်"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"ပြီးခဲ့သော <xliff:g id="DURATION">%1$s</xliff:g> ကျော်"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"မွေးနေ့"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"မကြာမီလာမည့် မွေးနေ့"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"နှစ်ပတ်လည်"</string>
+    <string name="location_status" msgid="1294990572202541812">"တည်နေရာမျှဝေခြင်း"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"ဝဘ်ပို့စ်အသစ်"</string>
+    <string name="video_status" msgid="4548544654316843225">"ကြည့်ရှုနေသည်"</string>
+    <string name="audio_status" msgid="4237055636967709208">"နားထောင်နေသည်"</string>
+    <string name="game_status" msgid="1340694320630973259">"ကစားနေသည်"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"မိတ်ဆွေများ"</string>
+    <string name="empty_status" msgid="5938893404951307749">"ယနေ့ညချတ်လုပ်ကြစို့။"</string>
+    <string name="missed_call" msgid="4228016077700161689">"လွတ်သွားသောခေါ်ဆိုမှု"</string>
+    <string name="people_tile_description" msgid="8154966188085545556">"မကြာသေးမီက မက်ဆေ့ဂျ်၊ လွတ်သွားသောခေါ်ဆိုမှုနှင့် အခြေအနေအပ်ဒိတ်များကို ကြည့်နိုင်သည်"</string>
+    <string name="people_tile_title" msgid="6589377493334871272">"စကားဝိုင်း"</string>
     <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"သင်၏ ဘက်ထရီမီတာကို ဖတ်ရာတွင် ပြဿနာရှိနေသည်"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"နောက်ထပ်အချက်အလက်များအတွက် တို့ပါ"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"နှိုးစက်ပေးမထားပါ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 52c289d..aa7139b 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Avbryt"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Del"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Skjermopptak er avbrutt"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Skjermopptaket er lagret"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Trykk for å se"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Feil ved sletting av skjermopptaket"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Kunne ikke få tillatelser"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Feil ved start av skjermopptaket"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Ny bruker"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Internett"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Trygg på fly"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Nettverk er tilgjengelige"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Nettverk er utilgjengelige"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Ikke tilkoblet"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Til soloppgang"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Slås på klokken <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Til <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Reduser lysstyrken"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC er slått av"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC er slått på"</string>
@@ -470,7 +466,6 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Vis profil"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Legg til brukere"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Ny bruker"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Avslutt gjesteøkten"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Vil du fjerne gjesten?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle appene og all informasjon i denne økten slettes."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Fjern"</string>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Denne enheten administreres av forelderen din"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Organisasjonen din eier denne enheten og kan overvåke nettverkstrafikken"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> eier denne enheten og kan overvåke nettverkstrafikken"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Denne enheten leveres av <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Denne enheten tilhører organisasjonen din og er koblet til <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Denne enheten tilhører <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> og er koblet til <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Denne enheten tilhører organisasjonen din"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Jobbprofilen din er koblet til <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Den personlige profilen din er koblet til <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Denne enheten er koblet til <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Denne enheten leveres av <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Enhetsadministrasjon"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Profilovervåking"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Nettverksovervåking"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Se retningslinjer"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Visningskontroller"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Denne enheten tilhører <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nIT-administratoren din kan overvåke og administrere innstillinger, bedriftstilgang, apper, data som er tilknyttet denne enheten, og enhetens posisjonsinformasjon.\n\nKontakt IT-administratoren for å få mer informasjon."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> kan ha tilgang til data som er knyttet til denne enheten, kan administrere apper og kan endre enhetsinnstillingene.\n\nHvis du har spørsmål, kan du kontakte <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Denne enheten tilhører organisasjonen din.\n\nIT-administratoren din kan overvåke og administrere innstillinger, bedriftstilgang, apper, data som er tilknyttet denne enheten, og enhetens posisjonsinformasjon.\n\nKontakt IT-administratoren for å få mer informasjon."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Organisasjonen din installerte en sertifiseringsinstans på denne enheten. Den sikre nettverkstrafikken din kan overvåkes eller endres."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Organisasjonen din installerte en sertifiseringsinstans i jobbprofilen din. Den sikre nettverkstrafikken din kan overvåkes eller endres."</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Vis demo-modus"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Alarm"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Klar"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Work-profil"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Flymodus"</string>
     <string name="add_tile" msgid="6239678623873086686">"Legg til felt"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Lukk hurtiginnstillingene."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Alarm er angitt."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Logget på som <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"velge en bruker"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Ingen internettilkobling"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Åpne informasjonen."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"Utilgjengelig fordi <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Åpne <xliff:g id="ID_1">%s</xliff:g>-innstillingene."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Endre rekkefølgen på innstillingene."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Av/på-meny"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Side <xliff:g id="ID_1">%1$d</xliff:g> av <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Låseskjerm"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"Telefon ble slått av pga varme"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Flytt til venstre"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Flytt til høyre"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Forstørringsbryter"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Forstørr hele skjermen"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Forstørr fullskjermen"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Forstørr en del av skjermen"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Bytt"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"Tilgjengelighet-knappen har erstattet tilgjengelighetsbevegelsen\n\n"<annotation id="link">"Se innstillingene"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Flytt knappen til kanten for å skjule den midlertidig"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Enhetsstyring"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Legg til kontroller for de tilkoblede enhetene dine"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Konfigurer enhetsstyring"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Koble til en ny enhet"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Samtalemoduler"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Trykk på en samtale for å legge den til på startskjermen"</string>
+    <string name="timestamp" msgid="6577851592534538533">"For <xliff:g id="DURATION">%1$s</xliff:g> siden"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"For mindre enn <xliff:g id="DURATION">%1$s</xliff:g> siden"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"For mer enn <xliff:g id="DURATION">%1$s</xliff:g> siden"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Bursdag"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Bursdag snart"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Merkedag"</string>
+    <string name="location_status" msgid="1294990572202541812">"Deler posisjonen"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Ny nyhetssak"</string>
+    <string name="video_status" msgid="4548544654316843225">"Ser på"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Lytter"</string>
+    <string name="game_status" msgid="1340694320630973259">"Spiller"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Venner"</string>
+    <string name="empty_status" msgid="5938893404951307749">"La oss chatte senere"</string>
+    <string name="missed_call" msgid="4228016077700161689">"Tapt anrop"</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="battery_state_unknown_notification_title" msgid="8464703640483773454">"Kunne ikke lese batterimåleren"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Trykk for å få mer informasjon"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Ingen alarm angitt"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 63a8423..0f9aa79 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"रद्द गर्नुहोस्"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"सेयर गर्नुहोस्"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"स्क्रिन रेकर्ड गर्ने कार्य रद्द गरियो"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"स्क्रिन रेकर्डिङ सुरक्षित गरियो"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"हेर्नका लागि ट्याप गर्नुहोस्"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"स्क्रिनको रेकर्डिङ मेट्ने क्रममा त्रुटि"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"अनुमति प्राप्त गर्न सकिएन"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"स्क्रिन रेकर्ड गर्न थाल्ने क्रममा त्रुटि भयो"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"नयाँ प्रयोगकर्ता"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"इन्टरनेट"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"हवाइजहाज मोडमा काम गर्ने सुरक्षित नेटवर्क"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"उपलब्ध नेटवर्कहरू"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"नेटवर्क उपलब्ध छैन"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"जोडिएको छैन"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"सूर्योदयसम्म"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g> मा सक्रिय"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> सम्म"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"चमक घटाइयोस्"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC लाई असक्षम पारिएको छ"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC लाई सक्षम पारिएको छ"</string>
@@ -470,11 +466,10 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"प्रोफाइल देखाउनुहोस्"</string>
     <string name="user_add_user" msgid="4336657383006913022">"प्रयोगकर्ता थप्नुहोस्"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"नयाँ प्रयोगकर्ता"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"अतिथिको सत्र अन्त्य गर्नुहोस्"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"अतिथि हटाउने हो?"</string>
-    <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"यस सत्रमा सबै एपहरू र डेटा मेटाइनेछ।"</string>
+    <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"यो सत्रमा भएका सबै एपहरू र डेटा मेटाइने छ।"</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"हटाउनुहोस्"</string>
-    <string name="guest_wipe_session_title" msgid="7147965814683990944">"पुनः स्वागत, अतिथि!"</string>
+    <string name="guest_wipe_session_title" msgid="7147965814683990944">"तपाईंलाई फेरि स्वागत छ, अतिथि"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"तपाईं आफ्नो सत्र जारी गर्न चाहनुहुन्छ?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"सुरु गर्नुहोस्"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"हो, जारी राख्नुहोस्"</string>
@@ -485,7 +480,7 @@
     <string name="user_logout_notification_text" msgid="7441286737342997991">"वर्तमान प्रयोगकर्ता लगआउट गर्नुहोस्"</string>
     <string name="user_logout_notification_action" msgid="7974458760719361881">"प्रयोगकर्ता लगआउट गर्नुहोस्"</string>
     <string name="user_add_user_title" msgid="4172327541504825032">"नयाँ प्रयोगकर्ता थप्ने हो?"</string>
-    <string name="user_add_user_message_short" msgid="2599370307878014791">"जब तपाईँले नयाँ प्रयोगकर्ता थप्नुहुन्छ, त्यस प्रयोगकर्ताले आफ्नो स्थान स्थापना गर्न पर्ने छ।\n\nकुनै पनि प्रयोगकर्ताले सबै अन्य प्रयोगकर्ताहरूका लागि एपहरू अद्यावधिक गर्न सक्छन्।"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"जब तपाईँले नयाँ प्रयोगकर्ता थप्नुहुन्छ, त्यस प्रयोगकर्ताले आफ्नो स्थान स्थापना गर्न पर्ने छ।\n\nसबै प्रयोगकर्ताले अरू प्रयोगकर्ताका एपहरू अपडेट गर्न सक्छन्।"</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"प्रयोगकर्ताको सीमा पुग्यो"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">तपाईं अधिकतम <xliff:g id="COUNT">%d</xliff:g> प्रयोगहरू मात्र थप्न सक्नुहुन्छ।</item>
@@ -506,7 +501,7 @@
     <string name="manage_notifications_text" msgid="6885645344647733116">"व्यवस्थित गर्नुहोस्"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"इतिहास"</string>
     <string name="notification_section_header_incoming" msgid="850925217908095197">"नयाँ"</string>
-    <string name="notification_section_header_gentle" msgid="6804099527336337197">"मौन"</string>
+    <string name="notification_section_header_gentle" msgid="6804099527336337197">"साइलेन्ट"</string>
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"सूचनाहरू"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"वार्तालापहरू"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"सबै मौन सूचनाहरू हटाउनुहोस्"</string>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"यो यन्त्र तपाईंका अभिभावक व्यवस्थापन गर्नुहुन्छ"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"यो यन्त्र तपाईंको सङ्गठनको स्वामित्वमा छ र उक्त सङ्गठनले यसको नेटवर्क ट्राफिक अनुगमन गर्न सक्छ"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"यो यन्त्र <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> को स्वामित्वमा छ र उक्त सङ्गठनले यसको नेटवर्क ट्राफिक अनुगमन गर्न सक्छ"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ले यो यन्त्र उपलब्ध गराएको हो"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"यो यन्त्र तपाईंको सङ्गठनको स्वामित्वमा छ र <xliff:g id="VPN_APP">%1$s</xliff:g> मा कनेक्ट गरिएको छ"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"यो यन्त्र <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> को स्वामित्वमा छ र <xliff:g id="VPN_APP">%2$s</xliff:g> मा कनेक्ट गरिएको छ"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"यो यन्त्र तपाईंको सङ्गठनको स्वामित्वमा छ"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"तपाईंको कार्य प्रोफाइल <xliff:g id="VPN_APP">%1$s</xliff:g> मा कनेक्ट गरिएको छ"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"तपाईंको व्यक्तिगत प्रोफाइल <xliff:g id="VPN_APP">%1$s</xliff:g> मा कनेक्ट गरिएको छ"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"यो यन्त्र <xliff:g id="VPN_APP">%1$s</xliff:g> मा कनेक्ट गरिएको छ"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ले यो यन्त्र उपलब्ध गराएको हो"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"यन्त्रको व्यवस्थापन"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"प्रोफाइल अनुगमन गर्दै"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"सञ्जाल अनुगमन"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"नीतिहरू हेर्नुहोस्"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"नियन्त्रणहरू हेर्नुहोस्"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"यो यन्त्र <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> को स्वामित्वमा छ।\n\nतपाईंका IT एड्मिन सेटिङ, संस्थागत पहुँच, एप, तपाईंको यन्त्रसँग सम्बन्धित डेटा र तपाईंको यन्त्रको स्थानसम्बन्धी जानकारीको निगरानी र व्यवस्थापन गर्न सक्नुहुन्छ।\n\nथप जानकारीका लागि आफ्ना IT एड्मिनसँग सम्पर्क गर्नुहोस्।"</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> ले यो यन्त्रसँग सम्बन्धित डेटा प्रयोग गर्न, एपहरू व्यवस्थापन गर्न र यी यन्त्रहरूको सेटिङ बदल्न सक्छ।\n\nतपाईंसँग प्रश्नहरू छन् भने <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g> मा सम्पर्क गर्नुहोस्।"</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"यो यन्त्र तपाईंको सङ्गठनको स्वामित्वमा छ।\n\nतपाईंका IT एड्मिन सेटिङ, संस्थागत पहुँच, एप, तपाईंको यन्त्रसँग सम्बन्धित डेटा र तपाईंको यन्त्रको स्थानसम्बन्धी जानकारीको निगरानी र व्यवस्थापन गर्न सक्नुहुन्छ।\n\nथप जानकारीका लागि आफ्ना IT एड्मिनसँग सम्पर्क गर्नुहोस्।"</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"तपाईंको संगठनले तपाईंको कार्य प्रोफाइलमा एउटा प्रमाणपत्र सम्बन्धी अख्तियार सुविधा स्थापित गऱ्यो। तपाईंको सुरक्षित नेटवर्क ट्राफिकको अनुगमन वा परिमार्जन हुनसक्छ।"</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"तपाईंको संगठनले तपाईंको कार्य प्रोफाइलमा एउटा प्रमाणपत्र सम्बन्धी अख्तियार सुविधा स्थापना गरेको छ। तपाईंको सुरक्षित नेटवर्क ट्राफिकको अनुगमन वा परिमार्जन हुनसक्छ।"</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"डेमो मोड देखाउनुहोस्"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"इथरनेट"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"अलार्म"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"वालेट"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"तयार छ"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"कार्य प्रोफाइल"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"हवाइजहाज मोड"</string>
     <string name="add_tile" msgid="6239678623873086686">"टाइल थप्नुहोस्"</string>
@@ -702,26 +702,26 @@
     <string name="inline_block_button" msgid="479892866568378793">"रोक लगाउनुहोस्"</string>
     <string name="inline_keep_button" msgid="299631874103662170">"देखाउने क्रम जारी राख्नुहोस्"</string>
     <string name="inline_minimize_button" msgid="1474436209299333445">"सानो बनाउनुहोस्"</string>
-    <string name="inline_silent_button_silent" msgid="525243786649275816">"मौन"</string>
+    <string name="inline_silent_button_silent" msgid="525243786649275816">"साइलेन्ट"</string>
     <string name="inline_silent_button_stay_silent" msgid="2129254868305468743">"मौन रहनुहोस्"</string>
     <string name="inline_silent_button_alert" msgid="5705343216858250354">"सतर्क गराउने"</string>
     <string name="inline_silent_button_keep_alerting" msgid="6577845442184724992">"सर्तक गराइरहनुहोस्"</string>
     <string name="inline_turn_off_notifications" msgid="8543989584403106071">"सूचनाहरू निष्क्रिय पार्नुहोस्"</string>
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"यो एपका सूचनाहरू देखाउने क्रम जारी राख्ने हो?"</string>
-    <string name="notification_silence_title" msgid="8608090968400832335">"मौन"</string>
+    <string name="notification_silence_title" msgid="8608090968400832335">"साइलेन्ट"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"पूर्वनिर्धारित"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"स्वचालित"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"न घन्टी बज्छ न त कम्पन नै हुन्छ"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"न घन्टी बज्छ न त कम्पन नै हुन्छ र वार्तालाप खण्डको तलतिर देखा पर्छ"</string>
-    <string name="notification_channel_summary_default" msgid="3282930979307248890">"फोनको सेटिङका आधारमा घन्टी बज्न वा कम्पन हुन सक्छ"</string>
-    <string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"फोनको सेटिङका आधारमा घन्टी बज्न वा कम्पन हुन सक्छ। <xliff:g id="APP_NAME">%1$s</xliff:g> का वार्तालापहरू पूर्वनिर्धारित रूपमा बबलमा देखाइन्छन्।"</string>
+    <string name="notification_channel_summary_default" msgid="3282930979307248890">"फोनको सेटिङका आधारमा घन्टी बज्न वा भाइब्रेट हुन सक्छ"</string>
+    <string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"फोनको सेटिङका आधारमा घन्टी बज्न वा भाइब्रेट हुन सक्छ। <xliff:g id="APP_NAME">%1$s</xliff:g> का वार्तालापहरू पूर्वनिर्धारित रूपमा बबलमा देखाइन्छन्।"</string>
     <string name="notification_channel_summary_bubble" msgid="7235935211580860537">"फ्लोटिङ सर्टकटमार्फत यो सामग्रीतर्फ तपाईंको ध्यान आकर्षित गर्दछ।"</string>
     <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"सिस्टमलाई यो सूचना आउँदा ध्वनि बज्नु पर्छ वा कम्पन हुनु पर्छ भन्ने कुराको निधो गर्न दिनुहोस्"</string>
     <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"&lt;b&gt;स्थिति:&lt;/b&gt; सूचनालाई महत्त्वपूर्ण ठानी पूर्वनिर्धारित मोडमा सेट गरिएको छ"</string>
     <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"&lt;b&gt;स्थिति:&lt;/b&gt; सूचनालाई कम महत्त्वपूर्ण ठानी साइलेन्ट मोडमा सेट गरिएको छ"</string>
     <string name="notification_channel_summary_automatic_promoted" msgid="1301710305149590426">"&lt;b&gt;स्थिति:&lt;/b&gt; धेरै महत्त्वपूर्ण सूचनाका रूपमा सेट गरिएको छ"</string>
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;स्थिति:&lt;/b&gt; कम महत्त्वपूर्ण सूचनाका रूपमा सेट गरिएको छ"</string>
-    <string name="notification_channel_summary_priority" msgid="7952654515769021553">"वार्तालाप खण्डको सिरानमा देखा पर्छ, तैरने बबलका रूपमा देखा पर्छ, लक स्क्रिनमा प्रोफाइल फोटो देखाइन्छ"</string>
+    <string name="notification_channel_summary_priority" msgid="7952654515769021553">"वार्तालाप खण्डको सिरानमा देखा पर्छ, तैरने बबलका रूपमा देखा पर्छ, लक स्क्रिनमा प्रोफाइल फोटो देखिन्छ"</string>
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"सेटिङ"</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>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"द्रुत सेटिङहरूलाई बन्द गर्नुहोस्।"</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"अलार्म सेट गरियो।"</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"<xliff:g id="ID_1">%s</xliff:g> को रूपमा साइन इन गरियो"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"प्रयोगकर्ता छान्नुहोस्"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"इन्टरनेट छैन"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"विवरणहरूलाई खोल्नुहोस्।"</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"<xliff:g id="REASON">%s</xliff:g> का कारण उपलब्ध छैन"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> सम्बन्धी सेटिङहरूलाई खोल्नुहोस्।"</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"सेटिङहरूको क्रमलाई सम्पादन गर्नुहोस्।"</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"पावर मेनु"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g> मध्ये पृष्ठ <xliff:g id="ID_1">%1$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"लक स्क्रिन"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"फोन अति नै तातिएकाले चिसिन बन्द भयो"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"बायाँ सार्नुहोस्"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"दायाँ सार्नुहोस्"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"म्याग्निफिकेसन स्विच"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"पूरै स्क्रिन म्याग्निफाइ गर्नुहोस्"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"पूरै स्क्रिन जुम इन गर्नुहोस्"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"स्क्रिनको केही भाग म्याग्निफाइ गर्नुहोस्"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"बदल्नुहोस्"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"एक्सेसिबिलिटी इसाराका स्थानमा एक्सेसिबिलिटी बटन प्रयोग हुन थालेको छ\n\n"<annotation id="link">"सेटिङ हेर्नुहोस्"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"यो बटन केही बेर नदेखिने पार्न किनारातिर सार्नुहोस्"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"यन्त्र नियन्त्रण गर्ने विजेटहरू"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"आफ्ना जोडिएका यन्त्रहरूका लागि नियन्त्रण सुविधाहरू थप्नुहोस्"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"यन्त्र नियन्त्रण गर्ने विजेटहरू सेटअप गर्नुहोस्"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"नयाँ यन्त्रको जोडा बनाउनुहोस्"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"वार्तालापसम्बन्धी विजेटहरू"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"कुनै वार्तालाप होम स्क्रिनमा हाल्न उक्त वार्तालापमा ट्याप गर्नुहोस्"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> अघि"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"<xliff:g id="DURATION">%1$s</xliff:g> भन्दा कम समयअघि"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"<xliff:g id="DURATION">%1$s</xliff:g> भन्दा बढी समयअघि"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"जन्मदिन"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"आगामी जन्मदिन"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"वार्षिकोत्सव"</string>
+    <string name="location_status" msgid="1294990572202541812">"स्थानसम्बन्धी जानकारी सेयर गरिँदै छ"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"नयाँ स्टोरी"</string>
+    <string name="video_status" msgid="4548544654316843225">"भिडियो हेरिँदै छ"</string>
+    <string name="audio_status" msgid="4237055636967709208">"सुनिँदै छ"</string>
+    <string name="game_status" msgid="1340694320630973259">"खेलिँदै छ"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"साथीहरू"</string>
+    <string name="empty_status" msgid="5938893404951307749">"आज राति च्याट गरौँ!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"मिस कल"</string>
+    <string name="people_tile_description" msgid="8154966188085545556">"हालसालैका म्यासेज, मिस कल र स्ट्याटस अपडेट हेर्नुहोस्"</string>
+    <string name="people_tile_title" msgid="6589377493334871272">"वार्तालाप"</string>
     <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"यन्त्रको ब्याट्रीको मिटर रिडिङ क्रममा समस्या भयो"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"थप जानकारी प्राप्त गर्न ट्याप गर्नुहोस्"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"अलार्म राखिएको छैन"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-night/colors.xml b/packages/SystemUI/res/values-night/colors.xml
index d571f2f..17fdeb3 100644
--- a/packages/SystemUI/res/values-night/colors.xml
+++ b/packages/SystemUI/res/values-night/colors.xml
@@ -33,6 +33,9 @@
     <!-- The color of the text inside a notification -->
     <color name="notification_primary_text_color">@*android:color/notification_primary_text_color_dark</color>
 
+    <color name="notif_pill_background">@android:color/system_neutral1_800</color>
+    <color name="notif_pill_text">@android:color/system_neutral1_50</color>
+
     <color name="notification_guts_link_icon_tint">@color/GM2_grey_500</color>
     <color name="notification_guts_sub_text_color">@color/GM2_grey_300</color>
     <color name="notification_guts_header_text_color">@color/GM2_grey_200</color>
@@ -99,8 +102,7 @@
     <color name="qs_user_switcher_avatar_background">#3C4043</color>
 
     <!-- Colors for privacy dialog. These should be changed to the new palette -->
-    <color name="privacy_circle_camera">#81C995</color> <!-- g300 -->
-    <color name="privacy_circle_microphone_location">#FCAD70</color> <!--o300 -->
+    <color name="privacy_circle">#81C995</color> <!-- g300 -->
 
     <!-- Accessibility floating menu -->
     <color name="accessibility_floating_menu_background">#B3000000</color> <!-- 70% -->
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 9da7ad7..523b4c3 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -54,7 +54,7 @@
     <string name="usb_accessory_confirm_prompt" msgid="5728408382798643421">"<xliff:g id="APPLICATION">%1$s</xliff:g> openen om <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> te verwerken?"</string>
     <string name="usb_accessory_uri_prompt" msgid="6756649383432542382">"Er werken geen geïnstalleerde apps met dit USB-accessoire. Meer informatie op: <xliff:g id="URL">%1$s</xliff:g>"</string>
     <string name="title_usb_accessory" msgid="1236358027511638648">"USB-accessoire"</string>
-    <string name="label_view" msgid="6815442985276363364">"Weergeven"</string>
+    <string name="label_view" msgid="6815442985276363364">"Bekijken"</string>
     <string name="always_use_device" msgid="210535878779644679">"<xliff:g id="APPLICATION">%1$s</xliff:g> altijd openen wanneer <xliff:g id="USB_DEVICE">%2$s</xliff:g> is verbonden"</string>
     <string name="always_use_accessory" msgid="1977225429341838444">"<xliff:g id="APPLICATION">%1$s</xliff:g> altijd openen wanneer <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> is verbonden"</string>
     <string name="usb_debugging_title" msgid="8274884945238642726">"USB-foutopsporing toestaan?"</string>
@@ -108,7 +108,7 @@
     <string name="screenrecord_start" msgid="330991441575775004">"Starten"</string>
     <string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"Scherm opnemen"</string>
     <string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"Scherm en audio opnemen"</string>
-    <string name="screenrecord_taps_label" msgid="1595690528298857649">"Tikken op het scherm weergeven"</string>
+    <string name="screenrecord_taps_label" msgid="1595690528298857649">"Tikken op het scherm tonen"</string>
     <string name="screenrecord_stop_text" msgid="6549288689506057686">"Tik om te stoppen"</string>
     <string name="screenrecord_stop_label" msgid="72699670052087989">"Stoppen"</string>
     <string name="screenrecord_pause_label" msgid="6004054907104549857">"Pauzeren"</string>
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Annuleren"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Delen"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Schermopname geannuleerd"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Schermopname opgeslagen"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Tik om te bekijken"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Fout bij verwijderen van schermopname"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Kan rechten niet ophalen"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Fout bij starten van schermopname"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Nieuwe gebruiker"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wifi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Internet"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Geschikt voor vliegtuigen"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Netwerken beschikbaar"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Netwerken niet beschikbaar"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Niet verbonden"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Tot zonsopgang"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Aan om <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Tot <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Helderheid verlagen"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC is uitgeschakeld"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC is ingeschakeld"</string>
@@ -467,10 +463,9 @@
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Gebruiker wijzigen"</string>
     <string name="accessibility_multi_user_switch_switcher_with_current" msgid="5759855008166759399">"Schakelen tussen gebruikers, huidige gebruiker <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
     <string name="accessibility_multi_user_switch_inactive" msgid="383168614528618402">"Huidige gebruiker <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
-    <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Profiel weergeven"</string>
+    <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Profiel tonen"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Gebruiker toevoegen"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Nieuwe gebruiker"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Gastsessie beëindigen"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Gast verwijderen?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle apps en gegevens in deze sessie worden verwijderd."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Verwijderen"</string>
@@ -485,7 +480,7 @@
     <string name="user_logout_notification_text" msgid="7441286737342997991">"Huidige gebruiker uitloggen"</string>
     <string name="user_logout_notification_action" msgid="7974458760719361881">"GEBRUIKER UITLOGGEN"</string>
     <string name="user_add_user_title" msgid="4172327541504825032">"Nieuwe gebruiker toevoegen?"</string>
-    <string name="user_add_user_message_short" msgid="2599370307878014791">"Wanneer u een nieuwe gebruiker toevoegt, moet die persoon zijn eigen profiel instellen.\n\nElke gebruiker kan apps updaten voor alle andere gebruikers."</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Als je een nieuwe gebruiker toevoegt, moet die persoon zijn eigen profiel instellen.\n\nElke gebruiker kan apps updaten voor alle andere gebruikers."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Gebruikerslimiet bereikt"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Je kunt maximaal <xliff:g id="COUNT">%d</xliff:g> gebruikers toevoegen.</item>
@@ -501,7 +496,7 @@
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"De service die deze functie levert, krijgt toegang tot alle informatie die zichtbaar is op je scherm of die wordt afgespeeld vanaf je apparaat tijdens het opnemen of casten. Dit omvat informatie zoals wachtwoorden, betalingsgegevens, foto\'s, berichten en audio die je afspeelt."</string>
     <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Beginnen met opnemen of casten?"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"Beginnen met opnemen of casten met <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
-    <string name="media_projection_remember_text" msgid="6896767327140422951">"Niet opnieuw weergeven"</string>
+    <string name="media_projection_remember_text" msgid="6896767327140422951">"Niet opnieuw tonen"</string>
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Alles wissen"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Beheren"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"Geschiedenis"</string>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Dit apparaat wordt beheerd door je ouder"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Je organisatie is eigenaar van dit apparaat en kan het netwerkverkeer bijhouden"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> is eigenaar van dit apparaat en kan het netwerkverkeer bijhouden"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Dit apparaat wordt geleverd door <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Dit apparaat is eigendom van je organisatie en is verbonden met <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Dit apparaat is eigendom van <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> en is verbonden met <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Dit apparaat is eigendom van je organisatie"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Je werkprofiel is verbonden met <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Je persoonlijke profiel is verbonden met <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Dit apparaat is verbonden met <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Dit apparaat wordt geleverd door <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Apparaatbeheer"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Profielcontrole"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Netwerkcontrole"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Beleid bekijken"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Beheeropties bekijken"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Dit apparaat is eigendom van <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nJe IT-beheerder kan instellingen, zakelijke toegang, apps, aan je apparaat gekoppelde gegevens en de locatiegegevens van je apparaat bekijken en beheren.\n\nNeem contact op met je IT-beheerder voor meer informatie."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> kan mogelijk toegang krijgen tot gegevens die aan dit apparaat zijn gekoppeld, apps beheren en de instellingen van dit apparaat wijzigen.\n\nAls je vragen hebt, kun je contact opnemen met <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Dit apparaat is eigendom van je organisatie.\n\nJe IT-beheerder kan instellingen, zakelijke toegang, apps, aan je apparaat gekoppelde gegevens en de locatiegegevens van je apparaat bekijken en beheren.\n\nNeem contact op met je IT-beheerder voor meer informatie."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Je organisatie heeft een certificeringsinstantie geïnstalleerd op dit apparaat. Je beveiligde netwerkverkeer kan worden bijgehouden of aangepast."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Je organisatie heeft een certificeringsinstantie geïnstalleerd in je werkprofiel. Je beveiligde netwerkverkeer kan worden bijgehouden of aangepast."</string>
@@ -607,7 +605,7 @@
     <string name="screen_pinning_start" msgid="7483998671383371313">"App vastgezet"</string>
     <string name="screen_pinning_exit" msgid="4553787518387346893">"App losgemaakt"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="463533331480997595">"<xliff:g id="TILE_LABEL">%1$s</xliff:g> verbergen?"</string>
-    <string name="quick_settings_reset_confirmation_message" msgid="2320586180785674186">"Deze wordt opnieuw weergegeven zodra u de instelling weer inschakelt."</string>
+    <string name="quick_settings_reset_confirmation_message" msgid="2320586180785674186">"Deze zie je opnieuw zodra je de instelling weer aanzet."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="3341477479055016776">"Verbergen"</string>
     <string name="stream_voice_call" msgid="7468348170702375660">"Bellen"</string>
     <string name="stream_system" msgid="7663148785370565134">"Systeem"</string>
@@ -643,16 +641,18 @@
     <string name="output_service_wifi" msgid="9003667810868222134">"Wifi"</string>
     <string name="output_service_bt_wifi" msgid="7186882540475524124">"Bluetooth en wifi"</string>
     <string name="system_ui_tuner" msgid="1471348823289954729">"Systeem-UI-tuner"</string>
-    <string name="show_battery_percentage" msgid="6235377891802910455">"Percentage ingebouwde batterij weergeven"</string>
-    <string name="show_battery_percentage_summary" msgid="9053024758304102915">"Accupercentage weergeven in het icoon op de statusbalk wanneer er niet wordt opgeladen"</string>
+    <string name="show_battery_percentage" msgid="6235377891802910455">"Percentage ingebouwde batterij tonen"</string>
+    <string name="show_battery_percentage_summary" msgid="9053024758304102915">"Batterijniveau (percentage) tonen in het icoon op de statusbalk wanneer niet wordt opgeladen"</string>
     <string name="quick_settings" msgid="6211774484997470203">"Snelle instellingen"</string>
     <string name="status_bar" msgid="4357390266055077437">"Statusbalk"</string>
     <string name="overview" msgid="3522318590458536816">"Overzicht"</string>
     <string name="demo_mode" msgid="263484519766901593">"Demomodus voor systeemgebruikersinterface"</string>
     <string name="enable_demo_mode" msgid="3180345364745966431">"Demomodus inschakelen"</string>
-    <string name="show_demo_mode" msgid="3677956462273059726">"Demomodus weergeven"</string>
+    <string name="show_demo_mode" msgid="3677956462273059726">"Demomodus tonen"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Wekker"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Klaar"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Werkprofiel"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Vliegtuigmodus"</string>
     <string name="add_tile" msgid="6239678623873086686">"Tegel toevoegen"</string>
@@ -672,56 +672,56 @@
     <string name="remove_from_settings" msgid="633775561782209994">"Verwijderen uit Instellingen"</string>
     <string name="remove_from_settings_prompt" msgid="551565437265615426">"Systeem-UI-tuner uit Instellingen verwijderen en het gebruik van alle functies daarvan stopzetten?"</string>
     <string name="activity_not_found" msgid="8711661533828200293">"Deze app is niet geïnstalleerd op je apparaat"</string>
-    <string name="clock_seconds" msgid="8709189470828542071">"Klokseconden weergeven"</string>
-    <string name="clock_seconds_desc" msgid="2415312788902144817">"Klokseconden op de statusbalk weergeven. Kan van invloed zijn op de accuduur."</string>
+    <string name="clock_seconds" msgid="8709189470828542071">"Klokseconden tonen"</string>
+    <string name="clock_seconds_desc" msgid="2415312788902144817">"Klokseconden op de statusbalk tonen. Kan van invloed zijn op de batterijduur."</string>
     <string name="qs_rearrange" msgid="484816665478662911">"Snelle instellingen opnieuw indelen"</string>
-    <string name="show_brightness" msgid="6700267491672470007">"Helderheid weergeven in Snelle instellingen"</string>
+    <string name="show_brightness" msgid="6700267491672470007">"Helderheid tonen in Snelle instellingen"</string>
     <string name="experimental" msgid="3549865454812314826">"Experimenteel"</string>
     <string name="enable_bluetooth_title" msgid="866883307336662596">"Bluetooth inschakelen?"</string>
     <string name="enable_bluetooth_message" msgid="6740938333772779717">"Als je je toetsenbord wilt verbinden met je tablet, moet je eerst Bluetooth inschakelen."</string>
     <string name="enable_bluetooth_confirmation_ok" msgid="2866408183324184876">"Inschakelen"</string>
-    <string name="show_silently" msgid="5629369640872236299">"Meldingen zonder geluid weergeven"</string>
+    <string name="show_silently" msgid="5629369640872236299">"Meldingen zonder geluid tonen"</string>
     <string name="block" msgid="188483833983476566">"Alle meldingen blokkeren"</string>
     <string name="do_not_silence" msgid="4982217934250511227">"Niet zonder geluid weergeven"</string>
     <string name="do_not_silence_block" msgid="4361847809775811849">"Niet zonder geluid weergeven of blokkeren"</string>
     <string name="tuner_full_importance_settings" msgid="1388025816553459059">"Beheeropties voor meldingen met betrekking tot stroomverbruik"</string>
     <string name="tuner_full_importance_settings_on" msgid="917981436602311547">"Aan"</string>
     <string name="tuner_full_importance_settings_off" msgid="5580102038749680829">"Uit"</string>
-    <string name="power_notification_controls_description" msgid="1334963837572708952">"Met beheeropties voor meldingen met betrekking tot stroomverbruik kun je een belangrijkheidsniveau van 0 tot 5 instellen voor de meldingen van een app. \n\n"<b>"Niveau 5"</b>" \n- Boven aan de lijst met meldingen weergeven \n- Onderbreking op volledig scherm toestaan \n- Altijd korte weergave \n\n"<b>"Niveau 4"</b>" \n- Geen onderbreking op volledig scherm \n- Altijd korte weergave \n\n"<b>"Niveau 3"</b>" \n- Geen onderbreking op volledig scherm \n- Nooit korte weergave \n\n"<b>"Niveau 2"</b>" \n- Geen onderbreking op volledig scherm \n- Nooit korte weergave \n- Nooit geluid laten horen of trillen \n\n"<b>"Niveau 1"</b>" \n- Geen onderbreking op volledig scherm \n- Nooit korte weergave \n- Nooit geluid laten horen of trillen \n- Verbergen op vergrendelscherm en statusbalk \n- Onder aan de lijst met meldingen weergeven \n\n"<b>"Niveau 0"</b>" \n- Alle meldingen van de app blokkeren"</string>
+    <string name="power_notification_controls_description" msgid="1334963837572708952">"Met beheeropties voor meldingen met betrekking tot stroomverbruik kun je een belangrijkheidsniveau van 0 tot 5 instellen voor de meldingen van een app. \n\n"<b>"Niveau 5"</b>" \n- Bovenaan de lijst met meldingen tonen \n- Onderbreking op volledig scherm toestaan \n- Altijd korte weergave \n\n"<b>"Niveau 4"</b>" \n- Geen onderbreking op volledig scherm \n- Altijd korte weergave \n\n"<b>"Niveau 3"</b>" \n- Geen onderbreking op volledig scherm \n- Nooit korte weergave \n\n"<b>"Niveau 2"</b>" \n- Geen onderbreking op volledig scherm \n- Nooit korte weergave \n- Nooit geluid laten horen of trillen \n\n"<b>"Niveau 1"</b>" \n- Geen onderbreking op volledig scherm \n- Nooit korte weergave \n- Nooit geluid laten horen of trillen \n- Verbergen op vergrendelscherm en statusbalk \n- Onderaan de lijst met meldingen tonen \n\n"<b>"Niveau 0"</b>" \n- Alle meldingen van de app blokkeren"</string>
     <string name="notification_header_default_channel" msgid="225454696914642444">"Meldingen"</string>
-    <string name="notification_channel_disabled" msgid="928065923928416337">"Meldingen worden niet meer weergegeven"</string>
+    <string name="notification_channel_disabled" msgid="928065923928416337">"Je ziet deze meldingen niet meer"</string>
     <string name="notification_channel_minimized" msgid="6892672757877552959">"Deze meldingen worden geminimaliseerd"</string>
-    <string name="notification_channel_silenced" msgid="1995937493874511359">"Deze meldingen worden zonder geluid weergegeven"</string>
+    <string name="notification_channel_silenced" msgid="1995937493874511359">"Deze meldingen worden zonder geluid getoond"</string>
     <string name="notification_channel_unsilenced" msgid="94878840742161152">"Deze meldingen stellen je op de hoogte"</string>
-    <string name="inline_blocking_helper" msgid="2891486013649543452">"Meestal sluit je deze meldingen. \nWil je ze blijven weergeven?"</string>
+    <string name="inline_blocking_helper" msgid="2891486013649543452">"Meestal sluit je deze meldingen. \nWil je ze blijven tonen?"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Klaar"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Toepassen"</string>
-    <string name="inline_keep_showing" msgid="8736001253507073497">"Deze meldingen blijven weergeven?"</string>
+    <string name="inline_keep_showing" msgid="8736001253507073497">"Deze meldingen blijven tonen?"</string>
     <string name="inline_stop_button" msgid="2453460935438696090">"Meldingen stoppen"</string>
     <string name="inline_deliver_silently_button" msgid="2714314213321223286">"Zonder geluid afleveren"</string>
     <string name="inline_block_button" msgid="479892866568378793">"Blokkeren"</string>
-    <string name="inline_keep_button" msgid="299631874103662170">"Blijven weergeven"</string>
+    <string name="inline_keep_button" msgid="299631874103662170">"Blijven tonen"</string>
     <string name="inline_minimize_button" msgid="1474436209299333445">"Minimaliseren"</string>
     <string name="inline_silent_button_silent" msgid="525243786649275816">"Stil"</string>
     <string name="inline_silent_button_stay_silent" msgid="2129254868305468743">"Stil blijven"</string>
     <string name="inline_silent_button_alert" msgid="5705343216858250354">"Waarschuwen"</string>
     <string name="inline_silent_button_keep_alerting" msgid="6577845442184724992">"Blijven waarschuwen"</string>
     <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Meldingen uitschakelen"</string>
-    <string name="inline_keep_showing_app" msgid="4393429060390649757">"Meldingen van deze app blijven weergeven?"</string>
+    <string name="inline_keep_showing_app" msgid="4393429060390649757">"Meldingen van deze app blijven tonen?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Stil"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Standaard"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automatisch"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Geen geluid of trilling"</string>
-    <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Geen geluid of trilling en wordt lager in het gedeelte met gesprekken weergegeven"</string>
+    <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Geen geluid of trilling en wordt lager in het gedeelte met gesprekken getoond"</string>
     <string name="notification_channel_summary_default" msgid="3282930979307248890">"Kan overgaan of trillen op basis van de telefooninstellingen"</string>
-    <string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"Kan overgaan of trillen op basis van de telefooninstellingen. Gesprekken uit <xliff:g id="APP_NAME">%1$s</xliff:g> worden standaard als bubbels weergegeven."</string>
+    <string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"Kan overgaan of trillen op basis van de telefooninstellingen. Gesprekken uit <xliff:g id="APP_NAME">%1$s</xliff:g> worden standaard als bubbels getoond."</string>
     <string name="notification_channel_summary_bubble" msgid="7235935211580860537">"Trekt de aandacht met een zwevende snelkoppeling naar deze content."</string>
     <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Het systeem laten bepalen of deze melding geluid moet maken of moet trillen"</string>
     <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"&lt;b&gt;Status:&lt;/b&gt; opgeschaald naar Standaard"</string>
     <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"&lt;b&gt;Status:&lt;/b&gt; verlaagd naar Stil"</string>
     <string name="notification_channel_summary_automatic_promoted" msgid="1301710305149590426">"&lt;b&gt;Status:&lt;/b&gt; hoger gerangschikt"</string>
     <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" msgid="7952654515769021553">"Wordt bovenaan het gespreksgedeelte weergegeven, verschijnt als zwevende bubbel, geeft profielfoto weer op vergrendelscherm"</string>
+    <string name="notification_channel_summary_priority" msgid="7952654515769021553">"Verschijnt als zwevende bubbel bovenaan het gespreksgedeelte en toont profielfoto op vergrendelscherm"</string>
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Instellingen"</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>
@@ -729,7 +729,7 @@
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Deze groep meldingen kan hier niet worden ingesteld"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Melding via proxy"</string>
     <string name="notification_channel_dialog_title" msgid="6856514143093200019">"Alle meldingen van <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="see_more_title" msgid="7409317011708185729">"Meer weergeven"</string>
+    <string name="see_more_title" msgid="7409317011708185729">"Meer tonen"</string>
     <string name="appops_camera" msgid="5215967620896725715">"Deze app gebruikt de camera."</string>
     <string name="appops_microphone" msgid="8805468338613070149">"Deze app gebruikt de microfoon."</string>
     <string name="appops_overlay" msgid="4822261562576558490">"Deze app wordt over andere apps op je scherm heen weergegeven."</string>
@@ -758,7 +758,7 @@
     <string name="notification_conversation_unfavorite" msgid="181383708304763807">"Geen belangrijk gesprek"</string>
     <string name="notification_conversation_mute" msgid="268951550222925548">"Zonder geluid"</string>
     <string name="notification_conversation_unmute" msgid="2692255619510896710">"Waarschuwen"</string>
-    <string name="notification_conversation_bubble" msgid="2242180995373949022">"Ballon weergeven"</string>
+    <string name="notification_conversation_bubble" msgid="2242180995373949022">"Ballon tonen"</string>
     <string name="notification_conversation_unbubble" msgid="6908427185031099868">"Bubbels verwijderen"</string>
     <string name="notification_conversation_home_screen" msgid="8347136037958438935">"Toevoegen aan startscherm"</string>
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
@@ -822,7 +822,7 @@
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Muziek"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="5078136084632450333">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Agenda"</string>
-    <string name="tuner_full_zen_title" msgid="5120366354224404511">"Weergeven met volumeknoppen"</string>
+    <string name="tuner_full_zen_title" msgid="5120366354224404511">"Tonen met volumeknoppen"</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="volume_up_silent" msgid="1035180298885717790">"\'Niet storen\' afsluiten bij volume omhoog"</string>
@@ -872,16 +872,16 @@
     <string name="qs_edit" msgid="5583565172803472437">"Bewerken"</string>
     <string name="tuner_time" msgid="2450785840990529997">"Tijd"</string>
   <string-array name="clock_options">
-    <item msgid="3986445361435142273">"Uren, minuten en seconden weergeven"</item>
-    <item msgid="1271006222031257266">"Uren en minuten weergeven (standaard)"</item>
-    <item msgid="6135970080453877218">"Dit icoon niet weergeven"</item>
+    <item msgid="3986445361435142273">"Uren, minuten en seconden tonen"</item>
+    <item msgid="1271006222031257266">"Uren en minuten tonen (standaard)"</item>
+    <item msgid="6135970080453877218">"Dit icoon niet tonen"</item>
   </string-array>
   <string-array name="battery_options">
-    <item msgid="7714004721411852551">"Percentage altijd weergeven"</item>
-    <item msgid="3805744470661798712">"Percentage weergeven tijdens opladen (standaard)"</item>
-    <item msgid="8619482474544321778">"Dit icoon niet weergeven"</item>
+    <item msgid="7714004721411852551">"Percentage altijd tonen"</item>
+    <item msgid="3805744470661798712">"Percentage tonen tijdens opladen (standaard)"</item>
+    <item msgid="8619482474544321778">"Dit icoon niet tonen"</item>
   </string-array>
-    <string name="tuner_low_priority" msgid="8412666814123009820">"Pictogrammen voor meldingen met lage prioriteit weergeven"</string>
+    <string name="tuner_low_priority" msgid="8412666814123009820">"Iconen voor meldingen met lage prioriteit tonen"</string>
     <string name="other" msgid="429768510980739978">"Overig"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"tegel verwijderen"</string>
     <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"tegel toevoegen aan einde"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Snelle instellingen sluiten."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Wekker is ingesteld."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Ingelogd als <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"gebruiker kiezen"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Geen internet"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Details openen."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"Niet beschikbaar vanwege <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g>-instellingen openen."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Volgorde van instellingen bewerken."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Aan/uit-menu"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Pagina <xliff:g id="ID_1">%1$d</xliff:g> van <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Vergrendelscherm"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"Telefoon uitgezet wegens hitte"</string>
@@ -961,10 +963,10 @@
     <string name="mobile_data_disable_message" msgid="8604966027899770415">"Je hebt dan geen toegang meer tot data of internet via <xliff:g id="CARRIER">%s</xliff:g>. Internet is alleen nog beschikbaar via wifi."</string>
     <string name="mobile_data_disable_message_default_carrier" msgid="6496033312431658238">"je provider"</string>
     <string name="touch_filtered_warning" msgid="8119511393338714836">"Aangezien een app een rechtenverzoek afdekt, kan Instellingen je reactie niet verifiëren."</string>
-    <string name="slice_permission_title" msgid="3262615140094151017">"<xliff:g id="APP_0">%1$s</xliff:g> toestaan om segmenten van <xliff:g id="APP_2">%2$s</xliff:g> weer te geven?"</string>
+    <string name="slice_permission_title" msgid="3262615140094151017">"<xliff:g id="APP_0">%1$s</xliff:g> toestaan om segmenten van <xliff:g id="APP_2">%2$s</xliff:g> te tonen?"</string>
     <string name="slice_permission_text_1" msgid="6675965177075443714">"- Deze kan informatie lezen van <xliff:g id="APP">%1$s</xliff:g>"</string>
     <string name="slice_permission_text_2" msgid="6758906940360746983">"- Deze kan acties uitvoeren in <xliff:g id="APP">%1$s</xliff:g>"</string>
-    <string name="slice_permission_checkbox" msgid="4242888137592298523">"<xliff:g id="APP">%1$s</xliff:g> toestaan om segmenten van apps weer te geven"</string>
+    <string name="slice_permission_checkbox" msgid="4242888137592298523">"<xliff:g id="APP">%1$s</xliff:g> toestaan om segmenten van apps te tonen"</string>
     <string name="slice_permission_allow" msgid="6340449521277951123">"Toestaan"</string>
     <string name="slice_permission_deny" msgid="6870256451658176895">"Weigeren"</string>
     <string name="auto_saver_title" msgid="6873691178754086596">"Tikken om Batterijbesparing in te schakelen"</string>
@@ -996,9 +998,9 @@
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Stand-by"</string>
     <string name="priority_onboarding_title" msgid="2893070698479227616">"Gesprek ingesteld als prioriteit"</string>
     <string name="priority_onboarding_behavior" msgid="5342816047020432929">"Prioriteitsgesprekken:"</string>
-    <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Worden bovenaan het gespreksgedeelte weergegeven"</string>
+    <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Worden bovenaan het gespreksgedeelte getoond"</string>
     <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Tonen profielafbeelding op vergrendelscherm"</string>
-    <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Worden als zwevende ballon weergegeven vóór apps"</string>
+    <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Zijn als zwevende ballon zichtbaar vóór apps"</string>
     <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Onderbreken \'Niet storen\'"</string>
     <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"OK"</string>
     <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Instellingen"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Naar links verplaatsen"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Naar rechts verplaatsen"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Vergrotingsschakelaar"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Hele scherm vergroten"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Volledig scherm vergroten"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Deel van het scherm vergroten"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Schakelen"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"De knop Toegankelijkheid vervangt het toegankelijkheidsgebaar\n\n"<annotation id="link">"Instellingen bekijken"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Knop naar de rand verplaatsen om deze tijdelijk te verbergen"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Apparaatbediening"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Bedieningselementen voor je gekoppelde apparaten toevoegen"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Apparaatbediening instellen"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Nieuw apparaat koppelen"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Gesprekswidgets"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Tik op een gesprek om het toe te voegen aan je startscherm"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> geleden"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"Minder dan <xliff:g id="DURATION">%1$s</xliff:g> geleden"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"Meer dan <xliff:g id="DURATION">%1$s</xliff:g> geleden"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Verjaardag"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Bijna jarig"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Jubileum"</string>
+    <string name="location_status" msgid="1294990572202541812">"Locatie delen"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Nieuw verhaal"</string>
+    <string name="video_status" msgid="4548544654316843225">"Aan het kijken"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Aan het luisteren"</string>
+    <string name="game_status" msgid="1340694320630973259">"Aan het spelen"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Vrienden"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Chatten vanavond?"</string>
+    <string name="missed_call" msgid="4228016077700161689">"Gemist gesprek"</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="battery_state_unknown_notification_title" msgid="8464703640483773454">"Probleem bij het lezen van je batterijmeter"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tik hier voor meer informatie"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Geen wekker gezet"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index c847d15..3bbdd30 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"ବାତିଲ୍‌ କରନ୍ତୁ"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"ସେୟାର୍‍ କରନ୍ତୁ"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"ସ୍କ୍ରିନ୍‍ ରେକର୍ଡିଂ ବାତିଲ୍‌ କରିଦିଆଯାଇଛି"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"ସ୍କ୍ରିନ୍ ରେକର୍ଡିଂ ସେଭ୍ କରାଯାଇଛି"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"ଦେଖିବାକୁ ଟାପ୍ କରନ୍ତୁ"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"ସ୍କ୍ରିନ୍‍ ରେକର୍ଡିଂ ଡିଲିଟ୍‍ କରିବାରେ ତ୍ରୁଟି"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"ଅନୁମତି ପାଇବାରେ ଅସଫଳ ହେଲା।"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"ସ୍କ୍ରିନ୍ ରେକର୍ଡିଂ ଆରମ୍ଭ କରିବାରେ ତ୍ରୁଟି"</string>
@@ -357,11 +355,10 @@
     <string name="quick_settings_settings_label" msgid="2214639529565474534">"ସେଟିଂସ୍"</string>
     <string name="quick_settings_time_label" msgid="3352680970557509303">"ସମୟ"</string>
     <string name="quick_settings_user_label" msgid="1253515509432672496">"ମୁଁ"</string>
-    <string name="quick_settings_user_title" msgid="8673045967216204537">"ୟୁଜର୍‌"</string>
+    <string name="quick_settings_user_title" msgid="8673045967216204537">"ଉପଯୋଗକର୍ତ୍ତା‌"</string>
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"ନୂଆ ଉପଯୋଗକର୍ତ୍ତା"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"ୱାଇ-ଫାଇ"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"ଇଣ୍ଟରନେଟ୍"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"ଏୟାରପ୍ଲେନ୍-ସେଫ୍"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"ନେଟୱାର୍କଗୁଡ଼ିକ ଉପଲବ୍ଧ"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"ନେଟୱାର୍କ ଉପଲବ୍ଧ ନାହିଁ"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"ସଂଯୁକ୍ତ ହୋଇନାହିଁ"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"ସକାଳ ପର୍ଯ୍ୟନ୍ତ"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g>ରେ ଚାଲୁ ହେବ"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> ପର୍ଯ୍ୟନ୍ତ"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"ଉଜ୍ଜ୍ୱଳତା କମ୍ କରନ୍ତୁ"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC ଅକ୍ଷମ କରାଯାଇଛି"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC ସକ୍ଷମ କରାଯାଇଛି"</string>
@@ -470,12 +466,11 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"ପ୍ରୋଫାଇଲ୍ ଦେଖାନ୍ତୁ"</string>
     <string name="user_add_user" msgid="4336657383006913022">"ଉପଯୋଗକର୍ତ୍ତାଙ୍କୁ ଯୋଗ କରନ୍ତୁ"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"ନୂଆ ଉପଯୋଗକର୍ତ୍ତା"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"ଅତିଥି ସେସନ୍ ଶେଷ କରନ୍ତୁ"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"ଅତିଥିଙ୍କୁ କାଢ଼ିଦେବେ?"</string>
-    <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ଏହି ଅବଧିର ସମସ୍ତ ଆପ୍‌ ଓ ଡାଟା ଡିଲିଟ୍‌ ହୋଇଯିବ।"</string>
+    <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ଏହି ସେସନର ସମସ୍ତ ଆପ୍‌ ଓ ଡାଟା ଡିଲିଟ୍‌ ହୋଇଯିବ।"</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"କାଢ଼ିଦିଅନ୍ତୁ"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"ପୁଣି ସ୍ୱାଗତ, ଅତିଥି!"</string>
-    <string name="guest_wipe_session_message" msgid="3393823610257065457">"ଆପଣ ନିଜର ଅବଧି ଜାରି ରଖିବାକୁ ଚାହାନ୍ତି କି?"</string>
+    <string name="guest_wipe_session_message" msgid="3393823610257065457">"ଆପଣ ନିଜର ସେସନ୍ ଜାରି ରଖିବାକୁ ଚାହାଁନ୍ତି କି?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ଆରମ୍ଭ କରନ୍ତୁ"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"ହଁ, ଜାରି ରଖନ୍ତୁ"</string>
     <string name="guest_notification_title" msgid="4434456703930764167">"ଅତିଥି ୟୁଜର୍‍"</string>
@@ -485,7 +480,7 @@
     <string name="user_logout_notification_text" msgid="7441286737342997991">"ବର୍ତ୍ତମାନର ୟୁଜରଙ୍କୁ ଲଗଆଉଟ୍‍ କରନ୍ତୁ"</string>
     <string name="user_logout_notification_action" msgid="7974458760719361881">"ୟୁଜରଙ୍କୁ ଲଗଆଉଟ୍‍ କରନ୍ତୁ"</string>
     <string name="user_add_user_title" msgid="4172327541504825032">"ନୂତନ ଉପଯୋଗକର୍ତ୍ତା ଯୋଗ କରିବେ?"</string>
-    <string name="user_add_user_message_short" msgid="2599370307878014791">"ଜଣେ ନୂଆ ୟୁଜର୍‍ଙ୍କୁ ଯୋଡ଼ିବାବେଳେ, ସେହି ବ୍ୟକ୍ତିଙ୍କୁ ସ୍ଥାନ ସେଟ୍‍ କରିବାକୁ ପଡ଼ିବ। \n \n ଅନ୍ୟ ସମସ୍ତ ୟୁଜର୍‍ଙ୍କ ପାଇଁ ଯେକୌଣସି ୟୁଜର୍‍ ଆପ୍‌ଗୁଡ଼ିକୁ ଅପଡେଟ୍‌ କରିପାରିବେ।"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"ଆପଣ ଜଣେ ନୂଆ ଉପଯୋଗକର୍ତ୍ତାଙ୍କୁ ଯୋଗ କଲେ,ତାଙ୍କୁ ସ୍ପେସ୍ ସେଟ୍ ଅପ୍ କରିବାକୁ ପଡ଼ିବ। \n \n ଅନ୍ୟ ସମସ୍ତ ଉପଯୋଗକର୍ତ୍ତାଙ୍କ ପାଇଁ ଯେ କୌଣସି ଉପଯୋଗକର୍ତ୍ତା ଆପଗୁଡ଼ିକୁ ଅପଡେଟ୍‌ କରିପାରିବେ।"</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"ଉପଯୋଗକର୍ତ୍ତା ସୀମାରେ ପହଞ୍ଚିଛି"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">କେବଳ <xliff:g id="COUNT">%d</xliff:g> ଉପଯୋଗକର୍ତ୍ତା ହିଁ ତିଆରି କରିହେବ।</item>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ଏହି ଡିଭାଇସ୍ ଆପଣଙ୍କ ବାପାମାଙ୍କ ଦ୍ୱାରା ପରିଚାଳିତ"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ଏହି ଡିଭାଇସର ମାଲିକାନା ଆପଣଙ୍କ ସଂସ୍ଥା ପାଖରେ ଅଛି ଏବଂ ଏହା ନେଟୱାର୍କ ଟ୍ରାଫିକର ନିରୀକ୍ଷଣ କରିପାରେ"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"ଏହି ଡିଭାଇସଟି <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>ର ଅଟେ ଏବଂ ଏହା ନେଟୱାର୍କ ଟ୍ରାଫିକକୁ ନିରୀକ୍ଷଣ କରିପାରେ"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"ଏହି ଡିଭାଇସ୍ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ଦ୍ୱାରା ପ୍ରଦାନ କରାଯାଇଛି"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"ଏହି ଡିଭାଇସଟି ଆପଣଙ୍କ ସଂସ୍ଥାର ଅଟେ ଏବଂ ଏହା <xliff:g id="VPN_APP">%1$s</xliff:g> ସହ ସଂଯୁକ୍ତ ଅଛି"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"ଏହି ଡିଭାଇସଟି <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>ର ଅଟେ ଏବଂ ଏହା <xliff:g id="VPN_APP">%2$s</xliff:g> ସହ ସଂଯୁକ୍ତ ଅଛି"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"ଏହି ଡିଭାଇସଟି ଆପଣଙ୍କ ସଂସ୍ଥାର ଅଟେ"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"ଆପଣଙ୍କ ୱାର୍କ ପ୍ରୋଫାଇଲ୍ <xliff:g id="VPN_APP">%1$s</xliff:g> ସହ ସଂଯୁକ୍ତ ଅଛି"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"ଆପଣଙ୍କ ବ୍ୟକ୍ତିଗତ ପ୍ରୋଫାଇଲ୍ <xliff:g id="VPN_APP">%1$s</xliff:g> ସହ ସଂଯୁକ୍ତ ଅଛି"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"ଏହି ଡିଭାଇସଟି <xliff:g id="VPN_APP">%1$s</xliff:g> ସହ ସଂଯୁକ୍ତ ଅଛି"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"ଏହି ଡିଭାଇସ୍ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ଦ୍ୱାରା ପ୍ରଦାନ କରାଯାଇଛି"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"ଡିଭାଇସ୍‌ ପରିଚାଳନା"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"ପ୍ରୋଫାଇଲ୍ ନୀରିକ୍ଷଣ"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"ନେଟ୍‌ୱର୍କ ନୀରିକ୍ଷଣ"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"ପଲିସୀ ଦେଖନ୍ତୁ"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକୁ ଦେଖନ୍ତୁ"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"ଏହି ଡିଭାଇସଟି <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>ର ଅଟେ।\n\nଆପଣଙ୍କ IT ଆଡମିନ୍ ସେଟିଂସ୍, କର୍ପୋରେଟ୍ ଆକ୍ସେସ୍, ଆପ୍ସ, ଆପଣଙ୍କ ଡିଭାଇସ୍ ସହ ସମ୍ବନ୍ଧିତ ଡାଟା ଏବଂ ଆପଣଙ୍କ ଡିଭାଇସର ଲୋକେସନ୍ ସୂଚନାକୁ ନିରୀକ୍ଷଣ ଏବଂ ପରିଚାଳନା କରିପାରିବେ।\n\nଅଧିକ ସୂଚନା ପାଇଁ, ଆପଣଙ୍କ IT ଆଡମିନଙ୍କ ସହ ଯୋଗାଯୋଗ କରନ୍ତୁ।"</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> ଏହି ଡିଭାଇସ ସହ ସମ୍ବନ୍ଧିତ ଡାଟା ଆକ୍ସେସ୍ କରିବା, ଆପଗୁଡ଼ିକୁ ପରିଚାଳନା କରିବା ଏବଂ ଏହି ଡିଭାଇସର ସେଟିଂସ୍ ବଦଳାଇବାକୁ ସକ୍ଷମ ହୋଇପାରେ।\n\nଯଦି ଆପଣଙ୍କର କିଛି ପ୍ରଶ୍ନ ଅଛି, ତେବେ <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g> ସହ ଯୋଗାଯୋଗ କରନ୍ତୁ।"</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"ଏହି ଡିଭାଇସଟି ଆପଣଙ୍କ ସଂସ୍ଥାର ଅଟେ।\n\nଆପଣଙ୍କ IT ଆଡମିନ୍ ସେଟିଂସ୍, କର୍ପୋରେଟ୍ ଆକ୍ସେସ୍, ଆପ୍ସ, ଆପଣଙ୍କ ଡିଭାଇସ୍ ସହ ସମ୍ବନ୍ଧିତ ଡାଟା ଏବଂ ଆପଣଙ୍କ ଡିଭାଇସର ଲୋକେସନ୍ ସୂଚନାକୁ ନିରୀକ୍ଷଣ ଏବଂ ପରିଚାଳନା କରିପାରିବେ।\n\nଅଧିକ ସୂଚନା ପାଇଁ, ଆପଣଙ୍କ IT ଆଡମିନଙ୍କ ସହ ଯୋଗାଯୋଗ କରନ୍ତୁ।"</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"ଏହି ଡିଭାଇସରେ ଆପଣଙ୍କ ସଂସ୍ଥା ଏକ ସର୍ଟିଫିକେଟ୍‍ ଅଥରିଟି ଇନଷ୍ଟଲ୍‍ କରିଛନ୍ତି। ଆପଣଙ୍କ ସୁରକ୍ଷିତ ନେଟୱର୍କ ଟ୍ରାଫିକ୍‍ ନୀରିକ୍ଷଣ କିମ୍ବା ସଂଶୋଧନ କରାଯାଇ ପାରେ।"</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"ଆପଣଙ୍କ ୱର୍କ ପ୍ରୋଫାଇଲରେ ଆପଣଙ୍କ ସଂସ୍ଥା ଏକ ସର୍ଟିଫିକେଟ୍‍ ଅଥରିଟି ଇନଷ୍ଟଲ୍‍ କରିଛନ୍ତି। ଆପଣଙ୍କ ସୁରକ୍ଷିତ ନେଟୱର୍କ ଟ୍ରାଫିକ୍‍ ନୀରିକ୍ଷଣ କିମ୍ବା ସଂଶୋଧନ କରାଯାଇ ପାରେ।"</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"ଡେମୋ ମୋଡ୍‍ ଦେଖାନ୍ତୁ"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"ଇଥରନେଟ୍‌"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"ଆଲାର୍ମ"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"ୱାଲେଟ୍"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"ପ୍ରସ୍ତୁତ"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"ୱର୍କ ପ୍ରୋଫାଇଲ୍‌"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"ଏରୋପ୍ଲେନ୍‍ ମୋଡ୍"</string>
     <string name="add_tile" msgid="6239678623873086686">"ଟାଇଲ୍‍ ଯୋଡ଼ନ୍ତୁ"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"ଦ୍ରୁତ ସେଟିଂସ୍ ବନ୍ଦ କରନ୍ତୁ।"</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"ଆଲାର୍ମ ସେଟ୍‍।"</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"<xliff:g id="ID_1">%s</xliff:g> ଭାବରେ ସାଇନ୍‌ ଇନ୍‌ କରିଛନ୍ତି"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"ଉପଯୋଗକର୍ତ୍ତା ବାଛନ୍ତୁ"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"କୌଣସି ଇଣ୍ଟରନେଟ୍‌ କନେକ୍ସନ୍ ନାହିଁ"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"ବିବରଣୀ ଖୋଲନ୍ତୁ"</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"<xliff:g id="REASON">%s</xliff:g> ଯୋଗୁଁ ଉପଲବ୍ଧ ନାହିଁ"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> ସେଟିଙ୍ଗ ଖୋଲନ୍ତୁ।"</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"ସେଟିଙ୍ଗର କ୍ରମ ସଂଶୋଧନ କରନ୍ତୁ।"</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"ପାୱାର ମେନୁ"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"ପୃଷ୍ଠା <xliff:g id="ID_1">%1$d</xliff:g> ମୋଟ <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"ଲକ୍‌ ସ୍କ୍ରୀନ୍‌"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"ଗରମ ହେତୁ ଫୋନ୍‍ ଅଫ୍‍ କରିଦିଆଗଲା"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"ବାମକୁ ମୁଭ୍ କରନ୍ତୁ"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"ଡାହାଣକୁ ମୁଭ୍ କରନ୍ତୁ"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"ମ୍ୟାଗ୍ନିଫିକେସନ୍ ସ୍ୱିଚ୍"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"ସମ୍ପୂର୍ଣ୍ଣ ସ୍କ୍ରିନ୍ ମାଗ୍ନିଫାଏ କରନ୍ତୁ"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"ସମ୍ପୂର୍ଣ୍ଣ ସ୍କ୍ରିନକୁ ମ୍ୟାଗ୍ନିଫାଏ କରନ୍ତୁ"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"ସ୍କ୍ରିନର ଅଂଶ ମାଗ୍ନିଫାଏ କରନ୍ତୁ"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"ସ୍ୱିଚ୍ କରନ୍ତୁ"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"ଆକ୍ସେସିବିଲିଟୀ ଜେଶ୍ଚରକୁ ଆକ୍ସେସିବିଲିଟୀ ବଟନରେ ପରିବର୍ତ୍ତନ କରାଯାଇଛି\n\n"<annotation id="link">"ସେଟିଂସ୍ ଦେଖନ୍ତୁ"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"ବଟନକୁ ଅସ୍ଥାୟୀ ଭାବେ ଲୁଚାଇବା ପାଇଁ ଧାରକୁ ମୁଭ୍ କରନ୍ତୁ"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"ଡିଭାଇସ୍ ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକ"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"ଆପଣଙ୍କ ସଂଯୁକ୍ତ ଡିଭାଇସଗୁଡ଼ିକ ପାଇଁ ନିୟନ୍ତ୍ରଣ ଯୋଗ କରନ୍ତୁ"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"ଡିଭାଇସ୍ ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକୁ ସେଟ୍ ଅପ୍ କରନ୍ତୁ"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"ନୂଆ ଡିଭାଇସକୁ ପେୟାର୍ କରନ୍ତୁ"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"ବାର୍ତ୍ତାଳାପ ୱିଜେଟଗୁଡ଼ିକ"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"ଏକ ବାର୍ତ୍ତାଳାପକୁ ଆପଣଙ୍କ ମୂଳସ୍କ୍ରିନରେ ଯୋଗ କରିବା ପାଇଁ ସେଥିରେ ଟାପ୍ କରନ୍ତୁ"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> ପୂର୍ବେ"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"<xliff:g id="DURATION">%1$s</xliff:g>ରୁ କମ୍ ସମୟ ପୂର୍ବେ"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"<xliff:g id="DURATION">%1$s</xliff:g>ରୁ ଅଧିକ ସମୟ ପୂର୍ବେ"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"ଜନ୍ମଦିନ"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"ଜନ୍ମଦିନ ଶୀଘ୍ର ଆସୁଛି"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"ବାର୍ଷିକ ଉତ୍ସବ"</string>
+    <string name="location_status" msgid="1294990572202541812">"ଲୋକେସନ୍ ସେୟାର୍ ହେଉଛି"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"ନୂଆ ଷ୍ଟୋରୀ"</string>
+    <string name="video_status" msgid="4548544654316843225">"ଦେଖୁଛନ୍ତି"</string>
+    <string name="audio_status" msgid="4237055636967709208">"ଶୁଣୁଛି"</string>
+    <string name="game_status" msgid="1340694320630973259">"ଚାଲୁଛି"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"ସାଙ୍ଗମାନେ"</string>
+    <string name="empty_status" msgid="5938893404951307749">"ରାତିରେ ଚାଟ୍ କରିବା!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"ମିସ୍ଡ କଲ୍"</string>
+    <string name="people_tile_description" msgid="8154966188085545556">"ବର୍ତ୍ତମାନର ମେସେଜ୍, ମିସ୍ଡ କଲ୍ ଏବଂ ସ୍ଥିତି ଅପଡେଟଗୁଡ଼ିକୁ ଦେଖନ୍ତୁ"</string>
+    <string name="people_tile_title" msgid="6589377493334871272">"ବାର୍ତ୍ତାଳାପ"</string>
     <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"ଆପଣଙ୍କ ବ୍ୟାଟେରୀ ମିଟର୍ ପଢ଼ିବାରେ ସମସ୍ୟା ହେଉଛି"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"ଅଧିକ ସୂଚନା ପାଇଁ ଟାପ୍ କରନ୍ତୁ"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"ଆଲାର୍ମ ସେଟ୍ ହୋଇନାହିଁ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 53a71a6..9a58ef6 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"ਰੱਦ ਕਰੋ"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"ਸਾਂਝਾ ਕਰੋ"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"ਸਕ੍ਰੀਨ ਦੀ ਰਿਕਾਰਡਿੰਗ ਰੱਦ ਕੀਤੀ ਗਈ"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਿੰਗ ਰੱਖਿਅਤ ਕੀਤੀ ਗਈ"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"ਦੇਖਣ ਲਈ ਟੈਪ ਕਰੋ"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਿੰਗ ਨੂੰ ਮਿਟਾਉਣ ਦੌਰਾਨ ਗੜਬੜ ਹੋਈ"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"ਇਜਾਜ਼ਤਾਂ ਪ੍ਰਾਪਤ ਕਰਨਾ ਅਸਫਲ ਰਿਹਾ"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਿੰਗ ਨੂੰ ਸ਼ੁਰੂ ਕਰਨ ਵੇਲੇ ਗੜਬੜ ਹੋਈ"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"ਨਵਾਂ ਵਰਤੋਂਕਾਰ"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"ਵਾਈ-ਫਾਈ"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"ਇੰਟਰਨੈੱਟ"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"ਹਵਾਈ-ਜਹਾਜ਼ ਸੁਰੱਖਿਅਤ ਮੋਡ"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"ਨੈੱਟਵਰਕ ਉਪਲਬਧ ਹਨ"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"ਨੈੱਟਵਰਕ ਉਪਲਬਧ ਨਹੀਂ ਹਨ"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"ਕਨੈਕਟ ਨਹੀਂ ਕੀਤਾ"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"ਸੂਰਜ ਚੜ੍ਹਨ ਤੱਕ"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g> ਵਜੇ ਚਾਲੂ"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> ਵਜੇ ਤੱਕ"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"ਚਮਕ ਘਟਾਓ"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC ਨੂੰ ਅਯੋਗ ਬਣਾਇਆ ਗਿਆ ਹੈ"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC ਨੂੰ ਯੋਗ ਬਣਾਇਆ ਗਿਆ ਹੈ"</string>
@@ -470,13 +466,12 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"ਪ੍ਰੋਫਾਈਲ ਦਿਖਾਓ"</string>
     <string name="user_add_user" msgid="4336657383006913022">"ਵਰਤੋਂਕਾਰ ਸ਼ਾਮਲ ਕਰੋ"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"ਨਵਾਂ ਵਰਤੋਂਕਾਰ"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"ਮਹਿਮਾਨ ਸੈਸ਼ਨ ਸਮਾਪਤ ਕਰੋ"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"ਕੀ ਮਹਿਮਾਨ ਹਟਾਉਣਾ ਹੈ?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ਇਸ ਸੈਸ਼ਨ ਵਿੱਚ ਸਾਰੀਆਂ ਐਪਾਂ ਅਤੇ ਡਾਟਾ ਨੂੰ ਮਿਟਾ ਦਿੱਤਾ ਜਾਏਗਾ।"</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"ਹਟਾਓ"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"ਮਹਿਮਾਨ, ਫਿਰ ਤੁਹਾਡਾ ਸੁਆਗਤ ਹੈ!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"ਕੀ ਤੁਸੀਂ ਆਪਣਾ ਸੈਸ਼ਨ ਜਾਰੀ ਰੱਖਣਾ ਚਾਹੁੰਦੇ ਹੋ?"</string>
-    <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ਸ਼ੁਰੂ ਕਰੋ"</string>
+    <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ਮੁੜ-ਸ਼ੁਰੂ ਕਰੋ"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"ਹਾਂ, ਜਾਰੀ ਰੱਖੋ"</string>
     <string name="guest_notification_title" msgid="4434456703930764167">"ਮਹਿਮਾਨ ਉਪਭੋਗਤਾ"</string>
     <string name="guest_notification_text" msgid="4202692942089571351">"ਐਪਾਂ ਅਤੇ ਡਾਟਾ ਮਿਟਾਉਣ ਲਈ, ਮਹਿਮਾਨ ਵਰਤੋਂਕਾਰ ਹਟਾਓ"</string>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ਇਸ ਡੀਵਾਈਸ ਦਾ ਪ੍ਰਬੰਧਨ ਤੁਹਾਡੇ ਮਾਂ-ਪਿਓ ਵੱਲੋਂ ਕੀਤਾ ਜਾਂਦਾ ਹੈ"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ਤੁਹਾਡੀ ਸੰਸਥਾ ਕੋਲ ਇਸ ਡੀਵਾਈਸ ਦੀ ਮਲਕੀਅਤ ਹੈ ਅਤੇ ਇਹ ਨੈੱਟਵਰਕ ਟਰੈਫ਼ਿਕ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦੀ ਹੈ"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ਕੋਲ ਇਸ ਡੀਵਾਈਸ ਦੀ ਮਲਕੀਅਤ ਹੈ ਅਤੇ ਇਹ ਨੈੱਟਵਰਕ ਟਰੈਫ਼ਿਕ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦੀ ਹੈ"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"ਇਹ ਡੀਵਾਈਸ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ਵੱਲੋਂ ਮੁਹੱਈਆ ਕੀਤਾ ਗਿਆ ਹੈ"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"ਇਹ ਡੀਵਾਈਸ ਤੁਹਾਡੀ ਸੰਸਥਾ ਨਾਲ ਸੰਬੰਧਿਤ ਹੈ ਅਤੇ <xliff:g id="VPN_APP">%1$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਹੈ"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"ਇਹ ਡੀਵਾਈਸ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ਨਾਲ ਸੰਬੰਧਿਤ ਹੈ ਅਤੇ <xliff:g id="VPN_APP">%2$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਹੈ"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"ਇਹ ਡੀਵਾਈਸ ਤੁਹਾਡੀ ਸੰਸਥਾ ਨਾਲ ਸੰਬੰਧਿਤ ਹੈ"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"ਤੁਹਾਡਾ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ <xliff:g id="VPN_APP">%1$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਹੈ"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"ਤੁਹਾਡਾ ਨਿੱਜੀ ਪ੍ਰੋਫਾਈਲ <xliff:g id="VPN_APP">%1$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਹੈ"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"ਇਹ ਡੀਵਾਈਸ <xliff:g id="VPN_APP">%1$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਹੈ"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"ਇਹ ਡੀਵਾਈਸ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ਵੱਲੋਂ ਮੁਹੱਈਆ ਕੀਤਾ ਗਿਆ ਹੈ"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"ਡੀਵਾਈਸ ਪ੍ਰਬੰਧਨ"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"ਪ੍ਰੋਫਾਈਲ ਦਾ ਨਿਰੀਖਣ ਕਰਨਾ"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"ਨੈੱਟਵਰਕ ਨਿਰੀਖਣ ਕਰ ਰਿਹਾ ਹੈ"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"ਨੀਤੀਆਂ ਦੇਖੋ"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"ਕੰਟਰੋਲ ਦੇਖੋ"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"ਇਹ ਡੀਵਾਈਸ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ਨਾਲ ਸੰਬੰਧਿਤ ਹੈ।\n\nਤੁਹਾਡਾ ਆਈ.ਟੀ. ਪ੍ਰਸ਼ਾਸਕ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਨਾਲ ਸੰਬੰਧਿਤ ਸੈਟਿੰਗਾਂ, ਕਾਰਪੋਰੇਟ ਪਹੁੰਚ, ਐਪਾਂ, ਡਾਟੇ ਅਤੇ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਦੀ ਟਿਕਾਣਾ ਜਾਣਕਾਰੀ ਦੀ ਨਿਗਰਾਨੀ ਅਤੇ ਪ੍ਰਬੰਧਨ ਕਰ ਸਕਦਾ ਹੈ।\n\nਹੋਰ ਜਾਣਕਾਰੀ ਲਈ, ਆਪਣੇ ਆਈ.ਟੀ. ਪ੍ਰਸ਼ਾਸਕ ਨੂੰ ਸੰਪਰਕ ਕਰੋ।"</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> ਇਸ ਡੀਵਾਈਸ ਨਾਲ ਸੰਬੰਧਿਤ ਡਾਟੇ ਤੱਕ ਪਹੁੰਚ ਕਰ ਸਕਦੀ ਹੈ, ਐਪਾਂ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰ ਸਕਦੀ ਹੈ ਅਤੇ ਇਸ ਡੀਵਾਈਸ ਦੀਆਂ ਸੈਟਿੰਗਾਂ ਨੂੰ ਬਦਲ ਸਕਦੀ ਹੈ।\n\nਜੇ ਤੁਹਾਡਾ ਕੋਈ ਸਵਾਲ ਹੈ, ਤਾਂ <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g> ਨੂੰ ਸੰਪਰਕ ਕਰੋ।"</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"ਇਹ ਡੀਵਾਈਸ ਤੁਹਾਡੀ ਸੰਸਥਾ ਨਾਲ ਸੰਬੰਧਿਤ ਹੈ।\n\nਤੁਹਾਡਾ ਆਈ.ਟੀ. ਪ੍ਰਸ਼ਾਸਕ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਨਾਲ ਸੰਬੰਧਿਤ ਸੈਟਿੰਗਾਂ, ਕਾਰਪੋਰੇਟ ਪਹੁੰਚ, ਐਪਾਂ, ਡਾਟੇ ਅਤੇ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਦੀ ਟਿਕਾਣਾ ਜਾਣਕਾਰੀ ਦੀ ਨਿਗਰਾਨੀ ਅਤੇ ਪ੍ਰਬੰਧਨ ਕਰ ਸਕਦਾ ਹੈ।\n\nਹੋਰ ਜਾਣਕਾਰੀ ਲਈ, ਆਪਣੇ ਆਈ.ਟੀ. ਪ੍ਰਸ਼ਾਸਕ ਨੂੰ ਸੰਪਰਕ ਕਰੋ।"</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"ਤੁਹਾਡੀ ਸੰਸਥਾ ਵੱਲੋਂ ਇਸ ਡੀਵਾਈਸ \'ਤੇ ਇੱਕ ਪ੍ਰਮਾਣ-ਪੱਤਰ ਅਥਾਰਟੀ ਸਥਾਪਤ ਕੀਤੀ ਗਈ ਹੈ। ਤੁਹਾਡੇ ਸੁਰੱਖਿਅਤ ਨੈੱਟਵਰਕ ਟਰੈਫਿਕ ਦੀ ਨਿਗਰਾਨੀ ਕੀਤੀ ਜਾ ਸਕਦੀ ਹੈ ਜਾਂ ਉਸਨੂੰ ਸੋਧਿਆ ਜਾ ਸਕਦਾ ਹੈ।"</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"ਤੁਹਾਡੀ ਸੰਸਥਾ ਵੱਲੋਂ ਤੁਹਾਡੇ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਵਿੱਚ ਇੱਕ ਪ੍ਰਮਾਣ-ਪੱਤਰ ਅਥਾਰਟੀ ਸਥਾਪਤ ਕੀਤੀ ਗਈ ਹੈ। ਤੁਹਾਡੇ ਸੁਰੱਖਿਅਤ ਨੈੱਟਵਰਕ ਟਰੈਫਿਕ ਦੀ ਨਿਗਰਾਨੀ ਕੀਤੀ ਜਾ ਸਕਦੀ ਹੈ ਜਾਂ ਉਸਨੂੰ ਸੋਧਿਆ ਜਾ ਸਕਦਾ ਹੈ।"</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"ਡੈਮੋ ਮੋਡ ਦੇਖੋ"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"ਈਥਰਨੈਟ"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"ਅਲਾਰਮ"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"ਵਾਲੇਟ"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"ਤਿਆਰ"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"ਹਵਾਈ-ਜਹਾਜ਼ ਮੋਡ"</string>
     <string name="add_tile" msgid="6239678623873086686">"ਟਾਇਲ ਸ਼ਾਮਲ ਕਰੋ"</string>
@@ -709,7 +709,7 @@
     <string name="inline_turn_off_notifications" msgid="8543989584403106071">"ਸੂਚਨਾਵਾਂ ਬੰਦ ਕਰੋ"</string>
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"ਕੀ ਇਸ ਐਪ ਤੋਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਦਿਖਾਉਣਾ ਜਾਰੀ ਰੱਖਣਾ ਹੈ?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"ਸ਼ਾਂਤ"</string>
-    <string name="notification_alert_title" msgid="3656229781017543655">"ਪੂਰਵ-ਨਿਰਧਾਰਤ"</string>
+    <string name="notification_alert_title" msgid="3656229781017543655">"ਪੂਰਵ-ਨਿਰਧਾਰਿਤ"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"ਸਵੈਚਲਿਤ"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"ਕੋਈ ਧੁਨੀ ਜਾਂ ਥਰਥਰਾਹਟ ਨਹੀਂ"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"ਕੋਈ ਧੁਨੀ ਜਾਂ ਥਰਥਰਾਹਟ ਨਹੀਂ ਅਤੇ ਸੂਚਨਾਵਾਂ ਗੱਲਬਾਤ ਸੈਕਸ਼ਨ ਵਿੱਚ ਹੇਠਲੇ ਪਾਸੇ ਦਿਸਦੀਆਂ ਹਨ"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"ਤਤਕਾਲ ਸੈਟਿੰਗਾਂ ਨੂੰ ਬੰਦ ਕਰੋ।"</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"ਅਲਾਰਮ ਸੈੱਟ ਕੀਤਾ।"</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"<xliff:g id="ID_1">%s</xliff:g> ਵਜੋਂ ਸਾਈਨ ਇਨ ਕੀਤਾ"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"ਵਰਤੋਂਕਾਰ ਚੁਣੋ"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"ਇੰਟਰਨੈੱਟ ਨਹੀਂ।"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"ਵੇਰਵੇ ਖੋਲ੍ਹੋ।"</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"<xliff:g id="REASON">%s</xliff:g> ਦੇ ਕਾਰਨ ਅਣਉਪਲਬਧ ਹੈ"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> ਸੈਟਿੰਗਾਂ ਖੋਲ੍ਹੋ।"</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"ਸੈਟਿੰਗਾਂ ਦੇ ਕ੍ਰਮ ਦਾ ਸੰਪਾਦਨ ਕਰੋ।"</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"ਪਾਵਰ ਮੀਨੂ"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g> ਦਾ <xliff:g id="ID_1">%1$d</xliff:g> ਪੰਨਾ"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">" ਲਾਕ  ਸਕ੍ਰੀਨ"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"ਗਰਮ ਹੋਣ ਕਾਰਨ ਫ਼ੋਨ ਬੰਦ ਹੋ ਗਿਆ"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"ਖੱਬੇ ਲਿਜਾਓ"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"ਸੱਜੇ ਲਿਜਾਓ"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"ਵੱਡਦਰਸ਼ੀਕਰਨ ਸਵਿੱਚ"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"ਸਾਰੀ ਸਕ੍ਰੀਨ ਨੂੰ ਵੱਡਾ ਕਰੋ"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"ਪੂਰੀ ਸਕ੍ਰੀਨ ਨੂੰ ਵੱਡਦਰਸ਼ੀ ਕਰੋ"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"ਸਕ੍ਰੀਨ ਦੇ ਹਿੱਸੇ ਨੂੰ ਵੱਡਾ ਕਰੋ"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"ਸਵਿੱਚ"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"ਪਹੁੰਚਯੋਗਤਾ ਬਟਨ ਨੂੰ ਪਹੁੰਚਯੋਗਤਾ ਸੰਕੇਤ ਨਾਲ ਬਦਲ ਦਿੱਤਾ ਗਿਆ\n\n"<annotation id="link">"ਸੈਟਿੰਗਾਂ ਦੇਖੋ"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"ਬਟਨ ਨੂੰ ਅਸਥਾਈ ਤੌਰ \'ਤੇ ਲੁਕਾਉਣ ਲਈ ਕਿਨਾਰੇ \'ਤੇ ਲਿਜਾਓ"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"ਡੀਵਾਈਸ ਕੰਟਰੋਲ"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"ਆਪਣੇ ਕਨੈਕਟ ਕੀਤੇ ਡੀਵਾਈਸਾਂ ਲਈ ਕੰਟਰੋਲ ਸ਼ਾਮਲ ਕਰੋ"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"ਡੀਵਾਈਸ ਕੰਟਰੋਲਾਂ ਦਾ ਸੈੱਟਅੱਪ ਕਰੋ"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"ਨਵਾਂ ਡੀਵਾਈਸ ਜੋੜਾਬੱਧ ਕਰੋ"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"ਗੱਲਬਾਤ ਵਿਜੇਟ"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"ਆਪਣੀ ਹੋਮ ਸਕ੍ਰੀਨ \'ਤੇ ਸ਼ਾਮਲ ਕਰਨ ਲਈ ਕੋਈ ਗੱਲਬਾਤ ਚੁਣੋ"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> ਪਹਿਲਾਂ"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"<xliff:g id="DURATION">%1$s</xliff:g> ਤੋਂ ਘੱਟ ਸਮਾਂ ਪਹਿਲਾਂ"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"<xliff:g id="DURATION">%1$s</xliff:g> ਤੋਂ ਵੱਧ ਸਮਾਂ ਪਹਿਲਾਂ"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"ਜਨਮਦਿਨ"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"ਜਨਮਦਿਨ ਜਲਦ ਆ ਰਿਹਾ ਹੈ"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"ਵਰ੍ਹੇਗੰਢ"</string>
+    <string name="location_status" msgid="1294990572202541812">"ਟਿਕਾਣਾ ਸਾਂਝਾ ਹੋ ਰਿਹਾ ਹੈ"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"ਨਵੀਂ ਕਹਾਣੀ"</string>
+    <string name="video_status" msgid="4548544654316843225">"ਦੇਖਿਆ ਜਾ ਰਿਹਾ ਹੈ"</string>
+    <string name="audio_status" msgid="4237055636967709208">"ਸੁਣਿਆ ਜਾ ਰਿਹਾ ਹੈ"</string>
+    <string name="game_status" msgid="1340694320630973259">"ਖੇਡੀ ਜਾ ਰਹੀ ਹੈ"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"ਦੋਸਤ"</string>
+    <string name="empty_status" msgid="5938893404951307749">"ਆਓ ਅੱਜ ਰਾਤ ਚੈਟ ਕਰੀਏ!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"ਮਿਸ ਕਾਲ"</string>
+    <string name="people_tile_description" msgid="8154966188085545556">"ਹਾਲੀਆ ਸੁਨੇਹੇ, ਮਿਸ ਕਾਲਾਂ ਅਤੇ ਸਥਿਤੀ ਸੰਬੰਧੀ ਅੱਪਡੇਟ ਦੇਖੋ"</string>
+    <string name="people_tile_title" msgid="6589377493334871272">"ਗੱਲਬਾਤ"</string>
     <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"ਤੁਹਾਡੇ ਬੈਟਰੀ ਮੀਟਰ ਨੂੰ ਪੜ੍ਹਨ ਵਿੱਚ ਸਮੱਸਿਆ ਹੋ ਰਹੀ ਹੈ"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"ਹੋਰ ਜਾਣਕਾਰੀ ਲਈ ਟੈਪ ਕਰੋ"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"ਕੋਈ ਅਲਾਰਮ ਸੈੱਟ ਨਹੀਂ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index f8c275d..c936dc2 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Anuluj"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Udostępnij"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Anulowano nagrywanie zawartości ekranu"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Zapisano nagranie zawartości ekranu"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Kliknij, aby wyświetlić"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Błąd podczas usuwania nagrania zawartości ekranu"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Nie udało się uzyskać uprawnień"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Błąd podczas rozpoczynania rejestracji zawartości ekranu"</string>
@@ -363,7 +361,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Nowy użytkownik"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Internet"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Bezpieczne w trybie samolotowym"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Sieci dostępne"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Sieci niedostępne"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Brak połączenia"</string>
@@ -419,7 +416,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Do wschodu słońca"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Włącz o <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Do <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Zmniejsz jasność"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"Komunikacja NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"Komunikacja NFC jest wyłączona"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"Komunikacja NFC jest włączona"</string>
@@ -474,11 +470,10 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Pokaż profil"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Dodaj użytkownika"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Nowy użytkownik"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Zakończ sesję gościa"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Usunąć gościa?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Wszystkie aplikacje i dane w tej sesji zostaną usunięte."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Usuń"</string>
-    <string name="guest_wipe_session_title" msgid="7147965814683990944">"Witaj ponownie, gościu!"</string>
+    <string name="guest_wipe_session_title" msgid="7147965814683990944">"Witaj ponownie, Gościu!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Chcesz kontynuować sesję?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Rozpocznij nową"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Tak, kontynuuj"</string>
@@ -525,6 +520,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Tym urządzeniem zarządza Twój rodzic"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Twoja organizacja jest właścicielem tego urządzenia i może monitorować ruch w sieci"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Organizacja <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> jest właścicielem tego urządzenia i może monitorować ruch w sieci"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"To urządzenie dostarcza organizacja <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"To urządzenie należy do Twojej organizacji i jest połączone z siecią <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"To urządzenie należy do organizacji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> i jest połączone z siecią <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"To urządzenie należy do Twojej organizacji"</string>
@@ -538,6 +534,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Twój profil służbowy jest połączony z siecią <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Twój profil osobisty jest połączony z siecią <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"To urządzenie jest połączone z siecią <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"To urządzenie dostarcza organizacja <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Zarządzanie urządzeniami"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Monitorowanie profilu"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Monitorowanie sieci"</string>
@@ -549,6 +546,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Zobacz zasady"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Wyświetl elementy sterujące"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"To urządzenie należy do organizacji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nAdministrator IT może monitorować ustawienia, firmowe uprawnienia dostępu, aplikacje, dane dotyczące urządzenia i lokalizacji oraz nimi zarządzać.\n\nAby dowiedzieć się więcej, skontaktuj się z administratorem IT."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"Organizacja <xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> może uzyskać dostęp do danych powiązanych z tym urządzeniem, zarządzać aplikacjami i zmieniać ustawienia urządzenia.\n\nJeśli masz pytania, skontaktuj się z organizacją <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"To urządzenie należy do Twojej organizacji.\n\nAdministrator IT może monitorować ustawienia, firmowe uprawnienia dostępu, aplikacje, dane dotyczące urządzenia i lokalizacji oraz nimi zarządzać.\n\nAby dowiedzieć się więcej, skontaktuj się z administratorem IT."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Twoja organizacja zainstalowała urząd certyfikacji na tym urządzeniu. Zabezpieczony ruch w sieci może być monitorowany i zmieniany."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Twoja organizacja zainstalowała urząd certyfikacji w Twoim profilu służbowym. Zabezpieczony ruch w sieci może być monitorowany i zmieniany."</string>
@@ -659,6 +657,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Pokaż tryb demonstracyjny"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Alarm"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Portfel"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Gotowe"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Profil służbowy"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Tryb samolotowy"</string>
     <string name="add_tile" msgid="6239678623873086686">"Dodaj nazwę"</string>
@@ -909,11 +909,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Zamknij szybkie ustawienia."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Alarm ustawiony."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Zalogowany użytkownik: <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"wybrać użytkownika"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Brak internetu"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Otwórz szczegóły."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"Niedostępne z powodu: <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Otwórz ustawienia: <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Edytuj kolejność ustawień."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menu zasilania"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Strona <xliff:g id="ID_1">%1$d</xliff:g> z <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Ekran blokady"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"Telefon wyłączony: przegrzanie"</string>
@@ -1021,9 +1023,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Przesuń w lewo"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Przesuń w prawo"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Przełączanie powiększenia"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Powiększ cały ekran"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Powiększanie pełnego ekranu"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Powiększ część ekranu"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Przełącz"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"Przycisk ułatwień dostępu zastąpił gest ułatwień dostępu\n\n"<annotation id="link">"Wyświetl ustawienia"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Przesuń przycisk do krawędzi, aby ukryć go tymczasowo"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Sterowanie urządzeniami"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Dodaj elementy sterujące połączonymi urządzeniami"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Konfigurowanie sterowania urządzeniami"</string>
@@ -1093,6 +1097,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Sparuj nowe urządzenie"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Widżety Rozmowa"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Kliknij rozmowę, aby dodać ją do ekranu głównego"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> temu"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"Mniej niż <xliff:g id="DURATION">%1$s</xliff:g> temu"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"Ponad <xliff:g id="DURATION">%1$s</xliff:g> temu"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Urodziny"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Wkrótce urodziny"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Rocznica"</string>
+    <string name="location_status" msgid="1294990572202541812">"Udostępniam lokalizację"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Nowy artykuł"</string>
+    <string name="video_status" msgid="4548544654316843225">"Oglądam"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Słucham"</string>
+    <string name="game_status" msgid="1340694320630973259">"Odtwarzam"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Znajomi"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Porozmawiajmy!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"Nieodebrane połączenie"</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="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problem z odczytaniem pomiaru wykorzystania baterii"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Kliknij, aby uzyskać więcej informacji"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nie ustawiono alarmu"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index ab53aa0..a9c454e 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Cancelar"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Compartilhar"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Gravação de tela cancelada"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Gravação de tela salva"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Toque para ver"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Erro ao excluir a gravação de tela"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Não foi possível acessar as permissões"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Erro ao iniciar a gravação de tela"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Novo usuário"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Internet"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Segura para aviões"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Redes disponíveis"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Redes indisponíveis"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Não conectado"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Até o nascer do sol"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Ativar: <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Até: <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Reduzir brilho"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"A NFC está desativada"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"A NFC está ativada"</string>
@@ -470,17 +466,16 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Mostrar perfil"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Adicionar usuário"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Novo usuário"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Encerrar sessão de visitante"</string>
-    <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Remover convidado?"</string>
+    <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Remover visitante?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Todos os apps e dados nesta sessão serão excluídos."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Remover"</string>
-    <string name="guest_wipe_session_title" msgid="7147965814683990944">"Bem-vindo, convidado."</string>
+    <string name="guest_wipe_session_title" msgid="7147965814683990944">"Você voltou, visitante!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Quer continuar a sessão?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Recomeçar"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Sim, continuar"</string>
-    <string name="guest_notification_title" msgid="4434456703930764167">"Usuário convidado"</string>
-    <string name="guest_notification_text" msgid="4202692942089571351">"Para excluir apps e dados, remova o usuário convidado"</string>
-    <string name="guest_notification_remove_action" msgid="4153019027696868099">"REMOVER CONVIDADO"</string>
+    <string name="guest_notification_title" msgid="4434456703930764167">"Usuário visitante"</string>
+    <string name="guest_notification_text" msgid="4202692942089571351">"Para excluir apps e dados, remova o usuário visitante"</string>
+    <string name="guest_notification_remove_action" msgid="4153019027696868099">"REMOVER VISITANTE"</string>
     <string name="user_logout_notification_title" msgid="3644848998053832589">"Desconectar usuário"</string>
     <string name="user_logout_notification_text" msgid="7441286737342997991">"Desconectar usuário atual"</string>
     <string name="user_logout_notification_action" msgid="7974458760719361881">"DESCONECTAR USUÁRIO"</string>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Este dispositivo é gerenciado pelo seu pai/mãe"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Sua organização é dona deste dispositivo e pode monitorar o tráfego de rede"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"A organização <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> é dona deste dispositivo e pode monitorar o tráfego de rede"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Este dispositivo é fornecido pela <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Este dispositivo pertence à sua organização e está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Este dispositivo pertence à organização <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> e está conectado a <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Este dispositivo pertence à sua organização"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Seu perfil de trabalho está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Seu perfil pessoal está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Este dispositivo está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Este dispositivo é fornecido pela <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Gerenciamento de dispositivos"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Monitoramento de perfis"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Monitoramento de rede"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Ver políticas"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Ver controles"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Este dispositivo pertence à organização <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nO administrador de TI pode monitorar e gerenciar configurações, acesso corporativo, apps, dados associados ao dispositivo e informações de local do dispositivo.\n\nPara saber mais, entre em contato com seu administrador de TI."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"A empresa <xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> pode gerenciar apps, mudar as configurações deste dispositivo e acessar dados associados a ele.\n\nNo caso de dúvidas, entre em contato com <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Este dispositivo pertence à sua organização.\n\nO administrador de TI pode monitorar e gerenciar configurações, acesso corporativo, apps, dados associados ao dispositivo e informações de local do dispositivo.\n\nPara saber mais, entre em contato com seu administrador de TI."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Sua organização instalou uma autoridade de certificação neste dispositivo. É possível monitorar ou modificar seu tráfego de rede seguro."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Sua organização instalou uma autoridade de certificação no seu perfil de trabalho. É possível monitorar ou modificar seu tráfego de rede seguro."</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Mostrar modo de demonstração"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Alarme"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Carteira"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Pronto"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Perfil de trabalho"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Modo avião"</string>
     <string name="add_tile" msgid="6239678623873086686">"Adicionar bloco"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Fechar as configurações rápidas."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Alarme definido."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Login efetuado como <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"escolher o usuário"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Sem Internet"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Abrir detalhes."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"Indisponível devido a <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Abrir configurações de <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Editar ordem das configurações."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menu liga/desliga"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Página <xliff:g id="ID_1">%1$d</xliff:g> de <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Tela de bloqueio"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"O smartphone foi desligado devido ao aquecimento"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Mover para a esquerda"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Mover para a direita"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Chave de ampliação"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Ampliar toda a tela"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Ampliar toda a tela"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Ampliar parte da tela"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Trocar"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"O botão de acessibilidade substituiu o gesto de acessibilidade\n\n"<annotation id="link">"Veja as configurações"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Mova o botão para a borda para ocultá-lo temporariamente"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Controles do dispositivo"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Adiciona controles aos dispositivos conectados"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Configurar controles do dispositivo"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Parear novo dispositivo"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Widgets de conversa"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Toque em uma conversa para adicioná-la à tela inicial"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> atrás"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"Menos de <xliff:g id="DURATION">%1$s</xliff:g> atrás"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"Mais de <xliff:g id="DURATION">%1$s</xliff:g> atrás"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Aniversário"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Aniversário chegando"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Data comemorativa"</string>
+    <string name="location_status" msgid="1294990572202541812">"Compartilhando local"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Nova story"</string>
+    <string name="video_status" msgid="4548544654316843225">"Assistindo"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Ouvindo"</string>
+    <string name="game_status" msgid="1340694320630973259">"Jogando"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Amigos"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Vamos conversar hoje à noite."</string>
+    <string name="missed_call" msgid="4228016077700161689">"Chamada perdida"</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="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problema para ler seu medidor de bateria"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Toque para mais informações"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nenhum alarme definido"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 884b210..dde6906 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Cancelar"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Partilhar"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Gravação de ecrã cancelada."</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Gravação de ecrã guardada."</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Toque para ver"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Erro ao eliminar a gravação de ecrã."</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Falha ao obter as autorizações."</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Ocorreu um erro ao iniciar a gravação do ecrã."</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Novo utilizador"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Internet"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Seguras para aviões"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Redes disponíveis"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Redes indisponíveis"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Não Ligado"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Até ao amanhecer"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Ativado à(s) <xliff:g id="TIME">%s</xliff:g>."</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Até à(s) <xliff:g id="TIME">%s</xliff:g>."</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Reduzir o brilho"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"O NFC está desativado"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"O NFC está ativado"</string>
@@ -470,11 +466,10 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Mostrar perfil"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Adicionar utilizador"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Novo utilizador"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Terminar sessão de convidado"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Remover o convidado?"</string>
-    <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Todas as aplicações e dados desta sessão serão eliminados."</string>
+    <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Todas as apps e dados desta sessão serão eliminados."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Remover"</string>
-    <string name="guest_wipe_session_title" msgid="7147965814683990944">"Bem-vindo de volta, caro(a) convidado(a)!"</string>
+    <string name="guest_wipe_session_title" msgid="7147965814683990944">"Bem-vindo de volta, convidado!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Pretende continuar a sessão?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Recomeçar"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Sim, continuar"</string>
@@ -485,7 +480,7 @@
     <string name="user_logout_notification_text" msgid="7441286737342997991">"Terminar sessão do utilizador atual"</string>
     <string name="user_logout_notification_action" msgid="7974458760719361881">"TERMINAR SESSÃO DO UTILIZADOR"</string>
     <string name="user_add_user_title" msgid="4172327541504825032">"Adicionar um novo utilizador?"</string>
-    <string name="user_add_user_message_short" msgid="2599370307878014791">"Ao adicionar um novo utilizador, essa pessoa tem de configurar o respetivo espaço.\n\nQualquer utilizador pode atualizar aplicações para todos os outros utilizadores."</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Ao adicionar um novo utilizador, essa pessoa tem de configurar o respetivo espaço.\n\nQualquer utilizador pode atualizar apps para todos os outros utilizadores."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Limite de utilizadores alcançado"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Pode adicionar até <xliff:g id="COUNT">%d</xliff:g> utilizadores.</item>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Este dispositivo é gerido pelos teus pais"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"A sua entidade gere este dispositivo e pode monitorizar o tráfego de rede."</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"A entidade <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> é proprietária deste dispositivo e pode monitorizar o tráfego de rede."</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Este dispositivo foi fornecido pela <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>."</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Este dispositivo pertence à sua entidade e está ligado a <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Este dispositivo pertence à entidade <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> e está ligado a <xliff:g id="VPN_APP">%2$s</xliff:g>."</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Este dispositivo pertence à sua entidade."</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"O seu perfil de trabalho está ligado a <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"O seu perfil pessoal está ligado a <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Este dispositivo está ligado a <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Este dispositivo foi fornecido pela <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>."</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Gestão de dispositivos"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Monitorização de perfis"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Monitorização da rede"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Ver Políticas"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Ver controlos"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Este dispositivo pertence à entidade <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nO administrador de TI pode monitorizar e gerir as definições, o acesso empresarial, as apps, os dados associados ao dispositivo e as informações de localização do mesmo.\n\nContacte o administrador de TI para obter mais informações."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"A <xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> pode conseguir aceder aos dados associados a este dispositivo, gerir apps e alterar as definições do mesmo.\n\nSe tiver perguntas, contacte a <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Este dispositivo pertence à sua entidade.\n\nO administrador de TI pode monitorizar e gerir as definições, o acesso empresarial, as apps, os dados associados ao dispositivo e as informações de localização do mesmo.\n\nContacte o administrador de TI para obter mais informações."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"A sua entidade instalou uma autoridade de certificação neste dispositivo. O tráfego da sua rede segura pode ser monitorizado ou alterado."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"A sua entidade instalou uma autoridade de certificação no seu perfil de trabalho. O tráfego da sua rede segura pode ser monitorizado ou alterado."</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Mostrar modo de demonstração"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Alarme"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Carteira"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Pronto"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Perfil de trabalho"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Modo de avião"</string>
     <string name="add_tile" msgid="6239678623873086686">"Adicionar mosaico"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Fechar as definições rápidas."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Alarme definido."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Sessão iniciada como <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"escolher o utilizador"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Sem Internet"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Abrir os detalhes."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"Indisponível devido a <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Abrir as definições de <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Editar a ordem das definições."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menu ligar/desligar"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Página <xliff:g id="ID_1">%1$d</xliff:g> de <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Ecrã de bloqueio"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"Telem. deslig. devido ao calor"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Mover para a esquerda"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Mover para a direita"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Interruptor de ampliação"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Ampliar o ecrã inteiro"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Ampliar o ecrã inteiro"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Ampliar parte do ecrã"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Mudar"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"O botão Acessibilidade substituiu o gesto de acessibilidade\n\n"<annotation id="link">"Ver definições"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Mova o botão para a extremidade para o ocultar temporariamente"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Controlos de dispositivos"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Adicione controlos para os dispositivos associados."</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Configure os controlos de dispositivos"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Sincronize o novo dispositivo"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Widgets de conversa"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Toque numa conversa para a adicionar ao ecrã principal"</string>
+    <string name="timestamp" msgid="6577851592534538533">"Há <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"Há menos de <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"Há mais de <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Aniversário"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Aniversário em breve"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Aniversário"</string>
+    <string name="location_status" msgid="1294990572202541812">"A partilhar localiz."</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Nova notícia"</string>
+    <string name="video_status" msgid="4548544654316843225">"A ver"</string>
+    <string name="audio_status" msgid="4237055636967709208">"A ouvir"</string>
+    <string name="game_status" msgid="1340694320630973259">"Em reprodução"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Amigos"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Vamos conversar!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"Chamada não atendida"</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="battery_state_unknown_notification_title" msgid="8464703640483773454">"Ocorreu um problema ao ler o medidor da bateria"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Toque para obter mais informações"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nenhum alarme defin."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index ab53aa0..a9c454e 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Cancelar"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Compartilhar"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Gravação de tela cancelada"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Gravação de tela salva"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Toque para ver"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Erro ao excluir a gravação de tela"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Não foi possível acessar as permissões"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Erro ao iniciar a gravação de tela"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Novo usuário"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Internet"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Segura para aviões"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Redes disponíveis"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Redes indisponíveis"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Não conectado"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Até o nascer do sol"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Ativar: <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Até: <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Reduzir brilho"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"A NFC está desativada"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"A NFC está ativada"</string>
@@ -470,17 +466,16 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Mostrar perfil"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Adicionar usuário"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Novo usuário"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Encerrar sessão de visitante"</string>
-    <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Remover convidado?"</string>
+    <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Remover visitante?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Todos os apps e dados nesta sessão serão excluídos."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Remover"</string>
-    <string name="guest_wipe_session_title" msgid="7147965814683990944">"Bem-vindo, convidado."</string>
+    <string name="guest_wipe_session_title" msgid="7147965814683990944">"Você voltou, visitante!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Quer continuar a sessão?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Recomeçar"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Sim, continuar"</string>
-    <string name="guest_notification_title" msgid="4434456703930764167">"Usuário convidado"</string>
-    <string name="guest_notification_text" msgid="4202692942089571351">"Para excluir apps e dados, remova o usuário convidado"</string>
-    <string name="guest_notification_remove_action" msgid="4153019027696868099">"REMOVER CONVIDADO"</string>
+    <string name="guest_notification_title" msgid="4434456703930764167">"Usuário visitante"</string>
+    <string name="guest_notification_text" msgid="4202692942089571351">"Para excluir apps e dados, remova o usuário visitante"</string>
+    <string name="guest_notification_remove_action" msgid="4153019027696868099">"REMOVER VISITANTE"</string>
     <string name="user_logout_notification_title" msgid="3644848998053832589">"Desconectar usuário"</string>
     <string name="user_logout_notification_text" msgid="7441286737342997991">"Desconectar usuário atual"</string>
     <string name="user_logout_notification_action" msgid="7974458760719361881">"DESCONECTAR USUÁRIO"</string>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Este dispositivo é gerenciado pelo seu pai/mãe"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Sua organização é dona deste dispositivo e pode monitorar o tráfego de rede"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"A organização <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> é dona deste dispositivo e pode monitorar o tráfego de rede"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Este dispositivo é fornecido pela <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Este dispositivo pertence à sua organização e está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Este dispositivo pertence à organização <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> e está conectado a <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Este dispositivo pertence à sua organização"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Seu perfil de trabalho está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Seu perfil pessoal está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Este dispositivo está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Este dispositivo é fornecido pela <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Gerenciamento de dispositivos"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Monitoramento de perfis"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Monitoramento de rede"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Ver políticas"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Ver controles"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Este dispositivo pertence à organização <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nO administrador de TI pode monitorar e gerenciar configurações, acesso corporativo, apps, dados associados ao dispositivo e informações de local do dispositivo.\n\nPara saber mais, entre em contato com seu administrador de TI."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"A empresa <xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> pode gerenciar apps, mudar as configurações deste dispositivo e acessar dados associados a ele.\n\nNo caso de dúvidas, entre em contato com <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Este dispositivo pertence à sua organização.\n\nO administrador de TI pode monitorar e gerenciar configurações, acesso corporativo, apps, dados associados ao dispositivo e informações de local do dispositivo.\n\nPara saber mais, entre em contato com seu administrador de TI."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Sua organização instalou uma autoridade de certificação neste dispositivo. É possível monitorar ou modificar seu tráfego de rede seguro."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Sua organização instalou uma autoridade de certificação no seu perfil de trabalho. É possível monitorar ou modificar seu tráfego de rede seguro."</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Mostrar modo de demonstração"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Alarme"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Carteira"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Pronto"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Perfil de trabalho"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Modo avião"</string>
     <string name="add_tile" msgid="6239678623873086686">"Adicionar bloco"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Fechar as configurações rápidas."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Alarme definido."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Login efetuado como <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"escolher o usuário"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Sem Internet"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Abrir detalhes."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"Indisponível devido a <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Abrir configurações de <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Editar ordem das configurações."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menu liga/desliga"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Página <xliff:g id="ID_1">%1$d</xliff:g> de <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Tela de bloqueio"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"O smartphone foi desligado devido ao aquecimento"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Mover para a esquerda"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Mover para a direita"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Chave de ampliação"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Ampliar toda a tela"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Ampliar toda a tela"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Ampliar parte da tela"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Trocar"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"O botão de acessibilidade substituiu o gesto de acessibilidade\n\n"<annotation id="link">"Veja as configurações"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Mova o botão para a borda para ocultá-lo temporariamente"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Controles do dispositivo"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Adiciona controles aos dispositivos conectados"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Configurar controles do dispositivo"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Parear novo dispositivo"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Widgets de conversa"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Toque em uma conversa para adicioná-la à tela inicial"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> atrás"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"Menos de <xliff:g id="DURATION">%1$s</xliff:g> atrás"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"Mais de <xliff:g id="DURATION">%1$s</xliff:g> atrás"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Aniversário"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Aniversário chegando"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Data comemorativa"</string>
+    <string name="location_status" msgid="1294990572202541812">"Compartilhando local"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Nova story"</string>
+    <string name="video_status" msgid="4548544654316843225">"Assistindo"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Ouvindo"</string>
+    <string name="game_status" msgid="1340694320630973259">"Jogando"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Amigos"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Vamos conversar hoje à noite."</string>
+    <string name="missed_call" msgid="4228016077700161689">"Chamada perdida"</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="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problema para ler seu medidor de bateria"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Toque para mais informações"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nenhum alarme definido"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 6a928da..d9e48a1 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Anulați"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Trimiteți"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Înregistrarea ecranului a fost anulată"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Înregistrarea ecranului a fost salvată"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Atingeți pentru a afișa"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Eroare la ștergerea înregistrării ecranului"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Nu s-au obținut permisiunile"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Eroare la începerea înregistrării ecranului"</string>
@@ -362,7 +360,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Utilizator nou"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Internet"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Sigur pentru avion"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Sunt disponibile rețele"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Nu sunt disponibile rețele"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Neconectată"</string>
@@ -417,7 +414,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Până la răsărit"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Activată la <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Până la <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Reduceți luminozitatea"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"Serviciul NFC este dezactivat"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"Serviciul NFC este activat"</string>
@@ -472,7 +468,6 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Afișați profilul"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Adăugați un utilizator"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Utilizator nou"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Încheiați sesiunea pentru invitați"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Ștergeți invitatul?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Toate aplicațiile și datele din această sesiune vor fi șterse."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Ștergeți"</string>
@@ -522,6 +517,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Dispozitivul este gestionat de unul dintre părinți"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Organizația dvs. deține acest dispozitiv și poate monitoriza traficul de rețea"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> deține acest dispozitiv și poate monitoriza traficul din rețea"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Acest dispozitiv este oferit de <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Dispozitivul aparține organizației dvs. și este conectat la <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Dispozitivul aparține organizației <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> și este conectat la <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Dispozitivul aparține organizației dvs."</string>
@@ -535,6 +531,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Profilul dvs. de serviciu este conectat la <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Profilul dvs. personal este conectat la <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Dispozitivul este conectat la <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Acest dispozitiv este oferit de <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Gestionarea dispozitivului"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Monitorizarea profilului"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Monitorizarea rețelei"</string>
@@ -546,6 +543,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Afișați politicile"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Vedeți opțiunile"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Dispozitivul aparține organizației <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nAdministratorul dvs. IT poate să monitorizeze și să gestioneze setările, accesul la nivelul companiei, aplicațiile, datele asociate dispozitivului și informațiile despre locația dispozitivului.\n\nPentru mai multe informații, contactați administratorul IT."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"Este posibil ca <xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> să acceseze date asociate dispozitivului, să gestioneze aplicații și să modifice setările acestuia.\n\nDacă aveți întrebări, luați legătura cu <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Dispozitivul aparține organizației dvs.\n\nAdministratorul dvs. IT poate să monitorizeze și să gestioneze setările, accesul la nivelul companiei, aplicațiile, datele asociate dispozitivului și informațiile despre locația dispozitivului.\n\nPentru mai multe informații, contactați administratorul IT."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Organizația dvs. a instalat un certificat CA pe acest dispozitiv. Traficul dvs. sigur de rețea poate fi monitorizat sau modificat."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Organizația dvs. a instalat un certificat CA în profilul dvs. de serviciu. Traficul dvs. sigur de rețea poate fi monitorizat sau modificat."</string>
@@ -656,6 +654,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Afișați modul demonstrativ"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Alarmă"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Gata"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Profil de serviciu"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Mod Avion"</string>
     <string name="add_tile" msgid="6239678623873086686">"Adăugați o casetă"</string>
@@ -904,11 +904,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Închideți setările rapide."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Alarmă setată."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Conectat(ă) ca <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"alege utilizatorul"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Fără conexiune la internet"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Deschideți detaliile."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"Indisponibile deoarece <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Deschideți setările <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Editați ordinea setărilor."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Meniul de pornire"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Pagina <xliff:g id="ID_1">%1$d</xliff:g> din <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Ecran de blocare"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"Telefonul s-a oprit din cauza încălzirii"</string>
@@ -1016,9 +1018,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Deplasați spre stânga"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Deplasați spre dreapta"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Comutator de mărire"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Măriți întregul ecran"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Măriți tot ecranul"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Măriți o parte a ecranului"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Comutator"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"Butonul de accesibilitate a înlocuit gestul de accesibilitate\n\n"<annotation id="link">"Vedeți setările"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Mutați butonul spre margine pentru a-l ascunde temporar"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Comenzile dispozitivelor"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Adăugați comenzi pentru dispozitivele conectate"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Configurați comenzile dispozitivelor"</string>
@@ -1087,6 +1091,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Asociați un nou dispozitiv"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Widgeturi pentru conversație"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Atingeți o conversație ca să o adăugați pe ecranul de pornire"</string>
+    <string name="timestamp" msgid="6577851592534538533">"Acum <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"În urmă cu mai puțin de <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"În urmă cu peste <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Ziua de naștere"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Zi de naștere în curând"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Zi aniversară"</string>
+    <string name="location_status" msgid="1294990572202541812">"Se afișează locația"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Subiect nou"</string>
+    <string name="video_status" msgid="4548544654316843225">"Urmăresc"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Se ascultă"</string>
+    <string name="game_status" msgid="1340694320630973259">"Se redă"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Prieteni"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Conversăm prin chat diseară?"</string>
+    <string name="missed_call" msgid="4228016077700161689">"Apel nepreluat"</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="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problemă la citirea măsurării bateriei"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Atingeți pentru mai multe informații"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nicio alarmă setată"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index f064e4f..2fb31e7 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Отмена"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Поделиться"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Запись видео с экрана отменена"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Запись видео с экрана сохранена"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Нажмите, чтобы посмотреть."</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Не удалось удалить запись видео с экрана"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Не удалось получить необходимые разрешения"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Не удалось начать запись видео с экрана."</string>
@@ -363,7 +361,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Новый пользователь"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Интернет"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Безопасные в самолете"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Сети доступны"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Сети недоступны"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Нет соединения"</string>
@@ -419,7 +416,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"До рассвета"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Включить в <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"До <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Уменьшение яркости"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"Модуль NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"Модуль NFC отключен"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"Модуль NFC включен"</string>
@@ -474,7 +470,6 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Показать профиль."</string>
     <string name="user_add_user" msgid="4336657383006913022">"Добавить пользователя"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Новый пользователь"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Завершить гостевой сеанс"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Удалить аккаунт гостя?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Все приложения и данные этого профиля будут удалены."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Удалить"</string>
@@ -525,6 +520,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Устройством управляет один из родителей."</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Ваша организация управляет этим устройством и может отслеживать сетевой трафик"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Организация \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\" управляет этим устройством и может отслеживать сетевой трафик"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Устройство предоставлено компанией \"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>\"."</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Это устройство принадлежит вашей организации и подключено к приложению \"<xliff:g id="VPN_APP">%1$s</xliff:g>\""</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Это устройство принадлежит организации \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\" и подключено к приложению \"<xliff:g id="VPN_APP">%2$s</xliff:g>\""</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Это устройство принадлежит вашей организации"</string>
@@ -538,6 +534,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Ваш рабочий профиль подключен к приложению \"<xliff:g id="VPN_APP">%1$s</xliff:g>\""</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Ваш личный профиль подключен к приложению \"<xliff:g id="VPN_APP">%1$s</xliff:g>\""</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Это устройство подключено к приложению \"<xliff:g id="VPN_APP">%1$s</xliff:g>\""</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Устройство предоставлено компанией \"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>\""</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Управление устройством"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Мониторинг профиля"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Отслеживание сетей"</string>
@@ -549,6 +546,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Просмотреть политику"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Показать элементы управления"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Это устройство принадлежит организации \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\".\n\nВаш системный администратор может управлять настройками, приложениями и параметрами доступа к корпоративным ресурсам на этом устройстве, а также связанными с ним данными (например, сведениями о местоположении).\n\nЗа подробной информацией обращайтесь к системному администратору."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"\"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g>\" может получать доступ к данным, связанным с этим устройством, изменять его настройки и управлять приложениями.\n\nЕсли у вас есть вопросы, свяжитесь с организацией \"<xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>\"."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Это устройство принадлежит вашей организации.\n\nСистемный администратор может управлять настройками, приложениями и параметрами доступа к корпоративным ресурсам на этом устройстве, а также связанными с ним данными (например, сведениями о местоположении).\n\nЗа подробной информацией обращайтесь к системному администратору."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Ваша организация установила сертификат ЦС на устройство. Она может отслеживать и изменять защищенный сетевой трафик."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Ваша организация установила сертификат ЦС в рабочем профиле. Она может отслеживать и изменять защищенный сетевой трафик."</string>
@@ -659,6 +657,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Перейти в демонстрационный режим"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Будильник"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Кошелек"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Готово"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Рабочий профиль"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Режим полета"</string>
     <string name="add_tile" msgid="6239678623873086686">"Добавить кнопку быстрого доступа"</string>
@@ -909,11 +909,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Скрыть быстрые настройки."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Будильник установлен."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Выполнен вход под именем <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"выбрать пользователя"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Нет подключения к Интернету."</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Показать подробности."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"Недоступно. <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Открыть настройки <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Изменить порядок быстрых настроек."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Меню кнопки питания"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Страница <xliff:g id="ID_1">%1$d</xliff:g> из <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Заблокированный экран"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"Телефон выключился из-за перегрева"</string>
@@ -1021,9 +1023,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Переместить влево"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Переместить вправо"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Переключатель режима увеличения"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Увеличить весь экран"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Увеличение всего экрана"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Увеличить часть экрана"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Переключить"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"Жест заменен на кнопку специальных возможностей\n\n"<annotation id="link">"Открыть настройки"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Чтобы временно скрыть кнопку, переместите ее к краю экрана"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Управление устройствами"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Добавьте виджеты для управления устройствами."</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Настройте виджеты управления устройствами"</string>
@@ -1093,6 +1097,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Подключить новое устройство"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Виджеты чатов"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Нажмите на чат, чтобы добавить его на главный экран"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> назад"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"Прошло не более чем <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"Прошло более чем <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"День рождения"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Скоро день рождения"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Годовщина"</string>
+    <string name="location_status" msgid="1294990572202541812">"Доступ открыт"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Новая история"</string>
+    <string name="video_status" msgid="4548544654316843225">"Просмотр"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Прослушивание аудио"</string>
+    <string name="game_status" msgid="1340694320630973259">"Игра запущена"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Друзья"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Давайте поболтаем!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"Пропущенный вызов"</string>
+    <string name="people_tile_description" msgid="8154966188085545556">"Просматривайте недавние сообщения, пропущенные звонки и обновления статуса."</string>
+    <string name="people_tile_title" msgid="6589377493334871272">"Чат"</string>
     <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Не удается получить данные об уровне заряда батареи"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Нажмите, чтобы узнать больше."</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Будильников нет"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 5a1f599..3e393bf 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"අවලංගු කරන්න"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"බෙදා ගන්න"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"තිර පටිගත කිරීම අවලංගු කරන ලදී"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"තිර පටිගත කිරීම සුරකින ලදී"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"බැලීමට තට්ටු කරන්න"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"තිර පටිගත කිරීම මැකීමේ දෝෂයකි"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"අවසර ලබා ගැනීමට අසමත් විය"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"තිර පටිගත කිරීම ආරම්භ කිරීමේ දෝෂයකි"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"නව පරිශීලකයා"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"අන්තර්ජාලය"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"ගුවන් යානා-ආරක්ෂිත"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"ජාල තිබේ"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"ජාල නොමැත"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"සම්බන්ධ වී නොමැත"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"හිරු නගින තෙක්"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g>ට ක්‍රියාත්මකයි"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> තෙක්"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"දීප්තිය අඩු කරන්න"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC අබලයි"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC සබලයි"</string>
@@ -470,7 +466,6 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"පැතිකඩ පෙන්වන්න"</string>
     <string name="user_add_user" msgid="4336657383006913022">"පරිශීලකයෙක් එක් කරන්න"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"නව පරිශීලකයා"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"ආරාධිත සැසිය අවසන් කරන්න"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"අමුත්තාන් ඉවත් කරන්නද?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"මෙම සැසියේ සියළුම යෙදුම් සහ දත්ත මකාවී."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"ඉවත් කරන්න"</string>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"මෙම උපාංගය ඔබගේ මාපියන්ගෙන් අයකු විසින් කළමනාකරණය කෙරේ"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ඔබේ සංවිධානයට මෙම උපාංගය අයිති අතර ජාල තදබදය නිරීක්ෂණය කළ හැකිය"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> සංවිධානයට මෙම උපාංගය අයිති අතර ජාල තදබදය නිරීක්ෂණය කළ හැකිය"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"මෙම උපාංගය <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> මගින් සැපයේ"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"මෙම උපාංගය ඔබේ සංවිධානයට අයිති අතර <xliff:g id="VPN_APP">%1$s</xliff:g> වෙත සම්බන්ධ කර ඇත"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"මෙම උපාංගය <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> සංවිධානයට අයිති අතර <xliff:g id="VPN_APP">%2$s</xliff:g> වෙත සම්බන්ධ කර ඇත"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"මෙම උපාංගය ඔබේ සංවිධානයට අයිතිය"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"ඔබේ කාර්යාල පැතිකඩ <xliff:g id="VPN_APP">%1$s</xliff:g> වෙත සම්බන්ධ කර ඇත"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"ඔබේ පෞද්ගලික පැතිකඩ <xliff:g id="VPN_APP">%1$s</xliff:g> වෙත සම්බන්ධ කර ඇත"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"මෙම උපාංගය <xliff:g id="VPN_APP">%1$s</xliff:g> වෙත සම්බන්ධ කර ඇත"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"මෙම උපාංගය <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> මගින් සැපයේ"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"උපාංග කළමනාකරණය"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"පැතිකඩ නිරීක්ෂණය කිරීම"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"ජාල නිරීක්ෂණය"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"ප්‍රතිපත්ති පෙන්වන්න"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"පාලන බලන්න"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"මෙම උපාංගය <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> සංවිධානයට අයිතිය.\n\nඔබේ IT පරිපාලකට ඔබේ උපාංගය හා සම්බන්ධිත සැකසීම්, ආයතනික ප්‍රවේශය, යෙදුම්, දත්ත සහ ඔබේ උපාංගයේ ස්ථාන තොරතුරු නිරීක්ෂණය කර කළමනාකරණය කිරීමට හැකිය.\n\nවැඩිදුර තොරතුරු සඳහා, ඔබේ IT අමතන්න."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> හට මෙම උපාංගය හා සම්බන්ධ දත්ත වෙත ප්‍රවේශ වීමට, යෙදුම් කළමනාකරණය කිරීමට සහ මෙම උපාංග සැකසීම් වෙනස් කිරීමට හැකිය.\n\nඔබට ප්‍රශ්න තිබේ නම්, <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g> සම්බන්ධ කර ගන්න."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"මෙම උපාංගය ඔබේ සංවිධානයට අයිතිය.\n\nඔබේ IT පරිපාලකට ඔබේ උපාංගය හා සම්බන්ධිත සැකසීම්, ආයතනික ප්‍රවේශය, යෙදුම්, දත්ත සහ ඔබේ උපාංගයේ ස්ථාන තොරතුරු නිරීක්ෂණය කර කළමනාකරණය කිරීමට හැකිය.\n\nවැඩිදුර තොරතුරු සඳහා, ඔබේ IT අමතන්න."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"ඔබගේ සංවිධානය ඔබගේ උපාංගය තුළ සහතික අධිකාරියක් ස්ථාපනය කර තිබේ. ඔබගේ ආරක්ෂක ජාල තදබදය නිරීක්ෂණය හෝ වෙනස් කිරීමට පුළුවනි."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"ඔබගේ සංවිධානය ඔබගේ කාර්යාල පැතිකඩ තුළ සහතික අධිකාරියක් ස්ථාපනය කර තිබේ. ඔබගේ ආරක්ෂක ජාල තදබදය නිරීක්ෂණය හෝ වෙනස් කිරීමට පුළුවනි."</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"ආදර්ශන ප්‍රකාරය පෙන්වන්න"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"එලාමය"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"පසුම්බිය"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"සූදානම්"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"කාර්යාල පැතිකඩ"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"ගුවන්යානා ප්‍රකාරය"</string>
     <string name="add_tile" msgid="6239678623873086686">"ටයිල් එක් කරන්න"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"ඉක්මන් සැකසීම් වසන්න."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"එලාමය සකසන ලදී."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"<xliff:g id="ID_1">%s</xliff:g> ලෙස පුරන්න"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"පරිශීලක තෝරන්න"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"අන්තර්ජාලය නැත"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"විස්තර විවෘත කරන්න."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"<xliff:g id="REASON">%s</xliff:g> හේතුවෙන් ලබා ගත නොහැකිය"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> සැකසීම් විවෘත කරන්න."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"සැකසීම්වල අනුපිළිවෙළ සංංස්කරණය කරන්න."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"බල මෙනුව"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g> න් <xliff:g id="ID_1">%1$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"අගුලු තිරය"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"දුරකථනය රත් වීම නිසා ක්‍රියාවිරහිත කරන ලදී"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"වමට ගෙන යන්න"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"දකුණට ගෙන යන්න"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"විශාලන ස්විචය"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"සම්පූර්ණ තිරය විශාලනය කරන්න"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"පූර්ණ තිරය විශාලනය කරන්න"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"තිරයේ කොටසක් විශාලනය කරන්න"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"ස්විචය"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"ප්‍රවේශ්‍යතා බොත්තම ප්‍රවේශ්‍යතා ඉංගිතය ප්‍රතිස්ථාපනය කළේය\n\n"<annotation id="link">"සැකසීම් බලන්න"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"එය තාවකාලිකව සැඟවීමට බොත්තම දාරයට ගෙන යන්න"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"උපාංග පාලන"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"ඔබේ සම්බන්ධිත උපාංග සඳහා පාලන එක් කරන්න"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"උපාංග පාලන පිහිටුවන්න"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"නව උපාංගය යුගල කරන්න"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"සංවාද විජට්"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"ඔබගේ මුල් තිරයට එය එක් කිරීමට සංවාදයක් තට්ටු කරන්න"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g>කට පෙර"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"<xliff:g id="DURATION">%1$s</xliff:g>කට වඩා අඩු කාලයකට පෙර"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"<xliff:g id="DURATION">%1$s</xliff:g>කට වඩා පෙර"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"උපන් දිනය"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"උපන් දිනය ඉක්මනින්"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"සංවත්සරය"</string>
+    <string name="location_status" msgid="1294990572202541812">"ස්ථානය බෙදා ගැනීම"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"අලුත් කතාව"</string>
+    <string name="video_status" msgid="4548544654316843225">"නරඹමින්"</string>
+    <string name="audio_status" msgid="4237055636967709208">"සවන් දෙමින්"</string>
+    <string name="game_status" msgid="1340694320630973259">"ක්‍රීඩා කරමින්"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"මිතුරන්"</string>
+    <string name="empty_status" msgid="5938893404951307749">"අද රෑ කතාබහ කරමු!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"මඟ හැරුණු ඇමතුම"</string>
+    <string name="people_tile_description" msgid="8154966188085545556">"මෑත පණිවිඩ, මඟ හැරුණු ඇමතුම් සහ තත්ත්ව යාවත්කාලීන කිරීම් බලන්න"</string>
+    <string name="people_tile_title" msgid="6589377493334871272">"සංවාදය"</string>
     <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"ඔබගේ බැටරි මනුව කියවීමේ දෝෂයකි"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"තවත් තොරතුරු සඳහා තට්ටු කරන්න"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"එලාම සකසා නැත"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index eba75e3..bbca0db 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Zrušiť"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Zdieľať"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Záznam obrazovky bol zrušený"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Nahrávka obrazovky bola uložená"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Zobrazte klepnutím"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Pri odstraňovaní záznamu obrazovky sa vyskytla chyba"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Nepodarilo sa získať povolenia"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Pri spustení nahrávania obrazovky sa vyskytla chyba"</string>
@@ -363,7 +361,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Nový používateľ"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi‑Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Internet"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Bezpečné v lietadle"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Siete sú k dispozícii"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Siete nie sú k dispozícii"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Nepripojené"</string>
@@ -419,7 +416,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Do východu slnka"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Zapne sa o <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Do <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Zníženie jasu"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC je deaktivované"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC je aktivované"</string>
@@ -474,7 +470,6 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Zobraziť profil"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Pridať používateľa"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Nový používateľ"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Ukončiť reláciu hosťa"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Odstrániť hosťa?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Všetky aplikácie a údaje v tejto relácii budú odstránené."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Odstrániť"</string>
@@ -525,6 +520,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Toto zariadenie spravuje tvoj rodič"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Vaša organizácia spravuje toto zariadenie a môže sledovať sieťovú premávku"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> vlastní toto zariadenie a môže sledovať sieťovú premávku"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Toto zariadenie poskytla organizácia <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Toto zariadenie patrí vašej organizácii a je pripojené k sieti <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Toto zariadenie patrí organizácii <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> a je pripojené k sieti <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Toto zariadenie patrí vašej organizácii"</string>
@@ -538,6 +534,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Váš pracovný profil je pripojený k sieti <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Váš osobný profil je pripojený k sieti <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Toto zariadenie je pripojené k sieti <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Toto zariadenie poskytla organizácia <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Správa zariadení"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Monitorovanie profilu"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Sledovanie siete"</string>
@@ -549,6 +546,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Zobraziť pravidlá"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Zobraziť ovládacie prvky"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Toto zariadenie patrí organizácii <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nVáš správca IT môže sledovať a spravovať nastavenia, podnikový prístup, aplikácie, údaje spojené s vaším zariadení a informácie o jeho polohe.\n\nViac sa dozviete od správcu IT."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> môže mať prístup k údajom spojeným s týmto zariadením, spravovať aplikácie a meniť jeho nastavenia.\n\nV prípade otázok kontaktujte organizáciu <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Toto zariadenie patrí vašej organizácii.\n\nVáš správca IT môže sledovať a spravovať nastavenia, podnikový prístup, aplikácie, údaje spojené s vaším zariadením a informácie o jeho polohe.\n\n. Viac sa dozviete od správcu IT."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Organizácia nainštalovala pre toto zariadenie certifikačnú autoritu. Zabezpečená sieťová premávka môže byť sledovaná či upravená."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Organizácia nainštalovala pre váš pracovný profil certifikačnú autoritu. Zabezpečená sieťová premávka môže byť sledovaná či upravená."</string>
@@ -659,6 +657,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Zobraziť režim ukážky"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Budík"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Peňaženka"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Pripravené"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Pracovný profil"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Režim v lietadle"</string>
     <string name="add_tile" msgid="6239678623873086686">"Pridať dlaždicu"</string>
@@ -909,11 +909,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Zavrieť rýchle nastavenia"</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Budík bol nastavený."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Prihlásený používateľ <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"vybrať používateľa"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Žiadny internet"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Otvoriť podrobnosti"</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"Nedostupné z nasledujúceho dôvodu: <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Otvoriť nastavenia <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Upraviť poradie nastavení"</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Ponuka vypínača"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Strana <xliff:g id="ID_1">%1$d</xliff:g> z <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Uzamknutá obrazovka"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"Telefón sa vypol z dôvodu prehriatia"</string>
@@ -1021,9 +1023,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Posunúť doľava"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Posunúť doprava"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Prepínač zväčenia"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Zväčšiť celú obrazovku"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Zväčšenie celej obrazovky"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Zväčšiť časť obrazovky"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Prepnúť"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"Tlačidlo dostupnosti nahradilo gesto dostupnosti\n\n"<annotation id="link">"Zobraziť nastavenia"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Ak chcete tlačidlo dočasne skryť, presuňte ho k okraju"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Ovládanie zariadení"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Pridajte si ovládače pripojených zariadení"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Nastavenie ovládania zariadení"</string>
@@ -1093,6 +1097,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Spárovať nové zariadenie"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Miniaplikácie konverzácií"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Klepnite na konverzáciu a pridajte ju tak na plochu"</string>
+    <string name="timestamp" msgid="6577851592534538533">"Pred <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"Pred menej ako <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"Pred viac ako <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Narodeniny"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Blížia sa narodeniny"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Výročie"</string>
+    <string name="location_status" msgid="1294990572202541812">"Zdieľa sa poloha"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Nová správa"</string>
+    <string name="video_status" msgid="4548544654316843225">"Pozerá sa video"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Počúvam"</string>
+    <string name="game_status" msgid="1340694320630973259">"Hrá sa hra"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Priatelia"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Porozprávajme sa."</string>
+    <string name="missed_call" msgid="4228016077700161689">"Zmeškaný hovor"</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="battery_state_unknown_notification_title" msgid="8464703640483773454">"Pri čítaní meradla batérie sa vyskytol problém"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Klepnutím si zobrazíte ďalšie informácie"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Žiadny budík"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 7bf496a..def787f 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Prekliči"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Deli"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Snemanje zaslona je preklicano"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Snemanje zaslona je shranjeno."</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Dotaknite se za ogled."</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Napaka pri brisanju videoposnetka zaslona"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Dovoljenj ni bilo mogoče pridobiti"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Napaka pri začenjanju snemanja zaslona"</string>
@@ -363,7 +361,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Nov uporabnik"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Internet"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Varna uporaba v letalu"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Omrežja so na voljo"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Omrežja niso na voljo"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Povezava ni vzpostavljena"</string>
@@ -419,7 +416,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Do sončnega vzhoda"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Vklop ob <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Do <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Zmanjšanje svetlosti"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"Tehnologija NFC je onemogočena"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"Tehnologija NFC je omogočena"</string>
@@ -474,7 +470,6 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Prikaz profila"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Dodajanje uporabnika"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Nov uporabnik"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Končaj sejo gosta"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Želite odstraniti gosta?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Vse aplikacije in podatki v tej seji bodo izbrisani."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Odstrani"</string>
@@ -525,6 +520,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"To napravo upravlja tvoj starš"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Vaša organizacija je lastnica te naprave in lahko nadzira omrežni promet"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Organizacija <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> je lastnica te naprave in lahko nadzira omrežni promet"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"To napravo zagotavlja <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>."</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Ta naprava pripada vaši organizaciji in je povezana v aplikacijo <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Ta naprava pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> in je povezana v aplikacijo <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Ta naprava pripada vaši organizaciji"</string>
@@ -538,6 +534,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Delovni profil je povezan v aplikacijo <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Osebni profil je povezan v aplikacijo <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Ta naprava je povezava v aplikacijo <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"To napravo zagotavlja <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>."</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Upravljanje naprav"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Nadzor nad profilom"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Nadzor omrežja"</string>
@@ -549,6 +546,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Prikaži pravilnike"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Ogled kontrolnikov"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Ta naprava pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nSkrbnik za IT lahko nadzira in upravlja nastavitve, dostop za podjetje, aplikacije, z napravo povezane podatke in podatke o lokaciji naprave.\n\nZa več informacij se obrnite na skrbnika za IT."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"Organizacija <xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> morda lahko dostopa do podatkov, povezanih s to napravo, upravlja aplikacije in spreminja nastavitve naprave.\n\nČe imate vprašanja, se obrnite na organizacijo <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Ta naprava pripada vaši organizaciji.\n\nSkrbnik za IT lahko nadzira in upravlja nastavitve, dostop za podjetje, aplikacije, z napravo povezane podatke in podatke o lokaciji naprave.\n\nZa več informacij se obrnite na skrbnika za IT."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Vaša organizacija je v to napravo namestila overitelja potrdil. Varni omrežni promet se lahko nadzira ali spreminja."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Vaša organizacija je v vaš delovni profil namestila overitelja potrdil. Varni omrežni promet se lahko nadzira ali spreminja."</string>
@@ -659,6 +657,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Prikaz predstavitvenega načina"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Opozorilo"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Denarnica"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Pripravljeno"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Profil za Android Work"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Način za letalo"</string>
     <string name="add_tile" msgid="6239678623873086686">"Dodajanje ploščice"</string>
@@ -909,11 +909,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Zapri hitre nastavitve."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Alarm je nastavljen."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Prijavljeni ste kot <xliff:g id="ID_1">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"izbiro uporabnika"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Brez internetne povezave"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Odpri podrobnosti."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"Ni na voljo zaradi tega razloga: <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Odpri nastavitve za <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Uredi vrstni red nastavitev."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Meni za vklop/izklop"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_1">%1$d</xliff:g>. stran od <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Zaklenjen zaslon"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"Tel. izklopljen zaradi vročine"</string>
@@ -1021,9 +1023,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Premakni levo"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Premakni desno"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Stikalo za povečavo"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Povečava celotnega zaslona"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Povečanje celotnega zaslona"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Povečava dela zaslona"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Stikalo"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"Gumb za funkcije za ljudi s posebnimi potrebami je zamenjal pripadajočo potezo.\n\n"<annotation id="link">"Ogled nastavitev"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Če želite gumb začasno skriti, ga premaknite ob rob."</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Kontrolniki naprave"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Dodajte kontrolnike za povezane naprave"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Nastavitev kontrolnikov naprave"</string>
@@ -1093,6 +1097,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Seznanitev nove naprave"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Pripomočki za pogovore"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Dotaknite se pogovora, da ga dodate na začetni zaslon."</string>
+    <string name="timestamp" msgid="6577851592534538533">"pred <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"Pred manj kot <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"Pred več kot <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Rojstni dan"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Rojstni dan se bliža"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Obletnica"</string>
+    <string name="location_status" msgid="1294990572202541812">"Deljenje lokacije"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Nova zgodba"</string>
+    <string name="video_status" msgid="4548544654316843225">"Gledanje"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Poslušanje"</string>
+    <string name="game_status" msgid="1340694320630973259">"Igranje"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Prijatelji"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Naj se klepet začne!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"Neodgovorjeni klic"</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="battery_state_unknown_notification_title" msgid="8464703640483773454">"Težava z branjem indikatorja stanja napolnjenosti baterije"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Dotaknite se za več informacij"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Ni nastavljenih alarmov"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index ac22fea..9e676c4 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Anulo"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Ndaj"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Regjistrimi i ekranit u anulua"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Regjistrimi i ekranit u ruajt"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Trokit për të parë"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Gabim gjatë fshirjes së regjistrimit të ekranit"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Marrja e lejeve dështoi"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Gabim gjatë nisjes së regjistrimit të ekranit"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Përdorues i ri"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Internet"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Të sigurta për në aeroplan"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Ofrohen rrjete"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Rrjetet nuk ofrohen"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Nuk është i lidhur"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Deri në lindje të diellit"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Aktiv në <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Deri në <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Redukto ndriçimin"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC është çaktivizuar"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC është aktivizuar"</string>
@@ -470,7 +466,6 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Shfaq profilin"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Shto përdorues"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Përdorues i ri"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Jepi fund sesionit të vizitorit"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Të hiqet i ftuari?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Të gjitha aplikacionet dhe të dhënat në këtë sesion do të fshihen."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Hiq"</string>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Kjo pajisje menaxhohet nga prindi yt"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Organizata jote e zotëron këtë pajisje dhe mund të monitorojë trafikun e rrjetit"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> e zotëron këtë pajisje dhe mund të monitorojë trafikun e rrjetit"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Kjo pajisje ofrohet nga <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Kjo pajisje i përket organizatës sate dhe është e lidhur me <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Kjo pajisje i përket <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> dhe është e lidhur me <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Kjo pajisje i përket organizatës sate"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Profili yt i punës është i lidhur me <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Profili yt personal është i lidhur me <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Kjo pajisje është e lidhur me <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Kjo pajisje ofrohet nga <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Menaxhimi i pajisjes"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Monitorimi i profilit"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Monitorimi i rrjetit"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Shiko politikat"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Shiko kontrollet"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Kjo pajisje i përket <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nAdministratori i teknologjisë së informacionit mund të monitorojë dhe menaxhojë cilësimet, qasjen e korporatës, aplikacionet, të dhënat e lidhura me pajisjen tënde, si dhe informacionet e vendndodhjes së pajisjes tënde.\n\nPër më shumë informacione, kontakto me administratorin e teknologjisë së informacionit."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> mund të arrijë të qaset te të dhënat e lidhura me këtë pajisje, të menaxhojë aplikacionet dhe të ndryshojë cilësimet e kësaj pajisjeje.\n\nNëse ke pyetje, kontakto me <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Kjo pajisje i përket organizatës sate.\n\nAdministratori i teknologjisë së informacionit mund të monitorojë dhe menaxhojë cilësimet, qasjen e korporatës, aplikacionet, të dhënat e lidhura me pajisjen tënde, si dhe informacionet e vendndodhjes së pajisjes tënde.\n\nPër më shumë informacione, kontakto me administratorin e teknologjisë së informacionit."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Organizata jote instaloi një autoritet certifikate në këtë pajisje. Trafiku i rrjetit tënd të sigurt mund të monitorohet ose modifikohet."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Organizata jote instaloi një autoritet certifikate në profilin tënd të punës. Trafiku i rrjetit tënd të sigurt mund të monitorohet ose modifikohet."</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Shfaq modalitetin e demonstrimit"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Eternet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Alarmi"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Gati"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Profili i punës"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Modaliteti i aeroplanit"</string>
     <string name="add_tile" msgid="6239678623873086686">"Shto një pllakëz"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Mbyll cilësimet e shpejta."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Alarmi u vendos."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Identifikuar si <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"zgjidh përdoruesin"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Nuk ka internet"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Hap detajet."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"Nuk ofrohet për shkak se <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Hap cilësimet e <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Modifiko rendin e cilësimeve."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menyja e energjisë"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Faqja <xliff:g id="ID_1">%1$d</xliff:g> nga <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Ekrani i kyçjes"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"Telefoni u fik për shkak të nxehtësisë"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Lëvize majtas"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Lëvize djathtas"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Ndërrimi i zmadhimit"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Zmadho të gjithë ekranin"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Zmadho ekranin e plotë"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Zmadho një pjesë të ekranit"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Ndërro"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"Butoni i qasshmërisë është zëvendësuar me gjestin e qasshmërisë\n\n"<annotation id="link">"Shiko cilësimet"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Zhvendose butonin në skaj për ta fshehur përkohësisht"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Kontrollet e pajisjes"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Shto kontrolle për pajisjet e tua të lidhura"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Konfiguro kontrollet e pajisjes"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Çifto pajisjen e re"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Miniaplikacionet e bisedave"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Trokit te një bisedë dhe shtoje në ekranin bazë"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> më parë"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"Më pak se <xliff:g id="DURATION">%1$s</xliff:g> më parë"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"Mbi <xliff:g id="DURATION">%1$s</xliff:g> më parë"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Ditëlindja"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Ditëlindje së shpejti"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Përvjetor"</string>
+    <string name="location_status" msgid="1294990572202541812">"Ndarja e vendndodhjes"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Histori e re"</string>
+    <string name="video_status" msgid="4548544654316843225">"Po shikon"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Po dëgjon"</string>
+    <string name="game_status" msgid="1340694320630973259">"Po luhet"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Miq"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Le të bisedojmë sonte!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"Telefonatë e humbur"</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="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problem me leximin e matësit të baterisë"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Trokit për më shumë informacione"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nuk është caktuar asnjë alarm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index bcfcf30..5fcb9c79 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Откажи"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Дели"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Снимање екрана је отказано"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Снимак екрана је сачуван"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Додирните да бисте прегледали"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Дошло је до проблема при брисању снимка екрана"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Преузимање дозвола није успело"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Грешка при покретању снимања екрана"</string>
@@ -362,7 +360,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Нови корисник"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"WiFi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Интернет"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Безбедно за авион"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Мреже су доступне"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Мреже нису доступне"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Веза није успостављена"</string>
@@ -417,7 +414,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"До изласка сунца"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Укључује се у <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"До <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Смањите осветљеност"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC је онемогућен"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC је омогућен"</string>
@@ -472,7 +468,6 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Прикажи профил"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Додај корисника"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Нови корисник"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Заврши сесију госта"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Желите ли да уклоните госта?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Све апликације и подаци у овој сесији ће бити избрисани."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Уклони"</string>
@@ -522,6 +517,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Овим уређајем управља родитељ"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Организација је власник уређаја и може да надгледа мрежни саобраћај"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> је власник овог уређаја и може да надгледа мрежни саобраћај"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Овај уређај пружа <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Овај уређај припада организацији и повезан је са апликацијом <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Овај уређај припада организацији <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> и повезан је са апликацијом <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Овај уређај припада организацији"</string>
@@ -535,6 +531,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Пословни профил је повезан са апликацијом <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Ваш лични профил је повезан са апликацијом <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Овај уређај је повезан са апликацијом <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Овај уређај пружа <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Управљање уређајима"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Надгледање профила"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Надгледање мреже"</string>
@@ -546,6 +543,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Прикажи смернице"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Прикажи контроле"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Овај уређај припада организацији <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nИТ администратор може да надгледа подешавања, корпоративни приступ, апликације, податке повезане са уређајем и информације о локацији уређаја, као и да управља њима.\n\nВише информација потражите од ИТ администратора."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> можда може да приступа подацима повезаним са овим уређајем, да управља апликацијама и да мења подешавања овог уређаја.\n\nАко имате питања, обратите се организацији <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Овај уређај припада организацији.\n\nИТ администратор може да надгледа подешавања, корпоративни приступ, апликације, податке повезане са уређајем и информације о локацији уређаја, као и да управља њима.\n\nВише информација потражите од ИТ администратора."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Организација је на овом уређају инсталирала ауторитет за издавање сертификата. Безбедни мрежни саобраћај може да се прати или мења."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Организација је на пословном профилу инсталирала ауторитет за издавање сертификата. Безбедни мрежни саобраћај може да се прати или мења."</string>
@@ -656,6 +654,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Прикажи режим демонстрације"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Етернет"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Аларм"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Новчаник"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Спремно"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Пословни профил"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Режим рада у авиону"</string>
     <string name="add_tile" msgid="6239678623873086686">"Додај плочицу"</string>
@@ -904,11 +904,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Затвори Брза подешавања."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Аларм је подешен."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Пријављени сте као <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"одабрали корисника"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Нема интернета"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Отвори детаље."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"Није доступно из следећег разлога: <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Отвори подешавања за <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Измени редослед подешавања."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Мени дугмета за укључивање"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_1">%1$d</xliff:g>. страна од <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Закључан екран"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"Телефон се искључио због топлоте"</string>
@@ -1016,9 +1018,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Померите налево"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Померите надесно"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Прелазак на други режим увећања"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Увећајте цео екран"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Увећајте цео екран"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Увећајте део екрана"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Пређи"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"Дугме Приступачност је заменило покрет за приступачност\n\n"<annotation id="link">"Прикажи подешавања"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Померите дугме до ивице да бисте га привремено сакрили"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Контроле уређаја"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Додајте контроле за повезане уређаје"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Подесите контроле уређаја"</string>
@@ -1087,6 +1091,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Упари нови уређај"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Виџети за конверзацију"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Додирните конверзацију да бисте је додали на почетни екран"</string>
+    <string name="timestamp" msgid="6577851592534538533">"Пре <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"Пре мање од <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"Пре више од <xliff:g id="DURATION">%1$s</xliff:g>"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Рођендан"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Рођендан је ускоро"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Годишњица"</string>
+    <string name="location_status" msgid="1294990572202541812">"Дели се локација"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Нова прича"</string>
+    <string name="video_status" msgid="4548544654316843225">"Гледа се"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Слуша се"</string>
+    <string name="game_status" msgid="1340694320630973259">"Игра се"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Пријатељи"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Ћаскамо вечерас!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"Пропуштен позив"</string>
+    <string name="people_tile_description" msgid="8154966188085545556">"Погледајте недавне поруке, пропуштене позиве и ажурирања статуса"</string>
+    <string name="people_tile_title" msgid="6589377493334871272">"Конверзација"</string>
     <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Проблем са очитавањем мерача батерије"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Додирните за више информација"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Аларм није подешен"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index f1f9f20..52d459b 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Avbryt"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Dela"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Skärminspelningen har avbrutits"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Skärminspelningen har sparats"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Tryck för att visa"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Det gick inte att radera skärminspelningen"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Behörighet saknas"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Det gick inte att starta skärminspelningen"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Ny användare"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Internet"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Flygplanssäker"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Nätverk är tillgängliga"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Inga nätverk är tillgängliga"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Ej ansluten"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Till soluppgången"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Aktivera kl. <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Till <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Minska ljusstyrkan"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC är inaktiverat"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC är aktiverat"</string>
@@ -470,11 +466,10 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Visa profil"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Lägg till användare"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Ny användare"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Avsluta gästsession"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Vill du ta bort gästen?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alla appar och data i denna session kommer att raderas."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Ta bort"</string>
-    <string name="guest_wipe_session_title" msgid="7147965814683990944">"Välkommen tillbaka gäst!"</string>
+    <string name="guest_wipe_session_title" msgid="7147965814683990944">"Välkommen tillbaka som gäst!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Vill du fortsätta sessionen?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Börja om"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ja, fortsätt"</string>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Den här enheten hanteras av din förälder"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Organisationen äger den här enheten och kan övervaka nätverkstrafiken"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> äger den här enheten och kan övervaka nätverkstrafiken"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Den här enheten tillhandahålls av <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Den här enheten tillhör organisationen och är ansluten till <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Den här enheten tillhör <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> och är ansluten till <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Den här enheten tillhör organisationen"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Jobbprofilen är ansluten till <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Din personliga profil är ansluten till <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Den här enheten är ansluten till <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Den här enheten tillhandahålls av <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Enhetshantering"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Profilövervakning"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Nätverksövervakning"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Visa policyer"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Visa kontroller"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Den här enheten tillhör <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nIT-administratören kan övervaka och hantera inställningar, företagsåtkomst, appar, data med koppling till enheten och enhetens plats.\n\nKontakta IT-administratören om du vill veta mer."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> kanske kan komma åt data kopplad till den här enheten, hantera appar och ändra enhetens inställningar.\n\nKontakta <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g> om du har frågor."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Den här enheten tillhör organisationen.\n\nIT-administratören kan övervaka och hantera inställningar, företagsåtkomst, appar, data med koppling till enheten och enhetens plats.\n\nKontakta IT-administratören om du vill veta mer."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Organisationen har installerat en certifikatutfärdare på enheten. Din säkra nätverkstrafik kan övervakas och ändras."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Organisationen har installerat en certifikatutfärdare i jobbprofilen. Din säkra nätverkstrafik kan övervakas och ändras."</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Visa demoläge"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Alarm"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Klar"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Jobbprofil"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Flygplansläge"</string>
     <string name="add_tile" msgid="6239678623873086686">"Lägg till en ruta"</string>
@@ -721,7 +721,7 @@
     <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"&lt;b&gt;Status:&lt;/b&gt; Ändrad till Tyst"</string>
     <string name="notification_channel_summary_automatic_promoted" msgid="1301710305149590426">"&lt;b&gt;Status:&lt;/b&gt; Höjd"</string>
     <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" msgid="7952654515769021553">"Visas högst upp bland konversationerna som en flytande bubbla, visar profilbilden på låsskärmen"</string>
+    <string name="notification_channel_summary_priority" msgid="7952654515769021553">"Visas högst upp bland konversationerna som en flytande bubbla och visar profilbilden på låsskärmen"</string>
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Inställningar"</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>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Stäng snabbinställningarna"</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Alarmet aktiverat"</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Inloggad som <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"välj användare"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Inget internet"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Visa information."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"Inte tillgänglig på grund av <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Öppna <xliff:g id="ID_1">%s</xliff:g>-inställningarna."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Ändra ordning på inställningarna."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Startmeny"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Sida <xliff:g id="ID_1">%1$d</xliff:g> av <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Låsskärm"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"Mobilen stängdes av pga. värme"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Flytta åt vänster"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Flytta åt höger"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Förstoringsreglage"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Förstora hela skärmen"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Förstora hela skärmen"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Förstora en del av skärmen"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Reglage"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"Tillgänglighetsknappen har ersatt tillgänglighetsrörelsen\n\n"<annotation id="link">"Visa inställningarna"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Flytta knappen till kanten för att dölja den tillfälligt"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Enhetsstyrning"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Lägg till snabbkontroller för anslutna enheter"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Konfigurera enhetsstyrning"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Parkoppla en ny enhet"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Konversationswidgetar"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Tryck på en konversation för att lägga till den på startskärmen"</string>
+    <string name="timestamp" msgid="6577851592534538533">"För <xliff:g id="DURATION">%1$s</xliff:g> sedan"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"Mindre än <xliff:g id="DURATION">%1$s</xliff:g> sedan"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"Mer än <xliff:g id="DURATION">%1$s</xliff:g> sedan"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Födelsedag"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Födelsedag inom kort"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Högtidsdag"</string>
+    <string name="location_status" msgid="1294990572202541812">"Delar plats"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Ny artikel"</string>
+    <string name="video_status" msgid="4548544654316843225">"Tittar"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Lyssnar"</string>
+    <string name="game_status" msgid="1340694320630973259">"Spelar"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Vänner"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Vi chattar i kväll!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"Missat samtal"</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="battery_state_unknown_notification_title" msgid="8464703640483773454">"Batteriindikatorn visas inte"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tryck för mer information"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Inget inställt alarm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 5a4088e..157c576 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Ghairi"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Shiriki"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Imeghairi mchakato wa kurekodi skrini"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Imehifadhi rekodi ya skrini"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Gusa ili uangalie"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Hitilafu imetokea wakati wa kufuta rekodi ya skrini"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Imeshindwa kupata ruhusa"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Hitilafu imetokea wakati wa kuanza kurekodi skrini"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Mtumiaji mpya"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Intaneti"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Hali salama ya ndegeni"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Mitandao inapatikana"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Mitandao haipatikani"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Haijaunganishwa"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Hadi macheo"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Itawashwa saa <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Hadi saa <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Punguza ung\'aavu"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC imezimwa"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC imewashwa"</string>
@@ -470,13 +466,12 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Onyesha wasifu"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Ongeza mtumiaji"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Mtumiaji mpya"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Maliza kipindi cha mgeni"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Ungependa kumwondoa mgeni?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Data na programu zote katika kipindi hiki zitafutwa."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Ondoa"</string>
-    <string name="guest_wipe_session_title" msgid="7147965814683990944">"Karibu tena, mwalikwa!"</string>
+    <string name="guest_wipe_session_title" msgid="7147965814683990944">"Karibu tena mgeni!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Je, unataka kuendelea na kipindi chako?"</string>
-    <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Anza tena"</string>
+    <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Anza upya"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ndiyo, endelea"</string>
     <string name="guest_notification_title" msgid="4434456703930764167">"Mtumiaji mgeni"</string>
     <string name="guest_notification_text" msgid="4202692942089571351">"Ili kufuta programu na data, mwondoe mtumiaji mgeni"</string>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Kifaa hiki kinadhibitiwa na mzazi wako"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Shirika lako linamiliki kifaa hiki na huenda likafuatilia trafiki ya mtandao"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> inamiliki kifaa hiki na huenda ikafuatilia trafiki ya mtandao"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Kifaa hiki kinatolewa na <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Kifaa hiki kinamilikiwa na shirika lako na kimeunganishwa kwenye <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Kifaa hiki kinamilikiwa na <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> na kimeunganishwa kwenye <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Kifaa hiki kinamilikiwa na shirika lako"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Wasifu wako wa kazini umeunganishwa kwenye <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Wasifu wako wa binafsi umeunganishwa kwenye <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Kifaa hiki kimeunganishwa kwenye <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Kifaa hiki kinatolewa na <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Udhibiti wa kifaa"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Ufuatiliaji wasifu"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Ufuatiliaji wa mtandao"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Angalia Sera"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Angalia vidhibiti"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Kifaa hiki kinamilikiwa na <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nMsimamizi wako wa TEHAMA anaweza kufuatilia na kudhibiti mipangilio, ufikiaji wa maudhui ya shirika, programu, data inayohusiana na kifaa chako na maelezo kuhusu mahali kifaa chako kilipo.\n\nKwa maelezo zaidi, wasiliana na msimamizi wako wa TEHAMA."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> inaweza kufikia data inayohusiana na kifaa hiki, kudhibiti programu na kubadilisha mipangilio ya kifaa hiki.\n\nIkiwa una maswali yoyote, wasiliana na <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Kifaa hiki kinamilikiwa na shirika lako.\n\nMsimamizi wako wa TEHAMA anaweza kufuatilia na kudhibiti mipangilio, ufikiaji wa maudhui ya shirika, programu, data inayohusiana na kifaa chako na maelezo kuhusu mahali kifaa chako kilipo.\n\nKwa maelezo zaidi, wasiliana na msimamizi wako wa TEHAMA."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Shirika lako limesakinisha mamlaka ya cheti kwenye kifaa hiki. Huenda shughuli kwenye mtandao wako salama zikafuatiliwa au kubadilishwa."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Shirika lako limesakinisha mamlaka ya cheti katika wasifu wako wa kazini. Huenda shughuli kwenye mtandao wako salama zikafuatiliwa au kubadilishwa."</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Onyesha hali ya onyesho"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethaneti"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Kengele"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Tayari"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Wasifu wa kazini"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Hali ya ndegeni"</string>
     <string name="add_tile" msgid="6239678623873086686">"Ongeza kigae"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Funga mipangilio ya haraka."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Imeweka kengele."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Umeingia katika akaunti ya <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"chagua mtumiaji"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Hakuna intaneti"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Fungua maelezo."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"Haipatikani kutokana na <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Fungua mipangilio ya <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Badilisha orodha ya mipangilio."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menyu ya kuzima/kuwasha"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Ukurasa wa <xliff:g id="ID_1">%1$d</xliff:g> kati ya <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Skrini iliyofungwa"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"Simu ilizima kutokana na joto"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Sogeza kushoto"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Sogeza kulia"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Swichi ya ukuzaji"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Kuza skrini yote"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Kuza skrini nzima"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Kuza sehemu ya skrini"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Swichi"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"Kitufe cha zana za ufikivu kimechukua nafasi ya ishara ya ufikivu\n\n"<annotation id="link">"Angalia mipangilio"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Sogeza kitufe kwenye ukingo ili ukifiche kwa muda"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Vidhibiti vya vifaa"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Weka vidhibiti vya vifaa ulivyounganisha"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Weka mipangilio ya vidhibiti vya vifaa"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Oanisha kifaa kipya"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Wijeti za mazungumzo"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Gusa mazungumzo ili uyaweke kwenye Skrini yako ya kwanza"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> zilizopita"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"Chini ya <xliff:g id="DURATION">%1$s</xliff:g> zilizopita"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"Zaidi ya <xliff:g id="DURATION">%1$s</xliff:g> zilizopita"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Siku ya kuzaliwa"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Siku ya kuzaliwa inakaribia"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Maadhimisho"</string>
+    <string name="location_status" msgid="1294990572202541812">"Inashiriki mahali"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Habari mpya"</string>
+    <string name="video_status" msgid="4548544654316843225">"Unatazama"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Inasikiliza"</string>
+    <string name="game_status" msgid="1340694320630973259">"Inacheza"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Marafiki"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Tupige gumzo usiku!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"Simu ambayo hukujibu"</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="battery_state_unknown_notification_title" msgid="8464703640483773454">"Tatizo la kusoma mita ya betri yako"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Gusa ili upate maelezo zaidi"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Hujaweka kengele"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 5750119..fc632fd 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"ரத்துசெய்"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"பகிர்"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"திரை ரெக்கார்டிங் ரத்துசெய்யப்பட்டது"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"ஸ்கிரீன் ரெக்கார்டிங் சேமிக்கப்பட்டது"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"பார்க்கத் தட்டவும்"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"திரை ரெக்கார்டிங்கை நீக்குவதில் பிழை"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"அனுமதிகளைப் பெற இயலவில்லை"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"ஸ்கிரீன் ரெக்கார்டிங்கைத் தொடங்குவதில் பிழை"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"புதியவர்"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"வைஃபை"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"இணையம்"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"விமானப் பாதுகாப்பு நெட்வொர்க்குகள்"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"நெட்வொர்க்குகள் கிடைக்கின்றன"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"நெட்வொர்க்குகள் கிடைக்கவில்லை"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"இணைக்கப்படவில்லை"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"காலை வரை"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g>க்கு ஆன் செய்"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> வரை"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"ஒளிர்வைக் குறைத்தல்"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC முடக்கப்பட்டது"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC இயக்கப்பட்டது"</string>
@@ -470,9 +466,8 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"சுயவிவரத்தைக் காட்டு"</string>
     <string name="user_add_user" msgid="4336657383006913022">"பயனரைச் சேர்"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"புதியவர்"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"விருந்தினர் அமர்வை நிறைவுசெய்"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"கெஸ்ட்டை அகற்றவா?"</string>
-    <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"இந்த அமர்வின் எல்லா பயன்பாடுகளும், தரவும் நீக்கப்படும்."</string>
+    <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"இந்த அமர்வின் எல்லா ஆப்ஸும் தரவும் நீக்கப்படும்."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"அகற்று"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"நல்வரவு!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"உங்கள் அமர்வைத் தொடர விருப்பமா?"</string>
@@ -485,7 +480,7 @@
     <string name="user_logout_notification_text" msgid="7441286737342997991">"தற்போதைய பயனரிலிருந்து வெளியேறு"</string>
     <string name="user_logout_notification_action" msgid="7974458760719361881">"பயனரை வெளியேற்று"</string>
     <string name="user_add_user_title" msgid="4172327541504825032">"புதியவரைச் சேர்க்கவா?"</string>
-    <string name="user_add_user_message_short" msgid="2599370307878014791">"புதிய பயனரைச் சேர்க்கும்போது, அவர் தனக்கான இடத்தை அமைக்க வேண்டும்.\n\nஎந்தவொரு பயனரும், மற்ற எல்லா பயனர்களுக்காகவும் பயன்பாடுகளைப் புதுப்பிக்கலாம்."</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"புதிய பயனரைச் சேர்க்கும்போது, அவர் தனக்கான இடத்தை அமைக்க வேண்டும்.\n\nஎந்தவொரு பயனரும், மற்ற எல்லா பயனர்களுக்காகவும் ஆப்ஸைப் புதுப்பிக்கலாம்."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"பயனர் வரம்பை அடைந்துவிட்டீர்கள்"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other"><xliff:g id="COUNT">%d</xliff:g> பயனர்கள் வரை சேர்க்க முடியும்.</item>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"இந்தச் சாதனம் உங்கள் பெற்றோரால் நிர்வகிக்கப்படுகிறது"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"இந்த சாதனம் உங்கள் நிறுவனத்துக்கு உரியது, நெட்வொர்க் ட்ராஃபிக்கையும் நிறுவனமே கண்காணிக்கக்கூடும்"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"இந்த சாதனம் <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> நிறுவனத்துக்கு உரியது, நெட்வொர்க் ட்ராஃபிக்கையும் நிறுவனமே கண்காணிக்கக்கூடும்"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"இந்தச் சாதனம் <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> நிறுவனத்தால் வழங்கப்பட்டது"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"இந்த சாதனம் உங்கள் நிறுவனத்துக்கு சொந்தமானது, அது <xliff:g id="VPN_APP">%1$s</xliff:g> உடன் இணைக்கப்பட்டுள்ளது"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"இந்த சாதனம் <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> நிறுவனத்துக்கு சொந்தமானது, அது <xliff:g id="VPN_APP">%2$s</xliff:g> உடன் இணைக்கப்பட்டுள்ளது"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"இந்த சாதனம் உங்கள் நிறுவனத்துக்கு சொந்தமானது"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"உங்கள் பணிக் கணக்கு <xliff:g id="VPN_APP">%1$s</xliff:g> உடன் இணைக்கப்பட்டுள்ளது"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"உங்கள் தனிப்பட்ட சுயவிவரம் <xliff:g id="VPN_APP">%1$s</xliff:g> உடன் இணைக்கப்பட்டுள்ளது"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"இந்த சாதனம் <xliff:g id="VPN_APP">%1$s</xliff:g> உடன் இணைக்கப்பட்டுள்ளது"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"இந்தச் சாதனம் <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> நிறுவனத்தால் வழங்கப்பட்டது"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"சாதன நிர்வாகம்"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"சுயவிவரத்தைக் கண்காணித்தல்"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"நெட்வொர்க்கைக் கண்காணித்தல்"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"கொள்கைகளைக் காட்டு"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"கட்டுப்பாடுகளைக் காட்டு"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"இந்த சாதனம் <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> நிறுவனத்துக்கு சொந்தமானது.\n\nஉங்கள் IT நிர்வாகியால் அமைப்புகள், நிறுவன அணுகல், ஆப்ஸ், உங்கள் சாதனத்துடன் தொடர்புடைய தரவு, சாதனத்தின் இருப்பிடத் தகவல்கள் ஆகியவற்றைக் கண்காணிக்கவும் நிர்வகிக்கவும் முடியும்.\n\nமேலும் தகவல்களுக்கு IT நிர்வாகியைத் தொடர்புகொள்ளவும்."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"இந்தச் சாதனத்துடன் தொடர்புடைய தரவை <xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> அணுகலாம், ஆப்ஸை நிர்வகிக்கலாம், இந்தச் சாதனத்தின் அமைப்புகளை மாற்றலாம்.\n\nஉங்களுக்குக் கேள்விகள் இருந்தால் <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g> நிறுவனத்தைத் தொடர்புகொள்ளுங்கள்."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"இந்த சாதனம் உங்கள் நிறுவனத்துக்கு சொந்தமானது.\n\nஉங்கள் IT நிர்வாகியால் அமைப்புகள், நிறுவன அணுகல், ஆப்ஸ், உங்கள் சாதனத்துடன் தொடர்புடைய தரவு, சாதனத்தின் இருப்பிடத் தகவல்கள் ஆகியவற்றைக் கண்காணிக்கவும் நிர்வகிக்கவும் முடியும்.\n\nமேலும் தகவல்களுக்கு IT நிர்வாகியைத் தொடர்புகொள்ளவும்."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"உங்கள் நிறுவனம் இந்தச் சாதனத்தில் சான்றிதழ் அங்கீகாரத்தை நிறுவியுள்ளது. உங்களின் பாதுகாப்பான நெட்வொர்க் ட்ராஃபிக் கண்காணிக்கப்படலாம் அல்லது மாற்றப்படலாம்."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"உங்கள் நிறுவனம், பணிக் கணக்கில் சான்றிதழ் அங்கீகாரத்தை நிறுவியுள்ளது. உங்களின் பாதுகாப்பான நெட்வொர்க் ட்ராஃபிக் கண்காணிக்கப்படலாம் அல்லது மாற்றப்படலாம்."</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"டெமோ முறையைக் காட்டு"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"ஈதர்நெட்"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"அலாரம்"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"வாலட்"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"தயாராக உள்ளது"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"பணிக் கணக்கு"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"விமானப் பயன்முறை"</string>
     <string name="add_tile" msgid="6239678623873086686">"டைலைச் சேர்க்கும்"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"விரைவு அமைப்புகளை மூடு."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"அலாரம் அமைக்கப்பட்டது."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"<xliff:g id="ID_1">%s</xliff:g> என்ற பெயரில் உள்நுழைந்துள்ளீர்கள்"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"பயனரைத் தேர்வுசெய்யவும்"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"இணைய இணைப்பு இல்லை"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"விவரங்களைத் திற."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"<xliff:g id="REASON">%s</xliff:g> என்பதால் தற்போது முடக்கப்பட்டுள்ளது"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> அமைப்புகளைத் திற."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"அமைப்புகளின் வரிசை முறையைத் திருத்து."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"பவர் மெனு"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"பக்கம் <xliff:g id="ID_1">%1$d</xliff:g> / <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"லாக் ஸ்கிரீன்"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"வெப்பத்தினால் ஃபோன் ஆஃப் செய்யப்பட்டது"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"இடப்புறம் நகர்த்து"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"வலப்புறம் நகர்த்து"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"பெரிதாக்கல் ஸ்விட்ச்"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"முழுத்திரையைப் பெரிதாக்கும்"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"முழுத்திரையைப் பெரிதாக்கும்"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"திரையின் ஒரு பகுதியைப் பெரிதாக்கும்"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"ஸ்விட்ச்"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"அணுகல்தன்மை பட்டன் இப்போது அணுகல்தன்மை சைகையாக மாற்றப்பட்டுள்ளது\n\n"<annotation id="link">"அமைப்புகளில் காண்க"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"பட்டனைத் தற்காலிகமாக மறைக்க ஓரத்திற்கு நகர்த்தும்"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"சாதனக் கட்டுப்பாடுகள்"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"இணைக்கப்பட்ட சாதனங்களில் கட்டுப்பாடுகளைச் சேர்க்கலாம்"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"சாதனக் கட்டுப்பாடுகளை அமைத்தல்"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"புதிய சாதனத்தை இணைத்தல்"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"உரையாடல் விட்ஜெட்டுகள்"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"ஓர் உரையாடலை உங்கள் முகப்புத் திரையில் சேர்க்க அந்த உரையாடலைத் தட்டுங்கள்"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g>க்கு முன்பு"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"<xliff:g id="DURATION">%1$s</xliff:g>க்குக் குறைவாக"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"<xliff:g id="DURATION">%1$s</xliff:g>க்கு முன்பு"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"பிறந்தநாள்"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"விரைவில் பிறந்தநாள்"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"ஆண்டு விழா"</string>
+    <string name="location_status" msgid="1294990572202541812">"இடத்தைப் பகிர்கிறது"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"புதிய செய்தி"</string>
+    <string name="video_status" msgid="4548544654316843225">"பார்க்கிறீர்கள்"</string>
+    <string name="audio_status" msgid="4237055636967709208">"ஆடியோ கேட்கிறீர்கள்"</string>
+    <string name="game_status" msgid="1340694320630973259">"விளையாடுகிறீர்கள்"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"நண்பர்கள்"</string>
+    <string name="empty_status" msgid="5938893404951307749">"இன்றிரவு உரையாடலாம்!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"தவறிய அழைப்பு"</string>
+    <string name="people_tile_description" msgid="8154966188085545556">"சமீபத்திய மெசேஜ்களையும் தவறிய அழைப்புகளையும் ஸ்டேட்டஸ் அப்டேட்களையும் பார்க்கலாம்"</string>
+    <string name="people_tile_title" msgid="6589377493334871272">"உரையாடல்"</string>
     <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"பேட்டரி அளவை அறிவதில் சிக்கல்"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"மேலும் தகவல்களுக்கு தட்டவும்"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"அலாரம் எதுவுமில்லை"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index f39fa69..74326dc 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"రద్దు చేయి"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"షేర్ చేయి"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"స్క్రీన్ రికార్డ్ రద్దు చేయబడింది"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"స్క్రీన్ రికార్డింగ్ సేవ్ చేయబడింది"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"చూడటానికి ట్యాప్ చేయండి"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"స్క్రీన్ రికార్డింగ్‌ని తొలగిస్తున్నప్పుడు ఎర్రర్ ఏర్పడింది"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"అనుమతులను పొందడం విఫలమైంది"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"స్క్రీన్ రికార్డింగ్ ప్రారంభించడంలో ఎర్రర్ ఏర్పడింది"</string>
@@ -357,11 +355,10 @@
     <string name="quick_settings_settings_label" msgid="2214639529565474534">"సెట్టింగ్‌లు"</string>
     <string name="quick_settings_time_label" msgid="3352680970557509303">"సమయం"</string>
     <string name="quick_settings_user_label" msgid="1253515509432672496">"నేను"</string>
-    <string name="quick_settings_user_title" msgid="8673045967216204537">"వినియోగదారు"</string>
+    <string name="quick_settings_user_title" msgid="8673045967216204537">"యూజర్"</string>
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"కొత్త వినియోగదారు"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"ఇంటర్నెట్"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"విమాన-సురక్షితం"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"నెట్‌వర్క్‌లు అందుబాటులో ఉన్నాయి"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"నెట్‌వర్క్‌లు అందుబాటులో లేవు"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"కనెక్ట్ చేయబడలేదు"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"సూర్యోదయం వరకు"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g> కు ఆన్ అవుతుంది"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> వరకు"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"ప్రకాశాన్ని తగ్గించండి"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC నిలిపివేయబడింది"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC ప్రారంభించబడింది"</string>
@@ -468,13 +464,12 @@
     <string name="accessibility_multi_user_switch_switcher_with_current" msgid="5759855008166759399">"వినియోగదారుని మార్చు, ప్రస్తుత వినియోగదారు <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
     <string name="accessibility_multi_user_switch_inactive" msgid="383168614528618402">"ప్రస్తుత వినియోగదారు <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"ప్రొఫైల్‌ని చూపు"</string>
-    <string name="user_add_user" msgid="4336657383006913022">"వినియోగదారుని జోడించండి"</string>
+    <string name="user_add_user" msgid="4336657383006913022">"యూజర్‌ను జోడించండి"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"కొత్త వినియోగదారు"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"గెస్ట్ సెషన్‌ను ముగించు"</string>
-    <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"అతిథిని తీసివేయాలా?"</string>
+    <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"గెస్ట్‌ను తీసివేయాలా?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ఈ సెషన్‌లోని అన్ని యాప్‌లు మరియు డేటా తొలగించబడతాయి."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"తీసివేయి"</string>
-    <string name="guest_wipe_session_title" msgid="7147965814683990944">"పునఃస్వాగతం, అతిథి!"</string>
+    <string name="guest_wipe_session_title" msgid="7147965814683990944">"గెస్ట్‌కు తిరిగి స్వాగతం!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"మీరు మీ సెషన్‌ని కొనసాగించాలనుకుంటున్నారా?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"మొదటి నుండి ప్రారంభించు"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"అవును, కొనసాగించు"</string>
@@ -484,8 +479,8 @@
     <string name="user_logout_notification_title" msgid="3644848998053832589">"వినియోగదారుని లాగ్ అవుట్ చేయండి"</string>
     <string name="user_logout_notification_text" msgid="7441286737342997991">"ప్రస్తుత వినియోగదారును లాగ్ అవుట్ చేయండి"</string>
     <string name="user_logout_notification_action" msgid="7974458760719361881">"వినియోగదారుని లాగ్ అవుట్ చేయి"</string>
-    <string name="user_add_user_title" msgid="4172327541504825032">"కొత్త వినియోగదారుని జోడించాలా?"</string>
-    <string name="user_add_user_message_short" msgid="2599370307878014791">"మీరు కొత్త వినియోగదారుని జోడించినప్పుడు, ఆ వ్యక్తి తన స్థలాన్ని సెటప్ చేసుకోవాలి.\n\nఏ వినియోగదారు అయినా మిగతా అందరు వినియోగదారుల కోసం అనువర్తనాలను నవీకరించగలరు."</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"కొత్త యూజర్‌ను జోడించాలా?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"ఒక కొత్త యూజర్‌ను మీరు జోడించినప్పుడు, ఆ వ్యక్తి తన స్పేస్‌ను సెటప్ చేసుకోవాలి.\n\nఏ యూజర్ అయినా మిగతా అందరు యూజర్‌ల కోసం యాప్‌లను అప్‌డేట్ చేయగలరు."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"వినియోగదారు పరిమితిని చేరుకున్నారు"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">మీరు <xliff:g id="COUNT">%d</xliff:g> వినియోగదారుల వరకు జోడించవచ్చు.</item>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ఈ పరికరాన్ని మీ తల్లి/తండ్రి మేనేజ్ చేస్తున్నారు"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ఈ పరికరం మీ సంస్థకు చెందినది, కాబట్టి అది నెట్‌వర్క్ ట్రాఫిక్‌ను పర్యవేక్షించవచ్చు"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"మీ పరికరం <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>కు చెందినది, కాబట్టి అది నెట్‌వర్క్ ట్రాఫిక్‌ను పర్యవేక్షించవచ్చు"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"ఈ పరికరం <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ద్వారా అందించబడింది"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"ఈ పరికరం మీ సంస్థకు చెందినది, ఇది <xliff:g id="VPN_APP">%1$s</xliff:g>కు కనెక్ట్ అయి ఉంది"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"ఈ పరికరం <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>కు చెందినది, ఇది <xliff:g id="VPN_APP">%2$s</xliff:g>కు కనెక్ట్ అయి ఉంది"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"ఈ పరికరం మీ సంస్థకు చెందినది"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"మీ వర్క్ ప్రొఫైల్ <xliff:g id="VPN_APP">%1$s</xliff:g>కు కనెక్ట్ చేయబడింది"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"<xliff:g id="VPN_APP">%1$s</xliff:g>కు మీ వ్యక్తిగత ప్రొఫైల్ కనెక్ట్ చేయబడింది"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"ఈ పరికరం <xliff:g id="VPN_APP">%1$s</xliff:g>కు కనెక్ట్ అయి ఉంది"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"ఈ పరికరం <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ద్వారా అందించబడింది"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"పరికర నిర్వహణ"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"ప్రొఫైల్ పర్యవేక్షణ"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"నెట్‌వర్క్ పర్యవేక్షణ"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"విధానాలను వీక్షించండి"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"నియంత్రణలను చూడండి"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"ఈ పరికరం <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>కు చెందినది.\n\nసెట్టింగ్‌లను, కార్పొరేట్ యాక్సెస్‌ను, యాప్‌లను, మీ పరికరానికి సంబంధించిన డేటాను, అలాగే మీ పరికరం యొక్క లొకేషన్ సమాచారాన్ని మీ IT అడ్మిన్ పర్యవేక్షించగలరు, మేనేజ్ చేయగలరు.\n\nమరింత సమాచారం కోసం, మీ IT అడ్మిన్‌ను సంప్రదించండి."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g>, ఈ పరికరంతో అనుబంధించబడిన డేటాను యాక్సెస్ చేయవచ్చు, యాప్‌లను మేనేజ్ చేయవచ్చు అలాగే ఈ పరికరాల సెట్టింగ్‌లను మార్చవచ్చు.\n\nమీకు ఏవైనా సందేహాలు ఉంటే, <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>ను కాంటాక్ట్ చేయండి."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"ఈ పరికరం మీ సంస్థకు చెందినది.\n\nసెట్టింగ్‌లను, కార్పొరేట్ యాక్సెస్‌ను, యాప్‌లను, మీ పరికరానికి సంబంధించిన డేటాను, అలాగే మీ పరికరం యొక్క లొకేషన్ సమాచారాన్ని మీ IT అడ్మిన్ పర్యవేక్షించగలరు, మేనేజ్ చేయగలరు.\n\nమరింత సమాచారం కోసం, మీ IT అడ్మిన్‌ను సంప్రదించండి."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"ఈ పరికరంలో మీ సంస్థ ఒక ప్రమాణపత్ర అధికారాన్ని ఇన్‌స్టాల్ చేసింది. మీ సురక్షిత నెట్‌వర్క్ ట్రాఫిక్ పర్యవేక్షించబడవచ్చు లేదా సవరించబడవచ్చు."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"మీ కార్యాలయ ప్రొఫైల్‌లో మీ సంస్థ ఒక ప్రమాణపత్ర అధికారాన్ని ఇన్‌స్టాల్ చేసింది. మీ సురక్షిత నెట్‌వర్క్ ట్రాఫిక్ పర్యవేక్షించబడవచ్చు లేదా సవరించబడవచ్చు."</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"డెమో మోడ్ చూపు"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"ఈథర్‌నెట్"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"అలారం"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"సిద్ధంగా ఉంది"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"కార్యాలయ ప్రొఫైల్‌"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"ఎయిర్‌ప్లేన్ మోడ్"</string>
     <string name="add_tile" msgid="6239678623873086686">"టైల్‌ను జోడించండి"</string>
@@ -760,7 +760,7 @@
     <string name="notification_conversation_unmute" msgid="2692255619510896710">"అలర్ట్ చేయడం"</string>
     <string name="notification_conversation_bubble" msgid="2242180995373949022">"బబుల్‌ను చూపించు"</string>
     <string name="notification_conversation_unbubble" msgid="6908427185031099868">"బబుల్స్ తీసివేయి"</string>
-    <string name="notification_conversation_home_screen" msgid="8347136037958438935">"హోమ్ స్క్రీన్‌కు జోడించు"</string>
+    <string name="notification_conversation_home_screen" msgid="8347136037958438935">"హోమ్ స్క్రీన్‌కు జోడించండి"</string>
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"నోటిఫికేషన్ నియంత్రణలు"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"నోటిఫికేషన్ తాత్కాలిక ఆపివేత ఎంపికలు"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"శీఘ్ర సెట్టింగ్‌లను మూసివేయండి."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"అలారం సెట్ చేయబడింది."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"<xliff:g id="ID_1">%s</xliff:g> వలె సైన్ ఇన్ చేసారు"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"యూజర్‌ను ఎంపిక చేయండి"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"ఇంటర్నెట్ లేదు"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"వివరాలను తెరవండి."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"<xliff:g id="REASON">%s</xliff:g> కారణంగా అందుబాటులో లేదు"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> సెట్టింగ్‌లను తెరవండి."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"సెట్టింగ్‌ల క్రమాన్ని సవరించండి."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"పవర్ మెనూ"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g>లో <xliff:g id="ID_1">%1$d</xliff:g>వ పేజీ"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"లాక్ స్క్రీన్"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"వేడెక్కినందుకు ఫోన్ ఆఫ్ చేయబడింది"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"ఎడమవైపుగా జరపండి"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"కుడివైపుగా జరపండి"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"మాగ్నిఫికేషన్ స్విచ్"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"స్క్రీన్ మొత్తాన్ని మాగ్నిఫై చేయండి"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"ఫుల్ స్క్రీన్‌ను మ్యాగ్నిఫై చేయండి"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"స్క్రీన్‌లో భాగాన్ని మాగ్నిఫై చేయండి"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"స్విచ్ చేయి"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"యాక్సెసిబిలిటీ బటన్, యాక్సెసిబిలిటీ సంజ్ఞను భర్తీ చేసింది\n\n"<annotation id="link">"సెట్టింగ్‌లను చూడండి"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"తాత్కాలికంగా దానిని దాచడానికి బటన్‌ను చివరకు తరలించండి"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"పరికరం నియంత్రణలు"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"మీ కనెక్ట్ అయిన పరికరాలకు నియంత్రణలను జోడించండి"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"పరికరం నియంత్రణలను సెటప్ చేయడం"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"కొత్త పరికరాన్ని పెయిర్ చేయండి"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"సంభాషణ విడ్జెట్‌లు"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"దీనిని మీ మొదటి స్క్రీన్‌కు జోడించడానికి సంభాషణను ట్యాప్ చేయండి"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> క్రితం"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"<xliff:g id="DURATION">%1$s</xliff:g> కంటే ముందు"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"<xliff:g id="DURATION">%1$s</xliff:g> క్రితం"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"పుట్టినరోజు"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"పుట్టినరోజు వస్తోంది"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"వార్షికోత్సవం"</string>
+    <string name="location_status" msgid="1294990572202541812">"లొకేషన్ షేరింగ్"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"కొత్త కథనం"</string>
+    <string name="video_status" msgid="4548544654316843225">"చూస్తున్నారు"</string>
+    <string name="audio_status" msgid="4237055636967709208">"వినడం"</string>
+    <string name="game_status" msgid="1340694320630973259">"ఆడుతున్నారు"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"ఫ్రెండ్స్"</string>
+    <string name="empty_status" msgid="5938893404951307749">"రాత్రి చాట్ చేద్దాం!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"మిస్డ్ కాల్"</string>
+    <string name="people_tile_description" msgid="8154966188085545556">"ఇటీవలి మెసేజ్‌లు, మిస్డ్ కాల్‌లు, అలాగే స్టేటస్ అప్‌డేట్‌లను చూడండి"</string>
+    <string name="people_tile_title" msgid="6589377493334871272">"సంభాషణ"</string>
     <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"మీ బ్యాటరీ మీటర్‌ను చదవడంలో సమస్య"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"మరింత సమాచారం కోసం ట్యాప్ చేయండి"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"అలారం సెట్ చేయలేదు"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index a726dda..2635418 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"ยกเลิก"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"แชร์"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"ยกเลิกการบันทึกหน้าจอแล้ว"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"บันทึกการบันทึกหน้าจอแล้ว"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"แตะเพื่อดู"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"เกิดข้อผิดพลาดในการลบการบันทึกหน้าจอ"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"ขอสิทธิ์ไม่สำเร็จ"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"เกิดข้อผิดพลาดขณะเริ่มบันทึกหน้าจอ"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"ผู้ใช้ใหม่"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"อินเทอร์เน็ต"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"ใช้บนเครื่องบินได้อย่างปลอดภัย"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"เครือข่ายที่พร้อมใช้งาน"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"ใช้งานเครือข่ายไม่ได้"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"ไม่ได้เชื่อมต่อ"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"จนพระอาทิตย์ขึ้น"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"เปิดเวลา <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"จนถึง <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"ลดความสว่าง"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC ถูกปิดใช้งาน"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"เปิดใช้งาน NFC แล้ว"</string>
@@ -470,11 +466,10 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"แสดงโปรไฟล์"</string>
     <string name="user_add_user" msgid="4336657383006913022">"เพิ่มผู้ใช้"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"ผู้ใช้ใหม่"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"จบเซสชันผู้เยี่ยมชม"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"ต้องการนำผู้เข้าร่วมออกไหม"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ระบบจะลบแอปและข้อมูลทั้งหมดในเซสชันนี้"</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"นำออก"</string>
-    <string name="guest_wipe_session_title" msgid="7147965814683990944">"ยินดีต้อนรับท่านผู้เยี่ยมชมกลับมาอีกครั้ง!"</string>
+    <string name="guest_wipe_session_title" msgid="7147965814683990944">"ยินดีต้อนรับผู้เข้าร่วมกลับมาอีกครั้ง"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"คุณต้องการอยู่ในเซสชันต่อไปไหม"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"เริ่มต้นใหม่"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"ใช่ ดำเนินการต่อ"</string>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"อุปกรณ์นี้จัดการโดยผู้ปกครอง"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"องค์กรของคุณเป็นเจ้าของอุปกรณ์นี้และอาจตรวจสอบการจราจรของข้อมูลในเครือข่าย"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> เป็นเจ้าของอุปกรณ์นี้และอาจตรวจสอบการจราจรของข้อมูลในเครือข่าย"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"อุปกรณ์นี้ให้บริการโดย <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"องค์กรของคุณเป็นเจ้าของอุปกรณ์นี้ และอุปกรณ์เชื่อมต่ออยู่กับ <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> เป็นเจ้าของอุปกรณ์นี้ และอุปกรณ์เชื่อมต่ออยู่กับ <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"องค์กรของคุณเป็นเจ้าของอุปกรณ์นี้"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"โปรไฟล์งานของคุณเชื่อมต่ออยู่กับ <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"โปรไฟล์ส่วนตัวของคุณเชื่อมต่ออยู่กับ <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"อุปกรณ์นี้เชื่อมต่ออยู่กับ <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"อุปกรณ์นี้ให้บริการโดย <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"การจัดการอุปกรณ์"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"การตรวจสอบโปรไฟล์"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"การตรวจสอบเครือข่าย"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"ดูนโยบาย"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"ดูการควบคุม"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> เป็นเจ้าของอุปกรณ์นี้\n\nผู้ดูแลระบบไอทีจะตรวจสอบและจัดการการตั้งค่า การเข้าถึงของบริษัท แอป ข้อมูลที่เชื่อมโยงกับอุปกรณ์ และข้อมูลตำแหน่งของอุปกรณ์ได้\n\nติดต่อผู้ดูแลระบบไอทีหากต้องการข้อมูลเพิ่มเติม"</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> อาจเข้าถึงข้อมูลที่เชื่อมโยงกับอุปกรณ์นี้ จัดการแอป และเปลี่ยนการตั้งค่าอุปกรณ์ได้\n\nหากมีคำถาม โปรดติดต่อ <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>"</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"องค์กรของคุณเป็นเจ้าของอุปกรณ์นี้\n\nผู้ดูแลระบบไอทีจะตรวจสอบและจัดการการตั้งค่า การเข้าถึงของบริษัท แอป ข้อมูลที่เชื่อมโยงกับอุปกรณ์ และข้อมูลตำแหน่งของอุปกรณ์ได้\n\nติดต่อผู้ดูแลระบบไอทีหากต้องการข้อมูลเพิ่มเติม"</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"องค์กรของคุณติดตั้งผู้ออกใบรับรองในอุปกรณ์นี้ อาจมีการตรวจสอบหรือแก้ไขการจราจรของข้อมูลในเครือข่ายที่ปลอดภัยของคุณ"</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"องค์กรของคุณติดตั้งผู้ออกใบรับรองในโปรไฟล์งาน อาจมีการตรวจสอบหรือแก้ไขการจราจรของข้อมูลในเครือข่ายที่ปลอดภัยของคุณ"</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"แสดงโหมดสาธิต"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"อีเทอร์เน็ต"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"การปลุก"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"พร้อม"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"โปรไฟล์งาน"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"โหมดบนเครื่องบิน"</string>
     <string name="add_tile" msgid="6239678623873086686">"เพิ่มไทล์"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"ปิดการตั้งค่าด่วน"</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"ตั้งปลุกแล้ว"</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"ลงชื่อเข้าใช้เป็น <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"เลือกผู้ใช้"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"ไม่มีอินเทอร์เน็ต"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"เปิดรายละเอียด"</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"ไม่พร้อมใช้งานเนื่องจาก<xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"เปิดการตั้งค่า <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"แก้ไขลำดับการตั้งค่า"</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"เมนูเปิด/ปิด"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"หน้า <xliff:g id="ID_1">%1$d</xliff:g> จาก <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"หน้าจอล็อก"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"โทรศัพท์ปิดไปเพราะร้อนมาก"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"ย้ายไปทางซ้าย"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"ย้ายไปทางขวา"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"เปลี่ยนโหมดการขยาย"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"ขยายทั้งหน้าจอ"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"ขยายเป็นเต็มหน้าจอ"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"ขยายบางส่วนของหน้าจอ"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"เปลี่ยน"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"ปุ่มการช่วยเหลือพิเศษแทนที่ท่าทางสัมผัสการช่วยเหลือพิเศษแล้ว\n\n"<annotation id="link">"ดูการตั้งค่า"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"ย้ายปุ่มไปที่ขอบเพื่อซ่อนชั่วคราว"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"ระบบควบคุมอุปกรณ์"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"เพิ่มตัวควบคุมของอุปกรณ์ที่เชื่อมต่อ"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"ตั้งค่าระบบควบคุมอุปกรณ์"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"จับคู่อุปกรณ์ใหม่"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"วิดเจ็ตการสนทนา"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"แตะการสนทนาเพื่อเพิ่มไปยังหน้าจอหลัก"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g>ที่ผ่านมา"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"ไม่ถึง <xliff:g id="DURATION">%1$s</xliff:g>ที่ผ่านมา"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"นานกว่า <xliff:g id="DURATION">%1$s</xliff:g>ที่ผ่านมา"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"วันเกิด"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"ใกล้ถึงวันเกิดแล้ว"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"วันครบรอบ"</string>
+    <string name="location_status" msgid="1294990572202541812">"กำลังแชร์ตำแหน่ง"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"เรื่องราวใหม่"</string>
+    <string name="video_status" msgid="4548544654316843225">"กำลังดูวิดีโอ"</string>
+    <string name="audio_status" msgid="4237055636967709208">"กำลังฟัง"</string>
+    <string name="game_status" msgid="1340694320630973259">"กำลังเล่น"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"เพื่อน"</string>
+    <string name="empty_status" msgid="5938893404951307749">"คืนนี้มาแชทกัน"</string>
+    <string name="missed_call" msgid="4228016077700161689">"สายที่ไม่ได้รับ"</string>
+    <string name="people_tile_description" msgid="8154966188085545556">"ดูข้อความล่าสุด สายที่ไม่ได้รับ และการอัปเดตสถานะ"</string>
+    <string name="people_tile_title" msgid="6589377493334871272">"การสนทนา"</string>
     <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"พบปัญหาในการอ่านเครื่องวัดแบตเตอรี่"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"แตะดูข้อมูลเพิ่มเติม"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"ไม่มีการตั้งปลุก"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 92d5a66..57e289f 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Kanselahin"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Ibahagi"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Kinansela ang pag-record ng screen"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Na-save ang pag-record ng screen"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"I-tap para tingnan"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Error sa pag-delete sa pag-record ng screen"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Hindi nakuha ang mga pahintulot"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Nagkaroon ng error sa pagsisimula ng pag-record ng screen"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Bagong user"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Internet"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Ligtas gamitin sa eroplano"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Available ang mga network"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Hindi available ang mga network"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Hindi Nakakonekta"</string>
@@ -380,7 +377,7 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="2325362583903258677">"AUTO"</string>
     <string name="quick_settings_inversion_label" msgid="5078769633069667698">"I-invert ang mga kulay"</string>
     <string name="quick_settings_color_space_label" msgid="537528291083575559">"Correction mode ng kulay"</string>
-    <string name="quick_settings_more_settings" msgid="2878235926753776694">"Marami pang setting"</string>
+    <string name="quick_settings_more_settings" msgid="2878235926753776694">"Higit pang setting"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Tapos na"</string>
     <string name="quick_settings_connected" msgid="3873605509184830379">"Nakakonekta"</string>
     <string name="quick_settings_connected_battery_level" msgid="1322075669498906959">"Nakakonekta, baterya <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Hanggang sunrise"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Ma-o-on nang <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Hanggang <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Bawasan ang liwanag"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"Naka-disable ang NFC"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"Naka-enable ang NFC"</string>
@@ -470,11 +466,10 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Ipakita ang profile"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Magdagdag ng user"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Bagong user"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Tapusin ang session ng bisita"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Alisin ang bisita?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Ide-delete ang lahat ng app at data sa session na ito."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Alisin"</string>
-    <string name="guest_wipe_session_title" msgid="7147965814683990944">"Maligayang pagbabalik, bisita!"</string>
+    <string name="guest_wipe_session_title" msgid="7147965814683990944">"Welcome ulit, bisita!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Gusto mo bang ipagpatuloy ang iyong session?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Magsimulang muli"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Oo, magpatuloy"</string>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Pinapamahalaan ng magulang mo itong device"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Pagmamay-ari ng organisasyon mo ang device na ito at puwede nitong subaybayan ang trapiko sa network"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Pagmamay-ari ng <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ang device na ito at puwede nitong subaybayan ang trapiko sa network"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Nagmula sa <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ang device na ito"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Pagmamay-ari ng iyong organisasyon ang device na ito at nakakonekta ito sa <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Pagmamay-ari ng <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ang device na ito at nakakonekta ito sa <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Pagmamay-ari ng iyong organisasyon ang device na ito"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Nakakonekta sa <xliff:g id="VPN_APP">%1$s</xliff:g> ang iyong profile sa trabaho"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Nakakonekta sa <xliff:g id="VPN_APP">%1$s</xliff:g> ang iyong personal na profile"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Nakakonekta sa <xliff:g id="VPN_APP">%1$s</xliff:g> ang device na ito"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Nagmula sa <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ang device na ito"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Pamamahala ng device"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Pagsubaybay sa Profile"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Pagsubaybay sa network"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Tingnan ang Mga Patakaran"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Tingnan ang mga kontrol"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Pagmamay-ari ng <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ang device na ito.\n\nMagagawa ng iyong IT admin na subaybayan at pamahalaan ang mga setting, pangkorporasyong access, mga app, data na nauugnay sa device mo, at ang impormasyon ng lokasyon ng iyong device.\n\nPara sa higit pang impormasyon, makipag-ugnayan sa iyong IT admin."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"Posibleng ma-access ng <xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> ang data na nauugnay sa device na ito at posible rin nitong mapamahalaan ang mga app at mabago ang mga setting ng device na ito.\n\nKung mayroon kang mga tanong, makipag-ugnayan sa <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Pagmamay-ari ng iyong organisasyon ang device na ito.\n\nMagagawa ng iyong IT admin na subaybayan at pamahalaan ang mga setting, pangkorporasyong access, mga app, data na nauugnay sa device mo, at ang impormasyon ng lokasyon ng iyong device.\n\nPara sa higit pang impormasyon, makipag-ugnayan sa iyong IT admin."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Nag-install ang iyong organisasyon ng awtoridad sa certificate sa device na ito. Maaaring subaybayan o baguhin ang iyong ligtas na trapiko sa network."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Nag-install ang iyong organisasyon ng awtoridad sa certificate sa iyong profile sa trabaho. Maaaring subaybayan o baguhin ang iyong ligtas na trapiko sa network."</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Ipakita ang demo mode"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Alarma"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Handa na"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Profile sa trabaho"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Airplane mode"</string>
     <string name="add_tile" msgid="6239678623873086686">"Magdagdag ng tile"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Isara ang mga mabilisang setting."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Naitakda ang alarm."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Naka-sign in bilang <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"pumili ng user"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Walang internet"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Buksan ang mga detalye."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"Hindi available dahil sa <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Buksan ang mga setting ng <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"I-edit ang pagkakasunud-sunod ng mga setting."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Power menu"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Page <xliff:g id="ID_1">%1$d</xliff:g> ng <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Lock screen"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"Na-off ang telepono dahil sa init"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Ilipat pakaliwa"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Ilipat pakanan"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Switch ng pag-magnify"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"I-magnify ang buong screen"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"I-magnify ang buong screen"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"I-magnify ang isang bahagi ng screen"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Switch"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"Pinalitan ng button ng accessibility ang galaw ng accessibility\n\n"<annotation id="link">"Tingnan ang mga setting"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Ilipat ang button sa gilid para pansamantala itong itago"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Mga kontrol ng device"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Magdagdag ng kontrol para sa mga nakakonektang device"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"I-set up ang mga kontrol ng device"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Magpares ng bagong device"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Mga widget ng pag-uusap"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Mag-tap sa isang pag-uusap para idagdag ito sa iyong Home screen"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> ang nakalipas"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"Wala pang <xliff:g id="DURATION">%1$s</xliff:g> ang nakalipas"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"Mahigit <xliff:g id="DURATION">%1$s</xliff:g> ang nakalipas"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Kaarawan"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Kaarawang paparating"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Anibersaryo"</string>
+    <string name="location_status" msgid="1294990572202541812">"Ibinabahagi ang lokasyon"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Bagong kuwento"</string>
+    <string name="video_status" msgid="4548544654316843225">"Nanonood"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Nakikinig"</string>
+    <string name="game_status" msgid="1340694320630973259">"Nagpe-play"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Mga Kaibigan"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Mag-chat tayo mamayang gabi!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"Hindi nasagot na tawag"</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="battery_state_unknown_notification_title" msgid="8464703640483773454">"Nagkaproblema sa pagbabasa ng iyong battery meter"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"I-tap para sa higit pang impormasyon"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Walang alarm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index c708b5a..a36c8d24 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"İptal"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Paylaş"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Ekran kaydı iptal edildi"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Ekran kaydı saklandı"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Görüntülemek için dokunun"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Ekran kaydı silinirken hata oluştu"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"İzinler alınamadı"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Ekran kaydı başlatılırken hata oluştu"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Yeni kullanıcı"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Kablosuz"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"İnternet"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Uçakta kullanımı güvenli"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Kullanılabilir ağlar"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Kullanılamayan ağlar"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Bağlı Değil"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Sabaha kadar"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Açılacağı saat: <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Şu saate kadar: <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Parlaklığı azalt"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC devre dışı"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC etkin"</string>
@@ -470,11 +466,10 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Profili göster"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Kullanıcı ekle"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Yeni kullanıcı"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Misafir oturumunu sonlandır"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Misafir oturumu kaldırılsın mı?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Bu oturumdaki tüm uygulamalar ve veriler silinecek."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Kaldır"</string>
-    <string name="guest_wipe_session_title" msgid="7147965814683990944">"Tekrar hoş geldiniz sayın misafir!"</string>
+    <string name="guest_wipe_session_title" msgid="7147965814683990944">"Misafir kullanıcı, tekrar hoşgeldiniz"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Oturumunuza devam etmek istiyor musunuz?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Baştan başla"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Evet, devam et"</string>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Bu cihaz ebeveyniniz tarafından yönetiliyor"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Bu cihaz, kuruluşunuza ait olup ağ trafiği kuruluşunuz tarafından izlenebilir"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Bu cihaz, <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> adlı kuruluşa ait olup ağ trafiği bu kuruluş tarafından izlenebilir"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Bu cihaz, <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> tarafından sağlanmaktadır"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Bu cihaz, kuruluşunuza ait olup <xliff:g id="VPN_APP">%1$s</xliff:g> uygulamasına bağlı"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Bu cihaz, <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> kuruluşuna ait olup <xliff:g id="VPN_APP">%2$s</xliff:g> uygulamasına bağlı"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Bu cihaz, kuruluşunuza ait"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"İş profiliniz <xliff:g id="VPN_APP">%1$s</xliff:g> uygulamasına bağlı"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Kişisel profiliniz <xliff:g id="VPN_APP">%1$s</xliff:g> uygulamasına bağlı"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Bu cihaz <xliff:g id="VPN_APP">%1$s</xliff:g> uygulamasına bağlı"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Bu cihaz, <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> tarafından sağlanmaktadır"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Cihaz yönetimi"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Profil izleme"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Ağ izleme"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Politikaları Göster"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Kontrolleri göster"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Bu cihaz <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> adlı kuruluşa ait.\n\nBT yöneticiniz cihazınızın ayarlarını, şirket erişimini, uygulamaları, cihazınızla ilişkilendirilen verileri, cihazınızın konum bilgilerini izleyip yönetebilir.\n\nDaha fazla bilgi için BT yöneticinize başvurun."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g>; bu cihazla ilişkilendirilmiş verilere erişebilir, uygulamaları yönetebilir ve bu cihazın ayarlarını değiştirebilir.\n\nSorularınız varsa <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g> ile iletişime geçin."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Bu cihaz kuruluşunuza ait.\n\nBT yöneticiniz cihazın ayarlarını, şirket erişimini, uygulamaları, cihazınızla ilişkilendirilen verileri, cihazınızın konum bilgilerini izleyip yönetebilir.\n\nDaha fazla bilgi için BT yöneticinize başvurun."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Kuruluşunuz bu cihaza bir sertifika yetkilisi yükledi. Güvenli ağ trafiğiniz izlenebilir veya değiştirilebilir."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Kuruluşunuz iş profilinize bir sertifika yetkilisi yükledi. Güvenli ağ trafiğiniz izlenebilir veya değiştirilebilir."</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Demo modunu göster"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Alarm"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Cüzdan"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Hazır"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"İş profili"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Uçak modu"</string>
     <string name="add_tile" msgid="6239678623873086686">"Blok ekle"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Hızlı ayarları kapat."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Alarm ayarlandı."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"<xliff:g id="ID_1">%s</xliff:g> olarak oturum açıldı"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"kullanıcı seç"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"İnternet yok"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Ayrıntıları aç."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"<xliff:g id="REASON">%s</xliff:g> nedeniyle kullanılamıyor"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> ayarlarını aç."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Ayarların sırasını düzenle."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Güç menüsü"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Sayfa <xliff:g id="ID_1">%1$d</xliff:g> / <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Kilit ekranı"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"Telefon ısındığından kapatıldı"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Sola taşı"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Sağa taşı"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Büyütme moduna geçin"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Ekranın tamamını büyütün"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Tam ekran büyütme"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Ekranın bir parçasını büyütün"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Geç"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"Erişilebilirlik hareketi, Erişilebilirlik düğmesi ile değiştirildi\n\n"<annotation id="link">"Ayarları görüntüle"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Düğmeyi geçici olarak gizlemek için kenara taşıyın"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Cihaz denetimleri"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Bağlı cihazlarınız için denetimler ekleyin"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Cihaz denetimlerini kur"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Yeni cihaz eşle"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Görüşme widget\'ları"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Ana ekranınıza eklemek için bir ileti dizisine dokunun"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> önce"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"Henüz <xliff:g id="DURATION">%1$s</xliff:g> olmadı"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"<xliff:g id="DURATION">%1$s</xliff:g> üzerinde bir süre önce"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Doğum günü"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Yaklaşan doğum günü"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Yıl dönümü"</string>
+    <string name="location_status" msgid="1294990572202541812">"Konum paylaşılıyor"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Yeni hikaye"</string>
+    <string name="video_status" msgid="4548544654316843225">"İzleniyor"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Dinleniyor"</string>
+    <string name="game_status" msgid="1340694320630973259">"Çalınıyor"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Arkadaşlar"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Haydi sohbet edelim."</string>
+    <string name="missed_call" msgid="4228016077700161689">"Cevapsız arama"</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">"Konuşma"</string>
     <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Pil ölçeriniz okunurken sorun oluştu"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Daha fazla bilgi için dokunun"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Alarm ayarlanmadı"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index e51122b..f7923eb 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Скасувати"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Поділитися"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Запис екрана скасовано"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Запис відео з екрана збережено"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Натисніть, щоб переглянути"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Не вдалося видалити запис екрана"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Не вдалось отримати дозволи"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Не вдалося почати запис екрана"</string>
@@ -363,7 +361,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Новий користувач"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Інтернет"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Безпечні в літаку"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Доступні мережі"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Недоступні мережі"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Не під’єднано."</string>
@@ -419,7 +416,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"До сходу сонця"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Вмикається о <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"До <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Зменшення яскравості"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC вимкнено"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC ввімкнено"</string>
@@ -474,8 +470,7 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Показати профіль"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Додати користувача"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Новий користувач"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Завершити сеанс у режимі \"Гість\""</string>
-    <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Вийти з режиму гостя?"</string>
+    <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Видалити гостя?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Усі додатки й дані з цього сеансу буде видалено."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Вийти"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"З поверненням!"</string>
@@ -525,6 +520,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Цим пристроєм керує батько або мати"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Цей пристрій належить вашій організації. Її адміністратор може відстежувати мережевий трафік"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Цей пристрій належить організації \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\". Її адміністратор може відстежувати мережевий трафік"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Цей пристрій надала організація <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Цей пристрій належить вашій організації. Його підключено до додатка <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Цей пристрій належить організації \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\". Його підключено до додатка <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Цей пристрій належить вашій організації"</string>
@@ -538,6 +534,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Ваш робочий профіль підключено до додатка <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Ваш особистий профіль підключено до додатка <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Цей пристрій підключено до додатка <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Цей пристрій надала організація <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Керування пристроями"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Відстеження профілю"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Відстеження дій у мережі"</string>
@@ -549,6 +546,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Переглянути правила"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Переглянути засоби контролю"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Цей пристрій належить організації \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\".\n\nIT-адміністратор може відстежувати й контролювати налаштування, корпоративний доступ, додатки, дані пристрою та інформацію про його місцезнаходження.\n\nЩоб дізнатися більше, зв\'яжіться з IT-адміністратором."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"Організація <xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> може отримувати доступ до даних, пов\'язаних із цим пристроєм, змінювати його налаштування та керувати додатками.\n\nЯкщо у вас є запитання, зв\'яжіться з організацією <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Цей пристрій належить вашій організації.\n\nІТ-адміністратор може відстежувати й контролювати налаштування, корпоративний доступ, додатки, дані пристрою та інформацію про його місцезнаходження.\n\nЩоб дізнатися більше, зв\'яжіться з ІТ-адміністратором."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Адміністратор організації встановив центр сертифікації на цьому пристрої. Захищений мережевий трафік може відстежуватися або змінюватися."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Адміністратор організації встановив центр сертифікації у вашому робочому профілі. Захищений мережевий трафік може відстежуватися або змінюватися."</string>
@@ -659,6 +657,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Показати демонстраційний режим"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Сигнал"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Гаманець"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Готово"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Робочий профіль"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Режим польоту"</string>
     <string name="add_tile" msgid="6239678623873086686">"Додавання опції"</string>
@@ -909,11 +909,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Закрити швидкі налаштування."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Будильник налаштовано."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Ви ввійшли як <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"вибрати користувача"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Немає Інтернету"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Відкрити деталі."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"Недоступно, оскільки <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Відкрити налаштування <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Змінити порядок налаштувань."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Меню кнопки живлення"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Сторінка <xliff:g id="ID_1">%1$d</xliff:g> з <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Заблокований екран"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"Телефон перегрівся й вимкнувся"</string>
@@ -1021,9 +1023,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Перемістити ліворуч"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Перемістити праворуч"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Перемикач режиму збільшення"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Збільшити весь екран"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Збільшення всього екрана"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Збільшити частину екрана"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Перемкнути"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"Замість жесту спеціальних можливостей тепер використовується кнопка\n\n"<annotation id="link">"Переглянути налаштування"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Щоб тимчасово сховати кнопку, перемістіть її на край екрана"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Керування пристроями"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Додайте елементи керування для підключених пристроїв"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Налаштувати елементи керування пристроями"</string>
@@ -1093,6 +1097,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Підключити новий пристрій"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Віджети розмов"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Натисніть розмову, щоб додати її на головний екран"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> тому"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"Менше ніж <xliff:g id="DURATION">%1$s</xliff:g> тому"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"Понад <xliff:g id="DURATION">%1$s</xliff:g> тому"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"День народження"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Скоро іменини"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Річниця"</string>
+    <string name="location_status" msgid="1294990572202541812">"Ділюся геоданими"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Нова історія"</string>
+    <string name="video_status" msgid="4548544654316843225">"Дивлюся відео"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Слухаю аудіо"</string>
+    <string name="game_status" msgid="1340694320630973259">"Граю в гру"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Друзі"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Поспілкуймося!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"Пропущений виклик"</string>
+    <string name="people_tile_description" msgid="8154966188085545556">"Переглядайте останні повідомлення, пропущені виклики й оновлення статусу"</string>
+    <string name="people_tile_title" msgid="6589377493334871272">"Розмова"</string>
     <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Не вдалось отримати дані лічильника акумулятора"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Натисніть, щоб дізнатися більше"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Немає будильників"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index d2e37e7..548784d 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"منسوخ کریں"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"اشتراک کریں"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"اسکرین ریکارڈنگ منسوخ ہو گئی"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"اسکرین ریکارڈنگ محفوظ ہو گئی"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"دیکھنے کے لیے تھپتھپائیں"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"اسکرین ریکارڈنگ کو حذف کرنے میں خرابی"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"اجازتیں حاصل کرنے میں ناکامی"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"اسکرین ریکارڈنگ شروع کرنے میں خرابی"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"نیا صارف"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"انٹرنیٹ"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"ہوائی جہاز کیلئے محفوظ"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"نیٹ ورکس دستیاب ہیں"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"نیٹ ورکس دستیاب نہیں ہیں"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"مربوط نہیں ہے"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"طلوع آفتاب تک"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"آن ہوگی بوقت <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> تک"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"چمک کم کریں"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"‏NFC غیر فعال ہے"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"‏NFC فعال ہے"</string>
@@ -470,7 +466,6 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"پروفائل دکھائیں"</string>
     <string name="user_add_user" msgid="4336657383006913022">"صارف کو شامل کریں"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"نیا صارف"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"مہمان سیشن ختم کریں"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"مہمان کو ہٹائیں؟"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"اس سیشن میں موجود سبھی ایپس اور ڈیٹا کو حذف کر دیا جائے گا۔"</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"ہٹائیں"</string>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"یہ آلہ آپ کے والدین کے زیر انتظام ہے"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"آپ کی تنظیم اس آلے کی مالک ہے اور نیٹ ورک ٹریفک کی نگرانی کر سکتی ہے"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> اس آلے کی مالک ہے اور نیٹ ورک ٹریفک کی نگرانی کر سکتی ہے"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"یہ آلہ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> نے فراہم کیا ہے"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"یہ آلہ آپ کی تنظیم کا ہے اور <xliff:g id="VPN_APP">%1$s</xliff:g> سے منسلک ہے"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"یہ آلہ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> کا ہے اور <xliff:g id="VPN_APP">%2$s</xliff:g> سے منسلک ہے"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"یہ آلہ آپ کی تنظیم کا ہے"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"آپ کی دفتری پروفائل <xliff:g id="VPN_APP">%1$s</xliff:g> سے منسلک ہے"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"آپ کی ذاتی پروفائل <xliff:g id="VPN_APP">%1$s</xliff:g> سے منسلک ہے"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"یہ آلہ <xliff:g id="VPN_APP">%1$s</xliff:g> سے منسلک ہے"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"یہ آلہ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> نے فراہم کیا ہے"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"آلے کا نظم و نسق"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"پروفائل کو مانیٹر کرنا"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"نیٹ ورک کو مانیٹر کرنا"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"پالیسیاں دیکھیں"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"کنٹرولز دیکھیں"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"‏یہ آلہ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> کا ہے۔\n\nآپ کا IT منتظم ترتیبات، کارپوریٹ رسائی، ایپس، آپ کے آلہ سے وابستہ ڈیٹا اور آپ کے آلہ کے مقام کی معلومات کی نگرانی اور ان کا نظم کر سکتا ہے۔\n\nمزید معلومات کے لیے اپنے IT منتظم سے رابطہ کریں۔"</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> اس آلے سے وابستہ ڈیٹا تک رسائی حاصل، ایپس کا نظم اور ان آلات کی ترتیبات کو تبدیل کر سکتا ہے۔\n\nاگر آپ سوالات پوچھنا چاہتے ہیں تو <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g> سے رابطہ کریں۔"</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"‏یہ آلہ آپ کی تنظیم کا ہے۔\n\nآپ کا IT منتظم ترتیبات، کارپوریٹ رسائی، ایپس، آپ کے آلہ سے وابستہ ڈیٹا اور آپ کے آلہ کے مقام کی معلومات کی نگرانی اور ان کا نظم کر سکتا ہے۔\n\nمزید معلومات کے لیے اپنے IT منتظم سے رابطہ کریں۔"</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"آپ کی تنظیم نے اس آلے پر ایک سرٹیفکیٹ کی اتھارٹی کو انسٹال کیا ہے۔ آپ کا محفوظ نیٹ ورک ٹریفک مانیٹر ہو سکتا ہے یا اس میں ترمیم کی جا سکتی ہے۔"</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"آپ کی تنظیم نے آپ کے دفتری پروفائل میں ایک سرٹیفکیٹ کی اتھارٹی کو انسٹال کیا ہے۔ آپ کا محفوظ نیٹ ورک ٹریفک مانیٹر ہو سکتا ہے یا اس میں ترمیم کی جا سکتی ہے۔"</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"ڈیمو موڈ دکھائیں"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"ایتھرنیٹ"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"الارم"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"تیار ہے"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"دفتری پروفائل"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"ہوائی جہاز وضع"</string>
     <string name="add_tile" msgid="6239678623873086686">"ٹائل شامل کریں"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"فوری ترتیبات بند کریں۔"</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"الارم سیٹ ہو گیا۔"</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"<xliff:g id="ID_1">%s</xliff:g> کے بطور سائن ان ہے"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"صارف منتخب کریں"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"انٹرنیٹ نہیں ہے"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"تفصیلات کھولیں۔"</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"<xliff:g id="REASON">%s</xliff:g> کی وجہ سے دستیاب نہیں ہے"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> ترتیبات کھولیں۔"</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"ترتیبات کی ترتیب میں ترمیم کریں۔"</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"پاور مینو"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"صفحہ <xliff:g id="ID_1">%1$d</xliff:g> از <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"مقفل اسکرین"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"حرارت کی وجہ سے فون آف ہو گیا"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"بائیں منتقل کریں"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"دائیں منتقل کریں"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"میگنیفکیشن پر سوئچ کریں"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"پوری اسکرین کو بڑا کریں"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"فُل اسکرین کو بڑا کریں"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"اسکرین کا حصہ بڑا کریں"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"سوئچ کریں"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"ایکسیسبیلٹی بٹن کو ایکسیسبیلٹی اشارے سے بدل دیا گیا\n\n"<annotation id="link">"ترتیبات دیکھیں"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"عارضی طور پر بٹن کو چھپانے کے لئے اسے کنارے پر لے جائیں"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"آلہ کے کنٹرولز"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"اپنے منسلک آلات کے لیے کنٹرولز شامل کریں"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"آلہ کے کنٹرولز سیٹ اپ کریں"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"نئے آلہ کا جوڑا بنائیں"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"گفتگو ویجیٹس"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"اسے اپنے ہوم اسکرین پر شامل کرنے کے لیے گفتگو پر تھپتھپائیں"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> قبل"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"<xliff:g id="DURATION">%1$s</xliff:g> سے کچھ کم وقت قبل"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"<xliff:g id="DURATION">%1$s</xliff:g> سے زائد عرصہ قبل"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"سالگرہ"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"سالگرہ قریب ہے"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"سالگرہ"</string>
+    <string name="location_status" msgid="1294990572202541812">"مقام کا اشتراک کیا جا رہا ہے"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"نئی کہانی"</string>
+    <string name="video_status" msgid="4548544654316843225">"دیکھ رہے ہیں"</string>
+    <string name="audio_status" msgid="4237055636967709208">"سنی جا رہی ہے"</string>
+    <string name="game_status" msgid="1340694320630973259">"کھیلی جا رہی ہے"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"دوست"</string>
+    <string name="empty_status" msgid="5938893404951307749">"آج رات چیٹ کرتے ہیں!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"چھوٹی ہوئی کال"</string>
+    <string name="people_tile_description" msgid="8154966188085545556">"حالیہ پیغامات، چھوٹی ہوئی کالز اور اسٹیٹس اپ ڈیٹس دیکھیں"</string>
+    <string name="people_tile_title" msgid="6589377493334871272">"گفتگو"</string>
     <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"آپ کے بیٹری میٹر کو پڑھنے میں دشواری"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"مزید معلومات کے لیے تھپتھپائیں"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"کوئی الارم سیٹ نہیں ہے"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 4615f4a..42da6f5 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Bekor qilish"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Ulashish"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Ekrandan yozib olish bekor qilindi"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Ekran lavhasi saqlandi"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Koʻrish uchun bosing"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Ekrandan yozib olingan vi olib tashlanmadi"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Zarur ruxsatlar olinmadi"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Ekranni yozib olish boshlanmadi"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Yangi foydalanuvchi"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Internet"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Samolyot uchun xavfsiz"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Tarmoqlar mavjud"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Tarmoqqa ulanish imkonsiz"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Ulanmagan"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Quyosh chiqqunicha"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g> da yoqiladi"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> gacha"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Yorqinlikni pasaytirish"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC o‘chiq"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC yoniq"</string>
@@ -470,8 +466,7 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Profilni ko‘rsatish"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Foydalanuvchi"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Yangi foydalanuvchi"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Mehmon seansini yakunlash"</string>
-    <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Mehmon hisobi o‘chirib tashlansinmi?"</string>
+    <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Mehmon olib tashlansinmi?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Ushbu seansdagi barcha ilovalar va ma’lumotlar o‘chirib tashlanadi."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Olib tashlash"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"Xush kelibsiz, mehmon!"</string>
@@ -480,7 +475,7 @@
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ha, davom ettirilsin"</string>
     <string name="guest_notification_title" msgid="4434456703930764167">"Mehmon foydalanuvchi"</string>
     <string name="guest_notification_text" msgid="4202692942089571351">"Ilova va ma’l-ni o‘chirish u-n mehmon hisobini o‘chiring"</string>
-    <string name="guest_notification_remove_action" msgid="4153019027696868099">"MEHMON HISOBINI O‘CHIRISH"</string>
+    <string name="guest_notification_remove_action" msgid="4153019027696868099">"MEHMONNI OLIB TASHLASH"</string>
     <string name="user_logout_notification_title" msgid="3644848998053832589">"Foydalanuvchi nomidan chiqish"</string>
     <string name="user_logout_notification_text" msgid="7441286737342997991">"Joriy foydalanuvchini tizimdan chiqaring"</string>
     <string name="user_logout_notification_action" msgid="7974458760719361881">"FOYDALANUVCHI NOMIDAN CHIQISH"</string>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Bu qurilmani ota-onangiz boshqaradi"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Bu qurilma tashkilotingizga tegishli va tarmoq trafigi tashkilotingiz tomonidan kuzatilishi mumkin"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Bu qurilma <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> tashkilotiga tegishli va tarmoq trafigi tashkilot tomonidan kuzatilishi mumkin"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Bu qurilma <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> tomonidan berilgan."</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Bu qurilma tashkilotingizga tegishli va <xliff:g id="VPN_APP">%1$s</xliff:g> tarmogʻiga ulangan"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Bu qurilma <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> tashkilotiga tegishli va <xliff:g id="VPN_APP">%2$s</xliff:g> tarmogʻiga ulangan"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Bu qurilma tashkilotingizga tegishli"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Ish profilingiz <xliff:g id="VPN_APP">%1$s</xliff:g> tarmogʻiga ulangan"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Shaxsiy profilingiz <xliff:g id="VPN_APP">%1$s</xliff:g> tarmogʻiga ulangan"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Bu qurilma <xliff:g id="VPN_APP">%1$s</xliff:g> tarmogʻiga ulangan"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Bu qurilma <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> tomonidan berilgan."</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Qurilmalar boshqaruvi"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Profilni kuzatish"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Tarmoqlarni kuzatish"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Siyosatlarni ko‘rish"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Boshqaruv sozlamalari"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Bu qurilma <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> tashkilotiga tegishli.\n\nAT administratori sozlamalar, korporativ ruxsat, ilovalar, qurilmaning geolokatsiyasi va unga aloqador axborotlarni kuzatishi va boshqarishi mumkin.\n\nBatafsil axborot uchun AT administratoriga murojaat qiling."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> bu qurilmaga aloqador maʼlumotlarga kirishi, ilovalarni boshqarishi hamda bu qurilma sozlamalarini oʻzgartirishi mumkin.\n\nSavollaringiz boʻlsa <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g> bilan bogʻlaning."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Bu qurilma tashkilotingizga tegishli.\n\nAT administratori sozlamalar, korporativ ruxsat, ilovalar, qurilmaning geolokatsiyasi va unga aloqador axborotlarni kuzatishi va boshqarishi mumkin.\n\nBatafsil axborot uchun AT administratoriga murojaat qiling."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Tashkilotingiz bu qurilmada CA sertifikatini o‘rnatdi. U himoyalangan tarmoq trafigini nazorat qilishi va o‘zgartirishi mumkin."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Tashkilotingiz ishchi profilingizga CA sertifikatini o‘rnatdi. U himoyalangan tarmoq trafigini nazorat qilishi va o‘zgartirishi mumkin."</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Demo rejimni ko‘rsatish"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Signal"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Tayyor"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Ish profili"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Parvoz rejimi"</string>
     <string name="add_tile" msgid="6239678623873086686">"Tezkor sozlamalar tugmasini qo‘shish"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Tezkor sozlamalarni yopish."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Signal o‘rnatildi."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"<xliff:g id="ID_1">%s</xliff:g> sifatida kirgansiz"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"foydalanuvchini tanlash"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Internetga ulanmagansiz"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Tafsilotlarini ko‘rsatish."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"Mavjud emas, sababi: <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> sozlamalarini ochish."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Sozlamalar tartibini o‘zgartirish."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Quvvat menyusi"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_1">%1$d</xliff:g>-sahifa, jami: <xliff:g id="ID_2">%2$d</xliff:g> ta sahifa"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Ekran qulfi"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"Qizigani uchun o‘chirildi"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Chapga siljitish"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Oʻngga siljitish"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Kattalashtirish rejimini almashtirish"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Butun ekranni kattalashtirish"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Ekranni toʻliq kattalashtirish"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Ekran qismini kattalashtirish"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Almashtirish"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"Maxsus imkoniyatlar tugmasi maxsus imkoniyatlar ishorasini almashtirdi\n\n"<annotation id="link">"Sozlamalarni ochish"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Vaqtinchalik berkitish uchun tugmani qirra tomon suring"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Qurilmalarni boshqarish"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Ulangan qurilmalar uchun boshqaruv elementlari"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Qurilma boshqaruv elementlarini sozlash"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Yangi qurilmani ulash"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Suhbat vidjetlari"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Bosh ekranga chiqariladigan suhbat ustiga bosing"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> oldin"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"<xliff:g id="DURATION">%1$s</xliff:g>dan kam vaqt oldin"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"<xliff:g id="DURATION">%1$s</xliff:g>dan ortiq vaqt oldin"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Tavallud kuni"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Yaqinda tavallud kun"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Yubiley"</string>
+    <string name="location_status" msgid="1294990572202541812">"Joylashuv ulashilmoqda"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Yangi hikoya"</string>
+    <string name="video_status" msgid="4548544654316843225">"Tomosha"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Gapiring"</string>
+    <string name="game_status" msgid="1340694320630973259">"Ijro etilmoqda"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Doʻstlar"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Bugun yozishaylik!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"Javobsiz chaqiruv"</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="battery_state_unknown_notification_title" msgid="8464703640483773454">"Batareya quvvati aniqlanmadi"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Batafsil axborot olish uchun bosing"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Signal sozlanmagan"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index ee97bc5..a137a12 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Hủy"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Chia sẻ"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Đã hủy bản ghi màn hình"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Đã lưu bản ghi màn hình"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Nhấn để xem"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Lỗi khi xóa bản ghi màn hình"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Không được cấp đủ quyền"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Lỗi khi bắt đầu ghi màn hình"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Người dùng mới"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Internet"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"An toàn với máy bay"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Có mạng"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Không có mạng"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Chưa được kết nối"</string>
@@ -380,7 +377,7 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="2325362583903258677">"TỰ ĐỘNG"</string>
     <string name="quick_settings_inversion_label" msgid="5078769633069667698">"Đảo ngược màu"</string>
     <string name="quick_settings_color_space_label" msgid="537528291083575559">"Chế độ chỉnh màu"</string>
-    <string name="quick_settings_more_settings" msgid="2878235926753776694">"Cài đặt khác"</string>
+    <string name="quick_settings_more_settings" msgid="2878235926753776694">"Chế độ cài đặt khác"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Xong"</string>
     <string name="quick_settings_connected" msgid="3873605509184830379">"Đã kết nối"</string>
     <string name="quick_settings_connected_battery_level" msgid="1322075669498906959">"Đã kết nối, mức pin <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Cho đến khi trời sáng"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Bật vào lúc <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Cho đến <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Giảm độ sáng"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC đã được tắt"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC đã được bật"</string>
@@ -470,7 +466,6 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Hiển thị hồ sơ"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Thêm người dùng"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Người dùng mới"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Kết thúc phiên khách"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Xóa phiên khách?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Tất cả ứng dụng và dữ liệu trong phiên này sẽ bị xóa."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Xóa"</string>
@@ -519,6 +514,7 @@
     <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>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Tổ chức của bạn sở hữu thiết bị này và có thể giám sát lưu lượng truy cập mạng"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> sở hữu thiết bị này và có thể giám sát lưu lượng truy cập mạng"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Thiết bị này do <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> cung cấp"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Thiết bị này thuộc về tổ chức của bạn và đã kết nối với <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Thiết bị này thuộc về <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> và đã kết nối với <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Thiết bị này thuộc về tổ chức của bạn"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Hồ sơ công việc của bạn đã kết nối với <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Hồ sơ cá nhân của bạn đã kết nối với <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Thiết bị này đã kết nối với <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Thiết bị này do <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> cung cấp"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Quản lý thiết bị"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Giám sát hồ sơ"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Giám sát mạng"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Xem chính sách"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Xem các quyền kiểm soát"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Thiết bị này thuộc về <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nQuản trị viên CNTT có thể giám sát và quản lý các tùy chọn cài đặt, quyền truy cập vào dữ liệu công ty, ứng dụng, dữ liệu liên kết với thiết bị và thông tin vị trí thiết bị của bạn.\n\nĐể biết thêm thông tin, hãy liên hệ với quản trị viên CNTT của bạn."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> có thể truy cập vào dữ liệu liên kết với thiết bị này, quản lý ứng dụng và thay đổi các chế độ cài đặt trên thiết bị này.\n\nNếu bạn có thắc mắc, hãy liên hệ với <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Thiết bị này thuộc về tổ chức của bạn.\n\nQuản trị viên CNTT có thể giám sát và quản lý các tùy chọn cài đặt, quyền truy cập vào dữ liệu công ty, ứng dụng, dữ liệu liên kết với thiết bị và thông tin vị trí thiết bị của bạn.\n\nĐể biết thêm thông tin, hãy liên hệ với quản trị viên CNTT của bạn."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Tổ chức của bạn đã cài đặt một tổ chức phát hành chứng chỉ trên thiết bị này. Lưu lượng truy cập mạng bảo mật của bạn có thể được giám sát hoặc sửa đổi."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Tổ chức của bạn đã cài đặt một tổ chức phát hành chứng chỉ trong hồ cơ công việc của bạn. Lưu lượng truy cập mạng bảo mật của bạn có thể được giám sát hoặc sửa đổi."</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Hiển thị chế độ trình diễn"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Báo thức"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Ví"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Sẵn sàng"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Hồ sơ công việc"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Chế độ máy bay"</string>
     <string name="add_tile" msgid="6239678623873086686">"Thêm ô"</string>
@@ -721,7 +721,7 @@
     <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"&lt;b&gt;Trạng thái:&lt;/b&gt; Đã thay đổi thành Im lặng"</string>
     <string name="notification_channel_summary_automatic_promoted" msgid="1301710305149590426">"&lt;b&gt;Trạng thái:&lt;/b&gt; Đã tăng mức độ quan trọng"</string>
     <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" msgid="7952654515769021553">"Hiển thị cuộc trò chuyện ở đầu phần cuộc trò chuyện và dưới dạng bong bóng nổi, hiển thị ảnh hồ sơ trên màn hình khóa"</string>
+    <string name="notification_channel_summary_priority" msgid="7952654515769021553">"Hiển thị ở đầu phần cuộc trò chuyện, dưới dạng bong bóng nổi và hiển thị ảnh hồ sơ trên màn hình khóa"</string>
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Cài đặt"</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>
@@ -749,7 +749,7 @@
     <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Đã mở điều khiển thông báo đối với <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="notification_channel_controls_closed_accessibility" msgid="1561909368876911701">"Đã đóng điều khiển thông báo đối với <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="notification_channel_switch_accessibility" msgid="8979885820432540252">"Cho phép thông báo từ kênh này"</string>
-    <string name="notification_more_settings" msgid="4936228656989201793">"Cài đặt khác"</string>
+    <string name="notification_more_settings" msgid="4936228656989201793">"Chế độ cài đặt khác"</string>
     <string name="notification_app_settings" msgid="8963648463858039377">"Tùy chỉnh"</string>
     <string name="notification_done" msgid="6215117625922713976">"Xong"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Hoàn tác"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Đóng cài đặt nhanh."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Đã đặt báo thức."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Đã đăng nhập là <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"chọn người dùng"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Không có Internet"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Mở chi tiết."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"Không sử dụng được do <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Mở cài đặt <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Chỉnh sửa thứ tự cài đặt."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Trình đơn nguồn"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Trang <xliff:g id="ID_1">%1$d</xliff:g> / <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Màn hình khóa"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"Điện thoại đã tắt do nhiệt"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Di chuyển sang trái"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Di chuyển sang phải"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Nút chuyển phóng to"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Phóng to toàn bộ màn hình"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Phóng to toàn màn hình"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Phóng to một phần màn hình"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Chuyển"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"Nút hỗ trợ tiếp cận đã thay thế cử chỉ hỗ trợ tiếp cận\n\n"<annotation id="link">"Xem chế độ cài đặt"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Di chuyển nút sang cạnh để ẩn nút tạm thời"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Điều khiển thiết bị"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Thêm các tùy chọn điều khiển cho các thiết bị đã kết nối của bạn"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Thiết lập các tùy chọn điều khiển thiết bị"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Ghép nối thiết bị mới"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Tiện ích trò chuyện"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Nhấn vào một cuộc trò chuyện để thêm cuộc trò chuyện đó vào Màn hình chính"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> trước"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"Chưa đầy <xliff:g id="DURATION">%1$s</xliff:g> trước"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"Hơn <xliff:g id="DURATION">%1$s</xliff:g> trước"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Sinh nhật"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Sắp đến sinh nhật"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Ngày kỷ niệm"</string>
+    <string name="location_status" msgid="1294990572202541812">"Đang chia sẻ vị trí"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Tin bài mới"</string>
+    <string name="video_status" msgid="4548544654316843225">"Đang xem"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Đang nghe"</string>
+    <string name="game_status" msgid="1340694320630973259">"Đang chơi"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Bạn bè"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Cùng trò chuyện tối nay nhé!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"Cuộc gọi nhỡ"</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="battery_state_unknown_notification_title" msgid="8464703640483773454">"Đã xảy ra vấn đề khi đọc dung lượng pin của bạn"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Nhấn để biết thêm thông tin"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Chưa đặt chuông báo"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index bee359d..b78569c 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"取消"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"分享"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"已取消录制屏幕"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"已保存屏幕录制内容"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"点按即可查看"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"删除屏幕录制内容时出错"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"无法获取权限"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"启动屏幕录制时出错"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"新用户"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"WLAN"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"互联网"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"可在飞机上安全使用"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"有可用的网络"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"没有可用的网络"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"未连接"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"在日出时关闭"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"在<xliff:g id="TIME">%s</xliff:g> 开启"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"直到<xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"调低亮度"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC 已停用"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC 已启用"</string>
@@ -470,7 +466,6 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"显示个人资料"</string>
     <string name="user_add_user" msgid="4336657383006913022">"添加用户"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"新用户"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"结束访客会话"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"要移除访客吗?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"此会话中的所有应用和数据都将被删除。"</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"移除"</string>
@@ -505,7 +500,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"全部清除"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"管理"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"历史记录"</string>
-    <string name="notification_section_header_incoming" msgid="850925217908095197">"新"</string>
+    <string name="notification_section_header_incoming" msgid="850925217908095197">"最新"</string>
     <string name="notification_section_header_gentle" msgid="6804099527336337197">"静音"</string>
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"通知"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"对话"</string>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"此设备由您的家长管理"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"贵单位拥有此设备,且可能会监控网络流量"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>拥有此设备,且可能会监控网络流量"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"此设备由<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>提供"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"此设备归贵单位所有,且已连接到“<xliff:g id="VPN_APP">%1$s</xliff:g>”"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"此设备归<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>所有,且已连接到“<xliff:g id="VPN_APP">%2$s</xliff:g>”"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"此设备归贵单位所有"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"您的工作资料已连接到“<xliff:g id="VPN_APP">%1$s</xliff:g>”"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"您的个人资料已连接到“<xliff:g id="VPN_APP">%1$s</xliff:g>”"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"此设备已连接到“<xliff:g id="VPN_APP">%1$s</xliff:g>”"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"此设备由<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>提供"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"设备管理"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"资料监控"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"网络监控"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"查看政策"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"查看家长控制功能相关信息"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"此设备归<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>所有。\n\n您的 IT 管理员能够监控和管理与您的设备相关的设置、企业权限、应用、数据,以及您设备的位置信息。\n\n如需了解详情,请与您的 IT 管理员联系。"</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g>或许能够访问与此设备相关的数据、管理应用以及更改此设备的设置。\n\n如果您有疑问,请与<xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>联系。"</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"此设备归贵单位所有。\n\n您的 IT 管理员能够监控和管理与您的设备相关的设置、企业权限、应用、数据,以及您设备的位置信息。\n\n如需了解详情,请与您的 IT 管理员联系。"</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"您所在的单位已在此设备上安装证书授权中心。您的安全网络流量可能会受到监控或修改。"</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"您所在的单位已为您的工作资料安装证书授权中心。您的安全网络流量可能会受到监控或修改。"</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"显示演示模式"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"以太网"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"闹钟"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"电子钱包"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"已可使用"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"工作资料"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"飞行模式"</string>
     <string name="add_tile" msgid="6239678623873086686">"添加图块"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"关闭快捷设置。"</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"已设置闹钟。"</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"目前登录的用户名为<xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"选择用户"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"未连接到互联网"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"打开详情页面。"</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"<xliff:g id="REASON">%s</xliff:g>,因此目前无法使用"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"打开<xliff:g id="ID_1">%s</xliff:g>设置。"</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"修改设置顺序。"</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"电源菜单"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"第 <xliff:g id="ID_1">%1$d</xliff:g> 页,共 <xliff:g id="ID_2">%2$d</xliff:g> 页"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"锁定屏幕"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"手机因严重发热而自动关机"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"左移"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"右移"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"切换放大模式"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"放大整个屏幕"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"放大整个屏幕"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"放大部分屏幕"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"切换"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"“无障碍”按钮已取代无障碍手势\n\n"<annotation id="link">"查看设置"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"将按钮移到边缘,即可暂时将其隐藏"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"设备控制器"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"为您所连接的设备添加控件"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"设置设备控件"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"与新设备配对"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"对话微件"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"点按对话即可将其添加到主屏幕"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g>前"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"最近 <xliff:g id="DURATION">%1$s</xliff:g>内"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"超过 <xliff:g id="DURATION">%1$s</xliff:g>前"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"生日"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"生日快到了"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"周年纪念日"</string>
+    <string name="location_status" msgid="1294990572202541812">"正在分享位置信息"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"新故事"</string>
+    <string name="video_status" msgid="4548544654316843225">"正在观看"</string>
+    <string name="audio_status" msgid="4237055636967709208">"正在收听"</string>
+    <string name="game_status" msgid="1340694320630973259">"正在玩游戏"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"好友"</string>
+    <string name="empty_status" msgid="5938893404951307749">"今晚来聊聊吧!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"未接电话"</string>
+    <string name="people_tile_description" msgid="8154966188085545556">"查看最近的信息、未接电话和状态更新"</string>
+    <string name="people_tile_title" msgid="6589377493334871272">"对话"</string>
     <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"读取电池计量器时出现问题"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"点按即可了解详情"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"未设置闹钟"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 7b4f663..f5481df 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"取消"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"分享"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"已取消錄影畫面"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"已儲存螢幕錄影內容"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"輕按即可查看"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"刪除錄影畫面時發生錯誤"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"無法獲得權限"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"開始錄影畫面時發生錯誤"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"新使用者"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"互聯網"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"飛行安全"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"有可用的網絡"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"網絡無法使用"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"未連線"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"在日出時關閉"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"於<xliff:g id="TIME">%s</xliff:g>開啟"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"直至<xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"調低亮度"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC 已停用"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC 已啟用"</string>
@@ -449,7 +445,7 @@
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"解鎖方可使用 NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"此裝置屬於您的機構"</string>
     <string name="do_disclosure_with_name" msgid="2091641464065004091">"此裝置屬於「<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>」"</string>
-    <string name="do_financed_disclosure_with_name" msgid="6723004643314467864">"此為「<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>」提供的裝置"</string>
+    <string name="do_financed_disclosure_with_name" msgid="6723004643314467864">"此裝置由 <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> 提供"</string>
     <string name="phone_hint" msgid="6682125338461375925">"從圖示滑動即可使用手機功能"</string>
     <string name="voice_hint" msgid="7476017460191291417">"從圖示滑動即可使用語音助手"</string>
     <string name="camera_hint" msgid="4519495795000658637">"從圖示滑動即可使用相機功能"</string>
@@ -470,7 +466,6 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"顯示個人檔案"</string>
     <string name="user_add_user" msgid="4336657383006913022">"加入使用者"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"新使用者"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"結束訪客工作階段"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"移除訪客?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"這個工作階段中的所有應用程式和資料都會被刪除。"</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"移除"</string>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"此裝置由您的家長管理"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"您的機構擁有此裝置,並可能會監察網絡流量"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"「<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>」擁有此裝置,並可能會監察網絡流量"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"此裝置由 <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> 提供"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"此裝置屬於您的機構,並已連結至「<xliff:g id="VPN_APP">%1$s</xliff:g>」"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"此裝置屬於「<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>」,並已連結至「<xliff:g id="VPN_APP">%2$s</xliff:g>」"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"此裝置屬於您的機構"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"您的工作設定檔已連結至「<xliff:g id="VPN_APP">%1$s</xliff:g>」"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"您的個人設定檔已連結至「<xliff:g id="VPN_APP">%1$s</xliff:g>」"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"此裝置已連結至「<xliff:g id="VPN_APP">%1$s</xliff:g>」"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"此裝置由 <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> 提供"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"裝置管理"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"個人檔案監控"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"網絡監控"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"查看政策"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"查看控制項"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"此裝置屬於 <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>。\n\n您的 IT 管理員可監察及管理與裝置相關聯的設定、公司存取權、應用程式和資料,以及裝置的位置資料。\n\n如要瞭解詳情,請與您的 IT 管理員聯絡。"</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> 或可存取此裝置的相關資料、管理應用程式並變更裝置設定。\n\n如有疑問,請聯絡 <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>。"</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"此裝置屬於您的機構。\n\n您的 IT 管理員可監察及管理與裝置相關聯的設定、公司存取權、應用程式和資料,以及裝置的位置資料。\n\n如要瞭解詳情,請與您的 IT 管理員聯絡。"</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"您的機構已在此裝置中安裝憑證授權單位。您的安全網絡流量可能會受監控或修改。"</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"您的機構已在您的工作設定檔中安裝憑證授權單位。您的安全網絡流量可能會受監控或修改。"</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"顯示示範模式"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"以太網"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"鬧鐘"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"電子錢包"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"已可使用"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"工作設定檔"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"飛行模式"</string>
     <string name="add_tile" msgid="6239678623873086686">"加入圖塊"</string>
@@ -721,9 +721,9 @@
     <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"&lt;b&gt;狀態:&lt;/b&gt;已降低為靜音"</string>
     <string name="notification_channel_summary_automatic_promoted" msgid="1301710305149590426">"&lt;b&gt;狀態:&lt;/b&gt;已提高次序"</string>
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;狀態:&lt;/b&gt;已調低次序"</string>
-    <string name="notification_channel_summary_priority" msgid="7952654515769021553">"以浮動對話泡顯示在對話部分的頂部,並在上鎖畫面顯示個人檔案相片"</string>
+    <string name="notification_channel_summary_priority" msgid="7952654515769021553">"在對話部分頂部顯示浮動對話氣泡,並在上鎖畫面上顯示個人檔案相片"</string>
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"設定"</string>
-    <string name="notification_priority_title" msgid="2079708866333537093">"重要"</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>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"無法在此設定這組通知"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"關閉快速設定。"</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"已設定鬧鐘。"</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"已登入為<xliff:g id="ID_1">%s</xliff:g>。"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"揀使用者"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"沒有互聯網連線"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"開啟詳細資料頁面。"</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"<xliff:g id="REASON">%s</xliff:g>,所以宜家用唔到"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"開啟<xliff:g id="ID_1">%s</xliff:g>設定頁面。"</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"編輯設定次序。"</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"電源選單"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"第 <xliff:g id="ID_1">%1$d</xliff:g> 頁 (共 <xliff:g id="ID_2">%2$d</xliff:g> 頁)"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"螢幕鎖定"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"手機因過熱而關上"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"向左移"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"向右移"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"放大開關"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"放大整個螢幕畫面"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"放大成個畫面"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"放大部分螢幕畫面"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"切換"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"無障礙工具按鈕取代咗無障礙手勢\n\n"<annotation id="link">"睇下設定"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"將按鈕移到邊緣即可暫時隱藏"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"裝置控制"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"為連接的裝置新增控制選項"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"設定裝置控制"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"配對新裝置"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"對話小工具"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"輕按對話即可新增至主畫面"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g>前"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"最近 <xliff:g id="DURATION">%1$s</xliff:g>內"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"超過 <xliff:g id="DURATION">%1$s</xliff:g>前"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"生日之星"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"即將生日"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"週年紀念"</string>
+    <string name="location_status" msgid="1294990572202541812">"分享位置資訊"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"最新報導"</string>
+    <string name="video_status" msgid="4548544654316843225">"正在觀看"</string>
+    <string name="audio_status" msgid="4237055636967709208">"正在聽取音訊"</string>
+    <string name="game_status" msgid="1340694320630973259">"正在玩遊戲"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"朋友"</string>
+    <string name="empty_status" msgid="5938893404951307749">"今晚聊天吧!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"未接來電"</string>
+    <string name="people_tile_description" msgid="8154966188085545556">"查看最近的訊息、未接來電和狀態更新"</string>
+    <string name="people_tile_title" msgid="6589377493334871272">"對話"</string>
     <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"讀取電池計量器時發生問題"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"輕按即可瞭解詳情"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"未設定鬧鐘"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 1dddeba..b7cbed1 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"取消"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"分享"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"已取消錄製螢幕畫面"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"已儲存螢幕錄影檔"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"輕觸即可查看"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"刪除螢幕畫面錄製內容時發生錯誤"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"無法取得權限"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"開始錄製螢幕畫面時發生錯誤"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"新使用者"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"網際網路"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"飛航安全"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"有可用的網路"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"沒有網路"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"未連線"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"於日出時關閉"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"開啟時間:<xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"關閉時間:<xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"調低亮度"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC 已停用"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC 已啟用"</string>
@@ -470,7 +466,6 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"顯示設定檔"</string>
     <string name="user_add_user" msgid="4336657383006913022">"新增使用者"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"新使用者"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"結束訪客工作階段"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"移除訪客?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"這個工作階段中的所有應用程式和資料都會遭到刪除。"</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"移除"</string>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"這個裝置是由你的家長管理"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"貴機構擁有這部裝置,而且可能會監控網路流量"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"這部裝置的擁有者為「<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>」,而且該機構可能會監控網路流量"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"這部裝置是由「<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>」提供"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"這部裝置的擁有者為貴機構,並且已連線到「<xliff:g id="VPN_APP">%1$s</xliff:g>」"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"這部裝置的擁有者為「<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>」,並且已連線到「<xliff:g id="VPN_APP">%2$s</xliff:g>」"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"這部裝置的擁有者為貴機構"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"你的工作資料夾已連線到「<xliff:g id="VPN_APP">%1$s</xliff:g>」"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"你的個人資料夾已連線到「<xliff:g id="VPN_APP">%1$s</xliff:g>」"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"這部裝置已連線到「<xliff:g id="VPN_APP">%1$s</xliff:g>」"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"這部裝置是由「<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>」提供"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"裝置管理"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"設定檔監控"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"網路監控"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"查看政策"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"查看監護功能相關資訊"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"這部裝置的擁有者為「<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>」。\n\n你的 IT 管理員可以監控及管理與裝置相關聯的設定、公司系統權限、應用程式和資料,以及裝置的位置資訊。\n\n如要瞭解詳情,請與你的 IT 管理員聯絡。"</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"「<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g>」或許可以存取這部裝置的相關資料、管理應用程式及變更裝置設定。\n\n如有任何疑問,請與「<xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>」聯絡。"</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"這部裝置的擁有者為貴機構。\n\n你的 IT 管理員可以監控及管理與裝置相關聯的設定、公司系統權限、應用程式和資料,以及裝置的位置資訊。\n\n如要瞭解詳情,請與你的 IT 管理員聯絡。"</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"貴機構已為這個裝置安裝憑證授權單位憑證。你的安全網路流量可能會受到監控或修改。"</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"貴機構已為你的工作資料夾安裝憑證授權單位憑證。你的安全網路流量可能會受到監控或修改。"</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"顯示示範模式"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"乙太網路"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"鬧鐘"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"電子錢包"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"已可使用"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"工作資料夾"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"飛航模式"</string>
     <string name="add_tile" msgid="6239678623873086686">"新增圖塊"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"關閉快速設定。"</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"已設定鬧鐘。"</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"以「<xliff:g id="ID_1">%s</xliff:g>」的身分登入"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"選擇使用者"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"沒有網際網路連線"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"開啟詳細資料。"</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"<xliff:g id="REASON">%s</xliff:g>,因此目前無法使用"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"開啟「<xliff:g id="ID_1">%s</xliff:g>」設定。"</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"編輯設定順序。"</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"電源按鈕選單"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"第 <xliff:g id="ID_1">%1$d</xliff:g> 頁,共 <xliff:g id="ID_2">%2$d</xliff:g> 頁"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"鎖定畫面"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"手機先前過熱,因此關閉電源"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"向左移"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"向右移"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"切換放大模式"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"放大整個螢幕畫面"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"放大整個螢幕畫面"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"放大局部螢幕畫面"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"切換"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"無障礙工具按鈕已取代無障礙手勢\n\n"<annotation id="link">"查看設定"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"將按鈕移到邊緣處即可暫時隱藏"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"裝置控制"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"新增已連結裝置的控制項"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"設定裝置控制"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"配對新裝置"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"對話小工具"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"輕觸對話即可新增至主畫面"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g>前"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"最近 <xliff:g id="DURATION">%1$s</xliff:g>內"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"超過 <xliff:g id="DURATION">%1$s</xliff:g>前"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"本日壽星"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"生日快到了"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"週年紀念"</string>
+    <string name="location_status" msgid="1294990572202541812">"正在分享位置資訊"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"新故事"</string>
+    <string name="video_status" msgid="4548544654316843225">"正在觀看影片"</string>
+    <string name="audio_status" msgid="4237055636967709208">"正在聆聽內容"</string>
+    <string name="game_status" msgid="1340694320630973259">"正在玩遊戲"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"好友"</string>
+    <string name="empty_status" msgid="5938893404951307749">"今晚來聊聊吧!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"未接來電"</string>
+    <string name="people_tile_description" msgid="8154966188085545556">"查看最近的訊息、未接來電和狀態更新"</string>
+    <string name="people_tile_title" msgid="6589377493334871272">"對話"</string>
     <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"讀取電池計量器時發生問題"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"輕觸即可瞭解詳情"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"未設定鬧鐘"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index c6f0ef9..c095383 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -116,10 +116,8 @@
     <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Khansela"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Yabelana"</string>
     <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Ukurekhoda isikrini kukhanseliwe"</string>
-    <!-- no translation found for screenrecord_save_title (1886652605520893850) -->
-    <skip />
-    <!-- no translation found for screenrecord_save_text (3008973099800840163) -->
-    <skip />
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Okokuqopha iskrini kulondoloziwe"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Thepha ukuze ubuke"</string>
     <string name="screenrecord_delete_error" msgid="2870506119743013588">"Iphutha lokususa ukurekhoda isikrini"</string>
     <string name="screenrecord_permission_error" msgid="7856841237023137686">"Yehlulekile ukuthola izimvume"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Iphutha lokuqala ukurekhoda isikrini"</string>
@@ -361,7 +359,6 @@
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Umsebenzisi omusha"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"I-Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"I-inthanethi"</string>
-    <string name="quick_settings_airplane_safe_label" msgid="2665758539772645899">"Indiza ephephile"</string>
     <string name="quick_settings_networks_available" msgid="1875138606855420438">"Amanethiwekhi ayatholakala"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Amanethiwekhi awatholakali"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Akuxhunyiwe"</string>
@@ -415,7 +412,6 @@
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Kuze kube sekuphumeni kwelanga"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Kuvulwe ngo-<xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Kuze kube ngu-<xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Nciphisa ukukhanya"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"I-NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"I-NFC ikhutshaziwe"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"I-NFC inikwe amandla"</string>
@@ -470,7 +466,6 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Bonisa iphrofayela"</string>
     <string name="user_add_user" msgid="4336657383006913022">"Engeza umsebenzisi"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Umsebenzisi omusha"</string>
-    <string name="guest_exit_button" msgid="3059840571760915762">"Misa isikhathi sesihambeli"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Susa isivakashi?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Zonke izinhlelo zokusebenza nedatha kulesi sikhathi zizosuswa."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Susa"</string>
@@ -519,6 +514,7 @@
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Le divayisi iphethwe ngumzali wakho"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Inhlangano yakho ingumnikazi wale divayisi futhi ingaqapha ithrafikhi yenethiwekhi"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"I-<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ingumnikazi wale divayisi futhi ingaqapha ithrafikhi yenethiwekhi"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Le divayisi ihlinzekwa yi-<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Le divayisi ngeyenhlangano yakho futhi ixhunywe ku-<xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Le divayisi ngeye-<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> futhi ixhunywe ku-<xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Le divayisi eyenhlangano yakho"</string>
@@ -532,6 +528,7 @@
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Iphrofayela yakho yomsebenzi ixhunywe ku-<xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Iphrofayela yakho yomuntu ixhunywe ku-<xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Le divayisi ixhunywe ku-<xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Le divayisi ihlinzekwa yi-<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Ukuphathwa kwedivayisi"</string>
     <string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Ukuqapha iphrofayela"</string>
     <string name="monitoring_title" msgid="4063890083735924568">"Ukuqashwa kwenethiwekhi"</string>
@@ -543,6 +540,7 @@
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Buka izinqubomgomo"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Buka izilawuli"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Le divayisi ngeye-<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nUmphathi wakho we-IT angakwazi ukugada nokulawula amasethingi, ukufinyelela kwenhlangano, izinhlelo zokusebenza, idatha ehlobene nedivayisi yakho, nolwazi lwendawo yedivayisi yakho.\n\nUkuze uthole ulwazi olwengeziwe, xhumana nomphathi wakho we-IT."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"I-<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> kungenzeka ikwazi ukufinyelela kudatha ehambisana nale divayisi, iphathe ama-app, iphinde ishintshe amasethingi alawa madivayisi.\n\nUma unemibuzo, xhumana ne-<xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Le divayisi ngeyenhlangano.\n\nUmphathi wakho we-IT angakwazi ukugada nokulawula amasethingi, ukufinyelela kwenhlangano, izinhlelo zokusebenza, idatha ehlobene nedivayisi yakho, nolwazi lwendawo yedivayisi yakho.\n\nUkuze uthole ulwazi olwengeziwe, xhumana nomphathi wakho we-IT."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Inhlangano yakho ifake ukugunyazwa kwesitifiketi kule divayisi. Ithrafikhi yenethiwekhi yakho evikelekile kungenzeka iqashelwe noma ilungiswe."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Inhlangano yakho ifake ukugunyaza kwesitifiketi kuphrofayela yakho yomsebenzi. Ithrafikhi yenethiwekhi yakho evikelekile ingaqashwa noma ilungiswe."</string>
@@ -653,6 +651,8 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Bonisa imodi yedemo"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"I-Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"I-alamu"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"I-wallet"</string>
+    <string name="wallet_secondary_label" msgid="2017028770884957543">"Isikulungele"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Iphrofayela yomsebenzi"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Imodi yendiza"</string>
     <string name="add_tile" msgid="6239678623873086686">"Engeza ithayili"</string>
@@ -899,11 +899,13 @@
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Vala izilungiselelo ezisheshayo."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"I-alamu isethiwe."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Ungene ngemvume njengo-<xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"khetha umsebenzisi"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Ayikho i-inthanethi"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Vula imininingwane."</string>
     <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"Ayitholakali ngenxa ye-<xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Vula izilungiselelo ze-<xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Hlela uhlelo lwezilungiselelo."</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Imenyu yamandla"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Ikhasi <xliff:g id="ID_1">%1$d</xliff:g> kwangu-<xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Khiya isikrini"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"Ifoni ivaliwe ngenxa yokushisa"</string>
@@ -1011,9 +1013,11 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"Yisa kwesokunxele"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"Yisa kwesokudla"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Iswishi yokukhulisa"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="2882507327576770574">"Khulisa sonke isikrini"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Khulisa isikrini esigcwele"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Khulisa ingxenye eyesikrini"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Iswishi"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"Inkinobho yokufinyeleleka ishintshaniswe ngokuthinta kokufinyeleleka\n\n"<annotation id="link">"Buka amasethingi"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Hambisa inkinobho onqenqemeni ukuze uyifihle okwesikhashana"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Izilawuli zezinsiza"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Engeza izilawuli zedivayisi yakho exhunyiwe"</string>
     <string name="quick_controls_setup_title" msgid="8901436655997849822">"Setha izilawuli zezinsiza"</string>
@@ -1081,6 +1085,26 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Bhangqa idivayisi entsha"</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>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Amawijethi wengxoxo"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Thepha ingxoxo ukuyengeza Kusikrini sakho sasekhaya"</string>
+    <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> edlule"</string>
+    <string name="less_than_timestamp" msgid="6598972791137724517">"Ngaphansi kwe-<xliff:g id="DURATION">%1$s</xliff:g> edlule"</string>
+    <string name="over_timestamp" msgid="4765793502859358634">"Ngaphezu kwe-<xliff:g id="DURATION">%1$s</xliff:g> edlule"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Usuku lokuzalwa"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Usuku lokuzalwa maduze"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Usuku olugujwa minyaka yonke"</string>
+    <string name="location_status" msgid="1294990572202541812">"Ukwabelana ngendawo"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Indaba entsha"</string>
+    <string name="video_status" msgid="4548544654316843225">"Ababukele"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Ilalele"</string>
+    <string name="game_status" msgid="1340694320630973259">"Iyadlala"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Abangane"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Asixoxe namuhla ebusuku!"</string>
+    <string name="missed_call" msgid="4228016077700161689">"Ikholi ephuthiwe"</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="battery_state_unknown_notification_title" msgid="8464703640483773454">"Kube khona inkinga ngokufunda imitha yakho yebhethri"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Thepha ukuze uthole olunye ulwazi"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Akukho alamu esethiwe"</string>
 </resources>
diff --git a/packages/SystemUI/res/values/attrs.xml b/packages/SystemUI/res/values/attrs.xml
index be49e1f..886f98e 100644
--- a/packages/SystemUI/res/values/attrs.xml
+++ b/packages/SystemUI/res/values/attrs.xml
@@ -124,6 +124,7 @@
     <attr name="darkIconTheme" format="reference" />
     <attr name="wallpaperTextColor" format="reference|color" />
     <attr name="wallpaperTextColorSecondary" format="reference|color" />
+    <attr name="wallpaperTextColorAccent" format="reference|color" />
     <attr name="backgroundProtectedStyle" format="reference" />
 
     <declare-styleable name="SmartReplyView">
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 0076c51..7a6de75 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -151,8 +151,8 @@
     <color name="minimize_dock_shadow_end">#00000000</color>
 
     <color name="default_remote_input_background">@*android:color/notification_default_color</color>
-    <color name="remote_input_hint">#99ffffff</color>
-
+    <color name="notif_pill_background">@android:color/system_neutral2_100</color>
+    <color name="notif_pill_text">@android:color/system_neutral1_900</color>
     <color name="remote_input_accent">?android:attr/colorAccent</color>
 
     <color name="quick_step_track_background_background_dark">#1F000000</color>
@@ -202,7 +202,7 @@
     <color name="global_screenshot_background_protection_start">#40000000</color> <!-- 25% black -->
 
     <!-- Long screenshot UI -->
-    <color name="screenshot_crop_scrim">#9444</color>
+    <color name="screenshot_crop_scrim">#6444</color>
 
     <!-- GM2 colors -->
     <color name="GM2_grey_50">#F8F9FA</color>
@@ -272,8 +272,7 @@
     <color name="screenrecord_status_color">#E94235</color>
 
     <!-- TODO(b/178093014) Colors for privacy dialog. These should be changed to the new palette -->
-    <color name="privacy_circle_camera">#1E8E3E</color> <!-- g600 -->
-    <color name="privacy_circle_microphone_location">#E8710A</color> <!--o600 -->
+    <color name="privacy_circle">#1E8E3E</color> <!-- g600 -->
 
     <!-- Accessibility floating menu -->
     <color name="accessibility_floating_menu_background">#CCFFFFFF</color> <!-- 80% -->
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index af6df32..6e61148 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -99,7 +99,7 @@
 
     <!-- The default tiles to display in QuickSettings -->
     <string name="quick_settings_tiles_default" translatable="false">
-        wifi,bt,dnd,flashlight,rotation,battery,cell,airplane,cast,screenrecord
+        internet,wifi,bt,dnd,flashlight,rotation,battery,cell,airplane,cast,screenrecord
     </string>
 
     <!-- The minimum number of tiles to display in QuickSettings -->
@@ -107,7 +107,7 @@
 
     <!-- Tiles native to System UI. Order should match "quick_settings_tiles_default" -->
     <string name="quick_settings_tiles_stock" translatable="false">
-        wifi,cell,battery,dnd,flashlight,rotation,bt,airplane,location,hotspot,inversion,saver,dark,work,cast,night,screenrecord,reverse,reduce_brightness,cameratoggle,mictoggle,controls,alarm,wallet
+        internet,wifi,cell,battery,dnd,flashlight,rotation,bt,airplane,location,hotspot,inversion,saver,dark,work,cast,night,screenrecord,reverse,reduce_brightness,cameratoggle,mictoggle,controls,alarm,wallet
     </string>
 
     <!-- The tiles to display in QuickSettings -->
@@ -591,4 +591,12 @@
 
     <!-- Determines whether to allow the nav bar handle to be forced to be opaque. -->
     <bool name="allow_force_nav_bar_handle_opaque">true</bool>
+
+    <!-- Whether a transition of ACTIVITY_TYPE_DREAM to the home app should play a home sound
+         effect -->
+    <bool name="config_playHomeSoundAfterDream">false</bool>
+
+    <!-- Whether a transition of ACTIVITY_TYPE_ASSISTANT to the home app should play a home sound
+         effect -->
+    <bool name="config_playHomeSoundAfterAssistant">false</bool>
 </resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index b050945..be00594 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -19,6 +19,8 @@
     <!-- Recommended minimum clickable element dimension -->
     <dimen name="min_clickable_item_size">48dp</dimen>
 
+    <dimen name="remote_input_view_text_stroke">3dp</dimen>
+
     <!-- Amount to offset bottom of notification peek window from top of status bar. -->
     <dimen name="peek_window_y_offset">-12dp</dimen>
 
@@ -334,7 +336,6 @@
     <dimen name="screenshot_action_container_corner_radius">10dp</dimen>
     <dimen name="screenshot_action_container_padding_vertical">6dp</dimen>
     <dimen name="screenshot_action_container_margin_horizontal">8dp</dimen>
-    <dimen name="screenshot_action_container_padding_left">96dp</dimen>
     <dimen name="screenshot_action_container_padding_right">8dp</dimen>
     <!-- Radius of the chip background on global screenshot actions -->
     <dimen name="screenshot_button_corner_radius">20dp</dimen>
@@ -463,6 +464,10 @@
 
     <dimen name="volume_dialog_slider_height">116dp</dimen>
 
+    <dimen name="volume_dialog_slider_width">@dimen/volume_dialog_panel_width</dimen>
+
+    <dimen name="volume_dialog_slider_corner_radius">@dimen/volume_dialog_panel_width_half</dimen>
+
     <dimen name="volume_dialog_ringer_size">64dp</dimen>
 
     <dimen name="volume_dialog_ringer_icon_padding">20dp</dimen>
@@ -1354,7 +1359,20 @@
 
     <dimen name="people_space_widget_radius">28dp</dimen>
     <dimen name="people_space_image_radius">20dp</dimen>
+    <dimen name="people_space_messages_count_radius">12dp</dimen>
     <dimen name="people_space_widget_background_padding">6dp</dimen>
+    <dimen name="required_width_for_medium">146dp</dimen>
+    <dimen name="required_width_for_large">138dp</dimen>
+    <dimen name="required_height_for_large">182dp</dimen>
+    <dimen name="default_width">146dp</dimen>
+    <dimen name="default_height">92dp</dimen>
+    <dimen name="avatar_size_for_medium">52dp</dimen>
+    <dimen name="max_people_avatar_size_for_large_content">64dp</dimen>
+    <dimen name="max_people_avatar_size">108dp</dimen>
+    <dimen name="name_text_size_for_small">14sp</dimen>
+    <dimen name="name_text_size_for_large">24sp</dimen>
+    <dimen name="content_text_size_for_medium">12sp</dimen>
+    <dimen name="content_text_size_for_large">14sp</dimen>
 
     <!-- Accessibility floating menu -->
     <dimen name="accessibility_floating_menu_elevation">5dp</dimen>
diff --git a/packages/SystemUI/res/values/flags.xml b/packages/SystemUI/res/values/flags.xml
index 52a97b1..2f3fbe7 100644
--- a/packages/SystemUI/res/values/flags.xml
+++ b/packages/SystemUI/res/values/flags.xml
@@ -45,8 +45,6 @@
 
     <bool name="flag_toast_style">false</bool>
 
-    <bool name="flag_navigation_bar_overlay">false</bool>
-
     <bool name="flag_pm_lite">false</bool>
 
     <bool name="flag_alarm_tile">false</bool>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 225e132..a815318 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -239,10 +239,8 @@
     <string name="screenshot_edit_label">Edit</string>
     <!-- Content description indicating that tapping the element will allow editing the screenshot [CHAR LIMIT=NONE] -->
     <string name="screenshot_edit_description">Edit screenshot</string>
-    <!-- Label for UI element which allows scrolling and extending the screenshot to be taller [CHAR LIMIT=30] -->
-    <string name="screenshot_scroll_label">Scroll</string>
-    <!-- Content description UI element which allows scrolling and extending the screenshot to be taller [CHAR LIMIT=NONE] -->
-    <string name="screenshot_scroll_description">Scroll screenshot</string>
+    <!-- Label for UI element which allows the user to capture additional off-screen content in a screenshot. [CHAR LIMIT=30] -->
+    <string name="screenshot_scroll_label">Capture more</string>
     <!-- Content description indicating that tapping a button will dismiss the screenshots UI [CHAR LIMIT=NONE] -->
     <string name="screenshot_dismiss_description">Dismiss screenshot</string>
     <!-- Content description indicating that the view is a preview of the screenshot that was just taken [CHAR LIMIT=NONE] -->
@@ -895,8 +893,12 @@
     <string name="quick_settings_color_space_label">Color correction mode</string>
     <!-- QuickSettings: Control panel: Label for button that navigates to settings. [CHAR LIMIT=NONE] -->
     <string name="quick_settings_more_settings">More settings</string>
+    <!-- QuickSettings: Control panel: Label for button that navigates to user settings. [CHAR LIMIT=NONE] -->
+    <string name="quick_settings_more_user_settings">User settings</string>
     <!-- QuickSettings: Control panel: Label for button that dismisses control panel. [CHAR LIMIT=NONE] -->
     <string name="quick_settings_done">Done</string>
+    <!-- QuickSettings: Control panel: Label for button that dismisses user switcher control panel. [CHAR LIMIT=NONE] -->
+    <string name="quick_settings_close_user_panel">Close</string>
     <!-- QuickSettings: Control panel: Label for connected device. [CHAR LIMIT=NONE] -->
     <string name="quick_settings_connected">Connected</string>
     <!-- QuickSettings: Control panel: Label for connected device, showing remote device battery level. [CHAR LIMIT=NONE] -->
@@ -1288,6 +1290,9 @@
     <!-- Disclosure at the bottom of Quick Settings that indicates that the device has a managed profile which can be monitored by the profile owner [CHAR LIMIT=100] -->
     <string name="quick_settings_disclosure_named_managed_profile_monitoring"><xliff:g id="organization_name" example="Foo, Inc.">%1$s</xliff:g> may monitor network traffic in your work profile</string>
 
+    <!-- Disclosure at the bottom of Quick Settings that indicates that the user's device has a managed profile where network activity is visible to their IT admin [CHAR LIMIT=100] -->
+    <string name="quick_settings_disclosure_managed_profile_network_activity">Work profile network activity is visible to your IT admin</string>
+
     <!-- Disclosure at the bottom of Quick Settings that indicates that a certificate authorithy is installed on this device and the traffic might be monitored [CHAR LIMIT=100] -->
     <string name="quick_settings_disclosure_monitoring">Network may be monitored</string>
 
@@ -2871,6 +2876,8 @@
     <string name="empty_status">Let’s chat tonight!</string>
     <!-- Default text for missed call notifications on their Conversation widget [CHAR LIMIT=20] -->
     <string name="missed_call">Missed call</string>
+    <!-- Text when a Notification may have more messages than the number indicated [CHAR LIMIT=5] -->
+    <string name="messages_count_overflow_indicator"><xliff:g id="number" example="7">%d</xliff:g>+</string>
     <!-- Description text for adding a Conversation widget [CHAR LIMIT=100] -->
     <string name="people_tile_description">See recent messages, missed calls, and status updates</string>
     <!-- Title text displayed for the Conversation widget [CHAR LIMIT=50] -->
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 4a661dc..ecc1a5c 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -321,6 +321,7 @@
         <item name="darkIconTheme">@style/DualToneDarkTheme</item>
         <item name="wallpaperTextColor">@*android:color/primary_text_material_dark</item>
         <item name="wallpaperTextColorSecondary">@*android:color/secondary_text_material_dark</item>
+        <item name="wallpaperTextColorAccent">@*android:color/system_accent1_100</item>
         <item name="android:colorError">@*android:color/error_color_material_dark</item>
         <item name="android:colorControlHighlight">@*android:color/primary_text_material_dark</item>
         <item name="*android:lockPatternStyle">@style/LockPatternStyle</item>
@@ -337,6 +338,7 @@
     <style name="Theme.SystemUI.Light">
         <item name="wallpaperTextColor">@*android:color/primary_text_material_light</item>
         <item name="wallpaperTextColorSecondary">@*android:color/secondary_text_material_light</item>
+        <item name="wallpaperTextColorAccent">@*android:color/system_accent2_600</item>
         <item name="android:colorError">@*android:color/error_color_material_light</item>
         <item name="android:colorControlHighlight">#40000000</item>
         <item name="shadowRadius">0</item>
diff --git a/packages/SystemUI/res/xml/people_space_widget_info.xml b/packages/SystemUI/res/xml/people_space_widget_info.xml
index d2bff18..b2bf6da 100644
--- a/packages/SystemUI/res/xml/people_space_widget_info.xml
+++ b/packages/SystemUI/res/xml/people_space_widget_info.xml
@@ -16,9 +16,9 @@
 
 <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
     android:minWidth="120dp"
-    android:minHeight="54dp"
+    android:minHeight="50dp"
     android:minResizeWidth="60dp"
-    android:minResizeHeight="54dp"
+    android:minResizeHeight="50dp"
     android:maxResizeHeight="207dp"
     android:updatePeriodMillis="60000"
     android:description="@string/people_tile_description"
diff --git a/packages/SystemUI/src/com/android/keyguard/AnimatableClockController.java b/packages/SystemUI/src/com/android/keyguard/AnimatableClockController.java
index 3f0e3eb..ab219f3 100644
--- a/packages/SystemUI/src/com/android/keyguard/AnimatableClockController.java
+++ b/packages/SystemUI/src/com/android/keyguard/AnimatableClockController.java
@@ -131,7 +131,7 @@
 
     private void initColors() {
         mLockScreenColor = Utils.getColorAttrDefaultColor(getContext(),
-                com.android.systemui.R.attr.wallpaperTextColor);
+                com.android.systemui.R.attr.wallpaperTextColorAccent);
         mView.setColors(mDozingColor, mLockScreenColor);
         mView.animateDoze(mIsDozing, false);
     }
diff --git a/packages/SystemUI/src/com/android/keyguard/CarrierText.java b/packages/SystemUI/src/com/android/keyguard/CarrierText.java
index f6b03c1..e4f6e131 100644
--- a/packages/SystemUI/src/com/android/keyguard/CarrierText.java
+++ b/packages/SystemUI/src/com/android/keyguard/CarrierText.java
@@ -24,41 +24,14 @@
 import android.view.View;
 import android.widget.TextView;
 
-import com.android.systemui.Dependency;
 import com.android.systemui.R;
 
 import java.util.Locale;
 
 public class CarrierText extends TextView {
-    private static final boolean DEBUG = KeyguardConstants.DEBUG;
-    private static final String TAG = "CarrierText";
+    private final boolean mShowMissingSim;
 
-    private static CharSequence mSeparator;
-
-    private boolean mShowMissingSim;
-
-    private boolean mShowAirplaneMode;
-    private boolean mShouldMarquee;
-
-    private CarrierTextController mCarrierTextController;
-
-    private CarrierTextController.CarrierTextCallback mCarrierTextCallback =
-            new CarrierTextController.CarrierTextCallback() {
-                @Override
-                public void updateCarrierInfo(CarrierTextController.CarrierTextCallbackInfo info) {
-                    setText(info.carrierText);
-                }
-
-                @Override
-                public void startedGoingToSleep() {
-                    setSelected(false);
-                }
-
-                @Override
-                public void finishedWakingUp() {
-                    setSelected(true);
-                }
-            };
+    private final boolean mShowAirplaneMode;
 
     public CarrierText(Context context) {
         this(context, null);
@@ -78,30 +51,6 @@
         }
         setTransformationMethod(new CarrierTextTransformationMethod(mContext, useAllCaps));
     }
-
-    @Override
-    protected void onFinishInflate() {
-        super.onFinishInflate();
-        mSeparator = getResources().getString(
-                com.android.internal.R.string.kg_text_message_separator);
-        mCarrierTextController = new CarrierTextController(mContext, mSeparator, mShowAirplaneMode,
-                mShowMissingSim);
-        mShouldMarquee = Dependency.get(KeyguardUpdateMonitor.class).isDeviceInteractive();
-        setSelected(mShouldMarquee); // Allow marquee to work.
-    }
-
-    @Override
-    protected void onAttachedToWindow() {
-        super.onAttachedToWindow();
-        mCarrierTextController.setListening(mCarrierTextCallback);
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-        mCarrierTextController.setListening(null);
-    }
-
     @Override
     protected void onVisibilityChanged(View changedView, int visibility) {
         super.onVisibilityChanged(changedView, visibility);
@@ -113,7 +62,15 @@
         }
     }
 
-    private class CarrierTextTransformationMethod extends SingleLineTransformationMethod {
+    public boolean getShowAirplaneMode() {
+        return mShowAirplaneMode;
+    }
+
+    public boolean getShowMissingSim() {
+        return mShowMissingSim;
+    }
+
+    private static class CarrierTextTransformationMethod extends SingleLineTransformationMethod {
         private final Locale mLocale;
         private final boolean mAllCaps;
 
diff --git a/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java b/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java
index b1e1434..997c527 100644
--- a/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java
+++ b/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * 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.
@@ -16,680 +16,60 @@
 
 package com.android.keyguard;
 
-import static android.telephony.PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE;
-import static android.telephony.PhoneStateListener.LISTEN_NONE;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.res.Resources;
-import android.net.ConnectivityManager;
-import android.net.wifi.WifiManager;
-import android.os.Handler;
-import android.telephony.PhoneStateListener;
-import android.telephony.ServiceState;
-import android.telephony.SubscriptionInfo;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
-import android.text.TextUtils;
-import android.util.Log;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
-import com.android.settingslib.WirelessUtils;
-import com.android.systemui.Dependency;
-import com.android.systemui.R;
-import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.keyguard.WakefulnessLifecycle;
-
-import java.util.List;
-import java.util.Objects;
-import java.util.concurrent.atomic.AtomicBoolean;
+import com.android.systemui.util.ViewController;
 
 import javax.inject.Inject;
 
 /**
- * Controller that generates text including the carrier names and/or the status of all the SIM
- * interfaces in the device. Through a callback, the updates can be retrieved either as a list or
- * separated by a given separator {@link CharSequence}.
+ * Controller for {@link CarrierText}.
  */
-public class CarrierTextController {
-    private static final boolean DEBUG = KeyguardConstants.DEBUG;
-    private static final String TAG = "CarrierTextController";
-
-    private final boolean mIsEmergencyCallCapable;
-    private final Handler mMainHandler;
-    private final Handler mBgHandler;
-    private boolean mTelephonyCapable;
-    private boolean mShowMissingSim;
-    private boolean mShowAirplaneMode;
-    private final AtomicBoolean mNetworkSupported = new AtomicBoolean();
-    @VisibleForTesting
-    protected KeyguardUpdateMonitor mKeyguardUpdateMonitor;
-    private WifiManager mWifiManager;
-    private boolean[] mSimErrorState;
-    private final int mSimSlotsNumber;
-    @Nullable // Check for nullability before dispatching
-    private CarrierTextCallback mCarrierTextCallback;
-    private Context mContext;
-    private CharSequence mSeparator;
-    private WakefulnessLifecycle mWakefulnessLifecycle;
-    private final WakefulnessLifecycle.Observer mWakefulnessObserver =
-            new WakefulnessLifecycle.Observer() {
+public class CarrierTextController extends ViewController<CarrierText> {
+    private final CarrierTextManager mCarrierTextManager;
+    private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+    private final CarrierTextManager.CarrierTextCallback mCarrierTextCallback =
+            new CarrierTextManager.CarrierTextCallback() {
                 @Override
-                public void onFinishedWakingUp() {
-                    final CarrierTextCallback callback = mCarrierTextCallback;
-                    if (callback != null) callback.finishedWakingUp();
+                public void updateCarrierInfo(CarrierTextManager.CarrierTextCallbackInfo info) {
+                    mView.setText(info.carrierText);
                 }
 
                 @Override
-                public void onStartedGoingToSleep() {
-                    final CarrierTextCallback callback = mCarrierTextCallback;
-                    if (callback != null) callback.startedGoingToSleep();
+                public void startedGoingToSleep() {
+                    mView.setSelected(false);
+                }
+
+                @Override
+                public void finishedWakingUp() {
+                    mView.setSelected(true);
                 }
             };
 
-    @VisibleForTesting
-    protected final KeyguardUpdateMonitorCallback mCallback = new KeyguardUpdateMonitorCallback() {
-        @Override
-        public void onRefreshCarrierInfo() {
-            if (DEBUG) {
-                Log.d(TAG, "onRefreshCarrierInfo(), mTelephonyCapable: "
-                        + Boolean.toString(mTelephonyCapable));
-            }
-            updateCarrierText();
-        }
+    @Inject
+    public CarrierTextController(CarrierText view,
+            CarrierTextManager.Builder carrierTextManagerBuilder,
+            KeyguardUpdateMonitor keyguardUpdateMonitor) {
+        super(view);
 
-        @Override
-        public void onTelephonyCapable(boolean capable) {
-            if (DEBUG) {
-                Log.d(TAG, "onTelephonyCapable() mTelephonyCapable: "
-                        + Boolean.toString(capable));
-            }
-            mTelephonyCapable = capable;
-            updateCarrierText();
-        }
-
-        public void onSimStateChanged(int subId, int slotId, int simState) {
-            if (slotId < 0 || slotId >= mSimSlotsNumber) {
-                Log.d(TAG, "onSimStateChanged() - slotId invalid: " + slotId
-                        + " mTelephonyCapable: " + Boolean.toString(mTelephonyCapable));
-                return;
-            }
-
-            if (DEBUG) Log.d(TAG, "onSimStateChanged: " + getStatusForIccState(simState));
-            if (getStatusForIccState(simState) == CarrierTextController.StatusMode.SimIoError) {
-                mSimErrorState[slotId] = true;
-                updateCarrierText();
-            } else if (mSimErrorState[slotId]) {
-                mSimErrorState[slotId] = false;
-                updateCarrierText();
-            }
-        }
-    };
-
-    private int mActiveMobileDataSubscription = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
-    private PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
-        @Override
-        public void onActiveDataSubscriptionIdChanged(int subId) {
-            mActiveMobileDataSubscription = subId;
-            if (mNetworkSupported.get() && mCarrierTextCallback != null) {
-                updateCarrierText();
-            }
-        }
-    };
-
-    /**
-     * The status of this lock screen. Primarily used for widgets on LockScreen.
-     */
-    private enum StatusMode {
-        Normal, // Normal case (sim card present, it's not locked)
-        NetworkLocked, // SIM card is 'network locked'.
-        SimMissing, // SIM card is missing.
-        SimMissingLocked, // SIM card is missing, and device isn't provisioned; don't allow access
-        SimPukLocked, // SIM card is PUK locked because SIM entered wrong too many times
-        SimLocked, // SIM card is currently locked
-        SimPermDisabled, // SIM card is permanently disabled due to PUK unlock failure
-        SimNotReady, // SIM is not ready yet. May never be on devices w/o a SIM.
-        SimIoError, // SIM card is faulty
-        SimUnknown // SIM card is unknown
+        mCarrierTextManager = carrierTextManagerBuilder
+                .setShowAirplaneMode(mView.getShowAirplaneMode())
+                .setShowMissingSim(mView.getShowMissingSim())
+                .build();
+        mKeyguardUpdateMonitor = keyguardUpdateMonitor;
     }
 
-    /**
-     * Controller that provides updates on text with carriers names or SIM status.
-     * Used by {@link CarrierText}.
-     *
-     * @param separator Separator between different parts of the text
-     */
-    public CarrierTextController(Context context, CharSequence separator, boolean showAirplaneMode,
-            boolean showMissingSim) {
-        mContext = context;
-        mIsEmergencyCallCapable = getTelephonyManager().isVoiceCapable();
-
-        mShowAirplaneMode = showAirplaneMode;
-        mShowMissingSim = showMissingSim;
-
-        mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
-        mSeparator = separator;
-        mWakefulnessLifecycle = Dependency.get(WakefulnessLifecycle.class);
-        mSimSlotsNumber = getTelephonyManager().getSupportedModemCount();
-        mSimErrorState = new boolean[mSimSlotsNumber];
-        mMainHandler = Dependency.get(Dependency.MAIN_HANDLER);
-        mBgHandler = new Handler(Dependency.get(Dependency.BG_LOOPER));
-        mKeyguardUpdateMonitor = Dependency.get(KeyguardUpdateMonitor.class);
-        mBgHandler.post(() -> {
-            boolean supported = ConnectivityManager.from(mContext).isNetworkSupported(
-                    ConnectivityManager.TYPE_MOBILE);
-            if (supported && mNetworkSupported.compareAndSet(false, supported)) {
-                // This will set/remove the listeners appropriately. Note that it will never double
-                // add the listeners.
-                handleSetListening(mCarrierTextCallback);
-            }
-        });
+    @Override
+    protected void onInit() {
+        super.onInit();
+        mView.setSelected(mKeyguardUpdateMonitor.isDeviceInteractive());
     }
 
-    private TelephonyManager getTelephonyManager() {
-        return (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
+    @Override
+    protected void onViewAttached() {
+        mCarrierTextManager.setListening(mCarrierTextCallback);
     }
 
-    /**
-     * Checks if there are faulty cards. Adds the text depending on the slot of the card
-     *
-     * @param text:   current carrier text based on the sim state
-     * @param carrierNames names order by subscription order
-     * @param subOrderBySlot array containing the sub index for each slot ID
-     * @param noSims: whether a valid sim card is inserted
-     * @return text
-     */
-    private CharSequence updateCarrierTextWithSimIoError(CharSequence text,
-            CharSequence[] carrierNames, int[] subOrderBySlot, boolean noSims) {
-        final CharSequence carrier = "";
-        CharSequence carrierTextForSimIOError = getCarrierTextForSimState(
-                TelephonyManager.SIM_STATE_CARD_IO_ERROR, carrier);
-        // mSimErrorState has the state of each sim indexed by slotID.
-        for (int index = 0; index < getTelephonyManager().getActiveModemCount(); index++) {
-            if (!mSimErrorState[index]) {
-                continue;
-            }
-            // In the case when no sim cards are detected but a faulty card is inserted
-            // overwrite the text and only show "Invalid card"
-            if (noSims) {
-                return concatenate(carrierTextForSimIOError,
-                        getContext().getText(
-                                com.android.internal.R.string.emergency_calls_only),
-                        mSeparator);
-            } else if (subOrderBySlot[index] != -1) {
-                int subIndex = subOrderBySlot[index];
-                // prepend "Invalid card" when faulty card is inserted in slot 0 or 1
-                carrierNames[subIndex] = concatenate(carrierTextForSimIOError,
-                        carrierNames[subIndex],
-                        mSeparator);
-            } else {
-                // concatenate "Invalid card" when faulty card is inserted in other slot
-                text = concatenate(text, carrierTextForSimIOError, mSeparator);
-            }
-
-        }
-        return text;
-    }
-
-    /**
-     * This may be called internally after retrieving the correct value of {@code mNetworkSupported}
-     * (assumed false to start). In that case, the following happens:
-     * <ul>
-     *     <li> If there was a registered callback, and the network is supported, it will register
-     *          listeners.
-     *     <li> If there was not a registered callback, it will try to remove unregistered listeners
-     *          which is a no-op
-     * </ul>
-     *
-     * This call will always be processed in a background thread.
-     */
-    private void handleSetListening(CarrierTextCallback callback) {
-        TelephonyManager telephonyManager = getTelephonyManager();
-        if (callback != null) {
-            mCarrierTextCallback = callback;
-            if (mNetworkSupported.get()) {
-                // Keyguard update monitor expects callbacks from main thread
-                mMainHandler.post(() -> mKeyguardUpdateMonitor.registerCallback(mCallback));
-                mWakefulnessLifecycle.addObserver(mWakefulnessObserver);
-                telephonyManager.listen(mPhoneStateListener,
-                        LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE);
-            } else {
-                // Don't listen and clear out the text when the device isn't a phone.
-                mMainHandler.post(() -> callback.updateCarrierInfo(
-                        new CarrierTextCallbackInfo("", null, false, null)
-                ));
-            }
-        } else {
-            mCarrierTextCallback = null;
-            mMainHandler.post(() -> mKeyguardUpdateMonitor.removeCallback(mCallback));
-            mWakefulnessLifecycle.removeObserver(mWakefulnessObserver);
-            telephonyManager.listen(mPhoneStateListener, LISTEN_NONE);
-        }
-    }
-
-    /**
-     * Sets the listening status of this controller. If the callback is null, it is set to
-     * not listening.
-     *
-     * @param callback Callback to provide text updates
-     */
-    public void setListening(CarrierTextCallback callback) {
-        mBgHandler.post(() -> handleSetListening(callback));
-    }
-
-    protected List<SubscriptionInfo> getSubscriptionInfo() {
-        return mKeyguardUpdateMonitor.getFilteredSubscriptionInfo(false);
-    }
-
-    protected void updateCarrierText() {
-        boolean allSimsMissing = true;
-        boolean anySimReadyAndInService = false;
-        CharSequence displayText = null;
-        List<SubscriptionInfo> subs = getSubscriptionInfo();
-
-        final int numSubs = subs.size();
-        final int[] subsIds = new int[numSubs];
-        // This array will contain in position i, the index of subscription in slot ID i.
-        // -1 if no subscription in that slot
-        final int[] subOrderBySlot = new int[mSimSlotsNumber];
-        for (int i = 0; i < mSimSlotsNumber; i++) {
-            subOrderBySlot[i] = -1;
-        }
-        final CharSequence[] carrierNames = new CharSequence[numSubs];
-        if (DEBUG) Log.d(TAG, "updateCarrierText(): " + numSubs);
-
-        for (int i = 0; i < numSubs; i++) {
-            int subId = subs.get(i).getSubscriptionId();
-            carrierNames[i] = "";
-            subsIds[i] = subId;
-            subOrderBySlot[subs.get(i).getSimSlotIndex()] = i;
-            int simState = mKeyguardUpdateMonitor.getSimState(subId);
-            CharSequence carrierName = subs.get(i).getCarrierName();
-            CharSequence carrierTextForSimState = getCarrierTextForSimState(simState, carrierName);
-            if (DEBUG) {
-                Log.d(TAG, "Handling (subId=" + subId + "): " + simState + " " + carrierName);
-            }
-            if (carrierTextForSimState != null) {
-                allSimsMissing = false;
-                carrierNames[i] = carrierTextForSimState;
-            }
-            if (simState == TelephonyManager.SIM_STATE_READY) {
-                ServiceState ss = mKeyguardUpdateMonitor.mServiceStates.get(subId);
-                if (ss != null && ss.getDataRegistrationState() == ServiceState.STATE_IN_SERVICE) {
-                    // hack for WFC (IWLAN) not turning off immediately once
-                    // Wi-Fi is disassociated or disabled
-                    if (ss.getRilDataRadioTechnology() != ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN
-                            || (mWifiManager.isWifiEnabled()
-                            && mWifiManager.getConnectionInfo() != null
-                            && mWifiManager.getConnectionInfo().getBSSID() != null)) {
-                        if (DEBUG) {
-                            Log.d(TAG, "SIM ready and in service: subId=" + subId + ", ss=" + ss);
-                        }
-                        anySimReadyAndInService = true;
-                    }
-                }
-            }
-        }
-        // Only create "No SIM card" if no cards with CarrierName && no wifi when some sim is READY
-        // This condition will also be true always when numSubs == 0
-        if (allSimsMissing && !anySimReadyAndInService) {
-            if (numSubs != 0) {
-                // Shows "No SIM card | Emergency calls only" on devices that are voice-capable.
-                // This depends on mPlmn containing the text "Emergency calls only" when the radio
-                // has some connectivity. Otherwise, it should be null or empty and just show
-                // "No SIM card"
-                // Grab the first subscripton, because they all should contain the emergency text,
-                // described above.
-                displayText = makeCarrierStringOnEmergencyCapable(
-                        getMissingSimMessage(), subs.get(0).getCarrierName());
-            } else {
-                // We don't have a SubscriptionInfo to get the emergency calls only from.
-                // Grab it from the old sticky broadcast if possible instead. We can use it
-                // here because no subscriptions are active, so we don't have
-                // to worry about MSIM clashing.
-                CharSequence text =
-                        getContext().getText(com.android.internal.R.string.emergency_calls_only);
-                Intent i = getContext().registerReceiver(null,
-                        new IntentFilter(TelephonyManager.ACTION_SERVICE_PROVIDERS_UPDATED));
-                if (i != null) {
-                    String spn = "";
-                    String plmn = "";
-                    if (i.getBooleanExtra(TelephonyManager.EXTRA_SHOW_SPN, false)) {
-                        spn = i.getStringExtra(TelephonyManager.EXTRA_SPN);
-                    }
-                    if (i.getBooleanExtra(TelephonyManager.EXTRA_SHOW_PLMN, false)) {
-                        plmn = i.getStringExtra(TelephonyManager.EXTRA_PLMN);
-                    }
-                    if (DEBUG) Log.d(TAG, "Getting plmn/spn sticky brdcst " + plmn + "/" + spn);
-                    if (Objects.equals(plmn, spn)) {
-                        text = plmn;
-                    } else {
-                        text = concatenate(plmn, spn, mSeparator);
-                    }
-                }
-                displayText = makeCarrierStringOnEmergencyCapable(getMissingSimMessage(), text);
-            }
-        }
-
-        if (TextUtils.isEmpty(displayText)) displayText = joinNotEmpty(mSeparator, carrierNames);
-
-        displayText = updateCarrierTextWithSimIoError(displayText, carrierNames, subOrderBySlot,
-                allSimsMissing);
-
-        boolean airplaneMode = false;
-        // APM (airplane mode) != no carrier state. There are carrier services
-        // (e.g. WFC = Wi-Fi calling) which may operate in APM.
-        if (!anySimReadyAndInService && WirelessUtils.isAirplaneModeOn(mContext)) {
-            displayText = getAirplaneModeMessage();
-            airplaneMode = true;
-        }
-
-        final CarrierTextCallbackInfo info = new CarrierTextCallbackInfo(
-                displayText,
-                carrierNames,
-                !allSimsMissing,
-                subsIds,
-                airplaneMode);
-        postToCallback(info);
-    }
-
-    @VisibleForTesting
-    protected void postToCallback(CarrierTextCallbackInfo info) {
-        final CarrierTextCallback callback = mCarrierTextCallback;
-        if (callback != null) {
-            mMainHandler.post(() -> callback.updateCarrierInfo(info));
-        }
-    }
-
-    private Context getContext() {
-        return mContext;
-    }
-
-    private String getMissingSimMessage() {
-        return mShowMissingSim && mTelephonyCapable
-                ? getContext().getString(R.string.keyguard_missing_sim_message_short) : "";
-    }
-
-    private String getAirplaneModeMessage() {
-        return mShowAirplaneMode
-                ? getContext().getString(R.string.airplane_mode) : "";
-    }
-
-    /**
-     * Top-level function for creating carrier text. Makes text based on simState, PLMN
-     * and SPN as well as device capabilities, such as being emergency call capable.
-     *
-     * @return Carrier text if not in missing state, null otherwise.
-     */
-    private CharSequence getCarrierTextForSimState(int simState, CharSequence text) {
-        CharSequence carrierText = null;
-        CarrierTextController.StatusMode status = getStatusForIccState(simState);
-        switch (status) {
-            case Normal:
-                carrierText = text;
-                break;
-
-            case SimNotReady:
-                // Null is reserved for denoting missing, in this case we have nothing to display.
-                carrierText = ""; // nothing to display yet.
-                break;
-
-            case NetworkLocked:
-                carrierText = makeCarrierStringOnEmergencyCapable(
-                        mContext.getText(R.string.keyguard_network_locked_message), text);
-                break;
-
-            case SimMissing:
-                carrierText = null;
-                break;
-
-            case SimPermDisabled:
-                carrierText = makeCarrierStringOnEmergencyCapable(
-                        getContext().getText(
-                                R.string.keyguard_permanent_disabled_sim_message_short),
-                        text);
-                break;
-
-            case SimMissingLocked:
-                carrierText = null;
-                break;
-
-            case SimLocked:
-                carrierText = makeCarrierStringOnLocked(
-                        getContext().getText(R.string.keyguard_sim_locked_message),
-                        text);
-                break;
-
-            case SimPukLocked:
-                carrierText = makeCarrierStringOnLocked(
-                        getContext().getText(R.string.keyguard_sim_puk_locked_message),
-                        text);
-                break;
-            case SimIoError:
-                carrierText = makeCarrierStringOnEmergencyCapable(
-                        getContext().getText(R.string.keyguard_sim_error_message_short),
-                        text);
-                break;
-            case SimUnknown:
-                carrierText = null;
-                break;
-        }
-
-        return carrierText;
-    }
-
-    /*
-     * Add emergencyCallMessage to carrier string only if phone supports emergency calls.
-     */
-    private CharSequence makeCarrierStringOnEmergencyCapable(
-            CharSequence simMessage, CharSequence emergencyCallMessage) {
-        if (mIsEmergencyCallCapable) {
-            return concatenate(simMessage, emergencyCallMessage, mSeparator);
-        }
-        return simMessage;
-    }
-
-    /*
-     * Add "SIM card is locked" in parenthesis after carrier name, so it is easily associated in
-     * DSDS
-     */
-    private CharSequence makeCarrierStringOnLocked(CharSequence simMessage,
-            CharSequence carrierName) {
-        final boolean simMessageValid = !TextUtils.isEmpty(simMessage);
-        final boolean carrierNameValid = !TextUtils.isEmpty(carrierName);
-        if (simMessageValid && carrierNameValid) {
-            return mContext.getString(R.string.keyguard_carrier_name_with_sim_locked_template,
-                    carrierName, simMessage);
-        } else if (simMessageValid) {
-            return simMessage;
-        } else if (carrierNameValid) {
-            return carrierName;
-        } else {
-            return "";
-        }
-    }
-
-    /**
-     * Determine the current status of the lock screen given the SIM state and other stuff.
-     */
-    private CarrierTextController.StatusMode getStatusForIccState(int simState) {
-        final boolean missingAndNotProvisioned =
-                !mKeyguardUpdateMonitor.isDeviceProvisioned()
-                        && (simState == TelephonyManager.SIM_STATE_ABSENT
-                        || simState == TelephonyManager.SIM_STATE_PERM_DISABLED);
-
-        // Assume we're NETWORK_LOCKED if not provisioned
-        simState = missingAndNotProvisioned ? TelephonyManager.SIM_STATE_NETWORK_LOCKED : simState;
-        switch (simState) {
-            case TelephonyManager.SIM_STATE_ABSENT:
-                return CarrierTextController.StatusMode.SimMissing;
-            case TelephonyManager.SIM_STATE_NETWORK_LOCKED:
-                return CarrierTextController.StatusMode.SimMissingLocked;
-            case TelephonyManager.SIM_STATE_NOT_READY:
-                return CarrierTextController.StatusMode.SimNotReady;
-            case TelephonyManager.SIM_STATE_PIN_REQUIRED:
-                return CarrierTextController.StatusMode.SimLocked;
-            case TelephonyManager.SIM_STATE_PUK_REQUIRED:
-                return CarrierTextController.StatusMode.SimPukLocked;
-            case TelephonyManager.SIM_STATE_READY:
-                return CarrierTextController.StatusMode.Normal;
-            case TelephonyManager.SIM_STATE_PERM_DISABLED:
-                return CarrierTextController.StatusMode.SimPermDisabled;
-            case TelephonyManager.SIM_STATE_UNKNOWN:
-                return CarrierTextController.StatusMode.SimUnknown;
-            case TelephonyManager.SIM_STATE_CARD_IO_ERROR:
-                return CarrierTextController.StatusMode.SimIoError;
-        }
-        return CarrierTextController.StatusMode.SimUnknown;
-    }
-
-    private static CharSequence concatenate(CharSequence plmn, CharSequence spn,
-            CharSequence separator) {
-        final boolean plmnValid = !TextUtils.isEmpty(plmn);
-        final boolean spnValid = !TextUtils.isEmpty(spn);
-        if (plmnValid && spnValid) {
-            return new StringBuilder().append(plmn).append(separator).append(spn).toString();
-        } else if (plmnValid) {
-            return plmn;
-        } else if (spnValid) {
-            return spn;
-        } else {
-            return "";
-        }
-    }
-
-    /**
-     * Joins the strings in a sequence using a separator. Empty strings are discarded with no extra
-     * separator added so there are no extra separators that are not needed.
-     */
-    private static CharSequence joinNotEmpty(CharSequence separator, CharSequence[] sequences) {
-        int length = sequences.length;
-        if (length == 0) return "";
-        StringBuilder sb = new StringBuilder();
-        for (int i = 0; i < length; i++) {
-            if (!TextUtils.isEmpty(sequences[i])) {
-                if (!TextUtils.isEmpty(sb)) {
-                    sb.append(separator);
-                }
-                sb.append(sequences[i]);
-            }
-        }
-        return sb.toString();
-    }
-
-    private static List<CharSequence> append(List<CharSequence> list, CharSequence string) {
-        if (!TextUtils.isEmpty(string)) {
-            list.add(string);
-        }
-        return list;
-    }
-
-    private CharSequence getCarrierHelpTextForSimState(int simState,
-            String plmn, String spn) {
-        int carrierHelpTextId = 0;
-        CarrierTextController.StatusMode status = getStatusForIccState(simState);
-        switch (status) {
-            case NetworkLocked:
-                carrierHelpTextId = R.string.keyguard_instructions_when_pattern_disabled;
-                break;
-
-            case SimMissing:
-                carrierHelpTextId = R.string.keyguard_missing_sim_instructions_long;
-                break;
-
-            case SimPermDisabled:
-                carrierHelpTextId = R.string.keyguard_permanent_disabled_sim_instructions;
-                break;
-
-            case SimMissingLocked:
-                carrierHelpTextId = R.string.keyguard_missing_sim_instructions;
-                break;
-
-            case Normal:
-            case SimLocked:
-            case SimPukLocked:
-                break;
-        }
-
-        return mContext.getText(carrierHelpTextId);
-    }
-
-    public static class Builder {
-        private final Context mContext;
-        private final String mSeparator;
-        private boolean mShowAirplaneMode;
-        private boolean mShowMissingSim;
-
-        @Inject
-        public Builder(Context context, @Main Resources resources) {
-            mContext = context;
-            mSeparator = resources.getString(
-                    com.android.internal.R.string.kg_text_message_separator);
-        }
-
-
-        public Builder setShowAirplaneMode(boolean showAirplaneMode) {
-            mShowAirplaneMode = showAirplaneMode;
-            return this;
-        }
-
-        public Builder setShowMissingSim(boolean showMissingSim) {
-            mShowMissingSim = showMissingSim;
-            return this;
-        }
-
-        public CarrierTextController build() {
-            return new CarrierTextController(
-                    mContext, mSeparator, mShowAirplaneMode, mShowMissingSim);
-        }
-    }
-    /**
-     * Data structure for passing information to CarrierTextController subscribers
-     */
-    public static final class CarrierTextCallbackInfo {
-        public final CharSequence carrierText;
-        public final CharSequence[] listOfCarriers;
-        public final boolean anySimReady;
-        public final int[] subscriptionIds;
-        public boolean airplaneMode;
-
-        @VisibleForTesting
-        public CarrierTextCallbackInfo(CharSequence carrierText, CharSequence[] listOfCarriers,
-                boolean anySimReady, int[] subscriptionIds) {
-            this(carrierText, listOfCarriers, anySimReady, subscriptionIds, false);
-        }
-
-        @VisibleForTesting
-        public CarrierTextCallbackInfo(CharSequence carrierText, CharSequence[] listOfCarriers,
-                boolean anySimReady, int[] subscriptionIds, boolean airplaneMode) {
-            this.carrierText = carrierText;
-            this.listOfCarriers = listOfCarriers;
-            this.anySimReady = anySimReady;
-            this.subscriptionIds = subscriptionIds;
-            this.airplaneMode = airplaneMode;
-        }
-    }
-
-    /**
-     * Callback to communicate to Views
-     */
-    public interface CarrierTextCallback {
-        /**
-         * Provides updated carrier information.
-         */
-        default void updateCarrierInfo(CarrierTextCallbackInfo info) {};
-
-        /**
-         * Notifies the View that the device is going to sleep
-         */
-        default void startedGoingToSleep() {};
-
-        /**
-         * Notifies the View that the device finished waking up
-         */
-        default void finishedWakingUp() {};
+    @Override
+    protected void onViewDetached() {
+        mCarrierTextManager.setListening(null);
     }
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java b/packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java
new file mode 100644
index 0000000..cfef6cb
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java
@@ -0,0 +1,731 @@
+/*
+ * 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.keyguard;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.net.wifi.WifiManager;
+import android.telephony.ServiceState;
+import android.telephony.SubscriptionInfo;
+import android.telephony.TelephonyCallback.ActiveDataSubscriptionIdListener;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+import android.util.Log;
+
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
+
+import com.android.settingslib.WirelessUtils;
+import com.android.systemui.R;
+import com.android.systemui.dagger.qualifiers.Background;
+import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.keyguard.WakefulnessLifecycle;
+import com.android.systemui.telephony.TelephonyListenerManager;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import javax.inject.Inject;
+
+/**
+ * Controller that generates text including the carrier names and/or the status of all the SIM
+ * interfaces in the device. Through a callback, the updates can be retrieved either as a list or
+ * separated by a given separator {@link CharSequence}.
+ */
+public class CarrierTextManager {
+    private static final boolean DEBUG = KeyguardConstants.DEBUG;
+    private static final String TAG = "CarrierTextController";
+
+    private final boolean mIsEmergencyCallCapable;
+    private final Executor mMainExecutor;
+    private final Executor mBgExecutor;
+    private boolean mTelephonyCapable;
+    private final boolean mShowMissingSim;
+    private final boolean mShowAirplaneMode;
+    private final AtomicBoolean mNetworkSupported = new AtomicBoolean();
+    @VisibleForTesting
+    protected KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+    private final WifiManager mWifiManager;
+    private final boolean[] mSimErrorState;
+    private final int mSimSlotsNumber;
+    @Nullable // Check for nullability before dispatching
+    private CarrierTextCallback mCarrierTextCallback;
+    private final Context mContext;
+    private final TelephonyManager mTelephonyManager;
+    private final CharSequence mSeparator;
+    private final TelephonyListenerManager mTelephonyListenerManager;
+    private final WakefulnessLifecycle mWakefulnessLifecycle;
+    private final WakefulnessLifecycle.Observer mWakefulnessObserver =
+            new WakefulnessLifecycle.Observer() {
+                @Override
+                public void onFinishedWakingUp() {
+                    final CarrierTextCallback callback = mCarrierTextCallback;
+                    if (callback != null) callback.finishedWakingUp();
+                }
+
+                @Override
+                public void onStartedGoingToSleep() {
+                    final CarrierTextCallback callback = mCarrierTextCallback;
+                    if (callback != null) callback.startedGoingToSleep();
+                }
+            };
+
+    @VisibleForTesting
+    protected final KeyguardUpdateMonitorCallback mCallback = new KeyguardUpdateMonitorCallback() {
+        @Override
+        public void onRefreshCarrierInfo() {
+            if (DEBUG) {
+                Log.d(TAG, "onRefreshCarrierInfo(), mTelephonyCapable: "
+                        + Boolean.toString(mTelephonyCapable));
+            }
+            updateCarrierText();
+        }
+
+        @Override
+        public void onTelephonyCapable(boolean capable) {
+            if (DEBUG) {
+                Log.d(TAG, "onTelephonyCapable() mTelephonyCapable: "
+                        + Boolean.toString(capable));
+            }
+            mTelephonyCapable = capable;
+            updateCarrierText();
+        }
+
+        public void onSimStateChanged(int subId, int slotId, int simState) {
+            if (slotId < 0 || slotId >= mSimSlotsNumber) {
+                Log.d(TAG, "onSimStateChanged() - slotId invalid: " + slotId
+                        + " mTelephonyCapable: " + Boolean.toString(mTelephonyCapable));
+                return;
+            }
+
+            if (DEBUG) Log.d(TAG, "onSimStateChanged: " + getStatusForIccState(simState));
+            if (getStatusForIccState(simState) == CarrierTextManager.StatusMode.SimIoError) {
+                mSimErrorState[slotId] = true;
+                updateCarrierText();
+            } else if (mSimErrorState[slotId]) {
+                mSimErrorState[slotId] = false;
+                updateCarrierText();
+            }
+        }
+    };
+
+    private final ActiveDataSubscriptionIdListener mPhoneStateListener =
+            new ActiveDataSubscriptionIdListener() {
+        @Override
+        public void onActiveDataSubscriptionIdChanged(int subId) {
+            if (mNetworkSupported.get() && mCarrierTextCallback != null) {
+                updateCarrierText();
+            }
+        }
+    };
+
+    /**
+     * The status of this lock screen. Primarily used for widgets on LockScreen.
+     */
+    private enum StatusMode {
+        Normal, // Normal case (sim card present, it's not locked)
+        NetworkLocked, // SIM card is 'network locked'.
+        SimMissing, // SIM card is missing.
+        SimMissingLocked, // SIM card is missing, and device isn't provisioned; don't allow access
+        SimPukLocked, // SIM card is PUK locked because SIM entered wrong too many times
+        SimLocked, // SIM card is currently locked
+        SimPermDisabled, // SIM card is permanently disabled due to PUK unlock failure
+        SimNotReady, // SIM is not ready yet. May never be on devices w/o a SIM.
+        SimIoError, // SIM card is faulty
+        SimUnknown // SIM card is unknown
+    }
+
+    /**
+     * Controller that provides updates on text with carriers names or SIM status.
+     * Used by {@link CarrierText}.
+     *
+     * @param separator Separator between different parts of the text
+     */
+    private CarrierTextManager(
+            Context context,
+            CharSequence separator,
+            boolean showAirplaneMode,
+            boolean showMissingSim,
+            @Nullable WifiManager wifiManager,
+            TelephonyManager telephonyManager,
+            TelephonyListenerManager telephonyListenerManager,
+            WakefulnessLifecycle wakefulnessLifecycle,
+            @Main Executor mainExecutor,
+            @Background Executor bgExecutor,
+            KeyguardUpdateMonitor keyguardUpdateMonitor) {
+        mContext = context;
+        mIsEmergencyCallCapable = telephonyManager.isVoiceCapable();
+
+        mShowAirplaneMode = showAirplaneMode;
+        mShowMissingSim = showMissingSim;
+
+        mWifiManager = wifiManager;
+        mTelephonyManager = telephonyManager;
+        mSeparator = separator;
+        mTelephonyListenerManager = telephonyListenerManager;
+        mWakefulnessLifecycle = wakefulnessLifecycle;
+        mSimSlotsNumber = getTelephonyManager().getSupportedModemCount();
+        mSimErrorState = new boolean[mSimSlotsNumber];
+        mMainExecutor = mainExecutor;
+        mBgExecutor = bgExecutor;
+        mKeyguardUpdateMonitor = keyguardUpdateMonitor;
+        mBgExecutor.execute(() -> {
+            boolean supported = mContext.getPackageManager()
+                    .hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
+            if (supported && mNetworkSupported.compareAndSet(false, supported)) {
+                // This will set/remove the listeners appropriately. Note that it will never double
+                // add the listeners.
+                handleSetListening(mCarrierTextCallback);
+            }
+        });
+    }
+
+    private TelephonyManager getTelephonyManager() {
+        return mTelephonyManager;
+    }
+
+    /**
+     * Checks if there are faulty cards. Adds the text depending on the slot of the card
+     *
+     * @param text:   current carrier text based on the sim state
+     * @param carrierNames names order by subscription order
+     * @param subOrderBySlot array containing the sub index for each slot ID
+     * @param noSims: whether a valid sim card is inserted
+     * @return text
+     */
+    private CharSequence updateCarrierTextWithSimIoError(CharSequence text,
+            CharSequence[] carrierNames, int[] subOrderBySlot, boolean noSims) {
+        final CharSequence carrier = "";
+        CharSequence carrierTextForSimIOError = getCarrierTextForSimState(
+                TelephonyManager.SIM_STATE_CARD_IO_ERROR, carrier);
+        // mSimErrorState has the state of each sim indexed by slotID.
+        for (int index = 0; index < getTelephonyManager().getActiveModemCount(); index++) {
+            if (!mSimErrorState[index]) {
+                continue;
+            }
+            // In the case when no sim cards are detected but a faulty card is inserted
+            // overwrite the text and only show "Invalid card"
+            if (noSims) {
+                return concatenate(carrierTextForSimIOError,
+                        getContext().getText(
+                                com.android.internal.R.string.emergency_calls_only),
+                        mSeparator);
+            } else if (subOrderBySlot[index] != -1) {
+                int subIndex = subOrderBySlot[index];
+                // prepend "Invalid card" when faulty card is inserted in slot 0 or 1
+                carrierNames[subIndex] = concatenate(carrierTextForSimIOError,
+                        carrierNames[subIndex],
+                        mSeparator);
+            } else {
+                // concatenate "Invalid card" when faulty card is inserted in other slot
+                text = concatenate(text, carrierTextForSimIOError, mSeparator);
+            }
+
+        }
+        return text;
+    }
+
+    /**
+     * This may be called internally after retrieving the correct value of {@code mNetworkSupported}
+     * (assumed false to start). In that case, the following happens:
+     * <ul>
+     *     <li> If there was a registered callback, and the network is supported, it will register
+     *          listeners.
+     *     <li> If there was not a registered callback, it will try to remove unregistered listeners
+     *          which is a no-op
+     * </ul>
+     *
+     * This call will always be processed in a background thread.
+     */
+    private void handleSetListening(CarrierTextCallback callback) {
+        if (callback != null) {
+            mCarrierTextCallback = callback;
+            if (mNetworkSupported.get()) {
+                // Keyguard update monitor expects callbacks from main thread
+                mMainExecutor.execute(() -> mKeyguardUpdateMonitor.registerCallback(mCallback));
+                mWakefulnessLifecycle.addObserver(mWakefulnessObserver);
+                mTelephonyListenerManager.addActiveDataSubscriptionIdListener(mPhoneStateListener);
+            } else {
+                // Don't listen and clear out the text when the device isn't a phone.
+                mMainExecutor.execute(() -> callback.updateCarrierInfo(
+                        new CarrierTextCallbackInfo("", null, false, null)
+                ));
+            }
+        } else {
+            mCarrierTextCallback = null;
+            mMainExecutor.execute(() -> mKeyguardUpdateMonitor.removeCallback(mCallback));
+            mWakefulnessLifecycle.removeObserver(mWakefulnessObserver);
+            mTelephonyListenerManager.removeActiveDataSubscriptionIdListener(mPhoneStateListener);
+        }
+    }
+
+    /**
+     * Sets the listening status of this controller. If the callback is null, it is set to
+     * not listening.
+     *
+     * @param callback Callback to provide text updates
+     */
+    public void setListening(CarrierTextCallback callback) {
+        mBgExecutor.execute(() -> handleSetListening(callback));
+    }
+
+    protected List<SubscriptionInfo> getSubscriptionInfo() {
+        return mKeyguardUpdateMonitor.getFilteredSubscriptionInfo(false);
+    }
+
+    protected void updateCarrierText() {
+        boolean allSimsMissing = true;
+        boolean anySimReadyAndInService = false;
+        CharSequence displayText = null;
+        List<SubscriptionInfo> subs = getSubscriptionInfo();
+
+        final int numSubs = subs.size();
+        final int[] subsIds = new int[numSubs];
+        // This array will contain in position i, the index of subscription in slot ID i.
+        // -1 if no subscription in that slot
+        final int[] subOrderBySlot = new int[mSimSlotsNumber];
+        for (int i = 0; i < mSimSlotsNumber; i++) {
+            subOrderBySlot[i] = -1;
+        }
+        final CharSequence[] carrierNames = new CharSequence[numSubs];
+        if (DEBUG) Log.d(TAG, "updateCarrierText(): " + numSubs);
+
+        for (int i = 0; i < numSubs; i++) {
+            int subId = subs.get(i).getSubscriptionId();
+            carrierNames[i] = "";
+            subsIds[i] = subId;
+            subOrderBySlot[subs.get(i).getSimSlotIndex()] = i;
+            int simState = mKeyguardUpdateMonitor.getSimState(subId);
+            CharSequence carrierName = subs.get(i).getCarrierName();
+            CharSequence carrierTextForSimState = getCarrierTextForSimState(simState, carrierName);
+            if (DEBUG) {
+                Log.d(TAG, "Handling (subId=" + subId + "): " + simState + " " + carrierName);
+            }
+            if (carrierTextForSimState != null) {
+                allSimsMissing = false;
+                carrierNames[i] = carrierTextForSimState;
+            }
+            if (simState == TelephonyManager.SIM_STATE_READY) {
+                ServiceState ss = mKeyguardUpdateMonitor.mServiceStates.get(subId);
+                if (ss != null && ss.getDataRegistrationState() == ServiceState.STATE_IN_SERVICE) {
+                    // hack for WFC (IWLAN) not turning off immediately once
+                    // Wi-Fi is disassociated or disabled
+                    if (ss.getRilDataRadioTechnology() != ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN
+                            || (mWifiManager != null && mWifiManager.isWifiEnabled()
+                            && mWifiManager.getConnectionInfo() != null
+                            && mWifiManager.getConnectionInfo().getBSSID() != null)) {
+                        if (DEBUG) {
+                            Log.d(TAG, "SIM ready and in service: subId=" + subId + ", ss=" + ss);
+                        }
+                        anySimReadyAndInService = true;
+                    }
+                }
+            }
+        }
+        // Only create "No SIM card" if no cards with CarrierName && no wifi when some sim is READY
+        // This condition will also be true always when numSubs == 0
+        if (allSimsMissing && !anySimReadyAndInService) {
+            if (numSubs != 0) {
+                // Shows "No SIM card | Emergency calls only" on devices that are voice-capable.
+                // This depends on mPlmn containing the text "Emergency calls only" when the radio
+                // has some connectivity. Otherwise, it should be null or empty and just show
+                // "No SIM card"
+                // Grab the first subscripton, because they all should contain the emergency text,
+                // described above.
+                displayText = makeCarrierStringOnEmergencyCapable(
+                        getMissingSimMessage(), subs.get(0).getCarrierName());
+            } else {
+                // We don't have a SubscriptionInfo to get the emergency calls only from.
+                // Grab it from the old sticky broadcast if possible instead. We can use it
+                // here because no subscriptions are active, so we don't have
+                // to worry about MSIM clashing.
+                CharSequence text =
+                        getContext().getText(com.android.internal.R.string.emergency_calls_only);
+                Intent i = getContext().registerReceiver(null,
+                        new IntentFilter(TelephonyManager.ACTION_SERVICE_PROVIDERS_UPDATED));
+                if (i != null) {
+                    String spn = "";
+                    String plmn = "";
+                    if (i.getBooleanExtra(TelephonyManager.EXTRA_SHOW_SPN, false)) {
+                        spn = i.getStringExtra(TelephonyManager.EXTRA_SPN);
+                    }
+                    if (i.getBooleanExtra(TelephonyManager.EXTRA_SHOW_PLMN, false)) {
+                        plmn = i.getStringExtra(TelephonyManager.EXTRA_PLMN);
+                    }
+                    if (DEBUG) Log.d(TAG, "Getting plmn/spn sticky brdcst " + plmn + "/" + spn);
+                    if (Objects.equals(plmn, spn)) {
+                        text = plmn;
+                    } else {
+                        text = concatenate(plmn, spn, mSeparator);
+                    }
+                }
+                displayText = makeCarrierStringOnEmergencyCapable(getMissingSimMessage(), text);
+            }
+        }
+
+        if (TextUtils.isEmpty(displayText)) displayText = joinNotEmpty(mSeparator, carrierNames);
+
+        displayText = updateCarrierTextWithSimIoError(displayText, carrierNames, subOrderBySlot,
+                allSimsMissing);
+
+        boolean airplaneMode = false;
+        // APM (airplane mode) != no carrier state. There are carrier services
+        // (e.g. WFC = Wi-Fi calling) which may operate in APM.
+        if (!anySimReadyAndInService && WirelessUtils.isAirplaneModeOn(mContext)) {
+            displayText = getAirplaneModeMessage();
+            airplaneMode = true;
+        }
+
+        final CarrierTextCallbackInfo info = new CarrierTextCallbackInfo(
+                displayText,
+                carrierNames,
+                !allSimsMissing,
+                subsIds,
+                airplaneMode);
+        postToCallback(info);
+    }
+
+    @VisibleForTesting
+    protected void postToCallback(CarrierTextCallbackInfo info) {
+        final CarrierTextCallback callback = mCarrierTextCallback;
+        if (callback != null) {
+            mMainExecutor.execute(() -> callback.updateCarrierInfo(info));
+        }
+    }
+
+    private Context getContext() {
+        return mContext;
+    }
+
+    private String getMissingSimMessage() {
+        return mShowMissingSim && mTelephonyCapable
+                ? getContext().getString(R.string.keyguard_missing_sim_message_short) : "";
+    }
+
+    private String getAirplaneModeMessage() {
+        return mShowAirplaneMode
+                ? getContext().getString(R.string.airplane_mode) : "";
+    }
+
+    /**
+     * Top-level function for creating carrier text. Makes text based on simState, PLMN
+     * and SPN as well as device capabilities, such as being emergency call capable.
+     *
+     * @return Carrier text if not in missing state, null otherwise.
+     */
+    private CharSequence getCarrierTextForSimState(int simState, CharSequence text) {
+        CharSequence carrierText = null;
+        CarrierTextManager.StatusMode status = getStatusForIccState(simState);
+        switch (status) {
+            case Normal:
+                carrierText = text;
+                break;
+
+            case SimNotReady:
+                // Null is reserved for denoting missing, in this case we have nothing to display.
+                carrierText = ""; // nothing to display yet.
+                break;
+
+            case NetworkLocked:
+                carrierText = makeCarrierStringOnEmergencyCapable(
+                        mContext.getText(R.string.keyguard_network_locked_message), text);
+                break;
+
+            case SimMissing:
+                carrierText = null;
+                break;
+
+            case SimPermDisabled:
+                carrierText = makeCarrierStringOnEmergencyCapable(
+                        getContext().getText(
+                                R.string.keyguard_permanent_disabled_sim_message_short),
+                        text);
+                break;
+
+            case SimMissingLocked:
+                carrierText = null;
+                break;
+
+            case SimLocked:
+                carrierText = makeCarrierStringOnLocked(
+                        getContext().getText(R.string.keyguard_sim_locked_message),
+                        text);
+                break;
+
+            case SimPukLocked:
+                carrierText = makeCarrierStringOnLocked(
+                        getContext().getText(R.string.keyguard_sim_puk_locked_message),
+                        text);
+                break;
+            case SimIoError:
+                carrierText = makeCarrierStringOnEmergencyCapable(
+                        getContext().getText(R.string.keyguard_sim_error_message_short),
+                        text);
+                break;
+            case SimUnknown:
+                carrierText = null;
+                break;
+        }
+
+        return carrierText;
+    }
+
+    /*
+     * Add emergencyCallMessage to carrier string only if phone supports emergency calls.
+     */
+    private CharSequence makeCarrierStringOnEmergencyCapable(
+            CharSequence simMessage, CharSequence emergencyCallMessage) {
+        if (mIsEmergencyCallCapable) {
+            return concatenate(simMessage, emergencyCallMessage, mSeparator);
+        }
+        return simMessage;
+    }
+
+    /*
+     * Add "SIM card is locked" in parenthesis after carrier name, so it is easily associated in
+     * DSDS
+     */
+    private CharSequence makeCarrierStringOnLocked(CharSequence simMessage,
+            CharSequence carrierName) {
+        final boolean simMessageValid = !TextUtils.isEmpty(simMessage);
+        final boolean carrierNameValid = !TextUtils.isEmpty(carrierName);
+        if (simMessageValid && carrierNameValid) {
+            return mContext.getString(R.string.keyguard_carrier_name_with_sim_locked_template,
+                    carrierName, simMessage);
+        } else if (simMessageValid) {
+            return simMessage;
+        } else if (carrierNameValid) {
+            return carrierName;
+        } else {
+            return "";
+        }
+    }
+
+    /**
+     * Determine the current status of the lock screen given the SIM state and other stuff.
+     */
+    private CarrierTextManager.StatusMode getStatusForIccState(int simState) {
+        final boolean missingAndNotProvisioned =
+                !mKeyguardUpdateMonitor.isDeviceProvisioned()
+                        && (simState == TelephonyManager.SIM_STATE_ABSENT
+                        || simState == TelephonyManager.SIM_STATE_PERM_DISABLED);
+
+        // Assume we're NETWORK_LOCKED if not provisioned
+        simState = missingAndNotProvisioned ? TelephonyManager.SIM_STATE_NETWORK_LOCKED : simState;
+        switch (simState) {
+            case TelephonyManager.SIM_STATE_ABSENT:
+                return CarrierTextManager.StatusMode.SimMissing;
+            case TelephonyManager.SIM_STATE_NETWORK_LOCKED:
+                return CarrierTextManager.StatusMode.SimMissingLocked;
+            case TelephonyManager.SIM_STATE_NOT_READY:
+                return CarrierTextManager.StatusMode.SimNotReady;
+            case TelephonyManager.SIM_STATE_PIN_REQUIRED:
+                return CarrierTextManager.StatusMode.SimLocked;
+            case TelephonyManager.SIM_STATE_PUK_REQUIRED:
+                return CarrierTextManager.StatusMode.SimPukLocked;
+            case TelephonyManager.SIM_STATE_READY:
+                return CarrierTextManager.StatusMode.Normal;
+            case TelephonyManager.SIM_STATE_PERM_DISABLED:
+                return CarrierTextManager.StatusMode.SimPermDisabled;
+            case TelephonyManager.SIM_STATE_UNKNOWN:
+                return CarrierTextManager.StatusMode.SimUnknown;
+            case TelephonyManager.SIM_STATE_CARD_IO_ERROR:
+                return CarrierTextManager.StatusMode.SimIoError;
+        }
+        return CarrierTextManager.StatusMode.SimUnknown;
+    }
+
+    private static CharSequence concatenate(CharSequence plmn, CharSequence spn,
+            CharSequence separator) {
+        final boolean plmnValid = !TextUtils.isEmpty(plmn);
+        final boolean spnValid = !TextUtils.isEmpty(spn);
+        if (plmnValid && spnValid) {
+            return new StringBuilder().append(plmn).append(separator).append(spn).toString();
+        } else if (plmnValid) {
+            return plmn;
+        } else if (spnValid) {
+            return spn;
+        } else {
+            return "";
+        }
+    }
+
+    /**
+     * Joins the strings in a sequence using a separator. Empty strings are discarded with no extra
+     * separator added so there are no extra separators that are not needed.
+     */
+    private static CharSequence joinNotEmpty(CharSequence separator, CharSequence[] sequences) {
+        int length = sequences.length;
+        if (length == 0) return "";
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < length; i++) {
+            if (!TextUtils.isEmpty(sequences[i])) {
+                if (!TextUtils.isEmpty(sb)) {
+                    sb.append(separator);
+                }
+                sb.append(sequences[i]);
+            }
+        }
+        return sb.toString();
+    }
+
+    private static List<CharSequence> append(List<CharSequence> list, CharSequence string) {
+        if (!TextUtils.isEmpty(string)) {
+            list.add(string);
+        }
+        return list;
+    }
+
+    private CharSequence getCarrierHelpTextForSimState(int simState,
+            String plmn, String spn) {
+        int carrierHelpTextId = 0;
+        CarrierTextManager.StatusMode status = getStatusForIccState(simState);
+        switch (status) {
+            case NetworkLocked:
+                carrierHelpTextId = R.string.keyguard_instructions_when_pattern_disabled;
+                break;
+
+            case SimMissing:
+                carrierHelpTextId = R.string.keyguard_missing_sim_instructions_long;
+                break;
+
+            case SimPermDisabled:
+                carrierHelpTextId = R.string.keyguard_permanent_disabled_sim_instructions;
+                break;
+
+            case SimMissingLocked:
+                carrierHelpTextId = R.string.keyguard_missing_sim_instructions;
+                break;
+
+            case Normal:
+            case SimLocked:
+            case SimPukLocked:
+                break;
+        }
+
+        return mContext.getText(carrierHelpTextId);
+    }
+
+    /** Injectable Buildeer for {@#link CarrierTextManager}. */
+    public static class Builder {
+        private final Context mContext;
+        private final String mSeparator;
+        private final WifiManager mWifiManager;
+        private final TelephonyManager mTelephonyManager;
+        private final TelephonyListenerManager mTelephonyListenerManager;
+        private final WakefulnessLifecycle mWakefulnessLifecycle;
+        private final Executor mMainExecutor;
+        private final Executor mBgExecutor;
+        private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+        private boolean mShowAirplaneMode;
+        private boolean mShowMissingSim;
+
+        @Inject
+        public Builder(
+                Context context,
+                @Main Resources resources,
+                @Nullable WifiManager wifiManager,
+                TelephonyManager telephonyManager,
+                TelephonyListenerManager telephonyListenerManager,
+                WakefulnessLifecycle wakefulnessLifecycle,
+                @Main Executor mainExecutor,
+                @Background Executor bgExecutor,
+                KeyguardUpdateMonitor keyguardUpdateMonitor) {
+            mContext = context;
+            mSeparator = resources.getString(
+                    com.android.internal.R.string.kg_text_message_separator);
+            mWifiManager = wifiManager;
+            mTelephonyManager = telephonyManager;
+            mTelephonyListenerManager = telephonyListenerManager;
+            mWakefulnessLifecycle = wakefulnessLifecycle;
+            mMainExecutor = mainExecutor;
+            mBgExecutor = bgExecutor;
+            mKeyguardUpdateMonitor = keyguardUpdateMonitor;
+        }
+
+        /** */
+        public Builder setShowAirplaneMode(boolean showAirplaneMode) {
+            mShowAirplaneMode = showAirplaneMode;
+            return this;
+        }
+
+        /** */
+        public Builder setShowMissingSim(boolean showMissingSim) {
+            mShowMissingSim = showMissingSim;
+            return this;
+        }
+
+        /** Create a CarrierTextManager. */
+        public CarrierTextManager build() {
+            return new CarrierTextManager(
+                    mContext, mSeparator, mShowAirplaneMode, mShowMissingSim, mWifiManager,
+                    mTelephonyManager, mTelephonyListenerManager, mWakefulnessLifecycle,
+                    mMainExecutor, mBgExecutor, mKeyguardUpdateMonitor);
+        }
+    }
+    /**
+     * Data structure for passing information to CarrierTextController subscribers
+     */
+    public static final class CarrierTextCallbackInfo {
+        public final CharSequence carrierText;
+        public final CharSequence[] listOfCarriers;
+        public final boolean anySimReady;
+        public final int[] subscriptionIds;
+        public boolean airplaneMode;
+
+        @VisibleForTesting
+        public CarrierTextCallbackInfo(CharSequence carrierText, CharSequence[] listOfCarriers,
+                boolean anySimReady, int[] subscriptionIds) {
+            this(carrierText, listOfCarriers, anySimReady, subscriptionIds, false);
+        }
+
+        @VisibleForTesting
+        public CarrierTextCallbackInfo(CharSequence carrierText, CharSequence[] listOfCarriers,
+                boolean anySimReady, int[] subscriptionIds, boolean airplaneMode) {
+            this.carrierText = carrierText;
+            this.listOfCarriers = listOfCarriers;
+            this.anySimReady = anySimReady;
+            this.subscriptionIds = subscriptionIds;
+            this.airplaneMode = airplaneMode;
+        }
+    }
+
+    /**
+     * Callback to communicate to Views
+     */
+    public interface CarrierTextCallback {
+        /**
+         * Provides updated carrier information.
+         */
+        default void updateCarrierInfo(CarrierTextCallbackInfo info) {};
+
+        /**
+         * Notifies the View that the device is going to sleep
+         */
+        default void startedGoingToSleep() {};
+
+        /**
+         * Notifies the View that the device finished waking up
+         */
+        default void finishedWakingUp() {};
+    }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java b/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java
index 707ee29..c4b02f6 100644
--- a/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java
+++ b/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java
@@ -16,34 +16,16 @@
 
 package com.android.keyguard;
 
-import static com.android.systemui.DejankUtils.whitelistIpcs;
-
-import android.app.ActivityOptions;
-import android.app.ActivityTaskManager;
 import android.content.Context;
-import android.content.Intent;
-import android.content.res.Configuration;
-import android.os.PowerManager;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.os.UserHandle;
-import android.telecom.TelecomManager;
-import android.telephony.TelephonyManager;
 import android.util.AttributeSet;
-import android.util.Log;
-import android.util.Slog;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewConfiguration;
 import android.widget.Button;
 
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.util.EmergencyAffordanceManager;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.settingslib.Utils;
-import com.android.systemui.Dependency;
-import com.android.systemui.util.EmergencyDialerConstants;
 
 /**
  * This class implements a smart emergency button that updates itself based
@@ -53,34 +35,14 @@
  */
 public class EmergencyButton extends Button {
 
-    private static final String LOG_TAG = "EmergencyButton";
     private final EmergencyAffordanceManager mEmergencyAffordanceManager;
 
     private int mDownX;
     private int mDownY;
-    KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() {
-
-        @Override
-        public void onSimStateChanged(int subId, int slotId, int simState) {
-            updateEmergencyCallButton();
-        }
-
-        @Override
-        public void onPhoneStateChanged(int phoneState) {
-            updateEmergencyCallButton();
-        }
-    };
     private boolean mLongPressWasDragged;
 
-    public interface EmergencyButtonCallback {
-        public void onEmergencyButtonClickedWhenInCall();
-    }
-
     private LockPatternUtils mLockPatternUtils;
-    private PowerManager mPowerManager;
-    private EmergencyButtonCallback mEmergencyButtonCallback;
 
-    private final boolean mIsVoiceCapable;
     private final boolean mEnableEmergencyCallWhileSimLocked;
 
     public EmergencyButton(Context context) {
@@ -89,34 +51,15 @@
 
     public EmergencyButton(Context context, AttributeSet attrs) {
         super(context, attrs);
-        mIsVoiceCapable = getTelephonyManager().isVoiceCapable();
         mEnableEmergencyCallWhileSimLocked = mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_enable_emergency_call_while_sim_locked);
         mEmergencyAffordanceManager = new EmergencyAffordanceManager(context);
     }
 
-    private TelephonyManager getTelephonyManager() {
-        return (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
-    }
-
-    @Override
-    protected void onAttachedToWindow() {
-        super.onAttachedToWindow();
-        Dependency.get(KeyguardUpdateMonitor.class).registerCallback(mInfoCallback);
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-        Dependency.get(KeyguardUpdateMonitor.class).removeCallback(mInfoCallback);
-    }
-
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
         mLockPatternUtils = new LockPatternUtils(mContext);
-        mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
-        setOnClickListener(v -> takeEmergencyCallAction());
         if (mEmergencyAffordanceManager.needsEmergencyAffordance()) {
             setOnLongClickListener(v -> {
                 if (!mLongPressWasDragged
@@ -127,7 +70,6 @@
                 return false;
             });
         }
-        whitelistIpcs(this::updateEmergencyCallButton);
     }
 
     @Override
@@ -165,65 +107,13 @@
         return super.performLongClick();
     }
 
-    @Override
-    protected void onConfigurationChanged(Configuration newConfig) {
-        super.onConfigurationChanged(newConfig);
-        updateEmergencyCallButton();
-    }
-
-    /**
-     * Shows the emergency dialer or returns the user to the existing call.
-     */
-    public void takeEmergencyCallAction() {
-        MetricsLogger.action(mContext, MetricsEvent.ACTION_EMERGENCY_CALL);
-        if (mPowerManager != null) {
-            mPowerManager.userActivity(SystemClock.uptimeMillis(), true);
-        }
-        try {
-            ActivityTaskManager.getService().stopSystemLockTaskMode();
-        } catch (RemoteException e) {
-            Slog.w(LOG_TAG, "Failed to stop app pinning");
-        }
-        if (isInCall()) {
-            resumeCall();
-            if (mEmergencyButtonCallback != null) {
-                mEmergencyButtonCallback.onEmergencyButtonClickedWhenInCall();
-            }
-        } else {
-            KeyguardUpdateMonitor updateMonitor = Dependency.get(KeyguardUpdateMonitor.class);
-            if (updateMonitor != null) {
-                updateMonitor.reportEmergencyCallAction(true /* bypassHandler */);
-            } else {
-                Log.w(LOG_TAG, "KeyguardUpdateMonitor was null, launching intent anyway.");
-            }
-            TelecomManager telecomManager = getTelecommManager();
-            if (telecomManager == null) {
-                Log.wtf(LOG_TAG, "TelecomManager was null, cannot launch emergency dialer");
-                return;
-            }
-            Intent emergencyDialIntent =
-                    telecomManager.createLaunchEmergencyDialerIntent(null /* number*/)
-                            .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
-                                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
-                                    | Intent.FLAG_ACTIVITY_CLEAR_TOP)
-                            .putExtra(EmergencyDialerConstants.EXTRA_ENTRY_TYPE,
-                                    EmergencyDialerConstants.ENTRY_TYPE_LOCKSCREEN_BUTTON);
-
-            getContext().startActivityAsUser(emergencyDialIntent,
-                    ActivityOptions.makeCustomAnimation(getContext(), 0, 0).toBundle(),
-                    new UserHandle(KeyguardUpdateMonitor.getCurrentUser()));
-        }
-    }
-
-    private void updateEmergencyCallButton() {
+    void updateEmergencyCallButton(boolean isInCall, boolean isVoiceCapable, boolean simLocked) {
         boolean visible = false;
-        if (mIsVoiceCapable) {
+        if (isVoiceCapable) {
             // Emergency calling requires voice capability.
-            if (isInCall()) {
+            if (isInCall) {
                 visible = true; // always show "return to call" if phone is off-hook
             } else {
-                final boolean simLocked = Dependency.get(KeyguardUpdateMonitor.class)
-                        .isSimPinVoiceSecure();
                 if (simLocked) {
                     // Some countries can't handle emergency calls while SIM is locked.
                     visible = mEnableEmergencyCallWhileSimLocked;
@@ -237,7 +127,7 @@
             setVisibility(View.VISIBLE);
 
             int textId;
-            if (isInCall()) {
+            if (isInCall) {
                 textId = com.android.internal.R.string.lockscreen_return_to_call;
             } else {
                 textId = com.android.internal.R.string.lockscreen_emergency_call;
@@ -247,26 +137,4 @@
             setVisibility(View.GONE);
         }
     }
-
-    public void setCallback(EmergencyButtonCallback callback) {
-        mEmergencyButtonCallback = callback;
-    }
-
-    /**
-     * Resumes a call in progress.
-     */
-    private void resumeCall() {
-        getTelecommManager().showInCallScreen(false);
-    }
-
-    /**
-     * @return {@code true} if there is a call currently in progress.
-     */
-    private boolean isInCall() {
-        return getTelecommManager().isInCall();
-    }
-
-    private TelecomManager getTelecommManager() {
-        return (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
-    }
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/EmergencyButtonController.java b/packages/SystemUI/src/com/android/keyguard/EmergencyButtonController.java
new file mode 100644
index 0000000..4275189
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/EmergencyButtonController.java
@@ -0,0 +1,196 @@
+/*
+ * 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 com.android.systemui.DejankUtils.whitelistIpcs;
+
+import android.app.ActivityOptions;
+import android.app.ActivityTaskManager;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.os.PowerManager;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.telecom.TelecomManager;
+import android.telephony.TelephonyManager;
+import android.util.Log;
+
+import androidx.annotation.Nullable;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.keyguard.dagger.KeyguardBouncerScope;
+import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
+import com.android.systemui.util.EmergencyDialerConstants;
+import com.android.systemui.util.ViewController;
+
+import javax.inject.Inject;
+
+/** View Controller for {@link com.android.keyguard.EmergencyButton}. */
+@KeyguardBouncerScope
+public class EmergencyButtonController extends ViewController<EmergencyButton> {
+    static final String LOG_TAG = "EmergencyButton";
+    private final ConfigurationController mConfigurationController;
+    private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+    private final TelephonyManager mTelephonyManager;
+    private final PowerManager mPowerManager;
+    private final ActivityTaskManager mActivityTaskManager;
+    private final TelecomManager mTelecomManager;
+    private final MetricsLogger mMetricsLogger;
+
+    private EmergencyButtonCallback mEmergencyButtonCallback;
+
+    private final KeyguardUpdateMonitorCallback mInfoCallback =
+            new KeyguardUpdateMonitorCallback() {
+        @Override
+        public void onSimStateChanged(int subId, int slotId, int simState) {
+            updateEmergencyCallButton();
+        }
+
+        @Override
+        public void onPhoneStateChanged(int phoneState) {
+            updateEmergencyCallButton();
+        }
+    };
+
+    private final ConfigurationListener mConfigurationListener = new ConfigurationListener() {
+        @Override
+        public void onConfigChanged(Configuration newConfig) {
+            updateEmergencyCallButton();
+        }
+    };
+
+    private EmergencyButtonController(@Nullable EmergencyButton view,
+            ConfigurationController configurationController,
+            KeyguardUpdateMonitor keyguardUpdateMonitor, TelephonyManager telephonyManager,
+            PowerManager powerManager, ActivityTaskManager activityTaskManager,
+            @Nullable TelecomManager telecomManager, MetricsLogger metricsLogger) {
+        super(view);
+        mConfigurationController = configurationController;
+        mKeyguardUpdateMonitor = keyguardUpdateMonitor;
+        mTelephonyManager = telephonyManager;
+        mPowerManager = powerManager;
+        mActivityTaskManager = activityTaskManager;
+        mTelecomManager = telecomManager;
+        mMetricsLogger = metricsLogger;
+    }
+
+    @Override
+    protected void onInit() {
+        whitelistIpcs(this::updateEmergencyCallButton);
+    }
+
+    @Override
+    protected void onViewAttached() {
+        mKeyguardUpdateMonitor.registerCallback(mInfoCallback);
+        mConfigurationController.addCallback(mConfigurationListener);
+        mView.setOnClickListener(v -> takeEmergencyCallAction());
+    }
+
+    @Override
+    protected void onViewDetached() {
+        mKeyguardUpdateMonitor.removeCallback(mInfoCallback);
+        mConfigurationController.removeCallback(mConfigurationListener);
+    }
+
+    private void updateEmergencyCallButton() {
+        if (mView != null) {
+            mView.updateEmergencyCallButton(
+                    mTelecomManager != null && mTelecomManager.isInCall(),
+                    mTelephonyManager.isVoiceCapable(),
+                    mKeyguardUpdateMonitor.isSimPinVoiceSecure());
+        }
+    }
+
+    public void setEmergencyButtonCallback(EmergencyButtonCallback callback) {
+        mEmergencyButtonCallback = callback;
+    }
+    /**
+     * Shows the emergency dialer or returns the user to the existing call.
+     */
+    public void takeEmergencyCallAction() {
+        mMetricsLogger.action(MetricsEvent.ACTION_EMERGENCY_CALL);
+        if (mPowerManager != null) {
+            mPowerManager.userActivity(SystemClock.uptimeMillis(), true);
+        }
+        mActivityTaskManager.stopSystemLockTaskMode();
+        if (mTelecomManager != null && mTelecomManager.isInCall()) {
+            mTelecomManager.showInCallScreen(false);
+            if (mEmergencyButtonCallback != null) {
+                mEmergencyButtonCallback.onEmergencyButtonClickedWhenInCall();
+            }
+        } else {
+            mKeyguardUpdateMonitor.reportEmergencyCallAction(true /* bypassHandler */);
+            if (mTelecomManager == null) {
+                Log.wtf(LOG_TAG, "TelecomManager was null, cannot launch emergency dialer");
+                return;
+            }
+            Intent emergencyDialIntent =
+                    mTelecomManager.createLaunchEmergencyDialerIntent(null /* number*/)
+                            .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+                                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
+                                    | Intent.FLAG_ACTIVITY_CLEAR_TOP)
+                            .putExtra(EmergencyDialerConstants.EXTRA_ENTRY_TYPE,
+                                    EmergencyDialerConstants.ENTRY_TYPE_LOCKSCREEN_BUTTON);
+
+            getContext().startActivityAsUser(emergencyDialIntent,
+                    ActivityOptions.makeCustomAnimation(getContext(), 0, 0).toBundle(),
+                    new UserHandle(KeyguardUpdateMonitor.getCurrentUser()));
+        }
+    }
+
+    /** */
+    public interface EmergencyButtonCallback {
+        /** */
+        void onEmergencyButtonClickedWhenInCall();
+    }
+
+    /** Injectable Factory for creating {@link EmergencyButtonController}. */
+    public static class Factory {
+        private final ConfigurationController mConfigurationController;
+        private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+        private final TelephonyManager mTelephonyManager;
+        private final PowerManager mPowerManager;
+        private final ActivityTaskManager mActivityTaskManager;
+        @Nullable
+        private final TelecomManager mTelecomManager;
+        private final MetricsLogger mMetricsLogger;
+
+        @Inject
+        public Factory(ConfigurationController configurationController,
+                KeyguardUpdateMonitor keyguardUpdateMonitor, TelephonyManager telephonyManager,
+                PowerManager powerManager, ActivityTaskManager activityTaskManager,
+                @Nullable TelecomManager telecomManager, MetricsLogger metricsLogger) {
+
+            mConfigurationController = configurationController;
+            mKeyguardUpdateMonitor = keyguardUpdateMonitor;
+            mTelephonyManager = telephonyManager;
+            mPowerManager = powerManager;
+            mActivityTaskManager = activityTaskManager;
+            mTelecomManager = telecomManager;
+            mMetricsLogger = metricsLogger;
+        }
+
+        /** Construct an {@link com.android.keyguard.EmergencyButtonController}. */
+        public EmergencyButtonController create(EmergencyButton view) {
+            return new EmergencyButtonController(view, mConfigurationController,
+                    mKeyguardUpdateMonitor, mTelephonyManager, mPowerManager, mActivityTaskManager,
+                    mTelecomManager, mMetricsLogger);
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputViewController.java
index 9f32c03..e41d5a3 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputViewController.java
@@ -31,7 +31,7 @@
 import com.android.internal.widget.LockPatternChecker;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.internal.widget.LockscreenCredential;
-import com.android.keyguard.EmergencyButton.EmergencyButtonCallback;
+import com.android.keyguard.EmergencyButtonController.EmergencyButtonCallback;
 import com.android.keyguard.KeyguardAbsKeyInputView.KeyDownListener;
 import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
 import com.android.systemui.R;
@@ -44,6 +44,7 @@
     private final LockPatternUtils mLockPatternUtils;
     private final LatencyTracker mLatencyTracker;
     private final FalsingCollector mFalsingCollector;
+    private final EmergencyButtonController mEmergencyButtonController;
     private CountDownTimer mCountdownTimer;
     protected KeyguardMessageAreaController mMessageAreaController;
     private boolean mDismissing;
@@ -73,12 +74,14 @@
             LockPatternUtils lockPatternUtils,
             KeyguardSecurityCallback keyguardSecurityCallback,
             KeyguardMessageAreaController.Factory messageAreaControllerFactory,
-            LatencyTracker latencyTracker, FalsingCollector falsingCollector) {
-        super(view, securityMode, keyguardSecurityCallback);
+            LatencyTracker latencyTracker, FalsingCollector falsingCollector,
+            EmergencyButtonController emergencyButtonController) {
+        super(view, securityMode, keyguardSecurityCallback, emergencyButtonController);
         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
         mLockPatternUtils = lockPatternUtils;
         mLatencyTracker = latencyTracker;
         mFalsingCollector = falsingCollector;
+        mEmergencyButtonController = emergencyButtonController;
         KeyguardMessageArea kma = KeyguardMessageArea.findSecurityMessageDisplay(mView);
         mMessageAreaController = messageAreaControllerFactory.create(kma);
     }
@@ -87,6 +90,7 @@
 
     @Override
     public void onInit() {
+        super.onInit();
         mMessageAreaController.init();
     }
 
@@ -95,10 +99,7 @@
         super.onViewAttached();
         mView.setKeyDownListener(mKeyDownListener);
         mView.setEnableHaptics(mLockPatternUtils.isTactileFeedbackEnabled());
-        EmergencyButton button = mView.findViewById(R.id.emergency_call_button);
-        if (button != null) {
-            button.setCallback(mEmergencyButtonCallback);
-        }
+        mEmergencyButtonController.setEmergencyButtonCallback(mEmergencyButtonCallback);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
index 276036c..76a7473 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
@@ -36,7 +36,6 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.keyguard.dagger.KeyguardStatusViewComponent;
-import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.dagger.qualifiers.UiBackground;
 import com.android.systemui.navigationbar.NavigationBarController;
@@ -46,12 +45,15 @@
 
 import javax.inject.Inject;
 
+import dagger.Lazy;
+
 public class KeyguardDisplayManager {
     protected static final String TAG = "KeyguardDisplayManager";
     private static boolean DEBUG = KeyguardConstants.DEBUG;
 
     private MediaRouter mMediaRouter = null;
     private final DisplayManager mDisplayService;
+    private final Lazy<NavigationBarController> mNavigationBarControllerLazy;
     private final KeyguardStatusViewComponent.Factory mKeyguardStatusViewComponentFactory;
     private final Context mContext;
 
@@ -85,9 +87,11 @@
 
     @Inject
     public KeyguardDisplayManager(Context context,
+            Lazy<NavigationBarController> navigationBarControllerLazy,
             KeyguardStatusViewComponent.Factory keyguardStatusViewComponentFactory,
             @UiBackground Executor uiBgExecutor) {
         mContext = context;
+        mNavigationBarControllerLazy = navigationBarControllerLazy;
         mKeyguardStatusViewComponentFactory = keyguardStatusViewComponentFactory;
         uiBgExecutor.execute(() -> mMediaRouter = mContext.getSystemService(MediaRouter.class));
         mDisplayService = mContext.getSystemService(DisplayManager.class);
@@ -240,7 +244,7 @@
         // Leave this task to {@link StatusBarKeyguardViewManager}
         if (displayId == DEFAULT_DISPLAY) return;
 
-        NavigationBarView navBarView = Dependency.get(NavigationBarController.class)
+        NavigationBarView navBarView = mNavigationBarControllerLazy.get()
                 .getNavigationBarView(displayId);
         // We may not have nav bar on a display.
         if (navBarView == null) return;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardHostViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardHostViewController.java
index 72dd72e..02a8958 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardHostViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardHostViewController.java
@@ -487,5 +487,9 @@
                 mView.setLayoutParams(lp);
             }
         }
+
+        if (mKeyguardSecurityContainerController != null) {
+            mKeyguardSecurityContainerController.updateResources();
+        }
     }
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java
index 05f33a9..3d42da2 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java
@@ -42,6 +42,7 @@
     private final SecurityMode mSecurityMode;
     private final KeyguardSecurityCallback mKeyguardSecurityCallback;
     private final EmergencyButton mEmergencyButton;
+    private final EmergencyButtonController mEmergencyButtonController;
     private boolean mPaused;
 
 
@@ -69,11 +70,18 @@
     };
 
     protected KeyguardInputViewController(T view, SecurityMode securityMode,
-            KeyguardSecurityCallback keyguardSecurityCallback) {
+            KeyguardSecurityCallback keyguardSecurityCallback,
+            EmergencyButtonController emergencyButtonController) {
         super(view);
         mSecurityMode = securityMode;
         mKeyguardSecurityCallback = keyguardSecurityCallback;
         mEmergencyButton = view == null ? null : view.findViewById(R.id.emergency_call_button);
+        mEmergencyButtonController = emergencyButtonController;
+    }
+
+    @Override
+    protected void onInit() {
+        mEmergencyButtonController.init();
     }
 
     @Override
@@ -157,6 +165,7 @@
         private final Resources mResources;
         private final LiftToActivateListener mLiftToActivateListener;
         private final TelephonyManager mTelephonyManager;
+        private final EmergencyButtonController.Factory mEmergencyButtonControllerFactory;
         private final FalsingCollector mFalsingCollector;
         private final boolean mIsNewLayoutEnabled;
 
@@ -168,6 +177,7 @@
                 InputMethodManager inputMethodManager, @Main DelayableExecutor mainExecutor,
                 @Main Resources resources, LiftToActivateListener liftToActivateListener,
                 TelephonyManager telephonyManager, FalsingCollector falsingCollector,
+                EmergencyButtonController.Factory emergencyButtonControllerFactory,
                 FeatureFlags featureFlags) {
             mKeyguardUpdateMonitor = keyguardUpdateMonitor;
             mLockPatternUtils = lockPatternUtils;
@@ -178,6 +188,7 @@
             mResources = resources;
             mLiftToActivateListener = liftToActivateListener;
             mTelephonyManager = telephonyManager;
+            mEmergencyButtonControllerFactory = emergencyButtonControllerFactory;
             mFalsingCollector = falsingCollector;
             mIsNewLayoutEnabled = featureFlags.isKeyguardLayoutEnabled();
         }
@@ -185,33 +196,40 @@
         /** Create a new {@link KeyguardInputViewController}. */
         public KeyguardInputViewController create(KeyguardInputView keyguardInputView,
                 SecurityMode securityMode, KeyguardSecurityCallback keyguardSecurityCallback) {
+            EmergencyButtonController emergencyButtonController =
+                    mEmergencyButtonControllerFactory.create(
+                            keyguardInputView.findViewById(R.id.emergency_call_button));
+
             if (keyguardInputView instanceof KeyguardPatternView) {
                 return new KeyguardPatternViewController((KeyguardPatternView) keyguardInputView,
                         mKeyguardUpdateMonitor, securityMode, mLockPatternUtils,
                         keyguardSecurityCallback, mLatencyTracker, mFalsingCollector,
-                        mMessageAreaControllerFactory);
+                        emergencyButtonController, mMessageAreaControllerFactory);
             } else if (keyguardInputView instanceof KeyguardPasswordView) {
                 return new KeyguardPasswordViewController((KeyguardPasswordView) keyguardInputView,
                         mKeyguardUpdateMonitor, securityMode, mLockPatternUtils,
                         keyguardSecurityCallback, mMessageAreaControllerFactory, mLatencyTracker,
-                        mInputMethodManager, mMainExecutor, mResources, mFalsingCollector);
+                        mInputMethodManager, emergencyButtonController, mMainExecutor, mResources,
+                        mFalsingCollector);
+
             } else if (keyguardInputView instanceof KeyguardPINView) {
                 return new KeyguardPinViewController((KeyguardPINView) keyguardInputView,
                         mKeyguardUpdateMonitor, securityMode, mLockPatternUtils,
                         keyguardSecurityCallback, mMessageAreaControllerFactory, mLatencyTracker,
-                        mLiftToActivateListener, mFalsingCollector, mIsNewLayoutEnabled);
+                        mLiftToActivateListener, emergencyButtonController, mFalsingCollector,
+                        mIsNewLayoutEnabled);
             } else if (keyguardInputView instanceof KeyguardSimPinView) {
                 return new KeyguardSimPinViewController((KeyguardSimPinView) keyguardInputView,
                         mKeyguardUpdateMonitor, securityMode, mLockPatternUtils,
                         keyguardSecurityCallback, mMessageAreaControllerFactory, mLatencyTracker,
                         mLiftToActivateListener, mTelephonyManager, mFalsingCollector,
-                        mIsNewLayoutEnabled);
+                        emergencyButtonController, mIsNewLayoutEnabled);
             } else if (keyguardInputView instanceof KeyguardSimPukView) {
                 return new KeyguardSimPukViewController((KeyguardSimPukView) keyguardInputView,
                         mKeyguardUpdateMonitor, securityMode, mLockPatternUtils,
                         keyguardSecurityCallback, mMessageAreaControllerFactory, mLatencyTracker,
                         mLiftToActivateListener, mTelephonyManager, mFalsingCollector,
-                        mIsNewLayoutEnabled);
+                        emergencyButtonController, mIsNewLayoutEnabled);
             }
 
             throw new RuntimeException("Unable to find controller for " + keyguardInputView);
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardMessageArea.java b/packages/SystemUI/src/com/android/keyguard/KeyguardMessageArea.java
index 561ea40..568bea0 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardMessageArea.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardMessageArea.java
@@ -70,7 +70,7 @@
 
     void onThemeChanged() {
         TypedArray array = mContext.obtainStyledAttributes(new int[] {
-                android.R.attr.textColor
+                android.R.attr.textColorPrimary
         });
         ColorStateList newTextColors = ColorStateList.valueOf(array.getColor(0, Color.RED));
         array.recycle();
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java
index e45dd8b..933a919 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java
@@ -112,11 +112,13 @@
             KeyguardMessageAreaController.Factory messageAreaControllerFactory,
             LatencyTracker latencyTracker,
             InputMethodManager inputMethodManager,
+            EmergencyButtonController emergencyButtonController,
             @Main DelayableExecutor mainExecutor,
             @Main Resources resources,
             FalsingCollector falsingCollector) {
         super(view, keyguardUpdateMonitor, securityMode, lockPatternUtils, keyguardSecurityCallback,
-                messageAreaControllerFactory, latencyTracker, falsingCollector);
+                messageAreaControllerFactory, latencyTracker, falsingCollector,
+                emergencyButtonController);
         mKeyguardSecurityCallback = keyguardSecurityCallback;
         mInputMethodManager = inputMethodManager;
         mMainExecutor = mainExecutor;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java
index e16c01a..f0d1e02 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java
@@ -32,7 +32,7 @@
 import com.android.internal.widget.LockPatternView;
 import com.android.internal.widget.LockPatternView.Cell;
 import com.android.internal.widget.LockscreenCredential;
-import com.android.keyguard.EmergencyButton.EmergencyButtonCallback;
+import com.android.keyguard.EmergencyButtonController.EmergencyButtonCallback;
 import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
 import com.android.settingslib.Utils;
 import com.android.systemui.R;
@@ -54,6 +54,7 @@
     private final LockPatternUtils mLockPatternUtils;
     private final LatencyTracker mLatencyTracker;
     private final FalsingCollector mFalsingCollector;
+    private final EmergencyButtonController mEmergencyButtonController;
     private final KeyguardMessageAreaController.Factory mMessageAreaControllerFactory;
 
     private KeyguardMessageAreaController mMessageAreaController;
@@ -189,12 +190,14 @@
             KeyguardSecurityCallback keyguardSecurityCallback,
             LatencyTracker latencyTracker,
             FalsingCollector falsingCollector,
+            EmergencyButtonController emergencyButtonController,
             KeyguardMessageAreaController.Factory messageAreaControllerFactory) {
-        super(view, securityMode, keyguardSecurityCallback);
+        super(view, securityMode, keyguardSecurityCallback, emergencyButtonController);
         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
         mLockPatternUtils = lockPatternUtils;
         mLatencyTracker = latencyTracker;
         mFalsingCollector = falsingCollector;
+        mEmergencyButtonController = emergencyButtonController;
         mMessageAreaControllerFactory = messageAreaControllerFactory;
         KeyguardMessageArea kma = KeyguardMessageArea.findSecurityMessageDisplay(mView);
         mMessageAreaController = mMessageAreaControllerFactory.create(kma);
@@ -222,11 +225,7 @@
             }
             return false;
         });
-
-        EmergencyButton button = mView.findViewById(R.id.emergency_call_button);
-        if (button != null) {
-            button.setCallback(mEmergencyButtonCallback);
-        }
+        mEmergencyButtonController.setEmergencyButtonCallback(mEmergencyButtonCallback);
 
         View cancelBtn = mView.findViewById(R.id.cancel_button);
         if (cancelBtn != null) {
@@ -242,10 +241,7 @@
         super.onViewDetached();
         mLockPatternView.setOnPatternListener(null);
         mLockPatternView.setOnTouchListener(null);
-        EmergencyButton button = mView.findViewById(R.id.emergency_call_button);
-        if (button != null) {
-            button.setCallback(null);
-        }
+        mEmergencyButtonController.setEmergencyButtonCallback(null);
         View cancelBtn = mView.findViewById(R.id.cancel_button);
         if (cancelBtn != null) {
             cancelBtn.setOnClickListener(null);
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java
index b156f81..8de4e7b 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java
@@ -57,9 +57,11 @@
             KeyguardMessageAreaController.Factory messageAreaControllerFactory,
             LatencyTracker latencyTracker,
             LiftToActivateListener liftToActivateListener,
+            EmergencyButtonController emergencyButtonController,
             FalsingCollector falsingCollector) {
         super(view, keyguardUpdateMonitor, securityMode, lockPatternUtils, keyguardSecurityCallback,
-                messageAreaControllerFactory, latencyTracker, falsingCollector);
+                messageAreaControllerFactory, latencyTracker, falsingCollector,
+                emergencyButtonController);
         mLiftToActivateListener = liftToActivateListener;
         mFalsingCollector = falsingCollector;
         mPasswordEntry = mView.findViewById(mView.getPasswordTextViewId());
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java
index 49099fa..a456d42 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java
@@ -34,10 +34,11 @@
             KeyguardSecurityCallback keyguardSecurityCallback,
             KeyguardMessageAreaController.Factory messageAreaControllerFactory,
             LatencyTracker latencyTracker, LiftToActivateListener liftToActivateListener,
+            EmergencyButtonController emergencyButtonController,
             FalsingCollector falsingCollector, boolean isNewLayoutEnabled) {
         super(view, keyguardUpdateMonitor, securityMode, lockPatternUtils, keyguardSecurityCallback,
                 messageAreaControllerFactory, latencyTracker, liftToActivateListener,
-                falsingCollector);
+                emergencyButtonController, falsingCollector);
         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
         view.setIsNewLayoutEnabled(isNewLayoutEnabled);
     }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index 4887767..708b2d5 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -33,7 +33,6 @@
 import android.util.TypedValue;
 import android.view.Gravity;
 import android.view.MotionEvent;
-import android.view.OrientationEventListener;
 import android.view.VelocityTracker;
 import android.view.View;
 import android.view.ViewConfiguration;
@@ -107,7 +106,6 @@
     private boolean mOneHandedMode = false;
     private SecurityMode mSecurityMode = SecurityMode.Invalid;
     private ViewPropertyAnimator mRunningOneHandedAnimator;
-    private final OrientationEventListener mOrientationEventListener;
 
     private final WindowInsetsAnimation.Callback mWindowInsetsAnimationCallback =
             new WindowInsetsAnimation.Callback(DISPATCH_MODE_STOP) {
@@ -247,13 +245,6 @@
         super(context, attrs, defStyle);
         mSpringAnimation = new SpringAnimation(this, DynamicAnimation.Y);
         mViewConfiguration = ViewConfiguration.get(context);
-
-        mOrientationEventListener = new OrientationEventListener(context) {
-            @Override
-            public void onOrientationChanged(int orientation) {
-                updateLayoutForSecurityMode(mSecurityMode);
-            }
-        };
     }
 
     void onResume(SecurityMode securityMode, boolean faceAuthEnabled) {
@@ -262,7 +253,6 @@
         updateBiometricRetry(securityMode, faceAuthEnabled);
 
         updateLayoutForSecurityMode(securityMode);
-        mOrientationEventListener.enable();
     }
 
     void updateLayoutForSecurityMode(SecurityMode securityMode) {
@@ -385,7 +375,6 @@
             mAlertDialog = null;
         }
         mSecurityViewFlipper.setWindowInsetsAnimationCallback(null);
-        mOrientationEventListener.disable();
     }
 
     @Override
@@ -663,6 +652,15 @@
                         childState << MEASURED_HEIGHT_STATE_SHIFT));
     }
 
+    @Override
+    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        super.onLayout(changed, left, top, right, bottom);
+
+        // After a layout pass, we need to re-place the inner bouncer, as our bounds may have
+        // changed.
+        updateSecurityViewLocation(/* animate= */false);
+    }
+
     void showAlmostAtWipeDialog(int attempts, int remaining, int userType) {
         String message = null;
         switch (userType) {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
index ccba1d5..760eaec 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
@@ -29,6 +29,7 @@
 import android.app.admin.DevicePolicyManager;
 import android.content.Intent;
 import android.content.res.ColorStateList;
+import android.content.res.Configuration;
 import android.metrics.LogMaker;
 import android.os.UserHandle;
 import android.util.Log;
@@ -74,6 +75,8 @@
     private final SecurityCallback mSecurityCallback;
     private final ConfigurationController mConfigurationController;
 
+    private int mLastOrientation = Configuration.ORIENTATION_UNDEFINED;
+
     private SecurityMode mCurrentSecurityMode = SecurityMode.Invalid;
 
     private final Gefingerpoken mGlobalTouchListener = new Gefingerpoken() {
@@ -212,6 +215,7 @@
         mAdminSecondaryLockScreenController = adminSecondaryLockScreenControllerFactory.create(
                 mKeyguardSecurityCallback);
         mConfigurationController = configurationController;
+        mLastOrientation = getResources().getConfiguration().orientation;
     }
 
     @Override
@@ -498,6 +502,19 @@
         return getCurrentSecurityController();
     }
 
+    /**
+     * Apply keyguard configuration from the currently active resources. This can be called when the
+     * device configuration changes, to re-apply some resources that are qualified on the device
+     * configuration.
+     */
+    public void updateResources() {
+        int newOrientation = getResources().getConfiguration().orientation;
+        if (newOrientation != mLastOrientation) {
+            mLastOrientation = newOrientation;
+            mView.updateLayoutForSecurityMode(mCurrentSecurityMode);
+        }
+    }
+
     static class Factory {
 
         private final KeyguardSecurityContainer mView;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java
index 631c248..69328cd 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java
@@ -23,7 +23,6 @@
 import android.telephony.TelephonyManager;
 
 import com.android.internal.widget.LockPatternUtils;
-import com.android.systemui.Dependency;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Main;
 
@@ -49,24 +48,27 @@
     private final boolean mIsPukScreenAvailable;
 
     private final LockPatternUtils mLockPatternUtils;
+    private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
 
     @Inject
-    KeyguardSecurityModel(@Main Resources resources, LockPatternUtils lockPatternUtils) {
+    KeyguardSecurityModel(@Main Resources resources, LockPatternUtils lockPatternUtils,
+            KeyguardUpdateMonitor keyguardUpdateMonitor) {
         mIsPukScreenAvailable = resources.getBoolean(
                 com.android.internal.R.bool.config_enable_puk_unlock_screen);
         mLockPatternUtils = lockPatternUtils;
+        mKeyguardUpdateMonitor = keyguardUpdateMonitor;
     }
 
     public SecurityMode getSecurityMode(int userId) {
-        KeyguardUpdateMonitor monitor = Dependency.get(KeyguardUpdateMonitor.class);
-
         if (mIsPukScreenAvailable && SubscriptionManager.isValidSubscriptionId(
-                monitor.getNextSubIdForState(TelephonyManager.SIM_STATE_PUK_REQUIRED))) {
+                mKeyguardUpdateMonitor.getNextSubIdForState(
+                        TelephonyManager.SIM_STATE_PUK_REQUIRED))) {
             return SecurityMode.SimPuk;
         }
 
         if (SubscriptionManager.isValidSubscriptionId(
-                monitor.getNextSubIdForState(TelephonyManager.SIM_STATE_PIN_REQUIRED))) {
+                mKeyguardUpdateMonitor.getNextSubIdForState(
+                        TelephonyManager.SIM_STATE_PIN_REQUIRED))) {
             return SecurityMode.SimPin;
         }
 
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipperController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipperController.java
index f1b504e..33d47fe 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipperController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipperController.java
@@ -44,15 +44,18 @@
     private final List<KeyguardInputViewController<KeyguardInputView>> mChildren =
             new ArrayList<>();
     private final LayoutInflater mLayoutInflater;
+    private final EmergencyButtonController.Factory mEmergencyButtonControllerFactory;
     private final Factory mKeyguardSecurityViewControllerFactory;
 
     @Inject
     protected KeyguardSecurityViewFlipperController(KeyguardSecurityViewFlipper view,
             LayoutInflater layoutInflater,
-            KeyguardInputViewController.Factory keyguardSecurityViewControllerFactory) {
+            KeyguardInputViewController.Factory keyguardSecurityViewControllerFactory,
+            EmergencyButtonController.Factory emergencyButtonControllerFactory) {
         super(view);
         mKeyguardSecurityViewControllerFactory = keyguardSecurityViewControllerFactory;
         mLayoutInflater = layoutInflater;
+        mEmergencyButtonControllerFactory = emergencyButtonControllerFactory;
     }
 
     @Override
@@ -111,7 +114,8 @@
 
         if (childController == null) {
             childController = new NullKeyguardInputViewController(
-                    securityMode, keyguardSecurityCallback);
+                    securityMode, keyguardSecurityCallback,
+                    mEmergencyButtonControllerFactory.create(null));
         }
 
         return childController;
@@ -140,8 +144,9 @@
     private static class NullKeyguardInputViewController
             extends KeyguardInputViewController<KeyguardInputView> {
         protected NullKeyguardInputViewController(SecurityMode securityMode,
-                KeyguardSecurityCallback keyguardSecurityCallback) {
-            super(null, securityMode, keyguardSecurityCallback);
+                KeyguardSecurityCallback keyguardSecurityCallback,
+                EmergencyButtonController emergencyButtonController) {
+            super(null, securityMode, keyguardSecurityCallback, emergencyButtonController);
         }
 
         @Override
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java
index b2bf2e6..fddbb3c 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java
@@ -79,10 +79,10 @@
             KeyguardMessageAreaController.Factory messageAreaControllerFactory,
             LatencyTracker latencyTracker, LiftToActivateListener liftToActivateListener,
             TelephonyManager telephonyManager, FalsingCollector falsingCollector,
-            boolean isNewLayoutEnabled) {
+            EmergencyButtonController emergencyButtonController, boolean isNewLayoutEnabled) {
         super(view, keyguardUpdateMonitor, securityMode, lockPatternUtils, keyguardSecurityCallback,
                 messageAreaControllerFactory, latencyTracker, liftToActivateListener,
-                falsingCollector);
+                emergencyButtonController, falsingCollector);
         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
         mTelephonyManager = telephonyManager;
         mSimImageView = mView.findViewById(R.id.keyguard_sim);
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java
index 620db48..50bd0c7 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java
@@ -37,7 +37,6 @@
 import com.android.internal.util.LatencyTracker;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
-import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.classifier.FalsingCollector;
 
@@ -86,10 +85,10 @@
             KeyguardMessageAreaController.Factory messageAreaControllerFactory,
             LatencyTracker latencyTracker, LiftToActivateListener liftToActivateListener,
             TelephonyManager telephonyManager, FalsingCollector falsingCollector,
-            boolean isNewLayoutEnabled) {
+            EmergencyButtonController emergencyButtonController, boolean isNewLayoutEnabled) {
         super(view, keyguardUpdateMonitor, securityMode, lockPatternUtils, keyguardSecurityCallback,
                 messageAreaControllerFactory, latencyTracker, liftToActivateListener,
-                falsingCollector);
+                emergencyButtonController, falsingCollector);
         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
         mTelephonyManager = telephonyManager;
         mSimImageView = mView.findViewById(R.id.keyguard_sim);
@@ -198,8 +197,7 @@
         if (count < 2) {
             msg = rez.getString(R.string.kg_puk_enter_puk_hint);
         } else {
-            SubscriptionInfo info = Dependency.get(KeyguardUpdateMonitor.class)
-                    .getSubscriptionInfoForSubId(mSubId);
+            SubscriptionInfo info = mKeyguardUpdateMonitor.getSubscriptionInfoForSubId(mSubId);
             CharSequence displayName = info != null ? info.getDisplayName() : "";
             msg = rez.getString(R.string.kg_puk_enter_puk_hint_multi, displayName);
             if (info != null) {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
index 83c2d1e..96e69ad 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
@@ -49,10 +49,8 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.graphics.ColorUtils;
 import com.android.settingslib.Utils;
-import com.android.systemui.Dependency;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
-import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.util.wakelock.KeepAwakeAnimationListener;
 
 import java.io.FileDescriptor;
@@ -299,8 +297,23 @@
     void onDensityOrFontScaleChanged() {
         mIconSize = mContext.getResources().getDimensionPixelSize(R.dimen.widget_icon_size);
         mIconSizeWithHeader = (int) mContext.getResources().getDimension(R.dimen.header_icon_size);
+
+        for (int i = 0; i < mRow.getChildCount(); i++) {
+            View child = mRow.getChildAt(i);
+            if (child instanceof KeyguardSliceTextView) {
+                ((KeyguardSliceTextView) child).onDensityOrFontScaleChanged();
+            }
+        }
     }
 
+    void onOverlayChanged() {
+        for (int i = 0; i < mRow.getChildCount(); i++) {
+            View child = mRow.getChildAt(i);
+            if (child instanceof KeyguardSliceTextView) {
+                ((KeyguardSliceTextView) child).onOverlayChanged();
+            }
+        }
+    }
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.println("KeyguardSliceView:");
         pw.println("  mTitle: " + (mTitle == null ? "null" : mTitle.getVisibility() == VISIBLE));
@@ -466,8 +479,7 @@
      * Representation of an item that appears under the clock on main keyguard message.
      */
     @VisibleForTesting
-    static class KeyguardSliceTextView extends TextView implements
-            ConfigurationController.ConfigurationListener {
+    static class KeyguardSliceTextView extends TextView {
         private int mLockScreenMode = KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL;
 
         @StyleRes
@@ -479,24 +491,10 @@
             setEllipsize(TruncateAt.END);
         }
 
-        @Override
-        protected void onAttachedToWindow() {
-            super.onAttachedToWindow();
-            Dependency.get(ConfigurationController.class).addCallback(this);
-        }
-
-        @Override
-        protected void onDetachedFromWindow() {
-            super.onDetachedFromWindow();
-            Dependency.get(ConfigurationController.class).removeCallback(this);
-        }
-
-        @Override
         public void onDensityOrFontScaleChanged() {
             updatePadding();
         }
 
-        @Override
         public void onOverlayChanged() {
             setTextAppearance(sStyleId);
         }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceViewController.java
index 1b0a7fa..8038ce4 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceViewController.java
@@ -83,6 +83,10 @@
         public void onDensityOrFontScaleChanged() {
             mView.onDensityOrFontScaleChanged();
         }
+        @Override
+        public void onOverlayChanged() {
+            mView.onOverlayChanged();
+        }
     };
 
     Observer<Slice> mObserver = new Observer<Slice>() {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
index fea152a..5db4f9e 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
@@ -34,7 +34,6 @@
 import androidx.core.graphics.ColorUtils;
 
 import com.android.internal.widget.LockPatternUtils;
-import com.android.systemui.Dependency;
 import com.android.systemui.R;
 
 import java.io.FileDescriptor;
@@ -56,7 +55,6 @@
     private final IActivityManager mIActivityManager;
 
     private TextView mLogoutView;
-    private boolean mCanShowLogout = true; // by default, try to show the logout button here
     private KeyguardClockSwitch mClockView;
     private TextView mOwnerInfo;
     private boolean mCanShowOwnerInfo = true; // by default, try to show the owner information here
@@ -130,11 +128,6 @@
         }
     }
 
-    void setCanShowLogout(boolean canShowLogout) {
-        mCanShowLogout = canShowLogout;
-        updateLogoutView();
-    }
-
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
@@ -159,10 +152,7 @@
         mKeyguardSlice.setContentChangeListener(this::onSliceContentChanged);
         onSliceContentChanged();
 
-        boolean shouldMarquee = Dependency.get(KeyguardUpdateMonitor.class).isDeviceInteractive();
-        setEnableMarquee(shouldMarquee);
         updateOwnerInfo();
-        updateLogoutView();
         updateDark();
     }
 
@@ -209,11 +199,11 @@
         return mOwnerInfo.getVisibility() == VISIBLE ? mOwnerInfo.getHeight() : 0;
     }
 
-    void updateLogoutView() {
+    void updateLogoutView(boolean shouldShowLogout) {
         if (mLogoutView == null) {
             return;
         }
-        mLogoutView.setVisibility(mCanShowLogout && shouldShowLogout() ? VISIBLE : GONE);
+        mLogoutView.setVisibility(shouldShowLogout ? VISIBLE : GONE);
         // Logout button will stay in language of user 0 if we don't set that manually.
         mLogoutView.setText(mContext.getResources().getString(
                 com.android.internal.R.string.global_action_logout));
@@ -313,11 +303,6 @@
         }
     }
 
-    private boolean shouldShowLogout() {
-        return Dependency.get(KeyguardUpdateMonitor.class).isLogoutEnabled()
-                && KeyguardUpdateMonitor.getCurrentUser() != UserHandle.USER_SYSTEM;
-    }
-
     private void onLogoutClicked(View view) {
         int currentUserId = KeyguardUpdateMonitor.getCurrentUser();
         try {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
index 934e768..31ec003 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
@@ -16,6 +16,7 @@
 
 package com.android.keyguard;
 
+import android.os.UserHandle;
 import android.util.Slog;
 import android.view.View;
 
@@ -78,6 +79,8 @@
     @Override
     public void onInit() {
         mKeyguardClockSwitchController.init();
+        mView.setEnableMarquee(mKeyguardUpdateMonitor.isDeviceInteractive());
+        mView.updateLogoutView(shouldShowLogout());
     }
 
     @Override
@@ -245,6 +248,11 @@
         }
     }
 
+    private boolean shouldShowLogout() {
+        return mKeyguardUpdateMonitor.isLogoutEnabled()
+                && KeyguardUpdateMonitor.getCurrentUser() != UserHandle.USER_SYSTEM;
+    }
+
     private final ConfigurationController.ConfigurationListener mConfigurationListener =
             new ConfigurationController.ConfigurationListener() {
         @Override
@@ -267,10 +275,10 @@
             mKeyguardSliceViewController.updateLockScreenMode(mode);
             if (mLockScreenMode == KeyguardUpdateMonitor.LOCK_SCREEN_MODE_LAYOUT_1) {
                 mView.setCanShowOwnerInfo(false);
-                mView.setCanShowLogout(false);
+                mView.updateLogoutView(false);
             } else {
                 mView.setCanShowOwnerInfo(true);
-                mView.setCanShowLogout(false);
+                mView.updateLogoutView(false);
             }
             updateAodIcons();
         }
@@ -296,7 +304,7 @@
                 if (DEBUG) Slog.v(TAG, "refresh statusview showing:" + showing);
                 refreshTime();
                 mView.updateOwnerInfo();
-                mView.updateLogoutView();
+                mView.updateLogoutView(shouldShowLogout());
             }
         }
 
@@ -314,12 +322,12 @@
         public void onUserSwitchComplete(int userId) {
             mKeyguardClockSwitchController.refreshFormat();
             mView.updateOwnerInfo();
-            mView.updateLogoutView();
+            mView.updateLogoutView(shouldShowLogout());
         }
 
         @Override
         public void onLogoutEnabledChanged() {
-            mView.updateLogoutView();
+            mView.updateLogoutView(shouldShowLogout());
         }
     };
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 69e6ed0..9abc1e7 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -22,7 +22,6 @@
 import static android.content.Intent.ACTION_USER_STOPPED;
 import static android.content.Intent.ACTION_USER_UNLOCKED;
 import static android.os.BatteryManager.BATTERY_STATUS_UNKNOWN;
-import static android.telephony.PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE;
 
 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT;
 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW;
@@ -76,11 +75,11 @@
 import android.service.dreams.DreamService;
 import android.service.dreams.IDreamManager;
 import android.telephony.CarrierConfigManager;
-import android.telephony.PhoneStateListener;
 import android.telephony.ServiceState;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
+import android.telephony.TelephonyCallback;
 import android.telephony.TelephonyManager;
 import android.util.Log;
 import android.util.SparseArray;
@@ -107,6 +106,7 @@
 import com.android.systemui.statusbar.FeatureFlags;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
+import com.android.systemui.telephony.TelephonyListenerManager;
 import com.android.systemui.util.Assert;
 import com.android.systemui.util.RingerModeTracker;
 
@@ -290,6 +290,7 @@
     private boolean mDeviceInteractive;
     private boolean mScreenOn;
     private SubscriptionManager mSubscriptionManager;
+    private final TelephonyListenerManager mTelephonyListenerManager;
     private List<SubscriptionInfo> mSubscriptionInfo;
     private TrustManager mTrustManager;
     private UserManager mUserManager;
@@ -358,7 +359,8 @@
             };
 
     @VisibleForTesting
-    public PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
+    public TelephonyCallback.ActiveDataSubscriptionIdListener mPhoneStateListener =
+            new TelephonyCallback.ActiveDataSubscriptionIdListener() {
         @Override
         public void onActiveDataSubscriptionIdChanged(int subId) {
             mActiveMobileDataSubscription = subId;
@@ -1614,9 +1616,11 @@
             StatusBarStateController statusBarStateController,
             LockPatternUtils lockPatternUtils,
             AuthController authController,
+            TelephonyListenerManager telephonyListenerManager,
             FeatureFlags featureFlags) {
         mContext = context;
         mSubscriptionManager = SubscriptionManager.from(context);
+        mTelephonyListenerManager = telephonyListenerManager;
         mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
         mStrongAuthTracker = new StrongAuthTracker(context, this::notifyStrongAuthStateChanged);
         mBackgroundExecutor = backgroundExecutor;
@@ -1865,8 +1869,7 @@
         mTelephonyManager =
                 (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
         if (mTelephonyManager != null) {
-            mTelephonyManager.listen(mPhoneStateListener,
-                    LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE);
+            mTelephonyListenerManager.addActiveDataSubscriptionIdListener(mPhoneStateListener);
             // Set initial sim states values.
             for (int slot = 0; slot < mTelephonyManager.getActiveModemCount(); slot++) {
                 int state = mTelephonyManager.getSimState(slot);
@@ -3123,7 +3126,7 @@
         TelephonyManager telephony =
                 (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
         if (telephony != null) {
-            telephony.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
+            mTelephonyListenerManager.removeActiveDataSubscriptionIdListener(mPhoneStateListener);
         }
 
         mSubscriptionManager.removeOnSubscriptionsChangedListener(mSubscriptionListener);
diff --git a/services/core/java/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneIdValidator.java b/packages/SystemUI/src/com/android/keyguard/clock/ClockModule.java
similarity index 62%
copy from services/core/java/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneIdValidator.java
copy to packages/SystemUI/src/com/android/keyguard/clock/ClockModule.java
index cab5ad2..c4be1ba535 100644
--- a/services/core/java/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneIdValidator.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/ClockModule.java
@@ -14,17 +14,20 @@
  * limitations under the License.
  */
 
-package com.android.server.timezonedetector.location;
+package com.android.keyguard.clock;
 
-import android.annotation.NonNull;
+import java.util.List;
 
-import com.android.i18n.timezone.ZoneInfoDb;
+import dagger.Module;
+import dagger.Provides;
 
-class ZoneInfoDbTimeZoneIdValidator implements
-        LocationTimeZoneProvider.TimeZoneIdValidator {
+/** Dagger Module for clock package. */
+@Module
+public abstract class ClockModule {
 
-    @Override
-    public boolean isValid(@NonNull String timeZoneId) {
-        return ZoneInfoDb.getInstance().hasTimeZone(timeZoneId);
+    /** */
+    @Provides
+    public static List<ClockInfo> provideClockInfoList(ClockManager clockManager) {
+        return clockManager.getClockInfos();
     }
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/ClockOptionsProvider.java b/packages/SystemUI/src/com/android/keyguard/clock/ClockOptionsProvider.java
index 5ef35be..b6413cb 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/ClockOptionsProvider.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/ClockOptionsProvider.java
@@ -28,11 +28,12 @@
 import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.Dependency;
 
 import java.io.FileNotFoundException;
 import java.util.List;
-import java.util.function.Supplier;
+
+import javax.inject.Inject;
+import javax.inject.Provider;
 
 /**
  * Exposes custom clock face options and provides realistic preview images.
@@ -65,15 +66,12 @@
     private static final String CONTENT_SCHEME = "content";
     private static final String AUTHORITY = "com.android.keyguard.clock";
 
-    private final Supplier<List<ClockInfo>> mClocksSupplier;
-
-    public ClockOptionsProvider() {
-        this(() -> Dependency.get(ClockManager.class).getClockInfos());
-    }
+    @Inject
+    public Provider<List<ClockInfo>> mClockInfosProvider;
 
     @VisibleForTesting
-    ClockOptionsProvider(Supplier<List<ClockInfo>> clocksSupplier) {
-        mClocksSupplier = clocksSupplier;
+    ClockOptionsProvider(Provider<List<ClockInfo>> clockInfosProvider) {
+        mClockInfosProvider = clockInfosProvider;
     }
 
     @Override
@@ -99,7 +97,7 @@
         }
         MatrixCursor cursor = new MatrixCursor(new String[] {
                 COLUMN_NAME, COLUMN_TITLE, COLUMN_ID, COLUMN_THUMBNAIL, COLUMN_PREVIEW});
-        List<ClockInfo> clocks = mClocksSupplier.get();
+        List<ClockInfo> clocks = mClockInfosProvider.get();
         for (int i = 0; i < clocks.size(); i++) {
             ClockInfo clock = clocks.get(i);
             cursor.newRow()
@@ -139,7 +137,7 @@
             throw new FileNotFoundException("Invalid preview url, missing id");
         }
         ClockInfo clock = null;
-        List<ClockInfo> clocks = mClocksSupplier.get();
+        List<ClockInfo> clocks = mClockInfosProvider.get();
         for (int i = 0; i < clocks.size(); i++) {
             if (id.equals(clocks.get(i).getId())) {
                 clock = clocks.get(i);
diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewComponent.java b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewComponent.java
new file mode 100644
index 0000000..49a617e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewComponent.java
@@ -0,0 +1,42 @@
+/*
+ * 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.keyguard.dagger;
+
+import com.android.keyguard.KeyguardStatusViewController;
+import com.android.systemui.statusbar.phone.KeyguardStatusBarView;
+import com.android.systemui.statusbar.phone.KeyguardStatusBarViewController;
+
+import dagger.BindsInstance;
+import dagger.Subcomponent;
+
+/**
+ * Subcomponent for helping work with KeyguardStatusView and its children.
+ *
+ * TODO: unify this with {@link KeyguardStatusViewComponent}
+ */
+@Subcomponent(modules = {KeyguardStatusBarViewModule.class})
+@KeyguardStatusBarViewScope
+public interface KeyguardStatusBarViewComponent {
+    /** Simple factory for {@link KeyguardStatusBarViewComponent}. */
+    @Subcomponent.Factory
+    interface Factory {
+        KeyguardStatusBarViewComponent build(@BindsInstance KeyguardStatusBarView view);
+    }
+
+    /** Builds a {@link KeyguardStatusViewController}. */
+    KeyguardStatusBarViewController getKeyguardStatusBarViewController();
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewModule.java b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewModule.java
new file mode 100644
index 0000000..a672523
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewModule.java
@@ -0,0 +1,34 @@
+/*
+ * 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.keyguard.dagger;
+
+import com.android.keyguard.CarrierText;
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.KeyguardStatusBarView;
+
+import dagger.Module;
+import dagger.Provides;
+
+/** Dagger module for {@link KeyguardStatusBarViewComponent}. */
+@Module
+public abstract class KeyguardStatusBarViewModule {
+    @Provides
+    @KeyguardStatusBarViewScope
+    static CarrierText getCarrierText(KeyguardStatusBarView view) {
+        return view.findViewById(R.id.keyguard_carrier_text);
+    }
+}
diff --git a/media/java/android/media/metrics/PlaybackComponent.java b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewScope.java
similarity index 62%
rename from media/java/android/media/metrics/PlaybackComponent.java
rename to packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewScope.java
index 1cadf3b..ba0642f 100644
--- a/media/java/android/media/metrics/PlaybackComponent.java
+++ b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewScope.java
@@ -14,22 +14,19 @@
  * limitations under the License.
  */
 
-package android.media.metrics;
+package com.android.keyguard.dagger;
 
-import android.annotation.NonNull;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+
+import javax.inject.Scope;
 
 /**
- * Interface for playback related components used by playback metrics.
+ * Scope annotation for singleton items within the StatusBarComponent.
  */
-public interface PlaybackComponent {
-
-    /**
-     * Sets the playback ID of the component.
-     */
-    void setPlaybackId(@NonNull String playbackId);
-
-    /**
-     * Gets playback ID.
-     */
-    @NonNull String getPlaybackId();
-}
+@Documented
+@Retention(RUNTIME)
+@Scope
+public @interface KeyguardStatusBarViewScope {}
diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusViewComponent.java b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusViewComponent.java
index 1b6476c..d342377 100644
--- a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusViewComponent.java
+++ b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusViewComponent.java
@@ -25,6 +25,8 @@
 
 /**
  * Subcomponent for helping work with KeyguardStatusView and its children.
+ *
+ * TODO: unify this with {@link KeyguardStatusBarViewComponent}
  */
 @Subcomponent(modules = {KeyguardStatusViewModule.class})
 @KeyguardStatusViewScope
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
index cd53a34..ac99f73 100644
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
@@ -349,6 +349,9 @@
     }
 
     private void setPercentTextAtCurrentLevel() {
+        if (mBatteryPercentView == null) {
+            return;
+        }
         mBatteryPercentView.setText(
                 NumberFormat.getPercentInstance().format(mLevel / 100f));
         setContentDescription(
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index 06b486e..a686fc0 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -120,6 +120,7 @@
 import com.android.systemui.statusbar.policy.UserInfoController;
 import com.android.systemui.statusbar.policy.UserSwitcherController;
 import com.android.systemui.statusbar.policy.ZenModeController;
+import com.android.systemui.telephony.TelephonyListenerManager;
 import com.android.systemui.tracing.ProtoTracer;
 import com.android.systemui.tuner.TunablePadding.TunablePaddingService;
 import com.android.systemui.tuner.TunerService;
@@ -350,6 +351,7 @@
     @Inject Lazy<MediaOutputDialogFactory> mMediaOutputDialogFactory;
     @Inject Lazy<DeviceConfigProxy> mDeviceConfigProxy;
     @Inject Lazy<NavigationBarOverlayController> mNavbarButtonsControllerLazy;
+    @Inject Lazy<TelephonyListenerManager> mTelephonyListenerManager;
 
     @Inject
     public Dependency() {
@@ -545,6 +547,7 @@
         mProviders.put(StatusBar.class, mStatusBar::get);
         mProviders.put(ProtoTracer.class, mProtoTracer::get);
         mProviders.put(DeviceConfigProxy.class, mDeviceConfigProxy::get);
+        mProviders.put(TelephonyListenerManager.class, mTelephonyListenerManager::get);
 
         // TODO(b/118592525): to support multi-display , we start to add something which is
         //                    per-display, while others may be global. I think it's time to add
diff --git a/packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java b/packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java
index 4afa969..45a0ea1 100644
--- a/packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java
+++ b/packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java
@@ -32,7 +32,9 @@
 import android.util.Log;
 import android.view.WindowManagerGlobal;
 
+import com.android.internal.logging.UiEventLogger;
 import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.qs.QSUserSwitcherEvent;
 import com.android.systemui.statusbar.phone.SystemUIDialog;
 
 /**
@@ -45,6 +47,11 @@
     private static final String SETTING_GUEST_HAS_LOGGED_IN = "systemui.guest_has_logged_in";
 
     private Dialog mNewSessionDialog;
+    private final UiEventLogger mUiEventLogger;
+
+    public GuestResumeSessionReceiver(UiEventLogger uiEventLogger) {
+        mUiEventLogger = uiEventLogger;
+    }
 
     /**
      * Register this receiver with the {@link BroadcastDispatcher}
@@ -83,7 +90,7 @@
             int notFirstLogin = Settings.System.getIntForUser(
                     cr, SETTING_GUEST_HAS_LOGGED_IN, 0, userId);
             if (notFirstLogin != 0) {
-                mNewSessionDialog = new ResetSessionDialog(context, userId);
+                mNewSessionDialog = new ResetSessionDialog(context, mUiEventLogger, userId);
                 mNewSessionDialog.show();
             } else {
                 Settings.System.putIntForUser(
@@ -153,9 +160,10 @@
         private static final int BUTTON_WIPE = BUTTON_NEGATIVE;
         private static final int BUTTON_DONTWIPE = BUTTON_POSITIVE;
 
+        private final UiEventLogger mUiEventLogger;
         private final int mUserId;
 
-        public ResetSessionDialog(Context context, int userId) {
+        ResetSessionDialog(Context context, UiEventLogger uiEventLogger, int userId) {
             super(context);
 
             setTitle(context.getString(R.string.guest_wipe_session_title));
@@ -167,15 +175,18 @@
             setButton(BUTTON_DONTWIPE,
                     context.getString(R.string.guest_wipe_session_dontwipe), this);
 
+            mUiEventLogger = uiEventLogger;
             mUserId = userId;
         }
 
         @Override
         public void onClick(DialogInterface dialog, int which) {
             if (which == BUTTON_WIPE) {
+                mUiEventLogger.log(QSUserSwitcherEvent.QS_USER_GUEST_WIPE);
                 wipeGuestSession(getContext(), mUserId);
                 dismiss();
             } else if (which == BUTTON_DONTWIPE) {
+                mUiEventLogger.log(QSUserSwitcherEvent.QS_USER_GUEST_CONTINUE);
                 cancel();
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
index 8b68ae9..721b758 100644
--- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
@@ -55,7 +55,7 @@
     private static final String TAG = ImageWallpaper.class.getSimpleName();
     // We delayed destroy render context that subsequent render requests have chance to cancel it.
     // This is to avoid destroying then recreating render context in a very short time.
-    private static final int DELAY_FINISH_RENDERING = 3000;
+    private static final int DELAY_FINISH_RENDERING = 1000;
     private static final @android.annotation.NonNull RectF LOCAL_COLOR_BOUNDS =
             new RectF(0, 0, 1, 1);
     private static final boolean DEBUG = false;
@@ -107,12 +107,14 @@
         private ImageWallpaperRenderer mRenderer;
         private EglHelper mEglHelper;
         private final Runnable mFinishRenderingTask = this::finishRendering;
+        private final Runnable mInitChoreographerTask = this::initChoreographerInternal;
         private int mWidth = 1;
         private int mHeight = 1;
         private int mImgWidth = 1;
         private int mImgHeight = 1;
         private volatile float mDozeAmount;
         private volatile boolean mNewDozeValue = false;
+        private volatile boolean mShouldScheduleFrame = false;
 
         GLEngine() {
         }
@@ -137,10 +139,7 @@
             mWidth = window.width();
             mMiniBitmap = null;
             if (mWorker != null && mWorker.getThreadHandler() != null) {
-                mWorker.getThreadHandler().post(() -> {
-                    updateMiniBitmap();
-                    Choreographer.getInstance().postFrameCallback(GLEngine.this);
-                });
+                mWorker.getThreadHandler().post(this::updateMiniBitmap);
             }
 
             mDozeAmount = mStatusBarStateController.getDozeAmount();
@@ -222,15 +221,16 @@
         @Override
         public void onDestroy() {
             mMiniBitmap = null;
+
+            mStatusBarStateController.removeCallback(this);
+
             mWorker.getThreadHandler().post(() -> {
-                Choreographer.getInstance().removeFrameCallback(this);
+                finishChoreographerInternal();
                 mRenderer.finish();
                 mRenderer = null;
                 mEglHelper.finish();
                 mEglHelper = null;
             });
-
-            mStatusBarStateController.removeCallback(this);
         }
 
         @Override
@@ -345,6 +345,8 @@
 
         @Override
         public void onDozeAmountChanged(float linear, float eased) {
+            initChoreographer();
+
             mDozeAmount = linear;
             mNewDozeValue = true;
         }
@@ -355,8 +357,10 @@
             postRender();
         }
 
+        /**
+         * Important: this method should only be invoked from the ImageWallpaper (worker) Thread.
+         */
         public void preRender() {
-            // This method should only be invoked from worker thread.
             Trace.beginSection("ImageWallpaper#preRender");
             preRenderInternal();
             Trace.endSection();
@@ -391,8 +395,10 @@
             }
         }
 
+        /**
+         * Important: this method should only be invoked from the ImageWallpaper (worker) Thread.
+         */
         public void requestRender() {
-            // This method should only be invoked from worker thread.
             Trace.beginSection("ImageWallpaper#requestRender");
             requestRenderInternal();
             Trace.endSection();
@@ -416,8 +422,10 @@
             }
         }
 
+        /**
+         * Important: this method should only be invoked from the ImageWallpaper (worker) Thread.
+         */
         public void postRender() {
-            // This method should only be invoked from worker thread.
             Trace.beginSection("ImageWallpaper#postRender");
             scheduleFinishRendering();
             Trace.endSection();
@@ -436,6 +444,7 @@
 
         private void finishRendering() {
             Trace.beginSection("ImageWallpaper#finishRendering");
+            finishChoreographerInternal();
             if (mEglHelper != null) {
                 mEglHelper.destroyEglSurface();
                 mEglHelper.destroyEglContext();
@@ -443,6 +452,35 @@
             Trace.endSection();
         }
 
+        private void initChoreographer() {
+            if (!mWorker.getThreadHandler().hasCallbacks(mInitChoreographerTask)
+                    && !mShouldScheduleFrame) {
+                mWorker.getThreadHandler().post(mInitChoreographerTask);
+            }
+        }
+
+        /**
+         * Subscribes the engine to listen to Choreographer frame events.
+         * Important: this method should only be invoked from the ImageWallpaper (worker) Thread.
+         */
+        private void initChoreographerInternal() {
+            if (!mShouldScheduleFrame) {
+                // Prepare EGL Context and Surface
+                preRender();
+                mShouldScheduleFrame = true;
+                Choreographer.getInstance().postFrameCallback(GLEngine.this);
+            }
+        }
+
+        /**
+         * Unsubscribe the engine from listening to Choreographer frame events.
+         * Important: this method should only be invoked from the ImageWallpaper (worker) Thread.
+         */
+        private void finishChoreographerInternal() {
+            mShouldScheduleFrame = false;
+            Choreographer.getInstance().removeFrameCallback(GLEngine.this);
+        }
+
         private boolean needSupportWideColorGamut() {
             return mRenderer.isWcgContent();
         }
@@ -469,7 +507,10 @@
                 drawFrame();
                 mNewDozeValue = false;
             }
-            Choreographer.getInstance().postFrameCallback(this);
+
+            if (mShouldScheduleFrame) {
+                Choreographer.getInstance().postFrameCallback(this);
+            }
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapter.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapter.java
index bb4038e..fd0c4ef 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapter.java
@@ -18,10 +18,6 @@
 
 import static android.view.View.GONE;
 
-import static com.android.systemui.accessibility.floatingmenu.AccessibilityTargetAdapter.ItemType.FIRST_ITEM;
-import static com.android.systemui.accessibility.floatingmenu.AccessibilityTargetAdapter.ItemType.LAST_ITEM;
-import static com.android.systemui.accessibility.floatingmenu.AccessibilityTargetAdapter.ItemType.REGULAR_ITEM;
-
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -47,9 +43,9 @@
     private final List<AccessibilityTarget> mTargets;
 
     @IntDef({
-            FIRST_ITEM,
-            REGULAR_ITEM,
-            LAST_ITEM
+            ItemType.FIRST_ITEM,
+            ItemType.REGULAR_ITEM,
+            ItemType.LAST_ITEM
     })
     @Retention(RetentionPolicy.SOURCE)
     @interface ItemType {
@@ -69,11 +65,11 @@
                 R.layout.accessibility_floating_menu_item, parent,
                 /* attachToRoot= */ false);
 
-        if (itemType == FIRST_ITEM) {
+        if (itemType == ItemType.FIRST_ITEM) {
             return new TopViewHolder(root);
         }
 
-        if (itemType == LAST_ITEM) {
+        if (itemType == ItemType.LAST_ITEM) {
             return new BottomViewHolder(root);
         }
 
@@ -91,14 +87,14 @@
     @Override
     public int getItemViewType(int position) {
         if (position == 0) {
-            return FIRST_ITEM;
+            return ItemType.FIRST_ITEM;
         }
 
         if (position == (getItemCount() - 1)) {
-            return LAST_ITEM;
+            return ItemType.LAST_ITEM;
         }
 
-        return REGULAR_ITEM;
+        return ItemType.REGULAR_ITEM;
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
index d3168c8..a7c1451 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
@@ -14,14 +14,8 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
-import android.content.pm.ActivityInfo;
-import android.content.pm.PackageManager;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.graphics.PixelFormat;
 import android.metrics.LogMaker;
 import android.os.AsyncTask;
-import android.os.Binder;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.RemoteException;
@@ -30,12 +24,6 @@
 import android.provider.Settings;
 import android.service.voice.VoiceInteractionSession;
 import android.util.Log;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-import android.widget.ImageView;
 
 import com.android.internal.app.AssistUtils;
 import com.android.internal.app.IVoiceInteractionSessionListener;
@@ -43,7 +31,6 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.settingslib.applications.InterestingConfigChanges;
 import com.android.systemui.R;
 import com.android.systemui.assist.ui.DefaultUiController;
 import com.android.systemui.dagger.SysUISingleton;
@@ -97,8 +84,6 @@
     // Note that VERBOSE logging may leak PII (e.g. transcription contents).
     private static final boolean VERBOSE = false;
 
-    private static final String ASSIST_ICON_METADATA_NAME =
-            "com.android.systemui.action_assist_icon";
     private static final String INVOCATION_TIME_MS_KEY = "invocation_time_ms";
     private static final String INVOCATION_PHONE_STATE_KEY = "invocation_phone_state";
     public static final String INVOCATION_TYPE_KEY = "invocation_type";
@@ -123,69 +108,29 @@
     private static final long TIMEOUT_ACTIVITY = 1000;
 
     protected final Context mContext;
-    private final WindowManager mWindowManager;
     private final AssistDisclosure mAssistDisclosure;
-    private final InterestingConfigChanges mInterestingConfigChanges;
     private final PhoneStateMonitor mPhoneStateMonitor;
     private final AssistHandleBehaviorController mHandleController;
     private final UiController mUiController;
     protected final Lazy<SysUiState> mSysUiState;
     protected final AssistLogger mAssistLogger;
 
-    private AssistOrbContainer mView;
     private final DeviceProvisionedController mDeviceProvisionedController;
     private final CommandQueue mCommandQueue;
+    private final AssistOrbController mOrbController;
     protected final AssistUtils mAssistUtils;
-    private final boolean mShouldEnableOrb;
 
     private IVoiceInteractionSessionShowCallback mShowCallback =
             new IVoiceInteractionSessionShowCallback.Stub() {
 
                 @Override
                 public void onFailed() throws RemoteException {
-                    mView.post(mHideRunnable);
+                    mOrbController.postHide();
                 }
 
                 @Override
                 public void onShown() throws RemoteException {
-                    mView.post(mHideRunnable);
-                }
-            };
-
-    private Runnable mHideRunnable = new Runnable() {
-        @Override
-        public void run() {
-            mView.removeCallbacks(this);
-            mView.show(false /* show */, true /* animate */);
-        }
-    };
-
-    private ConfigurationController.ConfigurationListener mConfigurationListener =
-            new ConfigurationController.ConfigurationListener() {
-                @Override
-                public void onConfigChanged(Configuration newConfig) {
-                    if (!mInterestingConfigChanges.applyNewConfig(mContext.getResources())) {
-                        return;
-                    }
-                    boolean visible = false;
-                    if (mView != null) {
-                        visible = mView.isShowing();
-                        if (mView.isAttachedToWindow()) {
-                            mWindowManager.removeView(mView);
-                        }
-                    }
-
-                    mView = (AssistOrbContainer) LayoutInflater.from(mContext).inflate(
-                            R.layout.assist_orb, null);
-                    mView.setVisibility(View.GONE);
-                    mView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
-                            | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
-                            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
-                    WindowManager.LayoutParams lp = getLayoutParams();
-                    mWindowManager.addView(mView, lp);
-                    if (visible) {
-                        mView.show(true /* show */, false /* animate */);
-                    }
+                    mOrbController.postHide();
                 }
             };
 
@@ -205,21 +150,15 @@
         mContext = context;
         mDeviceProvisionedController = controller;
         mCommandQueue = commandQueue;
-        mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
         mAssistUtils = assistUtils;
         mAssistDisclosure = new AssistDisclosure(context, new Handler());
         mPhoneStateMonitor = phoneStateMonitor;
         mHandleController = handleController;
         mAssistLogger = assistLogger;
 
-        configurationController.addCallback(mConfigurationListener);
+        mOrbController = new AssistOrbController(configurationController, context);
 
         registerVoiceInteractionSessionListener();
-        mInterestingConfigChanges = new InterestingConfigChanges(ActivityInfo.CONFIG_ORIENTATION
-                | ActivityInfo.CONFIG_LOCALE | ActivityInfo.CONFIG_UI_MODE
-                | ActivityInfo.CONFIG_SCREEN_LAYOUT | ActivityInfo.CONFIG_ASSETS_PATHS);
-        mConfigurationListener.onConfigChanged(context.getResources().getConfiguration());
-        mShouldEnableOrb = !ActivityManager.isLowRamDeviceStatic();
 
         mUiController = defaultUiController;
 
@@ -282,7 +221,7 @@
     }
 
     protected boolean shouldShowOrb() {
-        return false;
+        return !ActivityManager.isLowRamDeviceStatic();
     }
 
     public void startAssist(Bundle args) {
@@ -293,10 +232,8 @@
 
         final boolean isService = assistComponent.equals(getVoiceInteractorComponentName());
         if (!isService || (!isVoiceSessionRunning() && shouldShowOrb())) {
-            showOrb(assistComponent, isService);
-            mView.postDelayed(mHideRunnable, isService
-                    ? TIMEOUT_SERVICE
-                    : TIMEOUT_ACTIVITY);
+            mOrbController.showOrb(assistComponent, isService);
+            mOrbController.postHideDelayed(isService ? TIMEOUT_SERVICE : TIMEOUT_ACTIVITY);
         }
 
         if (args == null) {
@@ -340,30 +277,6 @@
         mAssistUtils.hideCurrentSession();
     }
 
-    private WindowManager.LayoutParams getLayoutParams() {
-        WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
-                ViewGroup.LayoutParams.MATCH_PARENT,
-                mContext.getResources().getDimensionPixelSize(R.dimen.assist_orb_scrim_height),
-                WindowManager.LayoutParams.TYPE_VOICE_INTERACTION_STARTING,
-                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
-                        | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
-                        | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
-                PixelFormat.TRANSLUCENT);
-        lp.token = new Binder();
-        lp.gravity = Gravity.BOTTOM | Gravity.START;
-        lp.setTitle("AssistPreviewPanel");
-        lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED
-                | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
-        return lp;
-    }
-
-    private void showOrb(@NonNull ComponentName assistComponent, boolean isService) {
-        maybeSwapSearchIcon(assistComponent, isService);
-        if (mShouldEnableOrb) {
-            mView.show(true /* show */, true /* animate */);
-        }
-    }
-
     private void startAssistInternal(Bundle args, @NonNull ComponentName assistComponent,
             boolean isService) {
         if (isService) {
@@ -440,44 +353,6 @@
         return mAssistUtils.isSessionRunning();
     }
 
-    private void maybeSwapSearchIcon(@NonNull ComponentName assistComponent, boolean isService) {
-        replaceDrawable(mView.getOrb().getLogo(), assistComponent, ASSIST_ICON_METADATA_NAME,
-                isService);
-    }
-
-    public void replaceDrawable(ImageView v, ComponentName component, String name,
-            boolean isService) {
-        if (component != null) {
-            try {
-                PackageManager packageManager = mContext.getPackageManager();
-                // Look for the search icon specified in the activity meta-data
-                Bundle metaData = isService
-                        ? packageManager.getServiceInfo(
-                        component, PackageManager.GET_META_DATA).metaData
-                        : packageManager.getActivityInfo(
-                                component, PackageManager.GET_META_DATA).metaData;
-                if (metaData != null) {
-                    int iconResId = metaData.getInt(name);
-                    if (iconResId != 0) {
-                        Resources res = packageManager.getResourcesForApplication(
-                                component.getPackageName());
-                        v.setImageDrawable(res.getDrawable(iconResId));
-                        return;
-                    }
-                }
-            } catch (PackageManager.NameNotFoundException e) {
-                if (VERBOSE) {
-                    Log.v(TAG, "Assistant component "
-                            + component.flattenToShortString() + " not found");
-                }
-            } catch (Resources.NotFoundException nfe) {
-                Log.w(TAG, "Failed to swap drawable from "
-                        + component.flattenToShortString(), nfe);
-            }
-        }
-        v.setImageDrawable(null);
-    }
-
     protected AssistHandleBehaviorController getHandleBehaviorController() {
         return mHandleController;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistOrbContainer.java b/packages/SystemUI/src/com/android/systemui/assist/AssistOrbContainer.java
index f78436a..fe48c26 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistOrbContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistOrbContainer.java
@@ -55,14 +55,17 @@
         mOrb = (AssistOrbView) findViewById(R.id.assist_orb);
     }
 
-    public void show(final boolean show, boolean animate) {
+    public void show(final boolean show, boolean animate, Runnable onDone) {
         if (show) {
             if (getVisibility() != View.VISIBLE) {
                 setVisibility(View.VISIBLE);
                 if (animate) {
-                    startEnterAnimation();
+                    startEnterAnimation(onDone);
                 } else {
                     reset();
+                    if (onDone != null) {
+                        onDone.run();
+                    }
                 }
             }
         } else {
@@ -72,10 +75,16 @@
                     public void run() {
                         mAnimatingOut = false;
                         setVisibility(View.GONE);
+                        if (onDone != null) {
+                            onDone.run();
+                        }
                     }
                 });
             } else {
                 setVisibility(View.GONE);
+                if (onDone != null) {
+                    onDone.run();
+                }
             }
         }
     }
@@ -87,7 +96,7 @@
         mNavbarScrim.setAlpha(1f);
     }
 
-    private void startEnterAnimation() {
+    private void startEnterAnimation(Runnable onDone) {
         if (mAnimatingOut) {
             return;
         }
@@ -106,7 +115,8 @@
                         .alpha(1f)
                         .setDuration(300)
                         .setStartDelay(0)
-                        .setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
+                        .setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN)
+                        .withEndAction(onDone);
             }
         });
     }
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistOrbController.java b/packages/SystemUI/src/com/android/systemui/assist/AssistOrbController.java
new file mode 100644
index 0000000..81a13a2
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistOrbController.java
@@ -0,0 +1,180 @@
+/*
+ * 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.assist;
+
+import android.annotation.NonNull;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.graphics.PixelFormat;
+import android.os.Binder;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.widget.ImageView;
+
+import com.android.settingslib.applications.InterestingConfigChanges;
+import com.android.systemui.R;
+import com.android.systemui.statusbar.policy.ConfigurationController;
+
+/**
+ * AssistOrbController controls the showing and hiding of the assistant orb.
+ */
+public class AssistOrbController {
+    private static final String ASSIST_ICON_METADATA_NAME =
+            "com.android.systemui.action_assist_icon";
+    private static final String TAG = "AssistOrbController";
+    private static final boolean VERBOSE = false;
+
+    private final InterestingConfigChanges mInterestingConfigChanges;
+    private AssistOrbContainer mView;
+    private final Context mContext;
+    private final WindowManager mWindowManager;
+
+    private Runnable mHideRunnable = new Runnable() {
+        @Override
+        public void run() {
+            mView.removeCallbacks(this);
+            mView.show(false /* show */, true /* animate */, () -> {
+                mWindowManager.removeView(mView);
+            });
+        }
+    };
+
+    private ConfigurationController.ConfigurationListener mConfigurationListener =
+            new ConfigurationController.ConfigurationListener() {
+                @Override
+                public void onConfigChanged(Configuration newConfig) {
+                    if (!mInterestingConfigChanges.applyNewConfig(mContext.getResources())) {
+                        return;
+                    }
+                    boolean visible = false;
+                    if (mView != null) {
+                        visible = mView.isShowing();
+                        if (mView.isAttachedToWindow()) {
+                            mWindowManager.removeView(mView);
+                        }
+                    }
+
+                    if (visible) {
+                        showOrb(false);
+                    }
+                }
+            };
+
+    AssistOrbController(ConfigurationController configurationController, Context context) {
+        mContext = context;
+        mWindowManager =  mContext.getSystemService(WindowManager.class);
+        mInterestingConfigChanges = new InterestingConfigChanges(ActivityInfo.CONFIG_ORIENTATION
+                | ActivityInfo.CONFIG_LOCALE | ActivityInfo.CONFIG_UI_MODE
+                | ActivityInfo.CONFIG_SCREEN_LAYOUT | ActivityInfo.CONFIG_ASSETS_PATHS);
+
+        configurationController.addCallback(mConfigurationListener);
+        mConfigurationListener.onConfigChanged(context.getResources().getConfiguration());
+    }
+
+    public void postHide() {
+        mView.post(mHideRunnable);
+    }
+
+    public void postHideDelayed(long delayMs) {
+        mView.postDelayed(mHideRunnable, delayMs);
+    }
+
+    private void showOrb(boolean animated) {
+        if (mView == null) {
+            mView = (AssistOrbContainer) LayoutInflater.from(mContext).inflate(
+                    R.layout.assist_orb, null);
+            mView.setVisibility(View.GONE);
+            mView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+                    | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
+        }
+        if (!mView.isAttachedToWindow()) {
+            WindowManager.LayoutParams params = getLayoutParams();
+            mWindowManager.addView(mView, params);
+        }
+        mView.show(true, animated, null);
+    }
+
+    private WindowManager.LayoutParams getLayoutParams() {
+        WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT,
+                mContext.getResources().getDimensionPixelSize(R.dimen.assist_orb_scrim_height),
+                WindowManager.LayoutParams.TYPE_VOICE_INTERACTION_STARTING,
+                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+                        | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
+                        | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
+                PixelFormat.TRANSLUCENT);
+        lp.token = new Binder();
+        lp.gravity = Gravity.BOTTOM | Gravity.START;
+        lp.setTitle("AssistPreviewPanel");
+        lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED
+                | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
+        return lp;
+    }
+
+    public void showOrb(@NonNull ComponentName assistComponent, boolean isService) {
+        showOrb(true);
+        maybeSwapSearchIcon(assistComponent, isService);
+    }
+
+    private void maybeSwapSearchIcon(@NonNull ComponentName assistComponent, boolean isService) {
+        replaceDrawable(mView.getOrb().getLogo(), assistComponent, ASSIST_ICON_METADATA_NAME,
+                isService);
+    }
+
+    public void replaceDrawable(ImageView v, ComponentName component, String name,
+            boolean isService) {
+        if (component != null) {
+            try {
+                PackageManager packageManager = mContext.getPackageManager();
+                // Look for the search icon specified in the activity meta-data
+                Bundle metaData = isService
+                        ? packageManager.getServiceInfo(
+                        component, PackageManager.GET_META_DATA).metaData
+                        : packageManager.getActivityInfo(
+                                component, PackageManager.GET_META_DATA).metaData;
+                if (metaData != null) {
+                    int iconResId = metaData.getInt(name);
+                    if (iconResId != 0) {
+                        Resources res = packageManager.getResourcesForApplication(
+                                component.getPackageName());
+                        v.setImageDrawable(res.getDrawable(iconResId));
+                        return;
+                    }
+                }
+            } catch (PackageManager.NameNotFoundException e) {
+                if (VERBOSE) {
+                    Log.v(TAG, "Assistant component "
+                            + component.flattenToShortString() + " not found");
+                }
+            } catch (Resources.NotFoundException nfe) {
+                Log.w(TAG, "Failed to swap drawable from "
+                        + component.flattenToShortString(), nfe);
+            }
+        }
+        v.setImageDrawable(null);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
new file mode 100644
index 0000000..a1149fd
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
@@ -0,0 +1,110 @@
+/*
+ * 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 android.content.Context
+import android.hardware.biometrics.BiometricSourceType
+import android.view.View
+import android.view.ViewGroup
+import com.android.internal.annotations.VisibleForTesting
+import com.android.keyguard.KeyguardUpdateMonitor
+import com.android.keyguard.KeyguardUpdateMonitorCallback
+import com.android.settingslib.Utils
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.statusbar.commandline.Command
+import com.android.systemui.statusbar.commandline.CommandRegistry
+import com.android.systemui.statusbar.policy.ConfigurationController
+import java.io.PrintWriter
+import javax.inject.Inject
+
+/***
+ * Controls the ripple effect that shows when authentication is successful.
+ * The ripple uses the accent color of the current theme.
+ */
+@SysUISingleton
+class AuthRippleController @Inject constructor(
+    commandRegistry: CommandRegistry,
+    configurationController: ConfigurationController,
+    private val context: Context,
+    private val keyguardUpdateMonitor: KeyguardUpdateMonitor
+) {
+    @VisibleForTesting
+    var rippleView: AuthRippleView = AuthRippleView(context, attrs = null)
+
+    val keyguardUpdateMonitorCallback = object : KeyguardUpdateMonitorCallback() {
+        override fun onBiometricAuthenticated(
+            userId: Int,
+            biometricSourceType: BiometricSourceType?,
+            isStrongBiometric: Boolean
+        ) {
+            if (biometricSourceType == BiometricSourceType.FINGERPRINT) {
+                rippleView.startRipple()
+            }
+        }
+    }
+
+    init {
+        val configurationChangedListener = object : ConfigurationController.ConfigurationListener {
+            override fun onUiModeChanged() {
+                updateRippleColor()
+            }
+            override fun onThemeChanged() {
+                updateRippleColor()
+            }
+            override fun onOverlayChanged() {
+                updateRippleColor()
+            }
+        }
+        configurationController.addCallback(configurationChangedListener)
+
+        commandRegistry.registerCommand("auth-ripple") { AuthRippleCommand() }
+    }
+
+    fun setSensorLocation(x: Float, y: Float) {
+        rippleView.setSensorLocation(x, y)
+    }
+
+    fun setViewHost(viewHost: View) {
+        // Add the ripple view to its host layout
+        viewHost.addOnAttachStateChangeListener(object : View.OnAttachStateChangeListener {
+            override fun onViewDetachedFromWindow(view: View?) {}
+
+            override fun onViewAttachedToWindow(view: View?) {
+                (viewHost as ViewGroup).addView(rippleView)
+                keyguardUpdateMonitor.registerCallback(keyguardUpdateMonitorCallback)
+                viewHost.removeOnAttachStateChangeListener(this)
+            }
+        })
+
+        updateRippleColor()
+    }
+
+    private fun updateRippleColor() {
+        rippleView.setColor(
+            Utils.getColorAttr(context, android.R.attr.colorAccent).defaultColor)
+    }
+
+    inner class AuthRippleCommand : Command {
+        override fun execute(pw: PrintWriter, args: List<String>) {
+            rippleView.startRipple()
+        }
+
+        override fun help(pw: PrintWriter) {
+            pw.println("Usage: adb shell cmd statusbar auth-ripple")
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt
new file mode 100644
index 0000000..2e32133
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt
@@ -0,0 +1,87 @@
+/*
+ * 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 android.animation.Animator
+import android.animation.AnimatorListenerAdapter
+import android.animation.ValueAnimator
+import android.content.Context
+import android.graphics.Canvas
+import android.graphics.Paint
+import android.graphics.PointF
+import android.util.AttributeSet
+import android.view.View
+import com.android.systemui.statusbar.charging.RippleShader
+
+private const val RIPPLE_ANIMATION_DURATION: Long = 950
+private const val RIPPLE_SPARKLE_STRENGTH: Float = 0.4f
+
+/**
+ * Expanding ripple effect on the transition from biometric authentication success to showing
+ * launcher.
+ */
+class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, attrs) {
+    private var rippleInProgress: Boolean = false
+    private val rippleShader = RippleShader()
+    private val defaultColor: Int = 0xffffffff.toInt()
+    private val ripplePaint = Paint()
+
+    init {
+        rippleShader.color = defaultColor
+        rippleShader.progress = 0f
+        rippleShader.sparkleStrength = RIPPLE_SPARKLE_STRENGTH
+        ripplePaint.shader = rippleShader
+        visibility = View.GONE
+    }
+
+    fun setSensorLocation(x: Float, y: Float) {
+        rippleShader.origin = PointF(x, y)
+        rippleShader.radius = maxOf(x, y, width - x, height - y).toFloat()
+    }
+
+    fun startRipple() {
+        if (rippleInProgress) {
+            return // Ignore if ripple effect is already playing
+        }
+        val animator = ValueAnimator.ofFloat(0f, 1f)
+        animator.duration = RIPPLE_ANIMATION_DURATION
+        animator.addUpdateListener { animator ->
+            val now = animator.currentPlayTime
+            val phase = now / 30000f
+            rippleShader.progress = animator.animatedValue as Float
+            rippleShader.noisePhase = phase
+            invalidate()
+        }
+        animator.addListener(object : AnimatorListenerAdapter() {
+            override fun onAnimationEnd(animation: Animator?) {
+                rippleInProgress = false
+                visibility = View.GONE
+            }
+        })
+        animator.start()
+        visibility = View.VISIBLE
+        rippleInProgress = true
+    }
+
+    fun setColor(color: Int) {
+        rippleShader.color = color
+    }
+
+    override fun onDraw(canvas: Canvas?) {
+        // draw over the entire screen
+        canvas?.drawRect(0f, 0f, width.toFloat(), height.toFloat(), ripplePaint)
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index 98b3fe4..078ec9f 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -87,6 +87,7 @@
     @NonNull private final StatusBarStateController mStatusBarStateController;
     @NonNull private final StatusBarKeyguardViewManager mKeyguardViewManager;
     @NonNull private final DumpManager mDumpManager;
+    @NonNull private final AuthRippleController mAuthRippleController;
     // Currently the UdfpsController supports a single UDFPS sensor. If devices have multiple
     // sensors, this, in addition to a lot of the code here, will be updated.
     @VisibleForTesting final FingerprintSensorPropertiesInternal mSensorProps;
@@ -305,7 +306,8 @@
             @Main DelayableExecutor fgExecutor,
             @NonNull StatusBar statusBar,
             @NonNull StatusBarKeyguardViewManager statusBarKeyguardViewManager,
-            @NonNull DumpManager dumpManager) {
+            @NonNull DumpManager dumpManager,
+            @NonNull AuthRippleController authRippleController) {
         mContext = context;
         mInflater = inflater;
         // The fingerprint manager is queried for UDFPS before this class is constructed, so the
@@ -317,6 +319,7 @@
         mStatusBarStateController = statusBarStateController;
         mKeyguardViewManager = statusBarKeyguardViewManager;
         mDumpManager = dumpManager;
+        mAuthRippleController = authRippleController;
 
         mSensorProps = findFirstUdfps();
         // At least one UDFPS sensor exists
@@ -343,6 +346,10 @@
         final IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
         context.registerReceiver(mBroadcastReceiver, filter);
+
+        mAuthRippleController.setViewHost(mStatusBar.getNotificationShadeWindowView());
+        mAuthRippleController.setSensorLocation(getSensorLocation().centerX(),
+                getSensorLocation().centerY());
     }
 
     @Nullable
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollHelper.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollHelper.java
index 98a703f..521c495 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollHelper.java
@@ -24,6 +24,7 @@
 import android.os.Build;
 import android.os.UserHandle;
 import android.provider.Settings;
+import android.util.Log;
 import android.util.TypedValue;
 
 import java.util.ArrayList;
@@ -39,6 +40,9 @@
             "com.android.systemui.biometrics.UdfpsEnrollHelper.scale";
     private static final float SCALE = 0.5f;
 
+    private static final String NEW_COORDS_OVERRIDE =
+            "com.android.systemui.biometrics.UdfpsNewCoords";
+
     // Enroll with two center touches before going to guided enrollment
     private static final int NUM_CENTER_TOUCHES = 2;
 
@@ -68,21 +72,42 @@
         // Number of pixels per mm
         float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_MM, 1,
                 context.getResources().getDisplayMetrics());
-
-        mGuidedEnrollmentPoints.add(new PointF( 2.00f * px,  0.00f * px));
-        mGuidedEnrollmentPoints.add(new PointF( 0.87f * px, -2.70f * px));
-        mGuidedEnrollmentPoints.add(new PointF(-1.80f * px, -1.31f * px));
-        mGuidedEnrollmentPoints.add(new PointF(-1.80f * px,  1.31f * px));
-        mGuidedEnrollmentPoints.add(new PointF( 0.88f * px,  2.70f * px));
-        mGuidedEnrollmentPoints.add(new PointF( 3.94f * px, -1.06f * px));
-        mGuidedEnrollmentPoints.add(new PointF( 2.90f * px, -4.14f * px));
-        mGuidedEnrollmentPoints.add(new PointF(-0.52f * px, -5.95f * px));
-        mGuidedEnrollmentPoints.add(new PointF(-3.33f * px, -3.33f * px));
-        mGuidedEnrollmentPoints.add(new PointF(-3.99f * px, -0.35f * px));
-        mGuidedEnrollmentPoints.add(new PointF(-3.62f * px,  2.54f * px));
-        mGuidedEnrollmentPoints.add(new PointF(-1.49f * px,  5.57f * px));
-        mGuidedEnrollmentPoints.add(new PointF( 2.29f * px,  4.92f * px));
-        mGuidedEnrollmentPoints.add(new PointF( 3.82f * px,  1.78f * px));
+        boolean useNewCoords = Settings.Secure.getIntForUser(mContext.getContentResolver(),
+                NEW_COORDS_OVERRIDE, 0,
+                UserHandle.USER_CURRENT) != 0;
+        if (useNewCoords && (Build.IS_ENG || Build.IS_USERDEBUG)) {
+            Log.v(TAG, "Using new coordinates");
+            mGuidedEnrollmentPoints.add(new PointF(-0.15f * px, -1.02f * px));
+            mGuidedEnrollmentPoints.add(new PointF(-0.15f * px,  1.02f * px));
+            mGuidedEnrollmentPoints.add(new PointF( 0.29f * px,  0.00f * px));
+            mGuidedEnrollmentPoints.add(new PointF( 2.17f * px, -2.35f * px));
+            mGuidedEnrollmentPoints.add(new PointF( 1.07f * px, -3.96f * px));
+            mGuidedEnrollmentPoints.add(new PointF(-0.37f * px, -4.31f * px));
+            mGuidedEnrollmentPoints.add(new PointF(-1.69f * px, -3.29f * px));
+            mGuidedEnrollmentPoints.add(new PointF(-2.48f * px, -1.23f * px));
+            mGuidedEnrollmentPoints.add(new PointF(-2.48f * px,  1.23f * px));
+            mGuidedEnrollmentPoints.add(new PointF(-1.69f * px,  3.29f * px));
+            mGuidedEnrollmentPoints.add(new PointF(-0.37f * px,  4.31f * px));
+            mGuidedEnrollmentPoints.add(new PointF( 1.07f * px,  3.96f * px));
+            mGuidedEnrollmentPoints.add(new PointF( 2.17f * px,  2.35f * px));
+            mGuidedEnrollmentPoints.add(new PointF( 2.58f * px,  0.00f * px));
+        } else {
+            Log.v(TAG, "Using old coordinates");
+            mGuidedEnrollmentPoints.add(new PointF( 2.00f * px,  0.00f * px));
+            mGuidedEnrollmentPoints.add(new PointF( 0.87f * px, -2.70f * px));
+            mGuidedEnrollmentPoints.add(new PointF(-1.80f * px, -1.31f * px));
+            mGuidedEnrollmentPoints.add(new PointF(-1.80f * px,  1.31f * px));
+            mGuidedEnrollmentPoints.add(new PointF( 0.88f * px,  2.70f * px));
+            mGuidedEnrollmentPoints.add(new PointF( 3.94f * px, -1.06f * px));
+            mGuidedEnrollmentPoints.add(new PointF( 2.90f * px, -4.14f * px));
+            mGuidedEnrollmentPoints.add(new PointF(-0.52f * px, -5.95f * px));
+            mGuidedEnrollmentPoints.add(new PointF(-3.33f * px, -3.33f * px));
+            mGuidedEnrollmentPoints.add(new PointF(-3.99f * px, -0.35f * px));
+            mGuidedEnrollmentPoints.add(new PointF(-3.62f * px,  2.54f * px));
+            mGuidedEnrollmentPoints.add(new PointF(-1.49f * px,  5.57f * px));
+            mGuidedEnrollmentPoints.add(new PointF( 2.29f * px,  4.92f * px));
+            mGuidedEnrollmentPoints.add(new PointF( 3.82f * px,  1.78f * px));
+        }
     }
 
     boolean shouldShowProgressBar() {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java
index 378907c..e274843 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java
@@ -62,7 +62,8 @@
 
         mBgProtection = findViewById(R.id.udfps_keyguard_fp_bg);
 
-        mWallpaperTexColor = Utils.getColorAttrDefaultColor(mContext, R.attr.wallpaperTextColor);
+        mWallpaperTexColor = Utils.getColorAttrDefaultColor(mContext,
+                R.attr.wallpaperTextColorAccent);
         mTextColorPrimary = Utils.getColorAttrDefaultColor(mContext,
                 android.R.attr.textColorPrimary);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java
index 08e5d56..1f652db 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java
@@ -33,6 +33,7 @@
     @NonNull private final StatusBarKeyguardViewManager mKeyguardViewManager;
 
     private boolean mForceShow;
+    private boolean mQsExpanded;
 
     protected UdfpsKeyguardViewController(
             @NonNull UdfpsKeyguardView view,
@@ -64,7 +65,7 @@
     protected void onViewDetached() {
         super.onViewDetached();
         mStatusBarStateController.removeCallback(mStateListener);
-        mAlternateAuthInterceptor.reset();
+        mAlternateAuthInterceptor.resetForceShow();
         mKeyguardViewManager.setAlternateAuthInterceptor(null);
     }
 
@@ -100,6 +101,11 @@
         if (mForceShow) {
             return false;
         }
+
+        if (mQsExpanded) {
+            return true;
+        }
+
         return super.shouldPauseAuth();
     }
 
@@ -130,7 +136,7 @@
                 }
 
                 @Override
-                public boolean reset() {
+                public boolean resetForceShow() {
                     if (!mForceShow) {
                         return false;
                     }
@@ -140,7 +146,7 @@
                 }
 
                 @Override
-                public boolean isShowingAlternativeAuth() {
+                public boolean isShowingAlternateAuth() {
                     return mForceShow;
                 }
 
@@ -150,6 +156,12 @@
                 }
 
                 @Override
+                public void setQsExpanded(boolean expanded) {
+                    mQsExpanded = expanded;
+                    updatePauseAuth();
+                }
+
+                @Override
                 public void dump(PrintWriter pw) {
                     pw.print(getTag());
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingAnimation.java b/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingAnimation.java
index 2569f7c..f7beaf1 100644
--- a/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingAnimation.java
+++ b/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingAnimation.java
@@ -26,7 +26,6 @@
 import android.util.Log;
 import android.util.Slog;
 import android.view.Gravity;
-import android.view.View;
 import android.view.WindowManager;
 
 /**
@@ -98,8 +97,8 @@
         private final Handler mHandler;
 
         private int mGravity;
-        private View mView;
-        private View mNextView;
+        private WirelessChargingLayout mView;
+        private WirelessChargingLayout mNextView;
         private WindowManager mWM;
         private Callback mCallback;
 
@@ -112,7 +111,7 @@
             mGravity = Gravity.CENTER_HORIZONTAL | Gravity.CENTER;
 
             final WindowManager.LayoutParams params = mParams;
-            params.height = WindowManager.LayoutParams.WRAP_CONTENT;
+            params.height = WindowManager.LayoutParams.MATCH_PARENT;
             params.width = WindowManager.LayoutParams.MATCH_PARENT;
             params.format = PixelFormat.TRANSLUCENT;
 
diff --git a/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingLayout.java b/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingLayout.java
index e8407f0..ce0b514 100644
--- a/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingLayout.java
@@ -20,6 +20,7 @@
 import android.animation.ObjectAnimator;
 import android.animation.ValueAnimator;
 import android.content.Context;
+import android.graphics.PointF;
 import android.graphics.drawable.Animatable;
 import android.util.AttributeSet;
 import android.util.TypedValue;
@@ -29,8 +30,10 @@
 import android.widget.ImageView;
 import android.widget.TextView;
 
+import com.android.settingslib.Utils;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
+import com.android.systemui.statusbar.charging.ChargingRippleView;
 
 import java.text.NumberFormat;
 
@@ -38,7 +41,9 @@
  * @hide
  */
 public class WirelessChargingLayout extends FrameLayout {
-    public final static int UNKNOWN_BATTERY_LEVEL = -1;
+    public static final int UNKNOWN_BATTERY_LEVEL = -1;
+    private static final long RIPPLE_ANIMATION_DURATION = 2000;
+    private ChargingRippleView mRippleView;
 
     public WirelessChargingLayout(Context context) {
         super(context);
@@ -120,6 +125,8 @@
         AnimatorSet animatorSet = new AnimatorSet();
         animatorSet.playTogether(textSizeAnimator, textOpacityAnimator, textFadeAnimator);
 
+        mRippleView = findViewById(R.id.wireless_charging_ripple);
+
         if (!showTransmittingBatteryLevel) {
             chargingAnimation.start();
             animatorSet.start();
@@ -195,4 +202,21 @@
         animatorSetTransmitting.start();
         animatorSetIcon.start();
     }
+
+    @Override
+    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        if (mRippleView != null) {
+            int width = getMeasuredWidth();
+            int height = getMeasuredHeight();
+            mRippleView.setColor(
+                    Utils.getColorAttr(mRippleView.getContext(),
+                            android.R.attr.colorAccent).getDefaultColor());
+            mRippleView.setOrigin(new PointF(width / 2, height / 2));
+            mRippleView.setRadius(Math.max(width, height) * 0.5f);
+            mRippleView.setDuration(RIPPLE_ANIMATION_DURATION);
+            mRippleView.startRipple();
+        }
+
+        super.onLayout(changed, left, top, right, bottom);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java
index 7e7cdce..6812f77 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java
@@ -46,7 +46,6 @@
 import java.util.Set;
 import java.util.StringJoiner;
 import java.util.stream.Collectors;
-import java.util.stream.Stream;
 
 import javax.inject.Inject;
 import javax.inject.Named;
@@ -107,11 +106,14 @@
         }
     };
 
-    private final FalsingDataProvider.GestureCompleteListener mGestureCompleteListener =
-            new FalsingDataProvider.GestureCompleteListener() {
+    private final FalsingDataProvider.GestureFinalizedListener mGestureFinalizedListener =
+            new FalsingDataProvider.GestureFinalizedListener() {
                 @Override
-                public void onGestureComplete(long completionTimeMs) {
+                public void onGestureFinalized(long completionTimeMs) {
                     if (mPriorResults != null) {
+                        boolean boolResult = mPriorResults.stream().anyMatch(
+                                FalsingClassifier.Result::isFalse);
+
                         mPriorResults.forEach(result -> {
                             if (result.isFalse()) {
                                 String reason = result.getReason();
@@ -121,8 +123,28 @@
                             }
                         });
 
+                        if (Build.IS_ENG || Build.IS_USERDEBUG) {
+                            // Copy motion events, as the results returned by
+                            // #getRecentMotionEvents are recycled elsewhere.
+                            RECENT_SWIPES.add(new DebugSwipeRecord(
+                                    boolResult,
+                                    mPriorInteractionType,
+                                    mDataProvider.getRecentMotionEvents().stream().map(
+                                            motionEvent -> new XYDt(
+                                                    (int) motionEvent.getX(),
+                                                    (int) motionEvent.getY(),
+                                                    (int) (motionEvent.getEventTime()
+                                                            - motionEvent.getDownTime())))
+                                            .collect(Collectors.toList())));
+                            while (RECENT_SWIPES.size() > RECENT_INFO_LOG_SIZE) {
+                                RECENT_SWIPES.remove();
+                            }
+                        }
+
+
                         mHistoryTracker.addResults(mPriorResults, completionTimeMs);
                         mPriorResults = null;
+                        mPriorInteractionType = Classifier.GENERIC;
                     } else {
                         // Gestures that were not classified get treated as a false.
                         mHistoryTracker.addResults(
@@ -135,6 +157,7 @@
             };
 
     private Collection<FalsingClassifier.Result> mPriorResults;
+    private @Classifier.InteractionType int mPriorInteractionType = Classifier.GENERIC;
 
     @Inject
     public BrightLineFalsingManager(FalsingDataProvider falsingDataProvider,
@@ -154,7 +177,7 @@
         mTestHarness = testHarness;
 
         mDataProvider.addSessionListener(mSessionListener);
-        mDataProvider.addGestureCompleteListener(mGestureCompleteListener);
+        mDataProvider.addGestureCompleteListener(mGestureFinalizedListener);
         mHistoryTracker.addBeliefListener(mBeliefListener);
     }
 
@@ -165,50 +188,33 @@
 
     @Override
     public boolean isFalseTouch(@Classifier.InteractionType int interactionType) {
+        mPriorInteractionType = interactionType;
         if (skipFalsing()) {
             return false;
         }
 
-        boolean result;
+        final boolean booleanResult;
 
         if (!mTestHarness && !mDataProvider.isJustUnlockedWithFace() && !mDockManager.isDocked()) {
-            Stream<FalsingClassifier.Result> results =
-                    mClassifiers.stream().map(falsingClassifier ->
-                            falsingClassifier.classifyGesture(
-                                    interactionType,
-                                    mHistoryTracker.falseBelief(),
-                                    mHistoryTracker.falseConfidence()));
-            mPriorResults = new ArrayList<>();
             final boolean[] localResult = {false};
-            results.forEach(classifierResult -> {
-                localResult[0] |= classifierResult.isFalse();
-                mPriorResults.add(classifierResult);
-            });
-            result = localResult[0];
+            mPriorResults = mClassifiers.stream().map(falsingClassifier -> {
+                FalsingClassifier.Result r = falsingClassifier.classifyGesture(
+                        interactionType,
+                        mHistoryTracker.falseBelief(),
+                        mHistoryTracker.falseConfidence());
+                localResult[0] |= r.isFalse();
+
+                return r;
+            }).collect(Collectors.toList());
+            booleanResult = localResult[0];
         } else {
-            result = false;
+            booleanResult = false;
             mPriorResults = Collections.singleton(FalsingClassifier.Result.passed(1));
         }
 
-        logDebug("False Gesture: " + result);
+        logDebug("False Gesture: " + booleanResult);
 
-        if (Build.IS_ENG || Build.IS_USERDEBUG) {
-            // Copy motion events, as the passed in list gets emptied out elsewhere in the code.
-            RECENT_SWIPES.add(new DebugSwipeRecord(
-                    result,
-                    interactionType,
-                    mDataProvider.getRecentMotionEvents().stream().map(
-                            motionEvent -> new XYDt(
-                                    (int) motionEvent.getX(),
-                                    (int) motionEvent.getY(),
-                                    (int) (motionEvent.getEventTime() - motionEvent.getDownTime())))
-                            .collect(Collectors.toList())));
-            while (RECENT_SWIPES.size() > RECENT_INFO_LOG_SIZE) {
-                RECENT_SWIPES.remove();
-            }
-        }
-
-        return result;
+        return booleanResult;
     }
 
     @Override
@@ -354,7 +360,7 @@
     @Override
     public void cleanup() {
         mDataProvider.removeSessionListener(mSessionListener);
-        mDataProvider.removeGestureCompleteListener(mGestureCompleteListener);
+        mDataProvider.removeGestureCompleteListener(mGestureFinalizedListener);
         mClassifiers.forEach(FalsingClassifier::cleanup);
         mFalsingBeliefListeners.clear();
         mHistoryTracker.removeBeliefListener(mBeliefListener);
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/Classifier.java b/packages/SystemUI/src/com/android/systemui/classifier/Classifier.java
index c7ad3e8..47b41f5 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/Classifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/Classifier.java
@@ -37,6 +37,7 @@
     public static final int GENERIC = 7;
     public static final int BOUNCER_UNLOCK = 8;
     public static final int PULSE_EXPAND = 9;
+    public static final int BRIGHTNESS_SLIDER = 10;
 
     @IntDef({
             QUICK_SETTINGS,
@@ -48,7 +49,8 @@
             RIGHT_AFFORDANCE,
             GENERIC,
             BOUNCER_UNLOCK,
-            PULSE_EXPAND
+            PULSE_EXPAND,
+            BRIGHTNESS_SLIDER
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface InteractionType {}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/DistanceClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/DistanceClassifier.java
index 5a9c386..80d7863 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/DistanceClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/DistanceClassifier.java
@@ -148,6 +148,10 @@
     Result calculateFalsingResult(
             @Classifier.InteractionType int interactionType,
             double historyBelief, double historyConfidence) {
+        if (interactionType == Classifier.BRIGHTNESS_SLIDER) {
+            return Result.passed(0);
+        }
+
         return !getPassedFlingThreshold() ? falsed(0.5, getReason()) : Result.passed(0.5);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java
index f665a74..1aaa139 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java
@@ -45,7 +45,7 @@
     private final float mYdpi;
     private final List<SessionListener> mSessionListeners = new ArrayList<>();
     private final List<MotionEventListener> mMotionEventListeners = new ArrayList<>();
-    private final List<GestureCompleteListener> mGestureCompleteListeners = new ArrayList<>();
+    private final List<GestureFinalizedListener> mGestureFinalizedListeners = new ArrayList<>();
 
     private TimeLimitedMotionEventBuffer mRecentMotionEvents =
             new TimeLimitedMotionEventBuffer(MOTION_EVENT_AGE_MS);
@@ -90,7 +90,7 @@
 
         mMotionEventListeners.forEach(listener -> listener.onMotionEvent(motionEvent));
 
-        // We explicitly do not complete a gesture on UP or CANCEL events.
+        // We explicitly do not "finalize" a gesture on UP or CANCEL events.
         // We wait for the next gesture to start before marking the prior gesture as complete.  This
         // has multiple benefits. First, it makes it trivial to track the "current" or "recent"
         // gesture, as it will always be found in mRecentMotionEvents. Second, and most importantly,
@@ -102,7 +102,7 @@
 
     private void completePriorGesture() {
         if (!mRecentMotionEvents.isEmpty()) {
-            mGestureCompleteListeners.forEach(listener -> listener.onGestureComplete(
+            mGestureFinalizedListeners.forEach(listener -> listener.onGestureFinalized(
                     mRecentMotionEvents.get(mRecentMotionEvents.size() - 1).getEventTime()));
 
             mPriorMotionEvents = mRecentMotionEvents;
@@ -312,14 +312,14 @@
         mMotionEventListeners.remove(listener);
     }
 
-    /** Register a {@link GestureCompleteListener}. */
-    public void addGestureCompleteListener(GestureCompleteListener listener) {
-        mGestureCompleteListeners.add(listener);
+    /** Register a {@link GestureFinalizedListener}. */
+    public void addGestureCompleteListener(GestureFinalizedListener listener) {
+        mGestureFinalizedListeners.add(listener);
     }
 
-    /** Unregister a {@link GestureCompleteListener}. */
-    public void removeGestureCompleteListener(GestureCompleteListener listener) {
-        mGestureCompleteListeners.remove(listener);
+    /** Unregister a {@link GestureFinalizedListener}. */
+    public void removeGestureCompleteListener(GestureFinalizedListener listener) {
+        mGestureFinalizedListeners.remove(listener);
     }
 
     void onSessionStarted() {
@@ -362,8 +362,12 @@
     }
 
     /** Callback to be alerted when the current gesture ends. */
-    public interface GestureCompleteListener {
-        /** */
-        void onGestureComplete(long completionTimeMs);
+    public interface GestureFinalizedListener {
+        /**
+         * Called just before a new gesture starts.
+         *
+         * Any pending work on a prior gesture can be considered cemented in place.
+         */
+        void onGestureFinalized(long completionTimeMs);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/ProximityClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/ProximityClassifier.java
index ac330f0..6f80010 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/ProximityClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/ProximityClassifier.java
@@ -17,6 +17,7 @@
 package com.android.systemui.classifier;
 
 import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_PROXIMITY_PERCENT_COVERED_THRESHOLD;
+import static com.android.systemui.classifier.Classifier.BRIGHTNESS_SLIDER;
 import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS;
 
 import android.provider.DeviceConfig;
@@ -115,7 +116,7 @@
     Result calculateFalsingResult(
             @Classifier.InteractionType int interactionType,
             double historyBelief, double historyConfidence) {
-        if (interactionType == QUICK_SETTINGS) {
+        if (interactionType == QUICK_SETTINGS || interactionType == BRIGHTNESS_SLIDER) {
             return Result.passed(0);
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/TypeClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/TypeClassifier.java
index 427c2ef..f665565 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/TypeClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/TypeClassifier.java
@@ -18,6 +18,7 @@
 
 
 import static com.android.systemui.classifier.Classifier.BOUNCER_UNLOCK;
+import static com.android.systemui.classifier.Classifier.BRIGHTNESS_SLIDER;
 import static com.android.systemui.classifier.Classifier.LEFT_AFFORDANCE;
 import static com.android.systemui.classifier.Classifier.NOTIFICATION_DISMISS;
 import static com.android.systemui.classifier.Classifier.NOTIFICATION_DRAG_DOWN;
@@ -45,6 +46,7 @@
         boolean up = isUp();
         boolean right = isRight();
 
+        double confidence = 1;
         boolean wrongDirection = true;
         switch (interactionType) {
             case QUICK_SETTINGS:
@@ -52,6 +54,11 @@
             case NOTIFICATION_DRAG_DOWN:
                 wrongDirection = !vertical || up;
                 break;
+            case BRIGHTNESS_SLIDER:
+                confidence = 0;  // Owners may return to original brightness.
+                // A more sophisticated thing to do here would be to look at the size of the
+                // vertical change relative to the screen size. _Some_ amount of vertical
+                // change should be expected.
             case NOTIFICATION_DISMISS:
                 wrongDirection = vertical;
                 break;
@@ -70,7 +77,7 @@
                 break;
         }
 
-        return wrongDirection ? falsed(1, getReason(interactionType)) : Result.passed(0.5);
+        return wrongDirection ? falsed(confidence, getReason(interactionType)) : Result.passed(0.5);
     }
 
     private String getReason(int interactionType) {
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/ZigZagClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/ZigZagClassifier.java
index 1d413af..d9197ef 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/ZigZagClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/ZigZagClassifier.java
@@ -20,6 +20,7 @@
 import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_ZIGZAG_X_SECONDARY_DEVIANCE;
 import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_ZIGZAG_Y_PRIMARY_DEVIANCE;
 import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_ZIGZAG_Y_SECONDARY_DEVIANCE;
+import static com.android.systemui.classifier.Classifier.BRIGHTNESS_SLIDER;
 
 import android.graphics.Point;
 import android.provider.DeviceConfig;
@@ -87,6 +88,10 @@
     Result calculateFalsingResult(
             @Classifier.InteractionType int interactionType,
             double historyBelief, double historyConfidence) {
+        if (interactionType == BRIGHTNESS_SLIDER) {
+            return Result.passed(0);
+        }
+
         List<MotionEvent> motionEvents = getRecentMotionEvents();
         // Rotate horizontal gestures to be horizontal between their first and last point.
         // Rotate vertical gestures to be vertical between their first and last point.
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
index ed3d5ec..8e4e308 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.dagger;
 
+import com.android.keyguard.clock.ClockOptionsProvider;
 import com.android.systemui.BootCompleteCacheImpl;
 import com.android.systemui.Dependency;
 import com.android.systemui.InitController;
@@ -150,4 +151,9 @@
      * Member injection into the supplied argument.
      */
     void inject(KeyguardSliceProvider keyguardSliceProvider);
+
+    /**
+     * Member injection into the supplied argument.
+     */
+    void inject(ClockOptionsProvider clockOptionsProvider);
 }
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
index b0067cd..b67db03 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
@@ -22,6 +22,7 @@
 import androidx.annotation.Nullable;
 
 import com.android.internal.statusbar.IStatusBarService;
+import com.android.keyguard.clock.ClockModule;
 import com.android.keyguard.dagger.KeyguardBouncerComponent;
 import com.android.systemui.BootCompleteCache;
 import com.android.systemui.BootCompleteCacheImpl;
@@ -90,6 +91,7 @@
 @Module(includes = {
             AppOpsModule.class,
             AssistModule.class,
+            ClockModule.class,
             ControlsModule.class,
             DemoModeModule.class,
             FalsingModule.class,
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
index 52c9f16..b7f6e2b 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
@@ -186,7 +186,7 @@
                 new TriggerSensor(
                         findSensorWithType(config.quickPickupSensorType()),
                         Settings.Secure.DOZE_QUICK_PICKUP_GESTURE,
-                        false /* setting default */,
+                        true /* setting default */,
                         config.quickPickupSensorEnabled(KeyguardUpdateMonitor.getCurrentUser())
                                 && udfpsEnrolled,
                         DozeLog.REASON_SENSOR_QUICK_PICKUP,
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
index 04b4670..aa66b75 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
@@ -531,9 +531,13 @@
         Assert.isMainThread();
         mDozeHost.extendPulse(reason);
 
+        // we can't determine the dozing state if we're currently transitioning
+        final DozeMachine.State dozeState =
+                mMachine.isExecutingTransition() ? null : mMachine.getState();
+
         // When already pulsing we're allowed to show the wallpaper directly without
         // requesting a new pulse.
-        if (mMachine.getState() == DozeMachine.State.DOZE_PULSING
+        if (dozeState == DozeMachine.State.DOZE_PULSING
                 && reason == DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN) {
             mMachine.requestState(DozeMachine.State.DOZE_PULSING_BRIGHT);
             return;
@@ -541,8 +545,7 @@
 
         if (mPulsePending || !mAllowPulseTriggers || !canPulse()) {
             if (mAllowPulseTriggers) {
-                mDozeLog.tracePulseDropped(mPulsePending, mMachine.getState(),
-                        mDozeHost.isPulsingBlocked());
+                mDozeLog.tracePulseDropped(mPulsePending, dozeState, mDozeHost.isPulsingBlocked());
             }
             runIfNotNull(onPulseSuppressedListener);
             return;
diff --git a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagReader.java b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagReader.java
index 073586e..6fbf81c 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagReader.java
+++ b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagReader.java
@@ -44,12 +44,12 @@
  * previous example, do the following:
  *
  * {@code
- *  $ adb shell device_config put systemui flag_foo_bar_baz true
+ *  $ adb shell setprop persist.systemui.flag_foo_bar_baz 1
  * }
  *
  * Note that all storage keys begin with "flag_", even if their associated resId does not.
  *
- * Calls to this class should probably be wrapped by {@link FeatureFlags}.
+ * Calls to this class should probably be wrapped by a method in {@link FeatureFlags}.
  */
 @SysUISingleton
 public class FeatureFlagReader {
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
index 461a730..1862718 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
@@ -50,6 +50,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.SharedPreferences;
+import android.content.pm.PackageManager;
 import android.content.pm.UserInfo;
 import android.content.res.ColorStateList;
 import android.content.res.Configuration;
@@ -72,8 +73,8 @@
 import android.service.dreams.IDreamManager;
 import android.sysprop.TelephonyProperties;
 import android.telecom.TelecomManager;
-import android.telephony.PhoneStateListener;
 import android.telephony.ServiceState;
+import android.telephony.TelephonyCallback;
 import android.telephony.TelephonyManager;
 import android.transition.AutoTransition;
 import android.transition.TransitionManager;
@@ -137,6 +138,7 @@
 import com.android.systemui.statusbar.NotificationShadeWindowController;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.telephony.TelephonyListenerManager;
 import com.android.systemui.util.EmergencyDialerConstants;
 import com.android.systemui.util.RingerModeTracker;
 import com.android.systemui.util.leak.RotationUtils;
@@ -302,7 +304,8 @@
             AudioManager audioManager, IDreamManager iDreamManager,
             DevicePolicyManager devicePolicyManager, LockPatternUtils lockPatternUtils,
             BroadcastDispatcher broadcastDispatcher,
-            ConnectivityManager connectivityManager, TelephonyManager telephonyManager,
+            ConnectivityManager connectivityManager,
+            TelephonyListenerManager telephonyListenerManager,
             ContentResolver contentResolver, @Nullable Vibrator vibrator, @Main Resources resources,
             ConfigurationController configurationController, ActivityStarter activityStarter,
             KeyguardStateController keyguardStateController, UserManager userManager,
@@ -356,10 +359,11 @@
         filter.addAction(TelephonyManager.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED);
         mBroadcastDispatcher.registerReceiver(mBroadcastReceiver, filter);
 
-        mHasTelephony = connectivityManager.isNetworkSupported(ConnectivityManager.TYPE_MOBILE);
+        mHasTelephony =
+                context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
 
         // get notified of phone state changes
-        telephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_SERVICE_STATE);
+        telephonyListenerManager.addServiceStateListener(mPhoneStateListener);
         contentResolver.registerContentObserver(
                 Settings.Global.getUriFor(Settings.Global.AIRPLANE_MODE_ON), true,
                 mAirplaneModeObserver);
@@ -2047,7 +2051,8 @@
         }
     };
 
-    PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
+    private final TelephonyCallback.ServiceStateListener mPhoneStateListener =
+            new TelephonyCallback.ServiceStateListener() {
         @Override
         public void onServiceStateChanged(ServiceState serviceState) {
             if (!mHasTelephony) return;
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 de2e7c47..a747edd 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java
@@ -30,6 +30,7 @@
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.KeyguardViewController;
 import com.android.keyguard.dagger.KeyguardQsUserSwitchComponent;
+import com.android.keyguard.dagger.KeyguardStatusBarViewComponent;
 import com.android.keyguard.dagger.KeyguardStatusViewComponent;
 import com.android.keyguard.dagger.KeyguardUserSwitcherComponent;
 import com.android.systemui.broadcast.BroadcastDispatcher;
@@ -63,8 +64,11 @@
 /**
  * Dagger Module providing {@link StatusBar}.
  */
-@Module(subcomponents = {KeyguardStatusViewComponent.class,
-        KeyguardQsUserSwitchComponent.class, KeyguardUserSwitcherComponent.class},
+@Module(subcomponents = {
+        KeyguardQsUserSwitchComponent.class,
+        KeyguardStatusBarViewComponent.class,
+        KeyguardStatusViewComponent.class,
+        KeyguardUserSwitcherComponent.class},
         includes = {FalsingModule.class})
 public class KeyguardModule {
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/media/systemsounds/HomeSoundEffectController.java b/packages/SystemUI/src/com/android/systemui/media/systemsounds/HomeSoundEffectController.java
index dd3d02a..31e4939 100644
--- a/packages/SystemUI/src/com/android/systemui/media/systemsounds/HomeSoundEffectController.java
+++ b/packages/SystemUI/src/com/android/systemui/media/systemsounds/HomeSoundEffectController.java
@@ -16,38 +16,64 @@
 
 package com.android.systemui.media.systemsounds;
 
+import android.Manifest;
 import android.app.ActivityManager;
 import android.app.WindowConfiguration;
 import android.content.Context;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
 import android.media.AudioManager;
+import android.util.Slog;
 
+import com.android.systemui.R;
 import com.android.systemui.SystemUI;
 import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.shared.system.TaskStackChangeListener;
 import com.android.systemui.shared.system.TaskStackChangeListeners;
 
 import javax.inject.Inject;
 
 /**
- * If a sound effect is defined for {@link android.media.AudioManager#FX_HOME}, a sound is played
- * when the home task moves to front and the last task that moved to front was not the home task.
+ * If a sound effect is defined for {@link android.media.AudioManager#FX_HOME}, a
+ * {@link TaskStackChangeListener} is registered to play a home sound effect when conditions
+ * documented at {@link #handleTaskStackChanged} apply.
  */
 @SysUISingleton
 public class HomeSoundEffectController extends SystemUI {
 
+    private static final String TAG = "HomeSoundEffectController";
     private final AudioManager mAudioManager;
     private final TaskStackChangeListeners mTaskStackChangeListeners;
+    private final ActivityManagerWrapper mActivityManagerWrapper;
+    private final PackageManager mPm;
+    private final boolean mPlayHomeSoundAfterAssistant;
+    private final boolean mPlayHomeSoundAfterDream;
     // Initialize true because home sound should not be played when the system boots.
     private boolean mIsLastTaskHome = true;
+    // mLastHomePackageName could go out of sync in rare circumstances if launcher changes,
+    // but it's cheaper than the alternative and potential impact is low
+    private String mLastHomePackageName;
+    private @WindowConfiguration.ActivityType int mLastActivityType;
+    private boolean mLastActivityHasNoHomeSound = false;
+    private int mLastTaskId;
 
     @Inject
     public HomeSoundEffectController(
             Context context,
             AudioManager audioManager,
-            TaskStackChangeListeners taskStackChangeListeners) {
+            TaskStackChangeListeners taskStackChangeListeners,
+            ActivityManagerWrapper activityManagerWrapper,
+            PackageManager packageManager) {
         super(context);
         mAudioManager = audioManager;
         mTaskStackChangeListeners = taskStackChangeListeners;
+        mActivityManagerWrapper = activityManagerWrapper;
+        mPm = packageManager;
+        mPlayHomeSoundAfterAssistant = context.getResources().getBoolean(
+                R.bool.config_playHomeSoundAfterAssistant);
+        mPlayHomeSoundAfterDream = context.getResources().getBoolean(
+                R.bool.config_playHomeSoundAfterDream);
     }
 
     @Override
@@ -56,27 +82,94 @@
             mTaskStackChangeListeners.registerTaskStackListener(
                     new TaskStackChangeListener() {
                         @Override
-                        public void onTaskMovedToFront(ActivityManager.RunningTaskInfo taskInfo) {
-                            handleHomeTaskMovedToFront(taskInfo);
+                        public void onTaskStackChanged() {
+                            ActivityManager.RunningTaskInfo currentTask =
+                                    mActivityManagerWrapper.getRunningTask();
+                            if (currentTask == null || currentTask.topActivityInfo == null) {
+                                return;
+                            }
+                            handleTaskStackChanged(currentTask);
                         }
                     });
         }
     }
 
-    private boolean isHomeTask(ActivityManager.RunningTaskInfo taskInfo) {
-        return taskInfo.getActivityType() == WindowConfiguration.ACTIVITY_TYPE_HOME;
+    private boolean hasFlagNoSound(ActivityInfo activityInfo) {
+        if ((activityInfo.privateFlags & ActivityInfo.PRIVATE_FLAG_HOME_TRANSITION_SOUND) == 0) {
+            // Only allow flag if app has permission
+            if (mPm.checkPermission(Manifest.permission.DISABLE_SYSTEM_SOUND_EFFECTS,
+                    activityInfo.packageName) == PackageManager.PERMISSION_GRANTED) {
+                return true;
+            } else {
+                Slog.w(TAG,
+                        "Activity has flag playHomeTransition set to false but doesn't hold "
+                                + "required permission "
+                                + Manifest.permission.DISABLE_SYSTEM_SOUND_EFFECTS);
+                return false;
+            }
+        }
+        return false;
     }
 
     /**
-     * To enable a home sound, check if the home app moves to front.
+     * The home sound is played if all of the following conditions are met:
+     * <ul>
+     * <li>The last task which moved to front was not home. This avoids playing the sound
+     * e.g. after FallbackHome transitions to home, another activity of the home app like a
+     * notification panel moved to front, or in case the home app crashed.</li>
+     * <li>The current activity which moved to front is home</li>
+     * <li>The topActivity of the last task has {@link android.R.attr#playHomeTransitionSound} set
+     * to <code>true</code>.</li>
+     * <li>The topActivity of the last task is not of type
+     * {@link WindowConfiguration#ACTIVITY_TYPE_ASSISTANT} if config_playHomeSoundAfterAssistant is
+     * set to <code>false</code> (default).</li>
+     * <li>The topActivity of the last task is not of type
+     * {@link WindowConfiguration#ACTIVITY_TYPE_DREAM} if config_playHomeSoundAfterDream is
+     * set to <code>false</code> (default).</li>
+     * </ul>
      */
-    private void handleHomeTaskMovedToFront(ActivityManager.RunningTaskInfo taskInfo) {
-        boolean isCurrentTaskHome = isHomeTask(taskInfo);
-        // If the last task is home we don't want to play the home sound. This avoids playing
-        // the home sound after FallbackHome transitions to Home
-        if (!mIsLastTaskHome && isCurrentTaskHome) {
+    private boolean shouldPlayHomeSoundForCurrentTransition(
+            ActivityManager.RunningTaskInfo currentTask) {
+        boolean isHomeActivity =
+                currentTask.topActivityType == WindowConfiguration.ACTIVITY_TYPE_HOME;
+        if (currentTask.taskId == mLastTaskId) {
+            return false;
+        }
+        if (mIsLastTaskHome || !isHomeActivity) {
+            return false;
+        }
+        if (mLastActivityHasNoHomeSound) {
+            return false;
+        }
+        if (mLastActivityType == WindowConfiguration.ACTIVITY_TYPE_ASSISTANT
+                && !mPlayHomeSoundAfterAssistant) {
+            return false;
+        }
+        if (mLastActivityType == WindowConfiguration.ACTIVITY_TYPE_DREAM
+                && !mPlayHomeSoundAfterDream) {
+            return false;
+        }
+        return true;
+    }
+
+    private void updateLastTaskInfo(ActivityManager.RunningTaskInfo currentTask) {
+        mLastTaskId = currentTask.taskId;
+        mLastActivityType = currentTask.topActivityType;
+        mLastActivityHasNoHomeSound = hasFlagNoSound(currentTask.topActivityInfo);
+        boolean isHomeActivity =
+                currentTask.topActivityType == WindowConfiguration.ACTIVITY_TYPE_HOME;
+        boolean isHomePackage = currentTask.topActivityInfo.packageName.equals(
+                mLastHomePackageName);
+        mIsLastTaskHome = isHomeActivity || isHomePackage;
+        if (isHomeActivity && !isHomePackage) {
+            mLastHomePackageName = currentTask.topActivityInfo.packageName;
+        }
+    }
+
+    private void handleTaskStackChanged(ActivityManager.RunningTaskInfo frontTask) {
+        if (shouldPlayHomeSoundForCurrentTransition(frontTask)) {
             mAudioManager.playSoundEffect(AudioManager.FX_HOME);
         }
-        mIsLastTaskHome = isCurrentTaskHome;
+        updateLastTaskInfo(frontTask);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
index 9d43e0c..c8dfde1 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
@@ -209,6 +209,8 @@
     private @TransitionMode int mNavigationBarMode;
     private ContentResolver mContentResolver;
     private boolean mAssistantAvailable;
+    private boolean mLongPressHomeEnabled;
+    private boolean mAssistantTouchGestureEnabled;
 
     private int mDisabledFlags1;
     private int mDisabledFlags2;
@@ -309,7 +311,7 @@
 
             // Send the assistant availability upon connection
             if (isConnected) {
-                sendAssistantAvailability(mAssistantAvailable);
+                updateAssistantEntrypoints();
             }
         }
 
@@ -404,12 +406,7 @@
             new Handler(Looper.getMainLooper())) {
         @Override
         public void onChange(boolean selfChange, Uri uri) {
-            boolean available = mAssistManagerLazy.get()
-                    .getAssistInfoForUser(UserHandle.USER_CURRENT) != null;
-            if (mAssistantAvailable != available) {
-                sendAssistantAvailability(available);
-                mAssistantAvailable = available;
-            }
+            updateAssistantEntrypoints();
         }
     };
 
@@ -531,6 +528,13 @@
         mContentResolver.registerContentObserver(
                 Settings.Secure.getUriFor(Settings.Secure.ASSISTANT),
                 false /* notifyForDescendants */, mAssistContentObserver, UserHandle.USER_ALL);
+        mContentResolver.registerContentObserver(
+                Settings.Secure.getUriFor(Settings.Secure.ASSIST_LONG_PRESS_HOME_ENABLED),
+                false, mAssistContentObserver, UserHandle.USER_ALL);
+        mContentResolver.registerContentObserver(
+                Settings.Secure.getUriFor(Settings.Secure.ASSIST_TOUCH_GESTURE_ENABLED),
+                false, mAssistContentObserver, UserHandle.USER_ALL);
+        updateAssistantEntrypoints();
 
         if (savedState != null) {
             mDisabledFlags1 = savedState.getInt(EXTRA_DISABLE_STATE, 0);
@@ -823,7 +827,7 @@
                 || mNavigationBarView.getHomeButton().getCurrentView() == null) {
             return;
         }
-        if (mHomeButtonLongPressDurationMs.isPresent()) {
+        if (mHomeButtonLongPressDurationMs.isPresent() || !mLongPressHomeEnabled) {
             mNavigationBarView.getHomeButton().getCurrentView().setLongClickable(false);
             mNavigationBarView.getHomeButton().getCurrentView().setHapticFeedbackEnabled(false);
             mNavigationBarView.getHomeButton().setOnLongClickListener(null);
@@ -845,6 +849,8 @@
         pw.println("  mStartingQuickSwitchRotation=" + mStartingQuickSwitchRotation);
         pw.println("  mCurrentRotation=" + mCurrentRotation);
         pw.println("  mHomeButtonLongPressDurationMs=" + mHomeButtonLongPressDurationMs);
+        pw.println("  mLongPressHomeEnabled=" + mLongPressHomeEnabled);
+        pw.println("  mAssistantTouchGestureEnabled=" + mAssistantTouchGestureEnabled);
 
         if (mNavigationBarView != null) {
             pw.println("  mNavigationBarWindowState="
@@ -1206,9 +1212,11 @@
                         return true;
                     }
                 }
-                mHomeButtonLongPressDurationMs.ifPresent(longPressDuration -> {
-                    mHandler.postDelayed(mOnVariableDurationHomeLongClick, longPressDuration);
-                });
+                if (mLongPressHomeEnabled) {
+                    mHomeButtonLongPressDurationMs.ifPresent(longPressDuration -> {
+                        mHandler.postDelayed(mOnVariableDurationHomeLongClick, longPressDuration);
+                    });
+                }
                 break;
             case MotionEvent.ACTION_UP:
             case MotionEvent.ACTION_CANCEL:
@@ -1480,15 +1488,23 @@
                 | (requestingServices >= 2 ? SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE : 0);
     }
 
-    private void sendAssistantAvailability(boolean available) {
+    private void updateAssistantEntrypoints() {
+        mAssistantAvailable = mAssistManagerLazy.get()
+                .getAssistInfoForUser(UserHandle.USER_CURRENT) != null;
+        mLongPressHomeEnabled = Settings.Secure.getInt(mContentResolver,
+                Settings.Secure.ASSIST_LONG_PRESS_HOME_ENABLED, 1) != 0;
+        mAssistantTouchGestureEnabled = Settings.Secure.getInt(mContentResolver,
+                Settings.Secure.ASSIST_TOUCH_GESTURE_ENABLED, 1) != 0;
         if (mOverviewProxyService.getProxy() != null) {
             try {
-                mOverviewProxyService.getProxy().onAssistantAvailable(available
+                mOverviewProxyService.getProxy().onAssistantAvailable(mAssistantAvailable
+                        && mAssistantTouchGestureEnabled
                         && QuickStepContract.isGesturalMode(mNavBarMode));
             } catch (RemoteException e) {
                 Log.w(TAG, "Unable to send assistant availability data to launcher");
             }
         }
+        reconfigureHomeLongClick();
     }
 
     // ----- Methods that DisplayNavigationBarController talks to -----
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarOverlayController.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarOverlayController.java
index 62b9458..2d0d5cd 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarOverlayController.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarOverlayController.java
@@ -21,7 +21,6 @@
 import android.view.View;
 
 import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.statusbar.FeatureFlags;
 
 import java.util.function.Consumer;
 
@@ -32,12 +31,10 @@
 public class NavigationBarOverlayController {
 
     protected final Context mContext;
-    protected final FeatureFlags mFeatureFlags;
 
     @Inject
-    public NavigationBarOverlayController(Context context, FeatureFlags featureFlags) {
+    public NavigationBarOverlayController(Context context) {
         mContext = context;
-        mFeatureFlags = featureFlags;
     }
 
     public Context getContext() {
@@ -45,7 +42,7 @@
     }
 
     public boolean isNavigationBarOverlayEnabled() {
-        return mFeatureFlags.isNavigationBarOverlayEnabled();
+        return false;
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java
index f9c2a2a..440c5ef 100644
--- a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java
+++ b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java
@@ -18,42 +18,23 @@
 
 import static android.app.Notification.CATEGORY_MISSED_CALL;
 import static android.app.Notification.EXTRA_MESSAGES;
-import static android.app.people.ConversationStatus.ACTIVITY_ANNIVERSARY;
-import static android.app.people.ConversationStatus.ACTIVITY_AUDIO;
-import static android.app.people.ConversationStatus.ACTIVITY_BIRTHDAY;
-import static android.app.people.ConversationStatus.ACTIVITY_GAME;
-import static android.app.people.ConversationStatus.ACTIVITY_LOCATION;
-import static android.app.people.ConversationStatus.ACTIVITY_NEW_STORY;
-import static android.app.people.ConversationStatus.ACTIVITY_UPCOMING_BIRTHDAY;
-import static android.app.people.ConversationStatus.ACTIVITY_VIDEO;
-import static android.app.people.ConversationStatus.AVAILABILITY_AVAILABLE;
-import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT;
-import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH;
-import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT;
-import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH;
 
-import android.annotation.Nullable;
 import android.app.INotificationManager;
 import android.app.Notification;
-import android.app.PendingIntent;
 import android.app.people.ConversationChannel;
-import android.app.people.ConversationStatus;
 import android.app.people.IPeopleManager;
 import android.app.people.PeopleSpaceTile;
 import android.appwidget.AppWidgetManager;
 import android.content.Context;
-import android.content.Intent;
 import android.content.SharedPreferences;
 import android.content.pm.LauncherApps;
 import android.content.pm.ShortcutInfo;
-import android.content.res.Configuration;
 import android.database.Cursor;
 import android.database.SQLException;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
-import android.graphics.drawable.Icon;
 import android.icu.text.MeasureFormat;
 import android.icu.util.Measure;
 import android.icu.util.MeasureUnit;
@@ -66,10 +47,7 @@
 import android.service.notification.ConversationChannelWrapper;
 import android.service.notification.StatusBarNotification;
 import android.text.TextUtils;
-import android.util.IconDrawableFactory;
 import android.util.Log;
-import android.util.TypedValue;
-import android.view.View;
 import android.widget.RemoteViews;
 
 import androidx.preference.PreferenceManager;
@@ -81,8 +59,6 @@
 import com.android.settingslib.utils.ThreadUtils;
 import com.android.systemui.R;
 import com.android.systemui.people.widget.AppWidgetOptionsHelper;
-import com.android.systemui.people.widget.LaunchConversationActivity;
-import com.android.systemui.people.widget.PeopleSpaceWidgetProvider;
 import com.android.systemui.people.widget.PeopleTileKey;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -99,10 +75,7 @@
 import java.util.Locale;
 import java.util.Map;
 import java.util.Objects;
-import java.util.Optional;
 import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
@@ -123,18 +96,6 @@
 
     public static final PeopleTileKey EMPTY_KEY =
             new PeopleTileKey(EMPTY_STRING, INVALID_USER_ID, EMPTY_STRING);
-    public static final int SMALL_LAYOUT = 0;
-    public static final int MEDIUM_LAYOUT = 1;
-    @VisibleForTesting
-    static final int REQUIRED_WIDTH_FOR_MEDIUM = 146;
-    private static final int AVATAR_SIZE_FOR_MEDIUM = 56;
-    private static final int DEFAULT_WIDTH = 146;
-    private static final int DEFAULT_HEIGHT = 92;
-
-    private static final Pattern DOUBLE_EXCLAMATION_PATTERN = Pattern.compile("[!][!]+");
-    private static final Pattern DOUBLE_QUESTION_PATTERN = Pattern.compile("[?][?]+");
-    private static final Pattern ANY_DOUBLE_MARK_PATTERN = Pattern.compile("[!?][!?]+");
-    private static final Pattern MIXED_MARK_PATTERN = Pattern.compile("![?].*|.*[?]!");
 
     /** Represents whether {@link StatusBarNotification} was posted or removed. */
     public enum NotificationAction {
@@ -214,7 +175,7 @@
 
     /** Sets all relevant storage for {@code appWidgetId} association to {@code tile}. */
     public static void setSharedPreferencesStorageForTile(Context context, PeopleTileKey key,
-            int appWidgetId) {
+            int appWidgetId, Uri contactUri) {
         // Write relevant persisted storage.
         SharedPreferences widgetSp = context.getSharedPreferences(String.valueOf(appWidgetId),
                 Context.MODE_PRIVATE);
@@ -225,27 +186,24 @@
         widgetEditor.apply();
         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
         SharedPreferences.Editor editor = sp.edit();
-        editor.putString(String.valueOf(appWidgetId), key.getShortcutId());
+        String contactUriString = contactUri == null ? EMPTY_STRING : contactUri.toString();
+        editor.putString(String.valueOf(appWidgetId), contactUriString);
 
         // Don't overwrite existing widgets with the same key.
-        Set<String> storedWidgetIds = new HashSet<>(
-                sp.getStringSet(key.toString(), new HashSet<>()));
-        storedWidgetIds.add(String.valueOf(appWidgetId));
-        editor.putStringSet(key.toString(), storedWidgetIds);
+        addAppWidgetIdForKey(sp, editor, appWidgetId, key.toString());
+        addAppWidgetIdForKey(sp, editor, appWidgetId, contactUriString);
         editor.apply();
     }
 
     /** Removes stored data when tile is deleted. */
     public static void removeSharedPreferencesStorageForTile(Context context, PeopleTileKey key,
-            int widgetId) {
+            int widgetId, String contactUriString) {
         // Delete widgetId mapping to key.
         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
         SharedPreferences.Editor editor = sp.edit();
-        Set<String> storedWidgetIds = new HashSet<>(
-                sp.getStringSet(key.toString(), new HashSet<>()));
-        storedWidgetIds.remove(String.valueOf(widgetId));
-        editor.putStringSet(key.toString(), storedWidgetIds);
         editor.remove(String.valueOf(widgetId));
+        removeAppWidgetIdForKey(sp, editor, widgetId, key.toString());
+        removeAppWidgetIdForKey(sp, editor, widgetId, contactUriString);
         editor.apply();
 
         // Delete all data specifically mapped to widgetId.
@@ -258,6 +216,23 @@
         widgetEditor.apply();
     }
 
+    private static void addAppWidgetIdForKey(SharedPreferences sp, SharedPreferences.Editor editor,
+            int widgetId, String storageKey) {
+        Set<String> storedWidgetIdsByKey = new HashSet<>(
+                sp.getStringSet(storageKey, new HashSet<>()));
+        storedWidgetIdsByKey.add(String.valueOf(widgetId));
+        editor.putStringSet(storageKey, storedWidgetIdsByKey);
+    }
+
+    private static void removeAppWidgetIdForKey(SharedPreferences sp,
+            SharedPreferences.Editor editor,
+            int widgetId, String storageKey) {
+        Set<String> storedWidgetIds = new HashSet<>(
+                sp.getStringSet(storageKey, new HashSet<>()));
+        storedWidgetIds.remove(String.valueOf(widgetId));
+        editor.putStringSet(storageKey, storedWidgetIds);
+    }
+
     /** Augments a single {@link PeopleSpaceTile} with notification content, if one is present. */
     public static PeopleSpaceTile augmentSingleTileFromVisibleNotifications(Context context,
             PeopleSpaceTile tile, NotificationEntryManager notificationEntryManager) {
@@ -295,7 +270,7 @@
             PeopleSpaceTile tile, Map<PeopleTileKey, NotificationEntry> visibleNotifications) {
         PeopleTileKey key = new PeopleTileKey(
                 tile.getId(), getUserId(tile), tile.getPackageName());
-
+        // TODO: Match missed calls with matching Uris in addition to keys.
         if (!visibleNotifications.containsKey(key)) {
             if (DEBUG) Log.d(TAG, "No existing notifications for key:" + key.toString());
             return tile;
@@ -313,13 +288,17 @@
             return tile;
         }
         boolean isMissedCall = Objects.equals(notification.category, CATEGORY_MISSED_CALL);
-        Notification.MessagingStyle.Message message = getLastMessagingStyleMessage(notification);
+        List<Notification.MessagingStyle.Message> messages =
+                getMessagingStyleMessages(notification);
 
-        if (!isMissedCall && message == null) {
+        if (!isMissedCall && ArrayUtils.isEmpty(messages)) {
             if (DEBUG) Log.d(TAG, "Notification has no content");
             return tile;
         }
 
+        // messages are in chronological order from most recent to least.
+        Notification.MessagingStyle.Message message = messages != null ? messages.get(0) : null;
+        int messagesCount = messages != null ? messages.size() : 0;
         // If it's a missed call notification and it doesn't include content, use fallback value,
         // otherwise, use notification content.
         boolean hasMessageText = message != null && !TextUtils.isEmpty(message.getText());
@@ -333,369 +312,16 @@
                 .setNotificationCategory(notification.category)
                 .setNotificationContent(content)
                 .setNotificationDataUri(dataUri)
+                .setMessagesCount(messagesCount)
                 .build();
     }
 
-    /** Creates a {@link RemoteViews} for {@code tile}. */
-    public static RemoteViews createRemoteViews(Context context,
-            PeopleSpaceTile tile, int appWidgetId, Bundle options) {
-        int layoutSize = getLayoutSize(context, options);
-        RemoteViews viewsForTile = getViewForTile(context, tile, layoutSize);
-        int maxAvatarSize = getMaxAvatarSize(context, options, layoutSize);
-        RemoteViews views = setCommonRemoteViewsFields(context, viewsForTile, tile, maxAvatarSize);
-        return setLaunchIntents(context, views, tile, appWidgetId);
-    }
-
     /**
-     * The prioritization for the {@code tile} content is missed calls, followed by notification
-     * content, then birthdays, then the most recent status, and finally last interaction.
+     * Returns {@link Notification.MessagingStyle.Message}s from the Notification in chronological
+     * order from most recent to least.
      */
-    private static RemoteViews getViewForTile(Context context, PeopleSpaceTile tile,
-            int layoutSize) {
-        if (Objects.equals(tile.getNotificationCategory(), CATEGORY_MISSED_CALL)) {
-            if (DEBUG) Log.d(TAG, "Create missed call view");
-            return createMissedCallRemoteViews(context, tile, layoutSize);
-        }
-
-        if (tile.getNotificationKey() != null) {
-            if (DEBUG) Log.d(TAG, "Create notification view");
-            return createNotificationRemoteViews(context, tile, layoutSize);
-        }
-
-        // TODO: Add sorting when we expose timestamp of statuses.
-        List<ConversationStatus> statusesForEntireView =
-                tile.getStatuses() == null ? Arrays.asList() : tile.getStatuses().stream().filter(
-                        c -> isStatusValidForEntireStatusView(c)).collect(Collectors.toList());
-        ConversationStatus birthdayStatus = getBirthdayStatus(tile, statusesForEntireView);
-        if (birthdayStatus != null) {
-            if (DEBUG) Log.d(TAG, "Create birthday view");
-            return createStatusRemoteViews(context, birthdayStatus, layoutSize);
-        }
-
-        if (!statusesForEntireView.isEmpty()) {
-            if (DEBUG) {
-                Log.d(TAG,
-                        "Create status view for: " + statusesForEntireView.get(0).getActivity());
-            }
-            return createStatusRemoteViews(context, statusesForEntireView.get(0), layoutSize);
-        }
-
-        return createLastInteractionRemoteViews(context, tile, layoutSize);
-    }
-
-    /** Calculates the best layout relative to the size in {@code options}. */
-    private static int getLayoutSize(Context context, Bundle options) {
-        int display = context.getResources().getConfiguration().orientation;
-        int width = display == Configuration.ORIENTATION_PORTRAIT
-                ? options.getInt(OPTION_APPWIDGET_MIN_WIDTH, DEFAULT_WIDTH) : options.getInt(
-                OPTION_APPWIDGET_MAX_WIDTH, DEFAULT_WIDTH);
-        int height = display == Configuration.ORIENTATION_PORTRAIT ? options.getInt(
-                OPTION_APPWIDGET_MAX_HEIGHT, DEFAULT_HEIGHT)
-                : options.getInt(OPTION_APPWIDGET_MIN_HEIGHT, DEFAULT_HEIGHT);
-        // Small layout used below a certain minimum width with any height.
-        if (width < REQUIRED_WIDTH_FOR_MEDIUM) {
-            if (DEBUG) Log.d(TAG, "Small view for width: " + width + " height: " + height);
-            return SMALL_LAYOUT;
-        }
-        if (DEBUG) Log.d(TAG, "Medium view for width: " + width + " height: " + height);
-        return MEDIUM_LAYOUT;
-    }
-
-    /** Returns the max avatar size for {@code layoutSize} under the current {@code options}. */
-    private static int getMaxAvatarSize(Context context, Bundle options, int layoutSize) {
-        int avatarHeightSpace = AVATAR_SIZE_FOR_MEDIUM;
-        int avatarWidthSpace = AVATAR_SIZE_FOR_MEDIUM;
-
-        if (layoutSize == SMALL_LAYOUT) {
-            int display = context.getResources().getConfiguration().orientation;
-            int width = display == Configuration.ORIENTATION_PORTRAIT
-                    ? options.getInt(OPTION_APPWIDGET_MIN_WIDTH, DEFAULT_WIDTH) : options.getInt(
-                    OPTION_APPWIDGET_MAX_WIDTH, DEFAULT_WIDTH);
-            int height = display == Configuration.ORIENTATION_PORTRAIT ? options.getInt(
-                    OPTION_APPWIDGET_MAX_HEIGHT, DEFAULT_HEIGHT)
-                    : options.getInt(OPTION_APPWIDGET_MIN_HEIGHT, DEFAULT_HEIGHT);
-            avatarHeightSpace = height - (8 + 4 + 18 + 8);
-            avatarWidthSpace = width - (4 + 4);
-        }
-        if (DEBUG) Log.d(TAG, "Height: " + avatarHeightSpace + " width: " + avatarWidthSpace);
-        return Math.min(avatarHeightSpace, avatarWidthSpace);
-    }
-
-    @Nullable
-    private static ConversationStatus getBirthdayStatus(PeopleSpaceTile tile,
-            List<ConversationStatus> statuses) {
-        Optional<ConversationStatus> birthdayStatus = statuses.stream().filter(
-                c -> c.getActivity() == ACTIVITY_BIRTHDAY).findFirst();
-        if (birthdayStatus.isPresent()) {
-            return birthdayStatus.get();
-        }
-        if (!TextUtils.isEmpty(tile.getBirthdayText())) {
-            return new ConversationStatus.Builder(tile.getId(), ACTIVITY_BIRTHDAY).build();
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns whether a {@code status} should have its own entire templated view.
-     *
-     * <p>A status may still be shown on the view (for example, as a new story ring) even if it's
-     * not valid to compose an entire view.
-     */
-    private static boolean isStatusValidForEntireStatusView(ConversationStatus status) {
-        switch (status.getActivity()) {
-            // Birthday & Anniversary don't require text provided or icon provided.
-            case ACTIVITY_BIRTHDAY:
-            case ACTIVITY_ANNIVERSARY:
-                return true;
-            default:
-                // For future birthday, location, new story, video, music, game, and other, the
-                // app must provide either text or an icon.
-                return !TextUtils.isEmpty(status.getDescription())
-                        || status.getIcon() != null;
-        }
-    }
-
-    private static RemoteViews createStatusRemoteViews(Context context, ConversationStatus status,
-            int layoutSize) {
-        int layout = layoutSize == SMALL_LAYOUT ? R.layout.people_space_small_view
-                : R.layout.people_space_small_avatar_tile;
-        RemoteViews views = new RemoteViews(context.getPackageName(), layout);
-        CharSequence statusText = status.getDescription();
-        if (TextUtils.isEmpty(statusText)) {
-            statusText = getStatusTextByType(context, status.getActivity());
-        }
-        views.setViewVisibility(R.id.subtext, View.GONE);
-        views.setViewVisibility(R.id.text_content, View.VISIBLE);
-        TypedValue typedValue = new TypedValue();
-        context.getTheme().resolveAttribute(android.R.attr.textColorSecondary, typedValue, true);
-        int secondaryTextColor = context.getColor(typedValue.resourceId);
-        views.setInt(R.id.text_content, "setTextColor", secondaryTextColor);
-        views.setTextViewText(R.id.text_content, statusText);
-        Icon statusIcon = status.getIcon();
-        if (statusIcon != null) {
-            views.setImageViewIcon(R.id.image, statusIcon);
-            views.setBoolean(R.id.content_background, "setClipToOutline", true);
-        } else {
-            views.setViewVisibility(R.id.content_background, View.GONE);
-        }
-        // TODO: Set status pre-defined icons
-        views.setImageViewResource(R.id.predefined_icon, R.drawable.ic_person);
-        ensurePredefinedIconVisibleOnSmallView(views, layoutSize);
-        return views;
-    }
-
-    private static String getStatusTextByType(Context context, int activity) {
-        switch (activity) {
-            case ACTIVITY_BIRTHDAY:
-                return context.getString(R.string.birthday_status);
-            case ACTIVITY_UPCOMING_BIRTHDAY:
-                return context.getString(R.string.upcoming_birthday_status);
-            case ACTIVITY_ANNIVERSARY:
-                return context.getString(R.string.anniversary_status);
-            case ACTIVITY_LOCATION:
-                return context.getString(R.string.location_status);
-            case ACTIVITY_NEW_STORY:
-                return context.getString(R.string.new_story_status);
-            case ACTIVITY_VIDEO:
-                return context.getString(R.string.video_status);
-            case ACTIVITY_AUDIO:
-                return context.getString(R.string.audio_status);
-            case ACTIVITY_GAME:
-                return context.getString(R.string.game_status);
-            default:
-                return EMPTY_STRING;
-        }
-    }
-
-    private static RemoteViews setCommonRemoteViewsFields(Context context, RemoteViews views,
-            PeopleSpaceTile tile, int maxAvatarSize) {
-        try {
-            boolean isAvailable =
-                    tile.getStatuses() != null && tile.getStatuses().stream().anyMatch(
-                            c -> c.getAvailability() == AVAILABILITY_AVAILABLE);
-            if (isAvailable) {
-                views.setViewVisibility(R.id.availability, View.VISIBLE);
-            } else {
-                views.setViewVisibility(R.id.availability, View.GONE);
-            }
-            boolean hasNewStory =
-                    tile.getStatuses() != null && tile.getStatuses().stream().anyMatch(
-                            c -> c.getActivity() == ACTIVITY_NEW_STORY);
-            views.setTextViewText(R.id.name, tile.getUserName().toString());
-            views.setBoolean(R.id.content_background, "setClipToOutline", true);
-            Icon icon = tile.getUserIcon();
-            PeopleStoryIconFactory storyIcon = new PeopleStoryIconFactory(context,
-                    context.getPackageManager(),
-                    IconDrawableFactory.newInstance(context, false),
-                    maxAvatarSize);
-            Drawable drawable = icon.loadDrawable(context);
-            Drawable personDrawable = storyIcon.getPeopleTileDrawable(drawable,
-                    tile.getPackageName(), getUserId(tile), tile.isImportantConversation(),
-                    hasNewStory);
-            Bitmap bitmap = convertDrawableToBitmap(personDrawable);
-            views.setImageViewBitmap(R.id.person_icon, bitmap);
-
-            return views;
-        } catch (Exception e) {
-            Log.e(TAG, "Failed to set common fields: " + e);
-        }
-        return views;
-    }
-
-    private static RemoteViews setLaunchIntents(Context context, RemoteViews views,
-            PeopleSpaceTile tile, int appWidgetId) {
-        try {
-            Intent activityIntent = new Intent(context, LaunchConversationActivity.class);
-            activityIntent.addFlags(
-                    Intent.FLAG_ACTIVITY_NEW_TASK
-                            | Intent.FLAG_ACTIVITY_CLEAR_TASK
-                            | Intent.FLAG_ACTIVITY_NO_HISTORY
-                            | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
-            activityIntent.putExtra(PeopleSpaceWidgetProvider.EXTRA_TILE_ID, tile.getId());
-            activityIntent.putExtra(
-                    PeopleSpaceWidgetProvider.EXTRA_PACKAGE_NAME, tile.getPackageName());
-            activityIntent.putExtra(PeopleSpaceWidgetProvider.EXTRA_USER_HANDLE,
-                    tile.getUserHandle());
-            activityIntent.putExtra(
-                    PeopleSpaceWidgetProvider.EXTRA_NOTIFICATION_KEY, tile.getNotificationKey());
-            views.setOnClickPendingIntent(R.id.item, PendingIntent.getActivity(
-                    context,
-                    appWidgetId,
-                    activityIntent,
-                    PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE));
-            return views;
-        } catch (Exception e) {
-            Log.e(TAG, "Failed to add launch intents: " + e);
-        }
-
-        return views;
-    }
-
-    private static RemoteViews createMissedCallRemoteViews(Context context,
-            PeopleSpaceTile tile, int layoutSize) {
-        int layout = layoutSize == SMALL_LAYOUT ? R.layout.people_space_small_view
-                : R.layout.people_space_small_avatar_tile;
-        RemoteViews views = new RemoteViews(context.getPackageName(), layout);
-        views.setViewVisibility(R.id.subtext, View.GONE);
-        views.setViewVisibility(R.id.text_content, View.VISIBLE);
-        views.setTextViewText(R.id.text_content, tile.getNotificationContent());
-        views.setImageViewResource(R.id.predefined_icon, R.drawable.ic_phone_missed);
-        ensurePredefinedIconVisibleOnSmallView(views, layoutSize);
-        views.setBoolean(R.id.content_background, "setClipToOutline", true);
-        return views;
-    }
-
-    private static void ensurePredefinedIconVisibleOnSmallView(RemoteViews views, int layoutSize) {
-        if (layoutSize == SMALL_LAYOUT) {
-            views.setViewVisibility(R.id.name, View.GONE);
-            views.setViewVisibility(R.id.predefined_icon, View.VISIBLE);
-        }
-    }
-
-    private static RemoteViews createNotificationRemoteViews(Context context,
-            PeopleSpaceTile tile, int layoutSize) {
-        int layout = layoutSize == SMALL_LAYOUT ? R.layout.people_space_small_view
-                : R.layout.people_space_small_avatar_tile;
-        RemoteViews views = new RemoteViews(context.getPackageName(), layout);
-        if (layoutSize != MEDIUM_LAYOUT) {
-            views.setViewVisibility(R.id.name, View.GONE);
-            views.setViewVisibility(R.id.predefined_icon, View.VISIBLE);
-        }
-        Uri image = tile.getNotificationDataUri();
-        ensurePredefinedIconVisibleOnSmallView(views, layoutSize);
-        if (image != null) {
-            // TODO: Use NotificationInlineImageCache
-            views.setImageViewUri(R.id.image, image);
-            views.setViewVisibility(R.id.content_background, View.VISIBLE);
-            views.setBoolean(R.id.content_background, "setClipToOutline", true);
-            views.setViewVisibility(R.id.text_content, View.GONE);
-            views.setImageViewResource(R.id.predefined_icon, R.drawable.ic_photo_camera);
-        } else {
-            CharSequence content = tile.getNotificationContent();
-            views = setPunctuationRemoteViewsFields(views, content);
-            views.setTextViewText(R.id.text_content, tile.getNotificationContent());
-            // TODO: Measure max lines from height.
-            views.setInt(R.id.text_content, "setMaxLines", 2);
-            TypedValue typedValue = new TypedValue();
-            context.getTheme().resolveAttribute(android.R.attr.textColorPrimary, typedValue, true);
-            int primaryTextColor = context.getColor(typedValue.resourceId);
-            views.setInt(R.id.text_content, "setTextColor", primaryTextColor);
-            views.setViewVisibility(R.id.text_content, View.VISIBLE);
-            views.setViewVisibility(R.id.content_background, View.GONE);
-            views.setImageViewResource(R.id.predefined_icon, R.drawable.ic_message);
-        }
-        // TODO: Set subtext as Group Sender name once storing the name in PeopleSpaceTile.
-        views.setViewVisibility(R.id.subtext, View.GONE);
-        return views;
-    }
-
-    private static RemoteViews createLastInteractionRemoteViews(Context context,
-            PeopleSpaceTile tile, int layoutSize) {
-        int layout = layoutSize == SMALL_LAYOUT ? R.layout.people_space_small_view
-                : R.layout.people_space_large_avatar_tile;
-        RemoteViews views = new RemoteViews(context.getPackageName(), layout);
-        if (layoutSize == SMALL_LAYOUT) {
-            views.setViewVisibility(R.id.name, View.VISIBLE);
-            views.setViewVisibility(R.id.predefined_icon, View.GONE);
-        }
-        String status = PeopleSpaceUtils.getLastInteractionString(
-                context, tile.getLastInteractionTimestamp());
-        views.setTextViewText(R.id.last_interaction, status);
-        return views;
-    }
-
-    private static RemoteViews setPunctuationRemoteViewsFields(
-            RemoteViews views, CharSequence content) {
-        String punctuation = getBackgroundTextFromMessage(content.toString());
-        int visibility = View.GONE;
-        if (punctuation != null) {
-            visibility = View.VISIBLE;
-        }
-        views.setTextViewText(R.id.punctuation1, punctuation);
-        views.setTextViewText(R.id.punctuation2, punctuation);
-        views.setTextViewText(R.id.punctuation3, punctuation);
-        views.setTextViewText(R.id.punctuation4, punctuation);
-        views.setTextViewText(R.id.punctuation5, punctuation);
-        views.setTextViewText(R.id.punctuation6, punctuation);
-
-        views.setViewVisibility(R.id.punctuation1, visibility);
-        views.setViewVisibility(R.id.punctuation2, visibility);
-        views.setViewVisibility(R.id.punctuation3, visibility);
-        views.setViewVisibility(R.id.punctuation4, visibility);
-        views.setViewVisibility(R.id.punctuation5, visibility);
-        views.setViewVisibility(R.id.punctuation6, visibility);
-
-        return views;
-    }
-
-    /** Gets character for tile background decoration based on notification content. */
     @VisibleForTesting
-    static String getBackgroundTextFromMessage(String message) {
-        if (!ANY_DOUBLE_MARK_PATTERN.matcher(message).find()) {
-            return null;
-        }
-        if (MIXED_MARK_PATTERN.matcher(message).find()) {
-            return "!?";
-        }
-        Matcher doubleQuestionMatcher = DOUBLE_QUESTION_PATTERN.matcher(message);
-        if (!doubleQuestionMatcher.find()) {
-            return "!";
-        }
-        Matcher doubleExclamationMatcher = DOUBLE_EXCLAMATION_PATTERN.matcher(message);
-        if (!doubleExclamationMatcher.find()) {
-            return "?";
-        }
-        // If we have both "!!" and "??", return the one that comes first.
-        if (doubleQuestionMatcher.start() < doubleExclamationMatcher.start()) {
-            return "?";
-        }
-        return "!";
-    }
-
-    /** Gets the most recent {@link Notification.MessagingStyle.Message} from the notification. */
-    @VisibleForTesting
-    public static Notification.MessagingStyle.Message getLastMessagingStyleMessage(
+    public static List<Notification.MessagingStyle.Message> getMessagingStyleMessages(
             Notification notification) {
         if (notification == null) {
             return null;
@@ -708,7 +334,7 @@
                         Notification.MessagingStyle.Message.getMessagesFromBundleArray(messages);
                 sortedMessages.sort(Collections.reverseOrder(
                         Comparator.comparing(Notification.MessagingStyle.Message::getTimestamp)));
-                return sortedMessages.get(0);
+                return sortedMessages;
             }
         }
         return null;
@@ -917,7 +543,8 @@
     public static void updateAppWidgetViews(AppWidgetManager appWidgetManager,
             Context context, int appWidgetId, PeopleSpaceTile tile, Bundle options) {
         if (DEBUG) Log.d(TAG, "Widget: " + appWidgetId + ", " + tile.getUserName());
-        RemoteViews views = createRemoteViews(context, tile, appWidgetId, options);
+        RemoteViews views = new PeopleTileViewHelper(context, tile, appWidgetId,
+                options).getViews();
 
         // Tell the AppWidgetManager to perform an update on the current app widget.
         appWidgetManager.updateAppWidget(appWidgetId, views);
@@ -1005,7 +632,7 @@
 
         if (DEBUG) Log.i(TAG, "Returning tile preview for shortcutId: " + shortcutId);
         Bundle bundle = new Bundle();
-        return PeopleSpaceUtils.createRemoteViews(context, augmentedTile, 0, bundle);
+        return new PeopleTileViewHelper(context, augmentedTile, 0, bundle).getViews();
     }
 
     /** Returns the userId associated with a {@link PeopleSpaceTile} */
diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java b/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java
new file mode 100644
index 0000000..8d1b712
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java
@@ -0,0 +1,586 @@
+/*
+ * 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.people;
+
+import static android.app.Notification.CATEGORY_MISSED_CALL;
+import static android.app.people.ConversationStatus.ACTIVITY_ANNIVERSARY;
+import static android.app.people.ConversationStatus.ACTIVITY_AUDIO;
+import static android.app.people.ConversationStatus.ACTIVITY_BIRTHDAY;
+import static android.app.people.ConversationStatus.ACTIVITY_GAME;
+import static android.app.people.ConversationStatus.ACTIVITY_LOCATION;
+import static android.app.people.ConversationStatus.ACTIVITY_NEW_STORY;
+import static android.app.people.ConversationStatus.ACTIVITY_UPCOMING_BIRTHDAY;
+import static android.app.people.ConversationStatus.ACTIVITY_VIDEO;
+import static android.app.people.ConversationStatus.AVAILABILITY_AVAILABLE;
+import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT;
+import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH;
+import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT;
+import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH;
+
+import static com.android.systemui.people.PeopleSpaceUtils.convertDrawableToBitmap;
+import static com.android.systemui.people.PeopleSpaceUtils.getUserId;
+
+import android.annotation.Nullable;
+import android.app.PendingIntent;
+import android.app.people.ConversationStatus;
+import android.app.people.PeopleSpaceTile;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.graphics.Bitmap;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
+import android.net.Uri;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.util.IconDrawableFactory;
+import android.util.Log;
+import android.util.TypedValue;
+import android.view.View;
+import android.widget.RemoteViews;
+import android.widget.TextView;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.R;
+import com.android.systemui.people.widget.LaunchConversationActivity;
+import com.android.systemui.people.widget.PeopleSpaceWidgetProvider;
+
+import java.text.NumberFormat;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Locale;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+class PeopleTileViewHelper {
+    /** Turns on debugging information about People Space. */
+    public static final boolean DEBUG = true;
+    private static final String TAG = "PeopleTileView";
+
+    public static final int LAYOUT_SMALL = 0;
+    public static final int LAYOUT_MEDIUM = 1;
+    public static final int LAYOUT_LARGE = 2;
+
+    private static final int MIN_CONTENT_MAX_LINES = 2;
+
+    private static final int FIXED_HEIGHT_DIMENS_FOR_LARGE_CONTENT = 14 + 12 + 4 + 16;
+    private static final int FIXED_HEIGHT_DIMENS_FOR_MEDIUM_CONTENT = 8 + 4 + 4 + 8;
+    private static final int FIXED_HEIGHT_DIMENS_FOR_SMALL = 6 + 4 + 8;
+    private static final int FIXED_WIDTH_DIMENS_FOR_SMALL = 4 + 4;
+
+    private static final int MESSAGES_COUNT_OVERFLOW = 7;
+
+    private static final Pattern DOUBLE_EXCLAMATION_PATTERN = Pattern.compile("[!][!]+");
+    private static final Pattern DOUBLE_QUESTION_PATTERN = Pattern.compile("[?][?]+");
+    private static final Pattern ANY_DOUBLE_MARK_PATTERN = Pattern.compile("[!?][!?]+");
+    private static final Pattern MIXED_MARK_PATTERN = Pattern.compile("![?].*|.*[?]!");
+
+    public static final String EMPTY_STRING = "";
+
+    private Context mContext;
+    private PeopleSpaceTile mTile;
+    private float mDensity;
+    private int mAppWidgetId;
+    private int mWidth;
+    private int mHeight;
+    private int mLayoutSize;
+
+    private Locale mLocale;
+    private NumberFormat mIntegerFormat;
+
+    PeopleTileViewHelper(Context context, PeopleSpaceTile tile,
+            int appWidgetId, Bundle options) {
+        mContext = context;
+        mTile = tile;
+        mAppWidgetId = appWidgetId;
+        mDensity = mContext.getResources().getDisplayMetrics().density;
+        int display = mContext.getResources().getConfiguration().orientation;
+        mWidth = display == Configuration.ORIENTATION_PORTRAIT
+                ? options.getInt(OPTION_APPWIDGET_MIN_WIDTH,
+                getSizeInDp(R.dimen.default_width)) : options.getInt(
+                OPTION_APPWIDGET_MAX_WIDTH,
+                getSizeInDp(R.dimen.default_width));
+        mHeight = display == Configuration.ORIENTATION_PORTRAIT ? options.getInt(
+                OPTION_APPWIDGET_MAX_HEIGHT,
+                getSizeInDp(R.dimen.default_height))
+                : options.getInt(OPTION_APPWIDGET_MIN_HEIGHT,
+                        getSizeInDp(R.dimen.default_height));
+        mLayoutSize = getLayoutSize();
+    }
+
+    public RemoteViews getViews() {
+        RemoteViews viewsForTile = getViewForTile();
+        int maxAvatarSize = getMaxAvatarSize(viewsForTile);
+        RemoteViews views = setCommonRemoteViewsFields(viewsForTile, maxAvatarSize);
+        return setLaunchIntents(views);
+    }
+
+    /**
+     * The prioritization for the {@code mTile} content is missed calls, followed by notification
+     * content, then birthdays, then the most recent status, and finally last interaction.
+     */
+    private RemoteViews getViewForTile() {
+        if (Objects.equals(mTile.getNotificationCategory(), CATEGORY_MISSED_CALL)) {
+            if (DEBUG) Log.d(TAG, "Create missed call view");
+            return createMissedCallRemoteViews();
+        }
+
+        if (mTile.getNotificationKey() != null) {
+            if (DEBUG) Log.d(TAG, "Create notification view");
+            return createNotificationRemoteViews();
+        }
+
+        // TODO: Add sorting when we expose timestamp of statuses.
+        List<ConversationStatus> statusesForEntireView =
+                mTile.getStatuses() == null ? Arrays.asList() : mTile.getStatuses().stream().filter(
+                        c -> isStatusValidForEntireStatusView(c)).collect(Collectors.toList());
+        ConversationStatus birthdayStatus = getBirthdayStatus(statusesForEntireView);
+        if (birthdayStatus != null) {
+            if (DEBUG) Log.d(TAG, "Create birthday view");
+            return createStatusRemoteViews(birthdayStatus);
+        }
+
+        if (!statusesForEntireView.isEmpty()) {
+            if (DEBUG) {
+                Log.d(TAG,
+                        "Create status view for: " + statusesForEntireView.get(0).getActivity());
+            }
+            return createStatusRemoteViews(statusesForEntireView.get(0));
+        }
+
+        return createLastInteractionRemoteViews();
+    }
+
+    private void setMaxLines(RemoteViews views) {
+        int textSize = mLayoutSize == LAYOUT_LARGE ? getSizeInDp(
+                R.dimen.content_text_size_for_medium)
+                : getSizeInDp(R.dimen.content_text_size_for_medium);
+        int lineHeight = getLineHeight(textSize);
+        int notificationContentHeight = getContentHeightForLayout(lineHeight);
+        int maxAdaptiveLines = Math.floorDiv(notificationContentHeight, lineHeight);
+        int maxLines = Math.max(MIN_CONTENT_MAX_LINES, maxAdaptiveLines);
+        views.setInt(R.id.text_content, "setMaxLines", maxLines);
+    }
+
+    private int getLineHeight(int textSize) {
+        try {
+            TextView text = new TextView(mContext);
+            text.setTextSize(textSize);
+            int lineHeight = (int) (text.getLineHeight() / mDensity);
+            return lineHeight;
+        } catch (Exception e) {
+            Log.e(TAG, "Could not create text view: " + e);
+            return getSizeInDp(
+                    R.dimen.content_text_size_for_medium);
+        }
+    }
+
+    private int getSizeInDp(int dimenResourceId) {
+        return (int) (mContext.getResources().getDimension(dimenResourceId) / mDensity);
+    }
+
+    private int getContentHeightForLayout(int lineHeight) {
+        switch (mLayoutSize) {
+            case LAYOUT_MEDIUM:
+                return mHeight - (lineHeight + FIXED_HEIGHT_DIMENS_FOR_MEDIUM_CONTENT);
+            case LAYOUT_LARGE:
+                return mHeight - (getSizeInDp(
+                        R.dimen.max_people_avatar_size_for_large_content) + lineHeight
+                        + FIXED_HEIGHT_DIMENS_FOR_LARGE_CONTENT);
+            default:
+                return -1;
+        }
+    }
+
+    /** Calculates the best layout relative to the size in {@code options}. */
+    private int getLayoutSize() {
+        if (mHeight >= getSizeInDp(R.dimen.required_width_for_large)
+                && mWidth >= getSizeInDp(R.dimen.required_width_for_large)) {
+            if (DEBUG) Log.d(TAG, "Large view for mWidth: " + mWidth + " mHeight: " + mHeight);
+            return LAYOUT_LARGE;
+        }
+        // Small layout used below a certain minimum mWidth with any mHeight.
+        if (mWidth >= getSizeInDp(R.dimen.required_width_for_medium)) {
+            if (DEBUG) Log.d(TAG, "Medium view for mWidth: " + mWidth + " mHeight: " + mHeight);
+            return LAYOUT_MEDIUM;
+        }
+        // Small layout can always handle our minimum mWidth and mHeight for our widget.
+        if (DEBUG) Log.d(TAG, "Small view for mWidth: " + mWidth + " mHeight: " + mHeight);
+        return LAYOUT_SMALL;
+    }
+
+    /** Returns the max avatar size for {@code views} under the current {@code options}. */
+    private int getMaxAvatarSize(RemoteViews views) {
+        int layoutId = views.getLayoutId();
+        int avatarSize = getSizeInDp(R.dimen.avatar_size_for_medium);
+        if (layoutId == R.layout.people_tile_medium_empty) {
+            return getSizeInDp(
+                    R.dimen.max_people_avatar_size_for_large_content);
+        }
+        if (layoutId == R.layout.people_tile_medium_with_content) {
+            return getSizeInDp(R.dimen.avatar_size_for_medium);
+        }
+
+        // Calculate adaptive avatar size for remaining layouts.
+        if (layoutId == R.layout.people_tile_small) {
+            int avatarHeightSpace = mHeight - (FIXED_HEIGHT_DIMENS_FOR_SMALL + Math.max(18,
+                    getLineHeight(getSizeInDp(
+                            R.dimen.name_text_size_for_small))));
+            int avatarWidthSpace = mWidth - FIXED_WIDTH_DIMENS_FOR_SMALL;
+            avatarSize = Math.min(avatarHeightSpace, avatarWidthSpace);
+        }
+
+        if (layoutId == R.layout.people_tile_large_with_content) {
+            avatarSize = mHeight - (FIXED_HEIGHT_DIMENS_FOR_LARGE_CONTENT + (getLineHeight(
+                    getSizeInDp(R.dimen.content_text_size_for_large))
+                    * 3));
+            return Math.min(avatarSize, getSizeInDp(
+                    R.dimen.max_people_avatar_size_for_large_content));
+        }
+
+        if (layoutId == R.layout.people_tile_large_empty) {
+            int avatarHeightSpace = mHeight - (14 + 14 + getLineHeight(
+                    getSizeInDp(R.dimen.name_text_size_for_large))
+                    + getLineHeight(
+                    getSizeInDp(R.dimen.content_text_size_for_large))
+                    + 16 + 10 + 14);
+            int avatarWidthSpace = mWidth - (14 + 14);
+            avatarSize = Math.min(avatarHeightSpace, avatarWidthSpace);
+        }
+        return Math.min(avatarSize,
+                getSizeInDp(R.dimen.max_people_avatar_size));
+    }
+
+    private RemoteViews setCommonRemoteViewsFields(RemoteViews views,
+            int maxAvatarSize) {
+        try {
+            boolean isAvailable =
+                    mTile.getStatuses() != null && mTile.getStatuses().stream().anyMatch(
+                            c -> c.getAvailability() == AVAILABILITY_AVAILABLE);
+            if (isAvailable) {
+                views.setViewVisibility(R.id.availability, View.VISIBLE);
+            } else {
+                views.setViewVisibility(R.id.availability, View.GONE);
+            }
+            boolean hasNewStory =
+                    mTile.getStatuses() != null && mTile.getStatuses().stream().anyMatch(
+                            c -> c.getActivity() == ACTIVITY_NEW_STORY);
+            views.setTextViewText(R.id.name, mTile.getUserName().toString());
+            views.setBoolean(R.id.image, "setClipToOutline", true);
+
+            Icon icon = mTile.getUserIcon();
+            PeopleStoryIconFactory storyIcon = new PeopleStoryIconFactory(mContext,
+                    mContext.getPackageManager(),
+                    IconDrawableFactory.newInstance(mContext, false),
+                    maxAvatarSize);
+            Drawable drawable = icon.loadDrawable(mContext);
+            Drawable personDrawable = storyIcon.getPeopleTileDrawable(drawable,
+                    mTile.getPackageName(), getUserId(mTile), mTile.isImportantConversation(),
+                    hasNewStory);
+            Bitmap bitmap = convertDrawableToBitmap(personDrawable);
+            views.setImageViewBitmap(R.id.person_icon, bitmap);
+
+            return views;
+        } catch (Exception e) {
+            Log.e(TAG, "Failed to set common fields: " + e);
+        }
+        return views;
+    }
+
+    private RemoteViews setLaunchIntents(RemoteViews views) {
+        try {
+            Intent activityIntent = new Intent(mContext, LaunchConversationActivity.class);
+            activityIntent.addFlags(
+                    Intent.FLAG_ACTIVITY_NEW_TASK
+                            | Intent.FLAG_ACTIVITY_CLEAR_TASK
+                            | Intent.FLAG_ACTIVITY_NO_HISTORY
+                            | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+            activityIntent.putExtra(PeopleSpaceWidgetProvider.EXTRA_TILE_ID, mTile.getId());
+            activityIntent.putExtra(
+                    PeopleSpaceWidgetProvider.EXTRA_PACKAGE_NAME, mTile.getPackageName());
+            activityIntent.putExtra(PeopleSpaceWidgetProvider.EXTRA_USER_HANDLE,
+                    mTile.getUserHandle());
+            activityIntent.putExtra(
+                    PeopleSpaceWidgetProvider.EXTRA_NOTIFICATION_KEY, mTile.getNotificationKey());
+            views.setOnClickPendingIntent(R.id.item, PendingIntent.getActivity(
+                    mContext,
+                    mAppWidgetId,
+                    activityIntent,
+                    PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE));
+            return views;
+        } catch (Exception e) {
+            Log.e(TAG, "Failed to add launch intents: " + e);
+        }
+
+        return views;
+    }
+
+    private RemoteViews createMissedCallRemoteViews() {
+        RemoteViews views = getViewForContentLayout();
+        views.setViewVisibility(R.id.predefined_icon, View.VISIBLE);
+        setMaxLines(views);
+        views.setTextViewText(R.id.text_content, mTile.getNotificationContent());
+        views.setImageViewResource(R.id.predefined_icon, R.drawable.ic_phone_missed);
+        return views;
+    }
+
+    private RemoteViews createNotificationRemoteViews() {
+        RemoteViews views = getViewForContentLayout();
+        Uri image = mTile.getNotificationDataUri();
+        if (image != null) {
+            // TODO: Use NotificationInlineImageCache
+            views.setImageViewUri(R.id.image, image);
+            views.setViewVisibility(R.id.image, View.VISIBLE);
+            views.setViewVisibility(R.id.text_content, View.GONE);
+            views.setImageViewResource(R.id.predefined_icon, R.drawable.ic_photo_camera);
+        } else {
+            setMaxLines(views);
+            CharSequence content = mTile.getNotificationContent();
+            views = setPunctuationRemoteViewsFields(views, content);
+            TypedValue typedValue = new TypedValue();
+            mContext.getTheme().resolveAttribute(android.R.attr.textColorPrimary, typedValue, true);
+            int primaryTextColor = mContext.getColor(typedValue.resourceId);
+            views.setInt(R.id.text_content, "setTextColor", primaryTextColor);
+            views.setTextViewText(R.id.text_content, mTile.getNotificationContent());
+            views.setViewVisibility(R.id.image, View.GONE);
+            views.setImageViewResource(R.id.predefined_icon, R.drawable.ic_message);
+        }
+        if (mTile.getMessagesCount() > 1) {
+            views.setViewVisibility(R.id.messages_count, View.VISIBLE);
+            views.setTextViewText(R.id.messages_count,
+                    getMessagesCountText(mTile.getMessagesCount()));
+            if (mLayoutSize == LAYOUT_SMALL) {
+                views.setViewVisibility(R.id.predefined_icon, View.GONE);
+            }
+        }
+        // TODO: Set subtext as Group Sender name once storing the name in PeopleSpaceTile and
+        //  subtract 1 from maxLines when present.
+        views.setViewVisibility(R.id.subtext, View.GONE);
+        return views;
+    }
+
+    // Some messaging apps only include up to 7 messages in their notifications.
+    private String getMessagesCountText(int count) {
+        if (count >= MESSAGES_COUNT_OVERFLOW) {
+            return mContext.getResources().getString(
+                    R.string.messages_count_overflow_indicator, MESSAGES_COUNT_OVERFLOW);
+        }
+
+        // Cache the locale-appropriate NumberFormat.  Configuration locale is guaranteed
+        // non-null, so the first time this is called we will always get the appropriate
+        // NumberFormat, then never regenerate it unless the locale changes on the fly.
+        final Locale curLocale = mContext.getResources().getConfiguration().getLocales().get(0);
+        if (!curLocale.equals(mLocale)) {
+            mLocale = curLocale;
+            mIntegerFormat = NumberFormat.getIntegerInstance(curLocale);
+        }
+        return mIntegerFormat.format(count);
+    }
+
+    private RemoteViews createStatusRemoteViews(ConversationStatus status) {
+        RemoteViews views = getViewForContentLayout();
+        CharSequence statusText = status.getDescription();
+        if (TextUtils.isEmpty(statusText)) {
+            statusText = getStatusTextByType(status.getActivity());
+        }
+        views.setViewVisibility(R.id.predefined_icon, View.VISIBLE);
+        setMaxLines(views);
+        // Secondary text color for statuses.
+        TypedValue typedValue = new TypedValue();
+        mContext.getTheme().resolveAttribute(android.R.attr.textColorSecondary, typedValue, true);
+        int secondaryTextColor = mContext.getColor(typedValue.resourceId);
+        views.setInt(R.id.text_content, "setTextColor", secondaryTextColor);
+        views.setTextViewText(R.id.text_content, statusText);
+
+        Icon statusIcon = status.getIcon();
+        if (statusIcon != null) {
+            // No multi-line text with status images on medium layout.
+            views.setViewVisibility(R.id.text_content, View.GONE);
+            // Show 1-line subtext on large layout with status images.
+            if (mLayoutSize == LAYOUT_LARGE) {
+                views.setViewVisibility(R.id.subtext, View.VISIBLE);
+                views.setTextViewText(R.id.subtext, statusText);
+            }
+            views.setViewVisibility(R.id.image, View.VISIBLE);
+            views.setImageViewIcon(R.id.image, statusIcon);
+        } else {
+            views.setViewVisibility(R.id.image, View.GONE);
+        }
+        // TODO: Set status pre-defined icons
+        views.setImageViewResource(R.id.predefined_icon, R.drawable.ic_person);
+        return views;
+    }
+
+    @Nullable
+    private ConversationStatus getBirthdayStatus(
+            List<ConversationStatus> statuses) {
+        Optional<ConversationStatus> birthdayStatus = statuses.stream().filter(
+                c -> c.getActivity() == ACTIVITY_BIRTHDAY).findFirst();
+        if (birthdayStatus.isPresent()) {
+            return birthdayStatus.get();
+        }
+        if (!TextUtils.isEmpty(mTile.getBirthdayText())) {
+            return new ConversationStatus.Builder(mTile.getId(), ACTIVITY_BIRTHDAY).build();
+        }
+
+        return null;
+    }
+
+    /**
+     * Returns whether a {@code status} should have its own entire templated view.
+     *
+     * <p>A status may still be shown on the view (for example, as a new story ring) even if it's
+     * not valid to compose an entire view.
+     */
+    private boolean isStatusValidForEntireStatusView(ConversationStatus status) {
+        switch (status.getActivity()) {
+            // Birthday & Anniversary don't require text provided or icon provided.
+            case ACTIVITY_BIRTHDAY:
+            case ACTIVITY_ANNIVERSARY:
+                return true;
+            default:
+                // For future birthday, location, new story, video, music, game, and other, the
+                // app must provide either text or an icon.
+                return !TextUtils.isEmpty(status.getDescription())
+                        || status.getIcon() != null;
+        }
+    }
+
+    private String getStatusTextByType(int activity) {
+        switch (activity) {
+            case ACTIVITY_BIRTHDAY:
+                return mContext.getString(R.string.birthday_status);
+            case ACTIVITY_UPCOMING_BIRTHDAY:
+                return mContext.getString(R.string.upcoming_birthday_status);
+            case ACTIVITY_ANNIVERSARY:
+                return mContext.getString(R.string.anniversary_status);
+            case ACTIVITY_LOCATION:
+                return mContext.getString(R.string.location_status);
+            case ACTIVITY_NEW_STORY:
+                return mContext.getString(R.string.new_story_status);
+            case ACTIVITY_VIDEO:
+                return mContext.getString(R.string.video_status);
+            case ACTIVITY_AUDIO:
+                return mContext.getString(R.string.audio_status);
+            case ACTIVITY_GAME:
+                return mContext.getString(R.string.game_status);
+            default:
+                return EMPTY_STRING;
+        }
+    }
+
+    private RemoteViews setPunctuationRemoteViewsFields(
+            RemoteViews views, CharSequence content) {
+        String punctuation = getBackgroundTextFromMessage(content.toString());
+        int visibility = View.GONE;
+        if (punctuation != null) {
+            visibility = View.VISIBLE;
+        }
+        views.setTextViewText(R.id.punctuation1, punctuation);
+        views.setTextViewText(R.id.punctuation2, punctuation);
+        views.setTextViewText(R.id.punctuation3, punctuation);
+        views.setTextViewText(R.id.punctuation4, punctuation);
+        views.setTextViewText(R.id.punctuation5, punctuation);
+        views.setTextViewText(R.id.punctuation6, punctuation);
+
+        views.setViewVisibility(R.id.punctuation1, visibility);
+        views.setViewVisibility(R.id.punctuation2, visibility);
+        views.setViewVisibility(R.id.punctuation3, visibility);
+        views.setViewVisibility(R.id.punctuation4, visibility);
+        views.setViewVisibility(R.id.punctuation5, visibility);
+        views.setViewVisibility(R.id.punctuation6, visibility);
+
+        return views;
+    }
+
+    /** Gets character for mTile background decoration based on notification content. */
+    @VisibleForTesting
+    String getBackgroundTextFromMessage(String message) {
+        if (!ANY_DOUBLE_MARK_PATTERN.matcher(message).find()) {
+            return null;
+        }
+        if (MIXED_MARK_PATTERN.matcher(message).find()) {
+            return "!?";
+        }
+        Matcher doubleQuestionMatcher = DOUBLE_QUESTION_PATTERN.matcher(message);
+        if (!doubleQuestionMatcher.find()) {
+            return "!";
+        }
+        Matcher doubleExclamationMatcher = DOUBLE_EXCLAMATION_PATTERN.matcher(message);
+        if (!doubleExclamationMatcher.find()) {
+            return "?";
+        }
+        // If we have both "!!" and "??", return the one that comes first.
+        if (doubleQuestionMatcher.start() < doubleExclamationMatcher.start()) {
+            return "?";
+        }
+        return "!";
+    }
+
+    private RemoteViews getViewForContentLayout() {
+        RemoteViews views = new RemoteViews(mContext.getPackageName(),
+                getLayoutForContent());
+        if (mLayoutSize == LAYOUT_SMALL) {
+            views.setViewVisibility(R.id.predefined_icon, View.VISIBLE);
+            views.setViewVisibility(R.id.name, View.GONE);
+        } else {
+            views.setViewVisibility(R.id.predefined_icon, View.GONE);
+            views.setViewVisibility(R.id.name, View.VISIBLE);
+            views.setViewVisibility(R.id.text_content, View.VISIBLE);
+            views.setViewVisibility(R.id.subtext, View.GONE);
+        }
+        return views;
+    }
+
+    private RemoteViews createLastInteractionRemoteViews() {
+        RemoteViews views = new RemoteViews(mContext.getPackageName(), getEmptyLayout());
+        if (mLayoutSize == LAYOUT_SMALL) {
+            views.setViewVisibility(R.id.name, View.VISIBLE);
+            views.setViewVisibility(R.id.predefined_icon, View.GONE);
+        }
+        String status = PeopleSpaceUtils.getLastInteractionString(mContext,
+                mTile.getLastInteractionTimestamp());
+        views.setTextViewText(R.id.last_interaction, status);
+        return views;
+    }
+
+    private int getEmptyLayout() {
+        switch (mLayoutSize) {
+            case LAYOUT_MEDIUM:
+                return R.layout.people_tile_medium_empty;
+            case LAYOUT_LARGE:
+                return R.layout.people_tile_large_empty;
+            case LAYOUT_SMALL:
+            default:
+                return R.layout.people_tile_small;
+        }
+    }
+
+    private int getLayoutForContent() {
+        switch (mLayoutSize) {
+            case LAYOUT_MEDIUM:
+                return R.layout.people_tile_medium_with_content;
+            case LAYOUT_LARGE:
+                return R.layout.people_tile_large_with_content;
+            case LAYOUT_SMALL:
+            default:
+                return R.layout.people_tile_small;
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java
index 4ad685e..5be2d4a 100644
--- a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java
+++ b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java
@@ -16,17 +16,23 @@
 
 package com.android.systemui.people.widget;
 
+import static android.Manifest.permission.READ_CONTACTS;
+import static android.app.Notification.CATEGORY_MISSED_CALL;
+import static android.app.Notification.EXTRA_PEOPLE_LIST;
+
 import static com.android.systemui.people.PeopleSpaceUtils.EMPTY_STRING;
 import static com.android.systemui.people.PeopleSpaceUtils.INVALID_USER_ID;
 import static com.android.systemui.people.PeopleSpaceUtils.PACKAGE_NAME;
 import static com.android.systemui.people.PeopleSpaceUtils.SHORTCUT_ID;
 import static com.android.systemui.people.PeopleSpaceUtils.USER_ID;
 import static com.android.systemui.people.PeopleSpaceUtils.augmentTileFromNotification;
+import static com.android.systemui.people.PeopleSpaceUtils.getMessagingStyleMessages;
 import static com.android.systemui.people.PeopleSpaceUtils.getStoredWidgetIds;
 import static com.android.systemui.people.PeopleSpaceUtils.updateAppWidgetOptionsAndView;
 import static com.android.systemui.people.PeopleSpaceUtils.updateAppWidgetViews;
 
 import android.annotation.Nullable;
+import android.app.Notification;
 import android.app.NotificationChannel;
 import android.app.PendingIntent;
 import android.app.Person;
@@ -39,6 +45,7 @@
 import android.content.Context;
 import android.content.SharedPreferences;
 import android.content.pm.LauncherApps;
+import android.content.pm.PackageManager;
 import android.content.pm.ShortcutInfo;
 import android.net.Uri;
 import android.os.Bundle;
@@ -54,16 +61,20 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.UiEventLogger;
 import com.android.internal.logging.UiEventLoggerImpl;
+import com.android.settingslib.utils.ThreadUtils;
 import com.android.systemui.Dependency;
 import com.android.systemui.people.PeopleSpaceUtils;
 import com.android.systemui.statusbar.NotificationListener;
 import com.android.systemui.statusbar.NotificationListener.NotificationHandler;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
 
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Set;
 
 import javax.inject.Inject;
@@ -83,11 +94,19 @@
     private SharedPreferences mSharedPrefs;
     private PeopleManager mPeopleManager;
     private NotificationEntryManager mNotificationEntryManager;
+    private PackageManager mPackageManager;
     public UiEventLogger mUiEventLogger = new UiEventLoggerImpl();
     @GuardedBy("mLock")
     public static Map<PeopleTileKey, PeopleSpaceWidgetProvider.TileConversationListener>
             mListeners = new HashMap<>();
 
+    @GuardedBy("mLock")
+    // Map of notification key mapped to widget IDs previously updated by the contact Uri field.
+    // This is required because on notification removal, the contact Uri field is stripped and we
+    // only have the notification key to determine which widget IDs should be updated.
+    private Map<String, Set<String>> mNotificationKeyToWidgetIdsMatchedByUri = new HashMap<>();
+    private boolean mIsForTesting;
+
     @Inject
     public PeopleSpaceWidgetManager(Context context) {
         if (DEBUG) Log.d(TAG, "constructor");
@@ -99,6 +118,7 @@
         mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(mContext);
         mPeopleManager = mContext.getSystemService(PeopleManager.class);
         mNotificationEntryManager = Dependency.get(NotificationEntryManager.class);
+        mPackageManager = mContext.getPackageManager();
     }
 
     /**
@@ -108,12 +128,15 @@
     protected void setAppWidgetManager(
             AppWidgetManager appWidgetManager, IPeopleManager iPeopleManager,
             PeopleManager peopleManager, LauncherApps launcherApps,
-            NotificationEntryManager notificationEntryManager) {
+            NotificationEntryManager notificationEntryManager, PackageManager packageManager,
+            boolean isForTesting) {
         mAppWidgetManager = appWidgetManager;
         mIPeopleManager = iPeopleManager;
         mPeopleManager = peopleManager;
         mLauncherApps = launcherApps;
         mNotificationEntryManager = notificationEntryManager;
+        mPackageManager = packageManager;
+        mIsForTesting = isForTesting;
     }
 
     /**
@@ -222,6 +245,16 @@
     public void updateWidgetsWithNotificationChanged(StatusBarNotification sbn,
             PeopleSpaceUtils.NotificationAction notificationAction) {
         if (DEBUG) Log.d(TAG, "updateWidgetsWithNotificationChanged called");
+        if (mIsForTesting) {
+            updateWidgetsWithNotificationChangedInBackground(sbn, notificationAction);
+            return;
+        }
+        ThreadUtils.postOnBackgroundThread(
+                () -> updateWidgetsWithNotificationChangedInBackground(sbn, notificationAction));
+    }
+
+    private void updateWidgetsWithNotificationChangedInBackground(StatusBarNotification sbn,
+            PeopleSpaceUtils.NotificationAction action) {
         try {
             String sbnShortcutId = sbn.getShortcutId();
             if (sbnShortcutId == null) {
@@ -235,23 +268,175 @@
                 Log.d(TAG, "No app widget ids returned");
                 return;
             }
+            PeopleTileKey key = new PeopleTileKey(
+                    sbnShortcutId,
+                    sbn.getUser().getIdentifier(),
+                    sbn.getPackageName());
+            if (!key.isValid()) {
+                Log.d(TAG, "Invalid key");
+                return;
+            }
             synchronized (mLock) {
-                PeopleTileKey key = new PeopleTileKey(
-                        sbnShortcutId,
-                        UserHandle.getUserHandleForUid(sbn.getUid()).getIdentifier(),
-                        sbn.getPackageName());
-                Set<String> storedWidgetIds = getStoredWidgetIds(mSharedPrefs, key);
-                for (String widgetIdString : storedWidgetIds) {
-                    int widgetId = Integer.parseInt(widgetIdString);
-                    if (DEBUG) Log.d(TAG, "Storing notification change, key:" + sbn.getKey());
-                    updateStorageAndViewWithNotificationData(sbn, notificationAction, widgetId);
-                }
+                // First, update People Tiles associated with the Notification's package/shortcut.
+                Set<String> tilesUpdatedByKey = getStoredWidgetIds(mSharedPrefs, key);
+                updateWidgetIdsForNotificationAction(tilesUpdatedByKey, sbn, action);
+
+                // Then, update People Tiles across other packages that use the same Uri.
+                updateTilesByUri(key, sbn, action);
             }
         } catch (Exception e) {
             Log.e(TAG, "Exception: " + e);
         }
     }
 
+    /** Updates {@code widgetIdsToUpdate} with {@code action}. */
+    private void updateWidgetIdsForNotificationAction(Set<String> widgetIdsToUpdate,
+            StatusBarNotification sbn, PeopleSpaceUtils.NotificationAction action) {
+        for (String widgetIdString : widgetIdsToUpdate) {
+            int widgetId = Integer.parseInt(widgetIdString);
+            PeopleSpaceTile storedTile = getTileForExistingWidget(widgetId);
+            if (storedTile == null) {
+                if (DEBUG) Log.d(TAG, "Could not find stored tile for notification");
+                continue;
+            }
+            if (DEBUG) Log.d(TAG, "Storing notification change, key:" + sbn.getKey());
+            updateStorageAndViewWithNotificationData(sbn, action, widgetId,
+                    storedTile);
+        }
+    }
+
+    /**
+     * Updates tiles with matched Uris, dependent on the {@code action}.
+     *
+     * <p>If the notification was added, adds the notification based on the contact Uri within
+     * {@code sbn}.
+     * <p>If the notification was removed, removes the notification based on the in-memory map of
+     * widgets previously updated by Uri (since the contact Uri is stripped from the {@code sbn}).
+     */
+    private void updateTilesByUri(PeopleTileKey key, StatusBarNotification sbn,
+            PeopleSpaceUtils.NotificationAction action) {
+        if (action.equals(PeopleSpaceUtils.NotificationAction.POSTED)) {
+            Set<String> widgetIdsUpdatedByUri = supplementTilesByUri(sbn, action, key);
+            if (widgetIdsUpdatedByUri != null && !widgetIdsUpdatedByUri.isEmpty()) {
+                if (DEBUG) Log.d(TAG, "Added due to uri: " + widgetIdsUpdatedByUri);
+                mNotificationKeyToWidgetIdsMatchedByUri.put(sbn.getKey(), widgetIdsUpdatedByUri);
+            }
+        } else {
+            // Remove the notification on any widgets where the notification was added
+            // purely based on the Uri.
+            Set<String> widgetsPreviouslyUpdatedByUri =
+                    mNotificationKeyToWidgetIdsMatchedByUri.remove(sbn.getKey());
+            if (widgetsPreviouslyUpdatedByUri != null && !widgetsPreviouslyUpdatedByUri.isEmpty()) {
+                if (DEBUG) Log.d(TAG, "Remove due to uri: " + widgetsPreviouslyUpdatedByUri);
+                updateWidgetIdsForNotificationAction(widgetsPreviouslyUpdatedByUri, sbn,
+                        action);
+            }
+        }
+    }
+
+    /**
+     * Retrieves from storage any tiles with the same contact Uri as linked via the {@code sbn}.
+     * Supplements the tiles with the notification content only if they still have {@link
+     * android.Manifest.permission.READ_CONTACTS} permission.
+     */
+    @Nullable
+    private Set<String> supplementTilesByUri(StatusBarNotification sbn,
+            PeopleSpaceUtils.NotificationAction notificationAction, PeopleTileKey key) {
+        if (!shouldMatchNotificationByUri(sbn)) {
+            if (DEBUG) Log.d(TAG, "Should not supplement conversation");
+            return null;
+        }
+
+        // Try to get the Contact Uri from the Missed Call notification directly.
+        String contactUri = getContactUri(sbn);
+        if (contactUri == null) {
+            if (DEBUG) Log.d(TAG, "No contact uri");
+            return null;
+        }
+
+        // Supplement any tiles with the same Uri.
+        Set<String> storedWidgetIdsByUri =
+                new HashSet<>(mSharedPrefs.getStringSet(contactUri, new HashSet<>()));
+        if (storedWidgetIdsByUri.isEmpty()) {
+            if (DEBUG) Log.d(TAG, "No tiles for contact");
+            return null;
+        }
+
+        if (mPackageManager.checkPermission(READ_CONTACTS,
+                sbn.getPackageName()) != PackageManager.PERMISSION_GRANTED) {
+            if (DEBUG) Log.d(TAG, "Notifying app missing permissions");
+            return null;
+        }
+
+        Set<String> widgetIdsUpdatedByUri = new HashSet<>();
+        for (String widgetIdString : storedWidgetIdsByUri) {
+            int widgetId = Integer.parseInt(widgetIdString);
+            PeopleSpaceTile storedTile = getTileForExistingWidget(widgetId);
+            // Don't update a widget already updated.
+            if (key.equals(new PeopleTileKey(storedTile))) {
+                continue;
+            }
+            if (storedTile == null || mPackageManager.checkPermission(READ_CONTACTS,
+                    storedTile.getPackageName()) != PackageManager.PERMISSION_GRANTED) {
+                if (DEBUG) Log.d(TAG, "Cannot supplement tile: " + storedTile.getUserName());
+                continue;
+            }
+            if (DEBUG) Log.d(TAG, "Adding notification by uri: " + sbn.getKey());
+            updateStorageAndViewWithNotificationData(sbn, notificationAction,
+                    widgetId, storedTile);
+            widgetIdsUpdatedByUri.add(String.valueOf(widgetId));
+        }
+        return widgetIdsUpdatedByUri;
+    }
+
+    /**
+     * Try to retrieve a valid Uri via {@code sbn}, falling back to the {@code
+     * contactUriFromShortcut} if valid.
+     */
+    @Nullable
+    private String getContactUri(StatusBarNotification sbn) {
+        // First, try to get a Uri from the Person directly set on the Notification.
+        ArrayList<Person> people = sbn.getNotification().extras.getParcelableArrayList(
+                EXTRA_PEOPLE_LIST);
+        if (people != null && people.get(0) != null) {
+            String contactUri = people.get(0).getUri();
+            if (contactUri != null && !contactUri.isEmpty()) {
+                return contactUri;
+            }
+        }
+
+        // Then, try to get a Uri from the Person set on the Notification message.
+        List<Notification.MessagingStyle.Message> messages =
+                getMessagingStyleMessages(sbn.getNotification());
+        if (messages != null && !messages.isEmpty()) {
+            Notification.MessagingStyle.Message message = messages.get(0);
+            Person sender = message.getSenderPerson();
+            if (sender != null && sender.getUri() != null && !sender.getUri().isEmpty()) {
+                return sender.getUri();
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Returns whether a notification should be matched to other Tiles by Uri.
+     *
+     * <p>Currently only matches missed calls.
+     */
+    private boolean shouldMatchNotificationByUri(StatusBarNotification sbn) {
+        Notification notification = sbn.getNotification();
+        if (notification == null) {
+            if (DEBUG) Log.d(TAG, "Notification is null");
+            return false;
+        }
+        if (!Objects.equals(notification.category, CATEGORY_MISSED_CALL)) {
+            if (DEBUG) Log.d(TAG, "Not missed call");
+            return false;
+        }
+        return true;
+    }
+
     /**
      * Update the tiles associated with the incoming conversation update.
      */
@@ -309,16 +494,11 @@
     private void updateStorageAndViewWithNotificationData(
             StatusBarNotification sbn,
             PeopleSpaceUtils.NotificationAction notificationAction,
-            int appWidgetId) {
-        PeopleSpaceTile storedTile = getTileForExistingWidget(appWidgetId);
-        if (storedTile == null) {
-            if (DEBUG) Log.d(TAG, "Could not find stored tile to add notification to");
-            return;
-        }
+            int appWidgetId, PeopleSpaceTile storedTile) {
         if (notificationAction == PeopleSpaceUtils.NotificationAction.POSTED) {
             if (DEBUG) Log.i(TAG, "Adding notification to storage, appWidgetId: " + appWidgetId);
             storedTile = augmentTileFromNotification(mContext, storedTile, sbn);
-        } else {
+        } else if (storedTile.getNotificationKey().equals(sbn.getKey())) {
             if (DEBUG) {
                 Log.i(TAG, "Removing notification from storage, appWidgetId: " + appWidgetId);
             }
@@ -328,6 +508,7 @@
                     .setNotificationKey(null)
                     .setNotificationContent(null)
                     .setNotificationDataUri(null)
+                    .setMessagesCount(0)
                     // Reset missed calls category.
                     .setNotificationCategory(null)
                     .build();
@@ -439,7 +620,8 @@
         synchronized (mLock) {
             if (DEBUG) Log.d(TAG, "Add storage for : " + tile.getId());
             PeopleTileKey key = new PeopleTileKey(tile);
-            PeopleSpaceUtils.setSharedPreferencesStorageForTile(mContext, key, appWidgetId);
+            PeopleSpaceUtils.setSharedPreferencesStorageForTile(mContext, key, appWidgetId,
+                    tile.getContactUri());
         }
         try {
             if (DEBUG) Log.d(TAG, "Caching shortcut for PeopleTile: " + tile.getId());
@@ -495,6 +677,7 @@
             // Retrieve storage needed for widget deletion.
             PeopleTileKey key;
             Set<String> storedWidgetIdsForKey;
+            String contactUriString;
             synchronized (mLock) {
                 SharedPreferences widgetSp = mContext.getSharedPreferences(String.valueOf(widgetId),
                         Context.MODE_PRIVATE);
@@ -508,9 +691,11 @@
                 }
                 storedWidgetIdsForKey = new HashSet<>(
                         mSharedPrefs.getStringSet(key.toString(), new HashSet<>()));
+                contactUriString = mSharedPrefs.getString(String.valueOf(widgetId), null);
             }
             synchronized (mLock) {
-                PeopleSpaceUtils.removeSharedPreferencesStorageForTile(mContext, key, widgetId);
+                PeopleSpaceUtils.removeSharedPreferencesStorageForTile(mContext, key, widgetId,
+                        contactUriString);
             }
             // If another tile with the conversation is still stored, we need to keep the listener.
             if (DEBUG) Log.d(TAG, "Stored widget IDs: " + storedWidgetIdsForKey.toString());
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt b/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt
index bdd37fc..9cd97ff8 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt
+++ b/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt
@@ -33,8 +33,6 @@
     private var iconMargin = 0
     private var iconSize = 0
     private var iconColor = 0
-    private var defaultBackgroundColor = 0
-    private var cameraBackgroundColor = 0
 
     private lateinit var iconsContainer: LinearLayout
 
@@ -75,11 +73,6 @@
         if (!privacyList.isEmpty()) {
             generateContentDescription(builder)
             setIcons(builder, iconsContainer)
-            if (builder.types.contains(PrivacyType.TYPE_CAMERA)) {
-                iconsContainer.background.setTint(cameraBackgroundColor)
-            } else {
-                iconsContainer.background.setTint(defaultBackgroundColor)
-            }
         } else {
             iconsContainer.removeAllViews()
         }
@@ -99,8 +92,6 @@
                 .getDimensionPixelSize(R.dimen.ongoing_appops_chip_icon_size)
         iconColor =
                 Utils.getColorAttrDefaultColor(context, com.android.internal.R.attr.colorPrimary)
-        defaultBackgroundColor = context.getColor(R.color.privacy_circle_microphone_location)
-        cameraBackgroundColor = context.getColor(R.color.privacy_circle_camera)
 
         val padding = context.resources
                 .getDimensionPixelSize(R.dimen.ongoing_appops_chip_side_padding)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
index b8823e1..ee0b0c2 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
@@ -65,12 +65,14 @@
     private final QuickQSPanel mQuickQsPanel;
     private final QSPanelController mQsPanelController;
     private final QuickQSPanelController mQuickQSPanelController;
+    private final QuickStatusBarHeader mQuickStatusBarHeader;
     private final QSSecurityFooter mSecurityFooter;
     private final QS mQs;
 
     private PagedTileLayout mPagedLayout;
 
     private boolean mOnFirstPage = true;
+    private QSExpansionPathInterpolator mQSExpansionPathInterpolator;
     private TouchAnimator mFirstPageAnimator;
     private TouchAnimator mFirstPageDelayedAnimator;
     private TouchAnimator mTranslationXAnimator;
@@ -98,19 +100,22 @@
     private final FeatureFlags mFeatureFlags;
 
     @Inject
-    public QSAnimator(QS qs, QuickQSPanel quickPanel, QSPanelController qsPanelController,
+    public QSAnimator(QS qs, QuickQSPanel quickPanel, QuickStatusBarHeader quickStatusBarHeader,
+            QSPanelController qsPanelController,
             QuickQSPanelController quickQSPanelController, QSTileHost qsTileHost,
             QSSecurityFooter securityFooter, @Main Executor executor, TunerService tunerService,
-            FeatureFlags featureFlags) {
+            FeatureFlags featureFlags, QSExpansionPathInterpolator qsExpansionPathInterpolator) {
         mQs = qs;
         mQuickQsPanel = quickPanel;
         mQsPanelController = qsPanelController;
         mQuickQSPanelController = quickQSPanelController;
+        mQuickStatusBarHeader = quickStatusBarHeader;
         mSecurityFooter = securityFooter;
         mHost = qsTileHost;
         mExecutor = executor;
         mTunerService = tunerService;
         mFeatureFlags = featureFlags;
+        mQSExpansionPathInterpolator = qsExpansionPathInterpolator;
         mHost.addCallback(this);
         mQsPanelController.addOnAttachStateChangeListener(this);
         qs.getView().addOnLayoutChangeListener(this);
@@ -252,7 +257,9 @@
                 if (count < tileLayout.getNumVisibleTiles()) {
                     getRelativePosition(loc1, quickTileView, view);
                     getRelativePosition(loc2, tileView, view);
-                    int yOffset = qsSideLabelsEnabled ? loc2[1] - loc1[1] : 0;
+                    int yOffset = qsSideLabelsEnabled
+                            ? loc2[1] - loc1[1]
+                            : mQuickStatusBarHeader.getOffsetTranslation();
                     // Move the quick tile right from its location to the new one.
                     View v = qsSideLabelsEnabled ? quickTileView.getIcon() : quickTileView;
                     translationXBuilder.addFloat(v, "translationX", 0, xDiff);
@@ -266,8 +273,14 @@
                     translationYBuilder.addFloat(v, "translationY", -yDiff + yOffset, 0);
 
                     if (qsSideLabelsEnabled) {
-                        translationYBuilder.addFloat(quickTileView, "translationY", 0, yOffset);
-                        translationYBuilder.addFloat(tileView, "translationY", -yOffset, 0);
+                        // Offset the translation animation on the views
+                        // (that goes from 0 to getOffsetTranslation)
+                        int offsetWithQSBHTranslation =
+                                yOffset - mQuickStatusBarHeader.getOffsetTranslation();
+                        translationYBuilder.addFloat(quickTileView, "translationY", 0,
+                                offsetWithQSBHTranslation);
+                        translationYBuilder.addFloat(tileView, "translationY",
+                                -offsetWithQSBHTranslation, 0);
 
                         if (mQQSTileHeightAnimator == null) {
                             mQQSTileHeightAnimator = new HeightExpansionAnimator(this,
@@ -375,22 +388,23 @@
             }
 
             float px = 0;
-            float py = 1;
             if (tiles.size() <= 3) {
                 px = 1;
             } else if (tiles.size() <= 6) {
                 px = .4f;
             }
-            PathInterpolatorBuilder interpolatorBuilder = new PathInterpolatorBuilder(0, 0, px, py);
-            translationXBuilder.setInterpolator(interpolatorBuilder.getXInterpolator());
-            translationYBuilder.setInterpolator(interpolatorBuilder.getYInterpolator());
+            mQSExpansionPathInterpolator.setControlX2(px);
+            translationXBuilder.setInterpolator(mQSExpansionPathInterpolator.getXInterpolator());
+            translationYBuilder.setInterpolator(mQSExpansionPathInterpolator.getYInterpolator());
             mTranslationXAnimator = translationXBuilder.build();
             mTranslationYAnimator = translationYBuilder.build();
             if (mQQSTileHeightAnimator != null) {
-                mQQSTileHeightAnimator.setInterpolator(interpolatorBuilder.getYInterpolator());
+                mQQSTileHeightAnimator.setInterpolator(
+                        mQSExpansionPathInterpolator.getYInterpolator());
             }
             if (mOtherTilesExpandAnimator != null) {
-                mOtherTilesExpandAnimator.setInterpolator(interpolatorBuilder.getYInterpolator());
+                mOtherTilesExpandAnimator.setInterpolator(
+                        mQSExpansionPathInterpolator.getYInterpolator());
             }
         }
         mNonfirstPageAnimator = new TouchAnimator.Builder()
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java b/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
index 9967936..d54d3f2 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
@@ -23,6 +23,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.Configuration;
+import android.content.res.Resources;
 import android.graphics.drawable.Animatable;
 import android.util.AttributeSet;
 import android.util.SparseArray;
@@ -139,8 +140,12 @@
     }
 
     private void updateDetailText() {
-        mDetailDoneButton.setText(R.string.quick_settings_done);
-        mDetailSettingsButton.setText(R.string.quick_settings_more_settings);
+        int resId = mDetailAdapter != null ? mDetailAdapter.getDoneText() : Resources.ID_NULL;
+        mDetailDoneButton.setText(
+                (resId != Resources.ID_NULL) ? resId : R.string.quick_settings_done);
+        resId = mDetailAdapter != null ? mDetailAdapter.getSettingsText() : Resources.ID_NULL;
+        mDetailSettingsButton.setText(
+                (resId != Resources.ID_NULL) ? resId : R.string.quick_settings_more_settings);
     }
 
     public void updateResources() {
@@ -218,6 +223,7 @@
             mQsPanelController.setGridContentVisibility(true);
             mQsPanelCallback.onScanStateChanged(false);
         }
+        updateDetailText();
         sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
 
         if (mShouldAnimate) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSEvents.kt b/packages/SystemUI/src/com/android/systemui/qs/QSEvents.kt
index 54e8a2b..cc5a771 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSEvents.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSEvents.kt
@@ -118,7 +118,19 @@
     QS_USER_DETAIL_CLOSE(426),
 
     @UiEvent(doc = "User switcher QS detail panel more settings pressed")
-    QS_USER_MORE_SETTINGS(427);
+    QS_USER_MORE_SETTINGS(427),
+
+    @UiEvent(doc = "The user has added a guest in the detail panel")
+    QS_USER_GUEST_ADD(754),
+
+    @UiEvent(doc = "The user selected 'Start over' after switching to the existing Guest user")
+    QS_USER_GUEST_WIPE(755),
+
+    @UiEvent(doc = "The user selected 'Yes, continue' after switching to the existing Guest user")
+    QS_USER_GUEST_CONTINUE(756),
+
+    @UiEvent(doc = "The user has pressed 'Remove guest' in the detail panel")
+    QS_USER_GUEST_REMOVE(757);
 
     override fun getId() = _id
 }
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSExpansionPathInterpolator.kt b/packages/SystemUI/src/com/android/systemui/qs/QSExpansionPathInterpolator.kt
new file mode 100644
index 0000000..d351b89
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSExpansionPathInterpolator.kt
@@ -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.qs
+
+import android.view.animation.Interpolator
+import javax.inject.Inject
+import javax.inject.Singleton
+
+@Singleton
+class QSExpansionPathInterpolator @Inject constructor() {
+
+    private var pathInterpolatorBuilder = PathInterpolatorBuilder(0f, 0f, 0f, 1f)
+    private var lastX = 0f
+    val xInterpolator: Interpolator
+        get() = pathInterpolatorBuilder.xInterpolator
+
+    val yInterpolator: Interpolator
+        get() = pathInterpolatorBuilder.yInterpolator
+
+    fun setControlX2(value: Float) {
+        if (value != lastX) {
+            lastX = value
+            pathInterpolatorBuilder = PathInterpolatorBuilder(0f, 0f, lastX, 1f)
+        }
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSHeaderInfoLayout.kt b/packages/SystemUI/src/com/android/systemui/qs/QSHeaderInfoLayout.kt
deleted file mode 100644
index c654621..0000000
--- a/packages/SystemUI/src/com/android/systemui/qs/QSHeaderInfoLayout.kt
+++ /dev/null
@@ -1,131 +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.qs
-
-import android.content.Context
-import android.util.AttributeSet
-import android.view.View
-import android.widget.FrameLayout
-import com.android.systemui.R
-
-/**
- * Container for the Next Alarm and Ringer status texts in [QuickStatusBarHeader].
- *
- * If both elements are visible, it splits the available space according to the following rules:
- * * If both views add up to less than the total space, they take all the space they need.
- * * If both views are larger than half the space, each view takes half the space.
- * * Otherwise, the smaller view takes the space it needs and the larger one takes all remaining
- * space.
- */
-class QSHeaderInfoLayout @JvmOverloads constructor(
-        context: Context,
-        attrs: AttributeSet? = null,
-        defStyle: Int = 0,
-        defStyleRes: Int = 0
-) : FrameLayout(context, attrs, defStyle, defStyleRes) {
-
-    private lateinit var alarmContainer: View
-    private lateinit var ringerContainer: View
-    private lateinit var statusSeparator: View
-    private val location = Location(0, 0)
-
-    override fun onFinishInflate() {
-        super.onFinishInflate()
-        alarmContainer = findViewById(R.id.alarm_container)
-        ringerContainer = findViewById(R.id.ringer_container)
-        statusSeparator = findViewById(R.id.status_separator)
-    }
-
-    override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
-        // At most one view is there
-        if (statusSeparator.visibility == View.GONE) super.onLayout(changed, l, t, r, b)
-        else {
-            val layoutRTL = isLayoutRtl
-            val width = r - l
-            val height = b - t
-            var offset = 0
-
-            offset += alarmContainer.layoutView(width, height, offset, layoutRTL)
-            offset += statusSeparator.layoutView(width, height, offset, layoutRTL)
-            ringerContainer.layoutView(width, height, offset, layoutRTL)
-        }
-    }
-
-    private fun View.layoutView(pWidth: Int, pHeight: Int, offset: Int, RTL: Boolean): Int {
-        location.setLocationFromOffset(pWidth, offset, this.measuredWidth, RTL)
-        layout(location.left, 0, location.right, pHeight)
-        return this.measuredWidth
-    }
-
-    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
-        super.onMeasure(
-                MeasureSpec.makeMeasureSpec(
-                        MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.AT_MOST),
-                heightMeasureSpec)
-        val width = MeasureSpec.getSize(widthMeasureSpec)
-        // Once we measure the views, using as much space as they need, we need to remeasure them
-        // assigning them their final width. This is because TextViews decide whether to MARQUEE
-        // after onMeasure.
-        if (statusSeparator.visibility != View.GONE) {
-            val alarmWidth = alarmContainer.measuredWidth
-            val separatorWidth = statusSeparator.measuredWidth
-            val ringerWidth = ringerContainer.measuredWidth
-            val availableSpace = MeasureSpec.getSize(width) - separatorWidth
-            if (alarmWidth < availableSpace / 2) {
-                measureChild(
-                        ringerContainer,
-                        MeasureSpec.makeMeasureSpec(
-                                Math.min(ringerWidth, availableSpace - alarmWidth),
-                                MeasureSpec.AT_MOST),
-                        heightMeasureSpec)
-            } else if (ringerWidth < availableSpace / 2) {
-                measureChild(alarmContainer,
-                        MeasureSpec.makeMeasureSpec(
-                                Math.min(alarmWidth, availableSpace - ringerWidth),
-                                MeasureSpec.AT_MOST),
-                        heightMeasureSpec)
-            } else {
-                measureChild(
-                        alarmContainer,
-                        MeasureSpec.makeMeasureSpec(availableSpace / 2, MeasureSpec.AT_MOST),
-                        heightMeasureSpec)
-                measureChild(
-                        ringerContainer,
-                        MeasureSpec.makeMeasureSpec(availableSpace / 2, MeasureSpec.AT_MOST),
-                        heightMeasureSpec)
-            }
-        }
-        setMeasuredDimension(width, measuredHeight)
-    }
-
-    private data class Location(var left: Int, var right: Int) {
-        /**
-         * Sets the [left] and [right] with the correct values for laying out the child, respecting
-         * RTL. Only set the variable through here to prevent concurrency issues.
-         * This is done to prevent allocation of [Pair] in [onLayout].
-         */
-        fun setLocationFromOffset(parentWidth: Int, offset: Int, width: Int, RTL: Boolean) {
-            if (RTL) {
-                left = parentWidth - offset - width
-                right = parentWidth - offset
-            } else {
-                left = offset
-                right = offset + width
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index c794a21..95f7e20 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -391,20 +391,13 @@
         index++;
 
         if (mSecurityFooter != null) {
-            LinearLayout.LayoutParams layoutParams =
-                    (LayoutParams) mSecurityFooter.getLayoutParams();
             if (mUsingHorizontalLayout && mHeaderContainer != null) {
                 // Adding the security view to the header, that enables us to avoid scrolling
-                layoutParams.width = 0;
-                layoutParams.weight = 1.6f;
-                switchToParent(mSecurityFooter, mHeaderContainer, 1 /* always in second place */);
+                switchToParent(mSecurityFooter, mHeaderContainer, 0);
             } else {
-                layoutParams.width = LayoutParams.WRAP_CONTENT;
-                layoutParams.weight = 0;
                 switchToParent(mSecurityFooter, parent, index);
                 index++;
             }
-            mSecurityFooter.setLayoutParams(layoutParams);
         }
 
         if (mFooter != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java
index 5e13fd3..2c5dbcd 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java
@@ -283,31 +283,17 @@
             return mContext.getString(R.string.quick_settings_disclosure_named_vpn,
                     vpnName);
         }
+        if (hasWorkProfile && isNetworkLoggingEnabled) {
+            return mContext.getString(
+                    R.string.quick_settings_disclosure_managed_profile_network_activity);
+        }
         if (isProfileOwnerOfOrganizationOwnedDevice) {
-            if (isNetworkLoggingEnabled) {
-                if (organizationName == null) {
-                    return mContext.getString(
-                            R.string.quick_settings_disclosure_management_monitoring);
-                }
-                return mContext.getString(
-                        R.string.quick_settings_disclosure_named_management_monitoring,
-                        organizationName);
-            }
             if (workProfileOrganizationName == null) {
                 return mContext.getString(R.string.quick_settings_disclosure_management);
             }
             return mContext.getString(R.string.quick_settings_disclosure_named_management,
                     workProfileOrganizationName);
         }
-        if (hasWorkProfile && isNetworkLoggingEnabled) {
-            if (workProfileOrganizationName == null) {
-                return mContext.getString(
-                        R.string.quick_settings_disclosure_managed_profile_monitoring);
-            }
-            return mContext.getString(
-                    R.string.quick_settings_disclosure_named_managed_profile_monitoring,
-                    workProfileOrganizationName);
-        }
         return null;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
index 3e3451e..0a9c12f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
@@ -474,22 +474,21 @@
         if (tiles.contains("internet") || tiles.contains("wifi") || tiles.contains("cell")) {
             if (FeatureFlagUtils.isEnabled(context, FeatureFlagUtils.SETTINGS_PROVIDER_MODEL)) {
                 if (!tiles.contains("internet")) {
-                    tiles.add("internet");
-                }
-                if (tiles.contains("wifi")) {
+                    if (tiles.contains("wifi")) {
+                        // Replace the WiFi with Internet, and remove the Cell
+                        tiles.set(tiles.indexOf("wifi"), "internet");
+                        tiles.remove("cell");
+                    } else if (tiles.contains("cell")) {
+                        // Replace the Cell with Internet
+                        tiles.set(tiles.indexOf("cell"), "internet");
+                    }
+                } else {
                     tiles.remove("wifi");
-                }
-                if (tiles.contains("cell")) {
                     tiles.remove("cell");
                 }
             } else {
                 if (tiles.contains("internet")) {
-                    tiles.remove("internet");
-                }
-                if (!tiles.contains("wifi")) {
-                    tiles.add("wifi");
-                }
-                if (!tiles.contains("cell")) {
+                    tiles.set(tiles.indexOf("internet"), "wifi");
                     tiles.add("cell");
                 }
             }
@@ -513,6 +512,14 @@
                 && GarbageMonitor.ADD_MEMORY_TILE_TO_DEFAULT_ON_DEBUGGABLE_BUILDS) {
             tiles.add(GarbageMonitor.MemoryTile.TILE_SPEC);
         }
+        // TODO(b/174753536): Change the config file directly.
+        // Filter out unused tiles from the default QS config.
+        if (FeatureFlagUtils.isEnabled(context, FeatureFlagUtils.SETTINGS_PROVIDER_MODEL)) {
+            tiles.remove("cell");
+            tiles.remove("wifi");
+        } else {
+            tiles.remove("internet");
+        }
         return tiles;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
index a0bf584..82ae2dd 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
@@ -17,15 +17,14 @@
 import static android.app.StatusBarManager.DISABLE2_QUICK_SETTINGS;
 import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
 
-import android.annotation.ColorInt;
-import android.app.AlarmManager.AlarmClockInfo;
+import static com.android.systemui.statusbar.StatusBarIconView.STATE_HIDDEN;
+import static com.android.systemui.statusbar.StatusBarIconView.STATE_ICON;
+
 import android.content.Context;
-import android.content.res.ColorStateList;
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.Color;
 import android.graphics.Rect;
-import android.media.AudioManager;
 import android.util.AttributeSet;
 import android.util.MathUtils;
 import android.util.Pair;
@@ -34,66 +33,46 @@
 import android.view.ViewGroup;
 import android.view.WindowInsets;
 import android.widget.FrameLayout;
-import android.widget.ImageView;
 import android.widget.LinearLayout;
-import android.widget.RelativeLayout;
 import android.widget.Space;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
-import androidx.lifecycle.Lifecycle;
-import androidx.lifecycle.LifecycleOwner;
-import androidx.lifecycle.LifecycleRegistry;
 
 import com.android.settingslib.Utils;
 import com.android.systemui.BatteryMeterView;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
-import com.android.systemui.privacy.OngoingPrivacyChip;
 import com.android.systemui.qs.QSDetail.Callback;
+import com.android.systemui.statusbar.StatusBarMobileView;
 import com.android.systemui.statusbar.phone.StatusBarIconController.TintedIconManager;
 import com.android.systemui.statusbar.phone.StatusBarWindowView;
+import com.android.systemui.statusbar.phone.StatusIconContainer;
 import com.android.systemui.statusbar.policy.Clock;
 
-import java.util.Locale;
-import java.util.Objects;
-
 /**
- * View that contains the top-most bits of the screen (primarily the status bar with date, time, and
- * battery) and also contains the {@link QuickQSPanel} along with some of the panel's inner
- * contents.
+ * View that contains the top-most bits of the QS panel (primarily the status bar with date, time,
+ * battery, carrier info and privacy icons) and also contains the {@link QuickQSPanel}.
  */
-public class QuickStatusBarHeader extends RelativeLayout implements LifecycleOwner {
-
-    public static final int MAX_TOOLTIP_SHOWN_COUNT = 2;
+public class QuickStatusBarHeader extends FrameLayout {
 
     private boolean mExpanded;
     private boolean mQsDisabled;
 
+    private TouchAnimator mAlphaAnimator;
+    private TouchAnimator mTranslationAnimator;
+
     protected QuickQSPanel mHeaderQsPanel;
-    private TouchAnimator mStatusIconsAlphaAnimator;
-    private TouchAnimator mHeaderTextContainerAlphaAnimator;
+    private View mDatePrivacyView;
+    private View mClockIconsView;
+    private View mContainer;
 
-    private View mSystemIconsView;
-    private View mQuickQsStatusIcons;
-    private View mHeaderTextContainerView;
-
-    private ImageView mNextAlarmIcon;
-    /** {@link TextView} containing the actual text indicating when the next alarm will go off. */
-    private TextView mNextAlarmTextView;
-    private View mNextAlarmContainer;
-    private View mStatusSeparator;
-    private ImageView mRingerModeIcon;
-    private TextView mRingerModeTextView;
-    private View mRingerContainer;
+    private View mQSCarriers;
     private Clock mClockView;
-    private OngoingPrivacyChip mPrivacyChip;
     private Space mSpace;
     private BatteryMeterView mBatteryRemainingIcon;
-    private TintedIconManager mTintedIconManager;
+    private StatusIconContainer mIconContainer;
 
-    // Used for RingerModeTracker
-    private final LifecycleRegistry mLifecycle = new LifecycleRegistry(this);
+
+    private TintedIconManager mTintedIconManager;
+    private QSExpansionPathInterpolator mQSExpansionPathInterpolator;
 
     private int mStatusBarPaddingTop = 0;
     private int mRoundedCornerPadding = 0;
@@ -102,12 +81,26 @@
     private int mWaterfallTopInset;
     private int mCutOutPaddingLeft;
     private int mCutOutPaddingRight;
-    private float mExpandedHeaderAlpha = 1.0f;
+    private float mClockIconsAlpha = 1.0f;
+    private float mDatePrivacyAlpha = 1.0f;
     private float mKeyguardExpansionFraction;
     private int mTextColorPrimary = Color.TRANSPARENT;
+    private int mTopViewMeasureHeight;
+
+    private final String mMobileSlotName;
 
     public QuickStatusBarHeader(Context context, AttributeSet attrs) {
         super(context, attrs);
+        mMobileSlotName = context.getString(com.android.internal.R.string.status_bar_mobile);
+    }
+
+    /**
+     * How much the view containing the clock and QQS will translate down when QS is fully expanded.
+     *
+     * This matches the measured height of the view containing the date and privacy icons.
+     */
+    public int getOffsetTranslation() {
+        return mTopViewMeasureHeight;
     }
 
     @Override
@@ -115,19 +108,12 @@
         super.onFinishInflate();
 
         mHeaderQsPanel = findViewById(R.id.quick_qs_panel);
-        mSystemIconsView = findViewById(R.id.quick_status_bar_system_icons);
-        mQuickQsStatusIcons = findViewById(R.id.quick_qs_status_icons);
+        mDatePrivacyView = findViewById(R.id.quick_status_bar_date_privacy);
+        mClockIconsView = findViewById(R.id.quick_qs_status_icons);
+        mQSCarriers = findViewById(R.id.carrier_group);
+        mContainer = findViewById(R.id.container);
+        mIconContainer = findViewById(R.id.statusIcons);
 
-        // Views corresponding to the header info section (e.g. ringer and next alarm).
-        mHeaderTextContainerView = findViewById(R.id.header_text_container);
-        mStatusSeparator = findViewById(R.id.status_separator);
-        mNextAlarmIcon = findViewById(R.id.next_alarm_icon);
-        mNextAlarmTextView = findViewById(R.id.next_alarm_text);
-        mNextAlarmContainer = findViewById(R.id.alarm_container);
-        mRingerModeIcon = findViewById(R.id.ringer_mode_icon);
-        mRingerModeTextView = findViewById(R.id.ringer_mode_text);
-        mRingerContainer = findViewById(R.id.ringer_container);
-        mPrivacyChip = findViewById(R.id.privacy_chip);
         mClockView = findViewById(R.id.clock);
         mSpace = findViewById(R.id.space);
         // Tint for the battery icons are handled in setupHost()
@@ -140,79 +126,34 @@
         // QS will always show the estimate, and BatteryMeterView handles the case where
         // it's unavailable or charging
         mBatteryRemainingIcon.setPercentShowMode(BatteryMeterView.MODE_ESTIMATE);
-        mRingerModeTextView.setSelected(true);
-        mNextAlarmTextView.setSelected(true);
     }
 
-    void onAttach(TintedIconManager iconManager) {
+    void onAttach(TintedIconManager iconManager,
+            QSExpansionPathInterpolator qsExpansionPathInterpolator) {
         mTintedIconManager = iconManager;
         int fillColor = Utils.getColorAttrDefaultColor(getContext(),
                 android.R.attr.textColorPrimary);
 
         // Set the correct tint for the status icons so they contrast
         iconManager.setTint(fillColor);
-        mNextAlarmIcon.setImageTintList(ColorStateList.valueOf(fillColor));
-        mRingerModeIcon.setImageTintList(ColorStateList.valueOf(fillColor));
+
+        mQSExpansionPathInterpolator = qsExpansionPathInterpolator;
+        updateAnimators();
     }
 
     public QuickQSPanel getHeaderQsPanel() {
         return mHeaderQsPanel;
     }
 
-    void updateStatusText(int ringerMode, AlarmClockInfo nextAlarm, boolean zenOverridingRinger,
-            boolean use24HourFormat) {
-        boolean changed = updateRingerStatus(ringerMode, zenOverridingRinger)
-                || updateAlarmStatus(nextAlarm, use24HourFormat);
-
-        if (changed) {
-            boolean alarmVisible = mNextAlarmTextView.getVisibility() == View.VISIBLE;
-            boolean ringerVisible = mRingerModeTextView.getVisibility() == View.VISIBLE;
-            mStatusSeparator.setVisibility(alarmVisible && ringerVisible ? View.VISIBLE
-                    : View.GONE);
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+        if (mDatePrivacyView.getMeasuredHeight() != mTopViewMeasureHeight) {
+            mTopViewMeasureHeight = mDatePrivacyView.getMeasuredHeight();
+            updateAnimators();
         }
     }
 
-    private boolean updateRingerStatus(int ringerMode, boolean zenOverridingRinger) {
-        boolean isOriginalVisible = mRingerModeTextView.getVisibility() == View.VISIBLE;
-        CharSequence originalRingerText = mRingerModeTextView.getText();
-
-        boolean ringerVisible = false;
-        if (!zenOverridingRinger) {
-            if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) {
-                mRingerModeIcon.setImageResource(R.drawable.ic_volume_ringer_vibrate);
-                mRingerModeTextView.setText(R.string.qs_status_phone_vibrate);
-                ringerVisible = true;
-            } else if (ringerMode == AudioManager.RINGER_MODE_SILENT) {
-                mRingerModeIcon.setImageResource(R.drawable.ic_volume_ringer_mute);
-                mRingerModeTextView.setText(R.string.qs_status_phone_muted);
-                ringerVisible = true;
-            }
-        }
-        mRingerModeIcon.setVisibility(ringerVisible ? View.VISIBLE : View.GONE);
-        mRingerModeTextView.setVisibility(ringerVisible ? View.VISIBLE : View.GONE);
-        mRingerContainer.setVisibility(ringerVisible ? View.VISIBLE : View.GONE);
-
-        return isOriginalVisible != ringerVisible ||
-                !Objects.equals(originalRingerText, mRingerModeTextView.getText());
-    }
-
-    private boolean updateAlarmStatus(AlarmClockInfo nextAlarm, boolean use24HourFormat) {
-        boolean isOriginalVisible = mNextAlarmTextView.getVisibility() == View.VISIBLE;
-        CharSequence originalAlarmText = mNextAlarmTextView.getText();
-
-        boolean alarmVisible = false;
-        if (nextAlarm != null) {
-            alarmVisible = true;
-            mNextAlarmTextView.setText(formatNextAlarm(nextAlarm, use24HourFormat));
-        }
-        mNextAlarmIcon.setVisibility(alarmVisible ? View.VISIBLE : View.GONE);
-        mNextAlarmTextView.setVisibility(alarmVisible ? View.VISIBLE : View.GONE);
-        mNextAlarmContainer.setVisibility(alarmVisible ? View.VISIBLE : View.GONE);
-
-        return isOriginalVisible != alarmVisible ||
-                !Objects.equals(originalAlarmText, mNextAlarmTextView.getText());
-    }
-
     @Override
     protected void onConfigurationChanged(Configuration newConfig) {
         super.onConfigurationChanged(newConfig);
@@ -225,40 +166,27 @@
         updateResources();
     }
 
-    /**
-     * The height of QQS should always be the status bar height + 128dp. This is normally easy, but
-     * when there is a notch involved the status bar can remain a fixed pixel size.
-     */
-    private void updateMinimumHeight() {
-        int sbHeight = mContext.getResources().getDimensionPixelSize(
-                com.android.internal.R.dimen.status_bar_height);
-        int qqsHeight = mContext.getResources().getDimensionPixelSize(
-                R.dimen.qs_quick_header_panel_height);
-
-        setMinimumHeight(sbHeight + qqsHeight);
-    }
-
     void updateResources() {
         Resources resources = mContext.getResources();
-        updateMinimumHeight();
 
         mRoundedCornerPadding = resources.getDimensionPixelSize(
                 R.dimen.rounded_corner_content_padding);
         mStatusBarPaddingTop = resources.getDimensionPixelSize(R.dimen.status_bar_padding_top);
 
-        // Update height for a few views, especially due to landscape mode restricting space.
-        mHeaderTextContainerView.getLayoutParams().height =
-                resources.getDimensionPixelSize(R.dimen.qs_header_tooltip_height);
-        mHeaderTextContainerView.setLayoutParams(mHeaderTextContainerView.getLayoutParams());
-
-        mSystemIconsView.getLayoutParams().height = resources.getDimensionPixelSize(
+        int qsOffsetHeight = resources.getDimensionPixelSize(
                 com.android.internal.R.dimen.quick_qs_offset_height);
-        mSystemIconsView.setLayoutParams(mSystemIconsView.getLayoutParams());
+
+        mDatePrivacyView.getLayoutParams().height =
+                Math.max(qsOffsetHeight, mDatePrivacyView.getMinimumHeight());
+        mDatePrivacyView.setLayoutParams(mDatePrivacyView.getLayoutParams());
+
+        mClockIconsView.getLayoutParams().height =
+                Math.max(qsOffsetHeight, mClockIconsView.getMinimumHeight());
+        mClockIconsView.setLayoutParams(mClockIconsView.getLayoutParams());
 
         ViewGroup.LayoutParams lp = getLayoutParams();
         if (mQsDisabled) {
-            lp.height = resources.getDimensionPixelSize(
-                    com.android.internal.R.dimen.quick_qs_offset_height);
+            lp.height = mClockIconsView.getLayoutParams().height;
         } else {
             lp.height = WRAP_CONTENT;
         }
@@ -276,21 +204,45 @@
             mBatteryRemainingIcon.updateColors(mTextColorPrimary, textColorSecondary,
                     mTextColorPrimary);
         }
-
-        updateStatusIconAlphaAnimator();
-        updateHeaderTextContainerAlphaAnimator();
+        updateHeadersPadding();
+        updateAnimators();
     }
 
-    private void updateStatusIconAlphaAnimator() {
-        mStatusIconsAlphaAnimator = new TouchAnimator.Builder()
-                .addFloat(mQuickQsStatusIcons, "alpha", 1, 0, 0)
+    private void updateAnimators() {
+        updateAlphaAnimator();
+        int offset = mTopViewMeasureHeight;
+
+        mTranslationAnimator = new TouchAnimator.Builder()
+                .addFloat(mContainer, "translationY", 0, offset)
+                .setInterpolator(mQSExpansionPathInterpolator != null
+                        ? mQSExpansionPathInterpolator.getYInterpolator()
+                        : null)
                 .build();
     }
 
-    private void updateHeaderTextContainerAlphaAnimator() {
-        mHeaderTextContainerAlphaAnimator = new TouchAnimator.Builder()
-                .addFloat(mHeaderTextContainerView, "alpha", 0, 0, mExpandedHeaderAlpha)
-                .build();
+    private void updateAlphaAnimator() {
+        StatusBarMobileView icon =
+                ((StatusBarMobileView) mIconContainer.getViewForSlot(mMobileSlotName));
+        TouchAnimator.Builder builder = new TouchAnimator.Builder()
+                .addFloat(mQSCarriers, "alpha", 0, 1)
+                .addFloat(mDatePrivacyView, "alpha", 0, mDatePrivacyAlpha);
+        if (icon != null) {
+            builder.addFloat(icon, "alpha", 1, 0);
+            builder.setListener(new TouchAnimator.ListenerAdapter() {
+                @Override
+                public void onAnimationAtEnd() {
+                    icon.forceHidden(true);
+                    icon.setVisibleState(STATE_HIDDEN);
+                }
+
+                @Override
+                public void onAnimationStarted() {
+                    icon.forceHidden(false);
+                    icon.setVisibleState(STATE_ICON);
+                }
+            });
+        }
+        mAlphaAnimator = builder.build();
     }
 
     /** */
@@ -312,25 +264,19 @@
     public void setExpansion(boolean forceExpanded, float expansionFraction,
                              float panelTranslationY) {
         final float keyguardExpansionFraction = forceExpanded ? 1f : expansionFraction;
-        if (mStatusIconsAlphaAnimator != null) {
-            mStatusIconsAlphaAnimator.setPosition(keyguardExpansionFraction);
-        }
 
+        if (mAlphaAnimator != null) {
+            mAlphaAnimator.setPosition(keyguardExpansionFraction);
+        }
+        if (mTranslationAnimator != null) {
+            mTranslationAnimator.setPosition(keyguardExpansionFraction);
+        }
+        // If forceExpanded (we are opening QS from lockscreen), the animators have been set to
+        // position = 1f.
         if (forceExpanded) {
-            // If the keyguard is showing, we want to offset the text so that it comes in at the
-            // same time as the panel as it slides down.
-            mHeaderTextContainerView.setTranslationY(panelTranslationY);
+            setTranslationY(panelTranslationY);
         } else {
-            mHeaderTextContainerView.setTranslationY(0f);
-        }
-
-        if (mHeaderTextContainerAlphaAnimator != null) {
-            mHeaderTextContainerAlphaAnimator.setPosition(keyguardExpansionFraction);
-            if (keyguardExpansionFraction > 0) {
-                mHeaderTextContainerView.setVisibility(VISIBLE);
-            } else {
-                mHeaderTextContainerView.setVisibility(INVISIBLE);
-            }
+            setTranslationY(0);
         }
 
         mKeyguardExpansionFraction = keyguardExpansionFraction;
@@ -341,28 +287,21 @@
         if (disabled == mQsDisabled) return;
         mQsDisabled = disabled;
         mHeaderQsPanel.setDisabledByPolicy(disabled);
-        mHeaderTextContainerView.setVisibility(mQsDisabled ? View.GONE : View.VISIBLE);
-        mQuickQsStatusIcons.setVisibility(mQsDisabled ? View.GONE : View.VISIBLE);
+        mClockIconsView.setVisibility(mQsDisabled ? View.GONE : View.VISIBLE);
         updateResources();
     }
 
     @Override
     public WindowInsets onApplyWindowInsets(WindowInsets insets) {
-        // Handle padding of the clock
+        // Handle padding of the views
         DisplayCutout cutout = insets.getDisplayCutout();
         Pair<Integer, Integer> cornerCutoutPadding = StatusBarWindowView.cornerCutoutMargins(
                 cutout, getDisplay());
         Pair<Integer, Integer> padding =
                 StatusBarWindowView.paddingNeededForCutoutAndRoundedCorner(
                         cutout, cornerCutoutPadding, -1);
-        if (padding == null) {
-            mSystemIconsView.setPaddingRelative(
-                    getResources().getDimensionPixelSize(R.dimen.status_bar_padding_start), 0,
-                    getResources().getDimensionPixelSize(R.dimen.status_bar_padding_end), 0);
-        } else {
-            mSystemIconsView.setPadding(padding.first, 0, padding.second, 0);
-
-        }
+        mDatePrivacyView.setPadding(padding.first, 0, padding.second, 0);
+        mClockIconsView.setPadding(padding.first, 0, padding.second, 0);
         LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mSpace.getLayoutParams();
         boolean cornerCutout = cornerCutoutPadding != null
                 && (cornerCutoutPadding.first == 0 || cornerCutoutPadding.second == 0);
@@ -380,13 +319,13 @@
         mCutOutPaddingLeft = padding.first;
         mCutOutPaddingRight = padding.second;
         mWaterfallTopInset = cutout == null ? 0 : cutout.getWaterfallInsets().top;
-        updateClockPadding();
+        updateHeadersPadding();
         return super.onApplyWindowInsets(insets);
     }
 
-    private void updateClockPadding() {
-        int clockPaddingLeft = 0;
-        int clockPaddingRight = 0;
+    private void updateHeadersPadding() {
+        int paddingLeft = 0;
+        int paddingRight = 0;
 
         FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams();
         int leftMargin = lp.leftMargin;
@@ -399,18 +338,22 @@
             // if there's a cutout, let's use at least the rounded corner inset
             int cutoutPadding = Math.max(mCutOutPaddingLeft, mRoundedCornerPadding);
             int contentMarginLeft = isLayoutRtl() ? mContentMarginEnd : mContentMarginStart;
-            clockPaddingLeft = Math.max(cutoutPadding - contentMarginLeft - leftMargin, 0);
+            paddingLeft = Math.max(cutoutPadding - contentMarginLeft - leftMargin, 0);
         }
         if (mCutOutPaddingRight > 0) {
             // if there's a cutout, let's use at least the rounded corner inset
             int cutoutPadding = Math.max(mCutOutPaddingRight, mRoundedCornerPadding);
             int contentMarginRight = isLayoutRtl() ? mContentMarginStart : mContentMarginEnd;
-            clockPaddingRight = Math.max(cutoutPadding - contentMarginRight - rightMargin, 0);
+            paddingRight = Math.max(cutoutPadding - contentMarginRight - rightMargin, 0);
         }
 
-        mSystemIconsView.setPadding(clockPaddingLeft,
+        mDatePrivacyView.setPadding(paddingLeft,
                 mWaterfallTopInset + mStatusBarPaddingTop,
-                clockPaddingRight,
+                paddingRight,
+                0);
+        mClockIconsView.setPadding(paddingLeft,
+                mWaterfallTopInset + mStatusBarPaddingTop,
+                paddingRight,
                 0);
     }
 
@@ -422,26 +365,6 @@
         mHeaderQsPanel.setCallback(qsPanelCallback);
     }
 
-    private String formatNextAlarm(AlarmClockInfo info, boolean use24HourFormat) {
-        if (info == null) {
-            return "";
-        }
-        String skeleton = use24HourFormat ? "EHm" : "Ehma";
-        String pattern = android.text.format.DateFormat
-                .getBestDateTimePattern(Locale.getDefault(), skeleton);
-        return android.text.format.DateFormat.format(pattern, info.getTriggerTime()).toString();
-    }
-
-    public static float getColorIntensity(@ColorInt int color) {
-        return color == Color.WHITE ? 0 : 1;
-    }
-
-    @NonNull
-    @Override
-    public Lifecycle getLifecycle() {
-        return mLifecycle;
-    }
-
     /** */
     public void setContentMargins(int marginStart, int marginEnd,
             QuickQSPanelController quickQSPanelController) {
@@ -459,24 +382,39 @@
                 view.setLayoutParams(lp);
             }
         }
-        updateClockPadding();
+        updateHeadersPadding();
     }
 
+    /**
+     * When QS is scrolling, mClockIconsAlpha should scroll away and fade out.
+     *
+     * For a given scroll level, this method does the following:
+     * <ol>
+     *     <li>Determine the alpha that {@code mClockIconsView} should have when the panel is fully
+     *         expanded.</li>
+     *     <li>Set the scroll of {@code mClockIconsView} to the same of {@code QSPanel}.</li>
+     *     <li>Set the alpha of {@code mClockIconsView} to that determined by the expansion of
+     *         the panel, interpolated between 1 (no expansion) and {@code mClockIconsAlpha} (fully
+     *         expanded), matching the animator.</li>
+     * </ol>
+     *
+     * @param scrollY the scroll of the QSPanel container
+     */
     public void setExpandedScrollAmount(int scrollY) {
         // The scrolling of the expanded qs has changed. Since the header text isn't part of it,
         // but would overlap content, we're fading it out.
         float newAlpha = 1.0f;
-        if (mHeaderTextContainerView.getHeight() > 0) {
-            newAlpha = MathUtils.map(0, mHeaderTextContainerView.getHeight() / 2.0f, 1.0f, 0.0f,
+        if (mClockIconsView.getHeight() > 0) {
+            newAlpha = MathUtils.map(0, mClockIconsView.getHeight() / 2.0f, 1.0f, 0.0f,
                     scrollY);
             newAlpha = Interpolators.ALPHA_OUT.getInterpolation(newAlpha);
         }
-        mHeaderTextContainerView.setScrollY(scrollY);
-        if (newAlpha != mExpandedHeaderAlpha) {
-            mExpandedHeaderAlpha = newAlpha;
-            mHeaderTextContainerView.setAlpha(MathUtils.lerp(0.0f, mExpandedHeaderAlpha,
+        mClockIconsView.setScrollY(scrollY);
+        if (newAlpha != mClockIconsAlpha) {
+            mClockIconsAlpha = newAlpha;
+            mClockIconsView.setAlpha(MathUtils.lerp(1.0f, mClockIconsAlpha,
                     mKeyguardExpansionFraction));
-            updateHeaderTextContainerAlphaAnimator();
+            updateAlphaAnimator();
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java
index eedcdab..3aafea98 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java
@@ -16,21 +16,13 @@
 
 package com.android.systemui.qs;
 
-import android.app.AlarmManager.AlarmClockInfo;
 import android.content.Intent;
-import android.media.AudioManager;
 import android.os.Bundle;
 import android.provider.AlarmClock;
-import android.provider.Settings;
-import android.service.notification.ZenModeConfig;
-import android.util.Log;
 import android.view.View;
 import android.view.View.OnClickListener;
 
 import androidx.annotation.NonNull;
-import androidx.lifecycle.Lifecycle;
-import androidx.lifecycle.LifecycleOwner;
-import androidx.lifecycle.LifecycleRegistry;
 
 import com.android.internal.colorextraction.ColorExtractor;
 import com.android.internal.logging.UiEventLogger;
@@ -47,16 +39,9 @@
 import com.android.systemui.privacy.logging.PrivacyLogger;
 import com.android.systemui.qs.carrier.QSCarrierGroupController;
 import com.android.systemui.qs.dagger.QSScope;
-import com.android.systemui.settings.UserTracker;
-import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
 import com.android.systemui.statusbar.phone.StatusIconContainer;
 import com.android.systemui.statusbar.policy.Clock;
-import com.android.systemui.statusbar.policy.NextAlarmController;
-import com.android.systemui.statusbar.policy.NextAlarmController.NextAlarmChangeCallback;
-import com.android.systemui.statusbar.policy.ZenModeController;
-import com.android.systemui.statusbar.policy.ZenModeController.Callback;
-import com.android.systemui.util.RingerModeTracker;
 import com.android.systemui.util.ViewController;
 
 import java.util.ArrayList;
@@ -71,76 +56,29 @@
 class QuickStatusBarHeaderController extends ViewController<QuickStatusBarHeader> {
     private static final String TAG = "QuickStatusBarHeader";
 
-    private final ZenModeController mZenModeController;
-    private final NextAlarmController mNextAlarmController;
     private final PrivacyItemController mPrivacyItemController;
-    private final RingerModeTracker mRingerModeTracker;
     private final ActivityStarter mActivityStarter;
     private final UiEventLogger mUiEventLogger;
     private final QSCarrierGroupController mQSCarrierGroupController;
     private final QuickQSPanelController mHeaderQsPanelController;
-    private final LifecycleRegistry mLifecycle;
     private final OngoingPrivacyChip mPrivacyChip;
     private final Clock mClockView;
-    private final View mNextAlarmContainer;
-    private final View mRingerContainer;
-    private final QSTileHost mQSTileHost;
     private final StatusBarIconController mStatusBarIconController;
-    private final CommandQueue mCommandQueue;
     private final DemoModeController mDemoModeController;
-    private final UserTracker mUserTracker;
     private final StatusIconContainer mIconContainer;
     private final StatusBarIconController.TintedIconManager mIconManager;
     private final DemoMode mDemoModeReceiver;
     private final PrivacyLogger mPrivacyLogger;
     private final PrivacyDialogController mPrivacyDialogController;
+    private final QSExpansionPathInterpolator mQSExpansionPathInterpolator;
 
     private boolean mListening;
-    private AlarmClockInfo mNextAlarm;
     private boolean mMicCameraIndicatorsEnabled;
     private boolean mLocationIndicatorsEnabled;
     private boolean mPrivacyChipLogged;
 
     private SysuiColorExtractor mColorExtractor;
     private ColorExtractor.OnColorsChangedListener mOnColorsChangedListener;
-    private int mRingerMode = AudioManager.RINGER_MODE_NORMAL;
-
-    private final ZenModeController.Callback mZenModeControllerCallback = new Callback() {
-        @Override
-        public void onZenChanged(int zen) {
-            mView.updateStatusText(mRingerMode, mNextAlarm, isZenOverridingRinger(),
-                    use24HourFormat());
-        }
-
-        @Override
-        public void onConfigChanged(ZenModeConfig config) {
-            mView.updateStatusText(mRingerMode, mNextAlarm, isZenOverridingRinger(),
-                    use24HourFormat());
-        }
-    };
-
-    private boolean use24HourFormat() {
-        return android.text.format.DateFormat.is24HourFormat(
-                mView.getContext(), mUserTracker.getUserId());
-
-    }
-
-    private final NextAlarmChangeCallback mNextAlarmChangeCallback = new NextAlarmChangeCallback() {
-        @Override
-        public void onNextAlarmChanged(AlarmClockInfo nextAlarm) {
-            mNextAlarm = nextAlarm;
-            mView.updateStatusText(mRingerMode, mNextAlarm, isZenOverridingRinger(),
-                    use24HourFormat());
-        }
-    };
-
-    private final LifecycleOwner mLifecycleOwner = new LifecycleOwner() {
-        @NonNull
-        @Override
-        public Lifecycle getLifecycle() {
-            return mLifecycle;
-        }
-    };
 
     private PrivacyItemController.Callback mPICCallback = new PrivacyItemController.Callback() {
         @Override
@@ -178,67 +116,46 @@
             if (v == mClockView) {
                 mActivityStarter.postStartActivityDismissingKeyguard(new Intent(
                         AlarmClock.ACTION_SHOW_ALARMS), 0);
-            } else if (v == mNextAlarmContainer && mNextAlarmContainer.isVisibleToUser()) {
-                if (mNextAlarm.getShowIntent() != null) {
-                    mActivityStarter.postStartActivityDismissingKeyguard(
-                            mNextAlarm.getShowIntent());
-                } else {
-                    Log.d(TAG, "No PendingIntent for next alarm. Using default intent");
-                    mActivityStarter.postStartActivityDismissingKeyguard(new Intent(
-                            AlarmClock.ACTION_SHOW_ALARMS), 0);
-                }
             } else if (v == mPrivacyChip) {
                 // If the privacy chip is visible, it means there were some indicators
                 mUiEventLogger.log(PrivacyChipEvent.ONGOING_INDICATORS_CHIP_CLICK);
                 mPrivacyDialogController.showDialog(getContext());
-            } else if (v == mRingerContainer && mRingerContainer.isVisibleToUser()) {
-                mActivityStarter.postStartActivityDismissingKeyguard(new Intent(
-                        Settings.ACTION_SOUND_SETTINGS), 0);
             }
         }
     };
 
     @Inject
     QuickStatusBarHeaderController(QuickStatusBarHeader view,
-            ZenModeController zenModeController, NextAlarmController nextAlarmController,
-            PrivacyItemController privacyItemController, RingerModeTracker ringerModeTracker,
+            PrivacyItemController privacyItemController,
             ActivityStarter activityStarter, UiEventLogger uiEventLogger,
-            QSTileHost qsTileHost, StatusBarIconController statusBarIconController,
-            CommandQueue commandQueue, DemoModeController demoModeController,
-            UserTracker userTracker, QuickQSPanelController quickQSPanelController,
+            StatusBarIconController statusBarIconController,
+            DemoModeController demoModeController,
+            QuickQSPanelController quickQSPanelController,
             QSCarrierGroupController.Builder qsCarrierGroupControllerBuilder,
             PrivacyLogger privacyLogger,
             SysuiColorExtractor colorExtractor,
-            PrivacyDialogController privacyDialogController) {
+            PrivacyDialogController privacyDialogController,
+            QSExpansionPathInterpolator qsExpansionPathInterpolator) {
         super(view);
-        mZenModeController = zenModeController;
-        mNextAlarmController = nextAlarmController;
         mPrivacyItemController = privacyItemController;
-        mRingerModeTracker = ringerModeTracker;
         mActivityStarter = activityStarter;
         mUiEventLogger = uiEventLogger;
-        mQSTileHost = qsTileHost;
         mStatusBarIconController = statusBarIconController;
-        mCommandQueue = commandQueue;
         mDemoModeController = demoModeController;
-        mUserTracker = userTracker;
-        mLifecycle = new LifecycleRegistry(mLifecycleOwner);
         mHeaderQsPanelController = quickQSPanelController;
         mPrivacyLogger = privacyLogger;
         mPrivacyDialogController = privacyDialogController;
+        mQSExpansionPathInterpolator = qsExpansionPathInterpolator;
 
         mQSCarrierGroupController = qsCarrierGroupControllerBuilder
                 .setQSCarrierGroup(mView.findViewById(R.id.carrier_group))
                 .build();
 
-
         mPrivacyChip = mView.findViewById(R.id.privacy_chip);
-        mNextAlarmContainer = mView.findViewById(R.id.alarm_container);
         mClockView = mView.findViewById(R.id.clock);
-        mRingerContainer = mView.findViewById(R.id.ringer_container);
         mIconContainer = mView.findViewById(R.id.statusIcons);
 
-        mIconManager = new StatusBarIconController.TintedIconManager(mIconContainer, mCommandQueue);
+        mIconManager = new StatusBarIconController.TintedIconManager(mIconContainer);
         mDemoModeReceiver = new ClockDemoModeReceiver(mClockView);
         mColorExtractor = colorExtractor;
         mOnColorsChangedListener = (extractor, which) -> {
@@ -250,15 +167,7 @@
 
     @Override
     protected void onViewAttached() {
-        mRingerModeTracker.getRingerModeInternal().observe(mLifecycleOwner, ringer -> {
-            mRingerMode = ringer;
-            mView.updateStatusText(mRingerMode, mNextAlarm, isZenOverridingRinger(),
-                    use24HourFormat());
-        });
-
         mClockView.setOnClickListener(mOnClickListener);
-        mNextAlarmContainer.setOnClickListener(mOnClickListener);
-        mRingerContainer.setOnClickListener(mOnClickListener);
         mPrivacyChip.setOnClickListener(mOnClickListener);
 
         mMicCameraIndicatorsEnabled = mPrivacyItemController.getMicCameraAvailable();
@@ -271,18 +180,15 @@
 
         setChipVisibility(mPrivacyChip.getVisibility() == View.VISIBLE);
 
-        mView.onAttach(mIconManager);
+        mView.onAttach(mIconManager, mQSExpansionPathInterpolator);
 
         mDemoModeController.addCallback(mDemoModeReceiver);
     }
 
     @Override
     protected void onViewDetached() {
-        mRingerModeTracker.getRingerModeInternal().removeObservers(mLifecycleOwner);
         mClockView.setOnClickListener(null);
         mColorExtractor.removeOnColorsChangedListener(mOnColorsChangedListener);
-        mNextAlarmContainer.setOnClickListener(null);
-        mRingerContainer.setOnClickListener(null);
         mPrivacyChip.setOnClickListener(null);
         mStatusBarIconController.removeIconGroup(mIconManager);
         mDemoModeController.removeCallback(mDemoModeReceiver);
@@ -307,17 +213,11 @@
         }
 
         if (listening) {
-            mZenModeController.addCallback(mZenModeControllerCallback);
-            mNextAlarmController.addCallback(mNextAlarmChangeCallback);
-            mLifecycle.setCurrentState(Lifecycle.State.RESUMED);
             // Get the most up to date info
             mMicCameraIndicatorsEnabled = mPrivacyItemController.getMicCameraAvailable();
             mLocationIndicatorsEnabled = mPrivacyItemController.getLocationAvailable();
             mPrivacyItemController.addCallback(mPICCallback);
         } else {
-            mZenModeController.removeCallback(mZenModeControllerCallback);
-            mNextAlarmController.removeCallback(mNextAlarmChangeCallback);
-            mLifecycle.setCurrentState(Lifecycle.State.CREATED);
             mPrivacyItemController.removeCallback(mPICCallback);
             mPrivacyChipLogged = false;
         }
@@ -360,11 +260,6 @@
         return mMicCameraIndicatorsEnabled || mLocationIndicatorsEnabled;
     }
 
-    private boolean isZenOverridingRinger() {
-        return ZenModeConfig.isZenOverridingRinger(mZenModeController.getZen(),
-                mZenModeController.getConsolidatedPolicy());
-    }
-
     public void setContentMargins(int contentPaddingStart, int contentPaddingEnd) {
         mView.setContentMargins(contentPaddingStart, contentPaddingEnd, mHeaderQsPanelController);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/SecureSetting.java b/packages/SystemUI/src/com/android/systemui/qs/SecureSetting.java
index 994da9a..8aa2d09 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/SecureSetting.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/SecureSetting.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.qs;
 
+import android.app.ActivityManager;
 import android.database.ContentObserver;
 import android.os.Handler;
 
@@ -24,27 +25,36 @@
 
 /** Helper for managing a secure setting. **/
 public abstract class SecureSetting extends ContentObserver implements Listenable {
-    private static final int DEFAULT = 0;
-
-    private SecureSettings mSecureSettings;
+    private final SecureSettings mSecureSettings;
     private final String mSettingName;
+    private final int mDefaultValue;
 
     private boolean mListening;
     private int mUserId;
-    private int mObservedValue = DEFAULT;
+    private int mObservedValue;
 
     protected abstract void handleValueChanged(int value, boolean observedChange);
 
     public SecureSetting(SecureSettings secureSettings, Handler handler, String settingName,
             int userId) {
+        this(secureSettings, handler, settingName, userId, 0);
+    }
+
+    public SecureSetting(SecureSettings secureSetting, Handler handler, String settingName) {
+        this(secureSetting, handler, settingName, ActivityManager.getCurrentUser());
+    }
+
+    public SecureSetting(SecureSettings secureSettings, Handler handler, String settingName,
+            int userId, int defaultValue) {
         super(handler);
         mSecureSettings = secureSettings;
         mSettingName = settingName;
+        mObservedValue = mDefaultValue = defaultValue;
         mUserId = userId;
     }
 
     public int getValue() {
-        return mSecureSettings.getIntForUser(mSettingName, DEFAULT, mUserId);
+        return mSecureSettings.getIntForUser(mSettingName, mDefaultValue, mUserId);
     }
 
     public void setValue(int value) {
@@ -61,7 +71,7 @@
                     mSecureSettings.getUriFor(mSettingName), false, this, mUserId);
         } else {
             mSecureSettings.unregisterContentObserver(this);
-            mObservedValue = DEFAULT;
+            mObservedValue = mDefaultValue;
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/SideLabelTileLayout.kt b/packages/SystemUI/src/com/android/systemui/qs/SideLabelTileLayout.kt
index 0ebadfd..d1deeca 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/SideLabelTileLayout.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/SideLabelTileLayout.kt
@@ -18,6 +18,7 @@
 
 import android.content.Context
 import android.util.AttributeSet
+import com.android.systemui.R
 
 open class SideLabelTileLayout(
     context: Context,
@@ -26,7 +27,7 @@
 
     override fun updateResources(): Boolean {
         return super.updateResources().also {
-            mMaxAllowedRows = 4
+            mMaxAllowedRows = context.resources.getInteger(R.integer.quick_settings_max_rows)
         }
     }
 
@@ -44,4 +45,19 @@
         val row = index / mColumns
         return getRowTop(row)
     }
+
+    override fun updateMaxRows(allowedHeight: Int, tilesCount: Int): Boolean {
+        val previousRows = mRows
+        mRows = mMaxAllowedRows
+        // We want at most mMaxAllowedRows, but it could be that we don't have enough tiles to fit
+        // that many rows. In that case, we want
+        // `tilesCount = (mRows - 1) * mColumns + X`
+        // where X is some remainder between 1 and `mColumns - 1`
+        // Adding `mColumns - 1` will guarantee that the final value F will satisfy
+        // `mRows * mColumns <= F < (mRows + 1) * mColumns
+        if (mRows > (tilesCount + mColumns - 1) / mColumns) {
+            mRows = (tilesCount + mColumns - 1) / mColumns
+        }
+        return previousRows != mRows
+    }
 }
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrierGroupController.java b/packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrierGroupController.java
index 0dc0b30..5afe1c8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrierGroupController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrierGroupController.java
@@ -34,7 +34,7 @@
 
 import androidx.annotation.VisibleForTesting;
 
-import com.android.keyguard.CarrierTextController;
+import com.android.keyguard.CarrierTextManager;
 import com.android.settingslib.AccessibilityContentDescriptions;
 import com.android.settingslib.mobile.TelephonyIcons;
 import com.android.systemui.R;
@@ -59,7 +59,7 @@
     private final ActivityStarter mActivityStarter;
     private final Handler mBgHandler;
     private final NetworkController mNetworkController;
-    private final CarrierTextController mCarrierTextController;
+    private final CarrierTextManager mCarrierTextManager;
     private final TextView mNoSimTextView;
     private final H mMainHandler;
     private final Callback mCallback;
@@ -149,7 +149,7 @@
                 }
             };
 
-    private static class Callback implements CarrierTextController.CarrierTextCallback {
+    private static class Callback implements CarrierTextManager.CarrierTextCallback {
         private H mHandler;
 
         Callback(H handler) {
@@ -157,7 +157,7 @@
         }
 
         @Override
-        public void updateCarrierInfo(CarrierTextController.CarrierTextCallbackInfo info) {
+        public void updateCarrierInfo(CarrierTextManager.CarrierTextCallbackInfo info) {
             mHandler.obtainMessage(H.MSG_UPDATE_CARRIER_INFO, info).sendToTarget();
         }
     }
@@ -165,7 +165,7 @@
     private QSCarrierGroupController(QSCarrierGroup view, ActivityStarter activityStarter,
             @Background Handler bgHandler, @Main Looper mainLooper,
             NetworkController networkController,
-            CarrierTextController.Builder carrierTextControllerBuilder, Context context) {
+            CarrierTextManager.Builder carrierTextManagerBuilder, Context context) {
         if (FeatureFlagUtils.isEnabled(context, FeatureFlagUtils.SETTINGS_PROVIDER_MODEL)) {
             mProviderModel = true;
         } else {
@@ -174,7 +174,7 @@
         mActivityStarter = activityStarter;
         mBgHandler = bgHandler;
         mNetworkController = networkController;
-        mCarrierTextController = carrierTextControllerBuilder
+        mCarrierTextManager = carrierTextManagerBuilder
                 .setShowAirplaneMode(false)
                 .setShowMissingSim(false)
                 .build();
@@ -192,7 +192,6 @@
         mMainHandler = new H(mainLooper, this::handleUpdateCarrierInfo, this::handleUpdateState);
         mCallback = new Callback(mMainHandler);
 
-
         mCarrierGroups[0] = view.getCarrier1View();
         mCarrierGroups[1] = view.getCarrier2View();
         mCarrierGroups[2] = view.getCarrier3View();
@@ -243,10 +242,10 @@
             if (mNetworkController.hasVoiceCallingFeature()) {
                 mNetworkController.addCallback(mSignalCallback);
             }
-            mCarrierTextController.setListening(mCallback);
+            mCarrierTextManager.setListening(mCallback);
         } else {
             mNetworkController.removeCallback(mSignalCallback);
-            mCarrierTextController.setListening(null);
+            mCarrierTextManager.setListening(null);
         }
     }
 
@@ -273,7 +272,7 @@
     }
 
     @MainThread
-    private void handleUpdateCarrierInfo(CarrierTextController.CarrierTextCallbackInfo info) {
+    private void handleUpdateCarrierInfo(CarrierTextManager.CarrierTextCallbackInfo info) {
         if (!mMainHandler.getLooper().isCurrentThread()) {
             mMainHandler.obtainMessage(H.MSG_UPDATE_CARRIER_INFO, info).sendToTarget();
             return;
@@ -327,13 +326,13 @@
     }
 
     private static class H extends Handler {
-        private Consumer<CarrierTextController.CarrierTextCallbackInfo> mUpdateCarrierInfo;
+        private Consumer<CarrierTextManager.CarrierTextCallbackInfo> mUpdateCarrierInfo;
         private Runnable mUpdateState;
         static final int MSG_UPDATE_CARRIER_INFO = 0;
         static final int MSG_UPDATE_STATE = 1;
 
         H(Looper looper,
-                Consumer<CarrierTextController.CarrierTextCallbackInfo> updateCarrierInfo,
+                Consumer<CarrierTextManager.CarrierTextCallbackInfo> updateCarrierInfo,
                 Runnable updateState) {
             super(looper);
             mUpdateCarrierInfo = updateCarrierInfo;
@@ -345,7 +344,7 @@
             switch (msg.what) {
                 case MSG_UPDATE_CARRIER_INFO:
                     mUpdateCarrierInfo.accept(
-                            (CarrierTextController.CarrierTextCallbackInfo) msg.obj);
+                            (CarrierTextManager.CarrierTextCallbackInfo) msg.obj);
                     break;
                 case MSG_UPDATE_STATE:
                     mUpdateState.run();
@@ -362,13 +361,13 @@
         private final Handler mHandler;
         private final Looper mLooper;
         private final NetworkController mNetworkController;
-        private final CarrierTextController.Builder mCarrierTextControllerBuilder;
+        private final CarrierTextManager.Builder mCarrierTextControllerBuilder;
         private final Context mContext;
 
         @Inject
         public Builder(ActivityStarter activityStarter, @Background Handler handler,
                 @Main Looper looper, NetworkController networkController,
-                CarrierTextController.Builder carrierTextControllerBuilder, Context context) {
+                CarrierTextManager.Builder carrierTextControllerBuilder, Context context) {
             mActivityStarter = activityStarter;
             mHandler = handler;
             mLooper = looper;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
index 32b41ec..d72f8e9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
@@ -115,34 +115,13 @@
 
         final ArrayList<QSTile> tilesToAdd = new ArrayList<>();
         // TODO(b/174753536): Move it into the config file.
-        // Only do the below hacking when at least one of the below tiles exist
-        //   --InternetTile
-        //   --WiFiTile
-        //   --CellularTIle
-        if (possibleTiles.contains("internet") || possibleTiles.contains("wifi")
-                || possibleTiles.contains("cell")) {
-            if (FeatureFlagUtils.isEnabled(mContext, FeatureFlagUtils.SETTINGS_PROVIDER_MODEL)) {
-                if (!possibleTiles.contains("internet")) {
-                    possibleTiles.add("internet");
-                }
-                if (possibleTiles.contains("wifi")) {
-                    possibleTiles.remove("wifi");
-                }
-                if (possibleTiles.contains("cell")) {
-                    possibleTiles.remove("cell");
-                }
-            } else {
-                if (possibleTiles.contains("internet")) {
-                    possibleTiles.remove("internet");
-                }
-                if (!possibleTiles.contains("wifi")) {
-                    possibleTiles.add("wifi");
-                }
-                if (!possibleTiles.contains("cell")) {
-                    possibleTiles.add("cell");
-                }
-            }
+        if (FeatureFlagUtils.isEnabled(mContext, FeatureFlagUtils.SETTINGS_PROVIDER_MODEL)) {
+            possibleTiles.remove("cell");
+            possibleTiles.remove("wifi");
+        } else {
+            possibleTiles.remove("internet");
         }
+
         for (String spec : possibleTiles) {
             // Only add current and stock tiles that can be created from QSFactoryImpl.
             // Do not include CustomTile. Those will be created by `addPackageTiles`.
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 f9d1def..a17aeba 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
@@ -56,7 +56,6 @@
 import com.android.settingslib.RestrictedLockUtilsInternal;
 import com.android.settingslib.Utils;
 import com.android.systemui.Dumpable;
-import com.android.systemui.Prefs;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.qs.DetailAdapter;
@@ -67,7 +66,6 @@
 import com.android.systemui.qs.PagedTileLayout.TilePage;
 import com.android.systemui.qs.QSEvent;
 import com.android.systemui.qs.QSHost;
-import com.android.systemui.qs.QuickStatusBarHeader;
 import com.android.systemui.qs.logging.QSLogger;
 
 import java.io.FileDescriptor;
@@ -300,11 +298,6 @@
                 getInstanceId());
         mQSLogger.logTileLongClick(mTileSpec, mStatusBarStateController.getState(), mState.state);
         mHandler.sendEmptyMessage(H.LONG_CLICK);
-
-        Prefs.putInt(
-                mContext,
-                Prefs.Key.QS_LONG_PRESS_TOOLTIP_SHOWN_COUNT,
-                QuickStatusBarHeader.MAX_TOOLTIP_SHOWN_COUNT);
     }
 
     public LogMaker populate(LogMaker logMaker) {
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
index bd46ffe..4300d37 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
@@ -300,7 +300,7 @@
                 .setColorized(true)
                 .setColor(getResources().getColor(R.color.GM2_red_700))
                 .setOngoing(true)
-                .setShowForegroundImmediately(true)
+                .setForegroundServiceBehavior(Notification.FOREGROUND_SERVICE_IMMEDIATE)
                 .setContentIntent(
                         PendingIntent.getService(this, REQUEST_CODE, stopIntent,
                                 PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE))
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/CropView.java b/packages/SystemUI/src/com/android/systemui/screenshot/CropView.java
index 1ec175c..78ee896 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/CropView.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/CropView.java
@@ -16,8 +16,6 @@
 
 package com.android.systemui.screenshot;
 
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
 import android.animation.ValueAnimator;
 import android.content.Context;
 import android.content.res.TypedArray;
@@ -25,6 +23,7 @@
 import android.graphics.Color;
 import android.graphics.Paint;
 import android.graphics.Rect;
+import android.graphics.RectF;
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -32,6 +31,7 @@
 import android.util.IntArray;
 import android.util.Log;
 import android.util.MathUtils;
+import android.util.Range;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.accessibility.AccessibilityEvent;
@@ -49,29 +49,30 @@
  */
 public class CropView extends View {
     private static final String TAG = "CropView";
+
     public enum CropBoundary {
-        NONE, TOP, BOTTOM
+        NONE, TOP, BOTTOM, LEFT, RIGHT
     }
 
     private final float mCropTouchMargin;
     private final Paint mShadePaint;
     private final Paint mHandlePaint;
 
-    // Top and bottom crops are stored as floats [0, 1], representing the top and bottom of the
-    // view, respectively.
-    private float mTopCrop = 0f;
-    private float mBottomCrop = 1f;
-
-    // When the user is dragging a handle, these variables store the distance between the top/bottom
-    // crop values and
-    private float mTopDelta = 0f;
-    private float mBottomDelta = 0f;
+    // Crop rect with each element represented as [0,1] along its proper axis.
+    private RectF mCrop = new RectF(0, 0, 1, 1);
 
     private int mExtraTopPadding;
     private int mExtraBottomPadding;
+    private int mImageWidth;
 
     private CropBoundary mCurrentDraggingBoundary = CropBoundary.NONE;
+    // The starting value of mCurrentDraggingBoundary's crop, used to compute touch deltas.
+    private float mMovementStartValue;
     private float mStartingY;  // y coordinate of ACTION_DOWN
+    private float mStartingX;
+    // The allowable values for the current boundary being dragged
+    private Range<Float> mMotionRange;
+
     private CropInteractionListener mCropInteractionListener;
 
     public CropView(Context context, @Nullable AttributeSet attrs) {
@@ -86,6 +87,7 @@
         mShadePaint.setColor(t.getColor(R.styleable.CropView_scrimColor, Color.TRANSPARENT));
         mHandlePaint = new Paint();
         mHandlePaint.setColor(t.getColor(R.styleable.CropView_handleColor, Color.BLACK));
+        mHandlePaint.setStrokeCap(Paint.Cap.ROUND);
         mHandlePaint.setStrokeWidth(
                 t.getDimensionPixelSize(R.styleable.CropView_handleThickness, 20));
         t.recycle();
@@ -100,8 +102,7 @@
         Parcelable superState = super.onSaveInstanceState();
 
         SavedState ss = new SavedState(superState);
-        ss.mTopBoundary = getTopBoundary();
-        ss.mBottomBoundary = getBottomBoundary();
+        ss.mCrop = mCrop;
         return ss;
     }
 
@@ -110,45 +111,67 @@
         SavedState ss = (SavedState) state;
         super.onRestoreInstanceState(ss.getSuperState());
 
-        setBoundaryTo(CropBoundary.TOP, ss.mTopBoundary);
-        setBoundaryTo(CropBoundary.BOTTOM, ss.mBottomBoundary);
+        mCrop = ss.mCrop;
     }
 
     @Override
     public void onDraw(Canvas canvas) {
         super.onDraw(canvas);
-        float top = mTopCrop + mTopDelta;
-        float bottom = mBottomCrop + mBottomDelta;
-        drawShade(canvas, 0, top);
-        drawShade(canvas, bottom, 1f);
-        drawHandle(canvas, top, /* draw the handle tab down */ false);
-        drawHandle(canvas, bottom, /* draw the handle tab up */ true);
+        drawShade(canvas, 0, 0, 1, mCrop.top);
+        drawShade(canvas, 0, mCrop.bottom, 1, 1);
+        drawShade(canvas, 0, mCrop.top, mCrop.left, mCrop.bottom);
+        drawShade(canvas, mCrop.right, mCrop.top, 1, mCrop.bottom);
+        drawHorizontalHandle(canvas, mCrop.top, /* draw the handle tab up */ true);
+        drawHorizontalHandle(canvas, mCrop.bottom, /* draw the handle tab down */ false);
+        drawVerticalHandle(canvas, mCrop.left, /* left */ true);
+        drawVerticalHandle(canvas, mCrop.right, /* right */ false);
     }
 
     @Override
     public boolean onTouchEvent(MotionEvent event) {
-        int topPx = fractionToPixels(mTopCrop);
-        int bottomPx = fractionToPixels(mBottomCrop);
+        int topPx = fractionToVerticalPixels(mCrop.top);
+        int bottomPx = fractionToVerticalPixels(mCrop.bottom);
         switch (event.getAction()) {
             case MotionEvent.ACTION_DOWN:
-                mCurrentDraggingBoundary = nearestBoundary(event, topPx, bottomPx);
+                mCurrentDraggingBoundary = nearestBoundary(event, topPx, bottomPx,
+                        fractionToHorizontalPixels(mCrop.left),
+                        fractionToHorizontalPixels(mCrop.right));
                 if (mCurrentDraggingBoundary != CropBoundary.NONE) {
                     mStartingY = event.getY();
+                    mStartingX = event.getX();
+                    mMovementStartValue = getBoundaryPosition(mCurrentDraggingBoundary);
                     updateListener(event);
+                    switch (mCurrentDraggingBoundary) {
+                        case TOP:
+                            mMotionRange = new Range<>(0f,
+                                    mCrop.bottom - pixelDistanceToFraction(mCropTouchMargin,
+                                            CropBoundary.BOTTOM));
+                            break;
+                        case BOTTOM:
+                            mMotionRange = new Range<>(
+                                    mCrop.top + pixelDistanceToFraction(mCropTouchMargin,
+                                            CropBoundary.TOP), 1f);
+                            break;
+                        case LEFT:
+                            mMotionRange = new Range<>(0f,
+                                    mCrop.right - pixelDistanceToFraction(mCropTouchMargin,
+                                            CropBoundary.RIGHT));
+                            break;
+                        case RIGHT:
+                            mMotionRange = new Range<>(
+                                    mCrop.left + pixelDistanceToFraction(mCropTouchMargin,
+                                            CropBoundary.LEFT), 1f);
+                            break;
+                    }
                 }
                 return true;
             case MotionEvent.ACTION_MOVE:
                 if (mCurrentDraggingBoundary != CropBoundary.NONE) {
-                    float delta = event.getY() - mStartingY;
-                    if (mCurrentDraggingBoundary == CropBoundary.TOP) {
-                        mTopDelta = pixelDistanceToFraction((int) MathUtils.constrain(delta,
-                                -topPx + mExtraTopPadding,
-                                bottomPx - 2 * mCropTouchMargin - topPx));
-                    } else {  // Bottom
-                        mBottomDelta = pixelDistanceToFraction((int) MathUtils.constrain(delta,
-                                topPx + 2 * mCropTouchMargin - bottomPx,
-                                getHeight() - bottomPx - mExtraBottomPadding));
-                    }
+                    float deltaPx = isVertical(mCurrentDraggingBoundary) ? event.getY() - mStartingY
+                            : event.getX() - mStartingX;
+                    float delta = pixelDistanceToFraction((int) deltaPx, mCurrentDraggingBoundary);
+                    setBoundaryPosition(mCurrentDraggingBoundary,
+                            mMotionRange.clamp(mMovementStartValue + delta));
                     updateListener(event);
                     invalidate();
                     return true;
@@ -156,8 +179,6 @@
             case MotionEvent.ACTION_CANCEL:
             case MotionEvent.ACTION_UP:
                 if (mCurrentDraggingBoundary != CropBoundary.NONE) {
-                    // Commit the delta to the stored crop values.
-                    commitDeltas(mCurrentDraggingBoundary);
                     updateListener(event);
                 }
         }
@@ -167,22 +188,46 @@
     /**
      * Set the given boundary to the given value without animation.
      */
-    public void setBoundaryTo(CropBoundary boundary, float value) {
+    public void setBoundaryPosition(CropBoundary boundary, float position) {
         switch (boundary) {
             case TOP:
-                mTopCrop = value;
+                mCrop.top = position;
                 break;
             case BOTTOM:
-                mBottomCrop = value;
+                mCrop.bottom = position;
+                break;
+            case LEFT:
+                mCrop.left = position;
+                break;
+            case RIGHT:
+                mCrop.right = position;
                 break;
             case NONE:
-                Log.w(TAG, "No boundary selected for animation");
+                Log.w(TAG, "No boundary selected");
                 break;
         }
 
         invalidate();
     }
 
+    private float getBoundaryPosition(CropBoundary boundary) {
+        switch (boundary) {
+            case TOP:
+                return mCrop.top;
+            case BOTTOM:
+                return mCrop.bottom;
+            case LEFT:
+                return mCrop.left;
+            case RIGHT:
+                return mCrop.right;
+        }
+        return 0;
+    }
+
+    private static boolean isVertical(CropBoundary boundary) {
+        return boundary == CropBoundary.TOP || boundary == CropBoundary.BOTTOM;
+    }
+
     /**
      * Animate the given boundary to the given value.
      */
@@ -191,28 +236,13 @@
             Log.w(TAG, "No boundary selected for animation");
             return;
         }
-        float totalDelta = (boundary == CropBoundary.TOP) ? (value - mTopCrop)
-                : (value - mBottomCrop);
+        float start = getBoundaryPosition(boundary);
         ValueAnimator animator = new ValueAnimator();
         animator.addUpdateListener(animation -> {
-            if (boundary == CropBoundary.TOP) {
-                mTopDelta = animation.getAnimatedFraction() * totalDelta;
-            } else {
-                mBottomDelta = animation.getAnimatedFraction() * totalDelta;
-            }
+            setBoundaryPosition(boundary,
+                    MathUtils.lerp(start, value, animation.getAnimatedFraction()));
             invalidate();
         });
-        animator.addListener(new AnimatorListenerAdapter() {
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                commitDeltas(boundary);
-            }
-
-            @Override
-            public void onAnimationCancel(Animator animation) {
-                commitDeltas(boundary);
-            }
-        });
         animator.setFloatValues(0f, 1f);
         animator.setDuration(750);
         animator.setInterpolator(new FastOutSlowInInterpolator());
@@ -230,65 +260,79 @@
     }
 
     /**
-     * @return value [0,1] representing the position of the top crop boundary. Does not reflect
-     * changes from any in-progress touch input.
+     * Set the pixel width of the image on the screen (on-screen dimension, not actual bitmap
+     * dimension)
      */
-    public float getTopBoundary() {
-        return mTopCrop;
+    public void setImageWidth(int width) {
+        mImageWidth = width;
+        invalidate();
     }
 
     /**
-     * @return value [0,1] representing the position of the bottom crop boundary. Does not reflect
-     * changes from any in-progress touch input.
+     * @return RectF with values [0,1] representing the position of the boundaries along image axes.
      */
-    public float getBottomBoundary() {
-        return mBottomCrop;
+    public Rect getCropBoundaries(int imageWidth, int imageHeight) {
+        return new Rect((int) (mCrop.left * imageWidth), (int) (mCrop.top * imageHeight),
+                (int) (mCrop.right * imageWidth), (int) (mCrop.bottom * imageHeight));
     }
 
     public void setCropInteractionListener(CropInteractionListener listener) {
         mCropInteractionListener = listener;
     }
 
-    private void commitDeltas(CropBoundary boundary) {
-        if (boundary == CropBoundary.TOP) {
-            mTopCrop += mTopDelta;
-            mTopDelta = 0;
-        } else if (boundary == CropBoundary.BOTTOM) {
-            mBottomCrop += mBottomDelta;
-            mBottomDelta = 0;
-        }
-    }
-
     private void updateListener(MotionEvent event) {
-        if (mCropInteractionListener != null) {
-            float boundaryPosition = (mCurrentDraggingBoundary == CropBoundary.TOP)
-                    ? mTopCrop + mTopDelta : mBottomCrop + mBottomDelta;
+        if (mCropInteractionListener != null && (isVertical(mCurrentDraggingBoundary))) {
+            float boundaryPosition = getBoundaryPosition(mCurrentDraggingBoundary);
             mCropInteractionListener.onCropMotionEvent(event, mCurrentDraggingBoundary,
-                    boundaryPosition, fractionToPixels(boundaryPosition));
+                    boundaryPosition, fractionToVerticalPixels(boundaryPosition),
+                    (mCrop.left + mCrop.right) / 2);
         }
     }
 
-    private void drawShade(Canvas canvas, float fracStart, float fracEnd) {
-        canvas.drawRect(0, fractionToPixels(fracStart), getWidth(),
-                fractionToPixels(fracEnd), mShadePaint);
+    /**
+     * Draw a shade to the given canvas with the given [0,1] fractional image bounds.
+     */
+    private void drawShade(Canvas canvas, float left, float top, float right, float bottom) {
+        canvas.drawRect(fractionToHorizontalPixels(left), fractionToVerticalPixels(top),
+                fractionToHorizontalPixels(right),
+                fractionToVerticalPixels(bottom), mShadePaint);
     }
 
-    private void drawHandle(Canvas canvas, float frac, boolean handleTabUp) {
-        int y = fractionToPixels(frac);
-        canvas.drawLine(0, y, getWidth(), y, mHandlePaint);
-        float radius = 15 * getResources().getDisplayMetrics().density;
-        float x = getWidth() * .9f;
+    private void drawHorizontalHandle(Canvas canvas, float frac, boolean handleTabUp) {
+        int y = fractionToVerticalPixels(frac);
+        canvas.drawLine(fractionToHorizontalPixels(mCrop.left), y,
+                fractionToHorizontalPixels(mCrop.right), y, mHandlePaint);
+        float radius = 8 * getResources().getDisplayMetrics().density;
+        int x = (fractionToHorizontalPixels(mCrop.left) + fractionToHorizontalPixels(mCrop.right))
+                / 2;
         canvas.drawArc(x - radius, y - radius, x + radius, y + radius, handleTabUp ? 180 : 0, 180,
                 true, mHandlePaint);
     }
 
+    private void drawVerticalHandle(Canvas canvas, float frac, boolean handleTabLeft) {
+        int x = fractionToHorizontalPixels(frac);
+        canvas.drawLine(x, fractionToVerticalPixels(mCrop.top), x,
+                fractionToVerticalPixels(mCrop.bottom), mHandlePaint);
+        float radius = 8 * getResources().getDisplayMetrics().density;
+        int y = (fractionToVerticalPixels(getBoundaryPosition(CropBoundary.TOP))
+                + fractionToVerticalPixels(
+                getBoundaryPosition(CropBoundary.BOTTOM))) / 2;
+        canvas.drawArc(x - radius, y - radius, x + radius, y + radius, handleTabLeft ? 90 : 270,
+                180,
+                true, mHandlePaint);
+    }
+
     /**
      * Convert the given fraction position to pixel position within the View.
      */
-    private int fractionToPixels(float frac) {
+    private int fractionToVerticalPixels(float frac) {
         return (int) (mExtraTopPadding + frac * getImageHeight());
     }
 
+    private int fractionToHorizontalPixels(float frac) {
+        return (int) ((getWidth() - mImageWidth) / 2 + frac * mImageWidth);
+    }
+
     private int getImageHeight() {
         return getHeight() - mExtraTopPadding - mExtraBottomPadding;
     }
@@ -296,17 +340,30 @@
     /**
      * Convert the given pixel distance to fraction of the image.
      */
-    private float pixelDistanceToFraction(int px) {
-        return px / (float) getImageHeight();
+    private float pixelDistanceToFraction(float px, CropBoundary boundary) {
+        if (isVertical(boundary)) {
+            return px / getImageHeight();
+        } else {
+            return px / mImageWidth;
+        }
     }
 
-    private CropBoundary nearestBoundary(MotionEvent event, int topPx, int bottomPx) {
+    private CropBoundary nearestBoundary(MotionEvent event, int topPx, int bottomPx, int leftPx,
+            int rightPx) {
         if (Math.abs(event.getY() - topPx) < mCropTouchMargin) {
             return CropBoundary.TOP;
         }
         if (Math.abs(event.getY() - bottomPx) < mCropTouchMargin) {
             return CropBoundary.BOTTOM;
         }
+        if (event.getY() > topPx || event.getY() < bottomPx) {
+            if (Math.abs(event.getX() - leftPx) < mCropTouchMargin) {
+                return CropBoundary.LEFT;
+            }
+            if (Math.abs(event.getX() - rightPx) < mCropTouchMargin) {
+                return CropBoundary.RIGHT;
+            }
+        }
         return CropBoundary.NONE;
     }
 
@@ -321,10 +378,10 @@
 
         @Override
         protected int getVirtualViewAt(float x, float y) {
-            if (Math.abs(y - fractionToPixels(mTopCrop)) < mCropTouchMargin) {
+            if (Math.abs(y - fractionToVerticalPixels(mCrop.top)) < mCropTouchMargin) {
                 return TOP_HANDLE_ID;
             }
-            if (Math.abs(y - fractionToPixels(mBottomCrop)) < mCropTouchMargin) {
+            if (Math.abs(y - fractionToVerticalPixels(mCrop.bottom)) < mCropTouchMargin) {
                 return BOTTOM_HANDLE_ID;
             }
             return ExploreByTouchHelper.INVALID_ID;
@@ -338,7 +395,7 @@
 
         @Override
         protected void onPopulateEventForVirtualView(int virtualViewId, AccessibilityEvent event) {
-            switch(virtualViewId) {
+            switch (virtualViewId) {
                 case TOP_HANDLE_ID:
                     event.setContentDescription(
                             getResources().getString(R.string.screenshot_top_boundary));
@@ -353,16 +410,16 @@
         @Override
         protected void onPopulateNodeForVirtualView(int virtualViewId,
                 AccessibilityNodeInfo node) {
-            switch(virtualViewId) {
+            switch (virtualViewId) {
                 case TOP_HANDLE_ID:
                     node.setContentDescription(
                             getResources().getString(R.string.screenshot_top_boundary));
-                    setNodePositions(mTopCrop, node);
+                    setNodePositions(mCrop.top, node);
                     break;
                 case BOTTOM_HANDLE_ID:
                     node.setContentDescription(
                             getResources().getString(R.string.screenshot_bottom_boundary));
-                    setNodePositions(mBottomCrop, node);
+                    setNodePositions(mCrop.bottom, node);
                     break;
             }
 
@@ -380,7 +437,7 @@
         }
 
         private void setNodePositions(float fraction, AccessibilityNodeInfo node) {
-            int pixels = fractionToPixels(fraction);
+            int pixels = fractionToVerticalPixels(fraction);
             Rect rect = new Rect(0, (int) (pixels - mCropTouchMargin),
                     getWidth(), (int) (pixels + mCropTouchMargin));
             node.setBoundsInParent(rect);
@@ -400,12 +457,11 @@
          * boundaries.
          */
         void onCropMotionEvent(MotionEvent event, CropBoundary boundary, float boundaryPosition,
-                int boundaryPositionPx);
+                int boundaryPositionPx, float horizontalCenter);
     }
 
     static class SavedState extends BaseSavedState {
-        float mTopBoundary;
-        float mBottomBoundary;
+        RectF mCrop;
 
         /**
          * Constructor called from {@link CropView#onSaveInstanceState()}
@@ -419,15 +475,13 @@
          */
         private SavedState(Parcel in) {
             super(in);
-            mTopBoundary = in.readFloat();
-            mBottomBoundary = in.readFloat();
+            mCrop = in.readParcelable(ClassLoader.getSystemClassLoader());
         }
 
         @Override
         public void writeToParcel(Parcel out, int flags) {
             super.writeToParcel(out, flags);
-            out.writeFloat(mTopBoundary);
-            out.writeFloat(mBottomBoundary);
+            out.writeParcelable(mCrop, 0);
         }
 
         public static final Parcelable.Creator<SavedState> CREATOR
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java b/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
index 6a004c2..04d1996 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
@@ -128,7 +128,7 @@
 
         mPreview.addOnLayoutChangeListener(
                 (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) ->
-                        updateCropLocation());
+                        updateImageDimensions());
 
         Intent intent = getIntent();
         mScrollCaptureResponse = intent.getParcelableExtra(EXTRA_CAPTURE_RESPONSE);
@@ -206,7 +206,7 @@
         Log.d(TAG, "onCaptureCompleted(longScreenshot=" + longScreenshot + ")");
         mLongScreenshot = longScreenshot;
         mPreview.setImageDrawable(mLongScreenshot.getDrawable());
-        updateCropLocation();
+        updateImageDimensions();
         mMagnifierView.setDrawable(mLongScreenshot.getDrawable(),
                 mLongScreenshot.getWidth(), mLongScreenshot.getHeight());
         // Original boundaries go from the image tile set's y=0 to y=pageSize, so
@@ -267,8 +267,14 @@
 
     @Override
     protected void onPause() {
-        Log.d(TAG, "onPause finishing=" + isFinishing());
+        Log.d(TAG, "onPause");
         super.onPause();
+    }
+
+    @Override
+    protected void onStop() {
+        Log.d(TAG, "onStop finishing=" + isFinishing());
+        super.onStop();
         if (isFinishing()) {
             if (mScrollCaptureResponse != null) {
                 mScrollCaptureResponse.close();
@@ -297,12 +303,6 @@
     }
 
     @Override
-    protected void onStop() {
-        Log.d(TAG, "onStop");
-        super.onStop();
-    }
-
-    @Override
     protected void onDestroy() {
         Log.d(TAG, "onDestroy");
         super.onDestroy();
@@ -363,10 +363,8 @@
             return;
         }
 
-        Rect bounds = new Rect(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
-        int height = bounds.height();
-        bounds.top = (int) (height * mCropView.getTopBoundary());
-        bounds.bottom = (int) (height * mCropView.getBottomBoundary());
+        Rect bounds = mCropView.getCropBoundaries(drawable.getIntrinsicWidth(),
+                drawable.getIntrinsicHeight());
 
         if (bounds.isEmpty()) {
             Log.w(TAG, "Crop bounds empty, skipping export.");
@@ -404,14 +402,16 @@
         }
     }
 
-    private void updateCropLocation() {
+    private void updateImageDimensions() {
         Drawable drawable = mPreview.getDrawable();
         if (drawable == null) {
             return;
         }
         Rect bounds = drawable.getBounds();
         float imageRatio = bounds.width() / (float) bounds.height();
-        float viewRatio = mPreview.getWidth() / (float) mPreview.getHeight();
+        int previewWidth = mPreview.getWidth() - mPreview.getPaddingLeft()
+                - mPreview.getPaddingRight();
+        float viewRatio = previewWidth / (float) mPreview.getHeight();
 
         if (imageRatio > viewRatio) {
             // Image is full width and height is constrained, compute extra padding to inform
@@ -419,9 +419,12 @@
             float imageHeight = mPreview.getHeight() * viewRatio / imageRatio;
             int extraPadding = (int) (mPreview.getHeight() - imageHeight) / 2;
             mCropView.setExtraPadding(extraPadding, extraPadding);
+            mCropView.setImageWidth(previewWidth);
         } else {
             // Image is full height
             mCropView.setExtraPadding(0, 0);
+            mCropView.setImageWidth((int) (mPreview.getHeight() * imageRatio));
         }
+
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/MagnifierView.java b/packages/SystemUI/src/com/android/systemui/screenshot/MagnifierView.java
index 90f3042..08cd91c 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/MagnifierView.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/MagnifierView.java
@@ -58,6 +58,7 @@
     private float mCheckerboardBoxSize = 40;
 
     private float mLastCropPosition;
+    private float mLastCenter = 0.5f;
     private CropView.CropBoundary mCropBoundary;
 
     private ViewPropertyAnimator mTranslationAnimator;
@@ -131,7 +132,7 @@
             canvas.save();
             // Translate such that the center of this view represents the center of the crop
             // boundary.
-            canvas.translate(-mDrawable.getBounds().width() / 2 + getWidth() / 2,
+            canvas.translate(-mDrawable.getBounds().width() * mLastCenter + getWidth() / 2,
                     -mDrawable.getBounds().height() * mLastCropPosition + getHeight() / 2);
             mDrawable.draw(canvas);
             canvas.restore();
@@ -148,8 +149,9 @@
 
     @Override
     public void onCropMotionEvent(MotionEvent event, CropView.CropBoundary boundary,
-            float cropPosition, int cropPositionPx) {
+            float cropPosition, int cropPositionPx, float horizontalCenter) {
         mCropBoundary = boundary;
+        mLastCenter = horizontalCenter;
         boolean touchOnRight = event.getX() > getParentWidth() / 2;
         float translateXTarget = touchOnRight ? 0 : getParentWidth() - getWidth();
         switch (event.getAction()) {
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
index c1ae292..badffce 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
@@ -25,7 +25,6 @@
 import static com.android.systemui.screenshot.LogConfig.DEBUG_CALLBACK;
 import static com.android.systemui.screenshot.LogConfig.DEBUG_DISMISS;
 import static com.android.systemui.screenshot.LogConfig.DEBUG_INPUT;
-import static com.android.systemui.screenshot.LogConfig.DEBUG_SCROLL;
 import static com.android.systemui.screenshot.LogConfig.DEBUG_UI;
 import static com.android.systemui.screenshot.LogConfig.DEBUG_WINDOW;
 import static com.android.systemui.screenshot.LogConfig.logTag;
@@ -39,7 +38,6 @@
 import android.app.ExitTransitionCoordinator;
 import android.app.ExitTransitionCoordinator.ExitTransitionCallbacks;
 import android.app.Notification;
-import android.app.WindowContext;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -56,7 +54,6 @@
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
-import android.provider.DeviceConfig;
 import android.provider.Settings;
 import android.util.DisplayMetrics;
 import android.util.Log;
@@ -76,9 +73,9 @@
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
 import android.widget.Toast;
+import android.window.WindowContext;
 
 import com.android.internal.app.ChooserActivity;
-import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
 import com.android.internal.logging.UiEventLogger;
 import com.android.internal.policy.PhoneWindow;
 import com.android.settingslib.applications.InterestingConfigChanges;
@@ -86,7 +83,6 @@
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.screenshot.ScreenshotController.SavedImageData.ActionTransition;
 import com.android.systemui.screenshot.TakeScreenshotService.RequestCallback;
-import com.android.systemui.util.DeviceConfigProxy;
 
 import com.google.common.util.concurrent.ListenableFuture;
 
@@ -193,7 +189,6 @@
     private final AccessibilityManager mAccessibilityManager;
     private final MediaActionSound mCameraSound;
     private final ScrollCaptureClient mScrollCaptureClient;
-    private final DeviceConfigProxy mConfigProxy;
     private final PhoneWindow mWindow;
     private final DisplayManager mDisplayManager;
 
@@ -237,7 +232,6 @@
             ScreenshotNotificationsController screenshotNotificationsController,
             ScrollCaptureClient scrollCaptureClient,
             UiEventLogger uiEventLogger,
-            DeviceConfigProxy configProxy,
             ImageExporter imageExporter,
             @Main Executor mainExecutor) {
         mScreenshotSmartActions = screenshotSmartActions;
@@ -254,7 +248,6 @@
         mWindowManager = mContext.getSystemService(WindowManager.class);
 
         mAccessibilityManager = AccessibilityManager.getInstance(mContext);
-        mConfigProxy = configProxy;
 
         // Setup the window that we are going to use
         mWindowLayoutParams = new WindowManager.LayoutParams(
@@ -525,22 +518,17 @@
         // The window is focusable by default
         setWindowFocusable(true);
 
-        if (mConfigProxy.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.SCREENSHOT_SCROLLING_ENABLED, true)) {
-            View decorView = mWindow.getDecorView();
-
-            // Wait until this window is attached to request because it is
-            // the reference used to locate the target window (below).
-            withWindowAttached(() -> {
-                mScrollCaptureClient.setHostWindowToken(decorView.getWindowToken());
-                if (mLastScrollCaptureRequest != null) {
-                    mLastScrollCaptureRequest.cancel(true);
-                }
-                mLastScrollCaptureRequest = mScrollCaptureClient.request(DEFAULT_DISPLAY);
-                mLastScrollCaptureRequest.addListener(() ->
-                        onScrollCaptureResponseReady(mLastScrollCaptureRequest), mMainExecutor);
-            });
-        }
+        // Wait until this window is attached to request because it is
+        // the reference used to locate the target window (below).
+        withWindowAttached(() -> {
+            mScrollCaptureClient.setHostWindowToken(mWindow.getDecorView().getWindowToken());
+            if (mLastScrollCaptureRequest != null) {
+                mLastScrollCaptureRequest.cancel(true);
+            }
+            mLastScrollCaptureRequest = mScrollCaptureClient.request(DEFAULT_DISPLAY);
+            mLastScrollCaptureRequest.addListener(() ->
+                    onScrollCaptureResponseReady(mLastScrollCaptureRequest), mMainExecutor);
+        });
 
         attachWindow();
         mScreenshotView.getViewTreeObserver().addOnPreDrawListener(
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
index 5c650ad..d15f1ff 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
@@ -142,6 +142,8 @@
     private ScreenshotViewCallback mCallbacks;
     private Animator mDismissAnimation;
     private boolean mPendingSharedTransition;
+    private GestureDetector mSwipeDetector;
+    private SwipeDismissHandler mSwipeDismissHandler;
 
     private final ArrayList<ScreenshotActionChip> mSmartChips = new ArrayList<>();
     private PendingInteraction mPendingInteraction;
@@ -181,6 +183,23 @@
         mContext.getDisplay().getRealMetrics(mDisplayMetrics);
 
         mAccessibilityManager = AccessibilityManager.getInstance(mContext);
+
+        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);
+        mSwipeDismissHandler = new SwipeDismissHandler();
     }
 
     /**
@@ -230,6 +249,15 @@
         inoutInfo.touchableRegion.set(touchRegion);
     }
 
+    @Override // ViewGroup
+    public boolean onInterceptTouchEvent(MotionEvent ev) {
+        // 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() {
         mScreenshotStatic = requireNonNull(findViewById(R.id.global_screenshot_static));
@@ -455,11 +483,7 @@
 
                 createScreenshotActionsShadeAnimation().start();
 
-                SwipeDismissHandler swipeDismissHandler = new SwipeDismissHandler();
-                mScreenshotPreview.setOnTouchListener(swipeDismissHandler);
-                mActionsContainer.setOnTouchListener(swipeDismissHandler);
-                mActionsContainerBackground.setOnTouchListener(swipeDismissHandler);
-                mBackgroundProtection.setOnTouchListener(swipeDismissHandler);
+                setOnTouchListener(mSwipeDismissHandler);
             }
         });
 
@@ -776,30 +800,16 @@
     }
 
     class SwipeDismissHandler implements OnTouchListener {
-
-        // if distance moved on ACTION_UP is less than this, register a click
-        // otherwise, run return animator
-        private static final float CLICK_MOVEMENT_THRESHOLD_DP = 1;
         // distance needed to register a dismissal
         private static final float DISMISS_DISTANCE_THRESHOLD_DP = 30;
 
         private final GestureDetector mGestureDetector;
-        private final float mDismissStartX;
-        private final Rect mActionsRect = new Rect();
 
         private float mStartX;
-        private float mStartY;
-        private float mTranslationX = 0;
-
-        // tracks whether mStartX has been set for this interaction
-        private boolean mInteractionStarted = false;
-        // tracks whether we're dragging the UI (as opposed to scrolling the actions bar)
-        private boolean mIsDragging = false;
 
         SwipeDismissHandler() {
             GestureDetector.OnGestureListener gestureListener = new SwipeDismissGestureListener();
             mGestureDetector = new GestureDetector(mContext, gestureListener);
-            mDismissStartX = mDismissButton.getX();
         }
 
         @Override
@@ -807,13 +817,9 @@
             boolean gestureResult = mGestureDetector.onTouchEvent(event);
             mCallbacks.onUserInteraction();
             if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
-                mInteractionStarted = true;
                 mStartX = event.getRawX();
-                mStartY = event.getRawY();
                 return true;
             } else if (event.getActionMasked() == MotionEvent.ACTION_UP) {
-                mInteractionStarted = false;
-                mIsDragging = false;
                 if (isPastDismissThreshold()
                         && (mDismissAnimation == null || !mDismissAnimation.isRunning())) {
                     if (DEBUG_INPUT) {
@@ -821,87 +827,47 @@
                     }
                     mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_SWIPE_DISMISSED);
                     animateDismissal(createSwipeDismissAnimation());
-                    return true;
-                } else if (MathUtils.dist(mStartX, mStartY, event.getRawX(), event.getRawY())
-                        > dpToPx(CLICK_MOVEMENT_THRESHOLD_DP)) {
-                    // if we've moved a non-negligible distance (but not past the threshold),
+                } else {
+                    // if we've moved, but not past the threshold, start the return animation
                     if (DEBUG_DISMISS) {
                         Log.d(TAG, "swipe gesture abandoned");
                     }
-                    // start the return animation
                     if ((mDismissAnimation == null || !mDismissAnimation.isRunning())) {
                         createSwipeReturnAnimation().start();
                     }
-                    return true;
-                } else {
-                    if (view == mScreenshotPreview) {
-                        mScreenshotPreview.performClick();
-                    }
                 }
+                return true;
             }
             return gestureResult;
         }
 
         class SwipeDismissGestureListener extends GestureDetector.SimpleOnGestureListener {
-
-            /**
-             * This is somewhat complicated to handle because we want to allow scrolling the actions
-             * bar (if it extends off the screen) as well as dismissing the UI horizontally by
-             * dragging the actions bar. In addition, we don't get the initial ACTION_DOWN because
-             * it is consumed by the action bar view.
-             *
-             * So, we use a gated system: first, keep track of the pointer location as we move;
-             * next, check whether the actions bar can scroll in the direction we're moving in. If
-             * it can, let the actions bar handle the event; otherwise, we've gone as far as we can
-             * and can start dragging the UI instead.
-             */
             @Override
             public boolean onScroll(
                     MotionEvent ev1, MotionEvent ev2, float distanceX, float distanceY) {
-                mActionsContainer.getBoundsOnScreen(mActionsRect);
-                if (!mInteractionStarted) {
-                    if (mActionsRect.contains((int) ev2.getRawX(), (int) ev2.getRawY())) {
-                        mStartX = ev2.getRawX();
-                        mInteractionStarted = true;
-                    }
-                } else {
-                    float distance = ev2.getRawX() - mStartX;
-                    if ((mIsDragging && distance * mTranslationX > 0)
-                            || !mActionsRect.contains((int) ev2.getRawX(), (int) ev2.getRawY())
-                            || !mActionsContainer.canScrollHorizontally(-1 * (int) distance)) {
-                        mIsDragging = true;
-                        mTranslationX = distance;
-                        mScreenshotStatic.setTranslationX(mTranslationX);
-                        return true;
-                    } else {
-                        mStartX = ev2.getRawX();
-                    }
-                }
-                return false;
+                mScreenshotStatic.setTranslationX(ev2.getRawX() - mStartX);
+                return true;
             }
         }
 
         private boolean isPastDismissThreshold() {
-            if (mDirectionLTR) {
-                return mTranslationX <= -1 * dpToPx(DISMISS_DISTANCE_THRESHOLD_DP);
-            } else {
-                return mTranslationX >= dpToPx(DISMISS_DISTANCE_THRESHOLD_DP);
-            }
+            float distance = Math.abs(mScreenshotStatic.getTranslationX());
+            return distance >= dpToPx(DISMISS_DISTANCE_THRESHOLD_DP);
         }
 
         private ValueAnimator createSwipeDismissAnimation() {
             ValueAnimator anim = ValueAnimator.ofFloat(0, 1);
-            float startX = mTranslationX;
-            float finalX = mDirectionLTR
-                    ? -1 * (mActionsContainerBackground.getX()
-                    + mActionsContainerBackground.getWidth())
+            float startX = mScreenshotStatic.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 = startX < 0
+                    ? -1 * mActionsContainerBackground.getRight()
                     : mDisplayMetrics.widthPixels;
 
             anim.addUpdateListener(animation -> {
-                float translation = MathUtils.lerp(startX, finalX,
-                        animation.getAnimatedFraction());
+                float translation = MathUtils.lerp(startX, finalX, animation.getAnimatedFraction());
                 mScreenshotStatic.setTranslationX(translation);
-
                 setAlpha(1 - animation.getAnimatedFraction());
             });
             anim.setDuration(400);
@@ -910,9 +876,8 @@
 
         private ValueAnimator createSwipeReturnAnimation() {
             ValueAnimator anim = ValueAnimator.ofFloat(0, 1);
-            float startX = mTranslationX;
+            float startX = mScreenshotStatic.getTranslationX();
             float finalX = 0;
-            mTranslationX = 0;
 
             anim.addUpdateListener(animation -> {
                 float translation = MathUtils.lerp(
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 fea521f..bdb3926 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessController.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessController.java
@@ -241,15 +241,7 @@
         public void run() {
             final float valFloat;
             final boolean inVrMode = mIsVrModeEnabled;
-            if (inVrMode) {
-                valFloat = Settings.System.getFloatForUser(mContext.getContentResolver(),
-                        Settings.System.SCREEN_BRIGHTNESS_FOR_VR_FLOAT, mDefaultBacklightForVr,
-                        UserHandle.USER_CURRENT);
-            } else {
-                valFloat = Settings.System.getFloatForUser(mContext.getContentResolver(),
-                        Settings.System.SCREEN_BRIGHTNESS_FLOAT, mDefaultBacklight,
-                        UserHandle.USER_CURRENT);
-            }
+            valFloat = mDisplayManager.getBrightness(mDisplayId);
             // Value is passed as intbits, since this is what the message takes.
             final int valueAsIntBits = Float.floatToIntBits(valFloat);
             mHandler.obtainMessage(MSG_UPDATE_SLIDER, valueAsIntBits,
@@ -364,14 +356,12 @@
             metric = MetricsEvent.ACTION_BRIGHTNESS_FOR_VR;
             minBacklight = mMinimumBacklightForVr;
             maxBacklight = mMaximumBacklightForVr;
-            settingToChange = Settings.System.SCREEN_BRIGHTNESS_FOR_VR_FLOAT;
         } else {
             metric = mAutomatic
                     ? MetricsEvent.ACTION_BRIGHTNESS_AUTO
                     : MetricsEvent.ACTION_BRIGHTNESS;
             minBacklight = PowerManager.BRIGHTNESS_MIN;
             maxBacklight = PowerManager.BRIGHTNESS_MAX;
-            settingToChange = Settings.System.SCREEN_BRIGHTNESS_FLOAT;
         }
         final float valFloat = MathUtils.min(convertGammaToLinearFloat(value,
                 minBacklight, maxBacklight),
@@ -386,8 +376,7 @@
         if (!tracking) {
             AsyncTask.execute(new Runnable() {
                     public void run() {
-                        Settings.System.putFloatForUser(mContext.getContentResolver(),
-                                settingToChange, valFloat, UserHandle.USER_CURRENT);
+                        mDisplayManager.setBrightness(mDisplayId, valFloat);
                     }
                 });
         }
diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSlider.java b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSlider.java
index 0b40e22..5d964a4 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSlider.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSlider.java
@@ -27,7 +27,10 @@
 import androidx.annotation.Nullable;
 
 import com.android.settingslib.RestrictedLockUtils;
+import com.android.systemui.Gefingerpoken;
 import com.android.systemui.R;
+import com.android.systemui.classifier.Classifier;
+import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.statusbar.policy.BrightnessMirrorController;
 import com.android.systemui.util.ViewController;
 
@@ -42,9 +45,7 @@
  *
  * @see BrightnessMirrorController
  */
-public class BrightnessSlider
-        extends ViewController<View>
-        implements ToggleSlider {
+public class BrightnessSlider extends ViewController<View> implements ToggleSlider {
 
     private Listener mListener;
     private ToggleSlider mMirror;
@@ -52,15 +53,34 @@
     private BrightnessMirrorController mMirrorController;
     private boolean mTracking;
     private final boolean mUseMirror;
+    private final FalsingManager mFalsingManager;
+
+    private final Gefingerpoken mOnInterceptListener = new Gefingerpoken() {
+        @Override
+        public boolean onInterceptTouchEvent(MotionEvent ev) {
+            int action = ev.getActionMasked();
+            if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
+                mFalsingManager.isFalseTouch(Classifier.BRIGHTNESS_SLIDER);
+            }
+
+            return false;
+        }
+
+        @Override
+        public boolean onTouchEvent(MotionEvent ev) {
+            return false;
+        }
+    };
 
     BrightnessSlider(
             View rootView,
             BrightnessSliderView brightnessSliderView,
-            boolean useMirror
-    ) {
+            boolean useMirror,
+            FalsingManager falsingManager) {
         super(rootView);
         mBrightnessSliderView = brightnessSliderView;
         mUseMirror = useMirror;
+        mFalsingManager = falsingManager;
     }
 
     /**
@@ -78,6 +98,7 @@
     protected void onViewAttached() {
         mBrightnessSliderView.setOnSeekBarChangeListener(mSeekListener);
         mBrightnessSliderView.setOnCheckedChangeListener(mCheckListener);
+        mBrightnessSliderView.setOnInterceptListener(mOnInterceptListener);
     }
 
     @Override
@@ -85,6 +106,7 @@
         mBrightnessSliderView.setOnSeekBarChangeListener(null);
         mBrightnessSliderView.setOnCheckedChangeListener(null);
         mBrightnessSliderView.setOnDispatchTouchEventListener(null);
+        mBrightnessSliderView.setOnInterceptListener(null);
     }
 
     @Override
@@ -247,10 +269,12 @@
     public static class Factory {
 
         BrightnessControllerSettings mSettings;
+        private final FalsingManager mFalsingManager;
 
         @Inject
-        public Factory(BrightnessControllerSettings settings) {
+        public Factory(BrightnessControllerSettings settings, FalsingManager falsingManager) {
             mSettings = settings;
+            mFalsingManager = falsingManager;
         }
 
         /**
@@ -270,7 +294,7 @@
         private BrightnessSlider fromTree(ViewGroup root, boolean useMirror) {
             BrightnessSliderView v = root.requireViewById(R.id.brightness_slider);
 
-            return new BrightnessSlider(root, v, useMirror);
+            return new BrightnessSlider(root, v, useMirror, mFalsingManager);
         }
 
         /** Get the layout to inflate based on what slider to use */
diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderView.java b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderView.java
index cbf4e88..5b71c62 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderView.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderView.java
@@ -31,6 +31,7 @@
 import androidx.annotation.Nullable;
 
 import com.android.settingslib.RestrictedLockUtils;
+import com.android.systemui.Gefingerpoken;
 import com.android.systemui.R;
 
 /**
@@ -54,6 +55,7 @@
     private TextView mLabel;
     private final CharSequence mText;
     private DispatchTouchEventListener mListener;
+    private Gefingerpoken mOnInterceptListener;
 
     public BrightnessSliderView(Context context) {
         this(context, null);
@@ -105,6 +107,15 @@
         return super.dispatchTouchEvent(ev);
     }
 
+    @Override
+    public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
+        // We prevent disallowing on this view, but bubble it up to our parents.
+        // We need interception to handle falsing.
+        if (mParent != null) {
+            mParent.requestDisallowInterceptTouchEvent(disallowIntercept);
+        }
+    }
+
     /**
      * Attaches a listener to the {@link ToggleSeekBar} in the view so changes can be observed
      * @param seekListener use {@code null} to remove listener
@@ -195,6 +206,18 @@
         return mSlider.getProgress();
     }
 
+    public void setOnInterceptListener(Gefingerpoken onInterceptListener) {
+        mOnInterceptListener = onInterceptListener;
+    }
+
+    @Override
+    public boolean onInterceptTouchEvent(MotionEvent ev) {
+        if (mOnInterceptListener != null) {
+            return mOnInterceptListener.onInterceptTouchEvent(ev);
+        }
+        return super.onInterceptTouchEvent(ev);
+    }
+
     /**
      * Interface to attach a listener for {@link View#dispatchTouchEvent}.
      */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java b/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java
index 708bdfe..90c3dfc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java
@@ -87,10 +87,6 @@
         return mFlagReader.isEnabled(R.bool.flag_wallet);
     }
 
-    public boolean isNavigationBarOverlayEnabled() {
-        return mFlagReader.isEnabled(R.bool.flag_navigation_bar_overlay);
-    }
-
     public boolean isPMLiteEnabled() {
         return mFlagReader.isEnabled(R.bool.flag_pm_lite);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
index ca3923f..c565a271 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
@@ -38,8 +38,6 @@
 import android.os.AsyncTask;
 import android.os.Trace;
 import android.os.UserHandle;
-import android.provider.DeviceConfig;
-import android.provider.DeviceConfig.Properties;
 import android.service.notification.NotificationListenerService;
 import android.service.notification.NotificationStats;
 import android.service.notification.StatusBarNotification;
@@ -48,7 +46,6 @@
 import android.view.View;
 import android.widget.ImageView;
 
-import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
 import com.android.internal.statusbar.NotificationVisibility;
 import com.android.systemui.Dependency;
 import com.android.systemui.Dumpable;
@@ -147,23 +144,6 @@
     private ImageView mBackdropFront;
     private ImageView mBackdropBack;
 
-    private boolean mShowCompactMediaSeekbar;
-    private final DeviceConfig.OnPropertiesChangedListener mPropertiesChangedListener =
-            new DeviceConfig.OnPropertiesChangedListener() {
-        @Override
-        public void onPropertiesChanged(Properties properties) {
-            for (String name : properties.getKeyset()) {
-                if (SystemUiDeviceConfigFlags.COMPACT_MEDIA_SEEKBAR_ENABLED.equals(name)) {
-                    String value = properties.getString(name, null);
-                    if (DEBUG_MEDIA) {
-                        Log.v(TAG, "DEBUG_MEDIA: compact media seekbar flag updated: " + value);
-                    }
-                    mShowCompactMediaSeekbar = "true".equals(value);
-                }
-            }
-        }
-    };
-
     private final MediaController.Callback mMediaListener = new MediaController.Callback() {
         @Override
         public void onPlaybackStateChanged(PlaybackState state) {
@@ -231,14 +211,6 @@
             setupNotifPipeline();
             mUsingNotifPipeline = true;
         }
-
-        mShowCompactMediaSeekbar = "true".equals(
-                DeviceConfig.getProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
-                    SystemUiDeviceConfigFlags.COMPACT_MEDIA_SEEKBAR_ENABLED));
-
-        deviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_SYSTEMUI,
-                mContext.getMainExecutor(),
-                mPropertiesChangedListener);
     }
 
     private void setupNotifPipeline() {
@@ -405,10 +377,6 @@
         return mMediaMetadata;
     }
 
-    public boolean getShowCompactMediaSeekbar() {
-        return mShowCompactMediaSeekbar;
-    }
-
     public Icon getMediaIcon() {
         if (mMediaNotificationKey == null) {
             return null;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
index ead6d32..e27c1a2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
@@ -189,7 +189,7 @@
         blurUtils.applyBlur(blurRoot?.viewRootImpl ?: root.viewRootImpl, blur)
         val zoomOut = blurUtils.ratioOfBlurRadius(blur)
         try {
-            if (root.isAttachedToWindow) {
+            if (root.isAttachedToWindow && root.windowToken != null) {
                 wallpaperManager.setWallpaperZoomOut(root.windowToken, zoomOut)
             } else {
                 Log.i(TAG, "Won't set zoom. Window not attached $root")
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/OperatorNameView.java b/packages/SystemUI/src/com/android/systemui/statusbar/OperatorNameView.java
index 2aba103..cc7a4f8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/OperatorNameView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/OperatorNameView.java
@@ -16,7 +16,6 @@
 
 import android.content.Context;
 import android.graphics.Rect;
-import android.net.ConnectivityManager;
 import android.os.Bundle;
 import android.telephony.ServiceState;
 import android.telephony.SubscriptionInfo;
@@ -123,8 +122,7 @@
                 .getValue(KEY_SHOW_OPERATOR_NAME, 1) != 0;
         setVisibility(showOperatorName ? VISIBLE : GONE);
 
-        boolean hasMobile = ConnectivityManager.from(mContext)
-                .isNetworkSupported(ConnectivityManager.TYPE_MOBILE);
+        boolean hasMobile = mContext.getSystemService(TelephonyManager.class).isDataCapable();
         boolean airplaneMode = WirelessUtils.isAirplaneModeOn(mContext);
         if (!hasMobile || airplaneMode) {
             setText(null);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index e5a960e..412d342 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -33,6 +33,7 @@
 import android.graphics.ColorMatrixColorFilter;
 import android.graphics.Paint;
 import android.graphics.Rect;
+import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.Icon;
 import android.os.Parcelable;
@@ -83,8 +84,15 @@
     public static final int STATE_DOT = 1;
     public static final int STATE_HIDDEN = 2;
 
-    /** Maximum allowed width or height for an icon drawable */
-    private static final int MAX_IMAGE_SIZE = 500;
+    /**
+     * Maximum allowed byte count for an icon bitmap
+     * @see android.graphics.RecordingCanvas.MAX_BITMAP_SIZE
+     */
+    private static final int MAX_BITMAP_SIZE = 100 * 1024 * 1024; // 100 MB
+    /**
+     * Maximum allowed width or height for an icon drawable, if we can't get byte count
+     */
+    private static final int MAX_IMAGE_SIZE = 5000;
 
     private static final String TAG = "StatusBarIconView";
     private static final Property<StatusBarIconView, Float> ICON_APPEAR_AMOUNT
@@ -382,9 +390,18 @@
             return false;
         }
 
-        if (drawable.getIntrinsicWidth() > MAX_IMAGE_SIZE
+        if (drawable instanceof BitmapDrawable && ((BitmapDrawable) drawable).getBitmap() != null) {
+            // If it's a bitmap we can check the size directly
+            int byteCount = ((BitmapDrawable) drawable).getBitmap().getByteCount();
+            if (byteCount > MAX_BITMAP_SIZE) {
+                Log.w(TAG, "Drawable is too large (" + byteCount + " bytes) " + mIcon);
+                return false;
+            }
+        } else if (drawable.getIntrinsicWidth() > MAX_IMAGE_SIZE
                 || drawable.getIntrinsicHeight() > MAX_IMAGE_SIZE) {
-            Log.w(TAG, "Drawable is too large " + mIcon);
+            // Otherwise, check dimensions
+            Log.w(TAG, "Drawable is too large (" + drawable.getIntrinsicWidth() + "x"
+                    + drawable.getIntrinsicHeight() + ") " + mIcon);
             return false;
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java
index 138c811..ab17ee0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java
@@ -59,6 +59,7 @@
     private View mMobileRoamingSpace;
     private int mVisibleState = -1;
     private DualToneHandler mDualToneHandler;
+    private boolean mForceHidden;
 
     public static StatusBarMobileView fromContext(Context context, String slot) {
         LayoutInflater inflater = LayoutInflater.from(context);
@@ -150,7 +151,7 @@
 
     private void initViewState() {
         setContentDescription(mState.contentDescription);
-        if (!mState.visible) {
+        if (!mState.visible || mForceHidden) {
             mMobileGroup.setVisibility(View.GONE);
         } else {
             mMobileGroup.setVisibility(View.VISIBLE);
@@ -176,8 +177,9 @@
         boolean needsLayout = false;
 
         setContentDescription(state.contentDescription);
-        if (mState.visible != state.visible) {
-            mMobileGroup.setVisibility(state.visible ? View.VISIBLE : View.GONE);
+        int newVisibility = state.visible && !mForceHidden ? View.VISIBLE : View.GONE;
+        if (newVisibility != mMobileGroup.getVisibility()) {
+            mMobileGroup.setVisibility(newVisibility);
             needsLayout = true;
         }
         if (mState.strengthId != state.strengthId) {
@@ -252,7 +254,7 @@
 
     @Override
     public boolean isIconVisible() {
-        return mState.visible;
+        return mState.visible && !mForceHidden;
     }
 
     @Override
@@ -279,6 +281,23 @@
         }
     }
 
+    /**
+     * Forces the state to be hidden (views will be GONE) and if necessary updates the layout.
+     *
+     * Makes sure that the {@link StatusBarIconController} cannot make it visible while this flag
+     * is enabled.
+     * @param forceHidden {@code true} if the icon should be GONE in its view regardless of its
+     *                                state.
+     *               {@code false} if the icon should show as determined by its controller.
+     */
+    public void forceHidden(boolean forceHidden) {
+        if (mForceHidden != forceHidden) {
+            mForceHidden = forceHidden;
+            updateState(mState);
+            requestLayout();
+        }
+    }
+
     @Override
     public int getVisibleState() {
         return mVisibleState;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/charging/ChargingRippleView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/charging/ChargingRippleView.kt
index 6f80317..05af08e0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/charging/ChargingRippleView.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/charging/ChargingRippleView.kt
@@ -25,10 +25,8 @@
 import android.graphics.PointF
 import android.util.AttributeSet
 import android.view.View
-import kotlin.math.max
 
-private const val RIPPLE_ANIMATION_DURATION: Long = 1500
-private const val RIPPLE_SPARKLE_STRENGTH: Float = 0.3f
+private const val RIPPLE_SPARKLE_STRENGTH: Float = 0.4f
 
 /**
  * Expanding ripple effect that shows when charging begins.
@@ -39,17 +37,18 @@
     private val defaultColor: Int = 0xffffffff.toInt()
     private val ripplePaint = Paint()
 
+    var radius: Float = 0.0f
+        set(value) { rippleShader.radius = value }
+    var origin: PointF = PointF()
+        set(value) { rippleShader.origin = value }
+    var duration: Long = 1500
+
     init {
         rippleShader.color = defaultColor
         rippleShader.progress = 0f
         rippleShader.sparkleStrength = RIPPLE_SPARKLE_STRENGTH
         ripplePaint.shader = rippleShader
-    }
-
-    override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
-        rippleShader.origin = PointF(measuredWidth / 2f, measuredHeight.toFloat())
-        rippleShader.radius = max(measuredWidth, measuredHeight).toFloat()
-        super.onLayout(changed, left, top, right, bottom)
+        visibility = View.GONE
     }
 
     fun startRipple() {
@@ -57,7 +56,7 @@
             return // Ignore if ripple effect is already playing
         }
         val animator = ValueAnimator.ofFloat(0f, 1f)
-        animator.duration = RIPPLE_ANIMATION_DURATION
+        animator.duration = duration
         animator.addUpdateListener { animator ->
             val now = animator.currentPlayTime
             val phase = now / 30000f
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/charging/RippleShader.kt b/packages/SystemUI/src/com/android/systemui/statusbar/charging/RippleShader.kt
index 5547c1e..d400205 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/charging/RippleShader.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/charging/RippleShader.kt
@@ -53,7 +53,7 @@
                   float s = 0.0;
                   for (float i = 0; i < 4; i += 1) {
                     float l = i * 0.25;
-                    float h = l + 0.025;
+                    float h = l + 0.005;
                     float o = abs(sin(0.1 * PI * (t + i)));
                     s += threshold(n + o, l, h);
                   }
@@ -97,7 +97,7 @@
                     float fadeRipple = min(fadeIn, 1.-fadeOutRipple);
                     float rippleAlpha = softRing(p, in_origin, radius, 0.5)
                         * fadeRipple * in_color.a;
-                    vec4 ripple = in_color * max(circle, rippleAlpha) * 0.4;
+                    vec4 ripple = in_color * max(circle, rippleAlpha) * 0.3;
                     return mix(ripple, vec4(sparkle), sparkle * in_sparkle_strength);
                 }"""
         private const val SHADER = SHADER_UNIFORMS + SHADER_LIB + SHADER_MAIN
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 b567ad4..2900462 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/charging/WiredChargingRippleController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/charging/WiredChargingRippleController.kt
@@ -18,6 +18,7 @@
 
 import android.content.Context
 import android.content.res.Configuration
+import android.graphics.PointF
 import android.util.DisplayMetrics
 import android.view.View
 import android.view.ViewGroupOverlay
@@ -31,6 +32,7 @@
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.statusbar.policy.KeyguardStateController
 import java.io.PrintWriter
+import java.lang.Integer.max
 import javax.inject.Inject
 
 /***
@@ -46,7 +48,7 @@
     private val context: Context,
     private val keyguardStateController: KeyguardStateController
 ) {
-    private var pluggedIn: Boolean? = null
+    private var charging: Boolean? = null
     private val rippleEnabled: Boolean = featureFlags.isChargingRippleEnabled
     @VisibleForTesting
     var rippleView: ChargingRippleView = ChargingRippleView(context, attrs = null)
@@ -55,16 +57,18 @@
         val batteryStateChangeCallback = object : BatteryController.BatteryStateChangeCallback {
             override fun onBatteryLevelChanged(
                 level: Int,
-                nowPluggedIn: Boolean,
-                charging: Boolean
+                pluggedIn: Boolean,
+                nowCharging: Boolean
             ) {
-                if (!rippleEnabled) {
+                // Suppresses the ripple when it's disabled, or when the state change comes
+                // from wireless charging.
+                if (!rippleEnabled || batteryController.isWirelessCharging) {
                     return
                 }
-                val wasPluggedIn = pluggedIn
-                pluggedIn = nowPluggedIn
+                val wasCharging = charging
+                charging = nowCharging
                 // Only triggers when the keyguard is active and the device is just plugged in.
-                if (wasPluggedIn == false && nowPluggedIn && keyguardStateController.isShowing) {
+                if (wasCharging == false && nowCharging && keyguardStateController.isShowing) {
                     rippleView.startRipple()
                 }
             }
@@ -113,10 +117,13 @@
         val width = displayMetrics.widthPixels
         val height = displayMetrics.heightPixels
         if (width != rippleView.width || height != rippleView.height) {
-            rippleView.measure(
-                    View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY),
-                    View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY))
-            rippleView.layout(0, 0, width, height)
+            rippleView.apply {
+                measure(View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY),
+                        View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY))
+                layout(0, 0, width, height)
+                origin = PointF(width / 2f, height.toFloat())
+                radius = max(width, height).toFloat()
+            }
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
index 85a1aed..23d13d3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.statusbar.notification;
 
+import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
+
 import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_APP_START;
 
 import android.animation.Animator;
@@ -34,6 +36,8 @@
 import android.view.SyncRtSurfaceTransactionApplier.SurfaceParams;
 import android.view.View;
 import android.view.WindowManager;
+import android.view.animation.Interpolator;
+import android.view.animation.PathInterpolator;
 
 import com.android.internal.jank.InteractionJankMonitor;
 import com.android.internal.policy.ScreenDecorationsUtils;
@@ -59,6 +63,14 @@
     public static final long ANIMATION_DELAY_ICON_FADE_IN = ANIMATION_DURATION -
             CollapsedStatusBarFragment.FADE_IN_DURATION - CollapsedStatusBarFragment.FADE_IN_DELAY
             - 16;
+    private static final int ANIMATION_DURATION_NAV_FADE_IN = 266;
+    private static final int ANIMATION_DURATION_NAV_FADE_OUT = 133;
+    private static final long ANIMATION_DELAY_NAV_FADE_IN =
+            ANIMATION_DURATION - ANIMATION_DURATION_NAV_FADE_IN;
+    private static final Interpolator NAV_FADE_IN_INTERPOLATOR =
+            new PathInterpolator(0f, 0f, 0f, 1f);
+    private static final Interpolator NAV_FADE_OUT_INTERPOLATOR =
+            new PathInterpolator(0.2f, 0f, 1f, 1f);
     private static final long LAUNCH_TIMEOUT = 500;
     private final NotificationPanelViewController mNotificationPanel;
     private final NotificationListContainer mNotificationContainer;
@@ -208,6 +220,8 @@
                 int notificationHeight = Math.max(mSourceNotification.getActualHeight()
                         - mSourceNotification.getClipBottomAmount(), 0);
                 int notificationWidth = mSourceNotification.getWidth();
+                final RemoteAnimationTarget navigationBarTarget =
+                        getNavBarRemoteAnimationTarget(remoteAnimationNonAppTargets);
                 anim.setDuration(ANIMATION_DURATION);
                 anim.setInterpolator(Interpolators.LINEAR);
                 anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@@ -234,6 +248,7 @@
                         applyParamsToWindow(primary);
                         applyParamsToNotification(mParams);
                         applyParamsToNotificationShade(mParams);
+                        applyNavigationBarParamsToWindow(navigationBarTarget);
                     }
                 });
                 anim.addListener(new AnimatorListenerAdapter() {
@@ -286,6 +301,18 @@
             return primary;
         }
 
+        private RemoteAnimationTarget getNavBarRemoteAnimationTarget(
+                RemoteAnimationTarget[] remoteAnimationTargets) {
+            RemoteAnimationTarget navBar = null;
+            for (RemoteAnimationTarget target : remoteAnimationTargets) {
+                if (target.windowType == TYPE_NAVIGATION_BAR) {
+                    navBar = target;
+                    break;
+                }
+            }
+            return navBar;
+        }
+
         private void setExpandAnimationRunning(boolean running) {
             mNotificationPanel.setLaunchingNotification(running);
             mSourceNotification.setExpandAnimationRunning(running);
@@ -326,6 +353,34 @@
             mSyncRtTransactionApplier.scheduleApply(params);
         }
 
+        private void applyNavigationBarParamsToWindow(RemoteAnimationTarget navBarTarget) {
+            if (navBarTarget == null) {
+                return;
+            }
+
+            // calculate navigation bar fade-out progress
+            final float fadeOutProgress = mParams.getProgress(0,
+                    ANIMATION_DURATION_NAV_FADE_OUT);
+
+            // calculate navigation bar fade-in progress
+            final float fadeInProgress = mParams.getProgress(ANIMATION_DELAY_NAV_FADE_IN,
+                    ANIMATION_DURATION_NAV_FADE_OUT);
+
+            final SurfaceParams.Builder builder = new SurfaceParams.Builder(navBarTarget.leash);
+            if (fadeInProgress > 0) {
+                Matrix m = new Matrix();
+                m.postTranslate(0, (float) (mParams.top - navBarTarget.position.y));
+                mWindowCrop.set(mParams.left, 0, mParams.right, mParams.getHeight());
+                builder.withMatrix(m)
+                        .withWindowCrop(mWindowCrop)
+                        .withVisibility(true);
+                builder.withAlpha(NAV_FADE_IN_INTERPOLATOR.getInterpolation(fadeInProgress));
+            } else {
+                builder.withAlpha(1f - NAV_FADE_OUT_INTERPOLATOR.getInterpolation(fadeOutProgress));
+            }
+            mSyncRtTransactionApplier.scheduleApply(builder.build());
+        }
+
         @Override
         public void onAnimationCancelled() throws RemoteException {
             mMainExecutor.execute(() -> {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ImageGradientColorizer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ImageGradientColorizer.java
deleted file mode 100644
index f5a76f0..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ImageGradientColorizer.java
+++ /dev/null
@@ -1,103 +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.statusbar.notification;
-
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.ColorMatrix;
-import android.graphics.ColorMatrixColorFilter;
-import android.graphics.LinearGradient;
-import android.graphics.Paint;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuffXfermode;
-import android.graphics.Shader;
-import android.graphics.drawable.Drawable;
-
-/**
- * A utility class to colorize bitmaps with a color gradient and a special blending mode
- */
-public class ImageGradientColorizer {
-    public Bitmap colorize(Drawable drawable, int backgroundColor, boolean isRtl) {
-        int width = drawable.getIntrinsicWidth();
-        int height = drawable.getIntrinsicHeight();
-        int size = Math.min(width, height);
-        int widthInset = (width - size) / 2;
-        int heightInset = (height - size) / 2;
-        drawable = drawable.mutate();
-        drawable.setBounds(- widthInset, - heightInset, width - widthInset, height - heightInset);
-        Bitmap newBitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
-        Canvas canvas = new Canvas(newBitmap);
-
-        // Values to calculate the luminance of a color
-        float lr = 0.2126f;
-        float lg = 0.7152f;
-        float lb = 0.0722f;
-
-        // Extract the red, green, blue components of the color extraction color in
-        // float and int form
-        int tri = Color.red(backgroundColor);
-        int tgi = Color.green(backgroundColor);
-        int tbi = Color.blue(backgroundColor);
-
-        float tr = tri / 255f;
-        float tg = tgi / 255f;
-        float tb = tbi / 255f;
-
-        // Calculate the luminance of the color extraction color
-        float cLum = (tr * lr + tg * lg + tb * lb) * 255;
-
-        ColorMatrix m = new ColorMatrix(new float[] {
-                lr, lg, lb, 0, tri - cLum,
-                lr, lg, lb, 0, tgi - cLum,
-                lr, lg, lb, 0, tbi - cLum,
-                0, 0, 0, 1, 0,
-        });
-
-        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
-        LinearGradient linearGradient =  new LinearGradient(0, 0, size, 0,
-                new int[] {0, Color.argb(0.5f, 1, 1, 1), Color.BLACK},
-                new float[] {0.0f, 0.4f, 1.0f}, Shader.TileMode.CLAMP);
-        paint.setShader(linearGradient);
-        Bitmap fadeIn = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
-        Canvas fadeInCanvas = new Canvas(fadeIn);
-        drawable.clearColorFilter();
-        drawable.draw(fadeInCanvas);
-
-        if (isRtl) {
-            // Let's flip the gradient
-            fadeInCanvas.translate(size, 0);
-            fadeInCanvas.scale(-1, 1);
-        }
-        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
-        fadeInCanvas.drawPaint(paint);
-
-        Paint coloredPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
-        coloredPaint.setColorFilter(new ColorMatrixColorFilter(m));
-        coloredPaint.setAlpha((int) (0.5f * 255));
-        canvas.drawBitmap(fadeIn, 0, 0, coloredPaint);
-
-        linearGradient =  new LinearGradient(0, 0, size, 0,
-                new int[] {0, Color.argb(0.5f, 1, 1, 1), Color.BLACK},
-                new float[] {0.0f, 0.6f, 1.0f}, Shader.TileMode.CLAMP);
-        paint.setShader(linearGradient);
-        fadeInCanvas.drawPaint(paint);
-        canvas.drawBitmap(fadeIn, 0, 0, null);
-
-        return newBitmap;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/MediaNotificationProcessor.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/MediaNotificationProcessor.java
index 2586e94..732c115 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/MediaNotificationProcessor.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/MediaNotificationProcessor.java
@@ -16,237 +16,30 @@
 
 package com.android.systemui.statusbar.notification;
 
-import android.app.Notification;
-import android.content.Context;
 import android.graphics.Bitmap;
-import android.graphics.Canvas;
 import android.graphics.Color;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.Icon;
-import android.util.LayoutDirection;
 
-import androidx.annotation.VisibleForTesting;
 import androidx.palette.graphics.Palette;
 
-import com.android.internal.util.ContrastColorUtil;
-import com.android.settingslib.Utils;
-
 import java.util.List;
 
 /**
- * A class the processes media notifications and extracts the right text and background colors.
+ * A gutted class that now contains only a color extraction utility used by the
+ * MediaArtworkProcessor, which has otherwise supplanted this.
+ *
+ * TODO(b/182926117): move this into MediaArtworkProcessor.kt
  */
 public class MediaNotificationProcessor {
 
     /**
-     * The fraction below which we select the vibrant instead of the light/dark vibrant color
-     */
-    private static final float POPULATION_FRACTION_FOR_MORE_VIBRANT = 1.0f;
-
-    /**
-     * Minimum saturation that a muted color must have if there exists if deciding between two
-     * colors
-     */
-    private static final float MIN_SATURATION_WHEN_DECIDING = 0.19f;
-
-    /**
-     * Minimum fraction that any color must have to be picked up as a text color
-     */
-    private static final double MINIMUM_IMAGE_FRACTION = 0.002;
-
-    /**
-     * The population fraction to select the dominant color as the text color over a the colored
-     * ones.
-     */
-    private static final float POPULATION_FRACTION_FOR_DOMINANT = 0.01f;
-
-    /**
      * The population fraction to select a white or black color as the background over a color.
      */
     private static final float POPULATION_FRACTION_FOR_WHITE_OR_BLACK = 2.5f;
     private static final float BLACK_MAX_LIGHTNESS = 0.08f;
     private static final float WHITE_MIN_LIGHTNESS = 0.90f;
     private static final int RESIZE_BITMAP_AREA = 150 * 150;
-    private final ImageGradientColorizer mColorizer;
-    private final Context mContext;
-    private final Palette.Filter mBlackWhiteFilter = (rgb, hsl) -> !isWhiteOrBlack(hsl);
 
-    /**
-     * The context of the notification. This is the app context of the package posting the
-     * notification.
-     */
-    private final Context mPackageContext;
-
-    public MediaNotificationProcessor(Context context, Context packageContext) {
-        this(context, packageContext, new ImageGradientColorizer());
-    }
-
-    @VisibleForTesting
-    MediaNotificationProcessor(Context context, Context packageContext,
-            ImageGradientColorizer colorizer) {
-        mContext = context;
-        mPackageContext = packageContext;
-        mColorizer = colorizer;
-    }
-
-    /**
-     * Processes a builder of a media notification and calculates the appropriate colors that should
-     * be used.
-     *
-     * @param notification the notification that is being processed
-     * @param builder the recovered builder for the notification. this will be modified
-     */
-    public void processNotification(Notification notification, Notification.Builder builder) {
-        Icon largeIcon = notification.getLargeIcon();
-        Bitmap bitmap = null;
-        Drawable drawable = null;
-        if (largeIcon != null) {
-            // We're transforming the builder, let's make sure all baked in RemoteViews are
-            // rebuilt!
-            builder.setRebuildStyledRemoteViews(true);
-            drawable = largeIcon.loadDrawable(mPackageContext);
-            int backgroundColor = 0;
-            if (notification.isColorizedMedia()) {
-                int width = drawable.getIntrinsicWidth();
-                int height = drawable.getIntrinsicHeight();
-                int area = width * height;
-                if (area > RESIZE_BITMAP_AREA) {
-                    double factor = Math.sqrt((float) RESIZE_BITMAP_AREA / area);
-                    width = (int) (factor * width);
-                    height = (int) (factor * height);
-                }
-                bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
-                Canvas canvas = new Canvas(bitmap);
-                drawable.setBounds(0, 0, width, height);
-                drawable.draw(canvas);
-
-                Palette.Builder paletteBuilder = generateArtworkPaletteBuilder(bitmap);
-                Palette palette = paletteBuilder.generate();
-                Palette.Swatch backgroundSwatch = findBackgroundSwatch(palette);
-                backgroundColor = backgroundSwatch.getRgb();
-                // we want most of the full region again, slightly shifted to the right
-                float textColorStartWidthFraction = 0.4f;
-                paletteBuilder.setRegion((int) (bitmap.getWidth() * textColorStartWidthFraction), 0,
-                        bitmap.getWidth(),
-                        bitmap.getHeight());
-                // We're not filtering on white or black
-                if (!isWhiteOrBlack(backgroundSwatch.getHsl())) {
-                    final float backgroundHue = backgroundSwatch.getHsl()[0];
-                    paletteBuilder.addFilter((rgb, hsl) -> {
-                        // at least 10 degrees hue difference
-                        float diff = Math.abs(hsl[0] - backgroundHue);
-                        return diff > 10 && diff < 350;
-                    });
-                }
-                paletteBuilder.addFilter(mBlackWhiteFilter);
-                palette = paletteBuilder.generate();
-                int foregroundColor = selectForegroundColor(backgroundColor, palette);
-                builder.setColorPalette(backgroundColor, foregroundColor);
-            } else {
-                backgroundColor = Utils.getColorAttr(mContext, android.R.attr.colorBackground)
-                        .getDefaultColor();
-            }
-            Bitmap colorized = mColorizer.colorize(drawable, backgroundColor,
-                    mContext.getResources().getConfiguration().getLayoutDirection() ==
-                            LayoutDirection.RTL);
-            builder.setLargeIcon(Icon.createWithBitmap(colorized));
-        }
-    }
-
-    /**
-     * Select a foreground color depending on whether the background color is dark or light
-     * @param backgroundColor Background color to coordinate with
-     * @param palette Artwork palette, should be obtained from {@link generateArtworkPaletteBuilder}
-     * @return foreground color
-     */
-    public static int selectForegroundColor(int backgroundColor, Palette palette) {
-        if (ContrastColorUtil.isColorLight(backgroundColor)) {
-            return selectForegroundColorForSwatches(palette.getDarkVibrantSwatch(),
-                    palette.getVibrantSwatch(),
-                    palette.getDarkMutedSwatch(),
-                    palette.getMutedSwatch(),
-                    palette.getDominantSwatch(),
-                    Color.BLACK);
-        } else {
-            return selectForegroundColorForSwatches(palette.getLightVibrantSwatch(),
-                    palette.getVibrantSwatch(),
-                    palette.getLightMutedSwatch(),
-                    palette.getMutedSwatch(),
-                    palette.getDominantSwatch(),
-                    Color.WHITE);
-        }
-    }
-
-    private static int selectForegroundColorForSwatches(Palette.Swatch moreVibrant,
-            Palette.Swatch vibrant, Palette.Swatch moreMutedSwatch, Palette.Swatch mutedSwatch,
-            Palette.Swatch dominantSwatch, int fallbackColor) {
-        Palette.Swatch coloredCandidate = selectVibrantCandidate(moreVibrant, vibrant);
-        if (coloredCandidate == null) {
-            coloredCandidate = selectMutedCandidate(mutedSwatch, moreMutedSwatch);
-        }
-        if (coloredCandidate != null) {
-            if (dominantSwatch == coloredCandidate) {
-                return coloredCandidate.getRgb();
-            } else if ((float) coloredCandidate.getPopulation() / dominantSwatch.getPopulation()
-                    < POPULATION_FRACTION_FOR_DOMINANT
-                    && dominantSwatch.getHsl()[1] > MIN_SATURATION_WHEN_DECIDING) {
-                return dominantSwatch.getRgb();
-            } else {
-                return coloredCandidate.getRgb();
-            }
-        } else if (hasEnoughPopulation(dominantSwatch)) {
-            return dominantSwatch.getRgb();
-        } else {
-            return fallbackColor;
-        }
-    }
-
-    private static Palette.Swatch selectMutedCandidate(Palette.Swatch first,
-            Palette.Swatch second) {
-        boolean firstValid = hasEnoughPopulation(first);
-        boolean secondValid = hasEnoughPopulation(second);
-        if (firstValid && secondValid) {
-            float firstSaturation = first.getHsl()[1];
-            float secondSaturation = second.getHsl()[1];
-            float populationFraction = first.getPopulation() / (float) second.getPopulation();
-            if (firstSaturation * populationFraction > secondSaturation) {
-                return first;
-            } else {
-                return second;
-            }
-        } else if (firstValid) {
-            return first;
-        } else if (secondValid) {
-            return second;
-        }
-        return null;
-    }
-
-    private static Palette.Swatch selectVibrantCandidate(Palette.Swatch first,
-            Palette.Swatch second) {
-        boolean firstValid = hasEnoughPopulation(first);
-        boolean secondValid = hasEnoughPopulation(second);
-        if (firstValid && secondValid) {
-            int firstPopulation = first.getPopulation();
-            int secondPopulation = second.getPopulation();
-            if (firstPopulation / (float) secondPopulation
-                    < POPULATION_FRACTION_FOR_MORE_VIBRANT) {
-                return second;
-            } else {
-                return first;
-            }
-        } else if (firstValid) {
-            return first;
-        } else if (secondValid) {
-            return second;
-        }
-        return null;
-    }
-
-    private static boolean hasEnoughPopulation(Palette.Swatch swatch) {
-        // We want a fraction that is at least 1% of the image
-        return swatch != null
-                && (swatch.getPopulation() / (float) RESIZE_BITMAP_AREA > MINIMUM_IMAGE_FRACTION);
+    private MediaNotificationProcessor() {
     }
 
     /**
@@ -279,7 +72,7 @@
         List<Palette.Swatch> swatches = palette.getSwatches();
         float highestNonWhitePopulation = -1;
         Palette.Swatch second = null;
-        for (Palette.Swatch swatch: swatches) {
+        for (Palette.Swatch swatch : swatches) {
             if (swatch != dominantSwatch
                     && swatch.getPopulation() > highestNonWhitePopulation
                     && !isWhiteOrBlack(swatch.getHsl())) {
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 6cf5c30..a3a4014 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
@@ -656,11 +656,6 @@
         boolean beforeN = mEntry.targetSdk < Build.VERSION_CODES.N;
         boolean beforeP = mEntry.targetSdk < Build.VERSION_CODES.P;
         boolean beforeS = mEntry.targetSdk < Build.VERSION_CODES.S;
-        if (Notification.DevFlags.shouldBackportSNotifRules(mContext.getContentResolver())) {
-            // When back-porting S rules, if an app targets P/Q/R then enforce the new S rule on
-            // that notification.  If it's before P though, we still want to enforce legacy rules.
-            beforeS = beforeP;
-        }
         int smallHeight;
 
         View expandedView = layout.getExpandedChild();
@@ -668,7 +663,6 @@
                 && expandedView.findViewById(com.android.internal.R.id.media_actions) != null;
         boolean isMessagingLayout = contractedView instanceof MessagingLayout;
         boolean isCallLayout = contractedView instanceof CallLayout;
-        boolean showCompactMediaSeekbar = mMediaManager.getShowCompactMediaSeekbar();
 
         if (customView && beforeS && !mIsSummaryWithChildren) {
             if (beforeN) {
@@ -678,12 +672,6 @@
             } else {
                 smallHeight = mMaxSmallHeightBeforeS;
             }
-        } else if (isMediaLayout) {
-            // TODO(b/172652345): MediaStyle notifications currently look broken when we enforce
-            //  the standard notification height, so we have to afford them more vertical space to
-            //  make sure we don't crop them terribly.  We actually need to revisit this and give
-            //  them a headerless design, then remove this hack.
-            smallHeight = showCompactMediaSeekbar ? mMaxSmallHeightMedia : mMaxSmallHeightBeforeS;
         } else if (isMessagingLayout) {
             // TODO(b/173204301): MessagingStyle notifications currently look broken when we enforce
             //  the standard notification height, so we have to afford them more vertical space to
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java
index 3ec8c23..4ed5056 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java
@@ -93,6 +93,13 @@
     @Override
     protected void onConfigurationChanged(Configuration newConfig) {
         super.onConfigurationChanged(newConfig);
+        mDismissButton.setBackground(
+                getResources().getDrawable(R.drawable.notif_footer_btn_background));
+        mDismissButton.setTextColor(getResources().getColor(R.color.notif_pill_text));
+        mManageButton.setBackground(
+                getResources().getDrawable(R.drawable.notif_footer_btn_background));
+        mManageButton.setTextColor(getResources().getColor(R.color.notif_pill_text));
+        mManageButton = findViewById(R.id.manage_text);
         mDismissButton.setText(R.string.clear_all_notifications_text);
         mDismissButton.setContentDescription(
                 mContext.getString(R.string.accessibility_clear_all));
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 58b87cd..73c4b05 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
@@ -40,13 +40,11 @@
 import com.android.internal.widget.ImageMessageConsumer;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Background;
-import com.android.systemui.media.MediaDataManagerKt;
 import com.android.systemui.media.MediaFeatureFlag;
 import com.android.systemui.statusbar.InflationTask;
 import com.android.systemui.statusbar.NotificationRemoteInputManager;
 import com.android.systemui.statusbar.notification.ConversationNotificationProcessor;
 import com.android.systemui.statusbar.notification.InflationException;
-import com.android.systemui.statusbar.notification.MediaNotificationProcessor;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewWrapper;
 import com.android.systemui.statusbar.phone.StatusBar;
@@ -799,13 +797,6 @@
                     // For all of our templates, we want it to be RTL
                     packageContext = new RtlEnabledContext(packageContext);
                 }
-                Notification notification = sbn.getNotification();
-                if (notification.isMediaNotification() && !(mIsMediaInQS
-                        && MediaDataManagerKt.isMediaNotification(sbn))) {
-                    MediaNotificationProcessor processor = new MediaNotificationProcessor(mContext,
-                            packageContext);
-                    processor.processNotification(notification, recoveredBuilder);
-                }
                 if (mEntry.getRanking().isConversation()) {
                     mConversationProcessor.processNotification(mEntry, recoveredBuilder);
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
index 55a27b2..c3ccba4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
@@ -1291,9 +1291,14 @@
                     }
                 }
             }
-
-            if (existing != null && entry.getSbn().getNotification().isColorized()) {
-                existing.overrideBackgroundTintColor(entry.getSbn().getNotification().color);
+            if (existing != null) {
+                if (entry.getSbn().getNotification().isColorized()) {
+                    existing.setBackgroundTintColor(
+                            entry.getSbn().getNotification().color, true);
+                } else {
+                    existing.setBackgroundTintColor(
+                            entry.getRow().getCurrentBackgroundTint(), false);
+                }
             }
             return existing;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java
index 2535e5d..c75cd78 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java
@@ -16,341 +16,26 @@
 
 package com.android.systemui.statusbar.notification.row.wrapper;
 
-import static com.android.systemui.Dependency.MAIN_HANDLER;
-
-import android.annotation.Nullable;
-import android.app.Notification;
 import android.content.Context;
-import android.content.res.ColorStateList;
-import android.media.MediaMetadata;
-import android.media.session.MediaController;
-import android.media.session.MediaSession;
-import android.media.session.PlaybackState;
-import android.metrics.LogMaker;
-import android.os.Handler;
-import android.text.format.DateUtils;
-import android.view.LayoutInflater;
 import android.view.View;
-import android.view.ViewStub;
-import android.widget.SeekBar;
-import android.widget.TextView;
 
-import com.android.internal.R;
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.internal.widget.MediaNotificationView;
-import com.android.systemui.Dependency;
-import com.android.systemui.statusbar.NotificationMediaManager;
 import com.android.systemui.statusbar.TransformableView;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 
-import java.util.Timer;
-import java.util.TimerTask;
-
 /**
  * Wraps a notification containing a media template
  */
 public class NotificationMediaTemplateViewWrapper extends NotificationTemplateViewWrapper {
 
-    private static final long PROGRESS_UPDATE_INTERVAL = 1000; // 1s
-    private static final String COMPACT_MEDIA_TAG = "media";
-    private final Handler mHandler = Dependency.get(MAIN_HANDLER);
-    private Timer mSeekBarTimer;
     private View mActions;
-    private SeekBar mSeekBar;
-    private TextView mSeekBarElapsedTime;
-    private TextView mSeekBarTotalTime;
-    private long mDuration = 0;
-    private MediaController mMediaController;
-    private MediaMetadata mMediaMetadata;
-    private NotificationMediaManager mMediaManager;
-    private View mSeekBarView;
-    private Context mContext;
-    private MetricsLogger mMetricsLogger;
-    private boolean mIsViewVisible;
-
-    @VisibleForTesting
-    protected SeekBar.OnSeekBarChangeListener mSeekListener =
-            new SeekBar.OnSeekBarChangeListener() {
-        @Override
-        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
-        }
-
-        @Override
-        public void onStartTrackingTouch(SeekBar seekBar) {
-        }
-
-        @Override
-        public void onStopTrackingTouch(SeekBar seekBar) {
-            if (mMediaController != null) {
-                mMediaController.getTransportControls().seekTo(mSeekBar.getProgress());
-                mMetricsLogger.write(newLog(MetricsEvent.TYPE_UPDATE));
-            }
-        }
-    };
-
-    private MediaNotificationView.VisibilityChangeListener mVisibilityListener =
-            new MediaNotificationView.VisibilityChangeListener() {
-        @Override
-        public void onAggregatedVisibilityChanged(boolean isVisible) {
-            mIsViewVisible = isVisible;
-            if (isVisible && mMediaController != null) {
-                // Restart timer if we're currently playing and didn't already have one going
-                PlaybackState state = mMediaController.getPlaybackState();
-                if (state != null && state.getState() == PlaybackState.STATE_PLAYING
-                        && mSeekBarTimer == null && mSeekBarView != null
-                        && mSeekBarView.getVisibility() != View.GONE) {
-                    startTimer();
-                }
-            } else {
-                clearTimer();
-            }
-        }
-    };
-
-    private View.OnAttachStateChangeListener mAttachStateListener =
-            new View.OnAttachStateChangeListener() {
-        @Override
-        public void onViewAttachedToWindow(View v) {
-        }
-
-        @Override
-        public void onViewDetachedFromWindow(View v) {
-            mIsViewVisible = false;
-        }
-    };
-
-    private MediaController.Callback mMediaCallback = new MediaController.Callback() {
-        @Override
-        public void onSessionDestroyed() {
-            clearTimer();
-            mMediaController.unregisterCallback(this);
-            if (mView instanceof MediaNotificationView) {
-                ((MediaNotificationView) mView).removeVisibilityListener(mVisibilityListener);
-                mView.removeOnAttachStateChangeListener(mAttachStateListener);
-            }
-        }
-
-        @Override
-        public void onPlaybackStateChanged(@Nullable PlaybackState state) {
-            if (state == null) {
-                return;
-            }
-
-            if (state.getState() != PlaybackState.STATE_PLAYING) {
-                // Update the UI once, in case playback info changed while we were paused
-                updatePlaybackUi(state);
-                clearTimer();
-            } else if (mSeekBarTimer == null && mSeekBarView != null
-                    && mSeekBarView.getVisibility() != View.GONE) {
-                startTimer();
-            }
-        }
-
-        @Override
-        public void onMetadataChanged(@Nullable MediaMetadata metadata) {
-            if (mMediaMetadata == null || !mMediaMetadata.equals(metadata)) {
-                mMediaMetadata = metadata;
-                updateDuration();
-            }
-        }
-    };
 
     protected NotificationMediaTemplateViewWrapper(Context ctx, View view,
             ExpandableNotificationRow row) {
         super(ctx, view, row);
-        mContext = ctx;
-        mMediaManager = Dependency.get(NotificationMediaManager.class);
-        mMetricsLogger = Dependency.get(MetricsLogger.class);
     }
 
     private void resolveViews() {
         mActions = mView.findViewById(com.android.internal.R.id.media_actions);
-        mIsViewVisible = mView.isShown();
-
-        final MediaSession.Token token = mRow.getEntry().getSbn().getNotification().extras
-                .getParcelable(Notification.EXTRA_MEDIA_SESSION);
-
-        boolean showCompactSeekbar = mMediaManager.getShowCompactMediaSeekbar();
-        if (token == null || (COMPACT_MEDIA_TAG.equals(mView.getTag()) && !showCompactSeekbar)) {
-            if (mSeekBarView != null) {
-                mSeekBarView.setVisibility(View.GONE);
-            }
-            return;
-        }
-
-        // Check for existing media controller and clean up / create as necessary
-        boolean shouldUpdateListeners = false;
-        if (mMediaController == null || !mMediaController.getSessionToken().equals(token)) {
-            if (mMediaController != null) {
-                mMediaController.unregisterCallback(mMediaCallback);
-            }
-            mMediaController = new MediaController(mContext, token);
-            shouldUpdateListeners = true;
-        }
-
-        mMediaMetadata = mMediaController.getMetadata();
-        if (mMediaMetadata != null) {
-            long duration = mMediaMetadata.getLong(MediaMetadata.METADATA_KEY_DURATION);
-            if (duration <= 0) {
-                // Don't include the seekbar if this is a livestream
-                if (mSeekBarView != null && mSeekBarView.getVisibility() != View.GONE) {
-                    mSeekBarView.setVisibility(View.GONE);
-                    mMetricsLogger.write(newLog(MetricsEvent.TYPE_CLOSE));
-                    clearTimer();
-                } else if (mSeekBarView == null && shouldUpdateListeners) {
-                    // Only log if the controller changed, otherwise we would log multiple times for
-                    // the same notification when user pauses/resumes
-                    mMetricsLogger.write(newLog(MetricsEvent.TYPE_CLOSE));
-                }
-                return;
-            } else if (mSeekBarView != null && mSeekBarView.getVisibility() == View.GONE) {
-                // Otherwise, make sure the seekbar is visible
-                mSeekBarView.setVisibility(View.VISIBLE);
-                mMetricsLogger.write(newLog(MetricsEvent.TYPE_OPEN));
-                updateDuration();
-                startTimer();
-            }
-        }
-
-        // Inflate the seekbar template
-        ViewStub stub = mView.findViewById(R.id.notification_media_seekbar_container);
-        if (stub instanceof ViewStub) {
-            LayoutInflater layoutInflater = LayoutInflater.from(stub.getContext());
-            stub.setLayoutInflater(layoutInflater);
-            stub.setLayoutResource(R.layout.notification_material_media_seekbar);
-            mSeekBarView = stub.inflate();
-            mMetricsLogger.write(newLog(MetricsEvent.TYPE_OPEN));
-
-            mSeekBar = mSeekBarView.findViewById(R.id.notification_media_progress_bar);
-            mSeekBar.setOnSeekBarChangeListener(mSeekListener);
-
-            mSeekBarElapsedTime = mSeekBarView.findViewById(R.id.notification_media_elapsed_time);
-            mSeekBarTotalTime = mSeekBarView.findViewById(R.id.notification_media_total_time);
-
-            shouldUpdateListeners = true;
-        }
-
-        if (shouldUpdateListeners) {
-            if (mView instanceof MediaNotificationView) {
-                MediaNotificationView mediaView = (MediaNotificationView) mView;
-                mediaView.addVisibilityListener(mVisibilityListener);
-                mView.addOnAttachStateChangeListener(mAttachStateListener);
-            }
-
-            if (mSeekBarTimer == null) {
-                if (mMediaController != null && canSeekMedia(mMediaController.getPlaybackState())) {
-                    // Log initial state, since it will not be updated
-                    mMetricsLogger.write(newLog(MetricsEvent.TYPE_DETAIL, 1));
-                } else {
-                    setScrubberVisible(false);
-                }
-                updateDuration();
-                startTimer();
-                mMediaController.registerCallback(mMediaCallback);
-            }
-        }
-        updateSeekBarTint(mSeekBarView);
-    }
-
-    private void startTimer() {
-        clearTimer();
-        if (mIsViewVisible) {
-            mSeekBarTimer = new Timer(true /* isDaemon */);
-            mSeekBarTimer.schedule(new TimerTask() {
-                @Override
-                public void run() {
-                    mHandler.post(mOnUpdateTimerTick);
-                }
-            }, 0, PROGRESS_UPDATE_INTERVAL);
-        }
-    }
-
-    private void clearTimer() {
-        if (mSeekBarTimer != null) {
-            mSeekBarTimer.cancel();
-            mSeekBarTimer.purge();
-            mSeekBarTimer = null;
-        }
-    }
-
-    @Override
-    public void setRemoved() {
-        clearTimer();
-        if (mMediaController != null) {
-            mMediaController.unregisterCallback(mMediaCallback);
-        }
-        if (mView instanceof MediaNotificationView) {
-            ((MediaNotificationView) mView).removeVisibilityListener(mVisibilityListener);
-            mView.removeOnAttachStateChangeListener(mAttachStateListener);
-        }
-    }
-
-    private boolean canSeekMedia(@Nullable PlaybackState state) {
-        if (state == null) {
-            return false;
-        }
-
-        long actions = state.getActions();
-        return ((actions & PlaybackState.ACTION_SEEK_TO) != 0);
-    }
-
-    private void setScrubberVisible(boolean isVisible) {
-        if (mSeekBar == null || mSeekBar.isEnabled() == isVisible) {
-            return;
-        }
-
-        mSeekBar.getThumb().setAlpha(isVisible ? 255 : 0);
-        mSeekBar.setEnabled(isVisible);
-        mMetricsLogger.write(newLog(MetricsEvent.TYPE_DETAIL, isVisible ? 1 : 0));
-    }
-
-    private void updateDuration() {
-        if (mMediaMetadata != null && mSeekBar != null) {
-            long duration = mMediaMetadata.getLong(MediaMetadata.METADATA_KEY_DURATION);
-            if (mDuration != duration) {
-                mDuration = duration;
-                mSeekBar.setMax((int) mDuration);
-                mSeekBarTotalTime.setText(millisecondsToTimeString(duration));
-            }
-        }
-    }
-
-    protected final Runnable mOnUpdateTimerTick = new Runnable() {
-        @Override
-        public void run() {
-            if (mMediaController != null && mSeekBar != null) {
-                PlaybackState playbackState = mMediaController.getPlaybackState();
-                if (playbackState != null) {
-                    updatePlaybackUi(playbackState);
-                } else {
-                    clearTimer();
-                }
-            } else {
-                clearTimer();
-            }
-        }
-    };
-
-    private void updatePlaybackUi(PlaybackState state) {
-        if (mSeekBar == null || mSeekBarElapsedTime == null) {
-            return;
-        }
-
-        long position = state.getPosition();
-        mSeekBar.setProgress((int) position);
-
-        mSeekBarElapsedTime.setText(millisecondsToTimeString(position));
-
-        // Update scrubber in case available actions have changed
-        setScrubberVisible(canSeekMedia(state));
-    }
-
-    private String millisecondsToTimeString(long milliseconds) {
-        long seconds = milliseconds / 1000;
-        String text = DateUtils.formatElapsedTime(seconds);
-        return text;
     }
 
     @Override
@@ -361,28 +46,6 @@
         super.onContentUpdated(row);
     }
 
-    private void updateSeekBarTint(View seekBarContainer) {
-        if (seekBarContainer == null) {
-            return;
-        }
-
-        if (this.getNotificationHeader() == null) {
-            return;
-        }
-
-        int tintColor = getOriginalIconColor();
-        mSeekBarElapsedTime.setTextColor(tintColor);
-        mSeekBarTotalTime.setTextColor(tintColor);
-        mSeekBarTotalTime.setShadowLayer(1.5f, 1.5f, 1.5f, mBackgroundColor);
-
-        ColorStateList tintList = ColorStateList.valueOf(tintColor);
-        mSeekBar.setThumbTintList(tintList);
-        tintList = tintList.withAlpha(192); // 75%
-        mSeekBar.setProgressTintList(tintList);
-        tintList = tintList.withAlpha(128); // 50%
-        mSeekBar.setProgressBackgroundTintList(tintList);
-    }
-
     @Override
     protected void updateTransformedTypes() {
         // This also clears the existing types
@@ -394,36 +57,7 @@
     }
 
     @Override
-    public boolean isDimmable() {
-        return getCustomBackgroundColor() == 0;
-    }
-
-    @Override
     public boolean shouldClipToRounding(boolean topRounded, boolean bottomRounded) {
         return true;
     }
-
-    /**
-     * Returns an initialized LogMaker for logging changes to the seekbar
-     * @return new LogMaker
-     */
-    private LogMaker newLog(int event) {
-        String packageName = mRow.getEntry().getSbn().getPackageName();
-
-        return new LogMaker(MetricsEvent.MEDIA_NOTIFICATION_SEEKBAR)
-                .setType(event)
-                .setPackageName(packageName);
-    }
-
-    /**
-     * Returns an initialized LogMaker for logging changes with subtypes
-     * @return new LogMaker
-     */
-    private LogMaker newLog(int event, int subtype) {
-        String packageName = mRow.getEntry().getSbn().getPackageName();
-        return new LogMaker(MetricsEvent.MEDIA_NOTIFICATION_SEEKBAR)
-                .setType(event)
-                .setSubtype(subtype)
-                .setPackageName(packageName);
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
index 39f5847c..562d0ec 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
@@ -42,6 +42,9 @@
 import com.android.systemui.statusbar.policy.NetworkController;
 import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
 
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * Contains the collapsed status bar and handles hiding/showing based on disable flags
  * and keyguard state. Also manages lifecycle to make sure the views it contains are being
@@ -70,6 +73,8 @@
     private View mOperatorNameFrame;
     private CommandQueue mCommandQueue;
 
+    private List<String> mBlockedIcons = new ArrayList<>();
+
     private SignalCallback mSignalCallback = new SignalCallback() {
         @Override
         public void setIsAirplaneMode(NetworkController.IconState icon) {
@@ -101,9 +106,12 @@
             mStatusBar.restoreHierarchyState(
                     savedInstanceState.getSparseParcelableArray(EXTRA_PANEL_STATE));
         }
-        mDarkIconManager = new DarkIconManager(view.findViewById(R.id.statusIcons),
-                Dependency.get(CommandQueue.class));
+        mDarkIconManager = new DarkIconManager(view.findViewById(R.id.statusIcons));
         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);
         Dependency.get(StatusBarIconController.class).addIconGroup(mDarkIconManager);
         mSystemIconArea = mStatusBar.findViewById(R.id.system_icon_area);
         mClockView = mStatusBar.findViewById(R.id.clock);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
index 33798d6..2d760e6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
@@ -47,7 +47,6 @@
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
 import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
-import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.phone.StatusBarIconController.TintedIconManager;
 import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
@@ -59,6 +58,8 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * The header group on Keyguard.
@@ -89,6 +90,7 @@
     private int mSystemIconsBaseMargin;
     private View mSystemIconsContainer;
     private TintedIconManager mIconManager;
+    private List<String> mBlockedIcons = new ArrayList<>();
 
     private View mCutoutSpace;
     private ViewGroup mStatusIconArea;
@@ -121,6 +123,7 @@
         mStatusIconContainer = findViewById(R.id.statusIcons);
 
         loadDimens();
+        loadBlockList();
         mBatteryController = Dependency.get(BatteryController.class);
     }
 
@@ -181,6 +184,14 @@
                 R.dimen.rounded_corner_content_padding);
     }
 
+    // Set hidden status bar items
+    private void loadBlockList() {
+        Resources r = getResources();
+        mBlockedIcons.add(r.getString(com.android.internal.R.string.status_bar_volume));
+        mBlockedIcons.add(r.getString(com.android.internal.R.string.status_bar_alarm_clock));
+        mBlockedIcons.add(r.getString(com.android.internal.R.string.status_bar_call_strength));
+    }
+
     private void updateVisibilities() {
         if (mMultiUserAvatar.getParent() != mStatusIconArea
                 && !mKeyguardUserSwitcherEnabled) {
@@ -336,8 +347,8 @@
         userInfoController.addCallback(this);
         userInfoController.reloadUserInfo();
         Dependency.get(ConfigurationController.class).addCallback(this);
-        mIconManager = new TintedIconManager(findViewById(R.id.statusIcons),
-                Dependency.get(CommandQueue.class));
+        mIconManager = new TintedIconManager(findViewById(R.id.statusIcons));
+        mIconManager.setBlockList(mBlockedIcons);
         Dependency.get(StatusBarIconController.class).addIconGroup(mIconManager);
         onThemeChanged();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
new file mode 100644
index 0000000..377fb92
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
@@ -0,0 +1,48 @@
+/*
+ * 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.phone;
+
+import com.android.keyguard.CarrierTextController;
+import com.android.systemui.util.ViewController;
+
+import javax.inject.Inject;
+
+/** View Controller for {@link com.android.systemui.statusbar.phone.KeyguardStatusBarView}. */
+public class KeyguardStatusBarViewController extends ViewController<KeyguardStatusBarView> {
+    private final CarrierTextController mCarrierTextController;
+
+    @Inject
+    public KeyguardStatusBarViewController(
+            KeyguardStatusBarView view, CarrierTextController carrierTextController) {
+        super(view);
+        mCarrierTextController = carrierTextController;
+    }
+
+    @Override
+    protected void onInit() {
+        super.onInit();
+        mCarrierTextController.init();
+    }
+
+    @Override
+    protected void onViewAttached() {
+    }
+
+    @Override
+    protected void onViewDetached() {
+    }
+}
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 4ef6668..d3da0bce 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -83,6 +83,7 @@
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
 import com.android.keyguard.dagger.KeyguardQsUserSwitchComponent;
+import com.android.keyguard.dagger.KeyguardStatusBarViewComponent;
 import com.android.keyguard.dagger.KeyguardStatusViewComponent;
 import com.android.keyguard.dagger.KeyguardUserSwitcherComponent;
 import com.android.systemui.DejankUtils;
@@ -298,6 +299,7 @@
     private final KeyguardStatusViewComponent.Factory mKeyguardStatusViewComponentFactory;
     private final KeyguardQsUserSwitchComponent.Factory mKeyguardQsUserSwitchComponentFactory;
     private final KeyguardUserSwitcherComponent.Factory mKeyguardUserSwitcherComponentFactory;
+    private final KeyguardStatusBarViewComponent.Factory mKeyguardStatusBarViewComponentFactory;
     private final QSDetailDisplayer mQSDetailDisplayer;
     private final FeatureFlags mFeatureFlags;
     private final ScrimController mScrimController;
@@ -313,6 +315,7 @@
     private KeyguardQsUserSwitchController mKeyguardQsUserSwitchController;
     private KeyguardUserSwitcherController mKeyguardUserSwitcherController;
     private KeyguardStatusBarView mKeyguardStatusBar;
+    private KeyguardStatusBarViewController mKeyguarStatusBarViewController;
     private ViewGroup mBigClockContainer;
     private QS mQs;
     private FrameLayout mQsFrame;
@@ -565,6 +568,7 @@
             KeyguardStatusViewComponent.Factory keyguardStatusViewComponentFactory,
             KeyguardQsUserSwitchComponent.Factory keyguardQsUserSwitchComponentFactory,
             KeyguardUserSwitcherComponent.Factory keyguardUserSwitcherComponentFactory,
+            KeyguardStatusBarViewComponent.Factory keyguardStatusBarViewComponentFactory,
             QSDetailDisplayer qsDetailDisplayer,
             NotificationGroupManagerLegacy groupManager,
             NotificationIconAreaController notificationIconAreaController,
@@ -589,6 +593,7 @@
         mGroupManager = groupManager;
         mNotificationIconAreaController = notificationIconAreaController;
         mKeyguardStatusViewComponentFactory = keyguardStatusViewComponentFactory;
+        mKeyguardStatusBarViewComponentFactory = keyguardStatusBarViewComponentFactory;
         mFeatureFlags = featureFlags;
         mKeyguardQsUserSwitchComponentFactory = keyguardQsUserSwitchComponentFactory;
         mKeyguardUserSwitcherComponentFactory = keyguardUserSwitcherComponentFactory;
@@ -693,7 +698,9 @@
         }
 
         updateViewControllers(mView.findViewById(R.id.keyguard_status_view),
-                userAvatarView, keyguardUserSwitcherView);
+                userAvatarView,
+                mKeyguardStatusBar,
+                keyguardUserSwitcherView);
         mNotificationContainerParent = mView.findViewById(R.id.notification_container_parent);
         NotificationStackScrollLayout stackScrollLayout = mView.findViewById(
                 R.id.notification_stack_scroller);
@@ -773,13 +780,21 @@
     }
 
     private void updateViewControllers(KeyguardStatusView keyguardStatusView,
-            UserAvatarView userAvatarView, KeyguardUserSwitcherView keyguardUserSwitcherView) {
+            UserAvatarView userAvatarView,
+            KeyguardStatusBarView keyguardStatusBarView,
+            KeyguardUserSwitcherView keyguardUserSwitcherView) {
         // Re-associate the KeyguardStatusViewController
         KeyguardStatusViewComponent statusViewComponent =
                 mKeyguardStatusViewComponentFactory.build(keyguardStatusView);
         mKeyguardStatusViewController = statusViewComponent.getKeyguardStatusViewController();
         mKeyguardStatusViewController.init();
 
+        KeyguardStatusBarViewComponent statusBarViewComponent =
+                mKeyguardStatusBarViewComponentFactory.build(keyguardStatusBarView);
+        mKeyguarStatusBarViewController =
+                statusBarViewComponent.getKeyguardStatusBarViewController();
+        mKeyguarStatusBarViewController.init();
+
         // Re-associate the clock container with the keyguard clock switch.
         KeyguardClockSwitchController keyguardClockSwitchController =
                 statusViewComponent.getKeyguardClockSwitchController();
@@ -919,7 +934,8 @@
                         showKeyguardUserSwitcher /* enabled */);
 
         mBigClockContainer.removeAllViews();
-        updateViewControllers(keyguardStatusView, userAvatarView, keyguardUserSwitcherView);
+        updateViewControllers(
+                keyguardStatusView, userAvatarView, mKeyguardStatusBar, keyguardUserSwitcherView);
 
         // Update keyguard bottom area
         index = mView.indexOfChild(mKeyguardBottomArea);
@@ -1325,6 +1341,9 @@
         traceQsJank(true /* startTracing */, false /* wasCancelled */);
         flingSettings(0 /* velocity */, FLING_EXPAND);
         mQSDetailDisplayer.showDetailAdapter(qsDetailAdapter, 0, 0);
+        if (mAccessibilityManager.isEnabled()) {
+            mView.setAccessibilityPaneTitle(determineAccessibilityPaneTitle());
+        }
     }
 
     public void expandWithoutQs() {
@@ -1824,6 +1843,7 @@
             mNotificationContainerParent.setQsExpanded(expanded);
             mPulseExpansionHandler.setQsExpanded(expanded);
             mKeyguardBypassController.setQSExpanded(expanded);
+            mStatusBarKeyguardViewManager.setQsExpanded(expanded);
         }
     }
 
@@ -3389,7 +3409,7 @@
         return new TouchHandler() {
             @Override
             public boolean onInterceptTouchEvent(MotionEvent event) {
-                if (mStatusBarKeyguardViewManager.isShowingAlternativeAuthOrAnimating()) {
+                if (mStatusBarKeyguardViewManager.isShowingAlternateAuthOrAnimating()) {
                     return true;
                 }
                 if (mBlockTouches || mQsFullyExpanded && mQs.disallowPanelTouches()) {
@@ -3420,8 +3440,8 @@
             @Override
             public boolean onTouch(View v, MotionEvent event) {
                 final boolean showingOrAnimatingAltAuth =
-                        mStatusBarKeyguardViewManager.isShowingAlternativeAuthOrAnimating();
-                if (showingOrAnimatingAltAuth) {
+                        mStatusBarKeyguardViewManager.isShowingAlternateAuthOrAnimating();
+                if (showingOrAnimatingAltAuth && event.getAction() == MotionEvent.ACTION_DOWN) {
                     mStatusBarKeyguardViewManager.resetAlternateAuth();
                 }
 
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 ed4f324..77abe79 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
@@ -454,7 +454,7 @@
                 mView.postOnAnimation(mPostCollapseRunnable);
             }
         } else if (!mStatusBar.isBouncerShowing()
-                && !mStatusBarKeyguardViewManager.isShowingAlternativeAuthOrAnimating()) {
+                && !mStatusBarKeyguardViewManager.isShowingAlternateAuthOrAnimating()) {
             boolean expands = onEmptySpaceClick(mInitialTouchX);
             onTrackingStopped(expands);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 0e1fe22..d581c4b6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -184,7 +184,6 @@
 import com.android.systemui.statusbar.BackDropView;
 import com.android.systemui.statusbar.CircleReveal;
 import com.android.systemui.statusbar.CommandQueue;
-import com.android.systemui.statusbar.CrossFadeHelper;
 import com.android.systemui.statusbar.FeatureFlags;
 import com.android.systemui.statusbar.GestureRecorder;
 import com.android.systemui.statusbar.KeyboardShortcuts;
@@ -2469,39 +2468,19 @@
 
     protected void showChargingAnimation(int batteryLevel, int transmittingBatteryLevel,
             long animationDelay) {
-        if (mDozing || mKeyguardManager.isKeyguardLocked()) {
-            // on ambient or lockscreen, hide notification panel
-            WirelessChargingAnimation.makeWirelessChargingAnimation(mContext, null,
-                    transmittingBatteryLevel, batteryLevel,
-                    new WirelessChargingAnimation.Callback() {
-                        @Override
-                        public void onAnimationStarting() {
-                            mNotificationShadeWindowController.setRequestTopUi(true, TAG);
-                            CrossFadeHelper.fadeOut(mNotificationPanelViewController.getView(), 1);
-                        }
+        WirelessChargingAnimation.makeWirelessChargingAnimation(mContext, null,
+                transmittingBatteryLevel, batteryLevel,
+                new WirelessChargingAnimation.Callback() {
+                    @Override
+                    public void onAnimationStarting() {
+                        mNotificationShadeWindowController.setRequestTopUi(true, TAG);
+                    }
 
-                        @Override
-                        public void onAnimationEnded() {
-                            CrossFadeHelper.fadeIn(mNotificationPanelViewController.getView());
-                            mNotificationShadeWindowController.setRequestTopUi(false, TAG);
-                        }
-                    }, mDozing).show(animationDelay);
-        } else {
-            // workspace
-            WirelessChargingAnimation.makeWirelessChargingAnimation(mContext, null,
-                    transmittingBatteryLevel, batteryLevel,
-                    new WirelessChargingAnimation.Callback() {
-                        @Override
-                        public void onAnimationStarting() {
-                            mNotificationShadeWindowController.setRequestTopUi(true, TAG);
-                        }
-
-                        @Override
-                        public void onAnimationEnded() {
-                            mNotificationShadeWindowController.setRequestTopUi(false, TAG);
-                        }
-                    }, false).show(animationDelay);
-        }
+                    @Override
+                    public void onAnimationEnded() {
+                        mNotificationShadeWindowController.setRequestTopUi(false, TAG);
+                    }
+                }, false).show(animationDelay);
     }
 
     @Override
@@ -4224,7 +4203,7 @@
                 mNotificationPanelViewController.isLaunchingAffordanceWithPreview();
         mScrimController.setLaunchingAffordanceWithPreview(launchingAffordanceWithPreview);
 
-        if (mStatusBarKeyguardViewManager.isShowingAlternativeAuth()) {
+        if (mStatusBarKeyguardViewManager.isShowingAlternateAuth()) {
             mScrimController.transitionTo(ScrimState.AUTH_SCRIMMED);
         } else if (mBouncerShowing) {
             // Bouncer needs the front scrim when it's on top of an activity,
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 8fe9a48..93b83d3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
@@ -18,6 +18,7 @@
 import static com.android.systemui.statusbar.phone.StatusBarIconHolder.TYPE_MOBILE;
 import static com.android.systemui.statusbar.phone.StatusBarIconHolder.TYPE_WIFI;
 
+import android.annotation.Nullable;
 import android.content.Context;
 import android.os.Bundle;
 import android.text.TextUtils;
@@ -37,7 +38,6 @@
 import com.android.systemui.demomode.DemoModeCommandReceiver;
 import com.android.systemui.plugins.DarkIconDispatcher;
 import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
-import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.StatusBarIconView;
 import com.android.systemui.statusbar.StatusBarMobileView;
 import com.android.systemui.statusbar.StatusBarWifiView;
@@ -46,6 +46,7 @@
 import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.MobileIconState;
 import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.WifiIconState;
 
+import java.util.ArrayList;
 import java.util.List;
 
 public interface StatusBarIconController {
@@ -54,15 +55,22 @@
      * When an icon is added with TAG_PRIMARY, it will be treated as the primary icon
      * in that slot and not added as a sub slot.
      */
-    public static final int TAG_PRIMARY = 0;
+    int TAG_PRIMARY = 0;
 
-    public void addIconGroup(IconManager iconManager);
-    public void removeIconGroup(IconManager iconManager);
-    public void setExternalIcon(String slot);
-    public void setIcon(String slot, int resourceId, CharSequence contentDescription);
-    public void setIcon(String slot, StatusBarIcon icon);
-    public void setSignalIcon(String slot, WifiIconState state);
-    public void setMobileIcons(String slot, List<MobileIconState> states);
+    /** */
+    void addIconGroup(IconManager iconManager);
+    /** */
+    void removeIconGroup(IconManager iconManager);
+    /** */
+    void setExternalIcon(String slot);
+    /** */
+    void setIcon(String slot, int resourceId, CharSequence contentDescription);
+    /** */
+    void setIcon(String slot, StatusBarIcon icon);
+    /** */
+    void setSignalIcon(String slot, WifiIconState state);
+    /** */
+    void setMobileIcons(String slot, List<MobileIconState> states);
     /**
      * Display the no calling & SMS icons.
      */
@@ -85,8 +93,9 @@
      * If you don't know what to pass for `tag`, either remove all icons for slot, or use
      * TAG_PRIMARY to refer to the first icon at a given slot.
      */
-    public void removeIcon(String slot, int tag);
-    public void removeAllIconsForSlot(String slot);
+    void removeIcon(String slot, int tag);
+    /** */
+    void removeAllIconsForSlot(String slot);
 
     // TODO: See if we can rename this tunable name.
     String ICON_HIDE_LIST = "icon_blacklist";
@@ -108,12 +117,12 @@
     /**
      * Version of ViewGroup that observes state from the DarkIconDispatcher.
      */
-    public static class DarkIconManager extends IconManager {
+    class DarkIconManager extends IconManager {
         private final DarkIconDispatcher mDarkIconDispatcher;
         private int mIconHPadding;
 
-        public DarkIconManager(LinearLayout linearLayout, CommandQueue commandQueue) {
-            super(linearLayout, commandQueue);
+        public DarkIconManager(LinearLayout linearLayout) {
+            super(linearLayout);
             mIconHPadding = mContext.getResources().getDimensionPixelSize(
                     R.dimen.status_bar_icon_padding);
             mDarkIconDispatcher = Dependency.get(DarkIconDispatcher.class);
@@ -169,11 +178,12 @@
         }
     }
 
-    public static class TintedIconManager extends IconManager {
+    /** */
+    class TintedIconManager extends IconManager {
         private int mColor;
 
-        public TintedIconManager(ViewGroup group, CommandQueue commandQueue) {
-            super(group, commandQueue);
+        public TintedIconManager(ViewGroup group) {
+            super(group);
         }
 
         @Override
@@ -219,7 +229,9 @@
         private boolean mIsInDemoMode;
         protected DemoStatusIcons mDemoStatusIcons;
 
-        public IconManager(ViewGroup group, CommandQueue commandQueue) {
+        protected ArrayList<String> mBlockList = new ArrayList<>();
+
+        public IconManager(ViewGroup group) {
             mGroup = group;
             mContext = group.getContext();
             mIconSize = mContext.getResources().getDimensionPixelSize(
@@ -234,6 +246,15 @@
             mDemoable = demoable;
         }
 
+        public void setBlockList(@Nullable List<String> blockList) {
+            mBlockList.clear();
+            if (blockList == null || blockList.isEmpty()) {
+                return;
+            }
+
+            mBlockList.addAll(blockList);
+        }
+
         public void setShouldLog(boolean should) {
             mShouldLog = should;
         }
@@ -249,6 +270,11 @@
 
         protected StatusIconDisplayable addHolder(int index, String slot, boolean blocked,
                 StatusBarIconHolder holder) {
+            // This is a little hacky, and probably regrettable, but just set `blocked` on any icon
+            // that is in our blocked list, then we'll never see it
+            if (mBlockList.contains(slot)) {
+                blocked = true;
+            }
             switch (holder.getType()) {
                 case TYPE_ICON:
                     return addIcon(index, slot, blocked, holder.getIcon());
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 6404aea..75900a2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
@@ -66,6 +66,7 @@
 
     private Context mContext;
 
+    /** */
     @Inject
     public StatusBarIconControllerImpl(
             Context context,
@@ -84,6 +85,7 @@
         demoModeController.addCallback(this);
     }
 
+    /** */
     @Override
     public void addIconGroup(IconManager group) {
         mIconGroups.add(group);
@@ -101,12 +103,14 @@
         }
     }
 
+    /** */
     @Override
     public void removeIconGroup(IconManager group) {
         group.destroy();
         mIconGroups.remove(group);
     }
 
+    /** */
     @Override
     public void onTuningChanged(String key, String newValue) {
         if (!ICON_HIDE_LIST.equals(key)) {
@@ -149,6 +153,7 @@
         mIconGroups.forEach(l -> l.onIconAdded(viewIndex, slot, hidden, holder));
     }
 
+    /** */
     @Override
     public void setIcon(String slot, int resourceId, CharSequence contentDescription) {
         int index = getSlotIndex(slot);
@@ -290,8 +295,9 @@
      * For backwards compatibility, in the event that someone gives us a slot and a status bar icon
      */
     private void setIcon(int index, StatusBarIcon icon) {
+        String slot = getSlotName(index);
         if (icon == null) {
-            removeAllIconsForSlot(getSlotName(index));
+            removeAllIconsForSlot(slot);
             return;
         }
 
@@ -299,6 +305,7 @@
         setIcon(index, holder);
     }
 
+    /** */
     @Override
     public void setIcon(int index, @NonNull StatusBarIconHolder holder) {
         boolean isNew = getIcon(index, holder.getTag()) == null;
@@ -328,6 +335,7 @@
         handleSet(index, holder);
     }
 
+    /** */
     @Override
     public void setIconAccessibilityLiveRegion(String slotName, int accessibilityLiveRegion) {
         Slot slot = getSlot(slotName);
@@ -344,15 +352,18 @@
         }
     }
 
+    /** */
     public void removeIcon(String slot) {
         removeAllIconsForSlot(slot);
     }
 
+    /** */
     @Override
     public void removeIcon(String slot, int tag) {
         removeIcon(getSlotIndex(slot), tag);
     }
 
+    /** */
     @Override
     public void removeAllIconsForSlot(String slotName) {
         Slot slot = getSlot(slotName);
@@ -369,6 +380,7 @@
         }
     }
 
+    /** */
     @Override
     public void removeIcon(int index, int tag) {
         if (getIcon(index, tag) == null) {
@@ -384,6 +396,7 @@
         mIconGroups.forEach(l -> l.onSetIconHolder(viewIndex, holder));
     }
 
+    /** */
     @Override
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.println(TAG + " state:");
@@ -402,6 +415,7 @@
         super.dump(pw);
     }
 
+    /** */
     @Override
     public void onDemoModeStarted() {
         for (IconManager manager : mIconGroups) {
@@ -411,6 +425,7 @@
         }
     }
 
+    /** */
     @Override
     public void onDemoModeFinished() {
         for (IconManager manager : mIconGroups) {
@@ -420,6 +435,7 @@
         }
     }
 
+    /** */
     @Override
     public void dispatchDemoCommand(String command, Bundle args) {
         for (IconManager manager : mIconGroups) {
@@ -429,6 +445,7 @@
         }
     }
 
+    /** */
     @Override
     public List<String> demoCommands() {
         List<String> s = new ArrayList<>();
@@ -436,6 +453,7 @@
         return s;
     }
 
+    /** */
     @Override
     public void onDensityOrFontScaleChanged() {
         loadDimens();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconHolder.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconHolder.java
index 19db02a..af342dd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconHolder.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconHolder.java
@@ -39,7 +39,10 @@
     private MobileIconState mMobileState;
     private int mType = TYPE_ICON;
     private int mTag = 0;
-    private boolean mVisible = true;
+
+    private StatusBarIconHolder() {
+
+    }
 
     public static StatusBarIconHolder fromIcon(StatusBarIcon icon) {
         StatusBarIconHolder wrapper = new StatusBarIconHolder();
@@ -48,7 +51,10 @@
         return wrapper;
     }
 
-    public static StatusBarIconHolder fromResId(Context context, int resId,
+    /** */
+    public static StatusBarIconHolder fromResId(
+            Context context,
+            int resId,
             CharSequence contentDescription) {
         StatusBarIconHolder holder = new StatusBarIconHolder();
         holder.mIcon = new StatusBarIcon(UserHandle.SYSTEM, context.getPackageName(),
@@ -56,6 +62,7 @@
         return holder;
     }
 
+    /** */
     public static StatusBarIconHolder fromWifiIconState(WifiIconState state) {
         StatusBarIconHolder holder = new StatusBarIconHolder();
         holder.mWifiState = state;
@@ -63,6 +70,7 @@
         return holder;
     }
 
+    /** */
     public static StatusBarIconHolder fromMobileIconState(MobileIconState state) {
         StatusBarIconHolder holder = new StatusBarIconHolder();
         holder.mMobileState = state;
@@ -75,7 +83,8 @@
      * Creates a new StatusBarIconHolder from a CallIndicatorIconState.
      */
     public static StatusBarIconHolder fromCallIndicatorState(
-            Context context, CallIndicatorIconState state) {
+            Context context,
+            CallIndicatorIconState state) {
         StatusBarIconHolder holder = new StatusBarIconHolder();
         int resId = state.isNoCalling ? state.noCallingResId : state.callStrengthResId;
         String contentDescription = state.isNoCalling
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 c1f300b..7ee7aa4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -476,11 +476,12 @@
                 return;
             }
 
-            if (mAlternateAuthInterceptor != null
-                    && mAlternateAuthInterceptor.showAlternativeAuthMethod()) {
-                mStatusBar.updateScrimController();
+            if (mAlternateAuthInterceptor != null) {
                 mAfterKeyguardGoneAction = r;
                 mKeyguardGoneCancelAction = cancelAction;
+                if (mAlternateAuthInterceptor.showAlternativeAuthMethod()) {
+                    mStatusBar.updateScrimController();
+                }
                 return;
             }
 
@@ -528,7 +529,7 @@
      * Stop showing any alternate auth methods
      */
     public void resetAlternateAuth() {
-        if (mAlternateAuthInterceptor != null && mAlternateAuthInterceptor.reset()) {
+        if (mAlternateAuthInterceptor != null && mAlternateAuthInterceptor.resetForceShow()) {
             mStatusBar.updateScrimController();
         }
     }
@@ -1125,18 +1126,27 @@
         setDozing(isDozing);
     }
 
+    /**
+     * Set whether qs is currently expanded
+     */
+    public void setQsExpanded(boolean expanded) {
+        if (mAlternateAuthInterceptor != null) {
+            mAlternateAuthInterceptor.setQsExpanded(expanded);
+        }
+    }
+
     public KeyguardBouncer getBouncer() {
         return mBouncer;
     }
 
-    public boolean isShowingAlternativeAuth() {
+    public boolean isShowingAlternateAuth() {
         return mAlternateAuthInterceptor != null
-                && mAlternateAuthInterceptor.isShowingAlternativeAuth();
+                && mAlternateAuthInterceptor.isShowingAlternateAuth();
     }
 
-    public boolean isShowingAlternativeAuthOrAnimating() {
+    public boolean isShowingAlternateAuthOrAnimating() {
         return mAlternateAuthInterceptor != null
-                && (mAlternateAuthInterceptor.isShowingAlternativeAuth()
+                && (mAlternateAuthInterceptor.isShowingAlternateAuth()
                 || mAlternateAuthInterceptor.isAnimating());
     }
 
@@ -1169,12 +1179,12 @@
          * reset the state to the default (only keyguard showing, no auth methods showing)
          * @return whether alternative auth method was newly hidden
          */
-        boolean reset();
+        boolean resetForceShow();
 
         /**
          * @return true if alternative auth method is showing
          */
-        boolean isShowingAlternativeAuth();
+        boolean isShowingAlternateAuth();
 
         /**
          * print information for the alternate auth interceptor registered
@@ -1185,5 +1195,10 @@
          * @return true if the new auth method is currently animating in or out.
          */
         boolean isAnimating();
+
+        /**
+         * Set whether qs is currently expanded
+         */
+        void setQsExpanded(boolean expanded);
     }
 }
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 525f220..94edd1e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
@@ -24,6 +24,7 @@
 import android.content.Context;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.service.notification.NotificationListenerService;
 import android.service.notification.StatusBarNotification;
 import android.service.vr.IVrManager;
 import android.service.vr.IVrStateCallbacks;
@@ -187,7 +188,7 @@
                         boolean removedByUser,
                         int reason) {
                     StatusBarNotificationPresenter.this.onNotificationRemoved(
-                            entry.getKey(), entry.getSbn());
+                            entry.getKey(), entry.getSbn(), reason);
                     if (removedByUser) {
                         maybeEndAmbientPulse();
                     }
@@ -301,13 +302,14 @@
         mNotificationPanel.updateNotificationViews(reason);
     }
 
-    public void onNotificationRemoved(String key, StatusBarNotification old) {
+    private void onNotificationRemoved(String key, StatusBarNotification old, int reason) {
         if (SPEW) Log.d(TAG, "removeNotification key=" + key + " old=" + old);
 
         if (old != null) {
             if (CLOSE_PANEL_WHEN_EMPTIED && !hasActiveNotifications()
                     && !mNotificationPanel.isTracking() && !mNotificationPanel.isQsExpanded()) {
-                if (mStatusBarStateController.getState() == StatusBarState.SHADE) {
+                if (mStatusBarStateController.getState() == StatusBarState.SHADE
+                        && reason != NotificationListenerService.REASON_CLICK) {
                     mCommandQueue.animateCollapsePanels();
                 } else if (mStatusBarStateController.getState() == StatusBarState.SHADE_LOCKED
                         && !isCollapsing()) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
index c6f7983..779ba1c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -33,6 +33,8 @@
 import android.view.WindowInsets;
 import android.widget.FrameLayout;
 
+import androidx.annotation.NonNull;
+
 import com.android.systemui.util.leak.RotationUtils;
 
 /**
@@ -91,6 +93,7 @@
      * @param roundedCornerContentPadding
      * @return
      */
+    @NonNull
     public static Pair<Integer, Integer> paddingNeededForCutoutAndRoundedCorner(
             DisplayCutout cutout, Pair<Integer, Integer> cornerCutoutPadding,
             int roundedCornerContentPadding) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java
index f65f97a..64a497d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java
@@ -262,6 +262,25 @@
     }
 
     /**
+     * Returns the view corresponding to a particular slot.
+     *
+     * Use it solely to manipulate how it is presented.
+     * @param slot name of the slot to find. Names are defined in
+     *            {@link com.android.internal.R.config_statusBarIcons}
+     * @return a view for the slot if this container has it, else {@code null}
+     */
+    public View getViewForSlot(String slot) {
+        for (int i = 0; i < getChildCount(); i++) {
+            View child = getChildAt(i);
+            if (child instanceof StatusIconDisplayable
+                    && ((StatusIconDisplayable) child).getSlot().equals(slot)) {
+                return child;
+            }
+        }
+        return null;
+    }
+
+    /**
      * Layout is happening from end -> start
      */
     private void calculateIconTranslations() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/EmergencyCryptkeeperText.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/EmergencyCryptkeeperText.java
index 5dc9104..f2ee858 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/EmergencyCryptkeeperText.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/EmergencyCryptkeeperText.java
@@ -21,7 +21,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.net.ConnectivityManager;
 import android.provider.Settings;
 import android.telephony.SubscriptionInfo;
 import android.telephony.TelephonyManager;
@@ -95,8 +94,7 @@
     }
 
     public void update() {
-        boolean hasMobile = ConnectivityManager.from(mContext)
-                .isNetworkSupported(ConnectivityManager.TYPE_MOBILE);
+        boolean hasMobile = mContext.getSystemService(TelephonyManager.class).isDataCapable();
         boolean airplaneMode = (Settings.Global.getInt(mContext.getContentResolver(),
                 Settings.Global.AIRPLANE_MODE_ON, 0) == 1);
 
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 4615877..fd37d89 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java
@@ -321,6 +321,11 @@
         }
 
         @Override
+        public int getDoneText() {
+            return R.string.quick_settings_close_user_panel;
+        }
+
+        @Override
         public boolean onDoneButtonClicked() {
             if (mNotificationPanelViewController != null) {
                 mNotificationPanelViewController.animateCloseQs(true /* animateAway */);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index db039b4..cfaeb0e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -22,7 +22,6 @@
 import static android.net.wifi.WifiManager.TrafficStateCallback.DATA_ACTIVITY_INOUT;
 import static android.net.wifi.WifiManager.TrafficStateCallback.DATA_ACTIVITY_NONE;
 import static android.net.wifi.WifiManager.TrafficStateCallback.DATA_ACTIVITY_OUT;
-import static android.telephony.PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE;
 
 import android.annotation.Nullable;
 import android.content.BroadcastReceiver;
@@ -44,11 +43,11 @@
 import android.provider.Settings;
 import android.telephony.CarrierConfigManager;
 import android.telephony.CellSignalStrength;
-import android.telephony.PhoneStateListener;
 import android.telephony.ServiceState;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
+import android.telephony.TelephonyCallback;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.FeatureFlagUtils;
@@ -74,11 +73,13 @@
 import com.android.systemui.demomode.DemoModeController;
 import com.android.systemui.settings.CurrentUserTracker;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
+import com.android.systemui.telephony.TelephonyListenerManager;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.BitSet;
 import java.util.Collections;
 import java.util.Comparator;
@@ -107,6 +108,7 @@
 
     private final Context mContext;
     private final TelephonyManager mPhone;
+    private final TelephonyListenerManager mTelephonyListenerManager;
     private final WifiManager mWifiManager;
     private final ConnectivityManager mConnectivityManager;
     private final SubscriptionManager mSubscriptionManager;
@@ -120,7 +122,7 @@
     private final boolean mProviderModel;
     private Config mConfig;
 
-    private PhoneStateListener mPhoneStateListener;
+    private TelephonyCallback.ActiveDataSubscriptionIdListener mPhoneStateListener;
     private int mActiveMobileDataSubscription = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
 
     // Subcontrollers.
@@ -200,12 +202,14 @@
             BroadcastDispatcher broadcastDispatcher,
             ConnectivityManager connectivityManager,
             TelephonyManager telephonyManager,
+            TelephonyListenerManager telephonyListenerManager,
             @Nullable WifiManager wifiManager,
             NetworkScoreManager networkScoreManager,
             AccessPointControllerImpl accessPointController,
             DemoModeController demoModeController) {
         this(context, connectivityManager,
                 telephonyManager,
+                telephonyListenerManager,
                 wifiManager,
                 networkScoreManager,
                 SubscriptionManager.from(context), Config.readConfig(context), bgLooper,
@@ -221,7 +225,9 @@
 
     @VisibleForTesting
     NetworkControllerImpl(Context context, ConnectivityManager connectivityManager,
-            TelephonyManager telephonyManager, WifiManager wifiManager,
+            TelephonyManager telephonyManager,
+            TelephonyListenerManager telephonyListenerManager,
+            WifiManager wifiManager,
             NetworkScoreManager networkScoreManager,
             SubscriptionManager subManager, Config config, Looper bgLooper,
             CallbackHandler callbackHandler,
@@ -232,6 +238,7 @@
             BroadcastDispatcher broadcastDispatcher,
             DemoModeController demoModeController) {
         mContext = context;
+        mTelephonyListenerManager = telephonyListenerManager;
         mConfig = config;
         mReceiverHandler = new Handler(bgLooper);
         mCallbackHandler = callbackHandler;
@@ -241,8 +248,7 @@
         mSubscriptionManager = subManager;
         mSubDefaults = defaultsHandler;
         mConnectivityManager = connectivityManager;
-        mHasMobileDataFeature =
-                mConnectivityManager.isNetworkSupported(ConnectivityManager.TYPE_MOBILE);
+        mHasMobileDataFeature = telephonyManager.isDataCapable();
         mDemoModeController = demoModeController;
 
         // telephony
@@ -337,10 +343,19 @@
 
                 // This callback is invoked a lot (i.e. when RSSI changes), so avoid updating
                 // icons when connectivity state has remained the same.
-                if (network.equals(mLastNetwork) &&
-                    networkCapabilities.equalsTransportTypes(mLastNetworkCapabilities) &&
-                    validated == lastValidated) {
-                    return;
+                if (network.equals(mLastNetwork) && validated == lastValidated) {
+                    // Should not rely on getTransportTypes() returning the same order of transport
+                    // types. So sort the array before comparing.
+                    int[] newTypes = networkCapabilities.getTransportTypes();
+                    Arrays.sort(newTypes);
+
+                    int[] lastTypes = (mLastNetworkCapabilities != null)
+                            ? mLastNetworkCapabilities.getTransportTypes() : null;
+                    if (lastTypes != null) Arrays.sort(lastTypes);
+
+                    if (Arrays.equals(newTypes, lastTypes)) {
+                        return;
+                    }
                 }
                 mLastNetwork = network;
                 mLastNetworkCapabilities = networkCapabilities;
@@ -363,23 +378,20 @@
         // exclusively for status bar icons.
         mConnectivityManager.registerDefaultNetworkCallback(callback, mReceiverHandler);
         // Register the listener on our bg looper
-        mPhoneStateListener = new PhoneStateListener(mReceiverHandler::post) {
-            @Override
-            public void onActiveDataSubscriptionIdChanged(int subId) {
-                // For data switching from A to B, we assume B is validated for up to 2 seconds iff:
-                // 1) A and B are in the same subscription group e.g. CBRS data switch. And
-                // 2) A was validated before the switch.
-                // This is to provide smooth transition for UI without showing cross during data
-                // switch.
-                if (keepCellularValidationBitInSwitch(mActiveMobileDataSubscription, subId)) {
-                    if (DEBUG) Log.d(TAG, ": mForceCellularValidated to true.");
-                    mForceCellularValidated = true;
-                    mReceiverHandler.removeCallbacks(mClearForceValidated);
-                    mReceiverHandler.postDelayed(mClearForceValidated, 2000);
-                }
-                mActiveMobileDataSubscription = subId;
-                doUpdateMobileControllers();
+        mPhoneStateListener = subId -> {
+            // For data switching from A to B, we assume B is validated for up to 2 seconds iff:
+            // 1) A and B are in the same subscription group e.g. CBRS data switch. And
+            // 2) A was validated before the switch.
+            // This is to provide smooth transition for UI without showing cross during data
+            // switch.
+            if (keepCellularValidationBitInSwitch(mActiveMobileDataSubscription, subId)) {
+                if (DEBUG) Log.d(TAG, ": mForceCellularValidated to true.");
+                mForceCellularValidated = true;
+                mReceiverHandler.removeCallbacks(mClearForceValidated);
+                mReceiverHandler.postDelayed(mClearForceValidated, 2000);
             }
+            mActiveMobileDataSubscription = subId;
+            doUpdateMobileControllers();
         };
 
         mDemoModeController.addCallback(this);
@@ -419,7 +431,7 @@
             mSubscriptionListener = new SubListener();
         }
         mSubscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionListener);
-        mPhone.listen(mPhoneStateListener, LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE);
+        mTelephonyListenerManager.addActiveDataSubscriptionIdListener(mPhoneStateListener);
 
         // broadcasts
         IntentFilter filter = new IntentFilter();
@@ -430,14 +442,13 @@
         filter.addAction(Intent.ACTION_SERVICE_STATE);
         filter.addAction(TelephonyManager.ACTION_SERVICE_PROVIDERS_UPDATED);
         filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
-        filter.addAction(ConnectivityManager.INET_CONDITION_ACTION);
         filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
         filter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
         mBroadcastDispatcher.registerReceiverWithHandler(this, filter, mReceiverHandler);
         mListening = true;
 
         // Initial setup of connectivity. Handled as if we had received a sticky broadcast of
-        // ConnectivityManager.CONNECTIVITY_ACTION or ConnectivityManager.INET_CONDITION_ACTION.
+        // ConnectivityManager.CONNECTIVITY_ACTION.
         mReceiverHandler.post(this::updateConnectivity);
 
         // Initial setup of WifiSignalController. Handled as if we had received a sticky broadcast
@@ -682,7 +693,6 @@
         final String action = intent.getAction();
         switch (action) {
             case ConnectivityManager.CONNECTIVITY_ACTION:
-            case ConnectivityManager.INET_CONDITION_ACTION:
                 updateConnectivity();
                 break;
             case Intent.ACTION_AIRPLANE_MODE_CHANGED:
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
index f72d2ae..5a78ea8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
@@ -32,7 +32,6 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ShortcutManager;
 import android.content.res.ColorStateList;
-import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.graphics.Color;
 import android.graphics.Rect;
@@ -74,6 +73,7 @@
 
 import androidx.annotation.NonNull;
 
+import com.android.internal.graphics.ColorUtils;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.internal.statusbar.IStatusBarService;
@@ -130,6 +130,9 @@
     private int mRevealCy;
     private int mRevealR;
 
+    private boolean mColorized;
+    private int mTint;
+
     private boolean mResetting;
     private NotificationViewWrapper mWrapper;
     private Consumer<Boolean> mOnVisibilityChangedListener;
@@ -143,35 +146,63 @@
         mRemoteInputManager = Dependency.get(NotificationRemoteInputManager.class);
         mStatusBarManagerService = IStatusBarService.Stub.asInterface(
                 ServiceManager.getService(Context.STATUS_BAR_SERVICE));
+        TypedArray ta = getContext().getTheme().obtainStyledAttributes(new int[]{
+                com.android.internal.R.attr.colorAccent,
+                com.android.internal.R.attr.colorBackgroundFloating,
+        });
+        mTint = ta.getColor(0, 0);
+        ta.recycle();
     }
 
     /**
      * The remote view needs to adapt to colorized notifications when set
+     * It overrides the background of itself as well as all of its childern
      * @param color colorized notification color
      */
-    public void overrideBackgroundTintColor(int color) {
-        mEditText.setBackgroundTintColor(color);
-        final boolean dark = !ContrastColorUtil.isColorLight(color);
-        int[][] states = new int[][] {
-                new int[] {android.R.attr.state_enabled},
-                new int[] {},
+    public void setBackgroundTintColor(int color, boolean colorized) {
+        if (colorized == mColorized && color == mTint) return;
+        mColorized = colorized;
+        mTint = color;
+        final int[][] states = new int[][]{
+                new int[]{com.android.internal.R.attr.state_enabled},
+                new int[]{},
         };
+        final int[] colors;
+        if (colorized) {
+            final boolean dark = !ContrastColorUtil.isColorLight(color);
+            final int finalColor = dark
+                    ? Color.WHITE
+                    : Color.BLACK;
+            colors = new int[]{
+                    finalColor,
+                    finalColor & 0x4DFFFFFF // %30 opacity
+            };
+            mEditText.setUniformBackgroundTintColor(color);
+            mEditText.setUniformForegroundColor(finalColor);
 
-        final int finalColor = dark
-                ? Color.WHITE
-                : Color.BLACK;
-
-        int[] colors = new int[] {
-                finalColor,
-                finalColor & 0x4DFFFFFF // %30 opacity
-        };
-
-        final ColorStateList tint = new ColorStateList(states, colors);
+        } else {
+            mEditText.setTextColor(mContext.getColor(R.color.remote_input_text));
+            mEditText.setHintTextColor(mContext.getColorStateList(R.color.remote_input_hint));
+            TypedArray ta = getContext().getTheme().obtainStyledAttributes(new int[]{
+                    com.android.internal.R.attr.colorAccent,
+                    com.android.internal.R.attr.colorBackgroundFloating,
+            });
+            int colorAccent = ta.getColor(0, 0);
+            int colorBackgroundFloating = ta.getColor(1, 0);
+            ta.recycle();
+            mEditText.setTextBackgroundColors(colorAccent, colorBackgroundFloating);
+            colors = new int[]{
+                    colorAccent,
+                    colorBackgroundFloating & 0x4DFFFFFF // %30 opacity
+            };
+        }
+        mEditText.setBackgroundColor(color);
+        final ColorStateList  tint = new ColorStateList(states, colors);
         mSendButton.setImageTintList(tint);
         mProgressBar.setProgressTintList(tint);
         mProgressBar.setIndeterminateTintList(tint);
         mProgressBar.setSecondaryProgressTintList(tint);
-        mEditText.setForegroundColor(finalColor);
+        setBackgroundColor(color);
     }
 
     @Override
@@ -326,7 +357,7 @@
                 reveal.addListener(new AnimatorListenerAdapter() {
                     @Override
                     public void onAnimationEnd(Animator animation) {
-                        setVisibility(INVISIBLE);
+                        setVisibility(GONE);
                         if (mWrapper != null) {
                             mWrapper.setRemoteInputVisible(false);
                         }
@@ -334,7 +365,7 @@
                 });
                 reveal.start();
             } else {
-                setVisibility(INVISIBLE);
+                setVisibility(GONE);
                 if (mWrapper != null) {
                     mWrapper.setRemoteInputVisible(false);
                 }
@@ -398,12 +429,6 @@
         }
     }
 
-    @Override
-    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-        mEditText.updateCornerRadius(heightMeasureSpec / 2);
-    }
-
     /** Populates the text field of the remote input with the given content. */
     public void setEditTextContent(@Nullable CharSequence editTextContent) {
         mEditText.setText(editTextContent);
@@ -700,40 +725,15 @@
         boolean mShowImeOnInputConnection;
         private LightBarController mLightBarController;
         private InputMethodManager mInputMethodManager;
-        private int mColor = Notification.COLOR_DEFAULT;
         UserHandle mUser;
-        private int mStokeWidth;
 
         public RemoteEditText(Context context, AttributeSet attrs) {
             super(context, attrs);
             mLightBarController = Dependency.get(LightBarController.class);
-            mTextBackground = createBackground(context, attrs);
+            mTextBackground = (GradientDrawable)
+                    context.getDrawable(R.drawable.remote_input_view_text_bg).mutate();
             mBackgroundColor = new ColorDrawable();
             mBackground = new LayerDrawable(new Drawable[] {mBackgroundColor, mTextBackground});
-            float density = context.getResources().getDisplayMetrics().density;
-            mStokeWidth = (int) (2 * density);
-            setDefaultColors();
-        }
-
-        private void setDefaultColors() {
-            Resources.Theme theme = getContext().getTheme();
-            TypedArray ta = theme.obtainStyledAttributes(
-                    new int[]{android.R.attr.colorAccent,
-                            com.android.internal.R.attr.colorBackgroundFloating});
-            mTextBackground.setStroke(mStokeWidth,
-                    ta.getColor(0, Notification.COLOR_DEFAULT));
-            mColor = ta.getColor(1, Notification.COLOR_DEFAULT);
-            mTextBackground.setColor(mColor);
-        }
-
-        private GradientDrawable createBackground(Context context, AttributeSet attrs) {
-            float density = context.getResources().getDisplayMetrics().density;
-            int padding = (int) (12 * density);
-            GradientDrawable d = new GradientDrawable();
-            d.setShape(GradientDrawable.RECTANGLE);
-            d.setPadding(padding, padding, padding, padding);
-            d.setCornerRadius(padding);
-            return d;
         }
 
         void setSupportedMimeTypes(@Nullable Collection<String> mimeTypes) {
@@ -796,16 +796,17 @@
             }
         }
 
-        protected void setBackgroundTintColor(int color) {
+        protected void setUniformBackgroundTintColor(int color) {
             mBackgroundColor.setColor(color);
             mTextBackground.setColor(color);
         }
 
-        protected void setForegroundColor(int color) {
-            mTextBackground.setStroke(mStokeWidth, color);
+        protected void setUniformForegroundColor(int color) {
+            int stroke = getContext().getResources()
+                    .getDimensionPixelSize(R.dimen.remote_input_view_text_stroke);
+            mTextBackground.setStroke(stroke, color);
             setTextColor(color);
-            // %60
-            setHintTextColor(color & 0x99FFFFFF);
+            setHintTextColor(ColorUtils.setAlphaComponent(color, 0x99));
             setTextCursorDrawable(null);
         }
 
@@ -896,10 +897,6 @@
             setSelection(getText().length());
         }
 
-        void updateCornerRadius(float radius) {
-            mTextBackground.setCornerRadius(radius);
-        }
-
         void setInnerFocusable(boolean focusable) {
             setFocusableInTouchMode(focusable);
             setFocusable(focusable);
@@ -924,16 +921,28 @@
                 if (clip.getItemCount() > 1
                         || description.getMimeTypeCount() < 1
                         || remainingItems != null) {
-                    // TODO(b/172363500): Update to loop over all the items
+                    // Direct-reply in notifications currently only supports only one uri item
+                    // at a time and requires the MIME type to be set.
+                    Log.w(TAG, "Invalid payload: " + payload);
                     return payload;
                 }
                 Uri contentUri = clip.getItemAt(0).getUri();
                 String mimeType = description.getMimeType(0);
                 Intent dataIntent =
                         mRemoteInputView.prepareRemoteInputFromData(mimeType, contentUri);
+                // We can release the uri permissions granted to us as soon as we've created the
+                // grant for the target app in the call above.
+                payload.releasePermissions();
                 mRemoteInputView.sendRemoteInput(dataIntent);
             }
             return remainingItems;
         }
+
+        protected void setTextBackgroundColors(int strokeColor, int textBackground) {
+            mTextBackground.setColor(textBackground);
+            int stroke = getContext().getResources()
+                    .getDimensionPixelSize(R.dimen.remote_input_view_text_stroke);
+            mTextBackground.setStroke(stroke, strokeColor);
+        }
     }
 }
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 d4029e64..83558cb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -42,8 +42,7 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings;
-import android.telephony.PhoneStateListener;
-import android.telephony.TelephonyManager;
+import android.telephony.TelephonyCallback;
 import android.util.Log;
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
@@ -69,6 +68,7 @@
 import com.android.systemui.qs.QSUserSwitcherEvent;
 import com.android.systemui.qs.tiles.UserDetailView;
 import com.android.systemui.statusbar.phone.SystemUIDialog;
+import com.android.systemui.telephony.TelephonyListenerManager;
 import com.android.systemui.user.CreateUserActivity;
 
 import java.io.FileDescriptor;
@@ -99,12 +99,12 @@
     protected final Context mContext;
     protected final UserManager mUserManager;
     private final ArrayList<WeakReference<BaseUserAdapter>> mAdapters = new ArrayList<>();
-    private final GuestResumeSessionReceiver mGuestResumeSessionReceiver
-            = new GuestResumeSessionReceiver();
+    private final GuestResumeSessionReceiver mGuestResumeSessionReceiver;
     private final KeyguardStateController mKeyguardStateController;
     protected final Handler mHandler;
     private final ActivityStarter mActivityStarter;
     private final BroadcastDispatcher mBroadcastDispatcher;
+    private final TelephonyListenerManager mTelephonyListenerManager;
     private final IActivityTaskManager mActivityTaskManager;
 
     private ArrayList<UserRecord> mUsers = new ArrayList<>();
@@ -127,11 +127,14 @@
     public UserSwitcherController(Context context, KeyguardStateController keyguardStateController,
             @Main Handler handler, ActivityStarter activityStarter,
             BroadcastDispatcher broadcastDispatcher, UiEventLogger uiEventLogger,
+            TelephonyListenerManager telephonyListenerManager,
             IActivityTaskManager activityTaskManager) {
         mContext = context;
         mBroadcastDispatcher = broadcastDispatcher;
+        mTelephonyListenerManager = telephonyListenerManager;
         mActivityTaskManager = activityTaskManager;
         mUiEventLogger = uiEventLogger;
+        mGuestResumeSessionReceiver = new GuestResumeSessionReceiver(mUiEventLogger);
         mUserDetailAdapter = new UserDetailAdapter(this, mContext, mUiEventLogger);
         if (!UserManager.isGuestUserEphemeral()) {
             mGuestResumeSessionReceiver.register(mBroadcastDispatcher);
@@ -388,6 +391,7 @@
                 // haven't reloaded the user list yet.
                 return;
             }
+            mUiEventLogger.log(QSUserSwitcherEvent.QS_USER_GUEST_ADD);
             id = guest.id;
         } else if (record.isAddUser) {
             showAddUserDialog();
@@ -458,18 +462,15 @@
     }
 
     private void listenForCallState() {
-        final TelephonyManager tele =
-            (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
-        if (tele != null) {
-            tele.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
-        }
+        mTelephonyListenerManager.addCallStateListener(mPhoneStateListener);
     }
 
-    private final PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
+    private final TelephonyCallback.CallStateListener mPhoneStateListener =
+            new TelephonyCallback.CallStateListener() {
         private int mCallState;
 
         @Override
-        public void onCallStateChanged(int state, String incomingNumber) {
+        public void onCallStateChanged(int state) {
             if (mCallState == state) return;
             if (DEBUG) Log.v(TAG, "Call state changed: " + state);
             mCallState = state;
@@ -821,6 +822,11 @@
         }
 
         @Override
+        public int getSettingsText() {
+            return R.string.quick_settings_more_user_settings;
+        }
+
+        @Override
         public Boolean getToggleState() {
             return null;
         }
@@ -891,6 +897,7 @@
             if (which == BUTTON_NEGATIVE) {
                 cancel();
             } else {
+                mUiEventLogger.log(QSUserSwitcherEvent.QS_USER_GUEST_REMOVE);
                 dismiss();
                 exitGuest(mGuestId, mTargetId);
             }
diff --git a/packages/SystemUI/src/com/android/systemui/telephony/TelephonyCallback.java b/packages/SystemUI/src/com/android/systemui/telephony/TelephonyCallback.java
new file mode 100644
index 0000000..95216c5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/telephony/TelephonyCallback.java
@@ -0,0 +1,99 @@
+/*
+ * 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.telephony;
+
+import android.telephony.ServiceState;
+import android.telephony.TelephonyCallback.ActiveDataSubscriptionIdListener;
+import android.telephony.TelephonyCallback.CallStateListener;
+import android.telephony.TelephonyCallback.ServiceStateListener;
+
+import androidx.annotation.NonNull;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.inject.Inject;
+
+/**
+ * Class for use by {@link TelephonyListenerManager} to centralize TelephonyManager Callbacks.
+ *
+ * There are more callback interfaces defined in {@link android.telephony.TelephonyCallback} that
+ * are not currently covered. Add them here if they ever become necessary.
+ */
+class TelephonyCallback extends android.telephony.TelephonyCallback
+        implements ActiveDataSubscriptionIdListener, CallStateListener, ServiceStateListener {
+
+    private final List<ActiveDataSubscriptionIdListener> mActiveDataSubscriptionIdListeners =
+            new ArrayList<>();
+    private final List<CallStateListener> mCallStateListeners = new ArrayList<>();
+    private final List<ServiceStateListener> mServiceStateListeners = new ArrayList<>();
+
+    @Inject
+    TelephonyCallback() {
+    }
+
+    boolean hasAnyListeners() {
+        return !mActiveDataSubscriptionIdListeners.isEmpty()
+                || !mCallStateListeners.isEmpty()
+                || !mServiceStateListeners.isEmpty();
+    }
+
+    @Override
+    public void onActiveDataSubscriptionIdChanged(int subId) {
+        mActiveDataSubscriptionIdListeners.forEach(listener -> {
+            listener.onActiveDataSubscriptionIdChanged(subId);
+        });
+    }
+
+    void addActiveDataSubscriptionIdListener(ActiveDataSubscriptionIdListener listener) {
+        mActiveDataSubscriptionIdListeners.add(listener);
+    }
+
+    void removeActiveDataSubscriptionIdListener(ActiveDataSubscriptionIdListener listener) {
+        mActiveDataSubscriptionIdListeners.remove(listener);
+    }
+
+    @Override
+    public void onCallStateChanged(int state) {
+        mCallStateListeners.forEach(listener -> {
+            listener.onCallStateChanged(state);
+        });
+    }
+
+    void addCallStateListener(CallStateListener listener) {
+        mCallStateListeners.add(listener);
+    }
+
+    void removeCallStateListener(CallStateListener listener) {
+        mCallStateListeners.remove(listener);
+    }
+
+    @Override
+    public void onServiceStateChanged(@NonNull ServiceState serviceState) {
+        mServiceStateListeners.forEach(listener -> {
+            listener.onServiceStateChanged(serviceState);
+        });
+    }
+
+    void addServiceStateListener(ServiceStateListener listener) {
+        mServiceStateListeners.add(listener);
+    }
+
+    void removeServiceStateListener(ServiceStateListener listener) {
+        mServiceStateListeners.remove(listener);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/telephony/TelephonyListenerManager.java b/packages/SystemUI/src/com/android/systemui/telephony/TelephonyListenerManager.java
new file mode 100644
index 0000000..3111930
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/telephony/TelephonyListenerManager.java
@@ -0,0 +1,105 @@
+/*
+ * 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.telephony;
+
+import android.telephony.PhoneStateListener;
+import android.telephony.TelephonyCallback.ActiveDataSubscriptionIdListener;
+import android.telephony.TelephonyCallback.CallStateListener;
+import android.telephony.TelephonyCallback.ServiceStateListener;
+import android.telephony.TelephonyManager;
+
+import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.dagger.qualifiers.Main;
+
+import java.util.concurrent.Executor;
+
+import javax.inject.Inject;
+
+/**
+ * Wrapper around {@link TelephonyManager#listen(PhoneStateListener, int)}.
+ *
+ * The TelephonyManager complains if too many places in code register a listener. This class
+ * encapsulates SystemUI's usage of this function, reducing it down to a single listener.
+ *
+ * See also
+ * {@link TelephonyManager#registerTelephonyCallback(Executor, android.telephony.TelephonyCallback)}
+ */
+@SysUISingleton
+public class TelephonyListenerManager {
+    private final TelephonyManager mTelephonyManager;
+    private final Executor mExecutor;
+    private final TelephonyCallback mTelephonyCallback;
+
+    private boolean mListening = false;
+
+    @Inject
+    public TelephonyListenerManager(
+            TelephonyManager telephonyManager,
+            @Main Executor executor,
+            TelephonyCallback telephonyCallback) {
+        mTelephonyManager = telephonyManager;
+        mExecutor = executor;
+        mTelephonyCallback = telephonyCallback;
+    }
+
+    /** */
+    public void addActiveDataSubscriptionIdListener(ActiveDataSubscriptionIdListener listener) {
+        mTelephonyCallback.addActiveDataSubscriptionIdListener(listener);
+        updateListening();
+    }
+
+    /** */
+    public void removeActiveDataSubscriptionIdListener(ActiveDataSubscriptionIdListener listener) {
+        mTelephonyCallback.removeActiveDataSubscriptionIdListener(listener);
+        updateListening();
+    }
+
+    /** */
+    public void addCallStateListener(CallStateListener listener) {
+        mTelephonyCallback.addCallStateListener(listener);
+        updateListening();
+    }
+
+    /** */
+    public void removeCallStateListener(CallStateListener listener) {
+        mTelephonyCallback.removeCallStateListener(listener);
+        updateListening();
+    }
+
+    /** */
+    public void addServiceStateListener(ServiceStateListener listener) {
+        mTelephonyCallback.addServiceStateListener(listener);
+        updateListening();
+    }
+
+    /** */
+    public void removeServiceStateListener(ServiceStateListener listener) {
+        mTelephonyCallback.removeServiceStateListener(listener);
+        updateListening();
+    }
+
+
+    private void updateListening() {
+        if (!mListening && mTelephonyCallback.hasAnyListeners()) {
+            mListening = true;
+            mTelephonyManager.registerTelephonyCallback(mExecutor, mTelephonyCallback);
+        } else if (mListening && !mTelephonyCallback.hasAnyListeners()) {
+            mTelephonyManager.unregisterTelephonyCallback(mTelephonyCallback);
+            mListening = false;
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayApplier.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayApplier.java
index bbb2f1a..278663b 100644
--- a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayApplier.java
+++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayApplier.java
@@ -65,8 +65,6 @@
             "android.theme.customization.accent_color";
     static final String OVERLAY_CATEGORY_SYSTEM_PALETTE =
             "android.theme.customization.system_palette";
-    static final String OVERLAY_CATEGORY_NEUTRAL_PALETTE =
-            "android.theme.customization.neutral_palette";
     @VisibleForTesting
     static final String OVERLAY_CATEGORY_FONT = "android.theme.customization.font";
     @VisibleForTesting
@@ -94,7 +92,6 @@
      */
     static final List<String> THEME_CATEGORIES = Lists.newArrayList(
             OVERLAY_CATEGORY_SYSTEM_PALETTE,
-            OVERLAY_CATEGORY_NEUTRAL_PALETTE,
             OVERLAY_CATEGORY_ICON_LAUNCHER,
             OVERLAY_CATEGORY_SHAPE,
             OVERLAY_CATEGORY_FONT,
@@ -108,7 +105,6 @@
     @VisibleForTesting
     static final Set<String> SYSTEM_USER_CATEGORIES = Sets.newHashSet(
             OVERLAY_CATEGORY_SYSTEM_PALETTE,
-            OVERLAY_CATEGORY_NEUTRAL_PALETTE,
             OVERLAY_CATEGORY_ACCENT_COLOR,
             OVERLAY_CATEGORY_FONT,
             OVERLAY_CATEGORY_SHAPE,
@@ -131,8 +127,8 @@
         mLauncherPackage = launcherPackage;
         mThemePickerPackage = themePickerPackage;
         mTargetPackageToCategories.put(ANDROID_PACKAGE, Sets.newHashSet(
-                OVERLAY_CATEGORY_SYSTEM_PALETTE, OVERLAY_CATEGORY_NEUTRAL_PALETTE,
-                OVERLAY_CATEGORY_ACCENT_COLOR, OVERLAY_CATEGORY_FONT, OVERLAY_CATEGORY_SHAPE,
+                OVERLAY_CATEGORY_SYSTEM_PALETTE, OVERLAY_CATEGORY_ACCENT_COLOR,
+                OVERLAY_CATEGORY_FONT, OVERLAY_CATEGORY_SHAPE,
                 OVERLAY_CATEGORY_ICON_ANDROID));
         mTargetPackageToCategories.put(SYSUI_PACKAGE,
                 Sets.newHashSet(OVERLAY_CATEGORY_ICON_SYSUI));
diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
index f192287..d317712 100644
--- a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
+++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
@@ -16,7 +16,6 @@
 package com.android.systemui.theme;
 
 import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_ACCENT_COLOR;
-import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_NEUTRAL_PALETTE;
 import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_SYSTEM_PALETTE;
 
 import android.annotation.Nullable;
@@ -82,9 +81,8 @@
     protected static final String TAG = "ThemeOverlayController";
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
-    protected static final int PRIMARY = 0;
-    protected static final int SECONDARY = 1;
-    protected static final int NEUTRAL = 2;
+    protected static final int NEUTRAL = 0;
+    protected static final int ACCENT = 1;
 
     private final ThemeOverlayApplier mThemeManager;
     private final UserManager mUserManager;
@@ -103,8 +101,6 @@
     protected int mMainWallpaperColor = Color.TRANSPARENT;
     // Accent color extracted from wallpaper, NOT the color used on the overlay
     protected int mWallpaperAccentColor = Color.TRANSPARENT;
-    // System colors overlay
-    private FabricatedOverlay mPrimaryOverlay;
     // Accent colors overlay
     private FabricatedOverlay mSecondaryOverlay;
     // Neutral system colors overlay
@@ -205,7 +201,7 @@
             mainColor = Color.TRANSPARENT;
             accentCandidate = Color.TRANSPARENT;
         } else {
-            mainColor = getDominantColor(currentColors);
+            mainColor = getNeutralColor(currentColors);
             accentCandidate = getAccentColor(currentColors);
         }
 
@@ -218,13 +214,12 @@
         mWallpaperAccentColor = accentCandidate;
 
         if (mIsMonetEnabled) {
-            mPrimaryOverlay = getOverlay(mMainWallpaperColor, PRIMARY);
-            mSecondaryOverlay = getOverlay(mWallpaperAccentColor, SECONDARY);
+            mSecondaryOverlay = getOverlay(mWallpaperAccentColor, ACCENT);
             mNeutralOverlay = getOverlay(mMainWallpaperColor, NEUTRAL);
             mNeedsOverlayCreation = true;
             if (DEBUG) {
-                Log.d(TAG, "fetched overlays. primary: " + mPrimaryOverlay + " secondary: "
-                        + mSecondaryOverlay + " neutral: " + mNeutralOverlay);
+                Log.d(TAG, "fetched overlays. accent: " + mSecondaryOverlay
+                        + " neutral: " + mNeutralOverlay);
             }
         }
 
@@ -234,7 +229,7 @@
     /**
      * Return the main theme color from a given {@link WallpaperColors} instance.
      */
-    protected int getDominantColor(@NonNull WallpaperColors wallpaperColors) {
+    protected int getNeutralColor(@NonNull WallpaperColors wallpaperColors) {
         return wallpaperColors.getPrimaryColor().toArgb();
     }
 
@@ -283,8 +278,6 @@
         if (mIsMonetEnabled && systemPalette != null && systemPalette.getPackageName() != null) {
             try {
                 int color = Integer.parseInt(systemPalette.getPackageName().toLowerCase(), 16);
-                mPrimaryOverlay = getOverlay(color, PRIMARY);
-                // Neutral palette is always derived from primary color.
                 mNeutralOverlay = getOverlay(color, NEUTRAL);
                 mNeedsOverlayCreation = true;
                 categoryToPackage.remove(OVERLAY_CATEGORY_SYSTEM_PALETTE);
@@ -308,7 +301,7 @@
         if (mIsMonetEnabled && accentPalette != null && accentPalette.getPackageName() != null) {
             try {
                 int color = Integer.parseInt(accentPalette.getPackageName().toLowerCase(), 16);
-                mSecondaryOverlay = getOverlay(color, SECONDARY);
+                mSecondaryOverlay = getOverlay(color, ACCENT);
                 mNeedsOverlayCreation = true;
                 categoryToPackage.remove(OVERLAY_CATEGORY_ACCENT_COLOR);
             } catch (NumberFormatException e) {
@@ -326,9 +319,8 @@
         // Compatibility with legacy themes, where full packages were defined, instead of just
         // colors.
         if (!categoryToPackage.containsKey(OVERLAY_CATEGORY_SYSTEM_PALETTE)
-                && mPrimaryOverlay != null) {
-            categoryToPackage.put(OVERLAY_CATEGORY_SYSTEM_PALETTE, mPrimaryOverlay.getIdentifier());
-            categoryToPackage.put(OVERLAY_CATEGORY_NEUTRAL_PALETTE,
+                && mNeutralOverlay != null) {
+            categoryToPackage.put(OVERLAY_CATEGORY_SYSTEM_PALETTE,
                     mNeutralOverlay.getIdentifier());
         }
         if (!categoryToPackage.containsKey(OVERLAY_CATEGORY_ACCENT_COLOR)
@@ -350,7 +342,7 @@
         if (mNeedsOverlayCreation) {
             mNeedsOverlayCreation = false;
             mThemeManager.applyCurrentUserOverlays(categoryToPackage, new FabricatedOverlay[] {
-                    mPrimaryOverlay, mSecondaryOverlay, mNeutralOverlay
+                    mSecondaryOverlay, mNeutralOverlay
             }, currentUser, managedProfiles);
         } else {
             mThemeManager.applyCurrentUserOverlays(categoryToPackage, null, currentUser,
@@ -363,7 +355,6 @@
         pw.println("mSystemColors=" + mSystemColors);
         pw.println("mMainWallpaperColor=" + Integer.toHexString(mMainWallpaperColor));
         pw.println("mWallpaperAccentColor=" + Integer.toHexString(mWallpaperAccentColor));
-        pw.println("mPrimaryOverlay=" + mPrimaryOverlay);
         pw.println("mSecondaryOverlay=" + mSecondaryOverlay);
         pw.println("mNeutralOverlay=" + mNeutralOverlay);
         pw.println("mIsMonetEnabled=" + mIsMonetEnabled);
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index 5dc7006..044d828 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -546,9 +546,10 @@
         row.sliderBgSolid = seekbarBgDrawable.findDrawableByLayerId(
                 R.id.volume_seekbar_background_solid);
 
-        row.sliderBgIcon = (AlphaTintDrawableWrapper)
-                ((RotateDrawable) seekbarBgDrawable.findDrawableByLayerId(
-                        R.id.volume_seekbar_background_icon)).getDrawable();
+        final Drawable sliderBgIcon = seekbarBgDrawable.findDrawableByLayerId(
+                        R.id.volume_seekbar_background_icon);
+        row.sliderBgIcon =  sliderBgIcon != null ? (AlphaTintDrawableWrapper)
+                ((RotateDrawable) sliderBgIcon).getDrawable() : null;
 
         final LayerDrawable seekbarProgressDrawable = (LayerDrawable)
                 ((RoundedCornerProgressDrawable) seekbarDrawable.findDrawableByLayerId(
@@ -556,13 +557,12 @@
 
         row.sliderProgressSolid = seekbarProgressDrawable.findDrawableByLayerId(
                 R.id.volume_seekbar_progress_solid);
-
-        row.sliderProgressIcon = (AlphaTintDrawableWrapper)
-                ((RotateDrawable) seekbarProgressDrawable.findDrawableByLayerId(
-                        R.id.volume_seekbar_progress_icon)).getDrawable();
+        final Drawable sliderProgressIcon = seekbarProgressDrawable.findDrawableByLayerId(
+                        R.id.volume_seekbar_progress_icon);
+        row.sliderProgressIcon = sliderProgressIcon != null ? (AlphaTintDrawableWrapper)
+                ((RotateDrawable) sliderProgressIcon).getDrawable() : null;
 
         row.slider.setProgressDrawable(seekbarDrawable);
-        row.slider.setThumb(null);
 
         row.icon = row.view.findViewById(R.id.volume_row_icon);
 
@@ -1484,10 +1484,14 @@
                 mContext, android.R.attr.colorBackgroundFloating);
 
         row.sliderProgressSolid.setTintList(colorTint);
-        row.sliderBgIcon.setTintList(colorTint);
+        if (row.sliderBgIcon != null) {
+            row.sliderBgIcon.setTintList(colorTint);
+        }
 
         row.sliderBgSolid.setTintList(bgTint);
-        row.sliderProgressIcon.setTintList(bgTint);
+        if (row.sliderProgressIcon != null) {
+            row.sliderProgressIcon.setTintList(bgTint);
+        }
 
         if (row.icon != null) {
             row.icon.setImageTintList(colorTint);
@@ -1878,8 +1882,12 @@
                 icon.setImageResource(iconRes);
             }
 
-            sliderProgressIcon.setDrawable(view.getResources().getDrawable(iconRes, theme));
-            sliderBgIcon.setDrawable(view.getResources().getDrawable(iconRes, theme));
+            if (sliderProgressIcon != null) {
+                sliderProgressIcon.setDrawable(view.getResources().getDrawable(iconRes, theme));
+            }
+            if (sliderBgIcon != null) {
+                sliderBgIcon.setDrawable(view.getResources().getDrawable(iconRes, theme));
+            }
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java
index ddfa63a..e403cfa 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java
@@ -16,26 +16,18 @@
 
 package com.android.systemui.wmshell;
 
-import static android.os.Process.THREAD_PRIORITY_DISPLAY;
-import static android.os.Process.THREAD_PRIORITY_TOP_APP_BOOST;
-
-import android.animation.AnimationHandler;
 import android.app.ActivityTaskManager;
 import android.content.Context;
 import android.content.pm.LauncherApps;
 import android.content.pm.PackageManager;
 import android.os.Handler;
-import android.os.HandlerThread;
 import android.view.IWindowManager;
 import android.view.WindowManager;
 
-import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
 import com.android.internal.logging.UiEventLogger;
 import com.android.internal.statusbar.IStatusBarService;
-import com.android.systemui.R;
 import com.android.systemui.dagger.WMComponent;
 import com.android.systemui.dagger.WMSingleton;
-import com.android.systemui.dagger.qualifiers.Main;
 import com.android.wm.shell.FullscreenTaskListener;
 import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
 import com.android.wm.shell.ShellCommandHandler;
@@ -52,14 +44,13 @@
 import com.android.wm.shell.bubbles.Bubbles;
 import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.common.DisplayImeController;
+import com.android.wm.shell.common.DisplayLayout;
 import com.android.wm.shell.common.FloatingContentCoordinator;
-import com.android.wm.shell.common.HandlerExecutor;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.SyncTransactionQueue;
 import com.android.wm.shell.common.SystemWindows;
 import com.android.wm.shell.common.TaskStackListenerImpl;
 import com.android.wm.shell.common.TransactionPool;
-import com.android.wm.shell.common.annotations.ChoreographerSfVsync;
 import com.android.wm.shell.common.annotations.ShellAnimationThread;
 import com.android.wm.shell.common.annotations.ShellMainThread;
 import com.android.wm.shell.common.annotations.ShellSplashscreenThread;
@@ -99,110 +90,9 @@
  * dependencies that are device/form factor SystemUI implementation specific should go into their
  * respective modules (ie. {@link WMShellModule} for handheld, {@link TvWMShellModule} for tv, etc.)
  */
-@Module
+@Module(includes = WMShellConcurrencyModule.class)
 public abstract class WMShellBaseModule {
 
-    /**
-     * Returns whether to enable a separate shell thread for the shell features.
-     */
-    private static boolean enableShellMainThread(Context context) {
-        return context.getResources().getBoolean(R.bool.config_enableShellMainThread);
-    }
-
-    //
-    // Shell Concurrency - Components used for managing threading in the Shell and SysUI
-    //
-
-    /**
-     * Provide a SysUI main-thread Executor.
-     */
-    @WMSingleton
-    @Provides
-    @Main
-    public static ShellExecutor provideSysUIMainExecutor(@Main Handler sysuiMainHandler) {
-        return new HandlerExecutor(sysuiMainHandler);
-    }
-
-    /**
-     * Shell main-thread Handler, don't use this unless really necessary (ie. need to dedupe
-     * multiple types of messages, etc.)
-     */
-    @WMSingleton
-    @Provides
-    @ShellMainThread
-    public static Handler provideShellMainHandler(Context context, @Main Handler sysuiMainHandler) {
-        if (enableShellMainThread(context)) {
-             HandlerThread mainThread = new HandlerThread("wmshell.main");
-             mainThread.start();
-             return mainThread.getThreadHandler();
-        }
-        return sysuiMainHandler;
-    }
-
-    /**
-     * Provide a Shell main-thread Executor.
-     */
-    @WMSingleton
-    @Provides
-    @ShellMainThread
-    public static ShellExecutor provideShellMainExecutor(Context context,
-            @ShellMainThread Handler mainHandler, @Main ShellExecutor sysuiMainExecutor) {
-        if (enableShellMainThread(context)) {
-            return new HandlerExecutor(mainHandler);
-        }
-        return sysuiMainExecutor;
-    }
-
-    /**
-     * Provide a Shell animation-thread Executor.
-     */
-    @WMSingleton
-    @Provides
-    @ShellAnimationThread
-    public static ShellExecutor provideShellAnimationExecutor() {
-         HandlerThread shellAnimationThread = new HandlerThread("wmshell.anim",
-                 THREAD_PRIORITY_DISPLAY);
-         shellAnimationThread.start();
-         return new HandlerExecutor(shellAnimationThread.getThreadHandler());
-    }
-
-    /**
-     * Provides a Shell splashscreen-thread Executor
-     */
-    @WMSingleton
-    @Provides
-    @ShellSplashscreenThread
-    public static ShellExecutor provideSplashScreenExecutor() {
-        HandlerThread shellSplashscreenThread = new HandlerThread("wmshell.splashscreen",
-                THREAD_PRIORITY_TOP_APP_BOOST);
-        shellSplashscreenThread.start();
-        return new HandlerExecutor(shellSplashscreenThread.getThreadHandler());
-    }
-
-    /**
-     * Provide a Shell main-thread AnimationHandler.  The AnimationHandler can be set on
-     * {@link android.animation.ValueAnimator}s and will ensure that the animation will run on
-     * the Shell main-thread with the SF vsync.
-     */
-    @WMSingleton
-    @Provides
-    @ChoreographerSfVsync
-    public static AnimationHandler provideShellMainExecutorSfVsyncAnimationHandler(
-            @ShellMainThread ShellExecutor mainExecutor) {
-        try {
-            AnimationHandler handler = new AnimationHandler();
-            mainExecutor.executeBlocking(() -> {
-                // This is called on the animation thread since it calls
-                // Choreographer.getSfInstance() which returns a thread-local Choreographer instance
-                // that uses the SF vsync
-                handler.setProvider(new SfVsyncFrameCallbackProvider());
-            });
-            return handler;
-        } catch (InterruptedException e) {
-            throw new RuntimeException("Failed to initialize SfVsync animation handler in 1s", e);
-        }
-    }
-
     //
     // Internal common - Components used internally by multiple shell features
     //
@@ -216,6 +106,12 @@
 
     @WMSingleton
     @Provides
+    static DisplayLayout provideDisplayLayout() {
+        return new DisplayLayout();
+    }
+
+    @WMSingleton
+    @Provides
     static DragAndDropController provideDragAndDropController(Context context,
             DisplayController displayController) {
         return new DragAndDropController(context, displayController);
@@ -344,11 +240,13 @@
     @Provides
     static Optional<OneHandedController> provideOneHandedController(Context context,
             WindowManager windowManager, DisplayController displayController,
-            TaskStackListenerImpl taskStackListener, UiEventLogger uiEventLogger,
+            DisplayLayout displayLayout, TaskStackListenerImpl taskStackListener,
+            UiEventLogger uiEventLogger,
             @ShellMainThread ShellExecutor mainExecutor,
             @ShellMainThread Handler mainHandler) {
         return Optional.ofNullable(OneHandedController.create(context, windowManager,
-                displayController, taskStackListener, uiEventLogger, mainExecutor, mainHandler));
+                displayController, displayLayout, taskStackListener, uiEventLogger, mainExecutor,
+                mainHandler));
     }
 
     //
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellConcurrencyModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellConcurrencyModule.java
new file mode 100644
index 0000000..61f50b5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellConcurrencyModule.java
@@ -0,0 +1,163 @@
+/*
+ * 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.wmshell;
+
+import static android.os.Process.THREAD_PRIORITY_DISPLAY;
+import static android.os.Process.THREAD_PRIORITY_TOP_APP_BOOST;
+
+import android.animation.AnimationHandler;
+import android.content.Context;
+import android.os.Build;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Trace;
+
+import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
+import com.android.systemui.R;
+import com.android.systemui.dagger.WMSingleton;
+import com.android.systemui.dagger.qualifiers.Main;
+import com.android.wm.shell.common.HandlerExecutor;
+import com.android.wm.shell.common.ShellExecutor;
+import com.android.wm.shell.common.annotations.ChoreographerSfVsync;
+import com.android.wm.shell.common.annotations.ShellAnimationThread;
+import com.android.wm.shell.common.annotations.ShellMainThread;
+import com.android.wm.shell.common.annotations.ShellSplashscreenThread;
+
+import dagger.Module;
+import dagger.Provides;
+
+/**
+ * Provides basic concurrency-related dependencies from {@link com.android.wm.shell}, these
+ * dependencies are only accessible from components within the WM subcomponent.
+ */
+@Module
+public abstract class WMShellConcurrencyModule {
+
+    private static final int MSGQ_SLOW_DELIVERY_THRESHOLD_MS = 30;
+    private static final int MSGQ_SLOW_DISPATCH_THRESHOLD_MS = 30;
+
+    /**
+     * Returns whether to enable a separate shell thread for the shell features.
+     */
+    private static boolean enableShellMainThread(Context context) {
+        return context.getResources().getBoolean(R.bool.config_enableShellMainThread);
+    }
+
+    //
+    // Shell Concurrency - Components used for managing threading in the Shell and SysUI
+    //
+
+    /**
+     * Provide a SysUI main-thread Executor.
+     */
+    @WMSingleton
+    @Provides
+    @Main
+    public static ShellExecutor provideSysUIMainExecutor(@Main Handler sysuiMainHandler) {
+        return new HandlerExecutor(sysuiMainHandler);
+    }
+
+    /**
+     * Shell main-thread Handler, don't use this unless really necessary (ie. need to dedupe
+     * multiple types of messages, etc.)
+     */
+    @WMSingleton
+    @Provides
+    @ShellMainThread
+    public static Handler provideShellMainHandler(Context context, @Main Handler sysuiMainHandler) {
+        if (enableShellMainThread(context)) {
+             HandlerThread mainThread = new HandlerThread("wmshell.main", THREAD_PRIORITY_DISPLAY);
+             mainThread.start();
+             if (Build.IS_DEBUGGABLE) {
+                 mainThread.getLooper().setTraceTag(Trace.TRACE_TAG_WINDOW_MANAGER);
+                 mainThread.getLooper().setSlowLogThresholdMs(MSGQ_SLOW_DISPATCH_THRESHOLD_MS,
+                         MSGQ_SLOW_DELIVERY_THRESHOLD_MS);
+             }
+             return Handler.createAsync(mainThread.getLooper());
+        }
+        return sysuiMainHandler;
+    }
+
+    /**
+     * Provide a Shell main-thread Executor.
+     */
+    @WMSingleton
+    @Provides
+    @ShellMainThread
+    public static ShellExecutor provideShellMainExecutor(Context context,
+            @ShellMainThread Handler mainHandler, @Main ShellExecutor sysuiMainExecutor) {
+        if (enableShellMainThread(context)) {
+            return new HandlerExecutor(mainHandler);
+        }
+        return sysuiMainExecutor;
+    }
+
+    /**
+     * Provide a Shell animation-thread Executor.
+     */
+    @WMSingleton
+    @Provides
+    @ShellAnimationThread
+    public static ShellExecutor provideShellAnimationExecutor() {
+         HandlerThread shellAnimationThread = new HandlerThread("wmshell.anim",
+                 THREAD_PRIORITY_DISPLAY);
+         shellAnimationThread.start();
+        if (Build.IS_DEBUGGABLE) {
+            shellAnimationThread.getLooper().setTraceTag(Trace.TRACE_TAG_WINDOW_MANAGER);
+            shellAnimationThread.getLooper().setSlowLogThresholdMs(MSGQ_SLOW_DISPATCH_THRESHOLD_MS,
+                    MSGQ_SLOW_DELIVERY_THRESHOLD_MS);
+        }
+         return new HandlerExecutor(Handler.createAsync(shellAnimationThread.getLooper()));
+    }
+
+    /**
+     * Provides a Shell splashscreen-thread Executor
+     */
+    @WMSingleton
+    @Provides
+    @ShellSplashscreenThread
+    public static ShellExecutor provideSplashScreenExecutor() {
+        HandlerThread shellSplashscreenThread = new HandlerThread("wmshell.splashscreen",
+                THREAD_PRIORITY_TOP_APP_BOOST);
+        shellSplashscreenThread.start();
+        return new HandlerExecutor(shellSplashscreenThread.getThreadHandler());
+    }
+
+    /**
+     * Provide a Shell main-thread AnimationHandler.  The AnimationHandler can be set on
+     * {@link android.animation.ValueAnimator}s and will ensure that the animation will run on
+     * the Shell main-thread with the SF vsync.
+     */
+    @WMSingleton
+    @Provides
+    @ChoreographerSfVsync
+    public static AnimationHandler provideShellMainExecutorSfVsyncAnimationHandler(
+            @ShellMainThread ShellExecutor mainExecutor) {
+        try {
+            AnimationHandler handler = new AnimationHandler();
+            mainExecutor.executeBlocking(() -> {
+                // This is called on the animation thread since it calls
+                // Choreographer.getSfInstance() which returns a thread-local Choreographer instance
+                // that uses the SF vsync
+                handler.setProvider(new SfVsyncFrameCallbackProvider());
+            });
+            return handler;
+        } catch (InterruptedException e) {
+            throw new RuntimeException("Failed to initialize SfVsync animation handler in 1s", e);
+        }
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextManagerTest.java
similarity index 72%
rename from packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java
rename to packages/SystemUI/tests/src/com/android/keyguard/CarrierTextManagerTest.java
index aa4122f..c2c7dde 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextManagerTest.java
@@ -21,12 +21,13 @@
 import static android.telephony.SubscriptionManager.DATA_ROAMING_ENABLE;
 import static android.telephony.SubscriptionManager.NAME_SOURCE_CARRIER_ID;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import static junit.framework.Assert.assertTrue;
 import static junit.framework.TestCase.assertFalse;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.fail;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
@@ -37,13 +38,9 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import android.net.ConnectivityManager;
+import android.content.pm.PackageManager;
 import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Process;
 import android.provider.Settings;
 import android.telephony.ServiceState;
 import android.telephony.SubscriptionInfo;
@@ -51,13 +48,14 @@
 import android.telephony.TelephonyManager;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
 import android.text.TextUtils;
 
-import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
+import com.android.systemui.telephony.TelephonyListenerManager;
+import com.android.systemui.util.concurrency.FakeExecutor;
+import com.android.systemui.util.time.FakeSystemClock;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -73,8 +71,7 @@
 
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-public class CarrierTextControllerTest extends SysuiTestCase {
+public class CarrierTextManagerTest extends SysuiTestCase {
 
     private static final CharSequence SEPARATOR = " \u2014 ";
     private static final CharSequence INVALID_CARD_TEXT = "Invalid card";
@@ -95,36 +92,39 @@
     @Mock
     private WifiManager mWifiManager;
     @Mock
-    private CarrierTextController.CarrierTextCallback mCarrierTextCallback;
+    private WakefulnessLifecycle mWakefulnessLifecycle;
+    @Mock
+    private CarrierTextManager.CarrierTextCallback mCarrierTextCallback;
     @Mock
     private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
     @Mock
-    private ConnectivityManager mConnectivityManager;
+    private PackageManager mPackageManager;
     @Mock
     private TelephonyManager mTelephonyManager;
     @Mock
+    private TelephonyListenerManager mTelephonyListenerManager;
+    private FakeSystemClock mFakeSystemClock = new FakeSystemClock();
+    private FakeExecutor mMainExecutor = new FakeExecutor(mFakeSystemClock);
+    private FakeExecutor mBgExecutor = new FakeExecutor(mFakeSystemClock);
+    @Mock
     private SubscriptionManager mSubscriptionManager;
-    private CarrierTextController.CarrierTextCallbackInfo mCarrierTextCallbackInfo;
+    private CarrierTextManager.CarrierTextCallbackInfo mCarrierTextCallbackInfo;
 
-    private CarrierTextController mCarrierTextController;
-    private TestableLooper mTestableLooper;
+    private CarrierTextManager mCarrierTextManager;
 
     private Void checkMainThread(InvocationOnMock inv) {
-        Looper mainLooper = Dependency.get(Dependency.MAIN_HANDLER).getLooper();
-        if (!mainLooper.isCurrentThread()) {
-            fail("This call should be done from the main thread");
-        }
+        assertThat(mMainExecutor.isExecuting()).isTrue();
+        assertThat(mBgExecutor.isExecuting()).isFalse();
         return null;
     }
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mTestableLooper = TestableLooper.get(this);
 
         mContext.addMockSystemService(WifiManager.class, mWifiManager);
-        mContext.addMockSystemService(ConnectivityManager.class, mConnectivityManager);
-        when(mConnectivityManager.isNetworkSupported(anyInt())).thenReturn(true);
+        mContext.addMockSystemService(PackageManager.class, mPackageManager);
+        when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)).thenReturn(true);
         mContext.addMockSystemService(TelephonyManager.class, mTelephonyManager);
         mContext.addMockSystemService(SubscriptionManager.class, mSubscriptionManager);
         mContext.getOrCreateTestableResources().addOverride(
@@ -132,9 +132,6 @@
         mContext.getOrCreateTestableResources().addOverride(
                 R.string.airplane_mode, AIRPLANE_MODE_TEXT);
         mDependency.injectMockDependency(WakefulnessLifecycle.class);
-        mDependency.injectTestDependency(Dependency.MAIN_HANDLER,
-                new Handler(mTestableLooper.getLooper()));
-        mDependency.injectTestDependency(Dependency.BG_LOOPER, mTestableLooper.getLooper());
         mDependency.injectTestDependency(KeyguardUpdateMonitor.class, mKeyguardUpdateMonitor);
 
         doAnswer(this::checkMainThread).when(mKeyguardUpdateMonitor)
@@ -142,35 +139,30 @@
         doAnswer(this::checkMainThread).when(mKeyguardUpdateMonitor)
                 .removeCallback(any(KeyguardUpdateMonitorCallback.class));
 
-        mCarrierTextCallbackInfo = new CarrierTextController.CarrierTextCallbackInfo("",
+        mCarrierTextCallbackInfo = new CarrierTextManager.CarrierTextCallbackInfo("",
                 new CharSequence[]{}, false, new int[]{});
         when(mTelephonyManager.getSupportedModemCount()).thenReturn(3);
         when(mTelephonyManager.getActiveModemCount()).thenReturn(3);
 
-        mCarrierTextController = new CarrierTextController(mContext, SEPARATOR, true, true);
+        mCarrierTextManager = new CarrierTextManager.Builder(
+                mContext, mContext.getResources(), mWifiManager,
+                mTelephonyManager, mTelephonyListenerManager, mWakefulnessLifecycle, mMainExecutor,
+                mBgExecutor, mKeyguardUpdateMonitor)
+                .setShowAirplaneMode(true)
+                .setShowMissingSim(true)
+                .build();
+
         // This should not start listening on any of the real dependencies but will test that
         // callbacks in mKeyguardUpdateMonitor are done in the mTestableLooper thread
-        mCarrierTextController.setListening(mCarrierTextCallback);
-        mTestableLooper.processAllMessages();
+        mCarrierTextManager.setListening(mCarrierTextCallback);
+        FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
     }
 
     @Test
     public void testKeyguardUpdateMonitorCalledInMainThread() throws Exception {
-        // This test will run on the main looper (which is not the same as the looper set as MAIN
-        // for CarrierTextCallback. This will fail if calls to mKeyguardUpdateMonitor are not done
-        // through the looper set in the set up
-        HandlerThread thread = new HandlerThread("testThread",
-                Process.THREAD_PRIORITY_BACKGROUND);
-        thread.start();
-        TestableLooper testableLooper = new TestableLooper(thread.getLooper());
-        Handler h = new Handler(testableLooper.getLooper());
-        h.post(() -> {
-            mCarrierTextController.setListening(null);
-            mCarrierTextController.setListening(mCarrierTextCallback);
-        });
-        testableLooper.processAllMessages();
-        mTestableLooper.processAllMessages();
-        thread.quitSafely();
+        mCarrierTextManager.setListening(null);
+        mCarrierTextManager.setListening(mCarrierTextCallback);
+        FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
     }
 
     @Test
@@ -183,13 +175,13 @@
         when(mKeyguardUpdateMonitor.getSimState(0)).thenReturn(TelephonyManager.SIM_STATE_READY);
         mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
 
-        mCarrierTextController.updateCarrierText();
+        mCarrierTextManager.updateCarrierText();
 
-        ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
+        ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
                 ArgumentCaptor.forClass(
-                        CarrierTextController.CarrierTextCallbackInfo.class);
+                        CarrierTextManager.CarrierTextCallbackInfo.class);
 
-        mTestableLooper.processAllMessages();
+        FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
         verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
         assertEquals(AIRPLANE_MODE_TEXT, captor.getValue().carrierText);
     }
@@ -205,14 +197,14 @@
                 TelephonyManager.SIM_STATE_CARD_IO_ERROR);
         mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
 
-        mCarrierTextController.mCallback.onSimStateChanged(3, 1,
+        mCarrierTextManager.mCallback.onSimStateChanged(3, 1,
                 TelephonyManager.SIM_STATE_CARD_IO_ERROR);
 
-        ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
+        ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
                 ArgumentCaptor.forClass(
-                        CarrierTextController.CarrierTextCallbackInfo.class);
+                        CarrierTextManager.CarrierTextCallbackInfo.class);
 
-        mTestableLooper.processAllMessages();
+        FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
         verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
         assertEquals("TEST_CARRIER" + SEPARATOR + INVALID_CARD_TEXT, captor.getValue().carrierText);
         // There's only one subscription in the list
@@ -223,8 +215,8 @@
         reset(mCarrierTextCallback);
         when(mTelephonyManager.getActiveModemCount()).thenReturn(1);
         // Update carrier text. It should ignore error state of subId 3 in inactive slotId.
-        mCarrierTextController.updateCarrierText();
-        mTestableLooper.processAllMessages();
+        mCarrierTextManager.updateCarrierText();
+        FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
         verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
         assertEquals("TEST_CARRIER", captor.getValue().carrierText);
     }
@@ -237,9 +229,9 @@
         when(mKeyguardUpdateMonitor.getSimState(anyInt())).thenReturn(
                 TelephonyManager.SIM_STATE_CARD_IO_ERROR);
         // This should not produce an out of bounds error, even though there are no subscriptions
-        mCarrierTextController.mCallback.onSimStateChanged(0, -3,
+        mCarrierTextManager.mCallback.onSimStateChanged(0, -3,
                 TelephonyManager.SIM_STATE_CARD_IO_ERROR);
-        mCarrierTextController.mCallback.onSimStateChanged(0, 3, TelephonyManager.SIM_STATE_READY);
+        mCarrierTextManager.mCallback.onSimStateChanged(0, 3, TelephonyManager.SIM_STATE_READY);
         verify(mCarrierTextCallback, never()).updateCarrierInfo(any());
     }
 
@@ -257,23 +249,23 @@
         when(mKeyguardUpdateMonitor.getSimState(anyInt())).thenReturn(
                 TelephonyManager.SIM_STATE_CARD_IO_ERROR);
         // This should not produce an out of bounds error, even though there are no subscriptions
-        mCarrierTextController.mCallback.onSimStateChanged(0, 1,
+        mCarrierTextManager.mCallback.onSimStateChanged(0, 1,
                 TelephonyManager.SIM_STATE_CARD_IO_ERROR);
 
-        mTestableLooper.processAllMessages();
+        FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
         verify(mCarrierTextCallback).updateCarrierInfo(
-                any(CarrierTextController.CarrierTextCallbackInfo.class));
+                any(CarrierTextManager.CarrierTextCallbackInfo.class));
     }
 
     @Test
     public void testCallback() {
         reset(mCarrierTextCallback);
-        mCarrierTextController.postToCallback(mCarrierTextCallbackInfo);
-        mTestableLooper.processAllMessages();
+        mCarrierTextManager.postToCallback(mCarrierTextCallbackInfo);
+        FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
 
-        ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
+        ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
                 ArgumentCaptor.forClass(
-                        CarrierTextController.CarrierTextCallbackInfo.class);
+                        CarrierTextManager.CarrierTextCallbackInfo.class);
         verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
         assertEquals(mCarrierTextCallbackInfo, captor.getValue());
     }
@@ -282,11 +274,11 @@
     public void testNullingCallback() {
         reset(mCarrierTextCallback);
 
-        mCarrierTextController.postToCallback(mCarrierTextCallbackInfo);
-        mCarrierTextController.setListening(null);
+        mCarrierTextManager.postToCallback(mCarrierTextCallbackInfo);
+        mCarrierTextManager.setListening(null);
 
         // This shouldn't produce NPE
-        mTestableLooper.processAllMessages();
+        FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
         verify(mCarrierTextCallback).updateCarrierInfo(any());
     }
 
@@ -301,15 +293,15 @@
 
         mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
 
-        ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
+        ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
                 ArgumentCaptor.forClass(
-                        CarrierTextController.CarrierTextCallbackInfo.class);
+                        CarrierTextManager.CarrierTextCallbackInfo.class);
 
-        mCarrierTextController.updateCarrierText();
-        mTestableLooper.processAllMessages();
+        mCarrierTextManager.updateCarrierText();
+        FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
         verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
 
-        CarrierTextController.CarrierTextCallbackInfo info = captor.getValue();
+        CarrierTextManager.CarrierTextCallbackInfo info = captor.getValue();
         assertEquals(1, info.listOfCarriers.length);
         assertEquals(TEST_CARRIER, info.listOfCarriers[0]);
         assertEquals(1, info.subscriptionIds.length);
@@ -326,15 +318,15 @@
 
         mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
 
-        ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
+        ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
                 ArgumentCaptor.forClass(
-                        CarrierTextController.CarrierTextCallbackInfo.class);
+                        CarrierTextManager.CarrierTextCallbackInfo.class);
 
-        mCarrierTextController.updateCarrierText();
-        mTestableLooper.processAllMessages();
+        mCarrierTextManager.updateCarrierText();
+        FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
         verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
 
-        CarrierTextController.CarrierTextCallbackInfo info = captor.getValue();
+        CarrierTextManager.CarrierTextCallbackInfo info = captor.getValue();
         assertEquals(1, info.listOfCarriers.length);
         assertTrue(info.listOfCarriers[0].toString().contains(TEST_CARRIER));
         assertEquals(1, info.subscriptionIds.length);
@@ -346,17 +338,17 @@
         List<SubscriptionInfo> list = new ArrayList<>();
         list.add(TEST_SUBSCRIPTION_NULL);
         when(mKeyguardUpdateMonitor.getSimState(anyInt())).thenReturn(
-            TelephonyManager.SIM_STATE_READY);
+                TelephonyManager.SIM_STATE_READY);
         when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo(anyBoolean())).thenReturn(list);
 
         mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
 
-        ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
+        ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
                 ArgumentCaptor.forClass(
-                        CarrierTextController.CarrierTextCallbackInfo.class);
+                        CarrierTextManager.CarrierTextCallbackInfo.class);
 
-        mCarrierTextController.updateCarrierText();
-        mTestableLooper.processAllMessages();
+        mCarrierTextManager.updateCarrierText();
+        FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
         verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
 
         assertTrue("Carrier text should be empty, instead it's " + captor.getValue().carrierText,
@@ -380,12 +372,12 @@
         when(ss.getDataRegistrationState()).thenReturn(ServiceState.STATE_IN_SERVICE);
         mKeyguardUpdateMonitor.mServiceStates.put(TEST_SUBSCRIPTION_NULL.getSubscriptionId(), ss);
 
-        ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
+        ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
                 ArgumentCaptor.forClass(
-                        CarrierTextController.CarrierTextCallbackInfo.class);
+                        CarrierTextManager.CarrierTextCallbackInfo.class);
 
-        mCarrierTextController.updateCarrierText();
-        mTestableLooper.processAllMessages();
+        mCarrierTextManager.updateCarrierText();
+        FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
         verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
 
         assertFalse("No SIM should be available", captor.getValue().anySimReady);
@@ -407,15 +399,15 @@
         when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo(anyBoolean())).thenReturn(
                 new ArrayList<>());
 
-        ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
+        ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
                 ArgumentCaptor.forClass(
-                        CarrierTextController.CarrierTextCallbackInfo.class);
+                        CarrierTextManager.CarrierTextCallbackInfo.class);
 
-        mCarrierTextController.updateCarrierText();
-        mTestableLooper.processAllMessages();
+        mCarrierTextManager.updateCarrierText();
+        FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
         verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
 
-        CarrierTextController.CarrierTextCallbackInfo info = captor.getValue();
+        CarrierTextManager.CarrierTextCallbackInfo info = captor.getValue();
         assertEquals(0, info.listOfCarriers.length);
         assertEquals(0, info.subscriptionIds.length);
 
@@ -428,17 +420,17 @@
         list.add(TEST_SUBSCRIPTION);
         list.add(TEST_SUBSCRIPTION);
         when(mKeyguardUpdateMonitor.getSimState(anyInt())).thenReturn(
-            TelephonyManager.SIM_STATE_READY);
+                TelephonyManager.SIM_STATE_READY);
         when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo(anyBoolean())).thenReturn(list);
 
         mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
 
-        ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
+        ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
                 ArgumentCaptor.forClass(
-                        CarrierTextController.CarrierTextCallbackInfo.class);
+                        CarrierTextManager.CarrierTextCallbackInfo.class);
 
-        mCarrierTextController.updateCarrierText();
-        mTestableLooper.processAllMessages();
+        mCarrierTextManager.updateCarrierText();
+        FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
         verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
 
         assertEquals(TEST_CARRIER + SEPARATOR + TEST_CARRIER,
@@ -458,12 +450,12 @@
 
         mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
 
-        ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
+        ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
                 ArgumentCaptor.forClass(
-                        CarrierTextController.CarrierTextCallbackInfo.class);
+                        CarrierTextManager.CarrierTextCallbackInfo.class);
 
-        mCarrierTextController.updateCarrierText();
-        mTestableLooper.processAllMessages();
+        mCarrierTextManager.updateCarrierText();
+        FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
         verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
 
         assertEquals(TEST_CARRIER,
@@ -483,12 +475,12 @@
 
         mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
 
-        ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
+        ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
                 ArgumentCaptor.forClass(
-                        CarrierTextController.CarrierTextCallbackInfo.class);
+                        CarrierTextManager.CarrierTextCallbackInfo.class);
 
-        mCarrierTextController.updateCarrierText();
-        mTestableLooper.processAllMessages();
+        mCarrierTextManager.updateCarrierText();
+        FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
         verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
 
         assertEquals(TEST_CARRIER,
@@ -509,12 +501,12 @@
         when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo(anyBoolean())).thenReturn(list);
         mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
 
-        ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
+        ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
                 ArgumentCaptor.forClass(
-                        CarrierTextController.CarrierTextCallbackInfo.class);
+                        CarrierTextManager.CarrierTextCallbackInfo.class);
 
-        mCarrierTextController.updateCarrierText();
-        mTestableLooper.processAllMessages();
+        mCarrierTextManager.updateCarrierText();
+        FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
         verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
 
         assertEquals(TEST_CARRIER + SEPARATOR + TEST_CARRIER,
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardAbsKeyInputViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardAbsKeyInputViewControllerTest.java
index 0cf343c..90f7fda 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardAbsKeyInputViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardAbsKeyInputViewControllerTest.java
@@ -72,6 +72,8 @@
     @Mock
     private LatencyTracker mLatencyTracker;
     private final FalsingCollector mFalsingCollector = new FalsingCollectorFake();
+    @Mock
+    private EmergencyButtonController mEmergencyButtonController;
 
     private KeyguardAbsKeyInputViewController mKeyguardAbsKeyInputViewController;
 
@@ -87,7 +89,8 @@
                 .thenReturn(mKeyguardMessageArea);
         mKeyguardAbsKeyInputViewController = new KeyguardAbsKeyInputViewController(mAbsKeyInputView,
                 mKeyguardUpdateMonitor, mSecurityMode, mLockPatternUtils, mKeyguardSecurityCallback,
-                mKeyguardMessageAreaControllerFactory, mLatencyTracker, mFalsingCollector) {
+                mKeyguardMessageAreaControllerFactory, mLatencyTracker, mFalsingCollector,
+                mEmergencyButtonController) {
             @Override
             void resetState() {
             }
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardDisplayManagerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardDisplayManagerTest.java
index 826be2b..4beec57 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardDisplayManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardDisplayManagerTest.java
@@ -54,11 +54,11 @@
 public class KeyguardDisplayManagerTest extends SysuiTestCase {
 
     @Mock
+    private NavigationBarController mNavigationBarController;
+    @Mock
     private KeyguardStatusViewComponent.Factory mKeyguardStatusViewComponentFactory;
-
     @Mock
     private DisplayManager mDisplayManager;
-
     @Mock
     private KeyguardDisplayManager.KeyguardPresentation mKeyguardPresentation;
 
@@ -76,9 +76,8 @@
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         mContext.addMockSystemService(DisplayManager.class, mDisplayManager);
-        mDependency.injectMockDependency(NavigationBarController.class);
-        mManager = spy(new KeyguardDisplayManager(mContext, mKeyguardStatusViewComponentFactory,
-                mBackgroundExecutor));
+        mManager = spy(new KeyguardDisplayManager(mContext, () -> mNavigationBarController,
+                mKeyguardStatusViewComponentFactory, mBackgroundExecutor));
         doReturn(mKeyguardPresentation).when(mManager).createPresentation(any());
 
         mDefaultDisplay = new Display(DisplayManagerGlobal.getInstance(), Display.DEFAULT_DISPLAY,
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt
index fc93ded..bb71bed8 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt
@@ -52,6 +52,8 @@
     private lateinit var mLatencyTracker: LatencyTracker
     private var mFalsingCollector: FalsingCollector = FalsingCollectorFake()
     @Mock
+    private lateinit var mEmergencyButtonController: EmergencyButtonController
+    @Mock
     private lateinit
     var mKeyguardMessageAreaControllerFactory: KeyguardMessageAreaController.Factory
     @Mock
@@ -75,7 +77,8 @@
                 .thenReturn(mKeyguardMessageAreaController)
         mKeyguardPatternViewController = KeyguardPatternViewController(mKeyguardPatternView,
         mKeyguardUpdateMonitor, mSecurityMode, mLockPatternUtils, mKeyguardSecurityCallback,
-                mLatencyTracker, mFalsingCollector, mKeyguardMessageAreaControllerFactory)
+                mLatencyTracker, mFalsingCollector, mEmergencyButtonController,
+                mKeyguardMessageAreaControllerFactory)
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java
index 33a0dcd0..9597cab 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java
@@ -68,6 +68,8 @@
     private LatencyTracker mLatencyTracker;
     @Mock
     private LiftToActivateListener mLiftToactivateListener;
+    @Mock
+    private EmergencyButtonController mEmergencyButtonController;
     private FalsingCollector mFalsingCollector = new FalsingCollectorFake();
     @Mock
     private SingleTapClassifier mSingleTapClassifier;
@@ -97,7 +99,7 @@
         mKeyguardPinViewController = new KeyguardPinBasedInputViewController(mPinBasedInputView,
                 mKeyguardUpdateMonitor, mSecurityMode, mLockPatternUtils, mKeyguardSecurityCallback,
                 mKeyguardMessageAreaControllerFactory, mLatencyTracker, mLiftToactivateListener,
-                mFalsingCollector) {
+                mEmergencyButtonController, mFalsingCollector) {
             @Override
             public void onResume(int reason) {
                 super.onResume(reason);
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
index 096ce0f..99b3f6f 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
@@ -25,9 +25,11 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
@@ -94,6 +96,11 @@
     private KeyguardMessageArea mKeyguardMessageArea;
     @Mock
     private ConfigurationController mConfigurationController;
+    @Mock
+    private EmergencyButtonController mEmergencyButtonController;
+    @Mock
+    private Resources mResources;
+    private Configuration mConfiguration;
 
     private KeyguardSecurityContainerController mKeyguardSecurityContainerController;
     private KeyguardPasswordViewController mKeyguardPasswordViewController;
@@ -101,6 +108,11 @@
 
     @Before
     public void setup() {
+        mConfiguration = new Configuration();
+        mConfiguration.setToDefaults(); // Defaults to ORIENTATION_UNDEFINED.
+
+        when(mResources.getConfiguration()).thenReturn(mConfiguration);
+        when(mView.getResources()).thenReturn(mResources);
         when(mAdminSecondaryLockScreenControllerFactory.create(any(KeyguardSecurityCallback.class)))
                 .thenReturn(mAdminSecondaryLockScreenController);
         when(mSecurityViewFlipper.getWindowInsetsController()).thenReturn(mWindowInsetsController);
@@ -112,11 +124,11 @@
         mKeyguardPasswordViewController = new KeyguardPasswordViewController(
                 (KeyguardPasswordView) mKeyguardPasswordView, mKeyguardUpdateMonitor,
                 SecurityMode.Password, mLockPatternUtils, null,
-                mKeyguardMessageAreaControllerFactory, null, null, null, mock(Resources.class),
-                null);
+                mKeyguardMessageAreaControllerFactory, null, null, mEmergencyButtonController,
+                null, mock(Resources.class), null);
 
         mKeyguardSecurityContainerController = new KeyguardSecurityContainerController.Factory(
-                mView,  mAdminSecondaryLockScreenControllerFactory, mLockPatternUtils,
+                mView, mAdminSecondaryLockScreenControllerFactory, mLockPatternUtils,
                 mKeyguardUpdateMonitor, mKeyguardSecurityModel, mMetricsLogger, mUiEventLogger,
                 mKeyguardStateController, mKeyguardSecurityViewFlipperController,
                 mConfigurationController)
@@ -152,4 +164,17 @@
         verify(mWindowInsetsController).controlWindowInsetsAnimation(
                 eq(ime()), anyLong(), any(), any(), any());
     }
+
+    @Test
+    public void onResourcesUpdate_callsThroughOnRotationChange() {
+        // Rotation is the same, shouldn't cause an update
+        mKeyguardSecurityContainerController.updateResources();
+        verify(mView, times(0)).updateLayoutForSecurityMode(any());
+
+        // Update rotation. Should trigger update
+        mConfiguration.orientation = Configuration.ORIENTATION_LANDSCAPE;
+
+        mKeyguardSecurityContainerController.updateResources();
+        verify(mView, times(1)).updateLayoutForSecurityMode(any());
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java
index 3b7f4b8..9296d3d 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java
@@ -59,6 +59,10 @@
     @Mock
     private KeyguardInputViewController.Factory mKeyguardSecurityViewControllerFactory;
     @Mock
+    private EmergencyButtonController.Factory mEmergencyButtonControllerFactory;
+    @Mock
+    private EmergencyButtonController mEmergencyButtonController;
+    @Mock
     private KeyguardInputViewController mKeyguardInputViewController;
     @Mock
     private KeyguardInputView mInputView;
@@ -76,9 +80,12 @@
                 any(KeyguardSecurityCallback.class)))
                 .thenReturn(mKeyguardInputViewController);
         when(mView.getWindowInsetsController()).thenReturn(mWindowInsetsController);
+        when(mEmergencyButtonControllerFactory.create(any(EmergencyButton.class)))
+                .thenReturn(mEmergencyButtonController);
 
         mKeyguardSecurityViewFlipperController = new KeyguardSecurityViewFlipperController(mView,
-                mLayoutInflater, mKeyguardSecurityViewControllerFactory);
+                mLayoutInflater, mKeyguardSecurityViewControllerFactory,
+                mEmergencyButtonControllerFactory);
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index 52e2016..160dae5 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -88,6 +88,7 @@
 import com.android.systemui.statusbar.FeatureFlags;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
+import com.android.systemui.telephony.TelephonyListenerManager;
 import com.android.systemui.util.RingerModeTracker;
 
 import org.junit.After;
@@ -163,6 +164,8 @@
     @Mock
     private AuthController mAuthController;
     @Mock
+    private TelephonyListenerManager mTelephonyListenerManager;
+    @Mock
     private FeatureFlags mFeatureFlags;
     @Captor
     private ArgumentCaptor<StatusBarStateController.StateListener> mStatusBarStateListenerCaptor;
@@ -883,7 +886,7 @@
                     mBroadcastDispatcher, mDumpManager,
                     mRingerModeTracker, mBackgroundExecutor,
                     mStatusBarStateController, mLockPatternUtils,
-                    mAuthController, mFeatureFlags);
+                    mAuthController, mTelephonyListenerManager, mFeatureFlags);
             setStrongAuthTracker(KeyguardUpdateMonitorTest.this.mStrongAuthTracker);
         }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt
new file mode 100644
index 0000000..02ba304
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt
@@ -0,0 +1,113 @@
+/*
+ * 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 android.hardware.biometrics.BiometricSourceType
+import android.testing.AndroidTestingRunner
+import android.view.View
+import android.view.ViewGroup
+import androidx.test.filters.SmallTest
+import com.android.keyguard.KeyguardUpdateMonitor
+import com.android.keyguard.KeyguardUpdateMonitorCallback
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.statusbar.commandline.CommandRegistry
+import com.android.systemui.statusbar.policy.ConfigurationController
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.ArgumentMatchers
+import org.mockito.Mock
+import org.mockito.Mockito.never
+import org.mockito.Mockito.reset
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class AuthRippleControllerTest : SysuiTestCase() {
+    private lateinit var controller: AuthRippleController
+    @Mock private lateinit var commandRegistry: CommandRegistry
+    @Mock private lateinit var configurationController: ConfigurationController
+    @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
+    @Mock private lateinit var rippleView: AuthRippleView
+    @Mock private lateinit var viewHost: ViewGroup
+
+    @Before
+
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+        controller = AuthRippleController(
+            commandRegistry, configurationController, context, keyguardUpdateMonitor)
+        controller.rippleView = rippleView // Replace the real ripple view with a mock instance
+        controller.setViewHost(viewHost)
+    }
+
+    @Test
+    fun testAddRippleView() {
+        val listenerCaptor = ArgumentCaptor.forClass(View.OnAttachStateChangeListener::class.java)
+        verify(viewHost).addOnAttachStateChangeListener(listenerCaptor.capture())
+
+        // Fake attach to window
+        listenerCaptor.value.onViewAttachedToWindow(viewHost)
+        verify(viewHost).addView(rippleView)
+    }
+
+    @Test
+    fun testTriggerRipple() {
+        // Fake attach to window
+        val listenerCaptor = ArgumentCaptor.forClass(View.OnAttachStateChangeListener::class.java)
+        verify(viewHost).addOnAttachStateChangeListener(listenerCaptor.capture())
+        listenerCaptor.value.onViewAttachedToWindow(viewHost)
+
+        val captor = ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback::class.java)
+        verify(keyguardUpdateMonitor).registerCallback(captor.capture())
+
+        captor.value.onBiometricAuthenticated(
+            0 /* userId */,
+            BiometricSourceType.FACE /* type */,
+            false /* isStrongBiometric */)
+        verify(rippleView, never()).startRipple()
+
+        captor.value.onBiometricAuthenticated(
+            0 /* userId */,
+            BiometricSourceType.FINGERPRINT /* type */,
+            false /* isStrongBiometric */)
+        verify(rippleView).startRipple()
+    }
+
+    @Test
+    fun testUpdateRippleColor() {
+        val captor = ArgumentCaptor
+            .forClass(ConfigurationController.ConfigurationListener::class.java)
+        verify(configurationController).addCallback(captor.capture())
+
+        reset(rippleView)
+        captor.value.onThemeChanged()
+        verify(rippleView).setColor(ArgumentMatchers.anyInt())
+
+        reset(rippleView)
+        captor.value.onUiModeChanged()
+        verify(rippleView).setColor(ArgumentMatchers.anyInt())
+    }
+
+    @Test
+    fun testForwardsSensorLocation() {
+        controller.setSensorLocation(5f, 5f)
+        verify(rippleView).setSensorLocation(5f, 5f)
+    }
+}
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 3f1a927..d3694dd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
@@ -98,6 +98,8 @@
     @Mock
     private DumpManager mDumpManager;
     @Mock
+    private AuthRippleController mAuthRippleController;
+    @Mock
     private IUdfpsOverlayControllerCallback mUdfpsOverlayControllerCallback;
 
     private FakeExecutor mFgExecutor;
@@ -148,7 +150,8 @@
                 mFgExecutor,
                 mStatusBar,
                 mStatusBarKeyguardViewManager,
-                mDumpManager);
+                mDumpManager,
+                mAuthRippleController);
         verify(mFingerprintManager).setUdfpsOverlayController(mOverlayCaptor.capture());
         mOverlayController = mOverlayCaptor.getValue();
 
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 65f0f7b..4410992 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java
@@ -170,11 +170,11 @@
 
         mAltAuthInterceptor.showAlternativeAuthMethod(); // force show
         assertFalse(mController.shouldPauseAuth());
-        assertTrue(mAltAuthInterceptor.isShowingAlternativeAuth());
+        assertTrue(mAltAuthInterceptor.isShowingAlternateAuth());
 
-        mAltAuthInterceptor.reset(); // stop force show
+        mAltAuthInterceptor.resetForceShow(); // stop force show
         assertTrue(mController.shouldPauseAuth());
-        assertFalse(mAltAuthInterceptor.isShowingAlternativeAuth());
+        assertFalse(mAltAuthInterceptor.isShowingAlternateAuth());
     }
 
     @Test
@@ -190,7 +190,7 @@
         mController.onViewDetached();
 
         // THEN alt auth state reports not showing
-        assertFalse(mAltAuthInterceptor.isShowingAlternativeAuth());
+        assertFalse(mAltAuthInterceptor.isShowingAlternateAuth());
     }
 
     private void sendStatusBarStateChanged(int statusBarState) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java
index 67c1d07..1f165bb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java
@@ -34,7 +34,7 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.testing.FakeMetricsLogger;
 import com.android.systemui.SysuiTestCase;
-import com.android.systemui.classifier.FalsingDataProvider.GestureCompleteListener;
+import com.android.systemui.classifier.FalsingDataProvider.GestureFinalizedListener;
 import com.android.systemui.dock.DockManagerFake;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.util.concurrency.FakeExecutor;
@@ -82,7 +82,7 @@
     private final FalsingClassifier.Result mFalsedResult =
             FalsingClassifier.Result.falsed(1, getClass().getSimpleName(), "");
     private final FalsingClassifier.Result mPassedResult = FalsingClassifier.Result.passed(1);
-    private GestureCompleteListener mGestureCompleteListener;
+    private GestureFinalizedListener mGestureFinalizedListener;
 
     @Before
     public void setup() {
@@ -103,13 +103,13 @@
                 mHistoryTracker, mKeyguardStateController, false);
 
 
-        ArgumentCaptor<GestureCompleteListener> gestureCompleteListenerCaptor =
-                ArgumentCaptor.forClass(GestureCompleteListener.class);
+        ArgumentCaptor<GestureFinalizedListener> gestureCompleteListenerCaptor =
+                ArgumentCaptor.forClass(GestureFinalizedListener.class);
 
         verify(mFalsingDataProvider).addGestureCompleteListener(
                 gestureCompleteListenerCaptor.capture());
 
-        mGestureCompleteListener = gestureCompleteListenerCaptor.getValue();
+        mGestureFinalizedListener = gestureCompleteListenerCaptor.getValue();
     }
 
     @Test
@@ -211,7 +211,7 @@
 
     @Test
     public void testHistory() {
-        mGestureCompleteListener.onGestureComplete(1000);
+        mGestureFinalizedListener.onGestureFinalized(1000);
 
         verify(mHistoryTracker).addResults(anyCollection(), eq(1000L));
     }
@@ -220,7 +220,7 @@
     public void testHistory_singleTap() {
         // When trying to classify single taps, we don't immediately add results to history.
         mBrightLineFalsingManager.isFalseTap(false, 0);
-        mGestureCompleteListener.onGestureComplete(1000);
+        mGestureFinalizedListener.onGestureFinalized(1000);
         verify(mHistoryTracker).addResults(anyCollection(), eq(1000L));
     }
 
@@ -228,9 +228,9 @@
     public void testHistory_multipleSingleTaps() {
         // When trying to classify single taps, we don't immediately add results to history.
         mBrightLineFalsingManager.isFalseTap(false, 0);
-        mGestureCompleteListener.onGestureComplete(1000);
+        mGestureFinalizedListener.onGestureFinalized(1000);
         mBrightLineFalsingManager.isFalseTap(false, 0);
-        mGestureCompleteListener.onGestureComplete(2000);
+        mGestureFinalizedListener.onGestureFinalized(2000);
         verify(mHistoryTracker).addResults(anyCollection(), eq(1000L));
         verify(mHistoryTracker).addResults(anyCollection(), eq(2000L));
     }
@@ -239,11 +239,11 @@
     public void testHistory_doubleTap() {
         // When trying to classify single taps, we don't immediately add results to history.
         mBrightLineFalsingManager.isFalseTap(false, 0);
-        mGestureCompleteListener.onGestureComplete(1000);
+        mGestureFinalizedListener.onGestureFinalized(1000);
         // Before checking for double tap, we may check for single-tap on the second gesture.
         mBrightLineFalsingManager.isFalseTap(false, 0);
         mBrightLineFalsingManager.isFalseDoubleTap();
-        mGestureCompleteListener.onGestureComplete(2000);
+        mGestureFinalizedListener.onGestureFinalized(2000);
 
         // Double tap is immediately added to history. Single tap is never added.
         verify(mHistoryTracker).addResults(anyCollection(), eq(2000L));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/DistanceClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/DistanceClassifierTest.java
index db06199..c912419 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/DistanceClassifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/DistanceClassifierTest.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.classifier;
 
+import static com.android.systemui.classifier.Classifier.BRIGHTNESS_SLIDER;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import android.testing.AndroidTestingRunner;
@@ -96,13 +98,9 @@
     }
 
     @Test
-    public void testPass_swipe() {
-
+    public void testPass_BrightnessSliderAlwaysPasses() {
         mClassifier.onTouchEvent(appendDownEvent(1, 1));
-        assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isTrue();
-
-        mClassifier.onTouchEvent(appendMoveEvent(1, mDataProvider.getYdpi() * 3, 3));
-        mClassifier.onTouchEvent(appendUpEvent(1, mDataProvider.getYdpi() * 3, 300));
-        assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse();
+        assertThat(mClassifier.classifyGesture(BRIGHTNESS_SLIDER, 0.5, 1).isFalse())
+                .isFalse();
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/ProximityClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/ProximityClassifierTest.java
index 52423bd..60786f6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/ProximityClassifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/ProximityClassifierTest.java
@@ -16,11 +16,12 @@
 
 package com.android.systemui.classifier;
 
+import static com.android.systemui.classifier.Classifier.BRIGHTNESS_SLIDER;
 import static com.android.systemui.classifier.Classifier.GENERIC;
 import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS;
 
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertThat;
+import static com.google.common.truth.Truth.assertThat;
+
 import static org.mockito.Mockito.when;
 
 import android.testing.AndroidTestingRunner;
@@ -72,7 +73,7 @@
     public void testPass_uncovered() {
         touchDown();
         touchUp(10);
-        assertThat(mClassifier.classifyGesture(GENERIC, 0.5, 0).isFalse(), is(false));
+        assertThat(mClassifier.classifyGesture(GENERIC, 0.5, 0).isFalse()).isFalse();
     }
 
     @Test
@@ -81,7 +82,7 @@
         mClassifier.onProximityEvent(createSensorEvent(true, 1));
         mClassifier.onProximityEvent(createSensorEvent(false, 2));
         touchUp(20);
-        assertThat(mClassifier.classifyGesture(GENERIC, 0.5, 0).isFalse(), is(false));
+        assertThat(mClassifier.classifyGesture(GENERIC, 0.5, 0).isFalse()).isFalse();
     }
 
     @Test
@@ -90,7 +91,17 @@
         mClassifier.onProximityEvent(createSensorEvent(true, 1));
         mClassifier.onProximityEvent(createSensorEvent(false, 11));
         touchUp(10);
-        assertThat(mClassifier.classifyGesture(QUICK_SETTINGS, 0.5, 0).isFalse(), is(false));
+        assertThat(mClassifier.classifyGesture(QUICK_SETTINGS, 0.5, 0).isFalse()).isFalse();
+    }
+
+    @Test
+    public void testPass_brightnessSlider() {
+        touchDown();
+        mClassifier.onProximityEvent(createSensorEvent(true, 1));
+        mClassifier.onProximityEvent(createSensorEvent(false, 11));
+        touchUp(10);
+        assertThat(mClassifier.classifyGesture(BRIGHTNESS_SLIDER, 0.5, 0).isFalse())
+                .isFalse();
     }
 
     @Test
@@ -99,7 +110,7 @@
         mClassifier.onProximityEvent(createSensorEvent(true, 1));
         mClassifier.onProximityEvent(createSensorEvent(false, 11));
         touchUp(10);
-        assertThat(mClassifier.classifyGesture(GENERIC, 0.5, 0).isFalse(), is(true));
+        assertThat(mClassifier.classifyGesture(GENERIC, 0.5, 0).isFalse()).isTrue();
     }
 
     @Test
@@ -110,7 +121,7 @@
         mClassifier.onProximityEvent(createSensorEvent(true, 96));
         mClassifier.onProximityEvent(createSensorEvent(false, 100));
         touchUp(100);
-        assertThat(mClassifier.classifyGesture(GENERIC, 0.5, 0).isFalse(), is(true));
+        assertThat(mClassifier.classifyGesture(GENERIC, 0.5, 0).isFalse()).isTrue();
     }
 
     @Test
@@ -120,7 +131,7 @@
         mClassifier.onProximityEvent(createSensorEvent(false, 11));
         touchUp(10);
         when(mDistanceClassifier.isLongSwipe()).thenReturn(mPassedResult);
-        assertThat(mClassifier.classifyGesture(GENERIC, 0.5, 0).isFalse(), is(false));
+        assertThat(mClassifier.classifyGesture(GENERIC, 0.5, 0).isFalse()).isFalse();
     }
 
     private void touchDown() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/TypeClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/TypeClassifierTest.java
index 068a1e5..32537b4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/TypeClassifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/TypeClassifierTest.java
@@ -17,6 +17,7 @@
 package com.android.systemui.classifier;
 
 import static com.android.systemui.classifier.Classifier.BOUNCER_UNLOCK;
+import static com.android.systemui.classifier.Classifier.BRIGHTNESS_SLIDER;
 import static com.android.systemui.classifier.Classifier.LEFT_AFFORDANCE;
 import static com.android.systemui.classifier.Classifier.NOTIFICATION_DISMISS;
 import static com.android.systemui.classifier.Classifier.NOTIFICATION_DRAG_DOWN;
@@ -277,4 +278,46 @@
         when(mDataProvider.isRight()).thenReturn(true);
         assertThat(mClassifier.classifyGesture(RIGHT_AFFORDANCE, 0.5, 0).isFalse()).isTrue();
     }
+
+    @Test
+    public void testPass_BrightnessSlider() {
+        when(mDataProvider.isVertical()).thenReturn(false);
+
+        when(mDataProvider.isUp()).thenReturn(false);  // up and right should cause no effect.
+        when(mDataProvider.isRight()).thenReturn(false);
+        assertThat(mClassifier.classifyGesture(BRIGHTNESS_SLIDER, 0.5, 0).isFalse()).isFalse();
+
+        when(mDataProvider.isUp()).thenReturn(true);
+        when(mDataProvider.isRight()).thenReturn(false);
+        assertThat(mClassifier.classifyGesture(BRIGHTNESS_SLIDER, 0.5, 0).isFalse()).isFalse();
+
+        when(mDataProvider.isUp()).thenReturn(false);
+        when(mDataProvider.isRight()).thenReturn(true);
+        assertThat(mClassifier.classifyGesture(BRIGHTNESS_SLIDER, 0.5, 0).isFalse()).isFalse();
+
+        when(mDataProvider.isUp()).thenReturn(true);
+        when(mDataProvider.isRight()).thenReturn(true);
+        assertThat(mClassifier.classifyGesture(BRIGHTNESS_SLIDER, 0.5, 0).isFalse()).isFalse();
+    }
+
+    @Test
+    public void testFalse_BrightnessSlider() {
+        when(mDataProvider.isVertical()).thenReturn(true);
+
+        when(mDataProvider.isUp()).thenReturn(false);  // up and right should cause no effect.
+        when(mDataProvider.isRight()).thenReturn(false);
+        assertThat(mClassifier.classifyGesture(BRIGHTNESS_SLIDER, 0.5, 0).isFalse()).isTrue();
+
+        when(mDataProvider.isUp()).thenReturn(true);
+        when(mDataProvider.isRight()).thenReturn(false);
+        assertThat(mClassifier.classifyGesture(BRIGHTNESS_SLIDER, 0.5, 0).isFalse()).isTrue();
+
+        when(mDataProvider.isUp()).thenReturn(false);
+        when(mDataProvider.isRight()).thenReturn(true);
+        assertThat(mClassifier.classifyGesture(BRIGHTNESS_SLIDER, 0.5, 0).isFalse()).isTrue();
+
+        when(mDataProvider.isUp()).thenReturn(true);
+        when(mDataProvider.isRight()).thenReturn(true);
+        assertThat(mClassifier.classifyGesture(BRIGHTNESS_SLIDER, 0.5, 0).isFalse()).isTrue();
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/ZigZagClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/ZigZagClassifierTest.java
index e004c30..c343c20 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/ZigZagClassifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/ZigZagClassifierTest.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.classifier;
 
+import static com.android.systemui.classifier.Classifier.BRIGHTNESS_SLIDER;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import android.testing.AndroidTestingRunner;
@@ -82,6 +84,13 @@
         assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse();
     }
 
+    @Test
+    public void testPass_brightnessSliderAlwaysPasses() {
+        appendMoveEvent(0, 0);
+        appendMoveEvent(0, 100);
+        appendMoveEvent(0, 1);
+        assertThat(mClassifier.classifyGesture(BRIGHTNESS_SLIDER, 0.5, 1).isFalse()).isFalse();
+    }
 
     @Test
     public void testFail_minimumTouchesVertical() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java
index eedf099..8add930 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java
@@ -43,7 +43,6 @@
 import android.os.RemoteException;
 import android.os.UserManager;
 import android.service.dreams.IDreamManager;
-import android.telephony.TelephonyManager;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.view.IWindowManager;
@@ -75,6 +74,7 @@
 import com.android.systemui.statusbar.NotificationShadeWindowController;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.telephony.TelephonyListenerManager;
 import com.android.systemui.util.RingerModeLiveData;
 import com.android.systemui.util.RingerModeTracker;
 import com.android.systemui.util.settings.SecureSettings;
@@ -106,7 +106,7 @@
     @Mock private LockPatternUtils mLockPatternUtils;
     @Mock private BroadcastDispatcher mBroadcastDispatcher;
     @Mock private ConnectivityManager mConnectivityManager;
-    @Mock private TelephonyManager mTelephonyManager;
+    @Mock private TelephonyListenerManager mTelephonyListenerManager;
     @Mock private ContentResolver mContentResolver;
     @Mock private Resources mResources;
     @Mock private ConfigurationController mConfigurationController;
@@ -167,7 +167,7 @@
                 mLockPatternUtils,
                 mBroadcastDispatcher,
                 mConnectivityManager,
-                mTelephonyManager,
+                mTelephonyListenerManager,
                 mContentResolver,
                 null,
                 mResources,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/systemsounds/HomeSoundEffectControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/systemsounds/HomeSoundEffectControllerTest.java
index 3a77f7ee..33a30e0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/systemsounds/HomeSoundEffectControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/systemsounds/HomeSoundEffectControllerTest.java
@@ -21,16 +21,20 @@
 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.Manifest;
 import android.app.ActivityManager;
 import android.app.WindowConfiguration;
-import android.content.Context;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
 import android.media.AudioManager;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.shared.system.TaskStackChangeListener;
 import com.android.systemui.shared.system.TaskStackChangeListeners;
 
@@ -41,30 +45,50 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
+
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class HomeSoundEffectControllerTest extends SysuiTestCase {
 
-    private @Mock Context mContext;
+    private static final String HOME_PACKAGE_NAME = "com.android.apps.home";
+    private static final String NON_HOME_PACKAGE_NAME = "com.android.apps.not.home";
+    private static final int HOME_TASK_ID = 0;
+    private static final int NON_HOME_TASK_ID = 1;
+
     private @Mock AudioManager mAudioManager;
     private @Mock TaskStackChangeListeners mTaskStackChangeListeners;
-    private @Mock ActivityManager.RunningTaskInfo mStandardActivityTaskInfo;
-    private @Mock ActivityManager.RunningTaskInfo mHomeActivityTaskInfo;
+    private @Mock ActivityManagerWrapper mActivityManagerWrapper;
+    private @Mock PackageManager mPackageManager;
 
+    private ActivityManager.RunningTaskInfo mTaskAStandardActivity;
+    private ActivityManager.RunningTaskInfo mTaskAExceptionActivity;
+    private ActivityManager.RunningTaskInfo mHomeTaskHomeActivity;
+    private ActivityManager.RunningTaskInfo mHomeTaskStandardActivity;
+    private ActivityManager.RunningTaskInfo mEmptyTask;
     private HomeSoundEffectController mController;
     private TaskStackChangeListener mTaskStackChangeListener;
 
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
-
-        doReturn(WindowConfiguration.ACTIVITY_TYPE_STANDARD).when(
-                mStandardActivityTaskInfo).getActivityType();
-        doReturn(WindowConfiguration.ACTIVITY_TYPE_HOME).when(
-                mHomeActivityTaskInfo).getActivityType();
-
+        mTaskAStandardActivity = createRunningTaskInfo(NON_HOME_PACKAGE_NAME,
+                WindowConfiguration.ACTIVITY_TYPE_STANDARD, NON_HOME_TASK_ID,
+                true /* playHomeTransitionSound */);
+        mTaskAExceptionActivity = createRunningTaskInfo(NON_HOME_PACKAGE_NAME,
+                WindowConfiguration.ACTIVITY_TYPE_STANDARD, NON_HOME_TASK_ID,
+                false /* playHomeTransitionSound */);
+        mHomeTaskHomeActivity = createRunningTaskInfo(HOME_PACKAGE_NAME,
+                WindowConfiguration.ACTIVITY_TYPE_HOME, HOME_TASK_ID,
+                true /* playHomeTransitionSound */);
+        mHomeTaskStandardActivity = createRunningTaskInfo(HOME_PACKAGE_NAME,
+                WindowConfiguration.ACTIVITY_TYPE_STANDARD, HOME_TASK_ID,
+                true /* playHomeTransitionSound */);
+        mEmptyTask = new ActivityManager.RunningTaskInfo();
+        mContext.setMockPackageManager(mPackageManager);
+        when(mPackageManager.checkPermission(Manifest.permission.DISABLE_SYSTEM_SOUND_EFFECTS,
+                NON_HOME_PACKAGE_NAME)).thenReturn(PackageManager.PERMISSION_GRANTED);
         mController = new HomeSoundEffectController(mContext, mAudioManager,
-                mTaskStackChangeListeners);
+                mTaskStackChangeListeners, mActivityManagerWrapper, mPackageManager);
     }
 
     @Test
@@ -73,43 +97,60 @@
         startController(true /* isHomeSoundEffectEnabled */);
 
         // And the home task moves to the front,
-        mTaskStackChangeListener.onTaskMovedToFront(mHomeActivityTaskInfo);
+        when(mActivityManagerWrapper.getRunningTask()).thenReturn(mHomeTaskHomeActivity);
+        mTaskStackChangeListener.onTaskStackChanged();
 
         // Then no home sound effect should be played.
         verify(mAudioManager, never()).playSoundEffect(AudioManager.FX_HOME);
     }
 
+    /**
+     * Task A (playHomeTransitionSound = true) -> HOME
+     * Expectation: Home sound is played
+     */
     @Test
     public void testHomeSoundEffectPlayedWhenEnabled() {
         // When HomeSoundEffectController is started and the home sound effect is enabled,
         startController(true /* isHomeSoundEffectEnabled */);
+        when(mActivityManagerWrapper.getRunningTask()).thenReturn(
+                mTaskAStandardActivity,
+                mHomeTaskHomeActivity);
 
         // And first a task different from the home task moves to front,
-        mTaskStackChangeListener.onTaskMovedToFront(mStandardActivityTaskInfo);
+        mTaskStackChangeListener.onTaskStackChanged();
 
         // And the home task moves to the front,
-        mTaskStackChangeListener.onTaskMovedToFront(mHomeActivityTaskInfo);
+        mTaskStackChangeListener.onTaskStackChanged();
 
         // Then the home sound effect should be played.
         verify(mAudioManager).playSoundEffect(AudioManager.FX_HOME);
     }
 
+    /**
+     * Task A (playHomeTransitionSound = true) -> HOME -> HOME
+     * Expectation: Home sound is played once after HOME moves to front the first time
+     */
     @Test
     public void testHomeSoundEffectNotPlayedTwiceInRow() {
         // When HomeSoundEffectController is started and the home sound effect is enabled,
         startController(true /* isHomeSoundEffectEnabled */);
+        when(mActivityManagerWrapper.getRunningTask()).thenReturn(
+                mTaskAStandardActivity,
+                mHomeTaskHomeActivity,
+                mHomeTaskHomeActivity);
+
 
         // And first a task different from the home task moves to front,
-        mTaskStackChangeListener.onTaskMovedToFront(mStandardActivityTaskInfo);
+        mTaskStackChangeListener.onTaskStackChanged();
 
         // And the home task moves to the front,
-        mTaskStackChangeListener.onTaskMovedToFront(mHomeActivityTaskInfo);
+        mTaskStackChangeListener.onTaskStackChanged();
 
         // Then the home sound effect should be played.
         verify(mAudioManager).playSoundEffect(AudioManager.FX_HOME);
 
         // If the home task moves to front a second time in a row,
-        mTaskStackChangeListener.onTaskMovedToFront(mHomeActivityTaskInfo);
+        mTaskStackChangeListener.onTaskStackChanged();
 
         // Then no home sound effect should be played.
         verify(mAudioManager, times(1)).playSoundEffect(AudioManager.FX_HOME);
@@ -121,7 +162,59 @@
         startController(true /* isHomeSoundEffectEnabled */);
 
         // And a standard, non-home task, moves to the front,
-        mTaskStackChangeListener.onTaskMovedToFront(mStandardActivityTaskInfo);
+        when(mActivityManagerWrapper.getRunningTask()).thenReturn(mTaskAStandardActivity);
+        mTaskStackChangeListener.onTaskStackChanged();
+
+        // Then no home sound effect should be played.
+        verify(mAudioManager, never()).playSoundEffect(AudioManager.FX_HOME);
+    }
+
+    /**
+     * Task A (playHomeTransitionSound = true) -> HOME -> HOME (activity type standard)
+     * Expectation: Home sound is played once after HOME moves to front
+     */
+    @Test
+    public void testHomeSoundEffectNotPlayedWhenOtherHomeActivityMovesToFront() {
+        // When HomeSoundEffectController is started and the home sound effect is enabled,
+        startController(true /* isHomeSoundEffectEnabled */);
+        when(mActivityManagerWrapper.getRunningTask()).thenReturn(
+                mTaskAStandardActivity,
+                mHomeTaskHomeActivity,
+                mHomeTaskStandardActivity);
+
+        // And first a task different from the home task moves to front,
+        mTaskStackChangeListener.onTaskStackChanged();
+
+        // And the home task moves to the front,
+        mTaskStackChangeListener.onTaskStackChanged();
+
+        // Then the home sound effect should be played.
+        verify(mAudioManager).playSoundEffect(AudioManager.FX_HOME);
+
+        // If the home task moves to front a second time in a row,
+        mTaskStackChangeListener.onTaskStackChanged();
+
+        // Then no home sound effect should be played.
+        verify(mAudioManager, times(1)).playSoundEffect(AudioManager.FX_HOME);
+    }
+
+    /**
+     * Task A (playHomeTransitionSound = true) -> HOME (activity type standard)
+     * Expectation: Home sound is not played
+     */
+    @Test
+    public void testHomeSoundEffectNotPlayedWhenOtherHomeActivityMovesToFrontOfOtherApp() {
+        // When HomeSoundEffectController is started and the home sound effect is enabled,
+        startController(true /* isHomeSoundEffectEnabled */);
+
+        // And first a task different from the home task moves to front,
+        when(mActivityManagerWrapper.getRunningTask()).thenReturn(
+                mTaskAStandardActivity,
+                mHomeTaskStandardActivity);
+        mTaskStackChangeListener.onTaskStackChanged();
+
+        // And an activity from the home package but not the home root activity moves to front
+        mTaskStackChangeListener.onTaskStackChanged();
 
         // Then no home sound effect should be played.
         verify(mAudioManager, never()).playSoundEffect(AudioManager.FX_HOME);
@@ -138,6 +231,171 @@
     }
 
     /**
+     * Task A (playHomeTransitionSound = false) -> HOME
+     * Expectation: Home sound is not played
+     */
+    @Test
+    public void testHomeSoundEffectNotPlayedWhenHomeActivityMovesToFrontAfterException() {
+        // When HomeSoundEffectController is started and the home sound effect is enabled,
+        startController(true /* isHomeSoundEffectEnabled */);
+
+        // And first a task different from the home task moves to front, which has
+        // {@link ActivityInfo#PRIVATE_FLAG_HOME_TRANSITION_SOUND} set to <code>false</code>
+        when(mActivityManagerWrapper.getRunningTask()).thenReturn(
+                mTaskAExceptionActivity,
+                mHomeTaskHomeActivity);
+        mTaskStackChangeListener.onTaskStackChanged();
+
+        // And the home task moves to the front,
+        mTaskStackChangeListener.onTaskStackChanged();
+
+        // Then no home sound effect should be played because the last package is an exception.
+        verify(mAudioManager, never()).playSoundEffect(AudioManager.FX_HOME);
+    }
+
+    /**
+     * HOME -> Task A (playHomeTransitionSound = true) -> Task A (playHomeTransitionSound = false)
+     * -> HOME
+     * Expectation: Home sound is not played
+     */
+    @Test
+    public void testHomeSoundEffectNotPlayedWhenHomeActivityMovesToFrontAfterException2() {
+        // When HomeSoundEffectController is started and the home sound effect is enabled,
+        startController(true /* isHomeSoundEffectEnabled */);
+
+        when(mActivityManagerWrapper.getRunningTask()).thenReturn(
+                mTaskAStandardActivity,
+                mTaskAExceptionActivity,
+                mHomeTaskHomeActivity);
+
+        // And first a task different from the home task moves to front
+        mTaskStackChangeListener.onTaskStackChanged();
+
+        // Then a different activity from the same task moves to front, which has
+        // {@link ActivityInfo#PRIVATE_FLAG_HOME_TRANSITION_SOUND} set to <code>false</code>
+        mTaskStackChangeListener.onTaskStackChanged();
+
+        // And the home task moves to the front,
+        mTaskStackChangeListener.onTaskStackChanged();
+
+        // Then no home sound effect should be played.
+        verify(mAudioManager, never()).playSoundEffect(AudioManager.FX_HOME);
+    }
+
+    /**
+     * HOME -> Task A (playHomeTransitionSound = false) -> Task A (playHomeTransitionSound = true)
+     * -> HOME
+     * Expectation: Home sound is played
+     */
+    @Test
+    public void testHomeSoundEffectPlayedWhenHomeActivityMovesToFrontAfterException() {
+        // When HomeSoundEffectController is started and the home sound effect is enabled,
+        startController(true /* isHomeSoundEffectEnabled */);
+        when(mActivityManagerWrapper.getRunningTask()).thenReturn(
+                mTaskAExceptionActivity,
+                mTaskAStandardActivity,
+                mHomeTaskHomeActivity);
+
+        // And first a task different from the home task moves to front,
+        // the topActivity of this task has {@link ActivityInfo#PRIVATE_FLAG_HOME_TRANSITION_SOUND}
+        // set to <code>false</code>
+        mTaskStackChangeListener.onTaskStackChanged();
+
+        // Then a different activity from the same task moves to front, which has
+        // {@link ActivityInfo#PRIVATE_FLAG_HOME_TRANSITION_SOUND} set to <code>true</code>
+        mTaskStackChangeListener.onTaskStackChanged();
+
+        // And the home task moves to the front,
+        mTaskStackChangeListener.onTaskStackChanged();
+
+        // Then the home sound effect should be played.
+        verify(mAudioManager).playSoundEffect(AudioManager.FX_HOME);
+    }
+
+    /**
+     * HOME -> Task A (playHomeTransitionSound = false) -> Task A (empty task, no top activity)
+     * -> HOME
+     * Expectation: Home sound is not played
+     */
+    @Test
+    public void testHomeSoundEffectNotPlayedWhenEmptyTaskMovesToFrontAfterException() {
+        // When HomeSoundEffectController is started and the home sound effect is enabled,
+        startController(true /* isHomeSoundEffectEnabled */);
+        when(mActivityManagerWrapper.getRunningTask()).thenReturn(
+                mTaskAExceptionActivity,
+                mEmptyTask,
+                mHomeTaskHomeActivity);
+
+        // And first a task different from the home task moves to front, whose topActivity has
+        // {@link ActivityInfo#PRIVATE_FLAG_HOME_TRANSITION_SOUND} set to <code>false</code>
+        mTaskStackChangeListener.onTaskStackChanged();
+
+        // Then a task with no topActivity moves to front,
+        mTaskStackChangeListener.onTaskStackChanged();
+
+        // And the home task moves to the front,
+        mTaskStackChangeListener.onTaskStackChanged();
+
+        // Then no home sound effect should be played.
+        verify(mAudioManager, never()).playSoundEffect(AudioManager.FX_HOME);
+    }
+
+    /**
+     * HOME -> Task A (playHomeTransitionSound = true) -> Task A (empty task, no top activity)
+     * -> HOME
+     * Expectation: Home sound is played
+     */
+    @Test
+    public void testHomeSoundEffectPlayedWhenEmptyTaskMovesToFrontAfterStandardActivity() {
+        // When HomeSoundEffectController is started and the home sound effect is enabled,
+        startController(true /* isHomeSoundEffectEnabled */);
+        when(mActivityManagerWrapper.getRunningTask()).thenReturn(
+                mTaskAStandardActivity,
+                mEmptyTask,
+                mHomeTaskHomeActivity);
+
+        // And first a task different from the home task moves to front, whose topActivity has
+        // {@link ActivityInfo#PRIVATE_FLAG_HOME_TRANSITION_SOUND} set to <code>false</code>
+        mTaskStackChangeListener.onTaskStackChanged();
+
+        // Then a task with no topActivity moves to front,
+        mTaskStackChangeListener.onTaskStackChanged();
+
+        // And the home task moves to the front,
+        mTaskStackChangeListener.onTaskStackChanged();
+
+        // Then the home sound effect should be played.
+        verify(mAudioManager).playSoundEffect(AudioManager.FX_HOME);
+    }
+
+    /**
+     * HOME -> Task A (playHomeTransitionSound = false, no permission) -> HOME
+     * Expectation: Home sound is played
+     */
+    @Test
+    public void testHomeSoundEffectPlayedWhenFlagSetButPermissionNotGranted() {
+        // When HomeSoundEffectController is started and the home sound effect is enabled,
+        startController(true /* isHomeSoundEffectEnabled */);
+        when(mActivityManagerWrapper.getRunningTask()).thenReturn(
+                mTaskAStandardActivity,
+                mHomeTaskHomeActivity);
+        when(mPackageManager.checkPermission(Manifest.permission.DISABLE_SYSTEM_SOUND_EFFECTS,
+                NON_HOME_PACKAGE_NAME)).thenReturn(PackageManager.PERMISSION_DENIED);
+
+        // And first a task different from the home task moves to front, whose topActivity has
+        // {@link ActivityInfo#PRIVATE_FLAG_HOME_TRANSITION_SOUND} set to <code>true</code>,
+        // but the app doesn't have the right permission granted
+        mTaskStackChangeListener.onTaskStackChanged();
+
+
+        // And the home task moves to the front,
+        mTaskStackChangeListener.onTaskStackChanged();
+
+        // Then the home sound effect should be played.
+        verify(mAudioManager).playSoundEffect(AudioManager.FX_HOME);
+    }
+
+    /**
      * Sets {@link AudioManager#isHomeSoundEffectEnabled()} and starts HomeSoundEffectController.
      * If the home sound effect is enabled, the registered TaskStackChangeListener is extracted.
      */
@@ -155,4 +413,20 @@
             mTaskStackChangeListener = listenerCaptor.getValue();
         }
     }
+
+    private ActivityManager.RunningTaskInfo createRunningTaskInfo(String packageName,
+            int activityType, int taskId, boolean playHomeTransitionSound) {
+        ActivityManager.RunningTaskInfo res = new ActivityManager.RunningTaskInfo();
+        res.topActivityInfo = new ActivityInfo();
+        res.topActivityInfo.packageName = packageName;
+        res.topActivityType = activityType;
+        res.taskId = taskId;
+        if (!playHomeTransitionSound) {
+            // set the flag to 0
+            res.topActivityInfo.privateFlags &=  ~ActivityInfo.PRIVATE_FLAG_HOME_TRANSITION_SOUND;
+        } else {
+            res.topActivityInfo.privateFlags |= ActivityInfo.PRIVATE_FLAG_HOME_TRANSITION_SOUND;
+        }
+        return res;
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/people/PeopleSpaceUtilsTest.java b/packages/SystemUI/tests/src/com/android/systemui/people/PeopleSpaceUtilsTest.java
index ee98a59..1f4dffa 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/people/PeopleSpaceUtilsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/people/PeopleSpaceUtilsTest.java
@@ -16,20 +16,11 @@
 
 package com.android.systemui.people;
 
-import static android.app.Notification.CATEGORY_MISSED_CALL;
-import static android.app.people.ConversationStatus.ACTIVITY_BIRTHDAY;
-import static android.app.people.ConversationStatus.ACTIVITY_GAME;
-import static android.app.people.ConversationStatus.ACTIVITY_NEW_STORY;
-import static android.app.people.ConversationStatus.AVAILABILITY_AVAILABLE;
-import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH;
-
 import static com.android.systemui.people.PeopleSpaceUtils.PACKAGE_NAME;
-import static com.android.systemui.people.PeopleSpaceUtils.REQUIRED_WIDTH_FOR_MEDIUM;
 import static com.android.systemui.people.widget.AppWidgetOptionsHelper.OPTIONS_PEOPLE_TILE;
 
 import static com.google.common.truth.Truth.assertThat;
 
-import static org.junit.Assert.assertEquals;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
@@ -48,7 +39,6 @@
 import android.app.NotificationManager;
 import android.app.Person;
 import android.app.people.ConversationChannel;
-import android.app.people.ConversationStatus;
 import android.app.people.IPeopleManager;
 import android.app.people.PeopleSpaceTile;
 import android.appwidget.AppWidgetManager;
@@ -70,13 +60,12 @@
 import android.service.notification.ConversationChannelWrapper;
 import android.service.notification.StatusBarNotification;
 import android.testing.AndroidTestingRunner;
-import android.view.View;
-import android.widget.RemoteViews;
-import android.widget.TextView;
+import android.util.DisplayMetrics;
 
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.appwidget.IAppWidgetService;
+import com.android.internal.util.ArrayUtils;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.people.widget.PeopleTileKey;
@@ -117,8 +106,6 @@
     private static final int TEST_COLUMN_INDEX = 1;
     private static final Uri URI = Uri.parse("fake_uri");
     private static final Icon ICON = Icon.createWithResource("package", R.drawable.ic_android);
-    private static final String GAME_DESCRIPTION = "Playing a game!";
-    private static final CharSequence MISSED_CALL = "Custom missed call message";
     private static final String NAME = "username";
     private static final Person PERSON = new Person.Builder()
             .setName("name")
@@ -126,11 +113,6 @@
             .setUri(URI.toString())
             .setBot(false)
             .build();
-    private static final PeopleSpaceTile PERSON_TILE_WITHOUT_NOTIFICATION =
-            new PeopleSpaceTile
-                    .Builder(SHORTCUT_ID_1, NAME, ICON, new Intent())
-                    .setLastInteractionTimestamp(0L)
-                    .build();
     private static final PeopleSpaceTile PERSON_TILE =
             new PeopleSpaceTile
                     .Builder(SHORTCUT_ID_1, NAME, ICON, new Intent())
@@ -138,16 +120,7 @@
                     .setNotificationKey(NOTIFICATION_KEY)
                     .setNotificationContent(NOTIFICATION_CONTENT)
                     .setNotificationDataUri(URI)
-                    .build();
-    private static final ConversationStatus GAME_STATUS =
-            new ConversationStatus
-                    .Builder(PERSON_TILE.getId(), ACTIVITY_GAME)
-                    .setDescription(GAME_DESCRIPTION)
-                    .build();
-    private static final ConversationStatus NEW_STORY_WITH_AVAILABILITY =
-            new ConversationStatus
-                    .Builder(PERSON_TILE.getId(), ACTIVITY_NEW_STORY)
-                    .setAvailability(AVAILABILITY_AVAILABLE)
+                    .setMessagesCount(1)
                     .build();
 
     private final ShortcutInfo mShortcutInfo = new ShortcutInfo.Builder(mContext,
@@ -244,6 +217,12 @@
         when(mAppWidgetManager.getAppWidgetOptions(eq(WIDGET_ID_WITHOUT_SHORTCUT)))
                 .thenReturn(new Bundle());
 
+        Configuration configuration = mock(Configuration.class);
+        DisplayMetrics displayMetrics = mock(DisplayMetrics.class);
+        Resources resources = mock(Resources.class);
+        when(mMockContext.getResources()).thenReturn(resources);
+        when(resources.getConfiguration()).thenReturn(configuration);
+        when(resources.getDisplayMetrics()).thenReturn(displayMetrics);
         when(mMockContext.getContentResolver()).thenReturn(mMockContentResolver);
         when(mMockContentResolver.query(any(Uri.class), any(), anyString(), any(),
                 isNull())).thenReturn(mMockCursor);
@@ -254,10 +233,6 @@
         when(mMockContext.getPackageManager()).thenReturn(mPackageManager);
         when(mMockContext.getString(R.string.over_timestamp)).thenReturn(
                 mContext.getString(R.string.over_timestamp));
-        Configuration configuration = mock(Configuration.class);
-        Resources resources = mock(Resources.class);
-        when(mMockContext.getResources()).thenReturn(resources);
-        when(resources.getConfiguration()).thenReturn(configuration);
         when(mPackageManager.getApplicationIcon(anyString())).thenReturn(null);
         when(mNotificationEntryManager.getVisibleNotifications())
                 .thenReturn(List.of(mNotificationEntry1, mNotificationEntry2, mNotificationEntry3));
@@ -345,7 +320,7 @@
     }
 
     @Test
-    public void testGetLastMessagingStyleMessageNoMessage() {
+    public void testGetMessagingStyleMessagesNoMessage() {
         Notification notification = new Notification.Builder(mContext, "test")
                 .setContentTitle("TEST_TITLE")
                 .setContentText("TEST_TEXT")
@@ -355,111 +330,23 @@
                 .setNotification(notification)
                 .build();
 
-        Notification.MessagingStyle.Message lastMessage =
-                PeopleSpaceUtils.getLastMessagingStyleMessage(sbn.getNotification());
+        List<Notification.MessagingStyle.Message> messages =
+                PeopleSpaceUtils.getMessagingStyleMessages(sbn.getNotification());
 
-        assertThat(lastMessage).isNull();
+        assertThat(ArrayUtils.isEmpty(messages)).isTrue();
     }
 
     @Test
-    public void testGetBackgroundTextFromMessageNoPunctuation() {
-        String backgroundText = PeopleSpaceUtils.getBackgroundTextFromMessage("test");
-
-        assertThat(backgroundText).isNull();
-    }
-
-    @Test
-    public void testGetBackgroundTextFromMessageSingleExclamation() {
-        String backgroundText = PeopleSpaceUtils.getBackgroundTextFromMessage("test!");
-
-        assertThat(backgroundText).isNull();
-    }
-
-    @Test
-    public void testGetBackgroundTextFromMessageSingleQuestion() {
-        String backgroundText = PeopleSpaceUtils.getBackgroundTextFromMessage("?test");
-
-        assertThat(backgroundText).isNull();
-    }
-
-    @Test
-    public void testGetBackgroundTextFromMessageSeparatedMarks() {
-        String backgroundText = PeopleSpaceUtils.getBackgroundTextFromMessage("test! right!");
-
-        assertThat(backgroundText).isNull();
-    }
-
-    @Test
-    public void testGetBackgroundTextFromMessageDoubleExclamation() {
-        String backgroundText = PeopleSpaceUtils.getBackgroundTextFromMessage("!!test");
-
-        assertThat(backgroundText).isEqualTo("!");
-    }
-
-    @Test
-    public void testGetBackgroundTextFromMessageDoubleQuestion() {
-        String backgroundText = PeopleSpaceUtils.getBackgroundTextFromMessage("test??");
-
-        assertThat(backgroundText).isEqualTo("?");
-    }
-
-    @Test
-    public void testGetBackgroundTextFromMessageMixed() {
-        String backgroundText = PeopleSpaceUtils.getBackgroundTextFromMessage("test?!");
-
-        assertThat(backgroundText).isEqualTo("!?");
-    }
-
-    @Test
-    public void testGetBackgroundTextFromMessageMixedInTheMiddle() {
-        String backgroundText = PeopleSpaceUtils.getBackgroundTextFromMessage(
-                "test!? in the middle");
-
-        assertThat(backgroundText).isEqualTo("!?");
-    }
-
-    @Test
-    public void testGetBackgroundTextFromMessageMixedDifferentOrder() {
-        String backgroundText = PeopleSpaceUtils.getBackgroundTextFromMessage(
-                "test!? in the middle");
-
-        assertThat(backgroundText).isEqualTo("!?");
-    }
-
-    @Test
-    public void testGetBackgroundTextFromMessageMultiple() {
-        String backgroundText = PeopleSpaceUtils.getBackgroundTextFromMessage(
-                "test!?!!? in the middle");
-
-        assertThat(backgroundText).isEqualTo("!?");
-    }
-
-    @Test
-    public void testGetBackgroundTextFromMessageQuestionFirst() {
-        String backgroundText = PeopleSpaceUtils.getBackgroundTextFromMessage(
-                "test?? in the middle!!");
-
-        assertThat(backgroundText).isEqualTo("?");
-    }
-
-    @Test
-    public void testGetBackgroundTextFromMessageExclamationFirst() {
-        String backgroundText = PeopleSpaceUtils.getBackgroundTextFromMessage(
-                "test!! in the middle??");
-
-        assertThat(backgroundText).isEqualTo("!");
-    }
-
-    @Test
-    public void testGetLastMessagingStyleMessage() {
+    public void testGetMessagingStyleMessages() {
         StatusBarNotification sbn = new SbnBuilder()
                 .setNotification(mNotification1)
                 .build();
 
-        Notification.MessagingStyle.Message lastMessage =
-                PeopleSpaceUtils.getLastMessagingStyleMessage(sbn.getNotification());
+        List<Notification.MessagingStyle.Message> messages =
+                PeopleSpaceUtils.getMessagingStyleMessages(sbn.getNotification());
 
-        assertThat(lastMessage.getText().toString()).isEqualTo(NOTIFICATION_TEXT_2);
+        assertThat(messages.size()).isEqualTo(3);
+        assertThat(messages.get(0).getText().toString()).isEqualTo(NOTIFICATION_TEXT_2);
     }
 
     @Test
@@ -687,225 +574,6 @@
                 any());
     }
 
-    @Test
-    public void testCreateRemoteViewsWithLastInteractionTime() {
-        RemoteViews views = PeopleSpaceUtils.createRemoteViews(mMockContext,
-                PERSON_TILE_WITHOUT_NOTIFICATION, 0, mOptions);
-        View result = views.apply(mContext, null);
-
-        TextView name = (TextView) result.findViewById(R.id.name);
-        assertEquals(name.getText(), NAME);
-        // Has last interaction.
-        TextView lastInteraction = (TextView) result.findViewById(R.id.last_interaction);
-        assertEquals(lastInteraction.getText(), mContext.getString(R.string.basic_status));
-        // No availability.
-        View availability = result.findViewById(R.id.availability);
-        assertEquals(View.GONE, availability.getVisibility());
-        // Shows person icon.
-        View personIcon = result.findViewById(R.id.person_icon);
-        assertEquals(View.VISIBLE, personIcon.getVisibility());
-        // No status.
-        assertThat((View) result.findViewById(R.id.text_content)).isNull();
-
-        mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH, REQUIRED_WIDTH_FOR_MEDIUM - 1);
-        RemoteViews smallView = PeopleSpaceUtils.createRemoteViews(mContext,
-                PERSON_TILE_WITHOUT_NOTIFICATION, 0, mOptions);
-        View smallResult = smallView.apply(mContext, null);
-
-        // Show name over predefined icon.
-        assertEquals(View.VISIBLE, smallResult.findViewById(R.id.name).getVisibility());
-        assertEquals(View.GONE, smallResult.findViewById(R.id.predefined_icon).getVisibility());
-        // Shows person icon.
-        assertEquals(View.VISIBLE, smallResult.findViewById(R.id.person_icon).getVisibility());
-    }
-
-    @Test
-    public void testCreateRemoteViewsWithGameTypeOnlyIsIgnored() {
-        PeopleSpaceTile tileWithAvailabilityAndNewStory =
-                PERSON_TILE_WITHOUT_NOTIFICATION.toBuilder().setStatuses(
-                        Arrays.asList(NEW_STORY_WITH_AVAILABILITY,
-                                new ConversationStatus.Builder(
-                                        PERSON_TILE_WITHOUT_NOTIFICATION.getId(),
-                                        ACTIVITY_GAME).build())).build();
-        RemoteViews views = PeopleSpaceUtils.createRemoteViews(mMockContext,
-                tileWithAvailabilityAndNewStory, 0, mOptions);
-        View result = views.apply(mContext, null);
-
-        TextView name = (TextView) result.findViewById(R.id.name);
-        assertEquals(name.getText(), NAME);
-        // Has last interaction over status.
-        TextView lastInteraction = (TextView) result.findViewById(R.id.last_interaction);
-        assertEquals(lastInteraction.getText(), mContext.getString(R.string.basic_status));
-        // Has availability.
-        View availability = result.findViewById(R.id.availability);
-        assertEquals(View.VISIBLE, availability.getVisibility());
-        // Has person icon.
-        View personIcon = result.findViewById(R.id.person_icon);
-        assertEquals(View.VISIBLE, personIcon.getVisibility());
-        // No status.
-        assertThat((View) result.findViewById(R.id.text_content)).isNull();
-
-        mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH, REQUIRED_WIDTH_FOR_MEDIUM - 1);
-        RemoteViews smallView = PeopleSpaceUtils.createRemoteViews(mContext,
-                tileWithAvailabilityAndNewStory, 0, mOptions);
-        View smallResult = smallView.apply(mContext, null);
-
-        // Show name rather than game type.
-        assertEquals(View.VISIBLE, smallResult.findViewById(R.id.name).getVisibility());
-        assertEquals(View.GONE, smallResult.findViewById(R.id.predefined_icon).getVisibility());
-        // Has person icon.
-        assertEquals(View.VISIBLE,
-                smallResult.findViewById(R.id.person_icon).getVisibility());
-    }
-
-    @Test
-    public void testCreateRemoteViewsWithBirthdayTypeOnlyIsNotIgnored() {
-        PeopleSpaceTile tileWithStatusTemplate =
-                PERSON_TILE_WITHOUT_NOTIFICATION.toBuilder().setStatuses(
-                        Arrays.asList(
-                                NEW_STORY_WITH_AVAILABILITY, new ConversationStatus.Builder(
-                                        PERSON_TILE_WITHOUT_NOTIFICATION.getId(),
-                                        ACTIVITY_BIRTHDAY).build())).build();
-        RemoteViews views = PeopleSpaceUtils.createRemoteViews(mContext,
-                tileWithStatusTemplate, 0, mOptions);
-        View result = views.apply(mContext, null);
-
-        TextView name = (TextView) result.findViewById(R.id.name);
-        assertEquals(name.getText(), NAME);
-        // Has availability.
-        View availability = result.findViewById(R.id.availability);
-        assertEquals(View.VISIBLE, availability.getVisibility());
-        // Has person icon.
-        View personIcon = result.findViewById(R.id.person_icon);
-        assertEquals(View.VISIBLE, personIcon.getVisibility());
-        // Has status text from backup text.
-        TextView statusContent = (TextView) result.findViewById(R.id.text_content);
-        assertEquals(statusContent.getText(), mContext.getString(R.string.birthday_status));
-
-        mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH, REQUIRED_WIDTH_FOR_MEDIUM - 1);
-        RemoteViews smallView = PeopleSpaceUtils.createRemoteViews(mContext,
-                tileWithStatusTemplate, 0, mOptions);
-        View smallResult = smallView.apply(mContext, null);
-
-        // Show icon instead of name.
-        assertEquals(View.GONE, smallResult.findViewById(R.id.name).getVisibility());
-        assertEquals(View.VISIBLE,
-                smallResult.findViewById(R.id.predefined_icon).getVisibility());
-        // Has person icon.
-        assertEquals(View.VISIBLE,
-                smallResult.findViewById(R.id.person_icon).getVisibility());
-    }
-
-    @Test
-    public void testCreateRemoteViewsWithStatusTemplate() {
-        PeopleSpaceTile tileWithStatusTemplate =
-                PERSON_TILE_WITHOUT_NOTIFICATION.toBuilder().setStatuses(
-                        Arrays.asList(GAME_STATUS,
-                                NEW_STORY_WITH_AVAILABILITY)).build();
-        RemoteViews views = PeopleSpaceUtils.createRemoteViews(mContext,
-                tileWithStatusTemplate, 0, mOptions);
-        View result = views.apply(mContext, null);
-
-        TextView name = (TextView) result.findViewById(R.id.name);
-        assertEquals(name.getText(), NAME);
-        // Has availability.
-        View availability = result.findViewById(R.id.availability);
-        assertEquals(View.VISIBLE, availability.getVisibility());
-        // Has person icon.
-        View personIcon = result.findViewById(R.id.person_icon);
-        assertEquals(View.VISIBLE, personIcon.getVisibility());
-        // Has status.
-        TextView statusContent = (TextView) result.findViewById(R.id.text_content);
-        assertEquals(statusContent.getText(), GAME_DESCRIPTION);
-
-        mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH, REQUIRED_WIDTH_FOR_MEDIUM - 1);
-        RemoteViews smallView = PeopleSpaceUtils.createRemoteViews(mContext,
-                tileWithStatusTemplate, 0, mOptions);
-        View smallResult = smallView.apply(mContext, null);
-
-        // Show icon instead of name.
-        assertEquals(View.GONE, smallResult.findViewById(R.id.name).getVisibility());
-        assertEquals(View.VISIBLE,
-                smallResult.findViewById(R.id.predefined_icon).getVisibility());
-        // Has person icon.
-        assertEquals(View.VISIBLE,
-                smallResult.findViewById(R.id.person_icon).getVisibility());
-    }
-
-    @Test
-    public void testCreateRemoteViewsWithMissedCallNotification() {
-        PeopleSpaceTile tileWithMissedCallNotification = PERSON_TILE.toBuilder()
-                .setNotificationDataUri(null)
-                .setNotificationCategory(CATEGORY_MISSED_CALL)
-                .setNotificationContent(MISSED_CALL)
-                .build();
-        RemoteViews views = PeopleSpaceUtils.createRemoteViews(mContext,
-                tileWithMissedCallNotification, 0, mOptions);
-        View result = views.apply(mContext, null);
-
-        TextView name = (TextView) result.findViewById(R.id.name);
-        assertEquals(name.getText(), NAME);
-        // Has availability.
-        View availability = result.findViewById(R.id.availability);
-        assertEquals(View.GONE, availability.getVisibility());
-        // Has person icon.
-        View personIcon = result.findViewById(R.id.person_icon);
-        assertEquals(View.VISIBLE, personIcon.getVisibility());
-        // Has missed call notification content.
-        TextView statusContent = (TextView) result.findViewById(R.id.text_content);
-        assertEquals(statusContent.getText(), MISSED_CALL);
-
-        mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH, REQUIRED_WIDTH_FOR_MEDIUM - 1);
-        RemoteViews smallView = PeopleSpaceUtils.createRemoteViews(mContext,
-                tileWithMissedCallNotification, 0, mOptions);
-        View smallResult = smallView.apply(mContext, null);
-
-        // Show icon instead of name.
-        assertEquals(View.GONE, smallResult.findViewById(R.id.name).getVisibility());
-        assertEquals(View.VISIBLE,
-                smallResult.findViewById(R.id.predefined_icon).getVisibility());
-        // Has person icon.
-        assertEquals(View.VISIBLE, smallResult.findViewById(R.id.person_icon).getVisibility());
-    }
-
-    @Test
-    public void testCreateRemoteViewsWithNotificationTemplate() {
-        PeopleSpaceTile tileWithStatusAndNotification = PERSON_TILE.toBuilder()
-                .setNotificationDataUri(null)
-                .setStatuses(Arrays.asList(GAME_STATUS,
-                        NEW_STORY_WITH_AVAILABILITY)).build();
-        RemoteViews views = PeopleSpaceUtils.createRemoteViews(mContext,
-                tileWithStatusAndNotification, 0, mOptions);
-        View result = views.apply(mContext, null);
-
-        TextView name = (TextView) result.findViewById(R.id.name);
-        assertEquals(name.getText(), NAME);
-        TextView subtext = (TextView) result.findViewById(R.id.subtext);
-        assertEquals(View.GONE, subtext.getVisibility());
-        // Has availability.
-        View availability = result.findViewById(R.id.availability);
-        assertEquals(View.VISIBLE, availability.getVisibility());
-        // Has person icon.
-        View personIcon = result.findViewById(R.id.person_icon);
-        assertEquals(View.VISIBLE, personIcon.getVisibility());
-        // Has notification content.
-        TextView statusContent = (TextView) result.findViewById(R.id.text_content);
-        assertEquals(statusContent.getText(), NOTIFICATION_CONTENT);
-
-        mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH, REQUIRED_WIDTH_FOR_MEDIUM - 1);
-        RemoteViews smallView = PeopleSpaceUtils.createRemoteViews(mContext,
-                tileWithStatusAndNotification, 0, mOptions);
-        View smallResult = smallView.apply(mContext, null);
-
-        // Show icon instead of name.
-        assertEquals(View.GONE, smallResult.findViewById(R.id.name).getVisibility());
-        assertEquals(View.VISIBLE,
-                smallResult.findViewById(R.id.predefined_icon).getVisibility());
-        // Has person icon.
-        assertEquals(View.VISIBLE,
-                smallResult.findViewById(R.id.person_icon).getVisibility());
-    }
-
     private ConversationChannelWrapper getConversationChannelWrapper(String shortcutId,
             boolean importantConversation, long lastInteractionTimestamp) throws Exception {
         ConversationChannelWrapper convo = new ConversationChannelWrapper();
@@ -931,13 +599,4 @@
                 eq(shortcutId))).thenReturn(lastInteractionTimestamp);
         return convo;
     }
-
-    private ConversationChannel getConversationChannelWithoutTimestamp(String shortcutId)
-            throws Exception {
-        ShortcutInfo shortcutInfo = new ShortcutInfo.Builder(mContext, shortcutId).setLongLabel(
-                "name").build();
-        ConversationChannel convo = new ConversationChannel(shortcutInfo, 0, null, null,
-                0L, false);
-        return convo;
-    }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/people/PeopleTileViewHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/people/PeopleTileViewHelperTest.java
new file mode 100644
index 0000000..8db0f33
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/people/PeopleTileViewHelperTest.java
@@ -0,0 +1,670 @@
+/*
+ * 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.people;
+
+import static android.app.Notification.CATEGORY_MISSED_CALL;
+import static android.app.people.ConversationStatus.ACTIVITY_BIRTHDAY;
+import static android.app.people.ConversationStatus.ACTIVITY_GAME;
+import static android.app.people.ConversationStatus.ACTIVITY_NEW_STORY;
+import static android.app.people.ConversationStatus.AVAILABILITY_AVAILABLE;
+import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH;
+
+import static com.android.systemui.people.widget.AppWidgetOptionsHelper.OPTIONS_PEOPLE_TILE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.app.people.ConversationStatus;
+import android.app.people.PeopleSpaceTile;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.graphics.drawable.Icon;
+import android.net.Uri;
+import android.os.Bundle;
+import android.testing.AndroidTestingRunner;
+import android.util.DisplayMetrics;
+import android.view.View;
+import android.widget.RemoteViews;
+import android.widget.TextView;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.R;
+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 java.util.Arrays;
+
+@RunWith(AndroidTestingRunner.class)
+@SmallTest
+public class PeopleTileViewHelperTest extends SysuiTestCase {
+
+    private static final String SHORTCUT_ID_1 = "101";
+    private static final String NOTIFICATION_KEY = "notification_key";
+    private static final String NOTIFICATION_CONTENT = "notification_content";
+    private static final Uri URI = Uri.parse("fake_uri");
+    private static final Icon ICON = Icon.createWithResource("package", R.drawable.ic_android);
+    private static final String GAME_DESCRIPTION = "Playing a game!";
+    private static final CharSequence MISSED_CALL = "Custom missed call message";
+    private static final String NAME = "username";
+    private static final PeopleSpaceTile PERSON_TILE_WITHOUT_NOTIFICATION =
+            new PeopleSpaceTile
+                    .Builder(SHORTCUT_ID_1, NAME, ICON, new Intent())
+                    .setLastInteractionTimestamp(0L)
+                    .build();
+    private static final PeopleSpaceTile PERSON_TILE =
+            new PeopleSpaceTile
+                    .Builder(SHORTCUT_ID_1, NAME, ICON, new Intent())
+                    .setLastInteractionTimestamp(123L)
+                    .setNotificationKey(NOTIFICATION_KEY)
+                    .setNotificationContent(NOTIFICATION_CONTENT)
+                    .setNotificationDataUri(URI)
+                    .build();
+    private static final ConversationStatus GAME_STATUS =
+            new ConversationStatus
+                    .Builder(PERSON_TILE.getId(), ACTIVITY_GAME)
+                    .setDescription(GAME_DESCRIPTION)
+                    .build();
+    private static final ConversationStatus NEW_STORY_WITH_AVAILABILITY =
+            new ConversationStatus
+                    .Builder(PERSON_TILE.getId(), ACTIVITY_NEW_STORY)
+                    .setAvailability(AVAILABILITY_AVAILABLE)
+                    .build();
+
+    @Mock
+    private Context mMockContext;
+    @Mock
+    private PackageManager mPackageManager;
+
+    private Bundle mOptions;
+    private PeopleTileViewHelper mPeopleTileViewHelper;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+
+        mOptions = new Bundle();
+        mOptions.putParcelable(OPTIONS_PEOPLE_TILE, PERSON_TILE);
+
+        when(mMockContext.getString(R.string.birthday_status)).thenReturn(
+                mContext.getString(R.string.birthday_status));
+        when(mMockContext.getString(R.string.basic_status)).thenReturn(
+                mContext.getString(R.string.basic_status));
+        when(mMockContext.getPackageManager()).thenReturn(mPackageManager);
+        when(mMockContext.getString(R.string.over_timestamp)).thenReturn(
+                mContext.getString(R.string.over_timestamp));
+        Configuration configuration = mock(Configuration.class);
+        DisplayMetrics displayMetrics = mock(DisplayMetrics.class);
+        Resources resources = mock(Resources.class);
+        when(mMockContext.getResources()).thenReturn(resources);
+        when(resources.getConfiguration()).thenReturn(configuration);
+        when(resources.getDisplayMetrics()).thenReturn(displayMetrics);
+        TextView textView = mock(TextView.class);
+        // when(new TextView(mMockContext)).thenReturn(textView);
+        when(textView.getLineHeight()).thenReturn(16);
+        when(mPackageManager.getApplicationIcon(anyString())).thenReturn(null);
+        mPeopleTileViewHelper = new PeopleTileViewHelper(mContext,
+                PERSON_TILE, 0, mOptions);
+    }
+
+    @Test
+    public void testCreateRemoteViewsWithLastInteractionTime() {
+        RemoteViews views = new PeopleTileViewHelper(mContext,
+                PERSON_TILE_WITHOUT_NOTIFICATION, 0, mOptions).getViews();
+        View result = views.apply(mContext, null);
+
+        TextView name = (TextView) result.findViewById(R.id.name);
+        assertEquals(name.getText(), NAME);
+        // Has last interaction.
+        TextView lastInteraction = (TextView) result.findViewById(R.id.last_interaction);
+        assertEquals(lastInteraction.getText(), mContext.getString(R.string.basic_status));
+        // No availability.
+        assertEquals(View.GONE, result.findViewById(R.id.availability).getVisibility());
+        // Shows person icon.
+        assertEquals(View.VISIBLE, result.findViewById(R.id.person_icon).getVisibility());
+        // No status.
+        assertThat((View) result.findViewById(R.id.text_content)).isNull();
+
+        mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
+                getSizeInDp(R.dimen.required_width_for_medium) - 1);
+        RemoteViews smallView = new PeopleTileViewHelper(mContext,
+                PERSON_TILE_WITHOUT_NOTIFICATION, 0, mOptions).getViews();
+        View smallResult = smallView.apply(mContext, null);
+
+        // Show name over predefined icon.
+        assertEquals(View.VISIBLE, smallResult.findViewById(R.id.name).getVisibility());
+        assertEquals(View.GONE, smallResult.findViewById(R.id.predefined_icon).getVisibility());
+        // Shows person icon.
+        assertEquals(View.VISIBLE, smallResult.findViewById(R.id.person_icon).getVisibility());
+
+        mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
+                getSizeInDp(R.dimen.required_width_for_large));
+        mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
+                getSizeInDp(R.dimen.required_height_for_large));
+        RemoteViews largeView = new PeopleTileViewHelper(mContext,
+                PERSON_TILE_WITHOUT_NOTIFICATION, 0, mOptions).getViews();
+        View largeResult = largeView.apply(mContext, null);
+
+        name = (TextView) largeResult.findViewById(R.id.name);
+        assertEquals(name.getText(), NAME);
+        // Has last interaction.
+        lastInteraction = (TextView) result.findViewById(R.id.last_interaction);
+        assertEquals(lastInteraction.getText(), mContext.getString(R.string.basic_status));
+        // No availability.
+        assertEquals(View.GONE, result.findViewById(R.id.availability).getVisibility());
+        // Shows person icon.
+        assertEquals(View.VISIBLE, result.findViewById(R.id.person_icon).getVisibility());
+        // No status.
+        assertThat((View) result.findViewById(R.id.text_content)).isNull();
+    }
+
+    @Test
+    public void testCreateRemoteViewsWithGameTypeOnlyIsIgnored() {
+        PeopleSpaceTile tileWithAvailabilityAndNewStory =
+                PERSON_TILE_WITHOUT_NOTIFICATION.toBuilder().setStatuses(
+                        Arrays.asList(NEW_STORY_WITH_AVAILABILITY,
+                                new ConversationStatus.Builder(
+                                        PERSON_TILE_WITHOUT_NOTIFICATION.getId(),
+                                        ACTIVITY_GAME).build())).build();
+        RemoteViews views = new PeopleTileViewHelper(mContext,
+                tileWithAvailabilityAndNewStory, 0, mOptions).getViews();
+        View result = views.apply(mContext, null);
+
+        TextView name = (TextView) result.findViewById(R.id.name);
+        assertEquals(name.getText(), NAME);
+        // Has last interaction over status.
+        TextView lastInteraction = (TextView) result.findViewById(R.id.last_interaction);
+        assertEquals(lastInteraction.getText(), mContext.getString(R.string.basic_status));
+        // Has availability.
+        assertEquals(View.VISIBLE, result.findViewById(R.id.availability).getVisibility());
+        // Has person icon.
+        assertEquals(View.VISIBLE, result.findViewById(R.id.person_icon).getVisibility());
+        // No status.
+        assertThat((View) result.findViewById(R.id.text_content)).isNull();
+
+        mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
+                getSizeInDp(R.dimen.required_width_for_medium) - 1);
+        RemoteViews smallView = new PeopleTileViewHelper(mContext,
+                tileWithAvailabilityAndNewStory, 0, mOptions).getViews();
+        View smallResult = smallView.apply(mContext, null);
+
+        // Show name rather than game type.
+        assertEquals(View.VISIBLE, smallResult.findViewById(R.id.name).getVisibility());
+        assertEquals(View.GONE, smallResult.findViewById(R.id.predefined_icon).getVisibility());
+        // Has person icon.
+        assertEquals(View.VISIBLE,
+                smallResult.findViewById(R.id.person_icon).getVisibility());
+
+        mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
+                getSizeInDp(R.dimen.required_width_for_large));
+        mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
+                getSizeInDp(R.dimen.required_height_for_large));
+        RemoteViews largeView = new PeopleTileViewHelper(mContext,
+                tileWithAvailabilityAndNewStory, 0, mOptions).getViews();
+        View largeResult = largeView.apply(mContext, null);
+
+        name = (TextView) largeResult.findViewById(R.id.name);
+        assertEquals(name.getText(), NAME);
+        // Has last interaction.
+        lastInteraction = (TextView) result.findViewById(R.id.last_interaction);
+        assertEquals(lastInteraction.getText(), mContext.getString(R.string.basic_status));
+        // Has availability.
+        assertEquals(View.VISIBLE, result.findViewById(R.id.availability).getVisibility());
+        // Shows person icon.
+        assertEquals(View.VISIBLE, result.findViewById(R.id.person_icon).getVisibility());
+        // No status.
+        assertThat((View) result.findViewById(R.id.text_content)).isNull();
+    }
+
+    @Test
+    public void testCreateRemoteViewsWithBirthdayTypeOnlyIsNotIgnored() {
+        PeopleSpaceTile tileWithStatusTemplate =
+                PERSON_TILE_WITHOUT_NOTIFICATION.toBuilder().setStatuses(
+                        Arrays.asList(
+                                NEW_STORY_WITH_AVAILABILITY, new ConversationStatus.Builder(
+                                        PERSON_TILE_WITHOUT_NOTIFICATION.getId(),
+                                        ACTIVITY_BIRTHDAY).build())).build();
+        RemoteViews views = new PeopleTileViewHelper(mContext,
+                tileWithStatusTemplate, 0, mOptions).getViews();
+        View result = views.apply(mContext, null);
+
+        TextView name = (TextView) result.findViewById(R.id.name);
+        assertEquals(name.getText(), NAME);
+        assertEquals(View.GONE, result.findViewById(R.id.subtext).getVisibility());
+        assertEquals(View.VISIBLE, result.findViewById(R.id.predefined_icon).getVisibility());
+        // Has availability.
+        assertEquals(View.VISIBLE, result.findViewById(R.id.availability).getVisibility());
+        // Has person icon.
+        assertEquals(View.VISIBLE, result.findViewById(R.id.person_icon).getVisibility());
+        // Has status text from backup text.
+        TextView statusContent = (TextView) result.findViewById(R.id.text_content);
+        assertEquals(View.VISIBLE, statusContent.getVisibility());
+        assertEquals(statusContent.getText(), mContext.getString(R.string.birthday_status));
+        assertThat(statusContent.getMaxLines()).isEqualTo(3);
+
+        mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
+                getSizeInDp(R.dimen.required_width_for_medium) - 1);
+        RemoteViews smallView = new PeopleTileViewHelper(mContext,
+                tileWithStatusTemplate, 0, mOptions).getViews();
+        View smallResult = smallView.apply(mContext, null);
+
+        // Show icon instead of name.
+        assertEquals(View.GONE, smallResult.findViewById(R.id.name).getVisibility());
+        assertEquals(View.VISIBLE,
+                smallResult.findViewById(R.id.predefined_icon).getVisibility());
+        // Has person icon.
+        assertEquals(View.VISIBLE,
+                smallResult.findViewById(R.id.person_icon).getVisibility());
+
+        mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
+                getSizeInDp(R.dimen.required_width_for_large));
+        mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
+                getSizeInDp(R.dimen.required_height_for_large));
+        RemoteViews largeView = new PeopleTileViewHelper(mContext,
+                tileWithStatusTemplate, 0, mOptions).getViews();
+        View largeResult = largeView.apply(mContext, null);
+
+        name = (TextView) largeResult.findViewById(R.id.name);
+        assertEquals(name.getText(), NAME);
+        assertEquals(View.GONE, largeResult.findViewById(R.id.subtext).getVisibility());
+        assertEquals(View.VISIBLE, largeResult.findViewById(R.id.predefined_icon).getVisibility());
+        // Has availability.
+        assertEquals(View.VISIBLE, largeResult.findViewById(R.id.availability).getVisibility());
+        // Has person icon.
+        View personIcon = largeResult.findViewById(R.id.person_icon);
+        assertEquals(View.VISIBLE, personIcon.getVisibility());
+        // Has notification content.
+        statusContent = (TextView) largeResult.findViewById(R.id.text_content);
+        assertEquals(View.VISIBLE, statusContent.getVisibility());
+        assertEquals(statusContent.getText(), mContext.getString(R.string.birthday_status));
+        assertThat(statusContent.getMaxLines()).isEqualTo(3);
+    }
+
+    @Test
+    public void testCreateRemoteViewsWithStatusTemplate() {
+        PeopleSpaceTile tileWithStatusTemplate =
+                PERSON_TILE_WITHOUT_NOTIFICATION.toBuilder().setStatuses(
+                        Arrays.asList(GAME_STATUS,
+                                NEW_STORY_WITH_AVAILABILITY)).build();
+        RemoteViews views = new PeopleTileViewHelper(mContext,
+                tileWithStatusTemplate, 0, mOptions).getViews();
+        View result = views.apply(mContext, null);
+
+        TextView name = (TextView) result.findViewById(R.id.name);
+        assertEquals(name.getText(), NAME);
+        assertEquals(View.GONE, result.findViewById(R.id.subtext).getVisibility());
+        assertEquals(View.VISIBLE, result.findViewById(R.id.predefined_icon).getVisibility());
+        // Has availability.
+        assertEquals(View.VISIBLE, result.findViewById(R.id.availability).getVisibility());
+        // Has person icon.
+        assertEquals(View.VISIBLE, result.findViewById(R.id.person_icon).getVisibility());
+        // Has status.
+        TextView statusContent = (TextView) result.findViewById(R.id.text_content);
+        assertEquals(statusContent.getText(), GAME_DESCRIPTION);
+        assertThat(statusContent.getMaxLines()).isEqualTo(3);
+
+        mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
+                getSizeInDp(R.dimen.required_width_for_medium) - 1);
+        RemoteViews smallView = new PeopleTileViewHelper(mContext,
+                tileWithStatusTemplate, 0, mOptions).getViews();
+        View smallResult = smallView.apply(mContext, null);
+
+        // Show icon instead of name.
+        assertEquals(View.GONE, smallResult.findViewById(R.id.name).getVisibility());
+        assertEquals(View.VISIBLE,
+                smallResult.findViewById(R.id.predefined_icon).getVisibility());
+        // Has person icon.
+        assertEquals(View.VISIBLE,
+                smallResult.findViewById(R.id.person_icon).getVisibility());
+
+        mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
+                getSizeInDp(R.dimen.required_width_for_large));
+        mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
+                getSizeInDp(R.dimen.required_height_for_large));
+        RemoteViews largeView = new PeopleTileViewHelper(mContext,
+                tileWithStatusTemplate, 0, mOptions).getViews();
+        View largeResult = largeView.apply(mContext, null);
+
+        name = (TextView) largeResult.findViewById(R.id.name);
+        assertEquals(name.getText(), NAME);
+        assertEquals(View.GONE, largeResult.findViewById(R.id.subtext).getVisibility());
+        assertEquals(View.VISIBLE, largeResult.findViewById(R.id.predefined_icon).getVisibility());
+        // Has availability.
+        assertEquals(View.VISIBLE, largeResult.findViewById(R.id.availability).getVisibility());
+        // Has person icon.
+        View personIcon = largeResult.findViewById(R.id.person_icon);
+        assertEquals(View.VISIBLE, personIcon.getVisibility());
+        // Has notification content.
+        statusContent = (TextView) largeResult.findViewById(R.id.text_content);
+        assertEquals(View.VISIBLE, statusContent.getVisibility());
+        assertEquals(statusContent.getText(), GAME_DESCRIPTION);
+        assertThat(statusContent.getMaxLines()).isEqualTo(3);
+    }
+
+    @Test
+    public void testCreateRemoteViewsWithMissedCallNotification() {
+        PeopleSpaceTile tileWithMissedCallNotification = PERSON_TILE.toBuilder()
+                .setNotificationDataUri(null)
+                .setNotificationCategory(CATEGORY_MISSED_CALL)
+                .setNotificationContent(MISSED_CALL)
+                .build();
+        RemoteViews views = new PeopleTileViewHelper(mContext,
+                tileWithMissedCallNotification, 0, mOptions).getViews();
+        View result = views.apply(mContext, null);
+
+        TextView name = (TextView) result.findViewById(R.id.name);
+        assertEquals(name.getText(), NAME);
+        assertEquals(View.GONE, result.findViewById(R.id.subtext).getVisibility());
+        assertEquals(View.VISIBLE, result.findViewById(R.id.predefined_icon).getVisibility());
+        // Has availability.
+        assertEquals(View.GONE, result.findViewById(R.id.availability).getVisibility());
+        // Has person icon.
+        assertEquals(View.VISIBLE, result.findViewById(R.id.person_icon).getVisibility());
+        // Has missed call notification content.
+        TextView statusContent = (TextView) result.findViewById(R.id.text_content);
+        assertEquals(View.VISIBLE, statusContent.getVisibility());
+        assertEquals(statusContent.getText(), MISSED_CALL);
+        assertThat(statusContent.getMaxLines()).isEqualTo(3);
+
+        mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
+                getSizeInDp(R.dimen.required_width_for_medium) - 1);
+        RemoteViews smallView = new PeopleTileViewHelper(mContext,
+                tileWithMissedCallNotification, 0, mOptions).getViews();
+        View smallResult = smallView.apply(mContext, null);
+
+        // Show icon instead of name.
+        assertEquals(View.GONE, smallResult.findViewById(R.id.name).getVisibility());
+        assertEquals(View.VISIBLE,
+                smallResult.findViewById(R.id.predefined_icon).getVisibility());
+        // Has person icon.
+        assertEquals(View.VISIBLE, smallResult.findViewById(R.id.person_icon).getVisibility());
+
+        mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
+                getSizeInDp(R.dimen.required_width_for_large));
+        mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
+                getSizeInDp(R.dimen.required_height_for_large));
+        RemoteViews largeView = new PeopleTileViewHelper(mContext,
+                tileWithMissedCallNotification, 0, mOptions).getViews();
+        View largeResult = largeView.apply(mContext, null);
+
+        name = (TextView) largeResult.findViewById(R.id.name);
+        assertEquals(name.getText(), NAME);
+        assertEquals(View.GONE, largeResult.findViewById(R.id.subtext).getVisibility());
+        assertEquals(View.VISIBLE, largeResult.findViewById(R.id.predefined_icon).getVisibility());
+        // Has availability.
+        assertEquals(View.GONE, largeResult.findViewById(R.id.availability).getVisibility());
+        // Has person icon.
+        View personIcon = largeResult.findViewById(R.id.person_icon);
+        assertEquals(View.VISIBLE, personIcon.getVisibility());
+        // Has notification content.
+        statusContent = (TextView) largeResult.findViewById(R.id.text_content);
+        assertEquals(View.VISIBLE, statusContent.getVisibility());
+        assertEquals(statusContent.getText(), MISSED_CALL);
+        assertThat(statusContent.getMaxLines()).isEqualTo(3);
+    }
+
+    @Test
+    public void testCreateRemoteViewsWithNotificationTemplate() {
+        PeopleSpaceTile tileWithStatusAndNotification = PERSON_TILE.toBuilder()
+                .setNotificationDataUri(null)
+                .setStatuses(Arrays.asList(GAME_STATUS,
+                        NEW_STORY_WITH_AVAILABILITY)).build();
+        RemoteViews views = new PeopleTileViewHelper(mContext,
+                tileWithStatusAndNotification, 0, mOptions).getViews();
+        View result = views.apply(mContext, null);
+
+        TextView name = (TextView) result.findViewById(R.id.name);
+        assertEquals(name.getText(), NAME);
+        assertEquals(View.GONE, result.findViewById(R.id.subtext).getVisibility());
+        assertEquals(View.GONE, result.findViewById(R.id.predefined_icon).getVisibility());
+        // Has availability.
+        assertEquals(View.VISIBLE, result.findViewById(R.id.availability).getVisibility());
+        // Has person icon.
+        assertEquals(View.VISIBLE, result.findViewById(R.id.person_icon).getVisibility());
+        // Has notification content.
+        TextView statusContent = (TextView) result.findViewById(R.id.text_content);
+        assertEquals(View.VISIBLE, statusContent.getVisibility());
+        assertEquals(statusContent.getText(), NOTIFICATION_CONTENT);
+        assertThat(statusContent.getMaxLines()).isEqualTo(3);
+
+        // Has a single message, no count shown.
+        assertEquals(View.GONE, result.findViewById(R.id.messages_count).getVisibility());
+
+        mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
+                getSizeInDp(R.dimen.required_width_for_medium) - 1);
+        RemoteViews smallView = new PeopleTileViewHelper(mContext,
+                tileWithStatusAndNotification, 0, mOptions).getViews();
+        View smallResult = smallView.apply(mContext, null);
+
+        // Show icon instead of name.
+        assertEquals(View.GONE, smallResult.findViewById(R.id.name).getVisibility());
+        assertEquals(View.VISIBLE,
+                smallResult.findViewById(R.id.predefined_icon).getVisibility());
+        // Has person icon.
+        assertEquals(View.VISIBLE,
+                smallResult.findViewById(R.id.person_icon).getVisibility());
+
+        // Has a single message, no count shown.
+        assertEquals(View.GONE, result.findViewById(R.id.messages_count).getVisibility());
+
+        mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
+                getSizeInDp(R.dimen.required_width_for_large));
+        mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
+                getSizeInDp(R.dimen.required_height_for_large));
+        RemoteViews largeView = new PeopleTileViewHelper(mContext,
+                tileWithStatusAndNotification, 0, mOptions).getViews();
+        View largeResult = largeView.apply(mContext, null);
+
+        name = (TextView) largeResult.findViewById(R.id.name);
+        assertEquals(name.getText(), NAME);
+        assertEquals(View.GONE, largeResult.findViewById(R.id.subtext).getVisibility());
+        assertEquals(View.GONE, largeResult.findViewById(R.id.predefined_icon).getVisibility());
+        // Has availability.
+        assertEquals(View.VISIBLE, largeResult.findViewById(R.id.availability).getVisibility());
+        // Has person icon.
+        View personIcon = largeResult.findViewById(R.id.person_icon);
+        assertEquals(View.VISIBLE, personIcon.getVisibility());
+        // Has notification content.
+        statusContent = (TextView) largeResult.findViewById(R.id.text_content);
+        assertEquals(View.VISIBLE, statusContent.getVisibility());
+        assertEquals(statusContent.getText(), NOTIFICATION_CONTENT);
+        assertThat(statusContent.getMaxLines()).isEqualTo(3);
+
+        // Has a single message, no count shown.
+        assertEquals(View.GONE, result.findViewById(R.id.messages_count).getVisibility());
+
+    }
+
+    @Test
+    public void testCreateRemoteViewsWithNotificationTemplateTwoMessages() {
+        PeopleSpaceTile tileWithStatusAndNotification = PERSON_TILE.toBuilder()
+                .setNotificationDataUri(null)
+                .setStatuses(Arrays.asList(GAME_STATUS,
+                        NEW_STORY_WITH_AVAILABILITY))
+                .setMessagesCount(2).build();
+        RemoteViews views = new PeopleTileViewHelper(mContext,
+                tileWithStatusAndNotification, 0, mOptions).getViews();
+        View result = views.apply(mContext, null);
+
+        TextView name = (TextView) result.findViewById(R.id.name);
+        assertEquals(name.getText(), NAME);
+        assertEquals(View.GONE, result.findViewById(R.id.subtext).getVisibility());
+        assertEquals(View.GONE, result.findViewById(R.id.predefined_icon).getVisibility());
+        // Has availability.
+        assertEquals(View.VISIBLE, result.findViewById(R.id.availability).getVisibility());
+        // Has person icon.
+        assertEquals(View.VISIBLE, result.findViewById(R.id.person_icon).getVisibility());
+        // Has notification content.
+        TextView statusContent = (TextView) result.findViewById(R.id.text_content);
+        assertEquals(View.VISIBLE, statusContent.getVisibility());
+        assertEquals(statusContent.getText(), NOTIFICATION_CONTENT);
+        assertThat(statusContent.getMaxLines()).isEqualTo(3);
+
+        // Has two messages, show count.
+        assertEquals(View.VISIBLE, result.findViewById(R.id.messages_count).getVisibility());
+
+        mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
+                getSizeInDp(R.dimen.required_width_for_medium) - 1);
+        RemoteViews smallView = new PeopleTileViewHelper(mContext,
+                tileWithStatusAndNotification, 0, mOptions).getViews();
+        View smallResult = smallView.apply(mContext, null);
+
+        // Show icon instead of name.
+        assertEquals(View.GONE, smallResult.findViewById(R.id.name).getVisibility());
+        assertEquals(View.GONE,
+                smallResult.findViewById(R.id.predefined_icon).getVisibility());
+        // Has person icon.
+        assertEquals(View.VISIBLE,
+                smallResult.findViewById(R.id.person_icon).getVisibility());
+
+        // Has two messages, show count.
+        assertEquals(View.VISIBLE, result.findViewById(R.id.messages_count).getVisibility());
+
+        mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
+                getSizeInDp(R.dimen.required_width_for_large));
+        mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
+                getSizeInDp(R.dimen.required_height_for_large));
+        RemoteViews largeView = new PeopleTileViewHelper(mContext,
+                tileWithStatusAndNotification, 0, mOptions).getViews();
+        View largeResult = largeView.apply(mContext, null);
+
+        name = (TextView) largeResult.findViewById(R.id.name);
+        assertEquals(name.getText(), NAME);
+        assertEquals(View.GONE, largeResult.findViewById(R.id.subtext).getVisibility());
+        assertEquals(View.GONE, largeResult.findViewById(R.id.predefined_icon).getVisibility());
+        // Has availability.
+        assertEquals(View.VISIBLE, largeResult.findViewById(R.id.availability).getVisibility());
+        // Has person icon.
+        View personIcon = largeResult.findViewById(R.id.person_icon);
+        assertEquals(View.VISIBLE, personIcon.getVisibility());
+        // Has notification content.
+        statusContent = (TextView) largeResult.findViewById(R.id.text_content);
+        assertEquals(View.VISIBLE, statusContent.getVisibility());
+        assertEquals(statusContent.getText(), NOTIFICATION_CONTENT);
+        assertThat(statusContent.getMaxLines()).isEqualTo(3);
+
+        // Has two messages, show count.
+        assertEquals(View.VISIBLE, result.findViewById(R.id.messages_count).getVisibility());
+    }
+
+
+    @Test
+    public void testGetBackgroundTextFromMessageNoPunctuation() {
+        String backgroundText = mPeopleTileViewHelper.getBackgroundTextFromMessage("test");
+
+        assertThat(backgroundText).isNull();
+    }
+
+    @Test
+    public void testGetBackgroundTextFromMessageSingleExclamation() {
+        String backgroundText = mPeopleTileViewHelper.getBackgroundTextFromMessage("test!");
+
+        assertThat(backgroundText).isNull();
+    }
+
+    @Test
+    public void testGetBackgroundTextFromMessageSingleQuestion() {
+        String backgroundText = mPeopleTileViewHelper.getBackgroundTextFromMessage("?test");
+
+        assertThat(backgroundText).isNull();
+    }
+
+    @Test
+    public void testGetBackgroundTextFromMessageSeparatedMarks() {
+        String backgroundText = mPeopleTileViewHelper.getBackgroundTextFromMessage("test! right!");
+
+        assertThat(backgroundText).isNull();
+    }
+
+    @Test
+    public void testGetBackgroundTextFromMessageDoubleExclamation() {
+        String backgroundText = mPeopleTileViewHelper.getBackgroundTextFromMessage("!!test");
+
+        assertThat(backgroundText).isEqualTo("!");
+    }
+
+    @Test
+    public void testGetBackgroundTextFromMessageDoubleQuestion() {
+        String backgroundText = mPeopleTileViewHelper.getBackgroundTextFromMessage("test??");
+
+        assertThat(backgroundText).isEqualTo("?");
+    }
+
+    @Test
+    public void testGetBackgroundTextFromMessageMixed() {
+        String backgroundText = mPeopleTileViewHelper.getBackgroundTextFromMessage("test?!");
+
+        assertThat(backgroundText).isEqualTo("!?");
+    }
+
+    @Test
+    public void testGetBackgroundTextFromMessageMixedInTheMiddle() {
+        String backgroundText = mPeopleTileViewHelper.getBackgroundTextFromMessage(
+                "test!? in the middle");
+
+        assertThat(backgroundText).isEqualTo("!?");
+    }
+
+    @Test
+    public void testGetBackgroundTextFromMessageMixedDifferentOrder() {
+        String backgroundText = mPeopleTileViewHelper.getBackgroundTextFromMessage(
+                "test!? in the middle");
+
+        assertThat(backgroundText).isEqualTo("!?");
+    }
+
+    @Test
+    public void testGetBackgroundTextFromMessageMultiple() {
+        String backgroundText = mPeopleTileViewHelper.getBackgroundTextFromMessage(
+                "test!?!!? in the middle");
+
+        assertThat(backgroundText).isEqualTo("!?");
+    }
+
+    @Test
+    public void testGetBackgroundTextFromMessageQuestionFirst() {
+        String backgroundText = mPeopleTileViewHelper.getBackgroundTextFromMessage(
+                "test?? in the middle!!");
+
+        assertThat(backgroundText).isEqualTo("?");
+    }
+
+    @Test
+    public void testGetBackgroundTextFromMessageExclamationFirst() {
+        String backgroundText = mPeopleTileViewHelper.getBackgroundTextFromMessage(
+                "test!! in the middle??");
+
+        assertThat(backgroundText).isEqualTo("!");
+    }
+
+    private int getSizeInDp(int dimenResourceId) {
+        return (int) (mContext.getResources().getDimension(dimenResourceId)
+                / mContext.getResources().getDisplayMetrics().density);
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java
index 7090e78..d91625e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java
@@ -17,11 +17,14 @@
 package com.android.systemui.people.widget;
 
 import static android.app.Notification.CATEGORY_MISSED_CALL;
+import static android.app.Notification.EXTRA_PEOPLE_LIST;
 import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
 import static android.app.NotificationManager.IMPORTANCE_HIGH;
 import static android.app.people.ConversationStatus.ACTIVITY_ANNIVERSARY;
 import static android.app.people.ConversationStatus.ACTIVITY_BIRTHDAY;
 import static android.app.people.ConversationStatus.ACTIVITY_GAME;
+import static android.content.PermissionChecker.PERMISSION_GRANTED;
+import static android.content.PermissionChecker.PERMISSION_HARD_DENIED;
 
 import static com.android.systemui.people.PeopleSpaceUtils.EMPTY_STRING;
 import static com.android.systemui.people.PeopleSpaceUtils.INVALID_USER_ID;
@@ -55,6 +58,7 @@
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.content.pm.LauncherApps;
+import android.content.pm.PackageManager;
 import android.content.pm.ShortcutInfo;
 import android.graphics.drawable.Icon;
 import android.net.Uri;
@@ -86,6 +90,7 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.List;
@@ -106,6 +111,8 @@
     private static final int SECOND_WIDGET_ID_WITH_SHORTCUT = 3;
     private static final int WIDGET_ID_WITHOUT_SHORTCUT = 2;
     private static final int WIDGET_ID_WITH_KEY_IN_OPTIONS = 4;
+    private static final int WIDGET_ID_WITH_SAME_URI = 5;
+    private static final int WIDGET_ID_WITH_DIFFERENT_URI = 6;
     private static final String SHORTCUT_ID = "101";
     private static final String OTHER_SHORTCUT_ID = "102";
     private static final String NOTIFICATION_KEY = "0|com.android.systemui.tests|0|null|0";
@@ -123,10 +130,21 @@
             new PeopleSpaceTile
                     .Builder(SHORTCUT_ID, "username", ICON, new Intent())
                     .setPackageName(TEST_PACKAGE_A)
-                    .setUserHandle(new UserHandle(1))
+                    .setUserHandle(new UserHandle(0))
                     .setNotificationKey(NOTIFICATION_KEY + "1")
                     .setNotificationContent(NOTIFICATION_CONTENT)
                     .setNotificationDataUri(URI)
+                    .setContactUri(URI)
+                    .build();
+    private static final PeopleSpaceTile PERSON_TILE_WITH_SAME_URI =
+            new PeopleSpaceTile
+                    // Different shortcut ID
+                    .Builder(OTHER_SHORTCUT_ID, "username", ICON, new Intent())
+                    // Different package name
+                    .setPackageName(TEST_PACKAGE_B)
+                    .setUserHandle(new UserHandle(0))
+                    // Same contact uri.
+                    .setContactUri(URI)
                     .build();
     private final ShortcutInfo mShortcutInfo = new ShortcutInfo.Builder(mContext,
             SHORTCUT_ID).setLongLabel("name").build();
@@ -149,6 +167,8 @@
     private LauncherApps mLauncherApps;
     @Mock
     private NotificationEntryManager mNotificationEntryManager;
+    @Mock
+    private PackageManager mPackageManager;
 
     @Captor
     private ArgumentCaptor<NotificationHandler> mListenerCaptor;
@@ -167,7 +187,7 @@
         mDependency.injectTestDependency(NotificationEntryManager.class, mNotificationEntryManager);
         mManager = new PeopleSpaceWidgetManager(mContext);
         mManager.setAppWidgetManager(mAppWidgetManager, mIPeopleManager, mPeopleManager,
-                mLauncherApps, mNotificationEntryManager);
+                mLauncherApps, mNotificationEntryManager, mPackageManager, true);
         mManager.attach(mListenerService);
         mProvider = new PeopleSpaceWidgetProvider();
         mProvider.setPeopleSpaceWidgetManager(mManager);
@@ -177,16 +197,10 @@
         mNoMan.addListener(serviceListener);
 
         clearStorage();
-        setStorageForTile(SHORTCUT_ID, TEST_PACKAGE_A, WIDGET_ID_WITH_SHORTCUT);
-
-        Bundle options = new Bundle();
-        options.putParcelable(OPTIONS_PEOPLE_TILE, PERSON_TILE);
-        when(mAppWidgetManager.getAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT)))
-                .thenReturn(options);
+        addTileForWidget(PERSON_TILE, WIDGET_ID_WITH_SHORTCUT);
+        addTileForWidget(PERSON_TILE_WITH_SAME_URI, WIDGET_ID_WITH_SAME_URI);
         when(mAppWidgetManager.getAppWidgetOptions(eq(WIDGET_ID_WITHOUT_SHORTCUT)))
                 .thenReturn(new Bundle());
-        when(mIPeopleManager.getConversation(TEST_PACKAGE_A, 0, SHORTCUT_ID)).thenReturn(
-                getConversationWithShortcutId(SHORTCUT_ID));
     }
 
     @Test
@@ -477,7 +491,7 @@
         addSecondWidgetForPersonTile();
 
         PeopleSpaceUtils.removeSharedPreferencesStorageForTile(
-                mContext, KEY, SECOND_WIDGET_ID_WITH_SHORTCUT);
+                mContext, KEY, SECOND_WIDGET_ID_WITH_SHORTCUT, EMPTY_STRING);
         NotifEvent notif1 = mNoMan.postNotif(new NotificationEntryBuilder()
                 .setSbn(createNotification(
                         SHORTCUT_ID, /* isMessagingStyle = */ true, /* isMissedCall = */ false))
@@ -501,7 +515,6 @@
             throws Exception {
         int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT};
         when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
-        setStorageForTile(SHORTCUT_ID, TEST_PACKAGE_A, WIDGET_ID_WITH_SHORTCUT);
 
         NotifEvent notif1 = mNoMan.postNotif(new NotificationEntryBuilder()
                 .setSbn(createNotification(
@@ -527,7 +540,6 @@
             throws Exception {
         int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT};
         when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
-        setStorageForTile(SHORTCUT_ID, TEST_PACKAGE_A, WIDGET_ID_WITH_SHORTCUT);
 
         NotifEvent notif1 = mNoMan.postNotif(new NotificationEntryBuilder()
                 .setSbn(createNotification(
@@ -548,10 +560,267 @@
     }
 
     @Test
+    public void testUpdateMissedCallNotificationWithContentPostedIfMatchingUriTile()
+            throws Exception {
+        int[] widgetIdsArray =
+                {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT, WIDGET_ID_WITH_SAME_URI};
+        when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
+
+        NotifEvent notif1 = mNoMan.postNotif(new NotificationEntryBuilder()
+                .setSbn(createNotification(
+                        SHORTCUT_ID, /* isMessagingStyle = */ true, /* isMissedCall = */ true))
+                .setId(1));
+        mClock.advanceTime(MIN_LINGER_DURATION);
+
+        verify(mAppWidgetManager, times(1))
+                .updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT),
+                        mBundleArgumentCaptor.capture());
+        Bundle bundle = requireNonNull(mBundleArgumentCaptor.getValue());
+        PeopleSpaceTile tileWithMissedCallOrigin = bundle.getParcelable(OPTIONS_PEOPLE_TILE);
+        assertThat(tileWithMissedCallOrigin.getNotificationKey()).isEqualTo(NOTIFICATION_KEY);
+        assertThat(tileWithMissedCallOrigin.getNotificationContent()).isEqualTo(
+                NOTIFICATION_CONTENT);
+        verify(mAppWidgetManager, times(1)).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
+                any());
+        verify(mAppWidgetManager, times(1))
+                .updateAppWidgetOptions(eq(WIDGET_ID_WITH_SAME_URI),
+                        mBundleArgumentCaptor.capture());
+        Bundle bundleForSameUriTile = requireNonNull(mBundleArgumentCaptor.getValue());
+        PeopleSpaceTile tileWithSameUri = bundleForSameUriTile.getParcelable(OPTIONS_PEOPLE_TILE);
+        assertThat(tileWithSameUri.getNotificationKey()).isEqualTo(NOTIFICATION_KEY);
+        assertThat(tileWithSameUri.getNotificationContent()).isEqualTo(NOTIFICATION_CONTENT);
+        verify(mAppWidgetManager, times(1)).updateAppWidget(eq(WIDGET_ID_WITH_SAME_URI),
+                any());
+    }
+
+    @Test
+    public void testRemoveMissedCallNotificationWithContentPostedIfMatchingUriTile()
+            throws Exception {
+        int[] widgetIdsArray =
+                {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT, WIDGET_ID_WITH_SAME_URI};
+        when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
+
+        NotifEvent notif1 = mNoMan.postNotif(new NotificationEntryBuilder()
+                .setSbn(createNotification(
+                        SHORTCUT_ID, /* isMessagingStyle = */ true, /* isMissedCall = */ true))
+                .setId(1));
+        mClock.advanceTime(MIN_LINGER_DURATION);
+        NotifEvent notif1b = mNoMan.retractNotif(notif1.sbn.cloneLight(), 0);
+        mClock.advanceTime(MIN_LINGER_DURATION);
+
+        verify(mAppWidgetManager, times(2)).updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT),
+                mBundleArgumentCaptor.capture());
+        Bundle bundle = mBundleArgumentCaptor.getValue();
+        PeopleSpaceTile tileWithMissedCallOrigin = bundle.getParcelable(OPTIONS_PEOPLE_TILE);
+        assertThat(tileWithMissedCallOrigin.getNotificationKey()).isEqualTo(null);
+        assertThat(tileWithMissedCallOrigin.getNotificationContent()).isEqualTo(null);
+        verify(mAppWidgetManager, times(2)).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
+                any());
+        verify(mAppWidgetManager, times(2))
+                .updateAppWidgetOptions(eq(WIDGET_ID_WITH_SAME_URI),
+                        mBundleArgumentCaptor.capture());
+        Bundle bundleForSameUriTile = requireNonNull(mBundleArgumentCaptor.getValue());
+        PeopleSpaceTile tileWithSameUri = bundleForSameUriTile.getParcelable(OPTIONS_PEOPLE_TILE);
+        assertThat(tileWithSameUri.getNotificationKey()).isEqualTo(null);
+        assertThat(tileWithSameUri.getNotificationContent()).isEqualTo(null);
+        verify(mAppWidgetManager, times(2)).updateAppWidget(eq(WIDGET_ID_WITH_SAME_URI),
+                any());
+    }
+
+    @Test
+    public void testDoNotRemoveMissedCallIfMatchingUriTileMissingReadContactsPermissionWhenPosted()
+            throws Exception {
+        when(mPackageManager.checkPermission(any(),
+                eq(PERSON_TILE_WITH_SAME_URI.getPackageName()))).thenReturn(
+                PERMISSION_HARD_DENIED);
+        int[] widgetIdsArray =
+                {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT, WIDGET_ID_WITH_SAME_URI};
+        when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
+
+        NotifEvent notif1 = mNoMan.postNotif(new NotificationEntryBuilder()
+                .setSbn(createNotification(
+                        SHORTCUT_ID, /* isMessagingStyle = */ true, /* isMissedCall = */ true))
+                .setId(1));
+        mClock.advanceTime(MIN_LINGER_DURATION);
+        // We should only try to remove the notification if the Missed Call was added when posted.
+        NotifEvent notif1b = mNoMan.retractNotif(notif1.sbn.cloneLight(), 0);
+        mClock.advanceTime(MIN_LINGER_DURATION);
+
+        verify(mAppWidgetManager, times(2)).updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT),
+                mBundleArgumentCaptor.capture());
+        Bundle bundle = mBundleArgumentCaptor.getValue();
+        PeopleSpaceTile tileWithMissedCallOrigin = bundle.getParcelable(OPTIONS_PEOPLE_TILE);
+        assertThat(tileWithMissedCallOrigin.getNotificationKey()).isEqualTo(null);
+        assertThat(tileWithMissedCallOrigin.getNotificationContent()).isEqualTo(null);
+        verify(mAppWidgetManager, times(2)).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
+                any());
+        verify(mAppWidgetManager, times(0))
+                .updateAppWidgetOptions(eq(WIDGET_ID_WITH_SAME_URI), any());
+        verify(mAppWidgetManager, times(0)).updateAppWidget(eq(WIDGET_ID_WITH_SAME_URI),
+                any());
+    }
+
+    @Test
+    public void testUpdateMissedCallNotificationWithContentPostedIfMatchingUriTileFromSender()
+            throws Exception {
+        int[] widgetIdsArray =
+                {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT, WIDGET_ID_WITH_SAME_URI};
+        when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
+
+        Notification notificationWithPersonOnlyInSender =
+                createMessagingStyleNotificationWithoutExtras(
+                        SHORTCUT_ID, /* isMessagingStyle = */ true, /* isMissedCall = */
+                        true).build();
+        StatusBarNotification sbn = new SbnBuilder()
+                .setNotification(notificationWithPersonOnlyInSender)
+                .setPkg(TEST_PACKAGE_A)
+                .setUid(0)
+                .setUser(new UserHandle(0))
+                .build();
+        NotifEvent notif1 = mNoMan.postNotif(new NotificationEntryBuilder()
+                .setSbn(sbn)
+                .setId(1));
+        mClock.advanceTime(MIN_LINGER_DURATION);
+
+        verify(mAppWidgetManager, times(1))
+                .updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT),
+                        mBundleArgumentCaptor.capture());
+        Bundle bundle = requireNonNull(mBundleArgumentCaptor.getValue());
+        PeopleSpaceTile tileWithMissedCallOrigin = bundle.getParcelable(OPTIONS_PEOPLE_TILE);
+        assertThat(tileWithMissedCallOrigin.getNotificationKey()).isEqualTo(NOTIFICATION_KEY);
+        assertThat(tileWithMissedCallOrigin.getNotificationContent()).isEqualTo(
+                NOTIFICATION_CONTENT);
+        verify(mAppWidgetManager, times(1)).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
+                any());
+        verify(mAppWidgetManager, times(1))
+                .updateAppWidgetOptions(eq(WIDGET_ID_WITH_SAME_URI),
+                        mBundleArgumentCaptor.capture());
+        Bundle bundleForSameUriTile = requireNonNull(mBundleArgumentCaptor.getValue());
+        PeopleSpaceTile tileWithSameUri = bundleForSameUriTile.getParcelable(OPTIONS_PEOPLE_TILE);
+        assertThat(tileWithSameUri.getNotificationKey()).isEqualTo(NOTIFICATION_KEY);
+        assertThat(tileWithSameUri.getNotificationContent()).isEqualTo(NOTIFICATION_CONTENT);
+        verify(mAppWidgetManager, times(1)).updateAppWidget(eq(WIDGET_ID_WITH_SAME_URI),
+                any());
+    }
+
+    @Test
+    public void testDoNotUpdateMissedCallNotificationWithContentPostedIfNoPersonsAttached()
+            throws Exception {
+        int[] widgetIdsArray =
+                {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT, WIDGET_ID_WITH_SAME_URI};
+        when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
+
+        // Notification posted without any Person attached.
+        Notification notificationWithoutPersonObject =
+                createMessagingStyleNotificationWithoutExtras(
+                        SHORTCUT_ID, /* isMessagingStyle = */ true, /* isMissedCall = */
+                        true).setStyle(new Notification.MessagingStyle("sender")
+                        .addMessage(
+                                new Notification.MessagingStyle.Message(NOTIFICATION_CONTENT, 10,
+                                        "sender"))
+                ).build();
+        StatusBarNotification sbn = new SbnBuilder()
+                .setNotification(notificationWithoutPersonObject)
+                .setPkg(TEST_PACKAGE_A)
+                .setUid(0)
+                .setUser(new UserHandle(0))
+                .build();
+        NotifEvent notif1 = mNoMan.postNotif(new NotificationEntryBuilder()
+                .setSbn(sbn)
+                .setId(1));
+        mClock.advanceTime(MIN_LINGER_DURATION);
+
+        verify(mAppWidgetManager, times(1))
+                .updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT),
+                        mBundleArgumentCaptor.capture());
+        Bundle bundle = requireNonNull(mBundleArgumentCaptor.getValue());
+        PeopleSpaceTile tileWithMissedCallOrigin = bundle.getParcelable(OPTIONS_PEOPLE_TILE);
+        assertThat(tileWithMissedCallOrigin.getNotificationKey()).isEqualTo(NOTIFICATION_KEY);
+        assertThat(tileWithMissedCallOrigin.getNotificationContent()).isEqualTo(
+                NOTIFICATION_CONTENT);
+        verify(mAppWidgetManager, times(1)).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
+                any());
+        // Do not update since notification doesn't include a Person reference.
+        verify(mAppWidgetManager, times(0))
+                .updateAppWidgetOptions(eq(WIDGET_ID_WITH_SAME_URI),
+                        any());
+        verify(mAppWidgetManager, times(0)).updateAppWidget(eq(WIDGET_ID_WITH_SAME_URI),
+                any());
+    }
+
+    @Test
+    public void testDoNotUpdateMissedCallNotificationWithContentPostedIfNotMatchingUriTile()
+            throws Exception {
+        clearStorage();
+        addTileForWidget(PERSON_TILE, WIDGET_ID_WITH_SHORTCUT);
+        addTileForWidget(PERSON_TILE_WITH_SAME_URI.toBuilder().setContactUri(
+                Uri.parse("different_uri")).build(), WIDGET_ID_WITH_DIFFERENT_URI);
+        int[] widgetIdsArray =
+                {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT, WIDGET_ID_WITH_DIFFERENT_URI};
+        when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
+
+        NotifEvent notif1 = mNoMan.postNotif(new NotificationEntryBuilder()
+                .setSbn(createNotification(
+                        SHORTCUT_ID, /* isMessagingStyle = */ true, /* isMissedCall = */ true))
+                .setId(1));
+        mClock.advanceTime(MIN_LINGER_DURATION);
+
+        verify(mAppWidgetManager, times(1))
+                .updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT),
+                        mBundleArgumentCaptor.capture());
+        Bundle bundle = requireNonNull(mBundleArgumentCaptor.getValue());
+        PeopleSpaceTile tileWithMissedCallOrigin = bundle.getParcelable(OPTIONS_PEOPLE_TILE);
+        assertThat(tileWithMissedCallOrigin.getNotificationKey()).isEqualTo(NOTIFICATION_KEY);
+        assertThat(tileWithMissedCallOrigin.getNotificationContent()).isEqualTo(
+                NOTIFICATION_CONTENT);
+        verify(mAppWidgetManager, times(1)).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
+                any());
+        // Do not update since missing permission to read contacts.
+        verify(mAppWidgetManager, times(0))
+                .updateAppWidgetOptions(eq(WIDGET_ID_WITH_DIFFERENT_URI),
+                        any());
+        verify(mAppWidgetManager, times(0)).updateAppWidget(eq(WIDGET_ID_WITH_DIFFERENT_URI),
+                any());
+    }
+
+    @Test
+    public void testDoNotUpdateMissedCallIfMatchingUriTileMissingReadContactsPermission()
+            throws Exception {
+        when(mPackageManager.checkPermission(any(),
+                eq(PERSON_TILE_WITH_SAME_URI.getPackageName()))).thenReturn(
+                PERMISSION_HARD_DENIED);
+        int[] widgetIdsArray =
+                {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT, WIDGET_ID_WITH_SAME_URI};
+        when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
+
+        NotifEvent notif1 = mNoMan.postNotif(new NotificationEntryBuilder()
+                .setSbn(createNotification(
+                        SHORTCUT_ID, /* isMessagingStyle = */ true, /* isMissedCall = */ true))
+                .setId(1));
+        mClock.advanceTime(MIN_LINGER_DURATION);
+
+        verify(mAppWidgetManager, times(1))
+                .updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT),
+                        mBundleArgumentCaptor.capture());
+        Bundle bundle = requireNonNull(mBundleArgumentCaptor.getValue());
+        PeopleSpaceTile tileWithMissedCallOrigin = bundle.getParcelable(OPTIONS_PEOPLE_TILE);
+        assertThat(tileWithMissedCallOrigin.getNotificationKey()).isEqualTo(NOTIFICATION_KEY);
+        assertThat(tileWithMissedCallOrigin.getNotificationContent()).isEqualTo(
+                NOTIFICATION_CONTENT);
+        verify(mAppWidgetManager, times(1)).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
+                any());
+        // Do not update since missing permission to read contacts.
+        verify(mAppWidgetManager, times(0))
+                .updateAppWidgetOptions(eq(WIDGET_ID_WITH_SAME_URI),
+                        any());
+        verify(mAppWidgetManager, times(0)).updateAppWidget(eq(WIDGET_ID_WITH_SAME_URI),
+                any());
+    }
+
+    @Test
     public void testUpdateNotificationRemovedIfExistingTile() throws Exception {
         int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT};
         when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
-        setStorageForTile(SHORTCUT_ID, TEST_PACKAGE_A, WIDGET_ID_WITH_SHORTCUT);
 
         StatusBarNotification sbn = createNotification(
                 SHORTCUT_ID, /* isMessagingStyle = */ true, /* isMissedCall = */ false);
@@ -574,7 +843,8 @@
     }
 
     @Test
-    public void testDeleteAllWidgetsForConversationsUncachesShortcutAndRemovesListeners() {
+    public void testDeleteAllWidgetsForConversationsUncachesShortcutAndRemovesListeners()
+            throws Exception {
         addSecondWidgetForPersonTile();
         mProvider.onUpdate(mContext, mAppWidgetManager,
                 new int[]{WIDGET_ID_WITH_SHORTCUT, SECOND_WIDGET_ID_WITH_SHORTCUT});
@@ -746,19 +1016,26 @@
      * Adds another widget for {@code PERSON_TILE} with widget ID: {@code
      * SECOND_WIDGET_ID_WITH_SHORTCUT}.
      */
-    private void addSecondWidgetForPersonTile() {
-        Bundle options = new Bundle();
-        options.putParcelable(OPTIONS_PEOPLE_TILE, PERSON_TILE);
-        when(mAppWidgetManager.getAppWidgetOptions(eq(SECOND_WIDGET_ID_WITH_SHORTCUT)))
-                .thenReturn(options);
+    private void addSecondWidgetForPersonTile() throws Exception {
         // Set the same Person associated on another People Tile widget ID.
-        setStorageForTile(SHORTCUT_ID, TEST_PACKAGE_A, WIDGET_ID_WITH_SHORTCUT);
-        setStorageForTile(SHORTCUT_ID, TEST_PACKAGE_A, SECOND_WIDGET_ID_WITH_SHORTCUT);
+        addTileForWidget(PERSON_TILE, SECOND_WIDGET_ID_WITH_SHORTCUT);
         int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT,
                 SECOND_WIDGET_ID_WITH_SHORTCUT};
         when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
     }
 
+    private void addTileForWidget(PeopleSpaceTile tile, int widgetId) throws Exception {
+        setStorageForTile(tile.getId(), tile.getPackageName(), widgetId, tile.getContactUri());
+        Bundle options = new Bundle();
+        options.putParcelable(OPTIONS_PEOPLE_TILE, tile);
+        when(mAppWidgetManager.getAppWidgetOptions(eq(widgetId)))
+                .thenReturn(options);
+        when(mIPeopleManager.getConversation(tile.getPackageName(), 0, tile.getId())).thenReturn(
+                getConversationWithShortcutId(tile.getId()));
+        when(mPackageManager.checkPermission(any(), eq(tile.getPackageName()))).thenReturn(
+                PERMISSION_GRANTED);
+    }
+
     /**
      * Returns a single conversation associated with {@code shortcutId}.
      */
@@ -772,7 +1049,7 @@
     private ConversationChannel getConversationWithShortcutId(String shortcutId,
             List<ConversationStatus> statuses) throws Exception {
         ShortcutInfo shortcutInfo = new ShortcutInfo.Builder(mContext, shortcutId).setLongLabel(
-                "name").build();
+                "name").setPerson(PERSON).build();
         ConversationChannel convo = new ConversationChannel(shortcutInfo, 0, null, null,
                 0L, false, false, statuses);
         return convo;
@@ -780,6 +1057,30 @@
 
     private Notification createMessagingStyleNotification(String shortcutId,
             boolean isMessagingStyle, boolean isMissedCall) {
+        Bundle extras = new Bundle();
+        ArrayList<Person> person = new ArrayList<Person>();
+        person.add(PERSON);
+        extras.putParcelableArrayList(EXTRA_PEOPLE_LIST, person);
+        Notification.Builder builder = new Notification.Builder(mContext)
+                .setContentTitle("TEST_TITLE")
+                .setContentText("TEST_TEXT")
+                .setExtras(extras)
+                .setShortcutId(shortcutId);
+        if (isMessagingStyle) {
+            builder.setStyle(new Notification.MessagingStyle(PERSON)
+                    .addMessage(
+                            new Notification.MessagingStyle.Message(NOTIFICATION_CONTENT, 10,
+                                    PERSON))
+            );
+        }
+        if (isMissedCall) {
+            builder.setCategory(CATEGORY_MISSED_CALL);
+        }
+        return builder.build();
+    }
+
+    private Notification.Builder createMessagingStyleNotificationWithoutExtras(String shortcutId,
+            boolean isMessagingStyle, boolean isMissedCall) {
         Notification.Builder builder = new Notification.Builder(mContext)
                 .setContentTitle("TEST_TITLE")
                 .setContentText("TEST_TEXT")
@@ -794,9 +1095,10 @@
         if (isMissedCall) {
             builder.setCategory(CATEGORY_MISSED_CALL);
         }
-        return builder.build();
+        return builder;
     }
 
+
     private StatusBarNotification createNotification(String shortcutId,
             boolean isMessagingStyle, boolean isMissedCall) {
         Notification notification = createMessagingStyleNotification(
@@ -804,6 +1106,8 @@
         return new SbnBuilder()
                 .setNotification(notification)
                 .setPkg(TEST_PACKAGE_A)
+                .setUid(0)
+                .setUser(new UserHandle(0))
                 .build();
     }
 
@@ -824,11 +1128,16 @@
                 String.valueOf(WIDGET_ID_WITH_KEY_IN_OPTIONS),
                 Context.MODE_PRIVATE);
         widgetSp4.edit().clear().commit();
+        SharedPreferences widgetSp5 = mContext.getSharedPreferences(
+                String.valueOf(WIDGET_ID_WITH_SAME_URI),
+                Context.MODE_PRIVATE);
+        widgetSp5.edit().clear().commit();
         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
         sp.edit().clear().commit();
     }
 
-    private void setStorageForTile(String shortcutId, String packageName, int widgetId) {
+    private void setStorageForTile(String shortcutId, String packageName, int widgetId,
+            Uri contactUri) {
         SharedPreferences widgetSp = mContext.getSharedPreferences(
                 String.valueOf(widgetId),
                 Context.MODE_PRIVATE);
@@ -840,11 +1149,17 @@
 
         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
         SharedPreferences.Editor editor = sp.edit();
-        editor.putString(String.valueOf(widgetId), shortcutId);
+        editor.putString(String.valueOf(widgetId), contactUri.toString());
+
         String key = new PeopleTileKey(shortcutId, 0, packageName).toString();
         Set<String> storedWidgetIds = new HashSet<>(sp.getStringSet(key, new HashSet<>()));
         storedWidgetIds.add(String.valueOf(widgetId));
         editor.putStringSet(key, storedWidgetIds);
+
+        Set<String> storedWidgetIdsByUri = new HashSet<>(
+                sp.getStringSet(contactUri.toString(), new HashSet<>()));
+        storedWidgetIdsByUri.add(String.valueOf(widgetId));
+        editor.putStringSet(contactUri.toString(), storedWidgetIdsByUri);
         editor.apply();
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QuickStatusBarHeaderControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QuickStatusBarHeaderControllerTest.kt
index 4948c2b..3c1b36e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QuickStatusBarHeaderControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QuickStatusBarHeaderControllerTest.kt
@@ -21,9 +21,9 @@
 import android.view.View
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.UiEventLogger
-import com.android.systemui.colorextraction.SysuiColorExtractor
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.colorextraction.SysuiColorExtractor
 import com.android.systemui.demomode.DemoModeController
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.privacy.OngoingPrivacyChip
@@ -32,17 +32,12 @@
 import com.android.systemui.privacy.logging.PrivacyLogger
 import com.android.systemui.qs.carrier.QSCarrierGroup
 import com.android.systemui.qs.carrier.QSCarrierGroupController
-import com.android.systemui.settings.UserTracker
-import com.android.systemui.statusbar.CommandQueue
 import com.android.systemui.statusbar.phone.StatusBarIconController
 import com.android.systemui.statusbar.phone.StatusIconContainer
 import com.android.systemui.statusbar.policy.Clock
-import com.android.systemui.statusbar.policy.NextAlarmController
-import com.android.systemui.util.RingerModeTracker
 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.utils.leaks.FakeZenModeController
 import com.google.common.truth.Truth.assertThat
 import org.junit.After
 import org.junit.Before
@@ -62,28 +57,16 @@
     @Mock
     private lateinit var view: QuickStatusBarHeader
     @Mock
-    private lateinit var zenModeController: FakeZenModeController
-    @Mock
-    private lateinit var nextAlarmController: NextAlarmController
-    @Mock
     private lateinit var privacyItemController: PrivacyItemController
-    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
-    private lateinit var ringerModeTracker: RingerModeTracker
     @Mock
     private lateinit var activityStarter: ActivityStarter
     @Mock
     private lateinit var uiEventLogger: UiEventLogger
     @Mock
-    private lateinit var qsTileHost: QSTileHost
-    @Mock
     private lateinit var statusBarIconController: StatusBarIconController
     @Mock
-    private lateinit var commandQueue: CommandQueue
-    @Mock
     private lateinit var demoModeController: DemoModeController
     @Mock
-    private lateinit var userTracker: UserTracker
-    @Mock
     private lateinit var quickQSPanelController: QuickQSPanelController
     @Mock(answer = Answers.RETURNS_SELF)
     private lateinit var qsCarrierGroupControllerBuilder: QSCarrierGroupController.Builder
@@ -108,6 +91,8 @@
     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
     private lateinit var context: Context
 
+    private val qsExpansionPathInterpolator = QSExpansionPathInterpolator()
+
     private lateinit var controller: QuickStatusBarHeaderController
 
     @Before
@@ -122,22 +107,17 @@
 
         controller = QuickStatusBarHeaderController(
                 view,
-                zenModeController,
-                nextAlarmController,
                 privacyItemController,
-                ringerModeTracker,
                 activityStarter,
                 uiEventLogger,
-                qsTileHost,
                 statusBarIconController,
-                commandQueue,
                 demoModeController,
-                userTracker,
                 quickQSPanelController,
                 qsCarrierGroupControllerBuilder,
                 privacyLogger,
                 colorExtractor,
-                privacyDialogController
+                privacyDialogController,
+                qsExpansionPathInterpolator
         )
     }
 
@@ -233,4 +213,4 @@
         `when`(privacyItemController.micCameraAvailable).thenReturn(micCamera)
         `when`(privacyItemController.locationAvailable).thenReturn(location)
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/SecureSettingTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/SecureSettingTest.kt
index 418fa61..6af8402 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/SecureSettingTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/SecureSettingTest.kt
@@ -41,6 +41,7 @@
         private const val TEST_SETTING = "setting"
         private const val USER = 0
         private const val OTHER_USER = 1
+        private const val DEFAULT_VALUE = 1
         private val FAIL_CALLBACK: Callback = { _, _ -> fail("Callback should not be called") }
     }
 
@@ -59,7 +60,8 @@
                 secureSettings,
                 Handler(testableLooper.looper),
                 TEST_SETTING,
-                USER
+                USER,
+                DEFAULT_VALUE
         ) {
             override fun handleValueChanged(value: Int, observedChange: Boolean) {
                 callback(value, observedChange)
@@ -150,4 +152,14 @@
 
         assertThat(changed).isTrue()
     }
+
+    @Test
+    fun testDefaultValue() {
+        // Check default value before listening
+        assertThat(setting.value).isEqualTo(DEFAULT_VALUE)
+
+        // Check default value if setting is not set
+        setting.isListening = true
+        assertThat(setting.value).isEqualTo(DEFAULT_VALUE)
+    }
 }
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/carrier/QSCarrierGroupControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/carrier/QSCarrierGroupControllerTest.java
index 5a1bd5f..59a5f03 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/carrier/QSCarrierGroupControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/carrier/QSCarrierGroupControllerTest.java
@@ -33,7 +33,7 @@
 
 import androidx.test.filters.SmallTest;
 
-import com.android.keyguard.CarrierTextController;
+import com.android.keyguard.CarrierTextManager;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.statusbar.policy.NetworkController;
 import com.android.systemui.statusbar.policy.NetworkController.MobileDataIndicators;
@@ -55,7 +55,7 @@
 
     private QSCarrierGroupController mQSCarrierGroupController;
     private NetworkController.SignalCallback mSignalCallback;
-    private CarrierTextController.CarrierTextCallback mCallback;
+    private CarrierTextManager.CarrierTextCallback mCallback;
     @Mock
     private QSCarrierGroup mQSCarrierGroup;
     @Mock
@@ -63,9 +63,9 @@
     @Mock
     private NetworkController mNetworkController;
     @Mock
-    private CarrierTextController.Builder mCarrierTextControllerBuilder;
+    private CarrierTextManager.Builder mCarrierTextControllerBuilder;
     @Mock
-    private CarrierTextController mCarrierTextController;
+    private CarrierTextManager mCarrierTextManager;
     private TestableLooper mTestableLooper;
 
     @Before
@@ -84,11 +84,11 @@
                 .thenReturn(mCarrierTextControllerBuilder);
         when(mCarrierTextControllerBuilder.setShowMissingSim(anyBoolean()))
                 .thenReturn(mCarrierTextControllerBuilder);
-        when(mCarrierTextControllerBuilder.build()).thenReturn(mCarrierTextController);
+        when(mCarrierTextControllerBuilder.build()).thenReturn(mCarrierTextManager);
 
         doAnswer(invocation -> mCallback = invocation.getArgument(0))
-                .when(mCarrierTextController)
-                .setListening(any(CarrierTextController.CarrierTextCallback.class));
+                .when(mCarrierTextManager)
+                .setListening(any(CarrierTextManager.CarrierTextCallback.class));
 
         when(mQSCarrierGroup.getNoSimTextView()).thenReturn(new TextView(mContext));
         when(mQSCarrierGroup.getCarrier1View()).thenReturn(mock(QSCarrier.class));
@@ -114,8 +114,8 @@
                 (Answer<Integer>) invocationOnMock -> invocationOnMock.getArgument(0));
 
         // listOfCarriers length 1, subscriptionIds length 1, anySims false
-        CarrierTextController.CarrierTextCallbackInfo
-                c1 = new CarrierTextController.CarrierTextCallbackInfo(
+        CarrierTextManager.CarrierTextCallbackInfo
+                c1 = new CarrierTextManager.CarrierTextCallbackInfo(
                 "",
                 new CharSequence[]{""},
                 false,
@@ -123,8 +123,8 @@
         mCallback.updateCarrierInfo(c1);
 
         // listOfCarriers length 1, subscriptionIds length 1, anySims true
-        CarrierTextController.CarrierTextCallbackInfo
-                c2 = new CarrierTextController.CarrierTextCallbackInfo(
+        CarrierTextManager.CarrierTextCallbackInfo
+                c2 = new CarrierTextManager.CarrierTextCallbackInfo(
                 "",
                 new CharSequence[]{""},
                 true,
@@ -132,8 +132,8 @@
         mCallback.updateCarrierInfo(c2);
 
         // listOfCarriers length 2, subscriptionIds length 2, anySims false
-        CarrierTextController.CarrierTextCallbackInfo
-                c3 = new CarrierTextController.CarrierTextCallbackInfo(
+        CarrierTextManager.CarrierTextCallbackInfo
+                c3 = new CarrierTextManager.CarrierTextCallbackInfo(
                 "",
                 new CharSequence[]{"", ""},
                 false,
@@ -141,8 +141,8 @@
         mCallback.updateCarrierInfo(c3);
 
         // listOfCarriers length 2, subscriptionIds length 2, anySims true
-        CarrierTextController.CarrierTextCallbackInfo
-                c4 = new CarrierTextController.CarrierTextCallbackInfo(
+        CarrierTextManager.CarrierTextCallbackInfo
+                c4 = new CarrierTextManager.CarrierTextCallbackInfo(
                 "",
                 new CharSequence[]{"", ""},
                 true,
@@ -160,8 +160,8 @@
                 (Answer<Integer>) invocationOnMock -> invocationOnMock.getArgument(0));
 
         // listOfCarriers length 2, subscriptionIds length 1, anySims false
-        CarrierTextController.CarrierTextCallbackInfo
-                c1 = new CarrierTextController.CarrierTextCallbackInfo(
+        CarrierTextManager.CarrierTextCallbackInfo
+                c1 = new CarrierTextManager.CarrierTextCallbackInfo(
                 "",
                 new CharSequence[]{"", ""},
                 false,
@@ -169,8 +169,8 @@
         mCallback.updateCarrierInfo(c1);
 
         // listOfCarriers length 2, subscriptionIds length 1, anySims true
-        CarrierTextController.CarrierTextCallbackInfo
-                c2 = new CarrierTextController.CarrierTextCallbackInfo(
+        CarrierTextManager.CarrierTextCallbackInfo
+                c2 = new CarrierTextManager.CarrierTextCallbackInfo(
                 "",
                 new CharSequence[]{"", ""},
                 true,
@@ -178,8 +178,8 @@
         mCallback.updateCarrierInfo(c2);
 
         // listOfCarriers length 1, subscriptionIds length 2, anySims false
-        CarrierTextController.CarrierTextCallbackInfo
-                c3 = new CarrierTextController.CarrierTextCallbackInfo(
+        CarrierTextManager.CarrierTextCallbackInfo
+                c3 = new CarrierTextManager.CarrierTextCallbackInfo(
                 "",
                 new CharSequence[]{""},
                 false,
@@ -187,8 +187,8 @@
         mCallback.updateCarrierInfo(c3);
 
         // listOfCarriers length 1, subscriptionIds length 2, anySims true
-        CarrierTextController.CarrierTextCallbackInfo
-                c4 = new CarrierTextController.CarrierTextCallbackInfo(
+        CarrierTextManager.CarrierTextCallbackInfo
+                c4 = new CarrierTextManager.CarrierTextCallbackInfo(
                 "",
                 new CharSequence[]{""},
                 true,
@@ -204,8 +204,8 @@
         when(spiedCarrierGroupController.getSlotIndex(anyInt())).thenReturn(
                 SubscriptionManager.INVALID_SIM_SLOT_INDEX);
 
-        CarrierTextController.CarrierTextCallbackInfo
-                c4 = new CarrierTextController.CarrierTextCallbackInfo(
+        CarrierTextManager.CarrierTextCallbackInfo
+                c4 = new CarrierTextManager.CarrierTextCallbackInfo(
                 "",
                 new CharSequence[]{"", ""},
                 true,
@@ -225,8 +225,8 @@
 
     @Test
     public void testNoEmptyVisibleView_airplaneMode() {
-        CarrierTextController.CarrierTextCallbackInfo
-                info = new CarrierTextController.CarrierTextCallbackInfo(
+        CarrierTextManager.CarrierTextCallbackInfo
+                info = new CarrierTextManager.CarrierTextCallbackInfo(
                 "",
                 new CharSequence[]{""},
                 true,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/carrier/QSCarrierTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/carrier/QSCarrierTest.java
index 022dc84..104b625 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/carrier/QSCarrierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/carrier/QSCarrierTest.java
@@ -21,10 +21,13 @@
 
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
+import android.util.FeatureFlagUtils;
 import android.view.LayoutInflater;
 
 import androidx.test.filters.SmallTest;
 
+import com.android.settingslib.graph.SignalDrawable;
+import com.android.settingslib.mobile.TelephonyIcons;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 
@@ -39,6 +42,7 @@
 
     private QSCarrier mQSCarrier;
     private TestableLooper mTestableLooper;
+    private int mSignalIconId;
 
     @Before
     public void setUp() throws Exception {
@@ -46,18 +50,26 @@
         LayoutInflater inflater = LayoutInflater.from(mContext);
         mTestableLooper.runWithLooper(() ->
                 mQSCarrier = (QSCarrier) inflater.inflate(R.layout.qs_carrier, null));
+
+        if (FeatureFlagUtils.isEnabled(mContext, FeatureFlagUtils.SETTINGS_PROVIDER_MODEL)) {
+            // In this case, the id is an actual drawable id
+            mSignalIconId = TelephonyIcons.MOBILE_CALL_STRENGTH_ICONS[0];
+        } else {
+            // In this case, the id is a level
+            mSignalIconId = SignalDrawable.getEmptyState(5);
+        }
     }
 
     @Test
     public void testUpdateState_first() {
-        CellSignalState c = new CellSignalState(true, 0, "", "", false);
+        CellSignalState c = new CellSignalState(true, mSignalIconId, "", "", false);
 
         assertTrue(mQSCarrier.updateState(c));
     }
 
     @Test
     public void testUpdateState_same() {
-        CellSignalState c = new CellSignalState(true, 0, "", "", false);
+        CellSignalState c = new CellSignalState(true, mSignalIconId, "", "", false);
 
         assertTrue(mQSCarrier.updateState(c));
         assertFalse(mQSCarrier.updateState(c));
@@ -65,7 +77,7 @@
 
     @Test
     public void testUpdateState_changed() {
-        CellSignalState c = new CellSignalState(true, 0, "", "", false);
+        CellSignalState c = new CellSignalState(true, mSignalIconId, "", "", false);
 
         assertTrue(mQSCarrier.updateState(c));
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScrollCaptureControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScrollCaptureControllerTest.java
index 410d9de..7fe178c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScrollCaptureControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScrollCaptureControllerTest.java
@@ -17,6 +17,7 @@
 package com.android.systemui.screenshot;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyFloat;
 import static org.mockito.ArgumentMatchers.anyInt;
@@ -57,13 +58,17 @@
         public int availableBottom = Integer.MAX_VALUE;
         // If true, return an empty rect any time a partial result would have been returned.
         public boolean emptyInsteadOfPartial = false;
+        private int mPreviousTopRequested = 0;
 
         @Override
         public ListenableFuture<ScrollCaptureClient.CaptureResult> requestTile(int top) {
+            // Ensure we don't request a tile more than a tile away.
+            assertTrue(Math.abs(top - mPreviousTopRequested) <= getTileHeight());
+            mPreviousTopRequested = top;
             Rect requested = new Rect(0, top, getPageWidth(), top + getTileHeight());
             Rect fullContent = new Rect(0, availableTop, getPageWidth(), availableBottom);
             Rect captured = new Rect(requested);
-            captured.intersect(fullContent);
+            assertTrue(captured.intersect(fullContent));
             if (emptyInsteadOfPartial && captured.height() != getTileHeight()) {
                 captured = new Rect();
             }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessSliderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessSliderTest.kt
index 0cc2072..95e9d1f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessSliderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessSliderTest.kt
@@ -25,6 +25,7 @@
 import androidx.test.filters.SmallTest
 import com.android.settingslib.RestrictedLockUtils
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.classifier.FalsingManagerFake
 import com.android.systemui.statusbar.policy.BrightnessMirrorController
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.capture
@@ -75,6 +76,7 @@
     private lateinit var checkedChangeCaptor: ArgumentCaptor<CompoundButton.OnCheckedChangeListener>
     @Mock
     private lateinit var compoundButton: CompoundButton
+    private var mFalsingManager: FalsingManagerFake = FalsingManagerFake()
 
     private lateinit var mController: BrightnessSlider
 
@@ -85,7 +87,7 @@
         whenever(mirrorController.toggleSlider).thenReturn(mirror)
         whenever(motionEvent.copy()).thenReturn(motionEvent)
 
-        mController = BrightnessSlider(rootView, brightnessSliderView, true)
+        mController = BrightnessSlider(rootView, brightnessSliderView, true, mFalsingManager)
         mController.init()
         mController.setOnChangedListener(listener)
     }
@@ -160,7 +162,8 @@
 
     @Test
     fun testSettingMirrorWhenNotUseMirrorIsNoOp() {
-        val otherController = BrightnessSlider(rootView, brightnessSliderView, false)
+        val otherController = BrightnessSlider(
+                rootView, brightnessSliderView, false, mFalsingManager)
         otherController.init()
 
         otherController.setMirrorControllerAndMirror(mirrorController)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt
index 0bf1ac3..e65db5e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.statusbar
 
 import android.app.WallpaperManager
+import android.os.IBinder
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper.RunWithLooper
 import android.view.Choreographer
@@ -64,6 +65,7 @@
     @Mock private lateinit var dumpManager: DumpManager
     @Mock private lateinit var root: View
     @Mock private lateinit var viewRootImpl: ViewRootImpl
+    @Mock private lateinit var windowToken: IBinder
     @Mock private lateinit var shadeSpring: NotificationShadeDepthController.DepthAnimation
     @Mock private lateinit var shadeAnimation: NotificationShadeDepthController.DepthAnimation
     @Mock private lateinit var globalActionsSpring: NotificationShadeDepthController.DepthAnimation
@@ -80,6 +82,7 @@
     @Before
     fun setup() {
         `when`(root.viewRootImpl).thenReturn(viewRootImpl)
+        `when`(root.windowToken).thenReturn(windowToken)
         `when`(root.isAttachedToWindow).thenReturn(true)
         `when`(statusBarStateController.state).then { statusBarState }
         `when`(blurUtils.blurRadiusOfRatio(anyFloat())).then { answer ->
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java
index f31639c..7c819f5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java
@@ -125,7 +125,7 @@
 
     @Test
     public void testGiantImageNotAllowed() {
-        Bitmap largeBitmap = Bitmap.createBitmap(1000, 1000, Bitmap.Config.ARGB_8888);
+        Bitmap largeBitmap = Bitmap.createBitmap(6000, 6000, Bitmap.Config.ARGB_8888);
         Icon icon = Icon.createWithBitmap(largeBitmap);
         StatusBarIcon largeIcon = new StatusBarIcon(UserHandle.ALL, "mockPackage",
                 icon, 0, 0, "");
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/charging/WiredChargingRippleControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/charging/WiredChargingRippleControllerTest.kt
index 3701b91..9ce7241 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/charging/WiredChargingRippleControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/charging/WiredChargingRippleControllerTest.kt
@@ -93,8 +93,8 @@
 
         captor.value.onBatteryLevelChanged(
                 unusedBatteryLevel,
-                true /* plugged in */,
-                false /* charging */)
+                false /* plugged in */,
+                true /* charging */)
         verify(rippleView).startRipple()
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/MediaNotificationProcessorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/MediaNotificationProcessorTest.java
index e6287e7..aeb5b03 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/MediaNotificationProcessorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/MediaNotificationProcessorTest.java
@@ -18,31 +18,18 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import static org.junit.Assert.assertNotSame;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-
 import android.annotation.Nullable;
-import android.app.Notification;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Color;
-import android.graphics.drawable.Drawable;
 import android.test.suitebuilder.annotation.SmallTest;
-import android.widget.RemoteViews;
 
 import androidx.palette.graphics.Palette;
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.systemui.SysuiTestCase;
-import com.android.systemui.tests.R;
 
 import org.junit.After;
-import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -58,17 +45,8 @@
      */
     private static final int COLOR_TOLERANCE = 8;
 
-    private MediaNotificationProcessor mProcessor;
-    private Bitmap mBitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
-    private ImageGradientColorizer mColorizer;
     @Nullable private Bitmap mArtwork;
 
-    @Before
-    public void setUp() {
-        mColorizer = spy(new TestableColorizer(mBitmap));
-        mProcessor = new MediaNotificationProcessor(getContext(), getContext(), mColorizer);
-    }
-
     @After
     public void tearDown() {
         if (mArtwork != null) {
@@ -78,53 +56,6 @@
     }
 
     @Test
-    public void testColorizedWithLargeIcon() {
-        Notification.Builder builder = new Notification.Builder(getContext()).setSmallIcon(
-                R.drawable.ic_person)
-                .setContentTitle("Title")
-                .setLargeIcon(mBitmap)
-                .setContentText("Text");
-        Notification notification = builder.build();
-        mProcessor.processNotification(notification, builder);
-        verify(mColorizer).colorize(any(), anyInt(), anyBoolean());
-    }
-
-    @Test
-    public void testNotColorizedWithoutLargeIcon() {
-        Notification.Builder builder = new Notification.Builder(getContext()).setSmallIcon(
-                R.drawable.ic_person)
-                .setContentTitle("Title")
-                .setContentText("Text");
-        Notification notification = builder.build();
-        mProcessor.processNotification(notification, builder);
-        verifyZeroInteractions(mColorizer);
-    }
-
-    @Test
-    public void testRemoteViewsReset() {
-        Notification.Builder builder = new Notification.Builder(getContext()).setSmallIcon(
-                R.drawable.ic_person)
-                .setContentTitle("Title")
-                .setStyle(new Notification.MediaStyle())
-                .setLargeIcon(mBitmap)
-                .setContentText("Text");
-        Notification notification = builder.build();
-        RemoteViews remoteViews = new RemoteViews(getContext().getPackageName(),
-                R.layout.custom_view_dark);
-        notification.contentView = remoteViews;
-        notification.bigContentView = remoteViews;
-        notification.headsUpContentView = remoteViews;
-        mProcessor.processNotification(notification, builder);
-        verify(mColorizer).colorize(any(), anyInt(), anyBoolean());
-        RemoteViews contentView = builder.createContentView();
-        assertNotSame(contentView, remoteViews);
-        contentView = builder.createBigContentView();
-        assertNotSame(contentView, remoteViews);
-        contentView = builder.createHeadsUpContentView();
-        assertNotSame(contentView, remoteViews);
-    }
-
-    @Test
     public void findBackgroundSwatch_white() {
         // Given artwork that is completely white.
         mArtwork = Bitmap.createBitmap(BITMAP_WIDTH, BITMAP_HEIGHT, Bitmap.Config.ARGB_8888);
@@ -153,17 +84,4 @@
         assertThat((float) Color.green(expected)).isWithin(COLOR_TOLERANCE).of(Color.green(actual));
         assertThat((float) Color.blue(expected)).isWithin(COLOR_TOLERANCE).of(Color.blue(actual));
     }
-
-    public static class TestableColorizer extends ImageGradientColorizer {
-        private final Bitmap mBitmap;
-
-        private TestableColorizer(Bitmap bitmap) {
-            mBitmap = bitmap;
-        }
-
-        @Override
-        public Bitmap colorize(Drawable drawable, int backgroundColor, boolean isRtl) {
-            return mBitmap;
-        }
-    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapperTest.java
deleted file mode 100644
index fbe4d73..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapperTest.java
+++ /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.android.systemui.statusbar.notification.row.wrapper;
-
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.argThat;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import android.app.Notification;
-import android.media.MediaMetadata;
-import android.media.session.MediaSession;
-import android.media.session.PlaybackState;
-import android.provider.Settings;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-import android.testing.TestableLooper.RunWithLooper;
-import android.view.View;
-import android.widget.RemoteViews;
-import android.widget.SeekBar;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.systemui.R;
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
-import com.android.systemui.statusbar.notification.row.NotificationTestHelper;
-
-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
-public class NotificationMediaTemplateViewWrapperTest extends SysuiTestCase {
-
-    private ExpandableNotificationRow mRow;
-    private Notification mNotif;
-    private View mView;
-    private NotificationMediaTemplateViewWrapper mWrapper;
-
-    @Mock
-    private MetricsLogger mMetricsLogger;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        allowTestableLooperAsMainThread();
-
-        mDependency.injectTestDependency(MetricsLogger.class, mMetricsLogger);
-
-        // These tests are for regular media style notifications, not controls in quick settings
-        Settings.System.putInt(mContext.getContentResolver(), "qs_media_player", 0);
-    }
-
-    private void makeTestNotification(long duration, boolean allowSeeking) throws Exception {
-        Notification.Builder builder = new Notification.Builder(mContext)
-                .setSmallIcon(R.drawable.ic_person)
-                .setContentTitle("Title")
-                .setContentText("Text");
-
-        MediaMetadata metadata = new MediaMetadata.Builder()
-                .putLong(MediaMetadata.METADATA_KEY_DURATION, duration)
-                .build();
-        MediaSession session = new MediaSession(mContext, "TEST_CHANNEL");
-        session.setMetadata(metadata);
-
-        PlaybackState playbackState = new PlaybackState.Builder()
-                .setActions(allowSeeking ? PlaybackState.ACTION_SEEK_TO : 0)
-                .build();
-
-        session.setPlaybackState(playbackState);
-
-        builder.setStyle(new Notification.MediaStyle()
-                .setMediaSession(session.getSessionToken())
-        );
-
-        mNotif = builder.build();
-        assertTrue(mNotif.hasMediaSession());
-
-        NotificationTestHelper helper = new NotificationTestHelper(
-                mContext,
-                mDependency,
-                TestableLooper.get(this));
-        mRow = helper.createRow(mNotif);
-
-        RemoteViews views = new RemoteViews(mContext.getPackageName(),
-                com.android.internal.R.layout.notification_template_material_big_media);
-        mView = views.apply(mContext, null);
-        mWrapper = new NotificationMediaTemplateViewWrapper(mContext,
-                mView, mRow);
-        mWrapper.onContentUpdated(mRow);
-    }
-
-    @Test
-    public void testLogging_NoSeekbar() throws Exception {
-        // Media sessions with duration <= 0 should not include a seekbar
-        makeTestNotification(0, false);
-
-        verify(mMetricsLogger).write(argThat(logMaker ->
-                logMaker.getCategory() == MetricsEvent.MEDIA_NOTIFICATION_SEEKBAR
-                        && logMaker.getType() == MetricsEvent.TYPE_CLOSE
-        ));
-
-        verify(mMetricsLogger, times(0)).write(argThat(logMaker ->
-                logMaker.getCategory() == MetricsEvent.MEDIA_NOTIFICATION_SEEKBAR
-                        && logMaker.getType() == MetricsEvent.TYPE_OPEN
-        ));
-    }
-
-    @Test
-    public void testLogging_HasSeekbarNoScrubber() throws Exception {
-        // Media sessions that do not support seeking should have a seekbar, but no scrubber
-        makeTestNotification(1000, false);
-
-        verify(mMetricsLogger).write(argThat(logMaker ->
-                logMaker.getCategory() == MetricsEvent.MEDIA_NOTIFICATION_SEEKBAR
-                        && logMaker.getType() == MetricsEvent.TYPE_OPEN
-        ));
-
-        // Ensure the callback runs at least once
-        mWrapper.mOnUpdateTimerTick.run();
-
-        verify(mMetricsLogger).write(argThat(logMaker ->
-                logMaker.getCategory() == MetricsEvent.MEDIA_NOTIFICATION_SEEKBAR
-                && logMaker.getType() == MetricsEvent.TYPE_DETAIL
-                && logMaker.getSubtype() == 0
-        ));
-    }
-
-    @Test
-    public void testLogging_HasSeekbarAndScrubber() throws Exception {
-        makeTestNotification(1000, true);
-
-        verify(mMetricsLogger).write(argThat(logMaker ->
-                logMaker.getCategory() == MetricsEvent.MEDIA_NOTIFICATION_SEEKBAR
-                        && logMaker.getType() == MetricsEvent.TYPE_OPEN
-        ));
-
-        verify(mMetricsLogger).write(argThat(logMaker ->
-                logMaker.getCategory() == MetricsEvent.MEDIA_NOTIFICATION_SEEKBAR
-                        && logMaker.getType() == MetricsEvent.TYPE_DETAIL
-                        && logMaker.getSubtype() == 1
-        ));
-    }
-
-    @Test
-    public void testLogging_UpdateSeekbar() throws Exception {
-        makeTestNotification(1000, true);
-
-        SeekBar seekbar = mView.findViewById(
-                com.android.internal.R.id.notification_media_progress_bar);
-        assertTrue(seekbar != null);
-
-        mWrapper.mSeekListener.onStopTrackingTouch(seekbar);
-
-        verify(mMetricsLogger).write(argThat(logMaker ->
-                logMaker.getCategory() == MetricsEvent.MEDIA_NOTIFICATION_SEEKBAR
-                        && logMaker.getType() == MetricsEvent.TYPE_UPDATE));
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
index 91f3611..6a5e6e8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
@@ -66,6 +66,7 @@
 import com.android.keyguard.KeyguardStatusViewController;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.dagger.KeyguardQsUserSwitchComponent;
+import com.android.keyguard.dagger.KeyguardStatusBarViewComponent;
 import com.android.keyguard.dagger.KeyguardStatusViewComponent;
 import com.android.keyguard.dagger.KeyguardUserSwitcherComponent;
 import com.android.systemui.R;
@@ -206,10 +207,16 @@
     @Mock
     private KeyguardStatusViewComponent mKeyguardStatusViewComponent;
     @Mock
+    private KeyguardStatusBarViewComponent.Factory mKeyguardStatusBarViewComponentFactory;
+    @Mock
+    private KeyguardStatusBarViewComponent mKeyguardStatusBarViewComponent;
+    @Mock
     private KeyguardClockSwitchController mKeyguardClockSwitchController;
     @Mock
     private KeyguardStatusViewController mKeyguardStatusViewController;
     @Mock
+    private KeyguardStatusBarViewController mKeyguardStatusBarViewController;
+    @Mock
     private NotificationStackScrollLayoutController mNotificationStackScrollLayoutController;
     @Mock
     private AuthController mAuthController;
@@ -296,6 +303,10 @@
                 .thenReturn(mKeyguardClockSwitchController);
         when(mKeyguardStatusViewComponent.getKeyguardStatusViewController())
                 .thenReturn(mKeyguardStatusViewController);
+        when(mKeyguardStatusBarViewComponentFactory.build(any()))
+                .thenReturn(mKeyguardStatusBarViewComponent);
+        when(mKeyguardStatusBarViewComponent.getKeyguardStatusBarViewController())
+                .thenReturn(mKeyguardStatusBarViewController);
 
         mNotificationPanelViewController = new NotificationPanelViewController(mView,
                 mResources,
@@ -314,6 +325,7 @@
                 mKeyguardStatusViewComponentFactory,
                 mKeyguardQsUserSwitchComponentFactory,
                 mKeyguardUserSwitcherComponentFactory,
+                mKeyguardStatusBarViewComponentFactory,
                 mQSDetailDisplayer,
                 mGroupManager,
                 mNotificationAreaController,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconControllerTest.java
index 7b7e2d3..f147f1ce 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconControllerTest.java
@@ -31,7 +31,6 @@
 
 import com.android.internal.statusbar.StatusBarIcon;
 import com.android.systemui.plugins.DarkIconDispatcher;
-import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.StatusBarIconView;
 import com.android.systemui.statusbar.StatusBarMobileView;
 import com.android.systemui.statusbar.StatusBarWifiView;
@@ -60,14 +59,14 @@
     @Test
     public void testSetCalledOnAdd_IconManager() {
         LinearLayout layout = new LinearLayout(mContext);
-        TestIconManager manager = new TestIconManager(layout, new CommandQueue(mContext));
+        TestIconManager manager = new TestIconManager(layout);
         testCallOnAdd_forManager(manager);
     }
 
     @Test
     public void testSetCalledOnAdd_DarkIconManager() {
         LinearLayout layout = new LinearLayout(mContext);
-        TestDarkIconManager manager = new TestDarkIconManager(layout, new CommandQueue(mContext));
+        TestDarkIconManager manager = new TestDarkIconManager(layout);
         testCallOnAdd_forManager(manager);
     }
 
@@ -104,8 +103,8 @@
     private static class TestDarkIconManager extends DarkIconManager
             implements TestableIconManager {
 
-        TestDarkIconManager(LinearLayout group, CommandQueue commandQueue) {
-            super(group, commandQueue);
+        TestDarkIconManager(LinearLayout group) {
+            super(group);
         }
 
         @Override
@@ -139,8 +138,8 @@
     }
 
     private static class TestIconManager extends IconManager implements TestableIconManager {
-        TestIconManager(ViewGroup group, CommandQueue commandQueue) {
-            super(group, commandQueue);
+        TestIconManager(ViewGroup group) {
+            super(group);
         }
 
         @Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
index 999d282..ef33172 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
@@ -35,7 +35,6 @@
 import static org.mockito.Mockito.when;
 
 import android.app.Instrumentation;
-import android.content.Intent;
 import android.net.ConnectivityManager;
 import android.net.LinkProperties;
 import android.net.Network;
@@ -54,7 +53,6 @@
 import android.telephony.SignalStrength;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyCallback;
 import android.telephony.TelephonyDisplayInfo;
 import android.telephony.TelephonyManager;
 import android.testing.TestableLooper;
@@ -78,6 +76,7 @@
 import com.android.systemui.statusbar.policy.NetworkController.IconState;
 import com.android.systemui.statusbar.policy.NetworkController.MobileDataIndicators;
 import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
+import com.android.systemui.telephony.TelephonyListenerManager;
 
 import org.junit.After;
 import org.junit.Before;
@@ -115,6 +114,7 @@
     protected NetworkScoreManager mMockNsm;
     protected SubscriptionManager mMockSm;
     protected TelephonyManager mMockTm;
+    protected TelephonyListenerManager mTelephonyListenerManager;
     protected BroadcastDispatcher mMockBd;
     protected Config mConfig;
     protected CallbackHandler mCallbackHandler;
@@ -166,13 +166,14 @@
         mDemoModeController = mock(DemoModeController.class);
         mMockWm = mock(WifiManager.class);
         mMockTm = mock(TelephonyManager.class);
+        mTelephonyListenerManager = mock(TelephonyListenerManager.class);
         mMockSm = mock(SubscriptionManager.class);
         mMockCm = mock(ConnectivityManager.class);
         mMockBd = mock(BroadcastDispatcher.class);
         mMockNsm = mock(NetworkScoreManager.class);
         mMockSubDefaults = mock(SubscriptionDefaults.class);
         mNetCapabilities = new NetworkCapabilities();
-        when(mMockCm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(true);
+        when(mMockTm.isDataCapable()).thenReturn(true);
         when(mMockTm.createForSubscriptionId(anyInt())).thenReturn(mMockTm);
         doAnswer(invocation -> {
             int rssi = invocation.getArgument(0);
@@ -215,6 +216,7 @@
         mNetworkController = new NetworkControllerImpl(mContext,
                 mMockCm,
                 mMockTm,
+                mTelephonyListenerManager,
                 mMockWm,
                 mMockNsm,
                 mMockSm,
@@ -285,9 +287,10 @@
     }
 
     protected NetworkControllerImpl setUpNoMobileData() {
-        when(mMockCm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(false);
+        when(mMockTm.isDataCapable()).thenReturn(false);
         NetworkControllerImpl networkControllerNoMobile =
-                new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockNsm, mMockSm,
+                new NetworkControllerImpl(mContext, mMockCm, mMockTm, mTelephonyListenerManager,
+                        mMockWm, mMockNsm, mMockSm,
                         mConfig, TestableLooper.get(this).getLooper(), mCallbackHandler,
                         mock(AccessPointControllerImpl.class),
                         mock(DataUsageController.class), mMockSubDefaults,
@@ -308,27 +311,14 @@
                 TelephonyManager.NETWORK_TYPE_UMTS);
         setConnectivityViaCallbackInNetworkController(
                 NetworkCapabilities.TRANSPORT_CELLULAR, true, true, null);
-        setConnectivityViaBroadcast(
-                NetworkCapabilities.TRANSPORT_CELLULAR, true, true);
     }
 
-    public void setConnectivityViaBroadcastForVcn(
+    public void setConnectivityViaCallbackInNetworkControllerForVcn(
             int networkType, boolean validated, boolean isConnected, VcnTransportInfo info) {
         mNetCapabilities.setTransportInfo(info);
         setConnectivityCommon(networkType, validated, isConnected);
         mDefaultCallbackInNetworkController.onCapabilitiesChanged(
                 mock(Network.class), new NetworkCapabilities(mNetCapabilities));
-        Intent i = new Intent(ConnectivityManager.INET_CONDITION_ACTION);
-        mNetworkController.onReceive(mContext, i);
-    }
-
-    public void setConnectivityViaBroadcast(
-        int networkType, boolean validated, boolean isConnected) {
-        setConnectivityCommon(networkType, validated, isConnected);
-        mDefaultCallbackInNetworkController.onCapabilitiesChanged(
-                mock(Network.class), new NetworkCapabilities(mNetCapabilities));
-        Intent i = new Intent(ConnectivityManager.INET_CONDITION_ACTION);
-        mNetworkController.onReceive(mContext, i);
     }
 
     public void setConnectivityViaCallbackInNetworkController(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
index 37b6a5d..f4ad819 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
@@ -106,7 +106,8 @@
     public void test4gDataIcon() {
         // Switch to showing 4g icon and re-initialize the NetworkController.
         mConfig.show4gForLte = true;
-        mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm,
+        mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm,
+                mTelephonyListenerManager, mMockWm,
                 mMockNsm, mMockSm, mConfig, Looper.getMainLooper(), mCallbackHandler,
                 mock(AccessPointControllerImpl.class),
                 mock(DataUsageController.class), mMockSubDefaults,
@@ -126,7 +127,8 @@
         when(mMockTm.isDataConnectionAllowed()).thenReturn(false);
         setupDefaultSignal();
         updateDataConnectionState(TelephonyManager.DATA_CONNECTED, 0);
-        setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_CELLULAR, false, false);
+        setConnectivityViaCallbackInNetworkController(
+                NetworkCapabilities.TRANSPORT_CELLULAR, false, false, null);
 
         // Verify that a SignalDrawable with a cut out is used to display data disabled.
         verifyLastMobileDataIndicators(false, DEFAULT_SIGNAL_STRENGTH, 0,
@@ -140,7 +142,8 @@
         when(mMockTm.isDataConnectionAllowed()).thenReturn(false);
         setupDefaultSignal();
         updateDataConnectionState(TelephonyManager.DATA_DISCONNECTED, 0);
-        setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_CELLULAR, false, false);
+        setConnectivityViaCallbackInNetworkController(
+                NetworkCapabilities.TRANSPORT_CELLULAR, false, false, null);
 
         // Verify that a SignalDrawable with a cut out is used to display data disabled.
         verifyLastMobileDataIndicators(false, DEFAULT_SIGNAL_STRENGTH, 0,
@@ -155,7 +158,8 @@
         setupDefaultSignal();
         setDefaultSubId(mSubId + 1);
         updateDataConnectionState(TelephonyManager.DATA_CONNECTED, 0);
-        setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_CELLULAR, false, false);
+        setConnectivityViaCallbackInNetworkController(
+                NetworkCapabilities.TRANSPORT_CELLULAR, false, false, null);
 
         // Verify that a SignalDrawable with a cut out is used to display data disabled.
         verifyLastMobileDataIndicators(false, DEFAULT_SIGNAL_STRENGTH, 0,
@@ -170,7 +174,8 @@
         setupDefaultSignal();
         setDefaultSubId(mSubId + 1);
         updateDataConnectionState(TelephonyManager.DATA_DISCONNECTED, 0);
-        setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_CELLULAR, false, false);
+        setConnectivityViaCallbackInNetworkController(
+                NetworkCapabilities.TRANSPORT_CELLULAR, false, false, null);
 
         // Verify that a SignalDrawable with a cut out is used to display data disabled.
         verifyLastMobileDataIndicators(false, DEFAULT_SIGNAL_STRENGTH, 0,
@@ -184,7 +189,8 @@
         when(mMockTm.isDataConnectionAllowed()).thenReturn(false);
         setupDefaultSignal();
         updateDataConnectionState(TelephonyManager.DATA_DISCONNECTED, 0);
-        setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_CELLULAR, false, false);
+        setConnectivityViaCallbackInNetworkController(
+                NetworkCapabilities.TRANSPORT_CELLULAR, false, false, null);
         when(mMockProvisionController.isUserSetup(anyInt())).thenReturn(false);
         mUserCallback.onUserSetupChanged();
         TestableLooper.get(this).processAllMessages();
@@ -206,7 +212,8 @@
         mConfig.alwaysShowDataRatIcon = true;
         mNetworkController.handleConfigurationChanged();
 
-        setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_CELLULAR, false, false);
+        setConnectivityViaCallbackInNetworkController(
+                NetworkCapabilities.TRANSPORT_CELLULAR, false, false, null);
         verifyLastMobileDataIndicators(false, DEFAULT_SIGNAL_STRENGTH, TelephonyIcons.ICON_G,
                 true, DEFAULT_QS_SIGNAL_STRENGTH, 0, false, false);
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerEthernetTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerEthernetTest.java
index 93cf3e8..6aab9c7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerEthernetTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerEthernetTest.java
@@ -37,7 +37,8 @@
     }
 
     protected void setEthernetState(boolean connected, boolean validated) {
-        setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_ETHERNET, validated, connected);
+        setConnectivityViaCallbackInNetworkController(
+                NetworkCapabilities.TRANSPORT_ETHERNET, validated, connected, null);
     }
 
     protected void verifyLastEthernetIcon(boolean visible, int icon) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
index c0d9c3d..3c5cbb6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
@@ -23,8 +23,8 @@
 import static org.mockito.Mockito.when;
 
 import android.content.Intent;
-import android.net.ConnectivityManager;
 import android.net.NetworkCapabilities;
+import android.net.wifi.WifiInfo;
 import android.os.Handler;
 import android.os.Looper;
 import android.telephony.CellSignalStrength;
@@ -59,10 +59,11 @@
     @Test
     public void testNoIconWithoutMobile() {
         // Turn off mobile network support.
-        when(mMockCm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(false);
+        when(mMockTm.isDataCapable()).thenReturn(false);
         // Create a new NetworkController as this is currently handled in constructor.
-        mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm,
-                mMockNsm, mMockSm, mConfig, Looper.getMainLooper(), mCallbackHandler,
+        mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm,
+                mTelephonyListenerManager, mMockWm, mMockNsm, mMockSm, mConfig,
+                Looper.getMainLooper(), mCallbackHandler,
                 mock(AccessPointControllerImpl.class), mock(DataUsageController.class),
                 mMockSubDefaults, mock(DeviceProvisionedController.class), mMockBd,
                 mDemoModeController);
@@ -80,8 +81,9 @@
         when(mMockTm.getServiceState()).thenReturn(mServiceState);
         when(mMockSm.getCompleteActiveSubscriptionInfoList()).thenReturn(Collections.emptyList());
 
-        mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm,
-                mMockNsm, mMockSm, mConfig, Looper.getMainLooper(), mCallbackHandler,
+        mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm,
+                mTelephonyListenerManager, mMockWm, mMockNsm, mMockSm, mConfig,
+                Looper.getMainLooper(), mCallbackHandler,
                 mock(AccessPointControllerImpl.class), mock(DataUsageController.class),
                 mMockSubDefaults, mock(DeviceProvisionedController.class), mMockBd,
                 mDemoModeController);
@@ -145,10 +147,11 @@
     @Test
     public void testNoSimlessIconWithoutMobile() {
         // Turn off mobile network support.
-        when(mMockCm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(false);
+        when(mMockTm.isDataCapable()).thenReturn(false);
         // Create a new NetworkController as this is currently handled in constructor.
-        mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm,
-                mMockNsm, mMockSm, mConfig, Looper.getMainLooper(), mCallbackHandler,
+        mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm,
+                mTelephonyListenerManager, mMockWm, mMockNsm, mMockSm, mConfig,
+                Looper.getMainLooper(), mCallbackHandler,
                 mock(AccessPointControllerImpl.class), mock(DataUsageController.class),
                 mMockSubDefaults, mock(DeviceProvisionedController.class), mMockBd,
                 mDemoModeController);
@@ -172,7 +175,8 @@
                     testStrength, DEFAULT_ICON);
 
             // Verify low inet number indexing.
-            setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_CELLULAR, false, true);
+            setConnectivityViaCallbackInNetworkController(
+                    NetworkCapabilities.TRANSPORT_CELLULAR, false, true, null);
             verifyLastMobileDataIndicators(true,
                     testStrength, DEFAULT_ICON, false, false);
         }
@@ -259,8 +263,10 @@
     @Test
     public void testNoBangWithWifi() {
         setupDefaultSignal();
-        setConnectivityViaBroadcast(mMobileSignalController.mTransportType, false, false);
-        setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_WIFI, true, true);
+        setConnectivityViaCallbackInNetworkController(
+                mMobileSignalController.mTransportType, false, false, null);
+        setConnectivityViaCallbackInNetworkController(
+                NetworkCapabilities.TRANSPORT_WIFI, true, true, mock(WifiInfo.class));
 
         verifyLastMobileDataIndicators(false, DEFAULT_LEVEL, 0);
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java
index 847030e..ab7cbf7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java
@@ -3,7 +3,7 @@
 import static junit.framework.Assert.assertEquals;
 
 import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
@@ -41,7 +41,7 @@
     @Before
     public void setUp() throws Exception {
         super.setUp();
-        when(mWifiInfo.makeCopy(anyBoolean())).thenReturn(mWifiInfo);
+        when(mWifiInfo.makeCopy(anyLong())).thenReturn(mWifiInfo);
     }
 
     @Test
@@ -59,9 +59,11 @@
         for (int testLevel = 0; testLevel < WifiIcons.WIFI_LEVEL_COUNT; testLevel++) {
             setWifiLevel(testLevel);
 
-            setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_WIFI, true, true);
+            setConnectivityViaCallbackInNetworkController(
+                    NetworkCapabilities.TRANSPORT_WIFI, true, true, mWifiInfo);
             verifyLastWifiIcon(true, WifiIcons.WIFI_SIGNAL_STRENGTH[1][testLevel]);
-            setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_WIFI, false, true);
+            setConnectivityViaCallbackInNetworkController(
+                    NetworkCapabilities.TRANSPORT_WIFI, false, true, mWifiInfo);
             // Icon does not show if not validated
             verifyLastWifiIcon(false, WifiIcons.WIFI_SIGNAL_STRENGTH[0][testLevel]);
         }
@@ -80,12 +82,14 @@
         setWifiState(true, testSsid);
         for (int testLevel = 0; testLevel < WifiIcons.WIFI_LEVEL_COUNT; testLevel++) {
             setWifiLevel(testLevel);
-            setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_WIFI, true, true);
+            setConnectivityViaCallbackInNetworkController(
+                    NetworkCapabilities.TRANSPORT_WIFI, true, true, mWifiInfo);
             setConnectivityViaDefaultCallbackInWifiTracker(
                     NetworkCapabilities.TRANSPORT_WIFI, true, true, mWifiInfo);
             verifyLastQsWifiIcon(true, true, WifiIcons.QS_WIFI_SIGNAL_STRENGTH[1][testLevel],
                     testSsid);
-            setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_WIFI, false, true);
+            setConnectivityViaCallbackInNetworkController(
+                    NetworkCapabilities.TRANSPORT_WIFI, false, true, mWifiInfo);
             verifyLastQsWifiIcon(true, true, WifiIcons.QS_WIFI_SIGNAL_STRENGTH[0][testLevel],
                     testSsid);
         }
@@ -99,7 +103,8 @@
         setWifiEnabled(true);
         setWifiState(true, testSsid);
         setWifiLevel(testLevel);
-        setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_WIFI, true, true);
+        setConnectivityViaCallbackInNetworkController(
+                NetworkCapabilities.TRANSPORT_WIFI, true, true, mWifiInfo);
         setConnectivityViaDefaultCallbackInWifiTracker(
                 NetworkCapabilities.TRANSPORT_WIFI, true, true, mWifiInfo);
         verifyLastQsWifiIcon(true, true,
@@ -126,14 +131,17 @@
         setWifiEnabled(true);
         setWifiState(true, testSsid);
         setWifiLevel(testLevel);
-        setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_WIFI, true, true);
+        setConnectivityViaCallbackInNetworkController(
+                NetworkCapabilities.TRANSPORT_WIFI, true, true, mWifiInfo);
         verifyLastWifiIcon(true, WifiIcons.WIFI_SIGNAL_STRENGTH[1][testLevel]);
 
         setupDefaultSignal();
         setGsmRoaming(true);
         // Still be on wifi though.
-        setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_WIFI, true, true);
-        setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_CELLULAR, false, false);
+        setConnectivityViaCallbackInNetworkController(
+                NetworkCapabilities.TRANSPORT_WIFI, true, true, mWifiInfo);
+        setConnectivityViaCallbackInNetworkController(
+                NetworkCapabilities.TRANSPORT_CELLULAR, false, false, null);
         verifyLastMobileDataIndicators(true, DEFAULT_LEVEL, 0, true);
     }
 
@@ -145,7 +153,8 @@
         setWifiEnabled(true);
         setWifiState(true, testSsid);
         setWifiLevel(testLevel);
-        setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_WIFI, true, true);
+        setConnectivityViaCallbackInNetworkController(
+                NetworkCapabilities.TRANSPORT_WIFI, true, true, mWifiInfo);
         verifyLastWifiIcon(true, WifiIcons.WIFI_SIGNAL_STRENGTH[1][testLevel]);
 
         setConnectivityViaCallbackInNetworkController(
@@ -161,7 +170,8 @@
         setWifiEnabled(true);
         setWifiState(true, testSsid);
         setWifiLevel(testLevel);
-        setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_WIFI, true, true);
+        setConnectivityViaCallbackInNetworkController(
+                NetworkCapabilities.TRANSPORT_WIFI, true, true, mWifiInfo);
         verifyLastWifiIcon(true, WifiIcons.WIFI_SIGNAL_STRENGTH[1][testLevel]);
 
         setWifiState(false, testSsid);
@@ -234,11 +244,11 @@
         for (int testLevel = 0; testLevel < WifiIcons.WIFI_LEVEL_COUNT; testLevel++) {
             setWifiLevelForVcn(testLevel);
 
-            setConnectivityViaBroadcastForVcn(
+            setConnectivityViaCallbackInNetworkControllerForVcn(
                     NetworkCapabilities.TRANSPORT_CELLULAR, true, true, mVcnTransportInfo);
             verifyLastMobileDataIndicatorsForVcn(true, testLevel, TelephonyIcons.ICON_CWF, true);
 
-            setConnectivityViaBroadcastForVcn(
+            setConnectivityViaCallbackInNetworkControllerForVcn(
                     NetworkCapabilities.TRANSPORT_CELLULAR, false, true, mVcnTransportInfo);
             verifyLastMobileDataIndicatorsForVcn(true, testLevel, TelephonyIcons.ICON_CWF, false);
         }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/telephony/TelephonyCallbackTest.java b/packages/SystemUI/tests/src/com/android/systemui/telephony/TelephonyCallbackTest.java
new file mode 100644
index 0000000..ac15903
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/telephony/TelephonyCallbackTest.java
@@ -0,0 +1,101 @@
+/*
+ * 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.telephony;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.telephony.TelephonyCallback.ActiveDataSubscriptionIdListener;
+import android.telephony.TelephonyCallback.CallStateListener;
+import android.telephony.TelephonyCallback.ServiceStateListener;
+
+import androidx.test.filters.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 TelephonyCallbackTest extends SysuiTestCase {
+
+    private TelephonyCallback mTelephonyCallback = new TelephonyCallback();
+
+    @Test
+    public void testAddListener_ActiveDataSubscriptionIdListener() {
+        assertThat(mTelephonyCallback.hasAnyListeners()).isFalse();
+        mTelephonyCallback.addActiveDataSubscriptionIdListener(subId -> {});
+        assertThat(mTelephonyCallback.hasAnyListeners()).isTrue();
+        mTelephonyCallback.addActiveDataSubscriptionIdListener(subId -> {});
+        assertThat(mTelephonyCallback.hasAnyListeners()).isTrue();
+    }
+
+    @Test
+    public void testAddListener_CallStateListener() {
+        assertThat(mTelephonyCallback.hasAnyListeners()).isFalse();
+        mTelephonyCallback.addCallStateListener(state -> {});
+        assertThat(mTelephonyCallback.hasAnyListeners()).isTrue();
+        mTelephonyCallback.addCallStateListener(state -> {});
+        assertThat(mTelephonyCallback.hasAnyListeners()).isTrue();
+    }
+
+    @Test
+    public void testAddListener_ServiceStateListener() {
+        assertThat(mTelephonyCallback.hasAnyListeners()).isFalse();
+        mTelephonyCallback.addServiceStateListener(serviceState -> {});
+        assertThat(mTelephonyCallback.hasAnyListeners()).isTrue();
+        mTelephonyCallback.addServiceStateListener(serviceState -> {});
+        assertThat(mTelephonyCallback.hasAnyListeners()).isTrue();
+    }
+
+    @Test
+    public void testRemoveListener_ActiveDataSubscriptionIdListener() {
+        ActiveDataSubscriptionIdListener listener = subId -> {};
+        mTelephonyCallback.addActiveDataSubscriptionIdListener(listener);
+        mTelephonyCallback.addActiveDataSubscriptionIdListener(listener);
+        assertThat(mTelephonyCallback.hasAnyListeners()).isTrue();
+        mTelephonyCallback.removeActiveDataSubscriptionIdListener(listener);
+        assertThat(mTelephonyCallback.hasAnyListeners()).isTrue();
+        mTelephonyCallback.removeActiveDataSubscriptionIdListener(listener);
+        assertThat(mTelephonyCallback.hasAnyListeners()).isFalse();
+    }
+
+    @Test
+    public void testRemoveListener_CallStateListener() {
+        CallStateListener listener = state -> {};
+        mTelephonyCallback.addCallStateListener(listener);
+        mTelephonyCallback.addCallStateListener(listener);
+        assertThat(mTelephonyCallback.hasAnyListeners()).isTrue();
+        mTelephonyCallback.removeCallStateListener(listener);
+        assertThat(mTelephonyCallback.hasAnyListeners()).isTrue();
+        mTelephonyCallback.removeCallStateListener(listener);
+        assertThat(mTelephonyCallback.hasAnyListeners()).isFalse();
+    }
+
+    @Test
+    public void testRemoveListener_ServiceStateListener() {
+        ServiceStateListener listener = serviceState -> {};
+        mTelephonyCallback.addServiceStateListener(listener);
+        mTelephonyCallback.addServiceStateListener(listener);
+        assertThat(mTelephonyCallback.hasAnyListeners()).isTrue();
+        mTelephonyCallback.removeServiceStateListener(listener);
+        assertThat(mTelephonyCallback.hasAnyListeners()).isTrue();
+        mTelephonyCallback.removeServiceStateListener(listener);
+        assertThat(mTelephonyCallback.hasAnyListeners()).isFalse();
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/telephony/TelephonyListenerManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/telephony/TelephonyListenerManagerTest.java
new file mode 100644
index 0000000..0d1ac7b
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/telephony/TelephonyListenerManagerTest.java
@@ -0,0 +1,209 @@
+/*
+ * 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.telephony;
+
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.telephony.TelephonyCallback.ActiveDataSubscriptionIdListener;
+import android.telephony.TelephonyCallback.CallStateListener;
+import android.telephony.TelephonyCallback.ServiceStateListener;
+import android.telephony.TelephonyManager;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+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.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class TelephonyListenerManagerTest extends SysuiTestCase {
+
+    @Mock
+    private TelephonyManager mTelephonyManager;
+    private FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock());
+    @Mock
+    private TelephonyCallback mTelephonyCallback;
+
+    TelephonyListenerManager mTelephonyListenerManager;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        mTelephonyListenerManager = new TelephonyListenerManager(
+                mTelephonyManager, mExecutor, mTelephonyCallback);
+    }
+
+    @Test
+    public void testAddListenerRegisters_ActiveDataSubscriptionIdListener() {
+        when(mTelephonyCallback.hasAnyListeners()).thenReturn(true);
+        mTelephonyListenerManager.addActiveDataSubscriptionIdListener(subId -> {});
+        mTelephonyListenerManager.addActiveDataSubscriptionIdListener(subId -> {});
+        mTelephonyListenerManager.addActiveDataSubscriptionIdListener(subId -> {});
+        mTelephonyListenerManager.addActiveDataSubscriptionIdListener(subId -> {});
+
+        verify(mTelephonyManager, times(1))
+                .registerTelephonyCallback(mExecutor, mTelephonyCallback);
+    }
+
+    @Test
+    public void testAddListenerRegisters_CallStateListener() {
+        when(mTelephonyCallback.hasAnyListeners()).thenReturn(true);
+        mTelephonyListenerManager.addCallStateListener(state -> {});
+        mTelephonyListenerManager.addCallStateListener(state -> {});
+        mTelephonyListenerManager.addCallStateListener(state -> {});
+        mTelephonyListenerManager.addCallStateListener(state -> {});
+
+        verify(mTelephonyManager, times(1))
+                .registerTelephonyCallback(mExecutor, mTelephonyCallback);
+    }
+
+    @Test
+    public void testAddListenerRegisters_ServiceStateListener() {
+        when(mTelephonyCallback.hasAnyListeners()).thenReturn(true);
+        mTelephonyListenerManager.addServiceStateListener(serviceState -> {});
+        mTelephonyListenerManager.addServiceStateListener(serviceState -> {});
+        mTelephonyListenerManager.addServiceStateListener(serviceState -> {});
+        mTelephonyListenerManager.addServiceStateListener(serviceState -> {});
+
+        verify(mTelephonyManager, times(1))
+                .registerTelephonyCallback(mExecutor, mTelephonyCallback);
+    }
+
+    @Test
+    public void testAddListenerRegisters_mixed() {
+        when(mTelephonyCallback.hasAnyListeners()).thenReturn(true);
+        mTelephonyListenerManager.addActiveDataSubscriptionIdListener(subId -> {});
+        mTelephonyListenerManager.addCallStateListener(state -> {});
+        mTelephonyListenerManager.addServiceStateListener(serviceState -> {});
+        mTelephonyListenerManager.addActiveDataSubscriptionIdListener(subId -> {});
+        mTelephonyListenerManager.addCallStateListener(state -> {});
+        mTelephonyListenerManager.addServiceStateListener(serviceState -> {});
+
+        verify(mTelephonyManager, times(1))
+                .registerTelephonyCallback(mExecutor, mTelephonyCallback);
+    }
+
+    @Test
+    public void testRemoveListenerUnregisters_ActiveDataSubscriptionIdListener() {
+        when(mTelephonyCallback.hasAnyListeners()).thenReturn(true);
+        ActiveDataSubscriptionIdListener mListener = subId -> { };
+
+        // Need to add one to actually register
+        mTelephonyListenerManager.addActiveDataSubscriptionIdListener(mListener);
+        verify(mTelephonyManager, times(1))
+                .registerTelephonyCallback(mExecutor, mTelephonyCallback);
+        reset(mTelephonyManager);
+
+        when(mTelephonyCallback.hasAnyListeners()).thenReturn(false);
+        mTelephonyListenerManager.removeActiveDataSubscriptionIdListener(mListener);
+        mTelephonyListenerManager.removeActiveDataSubscriptionIdListener(mListener);
+        mTelephonyListenerManager.removeActiveDataSubscriptionIdListener(mListener);
+        mTelephonyListenerManager.removeActiveDataSubscriptionIdListener(mListener);
+        verify(mTelephonyManager, times(1))
+                .unregisterTelephonyCallback(mTelephonyCallback);
+    }
+
+    @Test
+    public void testRemoveListenerUnregisters_CallStateListener() {
+        when(mTelephonyCallback.hasAnyListeners()).thenReturn(true);
+        CallStateListener mListener = state -> { };
+
+        // Need to add one to actually register
+        mTelephonyListenerManager.addCallStateListener(mListener);
+        verify(mTelephonyManager, times(1))
+                .registerTelephonyCallback(mExecutor, mTelephonyCallback);
+        reset(mTelephonyManager);
+
+        when(mTelephonyCallback.hasAnyListeners()).thenReturn(false);
+        mTelephonyListenerManager.removeCallStateListener(mListener);
+        mTelephonyListenerManager.removeCallStateListener(mListener);
+        mTelephonyListenerManager.removeCallStateListener(mListener);
+        mTelephonyListenerManager.removeCallStateListener(mListener);
+        verify(mTelephonyManager, times(1))
+                .unregisterTelephonyCallback(mTelephonyCallback);
+    }
+
+    @Test
+    public void testRemoveListenerUnregisters_ServiceStateListener() {
+        when(mTelephonyCallback.hasAnyListeners()).thenReturn(true);
+        ServiceStateListener mListener = serviceState -> { };
+
+        // Need to add one to actually register
+        mTelephonyListenerManager.addServiceStateListener(mListener);
+        verify(mTelephonyManager, times(1))
+                .registerTelephonyCallback(mExecutor, mTelephonyCallback);
+        reset(mTelephonyManager);
+
+        when(mTelephonyCallback.hasAnyListeners()).thenReturn(false);
+        mTelephonyListenerManager.removeServiceStateListener(mListener);
+        mTelephonyListenerManager.removeServiceStateListener(mListener);
+        mTelephonyListenerManager.removeServiceStateListener(mListener);
+        mTelephonyListenerManager.removeServiceStateListener(mListener);
+        verify(mTelephonyManager, times(1))
+                .unregisterTelephonyCallback(mTelephonyCallback);
+    }
+
+    @Test
+    public void testRemoveListenerUnregisters_mixed() {
+        when(mTelephonyCallback.hasAnyListeners()).thenReturn(true);
+        ActiveDataSubscriptionIdListener mListenerA = subId -> { };
+        ServiceStateListener mListenerB = serviceState -> { };
+        CallStateListener mListenerC = state -> { };
+
+        // Need to add one to actually register
+        mTelephonyListenerManager.addActiveDataSubscriptionIdListener(mListenerA);
+        verify(mTelephonyManager, times(1))
+                .registerTelephonyCallback(mExecutor, mTelephonyCallback);
+        reset(mTelephonyManager);
+
+        when(mTelephonyCallback.hasAnyListeners()).thenReturn(false);
+        mTelephonyListenerManager.removeActiveDataSubscriptionIdListener(mListenerA);
+        mTelephonyListenerManager.removeServiceStateListener(mListenerB);
+        mTelephonyListenerManager.removeCallStateListener(mListenerC);
+        mTelephonyListenerManager.removeActiveDataSubscriptionIdListener(mListenerA);
+        mTelephonyListenerManager.removeServiceStateListener(mListenerB);
+        mTelephonyListenerManager.removeCallStateListener(mListenerC);
+        verify(mTelephonyManager, times(1))
+                .unregisterTelephonyCallback(mTelephonyCallback);
+    }
+
+    @Test
+    public void testAddListener_noDoubleRegister() {
+        when(mTelephonyCallback.hasAnyListeners()).thenReturn(true);
+        mTelephonyListenerManager.addActiveDataSubscriptionIdListener(subId -> {});
+        verify(mTelephonyManager, times(1))
+                .registerTelephonyCallback(mExecutor, mTelephonyCallback);
+
+        reset(mTelephonyManager);
+
+        // A second call to add doesn't register another listener.
+        mTelephonyListenerManager.addActiveDataSubscriptionIdListener(subId -> {});
+        verify(mTelephonyManager, never()).registerTelephonyCallback(mExecutor, mTelephonyCallback);
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayApplierTest.java b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayApplierTest.java
index 6067b42..eb6fc2e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayApplierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayApplierTest.java
@@ -23,7 +23,6 @@
 import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_ICON_SETTINGS;
 import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_ICON_SYSUI;
 import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_ICON_THEME_PICKER;
-import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_NEUTRAL_PALETTE;
 import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_SHAPE;
 import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_SYSTEM_PALETTE;
 import static com.android.systemui.theme.ThemeOverlayApplier.SETTINGS_PACKAGE;
@@ -116,8 +115,6 @@
                                 ANDROID_PACKAGE, OVERLAY_CATEGORY_ACCENT_COLOR, false),
                         createOverlayInfo(TEST_DISABLED_PREFIX + OVERLAY_CATEGORY_SYSTEM_PALETTE,
                                 ANDROID_PACKAGE, OVERLAY_CATEGORY_SYSTEM_PALETTE, false),
-                        createOverlayInfo(TEST_DISABLED_PREFIX + OVERLAY_CATEGORY_NEUTRAL_PALETTE,
-                                ANDROID_PACKAGE, OVERLAY_CATEGORY_NEUTRAL_PALETTE, false),
                         createOverlayInfo(TEST_DISABLED_PREFIX + OVERLAY_CATEGORY_FONT,
                                 ANDROID_PACKAGE, OVERLAY_CATEGORY_FONT, false),
                         createOverlayInfo(TEST_DISABLED_PREFIX + OVERLAY_CATEGORY_SHAPE,
@@ -128,8 +125,6 @@
                                 ANDROID_PACKAGE, OVERLAY_CATEGORY_ACCENT_COLOR, true),
                         createOverlayInfo(TEST_ENABLED_PREFIX + OVERLAY_CATEGORY_SYSTEM_PALETTE,
                                 ANDROID_PACKAGE, OVERLAY_CATEGORY_SYSTEM_PALETTE, true),
-                        createOverlayInfo(TEST_ENABLED_PREFIX + OVERLAY_CATEGORY_NEUTRAL_PALETTE,
-                                ANDROID_PACKAGE, OVERLAY_CATEGORY_NEUTRAL_PALETTE, true),
                         createOverlayInfo(TEST_ENABLED_PREFIX + OVERLAY_CATEGORY_FONT,
                                 ANDROID_PACKAGE, OVERLAY_CATEGORY_FONT, true),
                         createOverlayInfo(TEST_ENABLED_PREFIX + OVERLAY_CATEGORY_SHAPE,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java
index 8a0ac11..4e7e0a3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java
@@ -17,7 +17,6 @@
 package com.android.systemui.theme;
 
 import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_ACCENT_COLOR;
-import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_NEUTRAL_PALETTE;
 import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_SYSTEM_PALETTE;
 
 import static com.google.common.truth.Truth.assertThat;
@@ -147,8 +146,6 @@
         // Assert that we received the colors that we were expecting
         assertThat(themeOverlays.getValue().get(OVERLAY_CATEGORY_SYSTEM_PALETTE))
                 .isEqualTo(new OverlayIdentifier("ffff0000"));
-        assertThat(themeOverlays.getValue().get(OVERLAY_CATEGORY_NEUTRAL_PALETTE))
-                .isEqualTo(new OverlayIdentifier("ffff0000"));
         assertThat(themeOverlays.getValue().get(OVERLAY_CATEGORY_ACCENT_COLOR))
                 .isEqualTo(new OverlayIdentifier("ff0000ff"));
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/concurrency/FakeExecutor.java b/packages/SystemUI/tests/src/com/android/systemui/util/concurrency/FakeExecutor.java
index 7c7ad53..d3d30f2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/concurrency/FakeExecutor.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/concurrency/FakeExecutor.java
@@ -27,6 +27,7 @@
     private final FakeSystemClock mClock;
     private PriorityQueue<QueuedRunnable> mQueuedRunnables = new PriorityQueue<>();
     private boolean mIgnoreClockUpdates;
+    private boolean mExecuting;
 
     /**
      * Initializes a fake executor.
@@ -56,7 +57,9 @@
      */
     public boolean runNextReady() {
         if (!mQueuedRunnables.isEmpty() && mQueuedRunnables.peek().mWhen <= mClock.uptimeMillis()) {
+            mExecuting = true;
             mQueuedRunnables.poll().mRunnable.run();
+            mExecuting = false;
             return true;
         }
 
@@ -162,6 +165,10 @@
         executeDelayed(command, 0);
     }
 
+    public boolean isExecuting() {
+        return mExecuting;
+    }
+
     /**
      * Run all Executors in a loop until they all report they have no ready work to do.
      *
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/concurrency/FakeExecutorTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/concurrency/FakeExecutorTest.java
index abc283f..87206c5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/concurrency/FakeExecutorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/concurrency/FakeExecutorTest.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.util.concurrency;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
@@ -319,6 +321,18 @@
         assertEquals(1, runnable.mRunCount);
     }
 
+    @Test
+    public void testIsExecuting() {
+        FakeSystemClock clock = new FakeSystemClock();
+        FakeExecutor fakeExecutor = new FakeExecutor(clock);
+
+        Runnable runnable = () -> assertThat(fakeExecutor.isExecuting()).isTrue();
+
+        assertThat(fakeExecutor.isExecuting()).isFalse();
+        fakeExecutor.execute(runnable);
+        assertThat(fakeExecutor.isExecuting()).isFalse();
+    }
+
     private static class RunnableImpl implements Runnable {
         int mRunCount;
 
diff --git a/packages/VpnDialogs/res/values/strings.xml b/packages/VpnDialogs/res/values/strings.xml
index 443a9bc..f971a09 100644
--- a/packages/VpnDialogs/res/values/strings.xml
+++ b/packages/VpnDialogs/res/values/strings.xml
@@ -28,6 +28,17 @@
         ]]> appears at the top of your screen when VPN is active.
     </string>
 
+    <!-- TV specific dialog message to warn about the risk of using a VPN application. [CHAR LIMIT=NONE] -->
+    <string name="warning" product="tv">
+      <xliff:g id="app">%s</xliff:g> wants to set up a VPN connection
+        that allows it to monitor network traffic. Only accept if you trust the source.
+        <![CDATA[
+        <br />
+        <br />
+        <img src="vpn_icon" />
+        ]]> appears on your screen when VPN is active.
+    </string>
+
     <!-- Dialog title for built-in VPN. [CHAR LIMIT=40]  -->
     <string name="legacy_title">VPN is connected</string>
     <!-- Label for the name of the current VPN session. [CHAR LIMIT=20] -->
diff --git a/proto/src/camera.proto b/proto/src/camera.proto
new file mode 100644
index 0000000..d07a525
--- /dev/null
+++ b/proto/src/camera.proto
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ */
+
+syntax = "proto2";
+
+package android.stats.camera;
+
+option java_package = "android.stats.camera";
+option java_outer_classname = "CameraProtos";
+
+/**
+ * CameraStreamProto from atoms.proto, duplicated here so that it's accessible from the
+ * logging code. Must be kept in sync with the definition in atoms.proto.
+ */
+message CameraStreamProto {
+    // The stream width (in pixels)
+    optional int32 width = 1;
+    // The stream height (in pixels)
+    optional int32 height = 2;
+    // The format of the stream
+    optional int32 format = 3;
+    // The dataspace of the stream
+    optional int32 data_space = 4;
+    // The usage flag of the stream
+    optional int64 usage = 5;
+
+    // The number of requests for this stream
+    optional int64 request_count = 6;
+    // The number of buffer error for this stream
+    optional int64 error_count = 7;
+    // The capture latency of first request for this stream
+    optional int32 first_capture_latency_millis = 8;
+
+    // The maximum number of hal buffers
+    optional int32 max_hal_buffers = 9;
+    // The maximum number of app buffers
+    optional int32 max_app_buffers = 10;
+
+    // Type of stream histogram
+    // 1: Capture latency: bin size in milliseconds
+    enum HistogramType {
+        UNKNOWN = 0;
+        CAPTURE_LATENCY = 1;
+    }
+    optional HistogramType histogram_type = 11;
+    // The boundary values between histogram bins
+    // Expected number of fields: 9
+    repeated float histogram_bins = 12;
+    // The frame counts for each histogram bins
+    // Expected number of fields: 10
+    repeated int64 histogram_counts = 13;
+}
diff --git a/services/Android.bp b/services/Android.bp
index f6bb157..c160842 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -9,7 +9,10 @@
 
 filegroup {
     name: "services-main-sources",
-    srcs: ["java/**/*.java"],
+    srcs: [
+        "java/**/*.java",
+        "java/**/package.html",
+    ],
     path: "java",
     visibility: ["//visibility:private"],
 }
@@ -19,6 +22,7 @@
     srcs: [
         ":services.core-sources",
         ":services.core-sources-am-wm",
+        "core/java/com/android/server/am/package.html",
         ":services.accessibility-sources",
         ":services.appprediction-sources",
         ":services.appwidget-sources",
@@ -153,7 +157,7 @@
         " --hide DeprecationMismatch" +
         " --hide HiddenTypedefConstant",
     visibility: ["//visibility:private"],
-    filter_packages: ["com.android."]
+    filter_packages: ["com.android."],
 }
 
 droidstubs {
@@ -168,7 +172,7 @@
         last_released: {
             api_file: ":android.api.system-server.latest",
             removed_api_file: ":removed.api.system-server.latest",
-            baseline_file: ":android-incompatibilities.api.system-server.latest"
+            baseline_file: ":android-incompatibilities.api.system-server.latest",
         },
         api_lint: {
             enabled: true,
@@ -178,18 +182,24 @@
     },
     dists: [
         {
-            targets: ["sdk", "win_sdk"],
+            targets: [
+                "sdk",
+                "win_sdk",
+            ],
             dir: "apistubs/android/system-server/api",
             dest: "android.txt",
-            tag: ".api.txt"
+            tag: ".api.txt",
         },
         {
-            targets: ["sdk", "win_sdk"],
+            targets: [
+                "sdk",
+                "win_sdk",
+            ],
             dir: "apistubs/android/system-server/api",
             dest: "removed.txt",
             tag: ".removed-api.txt",
         },
-    ]
+    ],
 }
 
 java_library {
@@ -223,16 +233,22 @@
     },
     dists: [
         {
-            targets: ["sdk", "win_sdk"],
+            targets: [
+                "sdk",
+                "win_sdk",
+            ],
             dir: "apistubs/android/system-server/api",
             dest: "android-non-updatable.txt",
-            tag: ".api.txt"
+            tag: ".api.txt",
         },
         {
-            targets: ["sdk", "win_sdk"],
+            targets: [
+                "sdk",
+                "win_sdk",
+            ],
             dir: "apistubs/android/system-server/api",
             dest: "android-non-updatable-removed.txt",
             tag: ".removed-api.txt",
         },
-    ]
-}
\ No newline at end of file
+    ],
+}
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 5b74cbd..1f66bfd 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java
@@ -79,7 +79,7 @@
 
     private final ScreenStateObserver mScreenStateObserver;
 
-    private final MagnificationRequestObserver mMagnificationRequestObserver;
+    private final MagnificationInfoChangedCallback mMagnificationInfoChangedCallback;
 
     private int mUserId;
 
@@ -284,6 +284,14 @@
             mControllerCtx.getHandler().sendMessage(m);
         }
 
+        @Override
+        public void onImeWindowVisibilityChanged(boolean shown) {
+            final Message m = PooledLambda.obtainMessage(
+                    FullScreenMagnificationController::notifyImeWindowVisibilityChanged,
+                    FullScreenMagnificationController.this, shown);
+            mControllerCtx.getHandler().sendMessage(m);
+        }
+
         /**
          * Update our copy of the current magnification region
          *
@@ -329,7 +337,7 @@
             final boolean lastMagnificationActivated = mMagnificationActivated;
             mMagnificationActivated = spec.scale > 1.0f;
             if (mMagnificationActivated != lastMagnificationActivated) {
-                mMagnificationRequestObserver.onFullScreenMagnificationActivationState(
+                mMagnificationInfoChangedCallback.onFullScreenMagnificationActivationState(
                         mMagnificationActivated);
             }
         }
@@ -498,7 +506,7 @@
             sendSpecToAnimation(mCurrentMagnificationSpec, animationCallback);
             if (isMagnifying() && (id != INVALID_ID)) {
                 mIdOfLastServiceToMagnify = id;
-                mMagnificationRequestObserver.onRequestMagnificationSpec(mDisplayId,
+                mMagnificationInfoChangedCallback.onRequestMagnificationSpec(mDisplayId,
                         mIdOfLastServiceToMagnify);
             }
             return changed;
@@ -631,12 +639,12 @@
      */
     public FullScreenMagnificationController(@NonNull Context context,
             @NonNull AccessibilityManagerService ams, @NonNull Object lock,
-            @NonNull MagnificationRequestObserver magnificationRequestObserver) {
+            @NonNull MagnificationInfoChangedCallback magnificationInfoChangedCallback) {
         this(new ControllerContext(context, ams,
                 LocalServices.getService(WindowManagerInternal.class),
                 new Handler(context.getMainLooper()),
                 context.getResources().getInteger(R.integer.config_longAnimTime)), lock,
-                magnificationRequestObserver);
+                magnificationInfoChangedCallback);
     }
 
     /**
@@ -645,12 +653,12 @@
     @VisibleForTesting
     public FullScreenMagnificationController(@NonNull ControllerContext ctx,
             @NonNull Object lock,
-            @NonNull MagnificationRequestObserver magnificationRequestObserver) {
+            @NonNull MagnificationInfoChangedCallback magnificationInfoChangedCallback) {
         mControllerCtx = ctx;
         mLock = lock;
         mMainThreadId = mControllerCtx.getContext().getMainLooper().getThread().getId();
         mScreenStateObserver = new ScreenStateObserver(mControllerCtx.getContext(), this);
-        mMagnificationRequestObserver = magnificationRequestObserver;
+        mMagnificationInfoChangedCallback = magnificationInfoChangedCallback;
     }
 
     /**
@@ -1168,6 +1176,16 @@
     }
 
     /**
+     * Notifies that the IME window visibility changed.
+     *
+     * @param shown {@code true} means the IME window shows on the screen. Otherwise it's
+     *                           hidden.
+     */
+    void notifyImeWindowVisibilityChanged(boolean shown) {
+        mMagnificationInfoChangedCallback.onImeWindowVisibilityChanged(shown);
+    }
+
+    /**
      * Returns {@code true} if the magnifiable regions of the display is forced to be shown.
      *
      * @param displayId The logical display id.
@@ -1528,7 +1546,7 @@
         return animate ? STUB_ANIMATION_CALLBACK : null;
     }
 
-    interface  MagnificationRequestObserver {
+    interface  MagnificationInfoChangedCallback {
 
         /**
          * Called when the {@link MagnificationSpec} is changed with non-default
@@ -1545,7 +1563,13 @@
          *
          * @param activated {@code true} if the magnification is activated, otherwise {@code false}.
          */
-        @GuardedBy("mLock")
         void onFullScreenMagnificationActivationState(boolean activated);
+
+        /**
+         * Called when the IME window visibility changed.
+         * @param shown {@code true} means the IME window shows on the screen. Otherwise it's
+         *                           hidden.
+         */
+        void onImeWindowVisibilityChanged(boolean shown);
     }
 }
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 2073c70..878ebc5 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java
@@ -18,6 +18,7 @@
 
 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;
 import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW;
 
 import android.annotation.NonNull;
@@ -33,6 +34,7 @@
 import android.view.accessibility.MagnificationAnimationCallback;
 
 import com.android.internal.accessibility.util.AccessibilityStatsLogUtils;
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.server.accessibility.AccessibilityManagerService;
 
@@ -58,7 +60,7 @@
  */
 public class MagnificationController implements WindowMagnificationManager.Callback,
         MagnificationGestureHandler.Callback,
-        FullScreenMagnificationController.MagnificationRequestObserver {
+        FullScreenMagnificationController.MagnificationInfoChangedCallback {
 
     private static final boolean DEBUG = false;
     private static final String TAG = "MagnificationController";
@@ -73,6 +75,10 @@
     private WindowMagnificationManager mWindowMagnificationMgr;
     private int mMagnificationCapabilities = ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
 
+    @GuardedBy("mLock")
+    private int mActivatedMode = ACCESSIBILITY_MAGNIFICATION_MODE_NONE;
+    @GuardedBy("mLock")
+    private boolean mImeWindowVisible = false;
     private long mWindowModeEnabledTime = 0;
     private long mFullScreenModeEnabledTime = 0;
 
@@ -216,9 +222,18 @@
     public void onWindowMagnificationActivationState(boolean activated) {
         if (activated) {
             mWindowModeEnabledTime = SystemClock.uptimeMillis();
+
+            synchronized (mLock) {
+                mActivatedMode = ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW;
+            }
+            logMagnificationModeWithImeOnIfNeeded();
         } else {
             logMagnificationUsageState(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW,
                     SystemClock.uptimeMillis() - mWindowModeEnabledTime);
+
+            synchronized (mLock) {
+                mActivatedMode = ACCESSIBILITY_MAGNIFICATION_MODE_NONE;
+            }
         }
     }
 
@@ -226,12 +241,29 @@
     public void onFullScreenMagnificationActivationState(boolean activated) {
         if (activated) {
             mFullScreenModeEnabledTime = SystemClock.uptimeMillis();
+
+            synchronized (mLock) {
+                mActivatedMode = ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
+            }
+            logMagnificationModeWithImeOnIfNeeded();
         } else {
             logMagnificationUsageState(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN,
                     SystemClock.uptimeMillis() - mFullScreenModeEnabledTime);
+
+            synchronized (mLock) {
+                mActivatedMode = ACCESSIBILITY_MAGNIFICATION_MODE_NONE;
+            }
         }
     }
 
+    @Override
+    public void onImeWindowVisibilityChanged(boolean shown) {
+        synchronized (mLock) {
+            mImeWindowVisible = shown;
+        }
+        logMagnificationModeWithImeOnIfNeeded();
+    }
+
     /**
      * Wrapper method of logging the magnification activated mode and its duration of the usage
      * when the magnification is disabled.
@@ -245,6 +277,17 @@
     }
 
     /**
+     * Wrapper method of logging the activated mode of the magnification when the IME window
+     * is shown on the screen.
+     *
+     * @param mode The activated magnification mode.
+     */
+    @VisibleForTesting
+    public void logMagnificationModeWithIme(int mode) {
+        AccessibilityStatsLogUtils.logMagnificationModeWithImeOn(mode);
+    }
+
+    /**
      * Updates the active user ID of {@link FullScreenMagnificationController} and {@link
      * WindowMagnificationManager}.
      *
@@ -295,6 +338,18 @@
         }
     }
 
+    private void logMagnificationModeWithImeOnIfNeeded() {
+        final int mode;
+
+        synchronized (mLock) {
+            if (!mImeWindowVisible || mActivatedMode == ACCESSIBILITY_MAGNIFICATION_MODE_NONE) {
+                return;
+            }
+            mode = mActivatedMode;
+        }
+        logMagnificationModeWithIme(mode);
+    }
+
     /**
      * Getter of {@link FullScreenMagnificationController}.
      *
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationPromptController.java b/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationPromptController.java
index d2c1bc1..1fdd908 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationPromptController.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationPromptController.java
@@ -108,7 +108,7 @@
                 SystemNotificationChannels.ACCESSIBILITY_MAGNIFICATION);
         final String message = mContext.getString(R.string.window_magnification_prompt_content);
 
-        notificationBuilder.setSmallIcon(R.drawable.ic_settings_24dp)
+        notificationBuilder.setSmallIcon(R.drawable.ic_accessibility_24dp)
                 .setContentTitle(mContext.getString(R.string.window_magnification_prompt_title))
                 .setContentText(message)
                 .setLargeIcon(Icon.createWithResource(mContext,
@@ -118,7 +118,7 @@
                 .setStyle(new Notification.BigTextStyle().bigText(message))
                 .setDeleteIntent(createPendingIntent(ACTION_DISMISS))
                 .setContentIntent(createPendingIntent(ACTION_TURN_ON_IN_SETTINGS))
-                .setActions(buildTurnOnAction(), buildDismissAction());
+                .setActions(buildTurnOnAction());
         mNotificationManager.notify(NOTE_A11Y_WINDOW_MAGNIFICATION_FEATURE,
                 notificationBuilder.build());
         registerReceiverIfNeeded();
@@ -145,11 +145,6 @@
                 createPendingIntent(ACTION_TURN_ON_IN_SETTINGS)).build();
     }
 
-    private Notification.Action buildDismissAction() {
-        return new Notification.Action.Builder(null, mContext.getString(R.string.dismiss_action),
-                createPendingIntent(ACTION_DISMISS)).build();
-    }
-
     private PendingIntent createPendingIntent(String action) {
         final Intent intent = new Intent(action);
         intent.setPackage(mContext.getPackageName());
diff --git a/services/api/current.txt b/services/api/current.txt
index a3e6715..a0b1e33 100644
--- a/services/api/current.txt
+++ b/services/api/current.txt
@@ -105,6 +105,14 @@
 
 }
 
+package com.android.server.stats {
+
+  public final class StatsHelper {
+    method public static void sendStatsdReadyBroadcast(@NonNull android.content.Context);
+  }
+
+}
+
 package com.android.server.wifi {
 
   public class SupplicantManager {
diff --git a/services/api/non-updatable-current.txt b/services/api/non-updatable-current.txt
index f01c182..475dcf5 100644
--- a/services/api/non-updatable-current.txt
+++ b/services/api/non-updatable-current.txt
@@ -52,6 +52,14 @@
 
 }
 
+package com.android.server.stats {
+
+  public final class StatsHelper {
+    method public static void sendStatsdReadyBroadcast(@NonNull android.content.Context);
+  }
+
+}
+
 package com.android.server.wifi {
 
   public class SupplicantManager {
diff --git a/services/appprediction/java/com/android/server/appprediction/AppPredictionManagerService.java b/services/appprediction/java/com/android/server/appprediction/AppPredictionManagerService.java
index e9a099a..2c50389 100644
--- a/services/appprediction/java/com/android/server/appprediction/AppPredictionManagerService.java
+++ b/services/appprediction/java/com/android/server/appprediction/AppPredictionManagerService.java
@@ -35,6 +35,7 @@
 import android.content.pm.ParceledListSlice;
 import android.os.Binder;
 import android.os.IBinder;
+import android.os.Process;
 import android.os.ResultReceiver;
 import android.os.ShellCallback;
 import android.util.Slog;
@@ -179,7 +180,8 @@
             Context ctx = getContext();
             if (!(ctx.checkCallingPermission(PACKAGE_USAGE_STATS) == PERMISSION_GRANTED
                     || mServiceNameResolver.isTemporary(userId)
-                    || mActivityTaskManagerInternal.isCallerRecents(Binder.getCallingUid()))) {
+                    || mActivityTaskManagerInternal.isCallerRecents(Binder.getCallingUid())
+                    || Binder.getCallingUid() == Process.SYSTEM_UID)) {
 
                 String msg = "Permission Denial: " + func + " from pid="
                         + Binder.getCallingPid()
diff --git a/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java b/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java
index 735f420..cd332a6 100644
--- a/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java
+++ b/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java
@@ -40,6 +40,7 @@
 import android.util.Slog;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
 import com.android.internal.infra.AbstractRemoteService;
 import com.android.server.LocalServices;
 import com.android.server.infra.AbstractPerUserSystemService;
@@ -55,6 +56,8 @@
     private static final String TAG = AppPredictionPerUserService.class.getSimpleName();
     private static final String PREDICT_USING_PEOPLE_SERVICE_PREFIX =
             "predict_using_people_service_";
+    private static final String REMOTE_APP_PREDICTOR_KEY = "remote_app_predictor";
+
 
     @Nullable
     @GuardedBy("mLock")
@@ -112,8 +115,16 @@
     @GuardedBy("mLock")
     public void onCreatePredictionSessionLocked(@NonNull AppPredictionContext context,
             @NonNull AppPredictionSessionId sessionId, @NonNull IBinder token) {
-        final boolean usesPeopleService = DeviceConfig.getBoolean(NAMESPACE_SYSTEMUI,
+        boolean usesPeopleService = DeviceConfig.getBoolean(NAMESPACE_SYSTEMUI,
                 PREDICT_USING_PEOPLE_SERVICE_PREFIX + context.getUiSurface(), false);
+        if (context.getExtras() != null
+                && context.getExtras().getBoolean(REMOTE_APP_PREDICTOR_KEY, false)
+                && DeviceConfig.getBoolean(NAMESPACE_SYSTEMUI,
+                SystemUiDeviceConfigFlags.DARK_LAUNCH_REMOTE_PREDICTION_SERVICE_ENABLED, false)
+        ) {
+            // connect with remote AppPredictionService instead for dark launch
+            usesPeopleService = false;
+        }
         final boolean serviceExists = resolveService(sessionId, false,
                 usesPeopleService, s -> s.onCreatePredictionSession(context, sessionId));
         if (serviceExists && !mSessionInfos.containsKey(sessionId)) {
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index a1ad72c..312cde6 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -25,6 +25,8 @@
 import static com.android.server.autofill.Helper.sFullScreenMode;
 import static com.android.server.autofill.Helper.sVerbose;
 
+import static java.util.Objects.requireNonNull;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.UserIdInt;
@@ -1370,15 +1372,16 @@
         }
 
         @Override
-        public void startSession(IBinder activityToken, IBinder appCallback, AutofillId autofillId,
-                Rect bounds, AutofillValue value, int userId, boolean hasCallback, int flags,
-                ComponentName componentName, boolean compatMode, IResultReceiver receiver) {
+        public void startSession(IBinder activityToken, IBinder clientCallback,
+                AutofillId autofillId, Rect bounds, AutofillValue value, int userId,
+                boolean hasCallback, int flags, ComponentName clientActivity,
+                boolean compatMode, IResultReceiver receiver) {
 
-            activityToken = Preconditions.checkNotNull(activityToken, "activityToken");
-            appCallback = Preconditions.checkNotNull(appCallback, "appCallback");
-            autofillId = Preconditions.checkNotNull(autofillId, "autoFillId");
-            componentName = Preconditions.checkNotNull(componentName, "componentName");
-            final String packageName = Preconditions.checkNotNull(componentName.getPackageName());
+            requireNonNull(activityToken, "activityToken");
+            requireNonNull(clientCallback, "clientCallback");
+            requireNonNull(autofillId, "autofillId");
+            requireNonNull(clientActivity, "clientActivity");
+            final String packageName = requireNonNull(clientActivity.getPackageName());
 
             Preconditions.checkArgument(userId == UserHandle.getUserId(getCallingUid()), "userId");
 
@@ -1395,7 +1398,7 @@
             synchronized (mLock) {
                 final AutofillManagerServiceImpl service = getServiceForUserLocked(userId);
                 result = service.startSessionLocked(activityToken, taskId, getCallingUid(),
-                        appCallback, autofillId, bounds, value, hasCallback, componentName,
+                        clientCallback, autofillId, bounds, value, hasCallback, clientActivity,
                         compatMode, mAllowInstantService, flags);
             }
             final int sessionId = (int) result;
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index b5f4813..27be331 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -307,10 +307,10 @@
      * {@link AutofillManager#RECEIVER_FLAG_SESSION_FOR_AUGMENTED_AUTOFILL_ONLY}).
      */
     @GuardedBy("mLock")
-    long startSessionLocked(@NonNull IBinder activityToken, int taskId, int uid,
-            @NonNull IBinder appCallbackToken, @NonNull AutofillId autofillId,
+    long startSessionLocked(@NonNull IBinder activityToken, int taskId, int clientUid,
+            @NonNull IBinder clientCallback, @NonNull AutofillId autofillId,
             @NonNull Rect virtualBounds, @Nullable AutofillValue value, boolean hasCallback,
-            @NonNull ComponentName componentName, boolean compatMode,
+            @NonNull ComponentName clientActivity, boolean compatMode,
             boolean bindInstantServiceAllowed, int flags) {
         // FLAG_AUGMENTED_AUTOFILL_REQUEST is set in the flags when standard autofill is disabled
         // but the package is allowlisted for augmented autofill
@@ -320,29 +320,29 @@
             return 0;
         }
 
-        if (!forAugmentedAutofillOnly && isAutofillDisabledLocked(componentName)) {
+        if (!forAugmentedAutofillOnly && isAutofillDisabledLocked(clientActivity)) {
             // Standard autofill is enabled, but service disabled autofill for this activity; that
             // means no session, unless the activity is allowlisted for augmented autofill
-            if (isWhitelistedForAugmentedAutofillLocked(componentName)) {
+            if (isWhitelistedForAugmentedAutofillLocked(clientActivity)) {
                 if (sDebug) {
-                    Slog.d(TAG, "startSession(" + componentName + "): disabled by service but "
+                    Slog.d(TAG, "startSession(" + clientActivity + "): disabled by service but "
                             + "whitelisted for augmented autofill");
                 }
                 forAugmentedAutofillOnly = true;
 
             } else {
                 if (sDebug) {
-                    Slog.d(TAG, "startSession(" + componentName + "): ignored because "
+                    Slog.d(TAG, "startSession(" + clientActivity + "): ignored because "
                             + "disabled by service and not whitelisted for augmented autofill");
                 }
                 final IAutoFillManagerClient client = IAutoFillManagerClient.Stub
-                        .asInterface(appCallbackToken);
+                        .asInterface(clientCallback);
                 try {
                     client.setSessionFinished(AutofillManager.STATE_DISABLED_BY_SERVICE,
                             /* autofillableIds= */ null);
                 } catch (RemoteException e) {
                     Slog.w(TAG,
-                            "Could not notify " + componentName + " that it's disabled: " + e);
+                            "Could not notify " + clientActivity + " that it's disabled: " + e);
                 }
 
                 return NO_SESSION;
@@ -357,8 +357,8 @@
         // Occasionally clean up abandoned sessions
         pruneAbandonedSessionsLocked();
 
-        final Session newSession = createSessionByTokenLocked(activityToken, taskId, uid,
-                appCallbackToken, hasCallback, componentName, compatMode,
+        final Session newSession = createSessionByTokenLocked(activityToken, taskId, clientUid,
+                clientCallback, hasCallback, clientActivity, compatMode,
                 bindInstantServiceAllowed, forAugmentedAutofillOnly, flags);
         if (newSession == null) {
             return NO_SESSION;
@@ -367,7 +367,7 @@
         // Service can be null when it's only for augmented autofill
         String servicePackageName = mInfo == null ? null : mInfo.getServiceInfo().packageName;
         final String historyItem =
-                "id=" + newSession.id + " uid=" + uid + " a=" + componentName.toShortString()
+                "id=" + newSession.id + " uid=" + clientUid + " a=" + clientActivity.toShortString()
                 + " s=" + servicePackageName
                 + " u=" + mUserId + " i=" + autofillId + " b=" + virtualBounds
                 + " hc=" + hasCallback + " f=" + flags + " aa=" + forAugmentedAutofillOnly;
@@ -493,9 +493,9 @@
     }
 
     @GuardedBy("mLock")
-    private Session createSessionByTokenLocked(@NonNull IBinder activityToken, int taskId, int uid,
-            @NonNull IBinder appCallbackToken, boolean hasCallback,
-            @NonNull ComponentName componentName, boolean compatMode,
+    private Session createSessionByTokenLocked(@NonNull IBinder clientActivityToken, int taskId,
+            int clientUid, @NonNull IBinder clientCallback, boolean hasCallback,
+            @NonNull ComponentName clientActivity, boolean compatMode,
             boolean bindInstantServiceAllowed, boolean forAugmentedAutofillOnly, int flags) {
         // use random ids so that one app cannot know that another app creates sessions
         int sessionId;
@@ -511,15 +511,15 @@
         } while (sessionId == 0 || sessionId == NO_SESSION
                 || mSessions.indexOfKey(sessionId) >= 0);
 
-        assertCallerLocked(componentName, compatMode);
+        assertCallerLocked(clientActivity, compatMode);
 
         // It's null when the session is just for augmented autofill
         final ComponentName serviceComponentName = mInfo == null ? null
                 : mInfo.getServiceInfo().getComponentName();
         final Session newSession = new Session(this, mUi, getContext(), mHandler, mUserId, mLock,
-                sessionId, taskId, uid, activityToken, appCallbackToken, hasCallback,
+                sessionId, taskId, clientUid, clientActivityToken, clientCallback, hasCallback,
                 mUiLatencyHistory, mWtfHistory, serviceComponentName,
-                componentName, compatMode, bindInstantServiceAllowed, forAugmentedAutofillOnly,
+                clientActivity, compatMode, bindInstantServiceAllowed, forAugmentedAutofillOnly,
                 flags, mInputMethodManagerInternal);
         mSessions.put(newSession.id, newSession);
 
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index b7f736e..a230f80 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -196,7 +196,7 @@
     /** userId the session belongs to */
     public final int userId;
 
-    /** uid the session is for */
+    /** The uid of the app that's being autofilled */
     public final int uid;
 
     /** ID of the task associated with this session's activity */
@@ -208,7 +208,7 @@
     @GuardedBy("mLock")
     @NonNull private IBinder mActivityToken;
 
-    /** Component that's being auto-filled */
+    /** The app activity that's being autofilled */
     @NonNull private final ComponentName mComponentName;
 
     /** Whether the app being autofilled is running in compat mode. */
diff --git a/services/backup/java/com/android/server/backup/utils/BackupEligibilityRules.java b/services/backup/java/com/android/server/backup/utils/BackupEligibilityRules.java
index 002f6d7..818155c 100644
--- a/services/backup/java/com/android/server/backup/utils/BackupEligibilityRules.java
+++ b/services/backup/java/com/android/server/backup/utils/BackupEligibilityRules.java
@@ -71,6 +71,14 @@
     @EnabledSince(targetSdkVersion = Build.VERSION_CODES.S)
     static final long RESTRICT_ADB_BACKUP = 171032338L;
 
+    /**
+     * When  this change is enabled, {@code android:allowBackup}  is ignored for apps during D2D
+     * (device-to-device) migrations.
+     */
+    @ChangeId
+    @EnabledSince(targetSdkVersion = Build.VERSION_CODES.S)
+    static final long IGNORE_ALLOW_BACKUP_IN_D2D = 183147249L;
+
     public static BackupEligibilityRules forBackup(PackageManager packageManager,
             PackageManagerInternal packageManagerInternal,
             int userId) {
@@ -148,13 +156,15 @@
     * @return boolean indicating whether backup is allowed.
     */
     public boolean isAppBackupAllowed(ApplicationInfo app) {
-        boolean isSystemApp = UserHandle.isCore(app.uid);
         boolean allowBackup = (app.flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0;
         switch (mOperationType) {
             case OperationType.MIGRATION:
                 // Backup / restore of all non-system apps is force allowed during
                 // device-to-device migration.
-                return !isSystemApp || allowBackup;
+                boolean isSystemApp = (app.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
+                boolean ignoreAllowBackup = !isSystemApp && CompatChanges.isChangeEnabled(
+                        IGNORE_ALLOW_BACKUP_IN_D2D, app.packageName, UserHandle.of(mUserId));
+                return ignoreAllowBackup || allowBackup;
             case OperationType.ADB_BACKUP:
                 String packageName = app.packageName;
                 if (packageName == null) {
@@ -176,7 +186,7 @@
 
                 boolean isPrivileged = (app.flags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
                 boolean isDebuggable = (app.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
-                if (isSystemApp || isPrivileged) {
+                if (UserHandle.isCore(app.uid) || isPrivileged) {
                     try {
                         return mPackageManager.getProperty(PackageManager.PROPERTY_ALLOW_ADB_BACKUP,
                                 packageName).getBoolean();
@@ -283,11 +293,6 @@
      */
     @VisibleForTesting
     public boolean appGetsFullBackup(PackageInfo pkg) {
-        if (forceFullBackup(pkg.applicationInfo.uid, mOperationType)) {
-            // If this is a migration, all non-system packages get full backup.
-            return true;
-        }
-
         if (pkg.applicationInfo.backupAgentName != null) {
             // If it has an agent, it gets full backups only if it says so
             return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_FULL_BACKUP_ONLY) != 0;
@@ -297,15 +302,6 @@
         return true;
     }
 
-    public boolean appIgnoresIncludeExcludeRules(ApplicationInfo app) {
-        return forceFullBackup(app.uid, mOperationType);
-    }
-
-    private boolean forceFullBackup(int appUid, @OperationType int operationType) {
-        return operationType == OperationType.MIGRATION &&
-                !UserHandle.isCore(appUid);
-    }
-
     /**
      * Returns whether the app is only capable of doing key/value. We say it's not if it allows full
      * backup, and it is otherwise.
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index 9ac93d9..483f67a 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -639,6 +639,16 @@
             }));
         }
 
+        @Override
+        public boolean createAssociation(String packageName, String macAddress, int userId) {
+            getContext().enforceCallingOrSelfPermission(
+                    android.Manifest.permission.ASSOCIATE_COMPANION_DEVICES, "createAssociation");
+
+            addAssociation(new Association(
+                    userId, macAddress, packageName, null, false, System.currentTimeMillis()));
+            return true;
+        }
+
         private void checkCanCallNotificationApi(String callingPackage) throws RemoteException {
             checkCallerIsSystemOr(callingPackage);
             int userId = getCallingUserId();
@@ -1205,8 +1215,6 @@
         }
 
         public void schedule() {
-            Slog.d(LOG_TAG,
-                    "TriggerDeviceDisappearedRunnable.schedule(address = " + mAddress + ")");
             mMainHandler.removeCallbacks(this);
             mMainHandler.postDelayed(this, this, DEVICE_DISAPPEARED_TIMEOUT_MS);
         }
@@ -1244,8 +1252,6 @@
     }
 
     private void onDeviceNearby(String address) {
-        Slog.i(LOG_TAG, "onDeviceNearby(address = " + address + ")");
-
         Date timestamp = new Date();
         Date oldTimestamp = mDevicesLastNearby.put(address, timestamp);
 
@@ -1259,13 +1265,11 @@
         boolean justAppeared = oldTimestamp == null
                 || timestamp.getTime() - oldTimestamp.getTime() >= DEVICE_DISAPPEARED_TIMEOUT_MS;
         if (justAppeared) {
+            Slog.i(LOG_TAG, "onDeviceNearby(justAppeared, address = " + address + ")");
             for (Association association : getAllAssociations(address)) {
                 if (association.isNotifyOnDeviceNearby()) {
-                    if (DEBUG) {
-                        Slog.i(LOG_TAG, "Device " + address
-                                + " managed by " + association.getPackageName()
-                                + " is nearby on " + timestamp);
-                    }
+                    Slog.i(LOG_TAG,
+                            "Sending onDeviceAppeared to " + association.getPackageName() + ")");
                     getDeviceListenerServiceConnector(association).run(
                             service -> service.onDeviceAppeared(association.getDeviceMacAddress()));
                 }
@@ -1279,12 +1283,8 @@
         boolean hasDeviceListeners = false;
         for (Association association : getAllAssociations(address)) {
             if (association.isNotifyOnDeviceNearby()) {
-                if (DEBUG) {
-                    Slog.i(LOG_TAG, "Device " + address
-                            + " managed by " + association.getPackageName()
-                            + " disappeared; last seen on " + mDevicesLastNearby.get(address));
-                }
-
+                Slog.i(LOG_TAG,
+                        "Sending onDeviceDisappeared to " + association.getPackageName() + ")");
                 getDeviceListenerServiceConnector(association).run(
                         service -> service.onDeviceDisappeared(address));
                 hasDeviceListeners = true;
diff --git a/services/core/Android.bp b/services/core/Android.bp
index ed2e625..1e3f12a 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -158,7 +158,7 @@
         "android.hardware.power.stats-V1-java",
         "android.hidl.manager-V1.2-java",
         "capture_state_listener-aidl-java",
-        "dnsresolver_aidl_interface-V7-java",
+        "dnsresolver_aidl_interface-V8-java",
         "icu4j_calendar_astronomer",
         "netd-client",
         "overlayable_policy_aidl-java",
@@ -222,10 +222,12 @@
     srcs: [
         "java/com/android/server/ConnectivityService.java",
         "java/com/android/server/ConnectivityServiceInitializer.java",
+        "java/com/android/server/NetIdManager.java",
         "java/com/android/server/TestNetworkService.java",
         "java/com/android/server/connectivity/AutodestructReference.java",
         "java/com/android/server/connectivity/ConnectivityConstants.java",
         "java/com/android/server/connectivity/DnsManager.java",
+        "java/com/android/server/connectivity/FullScore.java",
         "java/com/android/server/connectivity/KeepaliveTracker.java",
         "java/com/android/server/connectivity/LingerMonitor.java",
         "java/com/android/server/connectivity/MockableSystemProperties.java",
@@ -233,8 +235,11 @@
         "java/com/android/server/connectivity/NetworkAgentInfo.java",
         "java/com/android/server/connectivity/NetworkDiagnostics.java",
         "java/com/android/server/connectivity/NetworkNotificationManager.java",
+        "java/com/android/server/connectivity/NetworkOffer.java",
         "java/com/android/server/connectivity/NetworkRanker.java",
+        "java/com/android/server/connectivity/OsCompat.java",
         "java/com/android/server/connectivity/PermissionMonitor.java",
+        "java/com/android/server/connectivity/ProfileNetworkPreferences.java",
         "java/com/android/server/connectivity/ProxyTracker.java",
         "java/com/android/server/connectivity/QosCallbackAgentConnection.java",
         "java/com/android/server/connectivity/QosCallbackTracker.java",
diff --git a/services/core/java/android/content/pm/PackageManagerInternal.java b/services/core/java/android/content/pm/PackageManagerInternal.java
index b089014..a9eb2c1 100644
--- a/services/core/java/android/content/pm/PackageManagerInternal.java
+++ b/services/core/java/android/content/pm/PackageManagerInternal.java
@@ -1143,10 +1143,7 @@
             @NonNull String packageName, int callingUid, int userId);
 
     /**
-     * Returns true if the given {@code packageName} has declared the
-     * {@code neverForLocation} flag in the {@code uses-permission} manifest tag
-     * where they request the given {@code permissionName}.
+     * Deletes the OAT artifacts of a package.
      */
-    public abstract boolean isPackageUsesPermissionNeverForLocation(@NonNull String packageName,
-            @NonNull String permissionName);
+    public abstract void deleteOatArtifactsOfPackage(String packageName);
 }
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index f0c9ba9..09cfac0 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -16,7 +16,10 @@
 
 package com.android.server;
 
+import static android.Manifest.permission.BLUETOOTH_CONNECT;
+import static android.content.PermissionChecker.PERMISSION_HARD_DENIED;
 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.os.UserHandle.USER_SYSTEM;
 
 import android.Manifest;
@@ -43,6 +46,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.PermissionChecker;
 import android.content.ServiceConnection;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageManager;
@@ -95,8 +99,6 @@
     private static final String TAG = "BluetoothManagerService";
     private static final boolean DBG = true;
 
-    private static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN;
-    private static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH;
     private static final String BLUETOOTH_PRIVILEGED =
             android.Manifest.permission.BLUETOOTH_PRIVILEGED;
 
@@ -696,14 +698,18 @@
             Slog.w(TAG, "Callback is null in unregisterAdapter");
             return;
         }
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+        if (!checkConnectPermissionForPreflight(mContext)) {
+            return;
+        }
         synchronized (mCallbacks) {
             mCallbacks.unregister(callback);
         }
     }
 
     public void registerStateChangeCallback(IBluetoothStateChangeCallback callback) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+        if (!checkConnectPermissionForPreflight(mContext)) {
+            return;
+        }
         if (callback == null) {
             Slog.w(TAG, "registerStateChangeCallback: Callback is null!");
             return;
@@ -714,7 +720,9 @@
     }
 
     public void unregisterStateChangeCallback(IBluetoothStateChangeCallback callback) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+        if (!checkConnectPermissionForPreflight(mContext)) {
+            return;
+        }
         if (callback == null) {
             Slog.w(TAG, "unregisterStateChangeCallback: Callback is null!");
             return;
@@ -945,8 +953,9 @@
                 return false;
             }
 
-            mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
-                    "Need BLUETOOTH ADMIN permission");
+            if (!checkConnectPermissionForPreflight(mContext)) {
+                return false;
+            }
         }
         return true;
     }
@@ -1672,7 +1681,9 @@
     }
 
     public String getAddress() {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+        if (!checkConnectPermissionForPreflight(mContext)) {
+            return null;
+        }
 
         if ((Binder.getCallingUid() != Process.SYSTEM_UID) && (!checkIfCallerIsForegroundUser())) {
             Slog.w(TAG, "getAddress(): not allowed for non-active and non system user");
@@ -1704,7 +1715,9 @@
     }
 
     public String getName() {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+        if (!checkConnectPermissionForPreflight(mContext)) {
+            return null;
+        }
 
         if ((Binder.getCallingUid() != Process.SYSTEM_UID) && (!checkIfCallerIsForegroundUser())) {
             Slog.w(TAG, "getName(): not allowed for non-active and non system user");
@@ -2459,7 +2472,7 @@
         intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, prevState);
         intent.putExtra(BluetoothAdapter.EXTRA_STATE, newState);
         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
-        mContext.sendBroadcastAsUser(intent, UserHandle.ALL, BLUETOOTH_PERM);
+        mContext.sendBroadcastAsUser(intent, UserHandle.ALL, BLUETOOTH_CONNECT);
     }
 
     private void bluetoothStateChangeHandler(int prevState, int newState) {
@@ -2538,7 +2551,7 @@
             intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, prevState);
             intent.putExtra(BluetoothAdapter.EXTRA_STATE, newState);
             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
-            mContext.sendBroadcastAsUser(intent, UserHandle.ALL, BLUETOOTH_PERM);
+            mContext.sendBroadcastAsUser(intent, UserHandle.ALL, BLUETOOTH_CONNECT);
         }
     }
 
@@ -2827,4 +2840,20 @@
             default: return "UNKNOWN[" + reason + "]";
         }
     }
+
+    /**
+     * Returns true if the BLUETOOTH_CONNECT permission is granted for the calling app. Returns
+     * false if the result is a soft denial. Throws SecurityException if the result is a hard
+     * denial.
+     *
+     * <p>Should be used in situations where the app op should not be noted.
+     */
+    private static boolean checkConnectPermissionForPreflight(Context context) {
+        int permissionCheckResult = PermissionChecker.checkCallingOrSelfPermissionForPreflight(
+                context, BLUETOOTH_CONNECT);
+        if (permissionCheckResult == PERMISSION_HARD_DENIED) {
+            throw new SecurityException("Need BLUETOOTH_CONNECT permission");
+        }
+        return permissionCheckResult == PERMISSION_GRANTED;
+    }
 }
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 0515eca..ca01c8e 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -15,7 +15,6 @@
  */
 
 package com.android.server;
-
 import static android.Manifest.permission.RECEIVE_DATA_ACTIVITY_CHANGE;
 import static android.content.pm.PackageManager.FEATURE_BLUETOOTH;
 import static android.content.pm.PackageManager.FEATURE_WATCH;
@@ -30,6 +29,9 @@
 import static android.net.ConnectivityDiagnosticsManager.DataStallReport.KEY_DNS_CONSECUTIVE_TIMEOUTS;
 import static android.net.ConnectivityDiagnosticsManager.DataStallReport.KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS;
 import static android.net.ConnectivityDiagnosticsManager.DataStallReport.KEY_TCP_PACKET_FAIL_RATE;
+import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_MASK;
+import static android.net.ConnectivityManager.BLOCKED_REASON_LOCKDOWN_VPN;
+import static android.net.ConnectivityManager.BLOCKED_REASON_NONE;
 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
 import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
 import static android.net.ConnectivityManager.TYPE_BLUETOOTH;
@@ -69,10 +71,12 @@
 import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
+import static android.net.NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION;
+import static android.net.NetworkCapabilities.REDACT_FOR_LOCAL_MAC_ADDRESS;
+import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS;
 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
 import static android.net.NetworkCapabilities.TRANSPORT_TEST;
 import static android.net.NetworkCapabilities.TRANSPORT_VPN;
-import static android.net.NetworkPolicyManager.BLOCKED_REASON_NONE;
 import static android.net.NetworkPolicyManager.blockedReasonsToString;
 import static android.net.NetworkRequest.Type.LISTEN_FOR_BEST;
 import static android.net.shared.NetworkMonitorUtils.isPrivateDnsValidationRequired;
@@ -84,7 +88,6 @@
 import static java.util.Map.Entry;
 
 import android.Manifest;
-import android.annotation.BoolRes;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.AppOpsManager;
@@ -105,6 +108,7 @@
 import android.net.ConnectivityDiagnosticsManager.ConnectivityReport;
 import android.net.ConnectivityDiagnosticsManager.DataStallReport;
 import android.net.ConnectivityManager;
+import android.net.ConnectivityManager.BlockedReason;
 import android.net.ConnectivityManager.NetworkCallback;
 import android.net.ConnectivityManager.RestrictBackgroundStatus;
 import android.net.ConnectivityResources;
@@ -120,6 +124,7 @@
 import android.net.INetworkAgent;
 import android.net.INetworkMonitor;
 import android.net.INetworkMonitorCallbacks;
+import android.net.INetworkOfferCallback;
 import android.net.IOnCompleteListener;
 import android.net.IQosCallback;
 import android.net.ISocketKeepaliveCallback;
@@ -143,7 +148,6 @@
 import android.net.NetworkScore;
 import android.net.NetworkSpecifier;
 import android.net.NetworkStack;
-import android.net.NetworkStackClient;
 import android.net.NetworkState;
 import android.net.NetworkStateSnapshot;
 import android.net.NetworkTestResultParcelable;
@@ -170,13 +174,14 @@
 import android.net.metrics.IpConnectivityLog;
 import android.net.metrics.NetworkEvent;
 import android.net.netlink.InetDiagMessage;
+import android.net.networkstack.ModuleNetworkStackClient;
+import android.net.networkstack.NetworkStackClientBase;
 import android.net.resolv.aidl.DnsHealthEventParcel;
 import android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener;
 import android.net.resolv.aidl.Nat64PrefixEventParcel;
 import android.net.resolv.aidl.PrivateDnsValidationEventParcel;
 import android.net.shared.PrivateDnsConfig;
 import android.net.util.MultinetworkPolicyTracker;
-import android.net.util.NetdService;
 import android.os.BatteryStatsManager;
 import android.os.Binder;
 import android.os.Build;
@@ -211,6 +216,7 @@
 import android.util.SparseArray;
 import android.util.SparseIntArray;
 
+import com.android.connectivity.resources.R;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.IndentingPrintWriter;
@@ -226,6 +232,7 @@
 import com.android.server.connectivity.AutodestructReference;
 import com.android.server.connectivity.DnsManager;
 import com.android.server.connectivity.DnsManager.PrivateDnsValidationUpdate;
+import com.android.server.connectivity.FullScore;
 import com.android.server.connectivity.KeepaliveTracker;
 import com.android.server.connectivity.LingerMonitor;
 import com.android.server.connectivity.MockableSystemProperties;
@@ -233,6 +240,7 @@
 import com.android.server.connectivity.NetworkDiagnostics;
 import com.android.server.connectivity.NetworkNotificationManager;
 import com.android.server.connectivity.NetworkNotificationManager.NotificationType;
+import com.android.server.connectivity.NetworkOffer;
 import com.android.server.connectivity.NetworkRanker;
 import com.android.server.connectivity.PermissionMonitor;
 import com.android.server.connectivity.ProfileNetworkPreferences;
@@ -590,6 +598,18 @@
     private static final int EVENT_UID_BLOCKED_REASON_CHANGED = 51;
 
     /**
+     * Event to register a new network offer
+     * obj = NetworkOffer
+     */
+    private static final int EVENT_REGISTER_NETWORK_OFFER = 52;
+
+    /**
+     * Event to unregister an existing network offer
+     * obj = INetworkOfferCallback
+     */
+    private static final int EVENT_UNREGISTER_NETWORK_OFFER = 53;
+
+    /**
      * Argument for {@link #EVENT_PROVISIONING_NOTIFICATION} to indicate that the notification
      * should be shown.
      */
@@ -817,8 +837,7 @@
 
         private ArrayMap<Integer, Integer> loadRestoreTimers() {
             final String[] configs = mService.mResources.get().getStringArray(
-                    com.android.connectivity.resources.R.array
-                            .config_legacy_networktype_restore_timers);
+                    R.array.config_legacy_networktype_restore_timers);
             final ArrayMap<Integer, Integer> ret = new ArrayMap<>(configs.length);
             for (final String config : configs) {
                 final String[] splits = TextUtils.split(config, ",");
@@ -1119,10 +1138,10 @@
         }
 
         /**
-         * Get a reference to the NetworkStackClient.
+         * Get a reference to the ModuleNetworkStackClient.
          */
-        public NetworkStackClient getNetworkStack() {
-            return NetworkStackClient.getInstance();
+        public NetworkStackClientBase getNetworkStack() {
+            return ModuleNetworkStackClient.getInstance(null);
         }
 
         /**
@@ -1143,8 +1162,8 @@
         /**
          * @see NetworkUtils#queryUserAccess(int, int)
          */
-        public boolean queryUserAccess(int uid, int netId) {
-            return NetworkUtils.queryUserAccess(uid, netId);
+        public boolean queryUserAccess(int uid, Network network, ConnectivityService cs) {
+            return cs.queryUserAccess(uid, network);
         }
 
         /**
@@ -1181,7 +1200,8 @@
 
     public ConnectivityService(Context context) {
         this(context, getDnsResolver(context), new IpConnectivityLog(),
-                NetdService.getInstance(), new Dependencies());
+                INetd.Stub.asInterface((IBinder) context.getSystemService(Context.NETD_SERVICE)),
+                new Dependencies());
     }
 
     @VisibleForTesting
@@ -1200,7 +1220,7 @@
         mNetworkRanker = new NetworkRanker();
         final NetworkRequest defaultInternetRequest = createDefaultRequest();
         mDefaultRequest = new NetworkRequestInfo(
-                defaultInternetRequest, null,
+                Process.myUid(), defaultInternetRequest, null,
                 new Binder(), NetworkCallback.FLAG_INCLUDE_LOCATION_INFO,
                 null /* attributionTags */);
         mNetworkRequests.put(defaultInternetRequest, mDefaultRequest);
@@ -1256,8 +1276,7 @@
 
         mLegacyTypeTracker.loadSupportedTypes(mContext, mTelephonyManager);
         mProtectedNetworks = new ArrayList<>();
-        int[] protectedNetworks = context.getResources().getIntArray(
-                com.android.internal.R.array.config_protectedNetworks);
+        int[] protectedNetworks = mResources.get().getIntArray(R.array.config_protectedNetworks);
         for (int p : protectedNetworks) {
             if (mLegacyTypeTracker.isTypeSupported(p) && !mProtectedNetworks.contains(p)) {
                 mProtectedNetworks.add(p);
@@ -1387,7 +1406,7 @@
         mHandler.sendEmptyMessage(EVENT_PRIVATE_DNS_SETTINGS_CHANGED);
     }
 
-    private void handleAlwaysOnNetworkRequest(NetworkRequest networkRequest, @BoolRes int id) {
+    private void handleAlwaysOnNetworkRequest(NetworkRequest networkRequest, int id) {
         final boolean enable = mContext.getResources().getBoolean(id);
         handleAlwaysOnNetworkRequest(networkRequest, enable);
     }
@@ -1407,8 +1426,7 @@
 
         if (enable) {
             handleRegisterNetworkRequest(new NetworkRequestInfo(
-                    networkRequest, null,
-                    new Binder(),
+                    Process.myUid(), networkRequest, null, new Binder(),
                     NetworkCallback.FLAG_INCLUDE_LOCATION_INFO,
                     null /* attributionTags */));
         } else {
@@ -1422,8 +1440,14 @@
                 ConnectivitySettingsManager.MOBILE_DATA_ALWAYS_ON, true /* defaultValue */);
         handleAlwaysOnNetworkRequest(mDefaultWifiRequest,
                 ConnectivitySettingsManager.WIFI_ALWAYS_REQUESTED, false /* defaultValue */);
+        final boolean vehicleAlwaysRequested = mResources.get().getBoolean(
+                R.bool.config_vehicleInternalNetworkAlwaysRequested);
+        // TODO (b/183076074): remove legacy fallback after migrating overlays
+        final boolean legacyAlwaysRequested = mContext.getResources().getBoolean(
+                mContext.getResources().getIdentifier(
+                        "config_vehicleInternalNetworkAlwaysRequested", "bool", "android"));
         handleAlwaysOnNetworkRequest(mDefaultVehicleRequest,
-                com.android.internal.R.bool.config_vehicleInternalNetworkAlwaysRequested);
+                vehicleAlwaysRequested || legacyAlwaysRequested);
     }
 
     private void registerSettingsCallbacks() {
@@ -1546,16 +1570,16 @@
         mNetworkInfoBlockingLogs.log(action + " " + uid);
     }
 
-    private void maybeLogBlockedStatusChanged(NetworkRequestInfo nri, Network net,
-            boolean blocked) {
+    private void maybeLogBlockedStatusChanged(NetworkRequestInfo nri, Network net, int blocked) {
         if (nri == null || net == null || !LOGD_BLOCKED_NETWORKINFO) {
             return;
         }
-        final String action = blocked ? "BLOCKED" : "UNBLOCKED";
+        final String action = (blocked != 0) ? "BLOCKED" : "UNBLOCKED";
         final int requestId = nri.getActiveRequest() != null
                 ? nri.getActiveRequest().requestId : nri.mRequests.get(0).requestId;
         mNetworkInfoBlockingLogs.log(String.format(
-                "%s %d(%d) on netId %d", action, nri.mUid, requestId, net.getNetId()));
+                "%s %d(%d) on netId %d: %s", action, nri.mAsUid, requestId, net.getNetId(),
+                blockedReasonsToString(blocked)));
     }
 
     /**
@@ -1771,7 +1795,8 @@
                         nai.network,
                         createWithLocationInfoSanitizedIfNecessaryWhenParceled(
                                 nc, false /* includeLocationSensitiveInfo */,
-                                mDeps.getCallingUid(), callingPackageName, callingAttributionTag));
+                                getCallingPid(), mDeps.getCallingUid(), callingPackageName,
+                                callingAttributionTag));
             }
         }
 
@@ -1786,7 +1811,7 @@
                             createWithLocationInfoSanitizedIfNecessaryWhenParceled(
                                     nc,
                                     false /* includeLocationSensitiveInfo */,
-                                    mDeps.getCallingUid(), callingPackageName,
+                                    getCallingPid(), mDeps.getCallingUid(), callingPackageName,
                                     callingAttributionTag));
                 }
             }
@@ -1869,7 +1894,7 @@
         return createWithLocationInfoSanitizedIfNecessaryWhenParceled(
                 getNetworkCapabilitiesInternal(network),
                 false /* includeLocationSensitiveInfo */,
-                mDeps.getCallingUid(), callingPackageName, callingAttributionTag);
+                getCallingPid(), mDeps.getCallingUid(), callingPackageName, callingAttributionTag);
     }
 
     @VisibleForTesting
@@ -1888,40 +1913,137 @@
         return newNc;
     }
 
-    private boolean hasLocationPermission(int callerUid, @NonNull String callerPkgName,
-            @Nullable String callingAttributionTag) {
-        final long token = Binder.clearCallingIdentity();
-        try {
-            return mLocationPermissionChecker.checkLocationPermission(
-                    callerPkgName, callingAttributionTag, callerUid, null /* message */);
-        } finally {
-            Binder.restoreCallingIdentity(token);
+    /**
+     * Wrapper used to cache the permission check results performed for the corresponding
+     * app. This avoid performing multiple permission checks for different fields in
+     * NetworkCapabilities.
+     * Note: This wrapper does not support any sort of invalidation and thus must not be
+     * persistent or long-lived. It may only be used for the time necessary to
+     * compute the redactions required by one particular NetworkCallback or
+     * synchronous call.
+     */
+    private class RedactionPermissionChecker {
+        private final int mCallingPid;
+        private final int mCallingUid;
+        @NonNull private final String mCallingPackageName;
+        @Nullable private final String mCallingAttributionTag;
+
+        private Boolean mHasLocationPermission = null;
+        private Boolean mHasLocalMacAddressPermission = null;
+        private Boolean mHasSettingsPermission = null;
+
+        RedactionPermissionChecker(int callingPid, int callingUid,
+                @NonNull String callingPackageName, @Nullable String callingAttributionTag) {
+            mCallingPid = callingPid;
+            mCallingUid = callingUid;
+            mCallingPackageName = callingPackageName;
+            mCallingAttributionTag = callingAttributionTag;
         }
+
+        private boolean hasLocationPermissionInternal() {
+            final long token = Binder.clearCallingIdentity();
+            try {
+                return mLocationPermissionChecker.checkLocationPermission(
+                        mCallingPackageName, mCallingAttributionTag, mCallingUid,
+                        null /* message */);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        /**
+         * Returns whether the app holds location permission or not (might return cached result
+         * if the permission was already checked before).
+         */
+        public boolean hasLocationPermission() {
+            if (mHasLocationPermission == null) {
+                // If there is no cached result, perform the check now.
+                mHasLocationPermission = hasLocationPermissionInternal();
+            }
+            return mHasLocationPermission;
+        }
+
+        /**
+         * Returns whether the app holds local mac address permission or not (might return cached
+         * result if the permission was already checked before).
+         */
+        public boolean hasLocalMacAddressPermission() {
+            if (mHasLocalMacAddressPermission == null) {
+                // If there is no cached result, perform the check now.
+                mHasLocalMacAddressPermission =
+                        checkLocalMacAddressPermission(mCallingPid, mCallingUid);
+            }
+            return mHasLocalMacAddressPermission;
+        }
+
+        /**
+         * Returns whether the app holds settings permission or not (might return cached
+         * result if the permission was already checked before).
+         */
+        public boolean hasSettingsPermission() {
+            if (mHasSettingsPermission == null) {
+                // If there is no cached result, perform the check now.
+                mHasSettingsPermission = checkSettingsPermission(mCallingPid, mCallingUid);
+            }
+            return mHasSettingsPermission;
+        }
+    }
+
+    private static boolean shouldRedact(@NetworkCapabilities.RedactionType long redactions,
+            @NetworkCapabilities.NetCapability long redaction) {
+        return (redactions & redaction) != 0;
+    }
+
+    /**
+     * Use the provided |applicableRedactions| to check the receiving app's
+     * permissions and clear/set the corresponding bit in the returned bitmask. The bitmask
+     * returned will be used to ensure the necessary redactions are performed by NetworkCapabilities
+     * before being sent to the corresponding app.
+     */
+    private @NetworkCapabilities.RedactionType long retrieveRequiredRedactions(
+            @NetworkCapabilities.RedactionType long applicableRedactions,
+            @NonNull RedactionPermissionChecker redactionPermissionChecker,
+            boolean includeLocationSensitiveInfo) {
+        long redactions = applicableRedactions;
+        if (shouldRedact(redactions, REDACT_FOR_ACCESS_FINE_LOCATION)) {
+            if (includeLocationSensitiveInfo
+                    && redactionPermissionChecker.hasLocationPermission()) {
+                redactions &= ~REDACT_FOR_ACCESS_FINE_LOCATION;
+            }
+        }
+        if (shouldRedact(redactions, REDACT_FOR_LOCAL_MAC_ADDRESS)) {
+            if (redactionPermissionChecker.hasLocalMacAddressPermission()) {
+                redactions &= ~REDACT_FOR_LOCAL_MAC_ADDRESS;
+            }
+        }
+        if (shouldRedact(redactions, REDACT_FOR_NETWORK_SETTINGS)) {
+            if (redactionPermissionChecker.hasSettingsPermission()) {
+                redactions &= ~REDACT_FOR_NETWORK_SETTINGS;
+            }
+        }
+        return redactions;
     }
 
     @VisibleForTesting
     @Nullable
     NetworkCapabilities createWithLocationInfoSanitizedIfNecessaryWhenParceled(
             @Nullable NetworkCapabilities nc, boolean includeLocationSensitiveInfo,
-            int callerUid, @NonNull String callerPkgName, @Nullable String callingAttributionTag) {
+            int callingPid, int callingUid, @NonNull String callingPkgName,
+            @Nullable String callingAttributionTag) {
         if (nc == null) {
             return null;
         }
-        Boolean hasLocationPermission = null;
-        final NetworkCapabilities newNc;
         // Avoid doing location permission check if the transport info has no location sensitive
         // data.
-        if (includeLocationSensitiveInfo
-                && nc.getTransportInfo() != null
-                && nc.getTransportInfo().hasLocationSensitiveFields()) {
-            hasLocationPermission =
-                    hasLocationPermission(callerUid, callerPkgName, callingAttributionTag);
-            newNc = new NetworkCapabilities(nc, hasLocationPermission);
-        } else {
-            newNc = new NetworkCapabilities(nc, false /* parcelLocationSensitiveFields */);
-        }
+        final RedactionPermissionChecker redactionPermissionChecker =
+                new RedactionPermissionChecker(callingPid, callingUid, callingPkgName,
+                        callingAttributionTag);
+        final long redactions = retrieveRequiredRedactions(
+                nc.getApplicableRedactions(), redactionPermissionChecker,
+                includeLocationSensitiveInfo);
+        final NetworkCapabilities newNc = new NetworkCapabilities(nc, redactions);
         // Reset owner uid if not destined for the owner app.
-        if (callerUid != nc.getOwnerUid()) {
+        if (callingUid != nc.getOwnerUid()) {
             newNc.setOwnerUid(INVALID_UID);
             return newNc;
         }
@@ -1930,23 +2052,17 @@
             // Owner UIDs already checked above. No need to re-check.
             return newNc;
         }
-        // If the caller does not want location sensitive data & target SDK >= S, then mask info.
-        // Else include the owner UID iff the caller has location permission to provide backwards
+        // If the calling does not want location sensitive data & target SDK >= S, then mask info.
+        // Else include the owner UID iff the calling has location permission to provide backwards
         // compatibility for older apps.
         if (!includeLocationSensitiveInfo
                 && isTargetSdkAtleast(
-                        Build.VERSION_CODES.S, callerUid, callerPkgName)) {
+                        Build.VERSION_CODES.S, callingUid, callingPkgName)) {
             newNc.setOwnerUid(INVALID_UID);
             return newNc;
         }
-
-        if (hasLocationPermission == null) {
-            // Location permission not checked yet, check now for masking owner UID.
-            hasLocationPermission =
-                    hasLocationPermission(callerUid, callerPkgName, callingAttributionTag);
-        }
         // Reset owner uid if the app has no location permission.
-        if (!hasLocationPermission) {
+        if (!redactionPermissionChecker.hasLocationPermission()) {
             newNc.setOwnerUid(INVALID_UID);
         }
         return newNc;
@@ -1978,6 +2094,8 @@
     private void restrictRequestUidsForCallerAndSetRequestorInfo(NetworkCapabilities nc,
             int callerUid, String callerPackageName) {
         if (!checkSettingsPermission()) {
+            // There is no need to track the effective UID of the request here. If the caller lacks
+            // the settings permission, the effective UID is the same as the calling ID.
             nc.setSingleUid(callerUid);
         }
         nc.setRequestorUidAndPackageName(callerUid, callerPackageName);
@@ -2242,15 +2360,15 @@
 
     private final NetworkPolicyCallback mPolicyCallback = new NetworkPolicyCallback() {
         @Override
-        public void onUidBlockedReasonChanged(int uid, int blockedReasons) {
+        public void onUidBlockedReasonChanged(int uid, @BlockedReason int blockedReasons) {
             mHandler.sendMessage(mHandler.obtainMessage(EVENT_UID_BLOCKED_REASON_CHANGED,
                     uid, blockedReasons));
         }
     };
 
-    void handleUidBlockedReasonChanged(int uid, int blockedReasons) {
+    private void handleUidBlockedReasonChanged(int uid, @BlockedReason int blockedReasons) {
         maybeNotifyNetworkBlockedForNewState(uid, blockedReasons);
-        mUidBlockedReasons.put(uid, blockedReasons);
+        setUidBlockedReasons(uid, blockedReasons);
     }
 
     private boolean checkAnyPermissionOf(String... permissions) {
@@ -2437,6 +2555,11 @@
         mContext.enforceCallingOrSelfPermission(KeepaliveTracker.PERMISSION, "ConnectivityService");
     }
 
+    private boolean checkLocalMacAddressPermission(int pid, int uid) {
+        return PERMISSION_GRANTED == mContext.checkPermission(
+                Manifest.permission.LOCAL_MAC_ADDRESS, pid, uid);
+    }
+
     private void sendConnectedBroadcast(NetworkInfo info) {
         sendGeneralBroadcast(info, CONNECTIVITY_ACTION);
     }
@@ -2800,10 +2923,6 @@
         }
 
         pw.println();
-        pw.println("NetworkStackClient logs:");
-        pw.increaseIndent();
-        NetworkStackClient.getInstance().dump(pw);
-        pw.decreaseIndent();
 
         pw.println();
         pw.println("Permission Monitor:");
@@ -3018,6 +3137,13 @@
                     }
                     break;
                 }
+                case NetworkAgent.EVENT_TEARDOWN_DELAY_CHANGED: {
+                    if (msg.arg1 >= 0 && msg.arg1 <= NetworkAgent.MAX_TEARDOWN_DELAY_MS) {
+                        nai.teardownDelayMs = msg.arg1;
+                    } else {
+                        logwtf(nai.toShortString() + " set invalid teardown delay " + msg.arg1);
+                    }
+                }
             }
         }
 
@@ -3143,8 +3269,6 @@
                 nai.lastValidated = valid;
                 nai.everValidated |= valid;
                 updateCapabilities(oldScore, nai, nai.networkCapabilities);
-                // If score has changed, rebroadcast to NetworkProviders. b/17726566
-                if (oldScore != nai.getCurrentScore()) sendUpdatedScoreToFactories(nai);
                 if (valid) {
                     handleFreshlyValidatedNetwork(nai);
                     // Clear NO_INTERNET, PRIVATE_DNS_BROKEN, PARTIAL_CONNECTIVITY and
@@ -3565,9 +3689,12 @@
             if (currentNetwork != null
                     && currentNetwork.network.getNetId() == nai.network.getNetId()) {
                 // uid rules for this network will be removed in destroyNativeNetwork(nai).
+                // TODO : setting the satisfier is in fact the job of the rematch. Teach the
+                // rematch not to keep disconnected agents instead of setting it here ; this
+                // will also allow removing updating the offers below.
                 nri.setSatisfier(null, null);
-                if (request.isRequest()) {
-                    sendUpdatedScoreToFactories(request, null);
+                for (final NetworkOfferInfo noi : mNetworkOffers) {
+                    informOffer(nri, noi.offer, mNetworkRanker);
                 }
 
                 if (mDefaultRequest == nri) {
@@ -3588,6 +3715,23 @@
         mLegacyTypeTracker.remove(nai, wasDefault);
         rematchAllNetworksAndRequests();
         mLingerMonitor.noteDisconnect(nai);
+
+        // Immediate teardown.
+        if (nai.teardownDelayMs == 0) {
+            destroyNetwork(nai);
+            return;
+        }
+
+        // Delayed teardown.
+        try {
+            mNetd.networkSetPermissionForNetwork(nai.network.netId, INetd.PERMISSION_SYSTEM);
+        } catch (RemoteException e) {
+            Log.d(TAG, "Error marking network restricted during teardown: " + e);
+        }
+        mHandler.postDelayed(() -> destroyNetwork(nai), nai.teardownDelayMs);
+    }
+
+    private void destroyNetwork(NetworkAgentInfo nai) {
         if (nai.created) {
             // Tell netd to clean up the configuration for this network
             // (routing rules, DNS, etc).
@@ -3600,6 +3744,7 @@
             mDnsManager.removeNetwork(nai.network);
         }
         mNetIdManager.releaseNetId(nai.network.getNetId());
+        nai.onNetworkDestroyed();
     }
 
     private boolean createNativeNetwork(@NonNull NetworkAgentInfo networkAgent) {
@@ -3694,16 +3839,13 @@
         }
 
         rematchAllNetworksAndRequests();
-        for (final NetworkRequestInfo nri : nris) {
-            // If the nri is satisfied, return as its score has already been sent if needed.
-            if (nri.isBeingSatisfied()) {
-                return;
-            }
 
-            // As this request was not satisfied on rematch and thus never had any scores sent to
-            // the factories, send null now for each request of type REQUEST.
-            for (final NetworkRequest req : nri.mRequests) {
-                if (req.isRequest()) sendUpdatedScoreToFactories(req, null);
+        // Requests that have not been matched to a network will not have been sent to the
+        // providers, because the old satisfier and the new satisfier are the same (null in this
+        // case). Send these requests to the providers.
+        for (final NetworkRequestInfo nri : nris) {
+            for (final NetworkOfferInfo noi : mNetworkOffers) {
+                informOffer(nri, noi.offer, mNetworkRanker);
             }
         }
     }
@@ -3731,6 +3873,12 @@
     //   then it should be lingered.
     private boolean unneeded(NetworkAgentInfo nai, UnneededFor reason) {
         ensureRunningOnConnectivityServiceThread();
+
+        if (!nai.everConnected || nai.isVPN() || nai.isInactive()
+                || nai.getScore().getKeepConnectedReason() != NetworkScore.KEEP_CONNECTED_NONE) {
+            return false;
+        }
+
         final int numRequests;
         switch (reason) {
             case TEARDOWN:
@@ -3744,9 +3892,8 @@
                 return true;
         }
 
-        if (!nai.everConnected || nai.isVPN() || nai.isInactive() || numRequests > 0) {
-            return false;
-        }
+        if (numRequests > 0) return false;
+
         for (NetworkRequestInfo nri : mNetworkRequests.values()) {
             if (reason == UnneededFor.LINGER
                     && !nri.isMultilayerRequest()
@@ -3911,7 +4058,15 @@
             }
         }
 
-        cancelNpiRequests(nri);
+        // For all outstanding offers, cancel any of the layers of this NRI that used to be
+        // needed for this offer.
+        for (final NetworkOfferInfo noi : mNetworkOffers) {
+            for (final NetworkRequest req : nri.mRequests) {
+                if (req.isRequest() && noi.offer.neededFor(req)) {
+                    noi.offer.onNetworkUnneeded(req);
+                }
+            }
+        }
     }
 
     private void handleRemoveNetworkRequests(@NonNull final Set<NetworkRequestInfo> nris) {
@@ -3924,20 +4079,6 @@
         }
     }
 
-    private void cancelNpiRequests(@NonNull final NetworkRequestInfo nri) {
-        for (final NetworkRequest req : nri.mRequests) {
-            cancelNpiRequest(req);
-        }
-    }
-
-    private void cancelNpiRequest(@NonNull final NetworkRequest req) {
-        if (req.isRequest()) {
-            for (final NetworkProviderInfo npi : mNetworkProviderInfos.values()) {
-                npi.cancelRequest(req);
-            }
-        }
-    }
-
     private void removeListenRequestFromNetworks(@NonNull final NetworkRequest req) {
         // listens don't have a singular affected Network. Check all networks to see
         // if this listen request applies and remove it.
@@ -4058,7 +4199,6 @@
             nai.networkAgentConfig.acceptPartialConnectivity = accept;
             nai.updateScoreForNetworkAgentConfigUpdate();
             rematchAllNetworksAndRequests();
-            sendUpdatedScoreToFactories(nai);
         }
 
         if (always) {
@@ -4126,7 +4266,6 @@
         if (!nai.avoidUnvalidated) {
             nai.avoidUnvalidated = true;
             rematchAllNetworksAndRequests();
-            sendUpdatedScoreToFactories(nai);
         }
     }
 
@@ -4231,14 +4370,9 @@
         return avoidBadWifi();
     }
 
-
+    // TODO : this function is now useless.
     private void rematchForAvoidBadWifiUpdate() {
         rematchAllNetworksAndRequests();
-        for (NetworkAgentInfo nai: mNetworkAgentInfos) {
-            if (nai.networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
-                sendUpdatedScoreToFactories(nai);
-            }
-        }
     }
 
     // TODO: Evaluate whether this is of interest to other consumers of
@@ -4463,6 +4597,18 @@
                     handleUnregisterNetworkProvider((Messenger) msg.obj);
                     break;
                 }
+                case EVENT_REGISTER_NETWORK_OFFER: {
+                    handleRegisterNetworkOffer((NetworkOffer) msg.obj);
+                    break;
+                }
+                case EVENT_UNREGISTER_NETWORK_OFFER: {
+                    final NetworkOfferInfo offer =
+                            findNetworkOfferInfoByCallback((INetworkOfferCallback) msg.obj);
+                    if (null != offer) {
+                        handleUnregisterNetworkOffer(offer);
+                    }
+                    break;
+                }
                 case EVENT_REGISTER_NETWORK_AGENT: {
                     final Pair<NetworkAgentInfo, INetworkMonitor> arg =
                             (Pair<NetworkAgentInfo, INetworkMonitor>) msg.obj;
@@ -4632,7 +4778,7 @@
         mWakelockLogs.log("ACQUIRE for " + forWhom);
         Message msg = mHandler.obtainMessage(EVENT_EXPIRE_NET_TRANSITION_WAKELOCK);
         final int lockTimeout = mResources.get().getInteger(
-                com.android.connectivity.resources.R.integer.config_networkTransitionTimeout);
+                R.integer.config_networkTransitionTimeout);
         mHandler.sendMessageDelayed(msg, lockTimeout);
     }
 
@@ -4738,6 +4884,42 @@
         nai.networkMonitor().forceReevaluation(uid);
     }
 
+    // TODO: call into netd.
+    private boolean queryUserAccess(int uid, Network network) {
+        final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
+        if (nai == null) return false;
+
+        // Any UID can use its default network.
+        if (nai == getDefaultNetworkForUid(uid)) return true;
+
+        // Privileged apps can use any network.
+        if (mPermissionMonitor.hasRestrictedNetworksPermission(uid)) {
+            return true;
+        }
+
+        // An unprivileged UID can use a VPN iff the VPN applies to it.
+        if (nai.isVPN()) {
+            return nai.networkCapabilities.appliesToUid(uid);
+        }
+
+        // An unprivileged UID can bypass the VPN that applies to it only if it can protect its
+        // sockets, i.e., if it is the owner.
+        final NetworkAgentInfo vpn = getVpnForUid(uid);
+        if (vpn != null && !vpn.networkAgentConfig.allowBypass
+                && uid != vpn.networkCapabilities.getOwnerUid()) {
+            return false;
+        }
+
+        // The UID's permission must be at least sufficient for the network. Since the restricted
+        // permission was already checked above, that just leaves background networks.
+        if (!nai.networkCapabilities.hasCapability(NET_CAPABILITY_FOREGROUND)) {
+            return mPermissionMonitor.hasUseBackgroundNetworksPermission(uid);
+        }
+
+        // Unrestricted network. Anyone gets to use it.
+        return true;
+    }
+
     /**
      * Returns information about the proxy a certain network is using. If given a null network, it
      * it will return the proxy for the bound network for the caller app or the default proxy if
@@ -4758,7 +4940,7 @@
                 return null;
             }
             return getLinkPropertiesProxyInfo(activeNetwork);
-        } else if (mDeps.queryUserAccess(mDeps.getCallingUid(), network.getNetId())) {
+        } else if (mDeps.queryUserAccess(mDeps.getCallingUid(), network, this)) {
             // Don't call getLinkProperties() as it requires ACCESS_NETWORK_STATE permission, which
             // caller may not have.
             return getLinkPropertiesProxyInfo(network);
@@ -4985,7 +5167,7 @@
 
     @Override
     public void setRequireVpnForUids(boolean requireVpn, UidRange[] ranges) {
-        PermissionUtils.enforceNetworkStackPermission(mContext);
+        enforceNetworkStackOrSettingsPermission();
         mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_REQUIRE_VPN_FOR_UIDS,
                 encodeBool(requireVpn), 0 /* arg2 */, ranges));
     }
@@ -5023,7 +5205,7 @@
 
     @Override
     public void setLegacyLockdownVpnEnabled(boolean enabled) {
-        enforceSettingsPermission();
+        enforceNetworkStackOrSettingsPermission();
         mHandler.post(() -> mLockdownEnabled = enabled);
     }
 
@@ -5184,24 +5366,6 @@
             }
         }
 
-        void sendMessageToNetworkProvider(int what, int arg1, int arg2, Object obj) {
-            try {
-                messenger.send(Message.obtain(null /* handler */, what, arg1, arg2, obj));
-            } catch (RemoteException e) {
-                // Remote process died. Ignore; the death recipient will remove this
-                // NetworkProviderInfo from mNetworkProviderInfos.
-            }
-        }
-
-        void requestNetwork(NetworkRequest request, int score, int servingProviderId) {
-            sendMessageToNetworkProvider(NetworkProvider.CMD_REQUEST_NETWORK, score,
-                            servingProviderId, request);
-        }
-
-        void cancelRequest(NetworkRequest request) {
-            sendMessageToNetworkProvider(NetworkProvider.CMD_CANCEL_REQUEST, 0, 0, request);
-        }
-
         void connect(Context context, Handler handler) {
             try {
                 messenger.getBinder().linkToDeath(mDeathRecipient, 0);
@@ -5263,6 +5427,8 @@
         boolean mPendingIntentSent;
         @Nullable
         final Messenger mMessenger;
+
+        // Information about the caller that caused this object to be created.
         @Nullable
         private final IBinder mBinder;
         final int mPid;
@@ -5270,6 +5436,13 @@
         final @NetworkCallback.Flag int mCallbackFlags;
         @Nullable
         final String mCallingAttributionTag;
+
+        // Effective UID of this request. This is different from mUid when a privileged process
+        // files a request on behalf of another UID. This UID is used to determine blocked status,
+        // UID matching, and so on. mUid above is used for permission checks and to enforce the
+        // maximum limit of registered callbacks per UID.
+        final int mAsUid;
+
         // In order to preserve the mapping of NetworkRequest-to-callback when apps register
         // callbacks using a returned NetworkRequest, the original NetworkRequest needs to be
         // maintained for keying off of. This is only a concern when the original nri
@@ -5297,12 +5470,12 @@
             return (null == uids) ? new ArraySet<>() : uids;
         }
 
-        NetworkRequestInfo(@NonNull final NetworkRequest r, @Nullable final PendingIntent pi,
-                @Nullable String callingAttributionTag) {
-            this(Collections.singletonList(r), r, pi, callingAttributionTag);
+        NetworkRequestInfo(int asUid, @NonNull final NetworkRequest r,
+                @Nullable final PendingIntent pi, @Nullable String callingAttributionTag) {
+            this(asUid, Collections.singletonList(r), r, pi, callingAttributionTag);
         }
 
-        NetworkRequestInfo(@NonNull final List<NetworkRequest> r,
+        NetworkRequestInfo(int asUid, @NonNull final List<NetworkRequest> r,
                 @NonNull final NetworkRequest requestForCallback, @Nullable final PendingIntent pi,
                 @Nullable String callingAttributionTag) {
             ensureAllNetworkRequestsHaveType(r);
@@ -5313,6 +5486,7 @@
             mBinder = null;
             mPid = getCallingPid();
             mUid = mDeps.getCallingUid();
+            mAsUid = asUid;
             mNetworkRequestCounter.incrementCountOrThrow(mUid);
             /**
              * Location sensitive data not included in pending intent. Only included in
@@ -5322,14 +5496,15 @@
             mCallingAttributionTag = callingAttributionTag;
         }
 
-        NetworkRequestInfo(@NonNull final NetworkRequest r, @Nullable final Messenger m,
+        NetworkRequestInfo(int asUid, @NonNull final NetworkRequest r, @Nullable final Messenger m,
                 @Nullable final IBinder binder,
                 @NetworkCallback.Flag int callbackFlags,
                 @Nullable String callingAttributionTag) {
-            this(Collections.singletonList(r), r, m, binder, callbackFlags, callingAttributionTag);
+            this(asUid, Collections.singletonList(r), r, m, binder, callbackFlags,
+                    callingAttributionTag);
         }
 
-        NetworkRequestInfo(@NonNull final List<NetworkRequest> r,
+        NetworkRequestInfo(int asUid, @NonNull final List<NetworkRequest> r,
                 @NonNull final NetworkRequest requestForCallback, @Nullable final Messenger m,
                 @Nullable final IBinder binder,
                 @NetworkCallback.Flag int callbackFlags,
@@ -5342,6 +5517,7 @@
             mBinder = binder;
             mPid = getCallingPid();
             mUid = mDeps.getCallingUid();
+            mAsUid = asUid;
             mPendingIntent = null;
             mNetworkRequestCounter.incrementCountOrThrow(mUid);
             mCallbackFlags = callbackFlags;
@@ -5384,18 +5560,19 @@
             mBinder = nri.mBinder;
             mPid = nri.mPid;
             mUid = nri.mUid;
+            mAsUid = nri.mAsUid;
             mPendingIntent = nri.mPendingIntent;
             mNetworkRequestCounter.incrementCountOrThrow(mUid);
             mCallbackFlags = nri.mCallbackFlags;
             mCallingAttributionTag = nri.mCallingAttributionTag;
         }
 
-        NetworkRequestInfo(@NonNull final NetworkRequest r) {
-            this(Collections.singletonList(r));
+        NetworkRequestInfo(int asUid, @NonNull final NetworkRequest r) {
+            this(asUid, Collections.singletonList(r));
         }
 
-        NetworkRequestInfo(@NonNull final List<NetworkRequest> r) {
-            this(r, r.get(0), null /* pi */, null /* callingAttributionTag */);
+        NetworkRequestInfo(int asUid, @NonNull final List<NetworkRequest> r) {
+            this(asUid, r, r.get(0), null /* pi */, null /* callingAttributionTag */);
         }
 
         // True if this NRI is being satisfied. It also accounts for if the nri has its satisifer
@@ -5431,9 +5608,10 @@
 
         @Override
         public String toString() {
-            return "uid/pid:" + mUid + "/" + mPid + " active request Id: "
+            final String asUidString = (mAsUid == mUid) ? "" : " asUid: " + mAsUid;
+            return "uid/pid:" + mUid + "/" + mPid + asUidString + " activeRequest: "
                     + (mActiveRequest == null ? null : mActiveRequest.requestId)
-                    + " callback request Id: "
+                    + " callbackRequest: "
                     + mNetworkRequestForCallback.requestId
                     + " " + mRequests
                     + (mPendingIntent == null ? "" : " to trigger " + mPendingIntent)
@@ -5534,7 +5712,7 @@
     }
 
     @Override
-    public NetworkRequest requestNetwork(NetworkCapabilities networkCapabilities,
+    public NetworkRequest requestNetwork(int asUid, NetworkCapabilities networkCapabilities,
             int reqTypeInt, Messenger messenger, int timeoutMs, IBinder binder,
             int legacyType, int callbackFlags, @NonNull String callingPackageName,
             @Nullable String callingAttributionTag) {
@@ -5546,6 +5724,12 @@
         }
         final NetworkCapabilities defaultNc = mDefaultRequest.mRequests.get(0).networkCapabilities;
         final int callingUid = mDeps.getCallingUid();
+        // Privileged callers can track the default network of another UID by passing in a UID.
+        if (asUid != Process.INVALID_UID) {
+            enforceSettingsPermission();
+        } else {
+            asUid = callingUid;
+        }
         final NetworkRequest.Type reqType;
         try {
             reqType = NetworkRequest.Type.values()[reqTypeInt];
@@ -5555,10 +5739,10 @@
         switch (reqType) {
             case TRACK_DEFAULT:
                 // If the request type is TRACK_DEFAULT, the passed {@code networkCapabilities}
-                // is unused and will be replaced by ones appropriate for the caller.
-                // This allows callers to keep track of the default network for their app.
+                // is unused and will be replaced by ones appropriate for the UID (usually, the
+                // calling app). This allows callers to keep track of the default network.
                 networkCapabilities = copyDefaultNetworkCapabilitiesForUid(
-                        defaultNc, callingUid, callingPackageName);
+                        defaultNc, asUid, callingUid, callingPackageName);
                 enforceAccessPermission();
                 break;
             case TRACK_SYSTEM_DEFAULT:
@@ -5610,7 +5794,8 @@
         final NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, legacyType,
                 nextNetworkRequestId(), reqType);
         final NetworkRequestInfo nri = getNriToRegister(
-                networkRequest, messenger, binder, callbackFlags, callingAttributionTag);
+                asUid, networkRequest, messenger, binder, callbackFlags,
+                callingAttributionTag);
         if (DBG) log("requestNetwork for " + nri);
 
         // For TRACK_SYSTEM_DEFAULT callbacks, the capabilities have been modified since they were
@@ -5637,25 +5822,27 @@
      * requests registered to track the default request. If there is currently a per-app default
      * tracking the app requestor, then we need to create a version of this nri that mirrors that of
      * the tracking per-app default so that callbacks are sent to the app requestor appropriately.
+     * @param asUid the uid on behalf of which to file the request. Different from requestorUid
+     *              when a privileged caller is tracking the default network for another uid.
      * @param nr the network request for the nri.
      * @param msgr the messenger for the nri.
      * @param binder the binder for the nri.
      * @param callingAttributionTag the calling attribution tag for the nri.
      * @return the nri to register.
      */
-    private NetworkRequestInfo getNriToRegister(@NonNull final NetworkRequest nr,
+    private NetworkRequestInfo getNriToRegister(final int asUid, @NonNull final NetworkRequest nr,
             @Nullable final Messenger msgr, @Nullable final IBinder binder,
             @NetworkCallback.Flag int callbackFlags,
             @Nullable String callingAttributionTag) {
         final List<NetworkRequest> requests;
         if (NetworkRequest.Type.TRACK_DEFAULT == nr.type) {
             requests = copyDefaultNetworkRequestsForUid(
-                    nr.getRequestorUid(), nr.getRequestorPackageName());
+                    asUid, nr.getRequestorUid(), nr.getRequestorPackageName());
         } else {
             requests = Collections.singletonList(nr);
         }
         return new NetworkRequestInfo(
-                requests, nr, msgr, binder, callbackFlags, callingAttributionTag);
+                asUid, requests, nr, msgr, binder, callbackFlags, callingAttributionTag);
     }
 
     private void enforceNetworkRequestPermissions(NetworkCapabilities networkCapabilities,
@@ -5736,8 +5923,8 @@
 
         NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, TYPE_NONE,
                 nextNetworkRequestId(), NetworkRequest.Type.REQUEST);
-        NetworkRequestInfo nri =
-                new NetworkRequestInfo(networkRequest, operation, callingAttributionTag);
+        NetworkRequestInfo nri = new NetworkRequestInfo(callingUid, networkRequest, operation,
+                callingAttributionTag);
         if (DBG) log("pendingRequest for " + nri);
         mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT,
                 nri));
@@ -5804,7 +5991,7 @@
         NetworkRequest networkRequest = new NetworkRequest(nc, TYPE_NONE, nextNetworkRequestId(),
                 NetworkRequest.Type.LISTEN);
         NetworkRequestInfo nri =
-                new NetworkRequestInfo(networkRequest, messenger, binder, callbackFlags,
+                new NetworkRequestInfo(callingUid, networkRequest, messenger, binder, callbackFlags,
                         callingAttributionTag);
         if (VDBG) log("listenForNetwork for " + nri);
 
@@ -5829,8 +6016,8 @@
 
         NetworkRequest networkRequest = new NetworkRequest(nc, TYPE_NONE, nextNetworkRequestId(),
                 NetworkRequest.Type.LISTEN);
-        NetworkRequestInfo nri =
-                new NetworkRequestInfo(networkRequest, operation, callingAttributionTag);
+        NetworkRequestInfo nri = new NetworkRequestInfo(callingUid, networkRequest, operation,
+                callingAttributionTag);
         if (VDBG) log("pendingListenForNetwork for " + nri);
 
         mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_LISTENER, nri));
@@ -5867,7 +6054,6 @@
         if (DBG) log("Got NetworkProvider Messenger for " + npi.name);
         mNetworkProviderInfos.put(npi.messenger, npi);
         npi.connect(mContext, mTrackerHandler);
-        sendAllRequestsToProvider(npi);
     }
 
     @Override
@@ -5885,12 +6071,40 @@
         mHandler.sendMessage(mHandler.obtainMessage(EVENT_UNREGISTER_NETWORK_PROVIDER, messenger));
     }
 
+    @Override
+    public void offerNetwork(final int providerId,
+            @NonNull final NetworkScore score, @NonNull final NetworkCapabilities caps,
+            @NonNull final INetworkOfferCallback callback) {
+        Objects.requireNonNull(score);
+        Objects.requireNonNull(caps);
+        Objects.requireNonNull(callback);
+        final NetworkOffer offer = new NetworkOffer(
+                FullScore.makeProspectiveScore(score, caps), caps, callback, providerId);
+        mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_OFFER, offer));
+    }
+
+    @Override
+    public void unofferNetwork(@NonNull final INetworkOfferCallback callback) {
+        mHandler.sendMessage(mHandler.obtainMessage(EVENT_UNREGISTER_NETWORK_OFFER, callback));
+    }
+
     private void handleUnregisterNetworkProvider(Messenger messenger) {
         NetworkProviderInfo npi = mNetworkProviderInfos.remove(messenger);
         if (npi == null) {
             loge("Failed to find Messenger in unregisterNetworkProvider");
             return;
         }
+        // Unregister all the offers from this provider
+        final ArrayList<NetworkOfferInfo> toRemove = new ArrayList<>();
+        for (final NetworkOfferInfo noi : mNetworkOffers) {
+            if (noi.offer.providerId == npi.providerId) {
+                // Can't call handleUnregisterNetworkOffer here because iteration is in progress
+                toRemove.add(noi);
+            }
+        }
+        for (final NetworkOfferInfo noi : toRemove) {
+            handleUnregisterNetworkOffer(noi);
+        }
         if (DBG) log("unregisterNetworkProvider for " + npi.name);
     }
 
@@ -5929,6 +6143,10 @@
     // (on the handler thread).
     private volatile List<UidRange> mVpnBlockedUidRanges = new ArrayList<>();
 
+    // Must only be accessed on the handler thread
+    @NonNull
+    private final ArrayList<NetworkOfferInfo> mNetworkOffers = new ArrayList<>();
+
     @GuardedBy("mBlockedAppUids")
     private final HashSet<Integer> mBlockedAppUids = new HashSet<>();
 
@@ -5980,33 +6198,37 @@
     /**
      * Get a copy of the network requests of the default request that is currently tracking the
      * given uid.
+     * @param asUid the uid on behalf of which to file the request. Different from requestorUid
+     *              when a privileged caller is tracking the default network for another uid.
      * @param requestorUid the uid to check the default for.
      * @param requestorPackageName the requestor's package name.
      * @return a copy of the default's NetworkRequest that is tracking the given uid.
      */
     @NonNull
     private List<NetworkRequest> copyDefaultNetworkRequestsForUid(
-            @NonNull final int requestorUid, @NonNull final String requestorPackageName) {
+            final int asUid, final int requestorUid, @NonNull final String requestorPackageName) {
         return copyNetworkRequestsForUid(
-                getDefaultRequestTrackingUid(requestorUid).mRequests,
-                requestorUid, requestorPackageName);
+                getDefaultRequestTrackingUid(asUid).mRequests,
+                asUid, requestorUid, requestorPackageName);
     }
 
     /**
      * Copy the given nri's NetworkRequest collection.
      * @param requestsToCopy the NetworkRequest collection to be copied.
+     * @param asUid the uid on behalf of which to file the request. Different from requestorUid
+     *              when a privileged caller is tracking the default network for another uid.
      * @param requestorUid the uid to set on the copied collection.
      * @param requestorPackageName the package name to set on the copied collection.
      * @return the copied NetworkRequest collection.
      */
     @NonNull
     private List<NetworkRequest> copyNetworkRequestsForUid(
-            @NonNull final List<NetworkRequest> requestsToCopy, @NonNull final int requestorUid,
-            @NonNull final String requestorPackageName) {
+            @NonNull final List<NetworkRequest> requestsToCopy, final int asUid,
+            final int requestorUid, @NonNull final String requestorPackageName) {
         final List<NetworkRequest> requests = new ArrayList<>();
         for (final NetworkRequest nr : requestsToCopy) {
             requests.add(new NetworkRequest(copyDefaultNetworkCapabilitiesForUid(
-                            nr.networkCapabilities, requestorUid, requestorPackageName),
+                            nr.networkCapabilities, asUid, requestorUid, requestorPackageName),
                     nr.legacyType, nextNetworkRequestId(), nr.type));
         }
         return requests;
@@ -6014,12 +6236,17 @@
 
     @NonNull
     private NetworkCapabilities copyDefaultNetworkCapabilitiesForUid(
-            @NonNull final NetworkCapabilities netCapToCopy, @NonNull final int requestorUid,
-            @NonNull final String requestorPackageName) {
+            @NonNull final NetworkCapabilities netCapToCopy, final int asUid,
+            final int requestorUid, @NonNull final String requestorPackageName) {
+        // These capabilities are for a TRACK_DEFAULT callback, so:
+        // 1. Remove NET_CAPABILITY_VPN, because it's (currently!) the only difference between
+        //    mDefaultRequest and a per-UID default request.
+        //    TODO: stop depending on the fact that these two unrelated things happen to be the same
+        // 2. Always set the UIDs to asUid. restrictRequestUidsForCallerAndSetRequestorInfo will
+        //    not do this in the case of a privileged application.
         final NetworkCapabilities netCap = new NetworkCapabilities(netCapToCopy);
         netCap.removeCapability(NET_CAPABILITY_NOT_VPN);
-        netCap.setSingleUid(requestorUid);
-        netCap.setUids(new ArraySet<>());
+        netCap.setSingleUid(asUid);
         restrictRequestUidsForCallerAndSetRequestorInfo(
                 netCap, requestorUid, requestorPackageName);
         return netCap;
@@ -6229,6 +6456,71 @@
         updateUids(nai, null, nai.networkCapabilities);
     }
 
+    private class NetworkOfferInfo implements IBinder.DeathRecipient {
+        @NonNull public final NetworkOffer offer;
+
+        NetworkOfferInfo(@NonNull final NetworkOffer offer) {
+            this.offer = offer;
+        }
+
+        @Override
+        public void binderDied() {
+            mHandler.post(() -> handleUnregisterNetworkOffer(this));
+        }
+    }
+
+    private boolean isNetworkProviderWithIdRegistered(final int providerId) {
+        for (final NetworkProviderInfo npi : mNetworkProviderInfos.values()) {
+            if (npi.providerId == providerId) return true;
+        }
+        return false;
+    }
+
+    /**
+     * Register or update a network offer.
+     * @param newOffer The new offer. If the callback member is the same as an existing
+     *                 offer, it is an update of that offer.
+     */
+    private void handleRegisterNetworkOffer(@NonNull final NetworkOffer newOffer) {
+        ensureRunningOnConnectivityServiceThread();
+        if (!isNetworkProviderWithIdRegistered(newOffer.providerId)) {
+            // This may actually happen if a provider updates its score or registers and then
+            // immediately unregisters. The offer would still be in the handler queue, but the
+            // provider would have been removed.
+            if (DBG) log("Received offer from an unregistered provider");
+            return;
+        }
+        final NetworkOfferInfo existingOffer = findNetworkOfferInfoByCallback(newOffer.callback);
+        if (null != existingOffer) {
+            handleUnregisterNetworkOffer(existingOffer);
+            newOffer.migrateFrom(existingOffer.offer);
+        }
+        final NetworkOfferInfo noi = new NetworkOfferInfo(newOffer);
+        try {
+            noi.offer.callback.asBinder().linkToDeath(noi, 0 /* flags */);
+        } catch (RemoteException e) {
+            noi.binderDied();
+            return;
+        }
+        mNetworkOffers.add(noi);
+        issueNetworkNeeds(noi);
+    }
+
+    private void handleUnregisterNetworkOffer(@NonNull final NetworkOfferInfo noi) {
+        ensureRunningOnConnectivityServiceThread();
+        mNetworkOffers.remove(noi);
+        noi.offer.callback.asBinder().unlinkToDeath(noi, 0 /* flags */);
+    }
+
+    @Nullable private NetworkOfferInfo findNetworkOfferInfoByCallback(
+            @NonNull final INetworkOfferCallback callback) {
+        ensureRunningOnConnectivityServiceThread();
+        for (final NetworkOfferInfo noi : mNetworkOffers) {
+            if (noi.offer.callback.equals(callback)) return noi;
+        }
+        return null;
+    }
+
     /**
      * Called when receiving LinkProperties directly from a NetworkAgent.
      * Stores into |nai| any data coming from the agent that might also be written to the network's
@@ -6362,10 +6654,16 @@
             return;
         }
 
-        int mark = mContext.getResources().getInteger(
-            com.android.internal.R.integer.config_networkWakeupPacketMark);
-        int mask = mContext.getResources().getInteger(
-            com.android.internal.R.integer.config_networkWakeupPacketMask);
+        int mark = mResources.get().getInteger(R.integer.config_networkWakeupPacketMark);
+        int mask = mResources.get().getInteger(R.integer.config_networkWakeupPacketMask);
+
+        // TODO (b/183076074): remove legacy fallback after migrating overlays
+        final int legacyMark = mContext.getResources().getInteger(mContext.getResources()
+                .getIdentifier("config_networkWakeupPacketMark", "integer", "android"));
+        final int legacyMask = mContext.getResources().getInteger(mContext.getResources()
+                .getIdentifier("config_networkWakeupPacketMask", "integer", "android"));
+        mark = mark == 0 ? legacyMark : mark;
+        mask = mask == 0 ? legacyMask : mask;
 
         // Mask/mark of zero will not detect anything interesting.
         // Don't install rules unless both values are nonzero.
@@ -6558,8 +6856,7 @@
     private void updateWakeOnLan(@NonNull LinkProperties lp) {
         if (mWolSupportedInterfaces == null) {
             mWolSupportedInterfaces = new ArraySet<>(mResources.get().getStringArray(
-                    com.android.connectivity.resources.R.array
-                            .config_wakeonlan_supported_interfaces));
+                    R.array.config_wakeonlan_supported_interfaces));
         }
         lp.setWakeOnLanSupported(mWolSupportedInterfaces.contains(lp.getInterfaceName()));
     }
@@ -6981,100 +7278,6 @@
         updateLinkProperties(nai, newLp, new LinkProperties(nai.linkProperties));
     }
 
-    private void sendUpdatedScoreToFactories(NetworkAgentInfo nai) {
-        for (int i = 0; i < nai.numNetworkRequests(); i++) {
-            NetworkRequest nr = nai.requestAt(i);
-            // Don't send listening or track default request to factories. b/17393458
-            if (!nr.isRequest()) continue;
-            sendUpdatedScoreToFactories(nr, nai);
-        }
-    }
-
-    private void sendUpdatedScoreToFactories(
-            @NonNull final NetworkReassignment.RequestReassignment event) {
-        // If a request of type REQUEST is now being satisfied by a new network.
-        if (null != event.mNewNetworkRequest && event.mNewNetworkRequest.isRequest()) {
-            sendUpdatedScoreToFactories(event.mNewNetworkRequest, event.mNewNetwork);
-        }
-
-        // If a previously satisfied request of type REQUEST is no longer being satisfied.
-        if (null != event.mOldNetworkRequest && event.mOldNetworkRequest.isRequest()
-                && event.mOldNetworkRequest != event.mNewNetworkRequest) {
-            sendUpdatedScoreToFactories(event.mOldNetworkRequest, null);
-        }
-
-        cancelMultilayerLowerPriorityNpiRequests(event.mNetworkRequestInfo);
-    }
-
-    /**
-     *  Cancel with all NPIs the given NRI's multilayer requests that are a lower priority than
-     *  its currently satisfied active request.
-     * @param nri the NRI to cancel lower priority requests for.
-     */
-    private void cancelMultilayerLowerPriorityNpiRequests(
-            @NonNull final NetworkRequestInfo nri) {
-        if (!nri.isMultilayerRequest() || null == nri.mActiveRequest) {
-            return;
-        }
-
-        final int indexOfNewRequest = nri.mRequests.indexOf(nri.mActiveRequest);
-        for (int i = indexOfNewRequest + 1; i < nri.mRequests.size(); i++) {
-            cancelNpiRequest(nri.mRequests.get(i));
-        }
-    }
-
-    private void sendUpdatedScoreToFactories(@NonNull NetworkRequest networkRequest,
-            @Nullable NetworkAgentInfo nai) {
-        final int score;
-        final int serial;
-        if (nai != null) {
-            score = nai.getCurrentScore();
-            serial = nai.factorySerialNumber;
-        } else {
-            score = 0;
-            serial = 0;
-        }
-        if (VDBG || DDBG){
-            log("sending new Min Network Score(" + score + "): " + networkRequest.toString());
-        }
-        for (NetworkProviderInfo npi : mNetworkProviderInfos.values()) {
-            npi.requestNetwork(networkRequest, score, serial);
-        }
-    }
-
-    /** Sends all current NetworkRequests to the specified factory. */
-    private void sendAllRequestsToProvider(@NonNull final NetworkProviderInfo npi) {
-        ensureRunningOnConnectivityServiceThread();
-        for (final NetworkRequestInfo nri : getNrisFromGlobalRequests()) {
-            for (final NetworkRequest req : nri.mRequests) {
-                if (!req.isRequest() && nri.getActiveRequest() == req) {
-                    break;
-                }
-                if (!req.isRequest()) {
-                    continue;
-                }
-                // Only set the nai for the request it is satisfying.
-                final NetworkAgentInfo nai =
-                        nri.getActiveRequest() == req ? nri.getSatisfier() : null;
-                final int score;
-                final int serial;
-                if (null != nai) {
-                    score = nai.getCurrentScore();
-                    serial = nai.factorySerialNumber;
-                } else {
-                    score = 0;
-                    serial = NetworkProvider.ID_NONE;
-                }
-                npi.requestNetwork(req, score, serial);
-                // For multilayer requests, don't send lower priority requests if a higher priority
-                // request is already satisfied.
-                if (null != nai) {
-                    break;
-                }
-            }
-        }
-    }
-
     private void sendPendingIntentForRequest(NetworkRequestInfo nri, NetworkAgentInfo networkAgent,
             int notificationType) {
         if (notificationType == ConnectivityManager.CALLBACK_AVAILABLE && !nri.mPendingIntentSent) {
@@ -7143,7 +7346,7 @@
                 putParcelable(
                         bundle,
                         createWithLocationInfoSanitizedIfNecessaryWhenParceled(
-                                nc, includeLocationSensitiveInfo, nri.mUid,
+                                nc, includeLocationSensitiveInfo, nri.mPid, nri.mUid,
                                 nrForCallback.getRequestorPackageName(),
                                 nri.mCallingAttributionTag));
                 putParcelable(bundle, linkPropertiesRestrictedForCallerPermissions(
@@ -7164,7 +7367,7 @@
                 putParcelable(
                         bundle,
                         createWithLocationInfoSanitizedIfNecessaryWhenParceled(
-                                netCap, includeLocationSensitiveInfo, nri.mUid,
+                                netCap, includeLocationSensitiveInfo, nri.mPid, nri.mUid,
                                 nrForCallback.getRequestorPackageName(),
                                 nri.mCallingAttributionTag));
                 break;
@@ -7175,7 +7378,7 @@
                 break;
             }
             case ConnectivityManager.CALLBACK_BLK_CHANGED: {
-                maybeLogBlockedStatusChanged(nri, networkAgent.network, arg1 != 0);
+                maybeLogBlockedStatusChanged(nri, networkAgent.network, arg1);
                 msg.arg1 = arg1;
                 break;
             }
@@ -7566,6 +7769,7 @@
             log(changes.toString()); // Shorter form, only one line of log
         }
         applyNetworkReassignment(changes, now);
+        issueNetworkNeeds();
     }
 
     private void applyNetworkReassignment(@NonNull final NetworkReassignment changes,
@@ -7597,12 +7801,6 @@
         // before LegacyTypeTracker sends legacy broadcasts
         for (final NetworkReassignment.RequestReassignment event :
                 changes.getRequestReassignments()) {
-            // Tell NetworkProviders about the new score, so they can stop
-            // trying to connect if they know they cannot match it.
-            // TODO - this could get expensive if there are a lot of outstanding requests for this
-            // network. Think of a way to reduce this. Push netid->request mapping to each factory?
-            sendUpdatedScoreToFactories(event);
-
             if (null != event.mNewNetwork) {
                 notifyNetworkAvailable(event.mNewNetwork, event.mNetworkRequestInfo);
             } else {
@@ -7739,6 +7937,107 @@
         }
     }
 
+    private void issueNetworkNeeds() {
+        ensureRunningOnConnectivityServiceThread();
+        for (final NetworkOfferInfo noi : mNetworkOffers) {
+            issueNetworkNeeds(noi);
+        }
+    }
+
+    private void issueNetworkNeeds(@NonNull final NetworkOfferInfo noi) {
+        ensureRunningOnConnectivityServiceThread();
+        for (final NetworkRequestInfo nri : mNetworkRequests.values()) {
+            informOffer(nri, noi.offer, mNetworkRanker);
+        }
+    }
+
+    /**
+     * Inform a NetworkOffer about any new situation of a request.
+     *
+     * This function handles updates to offers. A number of events may happen that require
+     * updating the registrant for this offer about the situation :
+     * • The offer itself was updated. This may lead the offer to no longer being able
+     *     to satisfy a request or beat a satisfier (and therefore be no longer needed),
+     *     or conversely being strengthened enough to beat the satisfier (and therefore
+     *     start being needed)
+     * • The network satisfying a request changed (including cases where the request
+     *     starts or stops being satisfied). The new network may be a stronger or weaker
+     *     match than the old one, possibly affecting whether the offer is needed.
+     * • The network satisfying a request updated their score. This may lead the offer
+     *     to no longer be able to beat it if the current satisfier got better, or
+     *     conversely start being a good choice if the current satisfier got weaker.
+     *
+     * @param nri The request
+     * @param offer The offer. This may be an updated offer.
+     */
+    private static void informOffer(@NonNull NetworkRequestInfo nri,
+            @NonNull final NetworkOffer offer, @NonNull final NetworkRanker networkRanker) {
+        final NetworkRequest activeRequest = nri.isBeingSatisfied() ? nri.getActiveRequest() : null;
+        final NetworkAgentInfo satisfier = null != activeRequest ? nri.getSatisfier() : null;
+        final FullScore satisfierScore = null != satisfier ? satisfier.getScore() : null;
+
+        // Multi-layer requests have a currently active request, the one being satisfied.
+        // Since the system will try to bring up a better network than is currently satisfying
+        // the request, NetworkProviders need to be told the offers matching the requests *above*
+        // the currently satisfied one are needed, that the ones *below* the satisfied one are
+        // not needed, and the offer is needed for the active request iff the offer can beat
+        // the satisfier.
+        // For non-multilayer requests, the logic above gracefully degenerates to only the
+        // last case.
+        // To achieve this, the loop below will proceed in three steps. In a first phase, inform
+        // providers that the offer is needed for this request, until the active request is found.
+        // In a second phase, deal with the currently active request. In a third phase, inform
+        // the providers that offer is unneeded for the remaining requests.
+
+        // First phase : inform providers of all requests above the active request.
+        int i;
+        for (i = 0; nri.mRequests.size() > i; ++i) {
+            final NetworkRequest request = nri.mRequests.get(i);
+            if (activeRequest == request) break; // Found the active request : go to phase 2
+            if (!request.isRequest()) continue; // Listens/track defaults are never sent to offers
+            // Since this request is higher-priority than the one currently satisfied, if the
+            // offer can satisfy it, the provider should try and bring up the network for sure ;
+            // no need to even ask the ranker – an offer that can satisfy is always better than
+            // no network. Hence tell the provider so unless it already knew.
+            if (request.canBeSatisfiedBy(offer.caps) && !offer.neededFor(request)) {
+                offer.onNetworkNeeded(request);
+            }
+        }
+
+        // Second phase : deal with the active request (if any)
+        if (null != activeRequest && activeRequest.isRequest()) {
+            final boolean oldNeeded = offer.neededFor(activeRequest);
+            // An offer is needed if it is currently served by this provider or if this offer
+            // can beat the current satisfier.
+            final boolean currentlyServing = satisfier != null
+                    && satisfier.factorySerialNumber == offer.providerId;
+            final boolean newNeeded = (currentlyServing
+                    || (activeRequest.canBeSatisfiedBy(offer.caps)
+                            && networkRanker.mightBeat(activeRequest, satisfierScore, offer)));
+            if (newNeeded != oldNeeded) {
+                if (newNeeded) {
+                    offer.onNetworkNeeded(activeRequest);
+                } else {
+                    // The offer used to be able to beat the satisfier. Now it can't.
+                    offer.onNetworkUnneeded(activeRequest);
+                }
+            }
+        }
+
+        // Third phase : inform the providers that the offer isn't needed for any request
+        // below the active one.
+        for (++i /* skip the active request */; nri.mRequests.size() > i; ++i) {
+            final NetworkRequest request = nri.mRequests.get(i);
+            if (!request.isRequest()) continue; // Listens/track defaults are never sent to offers
+            // Since this request is lower-priority than the one currently satisfied, if the
+            // offer can satisfy it, the provider should not try and bring up the network.
+            // Hence tell the provider so unless it already knew.
+            if (offer.neededFor(request)) {
+                offer.onNetworkUnneeded(request);
+            }
+        }
+    }
+
     private void addNetworkToLegacyTypeTracker(@NonNull final NetworkAgentInfo nai) {
         for (int i = 0; i < nai.numNetworkRequests(); i++) {
             NetworkRequest nr = nai.requestAt(i);
@@ -7831,6 +8130,7 @@
                 updateCapabilitiesForNetwork(networkAgent);
             }
             networkAgent.created = true;
+            networkAgent.onNetworkCreated();
         }
 
         if (!networkAgent.everConnected && state == NetworkInfo.State.CONNECTED) {
@@ -7903,7 +8203,6 @@
         if (VDBG || DDBG) log("updateNetworkScore for " + nai.toShortString() + " to " + score);
         nai.setScore(score);
         rematchAllNetworksAndRequests();
-        sendUpdatedScoreToFactories(nai);
     }
 
     // Notify only this one new request of the current state. Transfer all the
@@ -7918,12 +8217,11 @@
             return;
         }
 
+        final int blockedReasons = mUidBlockedReasons.get(nri.mAsUid, BLOCKED_REASON_NONE);
         final boolean metered = nai.networkCapabilities.isMetered();
-        boolean blocked;
-        blocked = isUidBlockedByVpn(nri.mUid, mVpnBlockedUidRanges);
-        blocked |= NetworkPolicyManager.isUidBlocked(
-                mUidBlockedReasons.get(nri.mUid, BLOCKED_REASON_NONE), metered);
-        callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_AVAILABLE, blocked ? 1 : 0);
+        final boolean vpnBlocked = isUidBlockedByVpn(nri.mAsUid, mVpnBlockedUidRanges);
+        callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_AVAILABLE,
+                getBlockedState(blockedReasons, metered, vpnBlocked));
     }
 
     // Notify the requests on this NAI that the network is now lingered.
@@ -7932,6 +8230,21 @@
         notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOSING, lingerTime);
     }
 
+    private static int getBlockedState(int reasons, boolean metered, boolean vpnBlocked) {
+        if (!metered) reasons &= ~BLOCKED_METERED_REASON_MASK;
+        return vpnBlocked
+                ? reasons | BLOCKED_REASON_LOCKDOWN_VPN
+                : reasons & ~BLOCKED_REASON_LOCKDOWN_VPN;
+    }
+
+    private void setUidBlockedReasons(int uid, @BlockedReason int blockedReasons) {
+        if (blockedReasons == BLOCKED_REASON_NONE) {
+            mUidBlockedReasons.delete(uid);
+        } else {
+            mUidBlockedReasons.put(uid, blockedReasons);
+        }
+    }
+
     /**
      * Notify of the blocked state apps with a registered callback matching a given NAI.
      *
@@ -7939,7 +8252,10 @@
      * any given nai, all requests need to be considered according to the uid who filed it.
      *
      * @param nai The target NetworkAgentInfo.
-     * @param oldMetered True if the previous network capabilities is metered.
+     * @param oldMetered True if the previous network capabilities were metered.
+     * @param newMetered True if the current network capabilities are metered.
+     * @param oldBlockedUidRanges list of UID ranges previously blocked by lockdown VPN.
+     * @param newBlockedUidRanges list of UID ranges blocked by lockdown VPN.
      */
     private void maybeNotifyNetworkBlocked(NetworkAgentInfo nai, boolean oldMetered,
             boolean newMetered, List<UidRange> oldBlockedUidRanges,
@@ -7948,22 +8264,18 @@
         for (int i = 0; i < nai.numNetworkRequests(); i++) {
             NetworkRequest nr = nai.requestAt(i);
             NetworkRequestInfo nri = mNetworkRequests.get(nr);
-            final boolean oldBlocked, newBlocked, oldVpnBlocked, newVpnBlocked;
 
-            oldVpnBlocked = isUidBlockedByVpn(nri.mUid, oldBlockedUidRanges);
-            newVpnBlocked = (oldBlockedUidRanges != newBlockedUidRanges)
-                    ? isUidBlockedByVpn(nri.mUid, newBlockedUidRanges)
+            final int blockedReasons = mUidBlockedReasons.get(nri.mAsUid, BLOCKED_REASON_NONE);
+            final boolean oldVpnBlocked = isUidBlockedByVpn(nri.mAsUid, oldBlockedUidRanges);
+            final boolean newVpnBlocked = (oldBlockedUidRanges != newBlockedUidRanges)
+                    ? isUidBlockedByVpn(nri.mAsUid, newBlockedUidRanges)
                     : oldVpnBlocked;
 
-            final int blockedReasons = mUidBlockedReasons.get(nri.mUid, BLOCKED_REASON_NONE);
-            oldBlocked = oldVpnBlocked || NetworkPolicyManager.isUidBlocked(
-                    blockedReasons, oldMetered);
-            newBlocked = newVpnBlocked || NetworkPolicyManager.isUidBlocked(
-                    blockedReasons, newMetered);
-
-            if (oldBlocked != newBlocked) {
+            final int oldBlockedState = getBlockedState(blockedReasons, oldMetered, oldVpnBlocked);
+            final int newBlockedState = getBlockedState(blockedReasons, newMetered, newVpnBlocked);
+            if (oldBlockedState != newBlockedState) {
                 callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_BLK_CHANGED,
-                        encodeBool(newBlocked));
+                        newBlockedState);
             }
         }
     }
@@ -7973,25 +8285,23 @@
      * @param uid The uid for which the rules changed.
      * @param blockedReasons The reasons for why an uid is blocked.
      */
-    private void maybeNotifyNetworkBlockedForNewState(int uid, int blockedReasons) {
+    private void maybeNotifyNetworkBlockedForNewState(int uid, @BlockedReason int blockedReasons) {
         for (final NetworkAgentInfo nai : mNetworkAgentInfos) {
             final boolean metered = nai.networkCapabilities.isMetered();
             final boolean vpnBlocked = isUidBlockedByVpn(uid, mVpnBlockedUidRanges);
-            final boolean oldBlocked, newBlocked;
 
-            oldBlocked = vpnBlocked || NetworkPolicyManager.isUidBlocked(
-                    mUidBlockedReasons.get(uid, BLOCKED_REASON_NONE), metered);
-            newBlocked = vpnBlocked || NetworkPolicyManager.isUidBlocked(
-                    blockedReasons, metered);
-            if (oldBlocked == newBlocked) {
+            final int oldBlockedState = getBlockedState(
+                    mUidBlockedReasons.get(uid, BLOCKED_REASON_NONE), metered, vpnBlocked);
+            final int newBlockedState = getBlockedState(blockedReasons, metered, vpnBlocked);
+            if (oldBlockedState == newBlockedState) {
                 continue;
             }
-            final int arg = encodeBool(newBlocked);
             for (int i = 0; i < nai.numNetworkRequests(); i++) {
                 NetworkRequest nr = nai.requestAt(i);
                 NetworkRequestInfo nri = mNetworkRequests.get(nr);
-                if (nri != null && nri.mUid == uid) {
-                    callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_BLK_CHANGED, arg);
+                if (nri != null && nri.mAsUid == uid) {
+                    callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_BLK_CHANGED,
+                            newBlockedState);
                 }
             }
         }
@@ -8123,7 +8433,7 @@
     public String getCaptivePortalServerUrl() {
         enforceNetworkStackOrSettingsPermission();
         String settingUrl = mResources.get().getString(
-                com.android.connectivity.resources.R.string.config_networkCaptivePortalServerUrl);
+                R.string.config_networkCaptivePortalServerUrl);
 
         if (!TextUtils.isEmpty(settingUrl)) {
             return settingUrl;
@@ -8300,7 +8610,7 @@
         }
     }
 
-    private @VpnManager.VpnType int getVpnType(@Nullable NetworkAgentInfo vpn) {
+    private int getVpnType(@Nullable NetworkAgentInfo vpn) {
         if (vpn == null) return VpnManager.TYPE_VPN_NONE;
         final TransportInfo ti = vpn.networkCapabilities.getTransportInfo();
         if (!(ti instanceof VpnTransportInfo)) return VpnManager.TYPE_VPN_NONE;
@@ -8755,7 +9065,7 @@
         // nri is not bound to the death of callback. Instead, callback.bindToDeath() is set in
         // handleRegisterConnectivityDiagnosticsCallback(). nri will be cleaned up as part of the
         // callback's binder death.
-        final NetworkRequestInfo nri = new NetworkRequestInfo(requestWithId);
+        final NetworkRequestInfo nri = new NetworkRequestInfo(callingUid, requestWithId);
         final ConnectivityDiagnosticsCallbackInfo cbInfo =
                 new ConnectivityDiagnosticsCallbackInfo(callback, nri, callingPackageName);
 
@@ -9239,7 +9549,7 @@
             nrs.add(createNetworkRequest(NetworkRequest.Type.REQUEST, pref.capabilities));
             nrs.add(createDefaultRequest());
             setNetworkRequestUids(nrs, UidRange.fromIntRanges(pref.capabilities.getUids()));
-            final NetworkRequestInfo nri = new NetworkRequestInfo(nrs);
+            final NetworkRequestInfo nri = new NetworkRequestInfo(Process.myUid(), nrs);
             result.add(nri);
         }
         return result;
@@ -9410,7 +9720,7 @@
             }
             // Include this nri if it will be tracked by the new per-app default requests.
             final boolean isNriGoingToBeTracked =
-                    getDefaultRequestTrackingUid(nri.mUid) != mDefaultRequest;
+                    getDefaultRequestTrackingUid(nri.mAsUid) != mDefaultRequest;
             if (isNriGoingToBeTracked) {
                 defaultCallbackRequests.add(nri);
             }
@@ -9432,7 +9742,7 @@
         final ArraySet<NetworkRequestInfo> callbackRequestsToRegister = new ArraySet<>();
         for (final NetworkRequestInfo callbackRequest : perAppCallbackRequestsForUpdate) {
             final NetworkRequestInfo trackingNri =
-                    getDefaultRequestTrackingUid(callbackRequest.mUid);
+                    getDefaultRequestTrackingUid(callbackRequest.mAsUid);
 
             // If this nri is not being tracked, the change it back to an untracked nri.
             if (trackingNri == mDefaultRequest) {
@@ -9442,12 +9752,12 @@
                 continue;
             }
 
-            final String requestorPackageName =
-                    callbackRequest.mRequests.get(0).getRequestorPackageName();
+            final NetworkRequest request = callbackRequest.mRequests.get(0);
             callbackRequestsToRegister.add(new NetworkRequestInfo(
                     callbackRequest,
                     copyNetworkRequestsForUid(
-                            trackingNri.mRequests, callbackRequest.mUid, requestorPackageName)));
+                            trackingNri.mRequests, callbackRequest.mAsUid,
+                            callbackRequest.mUid, request.getRequestorPackageName())));
         }
         return callbackRequestsToRegister;
     }
@@ -9551,7 +9861,7 @@
                 ranges.add(new UidRange(uid, uid));
             }
             setNetworkRequestUids(requests, ranges);
-            return new NetworkRequestInfo(requests);
+            return new NetworkRequestInfo(Process.myUid(), requests);
         }
 
         private NetworkRequest createUnmeteredNetworkRequest() {
diff --git a/services/core/java/com/android/server/DropBoxManagerService.java b/services/core/java/com/android/server/DropBoxManagerService.java
index f04af8b..0c3d884 100644
--- a/services/core/java/com/android/server/DropBoxManagerService.java
+++ b/services/core/java/com/android/server/DropBoxManagerService.java
@@ -448,7 +448,7 @@
                 final GZIPOutputStream gzipOutputStream =
                         new GZIPOutputStream(new FileOutputStream(fd));
                 FileUtils.copy(in, gzipOutputStream);
-                gzipOutputStream.finish();
+                gzipOutputStream.close();
             } else {
                 FileUtils.copy(in, new FileOutputStream(fd));
             }
diff --git a/services/core/java/com/android/server/PinnerService.java b/services/core/java/com/android/server/PinnerService.java
index ebd32e8..08bff81 100644
--- a/services/core/java/com/android/server/PinnerService.java
+++ b/services/core/java/com/android/server/PinnerService.java
@@ -265,18 +265,9 @@
      * Handler for on start pinning message
      */
     private void handlePinOnStart() {
-        final String bootImage = SystemProperties.get("dalvik.vm.boot-image", "");
-        String[] filesToPin = null;
-        if (bootImage.endsWith("boot-image.prof")) {
-            // Use the files listed for that specific boot image.
-            // TODO: find a better way to know we're using the JIT zygote configuration.
-            filesToPin = mContext.getResources().getStringArray(
-                  com.android.internal.R.array.config_jitzygoteBootImagePinnerServiceFiles);
-        } else {
-            // Files to pin come from the overlay and can be specified per-device config
-            filesToPin = mContext.getResources().getStringArray(
-                  com.android.internal.R.array.config_defaultPinnerServiceFiles);
-        }
+        // Files to pin come from the overlay and can be specified per-device config
+        String[] filesToPin = mContext.getResources().getStringArray(
+            com.android.internal.R.array.config_defaultPinnerServiceFiles);
         // Continue trying to pin each file even if we fail to pin some of them
         for (String fileToPin : filesToPin) {
             PinnedFile pf = pinFile(fileToPin,
@@ -286,10 +277,32 @@
                 Slog.e(TAG, "Failed to pin file = " + fileToPin);
                 continue;
             }
-
             synchronized (this) {
                 mPinnedFiles.add(pf);
             }
+            if (fileToPin.endsWith(".jar") | fileToPin.endsWith(".apk")) {
+                // Check whether the runtime has compilation artifacts to pin.
+                String arch = VMRuntime.getInstructionSet(Build.SUPPORTED_ABIS[0]);
+                String[] files = null;
+                try {
+                    files = DexFile.getDexFileOutputPaths(fileToPin, arch);
+                } catch (IOException ioe) { }
+                if (files == null) {
+                    continue;
+                }
+                for (String file : files) {
+                    PinnedFile df = pinFile(file,
+                                            Integer.MAX_VALUE,
+                                            /*attemptPinIntrospection=*/false);
+                    if (df == null) {
+                        Slog.i(TAG, "Failed to pin ART file = " + file);
+                        continue;
+                    }
+                    synchronized (this) {
+                        mPinnedFiles.add(df);
+                    }
+                }
+            }
         }
     }
 
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 7f96aff..09f4c22 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -143,7 +143,6 @@
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.os.FuseUnavailableMountException;
 import com.android.internal.os.SomeArgs;
-import com.android.internal.os.Zygote;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.CollectionUtils;
 import com.android.internal.util.DumpUtils;
@@ -3377,19 +3376,28 @@
     }
 
     @Override
-    public void notifyAppIoBlocked(String volumeUuid, int uid, int tid, int reason) {
+    public void notifyAppIoBlocked(String volumeUuid, int uid, int tid,
+            @StorageManager.AppIoBlockedReason int reason) {
         enforceExternalStorageService();
 
         mStorageSessionController.notifyAppIoBlocked(volumeUuid, uid, tid, reason);
     }
 
     @Override
-    public void notifyAppIoResumed(String volumeUuid, int uid, int tid, int reason) {
+    public void notifyAppIoResumed(String volumeUuid, int uid, int tid,
+            @StorageManager.AppIoBlockedReason int reason) {
         enforceExternalStorageService();
 
         mStorageSessionController.notifyAppIoResumed(volumeUuid, uid, tid, reason);
     }
 
+    @Override
+    public boolean isAppIoBlocked(String volumeUuid, int uid, int tid,
+            @StorageManager.AppIoBlockedReason int reason) {
+        return isAppIoBlocked(uid);
+    }
+
+
     private boolean isAppIoBlocked(int uid) {
         return mStorageSessionController.isAppIoBlocked(uid);
     }
@@ -4259,31 +4267,37 @@
         }
     }
 
+    @Override
+    public int getExternalStorageMountMode(int uid, String packageName) {
+        enforcePermission(android.Manifest.permission.WRITE_MEDIA_STORAGE);
+        return mStorageManagerInternal.getExternalStorageMountMode(uid, packageName);
+    }
+
     private int getMountModeInternal(int uid, String packageName) {
         try {
             // Get some easy cases out of the way first
             if (Process.isIsolated(uid)) {
-                return Zygote.MOUNT_EXTERNAL_NONE;
+                return StorageManager.MOUNT_MODE_EXTERNAL_NONE;
             }
 
             final String[] packagesForUid = mIPackageManager.getPackagesForUid(uid);
             if (ArrayUtils.isEmpty(packagesForUid)) {
                 // It's possible the package got uninstalled already, so just ignore.
-                return Zygote.MOUNT_EXTERNAL_NONE;
+                return StorageManager.MOUNT_MODE_EXTERNAL_NONE;
             }
             if (packageName == null) {
                 packageName = packagesForUid[0];
             }
 
             if (mPmInternal.isInstantApp(packageName, UserHandle.getUserId(uid))) {
-                return Zygote.MOUNT_EXTERNAL_NONE;
+                return StorageManager.MOUNT_MODE_EXTERNAL_NONE;
             }
 
             if (mStorageManagerInternal.isExternalStorageService(uid)) {
                 // Determine if caller requires pass_through mount; note that we do this for
                 // all processes that share a UID with MediaProvider; but this is fine, since
                 // those processes anyway share the same rights as MediaProvider.
-                return Zygote.MOUNT_EXTERNAL_PASS_THROUGH;
+                return StorageManager.MOUNT_MODE_EXTERNAL_PASS_THROUGH;
             }
 
             if ((mDownloadsAuthorityAppId == UserHandle.getAppId(uid)
@@ -4291,7 +4305,7 @@
                 // DownloadManager can write in app-private directories on behalf of apps;
                 // give it write access to Android/
                 // ExternalStorageProvider can access Android/{data,obb} dirs in managed mode
-                return Zygote.MOUNT_EXTERNAL_ANDROID_WRITABLE;
+                return StorageManager.MOUNT_MODE_EXTERNAL_ANDROID_WRITABLE;
             }
 
             final boolean hasMtp = mIPackageManager.checkUidPermission(ACCESS_MTP, uid) ==
@@ -4301,7 +4315,7 @@
                         0, UserHandle.getUserId(uid));
                 if (ai != null && ai.isSignedWithPlatformKey()) {
                     // Platform processes hosting the MTP server should be able to write in Android/
-                    return Zygote.MOUNT_EXTERNAL_ANDROID_WRITABLE;
+                    return StorageManager.MOUNT_MODE_EXTERNAL_ANDROID_WRITABLE;
                 }
             }
 
@@ -4326,13 +4340,13 @@
                 }
             }
             if ((hasInstall || hasInstallOp) && hasWrite) {
-                return Zygote.MOUNT_EXTERNAL_INSTALLER;
+                return StorageManager.MOUNT_MODE_EXTERNAL_INSTALLER;
             }
-            return Zygote.MOUNT_EXTERNAL_DEFAULT;
+            return StorageManager.MOUNT_MODE_EXTERNAL_DEFAULT;
         } catch (RemoteException e) {
             // Should not happen
         }
-        return Zygote.MOUNT_EXTERNAL_NONE;
+        return StorageManager.MOUNT_MODE_EXTERNAL_NONE;
     }
 
     private static class Callbacks extends Handler {
@@ -4702,7 +4716,8 @@
                 return true;
             }
 
-            return getExternalStorageMountMode(uid, packageName) != Zygote.MOUNT_EXTERNAL_NONE;
+            return getExternalStorageMountMode(uid, packageName)
+                    != StorageManager.MOUNT_MODE_EXTERNAL_NONE;
         }
 
         private void killAppForOpChange(int code, int uid) {
diff --git a/services/core/java/com/android/server/TEST_MAPPING b/services/core/java/com/android/server/TEST_MAPPING
index a09dbc7..ceb12c8 100644
--- a/services/core/java/com/android/server/TEST_MAPPING
+++ b/services/core/java/com/android/server/TEST_MAPPING
@@ -21,6 +21,21 @@
                 }
             ],
             "file_patterns": ["NotificationManagerService\\.java"]
+        },
+        {
+            "name": "CtsContentTestCases",
+            "options": [
+                {
+                    "include-filter": "android.content.cts.ClipboardManagerTest"
+                },
+                {
+                    "include-filter": "android.content.cts.ClipDataTest"
+                },
+                {
+                    "include-filter": "android.content.cts.ClipDescriptionTest"
+                }
+            ],
+            "file_patterns": ["ClipboardService\\.java"]
         }
     ],
     "presubmit-large": [
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 7276c78..b42a16d 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -44,6 +44,7 @@
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.provider.DeviceConfig;
+import android.telecom.TelecomManager;
 import android.telephony.Annotation;
 import android.telephony.Annotation.RadioPowerState;
 import android.telephony.Annotation.SrvccState;
@@ -154,6 +155,7 @@
         int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
 
         int phoneId = SubscriptionManager.INVALID_SIM_SLOT_INDEX;
+        int targetSdk;
 
         boolean matchTelephonyCallbackEvent(int event) {
             return (callback != null) && (this.eventList.contains(event));
@@ -214,6 +216,18 @@
             return Binder.withCleanCallingIdentity(() -> CompatChanges.isChangeEnabled(
                     TelephonyCallback.PHONE_STATE_LISTENER_LIMIT_CHANGE_ID, uid));
         }
+
+        /**
+         * See {@link TelecomManager#ENABLE_GET_CALL_STATE_PERMISSION_PROTECTION} for more
+         * information.
+         * @noinspection ConstantConditions
+         */
+        public boolean isCallStateReadPhoneStateEnforcedInPlatformCompat(String packageName,
+                UserHandle userHandle) {
+            return Binder.withCleanCallingIdentity(() -> CompatChanges.isChangeEnabled(
+                    TelecomManager.ENABLE_GET_CALL_STATE_PERMISSION_PROTECTION, packageName,
+                    userHandle));
+        }
     }
 
     private final Context mContext;
@@ -365,11 +379,13 @@
                 || events.contains(TelephonyCallback.EVENT_BARRING_INFO_CHANGED);
     }
 
-    private boolean isPhoneStatePermissionRequired(Set<Integer> events) {
+    private boolean isPhoneStatePermissionRequired(Set<Integer> events, int targetSdk) {
         return events.contains(TelephonyCallback.EVENT_CALL_FORWARDING_INDICATOR_CHANGED)
                 || events.contains(TelephonyCallback.EVENT_MESSAGE_WAITING_INDICATOR_CHANGED)
                 || events.contains(TelephonyCallback.EVENT_EMERGENCY_NUMBER_LIST_CHANGED)
-                || events.contains(TelephonyCallback.EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED);
+                || events.contains(TelephonyCallback.EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED)
+                || (targetSdk <= android.os.Build.VERSION_CODES.R ? events.contains(
+                TelephonyCallback.EVENT_DISPLAY_INFO_CHANGED) : false);
     }
 
     private boolean isPrecisePhoneStatePermissionRequired(Set<Integer> events) {
@@ -881,12 +897,12 @@
             remove(callback.asBinder());
             return;
         }
-
+        int callerTargetSdk = TelephonyPermissions.getTargetSdk(mContext, callingPackage);
         // Checks permission and throws SecurityException for disallowed operations. For pre-M
         // apps whose runtime permission has been revoked, we return immediately to skip sending
         // events to the app without crashing it.
         if (!checkListenerPermission(events, subId, callingPackage, callingFeatureId,
-                "listen")) {
+                "listen", callerTargetSdk)) {
             return;
         }
 
@@ -919,6 +935,8 @@
             }
             r.phoneId = phoneId;
             r.eventList = events;
+            r.targetSdk = callerTargetSdk;
+
             if (DBG) {
                 log("listen:  Register r=" + r + " r.subId=" + r.subId + " phoneId=" + phoneId);
             }
@@ -1177,7 +1195,9 @@
                         TelephonyCallback.EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED)) {
                     try {
                         r.callback.onPhysicalChannelConfigChanged(
-                                mPhysicalChannelConfigs);
+                                shouldSanitizeLocationForPhysicalChannelConfig(r)
+                                        ? getLocationSanitizedConfigs(mPhysicalChannelConfigs)
+                                        : mPhysicalChannelConfigs);
                     } catch (RemoteException ex) {
                         remove(r.binder);
                     }
@@ -1748,6 +1768,11 @@
                             TelephonyCallback.EVENT_DISPLAY_INFO_CHANGED)
                             && idMatchWithoutDefaultPhoneCheck(r.subId, subId)) {
                         try {
+                            if (r.targetSdk <= android.os.Build.VERSION_CODES.R) {
+                                telephonyDisplayInfo =
+                                        getBackwardCompatibleTelephonyDisplayInfo(
+                                                telephonyDisplayInfo);
+                            }
                             r.callback.onDisplayInfoChanged(telephonyDisplayInfo);
                         } catch (RemoteException ex) {
                             mRemoveList.add(r.binder);
@@ -1759,6 +1784,19 @@
         }
     }
 
+    private TelephonyDisplayInfo getBackwardCompatibleTelephonyDisplayInfo(
+            @NonNull TelephonyDisplayInfo telephonyDisplayInfo) {
+        int networkType = telephonyDisplayInfo.getNetworkType();
+        int overrideNetworkType = telephonyDisplayInfo.getOverrideNetworkType();
+        if (networkType == TelephonyManager.NETWORK_TYPE_NR) {
+            overrideNetworkType = TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE;
+        } else if (networkType == TelephonyManager.NETWORK_TYPE_LTE
+                && overrideNetworkType == TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED) {
+            overrideNetworkType = TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE;
+        }
+        return new TelephonyDisplayInfo(networkType, overrideNetworkType);
+    }
+
     public void notifyCallForwardingChanged(boolean cfi) {
         notifyCallForwardingChangedForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, cfi);
     }
@@ -2402,8 +2440,10 @@
             return;
         }
 
+        List<PhysicalChannelConfig> sanitizedConfigs = getLocationSanitizedConfigs(configs);
         if (VDBG) {
-            log("notifyPhysicalChannelConfig: subId=" + subId + " configs=" + configs);
+            log("notifyPhysicalChannelConfig: subId=" + subId + " configs=" + configs
+                    + " sanitizedConfigs=" + sanitizedConfigs);
         }
 
         synchronized (mRecords) {
@@ -2416,11 +2456,14 @@
                             && idMatch(r.subId, subId, phoneId)) {
                         try {
                             if (DBG_LOC) {
-                                log("notifyPhysicalChannelConfig: "
-                                        + "mPhysicalChannelConfigs="
-                                        + configs + " r=" + r);
+                                log("notifyPhysicalChannelConfig: mPhysicalChannelConfigs="
+                                        + (shouldSanitizeLocationForPhysicalChannelConfig(r)
+                                                ? sanitizedConfigs : configs)
+                                        + " r=" + r);
                             }
-                            r.callback.onPhysicalChannelConfigChanged(configs);
+                            r.callback.onPhysicalChannelConfigChanged(
+                                    shouldSanitizeLocationForPhysicalChannelConfig(r)
+                                            ? sanitizedConfigs : configs);
                         } catch (RemoteException ex) {
                             mRemoveList.add(r.binder);
                         }
@@ -2431,6 +2474,25 @@
         }
     }
 
+    private static boolean shouldSanitizeLocationForPhysicalChannelConfig(Record record) {
+        // Always redact location info from PhysicalChannelConfig if the registrant is from neither
+        // PHONE nor SYSTEM process. There is no user case that the registrant needs the location
+        // info (e.g. physicalCellId). This also remove the need for the location permissions check.
+        return record.callerUid != Process.PHONE_UID && record.callerUid != Process.SYSTEM_UID;
+    }
+
+    /**
+     * Return a copy of the PhysicalChannelConfig list but with location info removed.
+     */
+    private static List<PhysicalChannelConfig> getLocationSanitizedConfigs(
+            List<PhysicalChannelConfig> configs) {
+        List<PhysicalChannelConfig> sanitizedConfigs = new ArrayList<>(configs.size());
+        for (PhysicalChannelConfig config : configs) {
+            sanitizedConfigs.add(config.createLocationInfoSanitizedCopy());
+        }
+        return sanitizedConfigs;
+    }
+
     /**
      * Notify that the data enabled has changed.
      *
@@ -2855,7 +2917,7 @@
     }
 
     private boolean checkListenerPermission(Set<Integer> events, int subId, String callingPackage,
-                                            @Nullable String callingFeatureId, String message) {
+            @Nullable String callingFeatureId, String message, int targetSdk) {
         LocationAccessPolicy.LocationPermissionQuery.Builder locationQueryBuilder =
                 new LocationAccessPolicy.LocationPermissionQuery.Builder()
                         .setCallingPackage(callingPackage)
@@ -2891,13 +2953,26 @@
             }
         }
 
-        if (isPhoneStatePermissionRequired(events)) {
+        if (isPhoneStatePermissionRequired(events, targetSdk)) {
             if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
                     mContext, subId, callingPackage, callingFeatureId, message)) {
                 isPermissionCheckSuccessful = false;
             }
         }
 
+        // Only check READ_PHONE_STATE for CALL_STATE_CHANGED for API 31+.
+        if (mConfigurationProvider.isCallStateReadPhoneStateEnforcedInPlatformCompat(callingPackage,
+                Binder.getCallingUserHandle())) {
+            if (events.contains(TelephonyCallback.EVENT_LEGACY_CALL_STATE_CHANGED)
+                    || events.contains(TelephonyCallback.EVENT_CALL_STATE_CHANGED)) {
+                if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                        mContext, subId, callingPackage, callingFeatureId, message)) {
+                    throw new SecurityException("CALL_STATE_CHANGED event requires "
+                            + "READ_PHONE_STATE");
+                }
+            }
+        }
+
         if (isPrecisePhoneStatePermissionRequired(events)) {
             // check if calling app has either permission READ_PRECISE_PHONE_STATE
             // or with carrier privileges
diff --git a/services/core/java/com/android/server/TestNetworkService.java b/services/core/java/com/android/server/TestNetworkService.java
index f566277..09873f4 100644
--- a/services/core/java/com/android/server/TestNetworkService.java
+++ b/services/core/java/com/android/server/TestNetworkService.java
@@ -35,7 +35,6 @@
 import android.net.RouteInfo;
 import android.net.TestNetworkInterface;
 import android.net.TestNetworkSpecifier;
-import android.net.util.NetdService;
 import android.os.Binder;
 import android.os.Handler;
 import android.os.HandlerThread;
@@ -86,7 +85,9 @@
         mHandler = new Handler(mHandlerThread.getLooper());
 
         mContext = Objects.requireNonNull(context, "missing Context");
-        mNetd = Objects.requireNonNull(NetdService.getInstance(), "could not get netd instance");
+        mNetd = Objects.requireNonNull(
+                INetd.Stub.asInterface((IBinder) context.getSystemService(Context.NETD_SERVICE)),
+                "could not get netd instance");
         mCm = mContext.getSystemService(ConnectivityManager.class);
         mNetworkProvider = new NetworkProvider(mContext, mHandler.getLooper(),
                 TEST_NETWORK_PROVIDER_NAME);
diff --git a/services/core/java/com/android/server/VcnManagementService.java b/services/core/java/com/android/server/VcnManagementService.java
index 051cd99..cd2d6d4 100644
--- a/services/core/java/com/android/server/VcnManagementService.java
+++ b/services/core/java/com/android/server/VcnManagementService.java
@@ -29,7 +29,10 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.AppOpsManager;
+import android.content.BroadcastReceiver;
 import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
 import android.net.ConnectivityManager;
 import android.net.LinkProperties;
 import android.net.NetworkCapabilities;
@@ -158,6 +161,7 @@
     @NonNull private final TelephonySubscriptionTrackerCallback mTelephonySubscriptionTrackerCb;
     @NonNull private final TelephonySubscriptionTracker mTelephonySubscriptionTracker;
     @NonNull private final VcnContext mVcnContext;
+    @NonNull private final BroadcastReceiver mPkgChangeReceiver;
 
     /** Can only be assigned when {@link #systemReady()} is called, since it uses AppOpsManager. */
     @Nullable private LocationPermissionChecker mLocationPermissionChecker;
@@ -203,6 +207,29 @@
         mConfigDiskRwHelper = mDeps.newPersistableBundleLockingReadWriteHelper(VCN_CONFIG_FILE);
         mVcnContext = mDeps.newVcnContext(mContext, mLooper, mNetworkProvider);
 
+        mPkgChangeReceiver = new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                final String action = intent.getAction();
+
+                if (Intent.ACTION_PACKAGE_ADDED.equals(action)
+                        || Intent.ACTION_PACKAGE_REPLACED.equals(action)
+                        || Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
+                    mTelephonySubscriptionTracker.handleSubscriptionsChanged();
+                } else {
+                    Log.wtf(TAG, "received unexpected intent: " + action);
+                }
+            }
+        };
+
+        final IntentFilter intentFilter = new IntentFilter();
+        intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
+        intentFilter.addAction(Intent.ACTION_PACKAGE_REPLACED);
+        intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+        intentFilter.addDataScheme("package");
+        mContext.registerReceiver(
+                mPkgChangeReceiver, intentFilter, null /* broadcastPermission */, mHandler);
+
         // Run on handler to ensure I/O does not block system server startup
         mHandler.post(() -> {
             PersistableBundle configBundle = null;
@@ -348,7 +375,8 @@
         }
     }
 
-    private void enforceCallingUserAndCarrierPrivilege(ParcelUuid subscriptionGroup) {
+    private void enforceCallingUserAndCarrierPrivilege(
+            ParcelUuid subscriptionGroup, String pkgName) {
         // Only apps running in the primary (system) user are allowed to configure the VCN. This is
         // in line with Telephony's behavior with regards to binding to a Carrier App provided
         // CarrierConfigService.
@@ -362,12 +390,15 @@
                     subscriptionInfos.addAll(subMgr.getSubscriptionsInGroup(subscriptionGroup));
                 });
 
-        final TelephonyManager telMgr = mContext.getSystemService(TelephonyManager.class);
         for (SubscriptionInfo info : subscriptionInfos) {
+            final TelephonyManager telMgr = mContext.getSystemService(TelephonyManager.class)
+                    .createForSubscriptionId(info.getSubscriptionId());
+
             // Check subscription is active first; much cheaper/faster check, and an app (currently)
             // cannot be carrier privileged for inactive subscriptions.
             if (subMgr.isValidSlotIndex(info.getSimSlotIndex())
-                    && telMgr.hasCarrierPrivileges(info.getSubscriptionId())) {
+                    && telMgr.checkCarrierPrivilegesForPackage(pkgName)
+                            == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
                 // TODO (b/173717728): Allow configuration for inactive, but manageable
                 // subscriptions.
                 // TODO (b/173718661): Check for whole subscription groups at a time.
@@ -535,7 +566,7 @@
 
         mContext.getSystemService(AppOpsManager.class)
                 .checkPackage(mDeps.getBinderCallingUid(), config.getProvisioningPackageName());
-        enforceCallingUserAndCarrierPrivilege(subscriptionGroup);
+        enforceCallingUserAndCarrierPrivilege(subscriptionGroup, opPkgName);
 
         Binder.withCleanCallingIdentity(() -> {
             synchronized (mLock) {
@@ -553,11 +584,14 @@
      * <p>Implements the IVcnManagementService Binder interface.
      */
     @Override
-    public void clearVcnConfig(@NonNull ParcelUuid subscriptionGroup) {
+    public void clearVcnConfig(@NonNull ParcelUuid subscriptionGroup, @NonNull String opPkgName) {
         requireNonNull(subscriptionGroup, "subscriptionGroup was null");
+        requireNonNull(opPkgName, "opPkgName was null");
         Slog.v(TAG, "VCN config cleared for subGrp: " + subscriptionGroup);
 
-        enforceCallingUserAndCarrierPrivilege(subscriptionGroup);
+        mContext.getSystemService(AppOpsManager.class)
+                .checkPackage(mDeps.getBinderCallingUid(), opPkgName);
+        enforceCallingUserAndCarrierPrivilege(subscriptionGroup, opPkgName);
 
         Binder.withCleanCallingIdentity(() -> {
             synchronized (mLock) {
@@ -820,8 +854,7 @@
 
             final IBinder cbBinder = callback.asBinder();
             final VcnStatusCallbackInfo cbInfo =
-                    new VcnStatusCallbackInfo(
-                            subGroup, callback, opPkgName, mDeps.getBinderCallingUid());
+                    new VcnStatusCallbackInfo(subGroup, callback, opPkgName, callingUid);
 
             try {
                 cbBinder.linkToDeath(cbInfo, 0 /* flags */);
diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java
index 9636641..211999f 100644
--- a/services/core/java/com/android/server/Watchdog.java
+++ b/services/core/java/com/android/server/Watchdog.java
@@ -35,11 +35,11 @@
 import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.SystemProperties;
+import android.sysprop.WatchdogProperties;
 import android.util.EventLog;
 import android.util.Log;
 import android.util.Slog;
 import android.util.SparseArray;
-import android.sysprop.WatchdogProperties;
 
 import com.android.internal.os.ProcessCpuTracker;
 import com.android.internal.os.ZygoteConnectionConstants;
@@ -56,9 +56,9 @@
 import java.io.StringWriter;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.concurrent.TimeUnit;
 import java.util.HashSet;
 import java.util.List;
+import java.util.concurrent.TimeUnit;
 
 /** This class calls its monitor every minute. Killing this process if they don't return **/
 public class Watchdog {
@@ -688,7 +688,7 @@
                         if (mActivity != null) {
                             mActivity.addErrorToDropBox(
                                     "watchdog", null, "system_server", null, null, null,
-                                    subject, report.toString(), stack, null);
+                                    subject, report.toString(), stack, null, null, null);
                         }
                         FrameworkStatsLog.write(FrameworkStatsLog.SYSTEM_SERVER_WATCHDOG_OCCURRED,
                                 subject);
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 1b352c7..7f8d944 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -18,7 +18,6 @@
 
 import static android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND;
 import static android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND;
-import static android.Manifest.permission.SYSTEM_ALERT_WINDOW;
 import static android.app.ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
 import static android.app.ActivityManager.PROCESS_STATE_RECEIVER;
 import static android.app.ActivityManager.PROCESS_STATE_TOP;
@@ -49,6 +48,7 @@
 import static android.os.PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED;
 import static android.os.PowerWhitelistManager.getReasonCodeFromProcState;
 import static android.os.PowerWhitelistManager.reasonCodeToString;
+import static android.os.Process.INVALID_UID;
 import static android.os.Process.NFC_UID;
 import static android.os.Process.ROOT_UID;
 import static android.os.Process.SHELL_UID;
@@ -660,7 +660,7 @@
         }
 
         ServiceRecord r = res.record;
-        setFgsRestrictionLocked(callingPackage, callingPid, callingUid, service, r,
+        setFgsRestrictionLocked(callingPackage, callingPid, callingUid, service, r, userId,
                 allowBackgroundActivityStarts);
 
         if (!mAm.mUserController.exists(r.userId)) {
@@ -693,19 +693,7 @@
                         + r.shortInstanceName;
                 Slog.w(TAG, msg);
                 showFgsBgRestrictedNotificationLocked(r);
-                ApplicationInfo aInfo = null;
-                try {
-                    aInfo = AppGlobals.getPackageManager().getApplicationInfo(
-                            callingPackage, ActivityManagerService.STOCK_PM_FLAGS,
-                            userId);
-                } catch (android.os.RemoteException e) {
-                    // pm is in same process, this will never happen.
-                }
-                if (aInfo == null) {
-                    throw new SecurityException("startServiceLocked failed, "
-                            + "could not resolve client package " + callingPackage);
-                }
-                if (CompatChanges.isChangeEnabled(FGS_START_EXCEPTION_CHANGE_ID, aInfo.uid)) {
+                if (CompatChanges.isChangeEnabled(FGS_START_EXCEPTION_CHANGE_ID, callingUid)) {
                     throw new ForegroundServiceStartNotAllowedException(msg);
                 }
                 return null;
@@ -839,7 +827,7 @@
         boolean addToStarting = false;
         if (!callerFg && !fgRequired && r.app == null
                 && mAm.mUserController.hasStartedUserState(r.userId)) {
-            ProcessRecord proc = mAm.getProcessRecordLocked(r.processName, r.appInfo.uid, false);
+            ProcessRecord proc = mAm.getProcessRecordLocked(r.processName, r.appInfo.uid);
             if (proc == null || proc.mState.getCurProcState() > PROCESS_STATE_RECEIVER) {
                 // If this is not coming from a foreground caller, then we may want
                 // to delay the start if there are already other background services
@@ -1790,6 +1778,44 @@
                 }
 
                 if (!ignoreForeground) {
+                    if (r.mStartForegroundCount == 0) {
+                        /*
+                        If the service was started with startService(), not
+                        startForegroundService(), and if startForeground() isn't called within
+                        mFgsStartForegroundTimeoutMs, then we check the state of the app
+                        (who owns the service, which is the app that called startForeground())
+                        again. If the app is in the foreground, or in any other cases where
+                        FGS-starts are allowed, then we still allow the FGS to be started.
+                        Otherwise, startForeground() would fail.
+
+                        If the service was started with startForegroundService(), then the service
+                        must call startForeground() within a timeout anyway, so we don't need this
+                        check.
+                        */
+                        if (!r.fgRequired) {
+                            final long delayMs = SystemClock.elapsedRealtime() - r.createRealTime;
+                            if (delayMs > mAm.mConstants.mFgsStartForegroundTimeoutMs) {
+                                setFgsRestrictionLocked(r.serviceInfo.packageName, r.app.getPid(),
+                                        r.appInfo.uid, r.intent.getIntent(), r, r.userId,false);
+                                final String temp = "startForegroundDelayMs:" + delayMs;
+                                if (r.mInfoAllowStartForeground != null) {
+                                    r.mInfoAllowStartForeground += "; " + temp;
+                                } else {
+                                    r.mInfoAllowStartForeground = temp;
+                                }
+                                r.mLoggedInfoAllowStartForeground = false;
+                            }
+                        }
+                    } else if (r.mStartForegroundCount >= 1) {
+                        // The second or later time startForeground() is called after service is
+                        // started. Check for app state again.
+                        final long delayMs = SystemClock.elapsedRealtime() -
+                                r.mLastSetFgsRestrictionTime;
+                        if (delayMs > mAm.mConstants.mFgsStartForegroundTimeoutMs) {
+                            setFgsRestrictionLocked(r.serviceInfo.packageName, r.app.getPid(),
+                                    r.appInfo.uid, r.intent.getIntent(), r, r.userId,false);
+                        }
+                    }
                     logFgsBackgroundStart(r);
                     if (r.mAllowStartForeground == REASON_DENIED && isBgFgsRestrictionEnabled(r)) {
                         final String msg = "Service.startForeground() not allowed due to "
@@ -1843,6 +1869,7 @@
                             active.mNumActive++;
                         }
                         r.isForeground = true;
+                        r.mStartForegroundCount++;
                         if (!stopProcStatsOp) {
                             ServiceState stracker = r.getTracker();
                             if (stracker != null) {
@@ -1901,6 +1928,7 @@
                     decActiveForegroundAppLocked(smap, r);
                 }
                 r.isForeground = false;
+                resetFgsRestrictionLocked(r);
                 ServiceState stracker = r.getTracker();
                 if (stracker != null) {
                     stracker.setForeground(false, mAm.mProcessStats.getMemFactorLocked(),
@@ -1949,20 +1977,30 @@
                     && isLegacyApp;
         }
         if (!showNow) {
-            // is the notification such that it should show right away?
-            showNow = r.foregroundNoti.shouldShowForegroundImmediately();
-            // or is this an type of FGS that always shows immediately?
-            if (!showNow) {
-                switch (r.foregroundServiceType) {
-                    case ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK:
-                    case ServiceInfo.FOREGROUND_SERVICE_TYPE_PHONE_CALL:
-                    case ServiceInfo.FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE:
-                    case ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION:
-                        if (DEBUG_FOREGROUND_SERVICE) {
-                            Slog.d(TAG_SERVICE, "FGS " + r
-                                    + " type gets immediate display");
-                        }
-                        showNow = true;
+            // has the app forced deferral?
+            if (!r.foregroundNoti.isForegroundDisplayForceDeferred()) {
+                // is the notification such that it should show right away?
+                showNow = r.foregroundNoti.shouldShowForegroundImmediately();
+                if (DEBUG_FOREGROUND_SERVICE && showNow) {
+                    Slog.d(TAG_SERVICE, "FGS " + r
+                            + " notification policy says show immediately");
+                }
+                // or is this an type of FGS that always shows immediately?
+                if (!showNow) {
+                    switch (r.foregroundServiceType) {
+                        case ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK:
+                        case ServiceInfo.FOREGROUND_SERVICE_TYPE_PHONE_CALL:
+                        case ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION:
+                            if (DEBUG_FOREGROUND_SERVICE) {
+                                Slog.d(TAG_SERVICE, "FGS " + r
+                                        + " type gets immediate display");
+                            }
+                            showNow = true;
+                    }
+                }
+            } else {
+                if (DEBUG_FOREGROUND_SERVICE) {
+                    Slog.d(TAG_SERVICE, "FGS " + r + " notification is app deferred");
                 }
             }
         }
@@ -2539,7 +2577,8 @@
                     return 0;
                 }
             }
-            setFgsRestrictionLocked(callingPackage, callingPid, callingUid, service, s, false);
+            setFgsRestrictionLocked(callingPackage, callingPid, callingUid, service, s, userId,
+                    false);
 
             if (s.app != null) {
                 ProcessServiceRecord servicePsr = s.app.mServices;
@@ -3411,7 +3450,7 @@
         ProcessRecord app;
 
         if (!isolated) {
-            app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
+            app = mAm.getProcessRecordLocked(procName, r.appInfo.uid);
             if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid
                         + " app=" + app);
             if (app != null) {
@@ -3459,7 +3498,7 @@
             // TODO (chriswailes): Change the Zygote policy flags based on if the launch-for-service
             //  was initiated from a notification tap or not.
             if ((app = mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
-                        hostingRecord, ZYGOTE_POLICY_FLAG_EMPTY, false, isolated, false)) == null) {
+                        hostingRecord, ZYGOTE_POLICY_FLAG_EMPTY, false, isolated)) == null) {
                 String msg = "Unable to launch app "
                         + r.appInfo.packageName + "/"
                         + r.appInfo.uid + " for service "
@@ -3892,6 +3931,7 @@
         r.foregroundId = 0;
         r.foregroundNoti = null;
         r.mAllowWhileInUsePermissionInFgs = false;
+        r.mAllowStartForeground = REASON_DENIED;
 
         // Clear start entries.
         r.clearDeliveredStartsLocked();
@@ -5428,8 +5468,9 @@
      * @return true if allow, false otherwise.
      */
     private void setFgsRestrictionLocked(String callingPackage,
-            int callingPid, int callingUid, Intent intent, ServiceRecord r,
+            int callingPid, int callingUid, Intent intent, ServiceRecord r, int userId,
             boolean allowBackgroundActivityStarts) {
+        r.mLastSetFgsRestrictionTime = SystemClock.elapsedRealtime();
         // Check DeviceConfig flag.
         if (!mAm.mConstants.mFlagBackgroundFgsStartRestrictionEnabled) {
             r.mAllowWhileInUsePermissionInFgs = true;
@@ -5445,11 +5486,20 @@
             if (r.mAllowStartForeground == REASON_DENIED) {
                 r.mAllowStartForeground = shouldAllowFgsStartForegroundLocked(allowWhileInUse,
                         callingPackage, callingPid, callingUid, intent, r,
-                        allowBackgroundActivityStarts);
+                        userId);
             }
         }
     }
 
+    void resetFgsRestrictionLocked(ServiceRecord r) {
+        r.mAllowWhileInUsePermissionInFgs = false;
+        r.mAllowStartForeground = REASON_DENIED;
+        r.mInfoAllowStartForeground = null;
+        r.mInfoTempFgsAllowListReason = null;
+        r.mLoggedInfoAllowStartForeground = false;
+        r.mLastSetFgsRestrictionTime = 0;
+    }
+
     boolean canStartForegroundServiceLocked(int callingPid, int callingUid, String callingPackage) {
         if (!mAm.mConstants.mFlagBackgroundFgsStartRestrictionEnabled) {
             return true;
@@ -5579,13 +5629,20 @@
      */
     private @ReasonCode int shouldAllowFgsStartForegroundLocked(
             @ReasonCode int allowWhileInUse, String callingPackage, int callingPid,
-            int callingUid, Intent intent, ServiceRecord r, boolean allowBackgroundActivityStarts) {
+            int callingUid, Intent intent, ServiceRecord r, int userId) {
         FgsStartTempAllowList.TempFgsAllowListEntry tempAllowListReason =
                 r.mInfoTempFgsAllowListReason = mAm.isAllowlistedForFgsStartLOSP(callingUid);
         int ret = shouldAllowFgsStartForegroundLocked(allowWhileInUse, callingPid, callingUid,
                 callingPackage, r);
 
         final int uidState = mAm.getUidStateLocked(callingUid);
+        int callerTargetSdkVersion = INVALID_UID;
+        try {
+            ApplicationInfo ai = mAm.mContext.getPackageManager().getApplicationInfoAsUser(
+                    callingPackage, PackageManager.MATCH_KNOWN_PACKAGES, userId);
+            callerTargetSdkVersion = ai.targetSdkVersion;
+        } catch (PackageManager.NameNotFoundException e) {
+        }
         final String debugInfo =
                 "[callingPackage: " + callingPackage
                         + "; callingUid: " + callingUid
@@ -5601,6 +5658,8 @@
                                         + ",callingUid:" + tempAllowListReason.mCallingUid))
                         + ">"
                         + "; targetSdkVersion:" + r.appInfo.targetSdkVersion
+                        + "; callerTargetSdkVersion:" + callerTargetSdkVersion
+                        + "; startForegroundCount:" + r.mStartForegroundCount
                         + "]";
         if (!debugInfo.equals(r.mInfoAllowStartForeground)) {
             r.mLoggedInfoAllowStartForeground = false;
@@ -5663,8 +5722,8 @@
         }
 
         if (ret == REASON_DENIED) {
-            if (mAm.checkPermission(SYSTEM_ALERT_WINDOW, callingPid,
-                    callingUid) == PERMISSION_GRANTED) {
+            if (mAm.mAtmInternal.hasSystemAlertWindowPermission(callingUid, callingPid,
+                    callingPackage)) {
                 ret = REASON_SYSTEM_ALERT_WINDOW_PERMISSION;
             }
         }
@@ -5771,7 +5830,12 @@
 
     private boolean isBgFgsRestrictionEnabled(ServiceRecord r) {
         return mAm.mConstants.mFlagFgsStartRestrictionEnabled
-                && CompatChanges.isChangeEnabled(FGS_BG_START_RESTRICTION_CHANGE_ID, r.appInfo.uid);
+                // Checking service's targetSdkVersion.
+                && CompatChanges.isChangeEnabled(FGS_BG_START_RESTRICTION_CHANGE_ID, r.appInfo.uid)
+                && (!mAm.mConstants.mFgsStartRestrictionCheckCallerTargetSdk
+                    // Checking callingUid's targetSdkVersion.
+                    || CompatChanges.isChangeEnabled(
+                            FGS_BG_START_RESTRICTION_CHANGE_ID, r.mRecentCallingUid));
     }
 
     private void logFgsBackgroundStart(ServiceRecord r) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java
index 5859cea..e16f4c9 100644
--- a/services/core/java/com/android/server/am/ActivityManagerConstants.java
+++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java
@@ -96,6 +96,7 @@
     static final String KEY_PROCESS_CRASH_COUNT_LIMIT = "process_crash_count_limit";
     static final String KEY_BOOT_TIME_TEMP_ALLOWLIST_DURATION = "boot_time_temp_allowlist_duration";
     static final String KEY_FG_TO_BG_FGS_GRACE_DURATION = "fg_to_bg_fgs_grace_duration";
+    static final String KEY_FGS_START_FOREGROUND_TIMEOUT = "fgs_start_foreground_timeout";
 
     private static final int DEFAULT_MAX_CACHED_PROCESSES = 32;
     private static final long DEFAULT_BACKGROUND_SETTLE_TIME = 60*1000;
@@ -135,7 +136,7 @@
     private static final int DEFAULT_PROCESS_CRASH_COUNT_LIMIT = 12;
     private static final int DEFAULT_BOOT_TIME_TEMP_ALLOWLIST_DURATION = 10 * 1000;
     private static final long DEFAULT_FG_TO_BG_FGS_GRACE_DURATION = 5 * 1000;
-
+    private static final int DEFAULT_FGS_START_FOREGROUND_TIMEOUT_MS = 10 * 1000;
 
     // Flag stored in the DeviceConfig API.
     /**
@@ -171,6 +172,13 @@
             "default_fgs_starts_restriction_enabled";
 
     /**
+     * Default value for mFgsStartRestrictionCheckCallerTargetSdk if not explicitly set in
+     * Settings.Global.
+     */
+    private static final String KEY_DEFAULT_FGS_STARTS_RESTRICTION_CHECK_CALLER_TARGET_SDK =
+            "default_fgs_starts_restriction_check_caller_target_sdk";
+
+    /**
      * Whether FGS notification display is deferred following the transition into
      * the foreground state.  Default behavior is {@code true} unless overridden.
      */
@@ -370,6 +378,13 @@
     // at all.
     volatile boolean mFlagFgsStartRestrictionEnabled = true;
 
+    /**
+     * Indicates whether the foreground service background start restriction is enabled for
+     * caller app that is targeting S+.
+     * This is in addition to check of {@link #mFlagFgsStartRestrictionEnabled} flag.
+     */
+    volatile boolean mFgsStartRestrictionCheckCallerTargetSdk = true;
+
     // Whether we defer FGS notifications a few seconds following their transition to
     // the foreground state.  Applies only to S+ apps; enabled by default.
     volatile boolean mFlagFgsNotificationDeferralEnabled = true;
@@ -396,6 +411,12 @@
      */
     volatile long mFgToBgFgsGraceDuration = DEFAULT_FG_TO_BG_FGS_GRACE_DURATION;
 
+    /**
+     * When service started from background, before the timeout it can be promoted to FGS by calling
+     * Service.startForeground().
+     */
+    volatile long mFgsStartForegroundTimeoutMs = DEFAULT_FGS_START_FOREGROUND_TIMEOUT_MS;
+
     private final ActivityManagerService mService;
     private ContentResolver mResolver;
     private final KeyValueListParser mParser = new KeyValueListParser(',');
@@ -547,6 +568,9 @@
                             case KEY_DEFAULT_FGS_STARTS_RESTRICTION_ENABLED:
                                 updateFgsStartsRestriction();
                                 break;
+                            case KEY_DEFAULT_FGS_STARTS_RESTRICTION_CHECK_CALLER_TARGET_SDK:
+                                updateFgsStartsRestrictionCheckCallerTargetSdk();
+                                break;
                             case KEY_DEFERRED_FGS_NOTIFICATIONS_ENABLED:
                                 updateFgsNotificationDeferralEnable();
                                 break;
@@ -586,6 +610,9 @@
                             case KEY_FG_TO_BG_FGS_GRACE_DURATION:
                                 updateFgToBgFgsGraceDuration();
                                 break;
+                            case KEY_FGS_START_FOREGROUND_TIMEOUT:
+                                updateFgsStartForegroundTimeout();
+                                break;
                             default:
                                 break;
                         }
@@ -819,6 +846,13 @@
                 /*defaultValue*/ true);
     }
 
+    private void updateFgsStartsRestrictionCheckCallerTargetSdk() {
+        mFgsStartRestrictionCheckCallerTargetSdk = DeviceConfig.getBoolean(
+                DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+                KEY_DEFAULT_FGS_STARTS_RESTRICTION_CHECK_CALLER_TARGET_SDK,
+                /*defaultValue*/ true);
+    }
+
     private void updateFgsNotificationDeferralEnable() {
         mFlagFgsNotificationDeferralEnabled = DeviceConfig.getBoolean(
                 DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
@@ -869,6 +903,13 @@
                 DEFAULT_FG_TO_BG_FGS_GRACE_DURATION);
     }
 
+    private void updateFgsStartForegroundTimeout() {
+        mFgsStartForegroundTimeoutMs = DeviceConfig.getLong(
+                DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+                KEY_FGS_START_FOREGROUND_TIMEOUT,
+                DEFAULT_FGS_START_FOREGROUND_TIMEOUT_MS);
+    }
+
     private void updateImperceptibleKillExemptions() {
         IMPERCEPTIBLE_KILL_EXEMPT_PACKAGES.clear();
         IMPERCEPTIBLE_KILL_EXEMPT_PACKAGES.addAll(mDefaultImperceptibleKillExemptPackages);
@@ -1071,6 +1112,16 @@
         pw.println(mBootTimeTempAllowlistDuration);
         pw.print("  "); pw.print(KEY_FG_TO_BG_FGS_GRACE_DURATION); pw.print("=");
         pw.println(mFgToBgFgsGraceDuration);
+        pw.print("  "); pw.print(KEY_FGS_START_FOREGROUND_TIMEOUT); pw.print("=");
+        pw.println(mFgsStartForegroundTimeoutMs);
+        pw.print("  "); pw.print(KEY_DEFAULT_BACKGROUND_ACTIVITY_STARTS_ENABLED); pw.print("=");
+        pw.println(mFlagBackgroundActivityStartsEnabled);
+        pw.print("  "); pw.print(KEY_DEFAULT_BACKGROUND_FGS_STARTS_RESTRICTION_ENABLED);
+        pw.print("="); pw.println(mFlagBackgroundFgsStartRestrictionEnabled);
+        pw.print("  "); pw.print(KEY_DEFAULT_FGS_STARTS_RESTRICTION_ENABLED); pw.print("=");
+        pw.println(mFlagFgsStartRestrictionEnabled);
+        pw.print("  "); pw.print(KEY_DEFAULT_FGS_STARTS_RESTRICTION_CHECK_CALLER_TARGET_SDK);
+        pw.print("="); pw.println(mFgsStartRestrictionCheckCallerTargetSdk);
 
         pw.println();
         if (mOverrideMaxCachedProcesses >= 0) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index c4548a3..2ee5c5a 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -182,11 +182,13 @@
 import android.app.WaitResult;
 import android.app.backup.BackupManager.OperationType;
 import android.app.backup.IBackupManager;
+import android.app.job.JobParameters;
 import android.app.usage.UsageEvents;
 import android.app.usage.UsageEvents.Event;
 import android.app.usage.UsageStatsManager;
 import android.app.usage.UsageStatsManagerInternal;
 import android.appwidget.AppWidgetManager;
+import android.content.AttributionSource;
 import android.content.AutofillOptions;
 import android.content.BroadcastReceiver;
 import android.content.ComponentCallbacks2;
@@ -212,7 +214,6 @@
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.PackageManagerInternal;
-import android.content.pm.PackageParser;
 import android.content.pm.ParceledListSlice;
 import android.content.pm.PermissionInfo;
 import android.content.pm.ProcessInfo;
@@ -223,6 +224,7 @@
 import android.content.pm.ServiceInfo;
 import android.content.pm.TestUtilityService;
 import android.content.pm.UserInfo;
+import android.content.pm.parsing.ParsingPackageUtils;
 import android.content.res.CompatibilityInfo;
 import android.content.res.Configuration;
 import android.content.res.Resources;
@@ -253,11 +255,11 @@
 import android.os.Message;
 import android.os.Parcel;
 import android.os.ParcelFileDescriptor;
+import android.os.PowerExemptionManager.ReasonCode;
+import android.os.PowerExemptionManager.TempAllowListType;
 import android.os.PowerManager;
 import android.os.PowerManager.ServiceType;
 import android.os.PowerManagerInternal;
-import android.os.PowerWhitelistManager.ReasonCode;
-import android.os.PowerWhitelistManager.TempAllowListType;
 import android.os.Process;
 import android.os.RemoteCallback;
 import android.os.RemoteException;
@@ -339,7 +341,11 @@
 import com.android.internal.util.MemInfoReader;
 import com.android.internal.util.Preconditions;
 import com.android.internal.util.function.HeptFunction;
+import com.android.internal.util.function.HexFunction;
+import com.android.internal.util.function.OctFunction;
 import com.android.internal.util.function.QuadFunction;
+import com.android.internal.util.function.QuintFunction;
+import com.android.internal.util.function.TriFunction;
 import com.android.server.AlarmManagerInternal;
 import com.android.server.DeviceIdleInternal;
 import com.android.server.DisplayThread;
@@ -366,6 +372,7 @@
 import com.android.server.job.JobSchedulerInternal;
 import com.android.server.os.NativeTombstoneManager;
 import com.android.server.pm.Installer;
+import com.android.server.pm.parsing.pkg.AndroidPackage;
 import com.android.server.pm.permission.PermissionManagerServiceInternal;
 import com.android.server.uri.GrantUri;
 import com.android.server.uri.NeededUriGrants;
@@ -1122,24 +1129,6 @@
     CoreSettingsObserver mCoreSettingsObserver;
 
     /**
-     * Thread-local storage used to carry caller permissions over through
-     * indirect content-provider access.
-     */
-    private class Identity {
-        public final IBinder token;
-        public final int pid;
-        public final int uid;
-
-        Identity(IBinder _token, int _pid, int _uid) {
-            token = _token;
-            pid = _pid;
-            uid = _uid;
-        }
-    }
-
-    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
-
-    /**
      * All information we have collected about the runtime performance of
      * any user id that can impact battery performance.
      */
@@ -2603,8 +2592,8 @@
     }
 
     @GuardedBy("this")
-    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
-        return mProcessList.getProcessRecordLocked(processName, uid, keepIfLarge);
+    final ProcessRecord getProcessRecordLocked(String processName, int uid) {
+        return mProcessList.getProcessRecordLocked(processName, uid);
     }
 
     @GuardedBy(anyOf = {"this", "mProcLock"})
@@ -2638,8 +2627,7 @@
                     false /* knownToBeDead */, 0 /* intentFlags */,
                     sNullHostingRecord  /* hostingRecord */, ZYGOTE_POLICY_FLAG_EMPTY,
                     true /* allowWhileBooting */, true /* isolated */,
-                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
-                    crashHandler);
+                    uid, abiOverride, entryPoint, entryPointArgs, crashHandler);
             return proc != null;
         }
     }
@@ -2648,10 +2636,10 @@
     final ProcessRecord startProcessLocked(String processName,
             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
             HostingRecord hostingRecord, int zygotePolicyFlags, boolean allowWhileBooting,
-            boolean isolated, boolean keepIfLarge) {
+            boolean isolated) {
         return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
                 hostingRecord, zygotePolicyFlags, allowWhileBooting, isolated, 0 /* isolatedUid */,
-                keepIfLarge, null /* ABI override */, null /* entryPoint */,
+                null /* ABI override */, null /* entryPoint */,
                 null /* entryPointArgs */, null /* crashHandler */);
     }
 
@@ -2970,9 +2958,9 @@
      */
     @GuardedBy("this")
     final void handleAppDiedLocked(ProcessRecord app, int pid,
-            boolean restarting, boolean allowRestart) {
+            boolean restarting, boolean allowRestart, boolean fromBinderDied) {
         boolean kept = cleanUpApplicationRecordLocked(app, pid, restarting, allowRestart, -1,
-                false /*replacingPid*/);
+                false /*replacingPid*/, fromBinderDied);
         if (!kept && !restarting) {
             removeLruProcessLocked(app);
             if (pid > 0) {
@@ -3030,12 +3018,15 @@
     final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
             boolean fromBinderDied, String reason) {
         // First check if this ProcessRecord is actually active for the pid.
+        final ProcessRecord curProc;
         synchronized (mPidsSelfLocked) {
-            ProcessRecord curProc = mPidsSelfLocked.get(pid);
-            if (curProc != app) {
+            curProc = mPidsSelfLocked.get(pid);
+        }
+        if (curProc != app) {
+            if (!fromBinderDied || !mProcessList.handleDyingAppDeathLocked(app, pid)) {
                 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
-                return;
             }
+            return;
         }
 
         mBatteryStatsService.noteProcessDied(app.info.uid, pid);
@@ -3075,7 +3066,7 @@
             EventLogTags.writeAmProcDied(app.userId, pid, app.processName, setAdj, setProcState);
             if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
                 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
-            handleAppDiedLocked(app, pid, false, true);
+            handleAppDiedLocked(app, pid, false, true, fromBinderDied);
 
             if (doOomAdj) {
                 updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_PROCESS_END);
@@ -3490,7 +3481,9 @@
 
                     // Clear its scheduled jobs
                     JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
-                    js.cancelJobsForUid(appInfo.uid, "clear data");
+                    // Clearing data is akin to uninstalling. The app is force stopped before we
+                    // get to this point, so the reason won't be checked by the app.
+                    js.cancelJobsForUid(appInfo.uid, JobParameters.STOP_REASON_USER, "clear data");
 
                     // Clear its pending alarms
                     AlarmManagerInternal ami = LocalServices.getService(AlarmManagerInternal.class);
@@ -3902,7 +3895,7 @@
         // Only the system server can kill an application
         if (callerUid == SYSTEM_UID) {
             synchronized (this) {
-                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
+                ProcessRecord app = getProcessRecordLocked(processName, uid);
                 IApplicationThread thread;
                 if (app != null && (thread = app.getThread()) != null) {
                     try {
@@ -4230,7 +4223,7 @@
                 EventLog.writeEvent(0x534e4554, "131105245", app.getStartUid(), msg);
                 // If there is already an app occupying that pid that hasn't been cleaned up
                 cleanUpApplicationRecordLocked(app, pid, false, false, -1,
-                        true /*replacingPid*/);
+                        true /*replacingPid*/, false /* fromBinderDied */);
                 removePidLocked(pid, app);
                 app = null;
             }
@@ -4272,7 +4265,7 @@
         // If this application record is still attached to a previous
         // process, clean it up now.
         if (app.getThread() != null) {
-            handleAppDiedLocked(app, pid, true, true);
+            handleAppDiedLocked(app, pid, true, true, false /* fromBinderDied */);
         }
 
         // Tell the process all about itself.
@@ -4475,7 +4468,7 @@
             app.unlinkDeathRecipient();
             app.killLocked("error during bind", ApplicationExitInfo.REASON_INITIALIZATION_FAILURE,
                     true);
-            handleAppDiedLocked(app, pid, false, true);
+            handleAppDiedLocked(app, pid, false, true, false /* fromBinderDied */);
             return false;
         }
 
@@ -4540,7 +4533,7 @@
         if (badApp) {
             app.killLocked("error during init", ApplicationExitInfo.REASON_INITIALIZATION_FAILURE,
                     true);
-            handleAppDiedLocked(app, pid, false, true);
+            handleAppDiedLocked(app, pid, false, true, false /* fromBinderDied */);
             return false;
         }
 
@@ -5339,26 +5332,6 @@
         return checkComponentPermission(permission, pid, uid, -1, true);
     }
 
-    @Override
-    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
-        if (permission == null) {
-            return PackageManager.PERMISSION_DENIED;
-        }
-
-        // We might be performing an operation on behalf of an indirect binder
-        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
-        // client identity accordingly before proceeding.
-        Identity tlsIdentity = sCallerIdentity.get();
-        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
-            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
-                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
-            uid = tlsIdentity.uid;
-            pid = tlsIdentity.pid;
-        }
-
-        return checkComponentPermission(permission, pid, uid, -1, true);
-    }
-
     /**
      * Binder IPC calls go through the public entry point.
      * This can be called with or without the global lock held.
@@ -5613,14 +5586,6 @@
             final int modeFlags, int userId, IBinder callerToken) {
         enforceNotIsolatedCaller("checkUriPermission");
 
-        // Another redirected-binder-call permissions check as in
-        // {@link checkPermissionWithToken}.
-        Identity tlsIdentity = sCallerIdentity.get();
-        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
-            uid = tlsIdentity.uid;
-            pid = tlsIdentity.pid;
-        }
-
         // Our own process gets to do everything.
         if (pid == MY_PID) {
             return PackageManager.PERMISSION_GRANTED;
@@ -6098,7 +6063,7 @@
         ProcessRecord app;
         if (!isolated) {
             app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
-                    info.uid, true);
+                    info.uid);
         } else {
             app = null;
         }
@@ -6154,23 +6119,22 @@
                 Binder.getCallingUid(), "*opencontent*", userId);
         ParcelFileDescriptor pfd = null;
         if (cph != null) {
-            // We record the binder invoker's uid in thread-local storage before
-            // going to the content provider to open the file.  Later, in the code
-            // that handles all permissions checks, we look for this uid and use
-            // that rather than the Activity Manager's own uid.  The effect is that
-            // we do the check against the caller's permissions even though it looks
-            // to the content provider like the Activity Manager itself is making
-            // the request.
-            Binder token = new Binder();
-            sCallerIdentity.set(new Identity(
-                    token, Binder.getCallingPid(), Binder.getCallingUid()));
             try {
-                pfd = cph.provider.openFile(null, null, uri, "r", null, token);
+                // This method is exposed to the VNDK and to avoid changing its
+                // signature we just use the first package in the UID. For shared
+                // UIDs we may blame the wrong app but that is Okay as they are
+                // in the same security/privacy sandbox.
+                final AndroidPackage androidPackage = mPackageManagerInt
+                        .getPackage(Binder.getCallingUid());
+                if (androidPackage == null) {
+                    return null;
+                }
+                final AttributionSource attributionSource = new AttributionSource(
+                        Binder.getCallingUid(), androidPackage.getPackageName(), null);
+                pfd = cph.provider.openFile(attributionSource, uri, "r", null);
             } catch (FileNotFoundException e) {
                 // do nothing; pfd will be returned null
             } finally {
-                // Ensure that whatever happens, we clean up the identity state
-                sCallerIdentity.remove();
                 // Ensure we're done with the provider.
                 mCpHelper.removeContentProviderExternalUnchecked(name, null, userId);
             }
@@ -7703,9 +7667,8 @@
      */
     void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
             ApplicationErrorReport.CrashInfo crashInfo) {
-        boolean isIncremental = false;
         float loadingProgress = 1;
-        long millisSinceOldestPendingRead = 0;
+        IncrementalMetrics incrementalMetrics = null;
         // Notify package manager service to possibly update package state
         if (r != null && r.info != null && r.info.packageName != null) {
             final String codePath = r.info.getCodePath();
@@ -7716,8 +7679,7 @@
             if (incrementalStatesInfo != null) {
                 loadingProgress = incrementalStatesInfo.getProgress();
             }
-            isIncremental = IncrementalManager.isIncrementalPath(codePath);
-            if (isIncremental) {
+            if (IncrementalManager.isIncrementalPath(codePath)) {
                 // Report in the main log about the incremental package
                 Slog.e(TAG, "App crashed on incremental package " + r.info.packageName
                         + " which is " + ((int) (loadingProgress * 100)) + "% loaded.");
@@ -7726,8 +7688,7 @@
                 if (incrementalService != null) {
                     final IncrementalManager incrementalManager = new IncrementalManager(
                             IIncrementalService.Stub.asInterface(incrementalService));
-                    IncrementalMetrics metrics = incrementalManager.getMetrics(codePath);
-                    millisSinceOldestPendingRead = metrics.getMillisSinceOldestPendingRead();
+                    incrementalMetrics = incrementalManager.getMetrics(codePath);
                 }
             }
         }
@@ -7757,7 +7718,9 @@
                 processName.equals("system_server") ? ServerProtoEnums.SYSTEM_SERVER
                         : (r != null) ? r.getProcessClassEnum()
                                       : ServerProtoEnums.ERROR_SOURCE_UNKNOWN,
-                isIncremental, loadingProgress, millisSinceOldestPendingRead
+                incrementalMetrics != null /* isIncremental */, loadingProgress,
+                incrementalMetrics != null ? incrementalMetrics.getMillisSinceOldestPendingRead()
+                        : -1
         );
 
         final int relaunchReason = r == null ? RELAUNCH_REASON_NONE
@@ -7770,7 +7733,8 @@
         }
 
         addErrorToDropBox(
-                eventType, r, processName, null, null, null, null, null, null, crashInfo);
+                eventType, r, processName, null, null, null, null, null, null, crashInfo,
+                new Float(loadingProgress), incrementalMetrics);
 
         mAppErrors.crashApplication(r, crashInfo);
     }
@@ -7952,7 +7916,8 @@
         FrameworkStatsLog.write(FrameworkStatsLog.WTF_OCCURRED, callingUid, tag, processName,
                 callingPid, (r != null) ? r.getProcessClassEnum() : 0);
 
-        addErrorToDropBox("wtf", r, processName, null, null, null, tag, null, null, crashInfo);
+        addErrorToDropBox("wtf", r, processName, null, null, null, tag, null, null, crashInfo,
+                null, null);
 
         return r;
     }
@@ -7977,7 +7942,7 @@
         for (Pair<String, ApplicationErrorReport.CrashInfo> p = list.poll();
                 p != null; p = list.poll()) {
             addErrorToDropBox("wtf", proc, "system_server", null, null, null, p.first, null, null,
-                    p.second);
+                    p.second, null, null);
         }
     }
 
@@ -8066,12 +8031,15 @@
      * @param report in long form describing the error, null if absent
      * @param dataFile text file to include in the report, null if none
      * @param crashInfo giving an application stack trace, null if absent
+     * @param loadingProgress the loading progress of an installed package, range in [0, 1].
+     * @param incrementalMetrics metrics for apps installed on Incremental.
      */
     public void addErrorToDropBox(String eventType,
             ProcessRecord process, String processName, String activityShortComponentName,
             String parentShortComponentName, ProcessRecord parentProcess,
             String subject, final String report, final File dataFile,
-            final ApplicationErrorReport.CrashInfo crashInfo) {
+            final ApplicationErrorReport.CrashInfo crashInfo,
+            @Nullable Float loadingProgress, @Nullable IncrementalMetrics incrementalMetrics) {
         // NOTE -- this must never acquire the ActivityManagerService lock,
         // otherwise the watchdog may be prevented from resetting the system.
 
@@ -8132,6 +8100,18 @@
         if (crashInfo != null && crashInfo.crashTag != null && !crashInfo.crashTag.isEmpty()) {
             sb.append("Crash-Tag: ").append(crashInfo.crashTag).append("\n");
         }
+        if (loadingProgress != null) {
+            sb.append("Loading-Progress: ").append(loadingProgress.floatValue()).append("\n");
+        }
+        if (incrementalMetrics != null) {
+            sb.append("Incremental: Yes").append("\n");
+            final long millisSinceOldestPendingRead =
+                    incrementalMetrics.getMillisSinceOldestPendingRead();
+            if (millisSinceOldestPendingRead > 0) {
+                sb.append("Millis-Since-Oldest-Pending-Read: ").append(
+                        millisSinceOldestPendingRead).append("\n");
+            }
+        }
         sb.append("\n");
 
         // Do the rest in a worker thread to avoid blocking the caller on I/O
@@ -11482,7 +11462,8 @@
      */
     @GuardedBy("this")
     final boolean cleanUpApplicationRecordLocked(ProcessRecord app, int pid,
-            boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
+            boolean restarting, boolean allowRestart, int index, boolean replacingPid,
+            boolean fromBinderDied) {
         boolean restart;
         synchronized (mProcLock) {
             if (index >= 0) {
@@ -11490,7 +11471,10 @@
                 ProcessList.remove(pid);
             }
 
-            restart = app.onCleanupApplicationRecordLSP(mProcessStats, allowRestart);
+            // We don't want to unlinkDeathRecipient immediately, if it's not called from binder
+            // and it's not isolated, as we'd need the signal to bookkeeping the dying process list.
+            restart = app.onCleanupApplicationRecordLSP(mProcessStats, allowRestart,
+                    fromBinderDied || app.isolated /* unlinkDeath */);
         }
         mAppProfiler.onCleanupApplicationRecordLocked(app);
         skipCurrentReceiverLocked(app);
@@ -11520,25 +11504,7 @@
         mProcessList.scheduleDispatchProcessDiedLocked(pid, app.info.uid);
 
         // If this is a preceding instance of another process instance
-        allowRestart = true;
-        synchronized (app) {
-            if (app.mSuccessor != null) {
-                // We don't allow restart with this ProcessRecord now,
-                // because we have created a new one already.
-                allowRestart = false;
-                // If it's persistent, add the successor to mPersistentStartingProcesses
-                if (app.isPersistent() && !app.isRemoved()) {
-                    if (mPersistentStartingProcesses.indexOf(app.mSuccessor) < 0) {
-                        mPersistentStartingProcesses.add(app.mSuccessor);
-                    }
-                }
-                // clean up the field so the successor's proc starter could proceed.
-                app.mSuccessor.mPredecessor = null;
-                app.mSuccessor = null;
-                // Notify if anyone is waiting for it.
-                app.notifyAll();
-            }
-        }
+        allowRestart = mProcessList.handlePrecedingAppDiedLocked(app);
 
         // If the caller is restarting this app, then leave it in its
         // current lists and let the caller take care of it.
@@ -11914,7 +11880,7 @@
             ProcessRecord proc = startProcessLocked(app.processName, app,
                     false, 0,
                     new HostingRecord("backup", hostingName),
-                    ZYGOTE_POLICY_FLAG_SYSTEM_PROCESS, false, false, false);
+                    ZYGOTE_POLICY_FLAG_SYSTEM_PROCESS, false, false);
             if (proc == null) {
                 Slog.e(TAG, "Unable to start backup agent process " + r);
                 return false;
@@ -13624,7 +13590,7 @@
             ProcessRecord app;
             synchronized (mProcLock) {
                 if (noRestart) {
-                    app = getProcessRecordLocked(ai.processName, ai.uid, true);
+                    app = getProcessRecordLocked(ai.processName, ai.uid);
                 } else {
                     // Instrumentation can kill and relaunch even persistent processes
                     forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false,
@@ -13667,7 +13633,7 @@
             ApplicationInfo targetInfo) {
         ProcessRecord pr;
         synchronized (this) {
-            pr = getProcessRecordLocked(targetInfo.processName, targetInfo.uid, true);
+            pr = getProcessRecordLocked(targetInfo.processName, targetInfo.uid);
         }
 
         try {
@@ -14634,7 +14600,8 @@
                     }
                 }
                 didSomething = true;
-                cleanUpApplicationRecordLocked(app, pid, false, true, -1, false /*replacingPid*/);
+                cleanUpApplicationRecordLocked(app, pid, false, true, -1, false /*replacingPid*/,
+                        false /* fromBinderDied */);
                 mProcessList.mRemovedProcesses.remove(i);
 
                 if (app.isPersistent()) {
@@ -15414,8 +15381,7 @@
         @Override
         public void killProcess(String processName, int uid, String reason) {
             synchronized (ActivityManagerService.this) {
-                final ProcessRecord proc = getProcessRecordLocked(processName, uid,
-                        true /* keepIfLarge */);
+                final ProcessRecord proc = getProcessRecordLocked(processName, uid);
                 if (proc != null) {
                     mProcessList.removeProcessLocked(proc, false /* callerWillRestart */,
                             true /* allowRestart */,  ApplicationExitInfo.REASON_OTHER, reason);
@@ -15822,7 +15788,7 @@
                     startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,
                             new HostingRecord(hostingType, hostingName, isTop),
                             ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE, false /* allowWhileBooting */,
-                            false /* isolated */, true /* keepIfLarge */);
+                            false /* isolated */);
                 }
             } finally {
                 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
@@ -16282,7 +16248,7 @@
     private void updateApplicationInfoLOSP(@NonNull List<String> packagesToUpdate, int userId) {
         final boolean updateFrameworkRes = packagesToUpdate.contains("android");
         if (updateFrameworkRes) {
-            PackageParser.readConfigUseRoundIcon(null);
+            ParsingPackageUtils.readConfigUseRoundIcon(null);
         }
         mProcessList.updateApplicationInfoLOSP(packagesToUpdate, userId, updateFrameworkRes);
 
@@ -16632,6 +16598,74 @@
                     message, shouldCollectMessage);
         }
 
+        @Override
+        public int noteProxyOperation(int code, @NonNull AttributionSource attributionSource,
+                boolean shouldCollectAsyncNotedOp, @Nullable String message,
+                boolean shouldCollectMessage, boolean skiProxyOperation,
+                @NonNull HexFunction<Integer, AttributionSource, Boolean, String, Boolean,
+                                Boolean, Integer> superImpl) {
+            if (attributionSource.getUid() == mTargetUid && isTargetOp(code)) {
+                final int shellUid = UserHandle.getUid(UserHandle.getUserId(
+                        attributionSource.getUid()), Process.SHELL_UID);
+                final long identity = Binder.clearCallingIdentity();
+                try {
+                    return superImpl.apply(code, new AttributionSource(shellUid,
+                            "com.android.shell", attributionSource.getAttributionTag(),
+                            attributionSource.getNext()),
+                            shouldCollectAsyncNotedOp, message, shouldCollectMessage,
+                            skiProxyOperation);
+                } finally {
+                    Binder.restoreCallingIdentity(identity);
+                }
+            }
+            return superImpl.apply(code, attributionSource, shouldCollectAsyncNotedOp,
+                    message, shouldCollectMessage, skiProxyOperation);
+        }
+
+        @Override
+        public int startProxyOperation(IBinder token, int code,
+                @NonNull AttributionSource attributionSource, boolean startIfModeDefault,
+                boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage,
+                boolean skipProsyOperation, @NonNull OctFunction<IBinder, Integer,
+                        AttributionSource, Boolean, Boolean, String, Boolean, Boolean,
+                        Integer> superImpl) {
+            if (attributionSource.getUid() == mTargetUid && isTargetOp(code)) {
+                final int shellUid = UserHandle.getUid(UserHandle.getUserId(
+                        attributionSource.getUid()), Process.SHELL_UID);
+                final long identity = Binder.clearCallingIdentity();
+                try {
+                    return superImpl.apply(token, code, new AttributionSource(shellUid,
+                                    "com.android.shell", attributionSource.getAttributionTag(),
+                                    attributionSource.getNext()), startIfModeDefault,
+                            shouldCollectAsyncNotedOp, message, shouldCollectMessage,
+                            skipProsyOperation);
+                } finally {
+                    Binder.restoreCallingIdentity(identity);
+                }
+            }
+            return superImpl.apply(token, code, attributionSource, startIfModeDefault,
+                    shouldCollectAsyncNotedOp, message, shouldCollectMessage, skipProsyOperation);
+        }
+
+        @Override
+        public void finishProxyOperation(IBinder clientId, int code,
+                @NonNull AttributionSource attributionSource,
+                @NonNull TriFunction<IBinder, Integer, AttributionSource, Void> superImpl) {
+            if (attributionSource.getUid() == mTargetUid && isTargetOp(code)) {
+                final int shellUid = UserHandle.getUid(UserHandle.getUserId(
+                        attributionSource.getUid()), Process.SHELL_UID);
+                final long identity = Binder.clearCallingIdentity();
+                try {
+                    superImpl.apply(clientId, code, new AttributionSource(shellUid,
+                            "com.android.shell", attributionSource.getAttributionTag(),
+                            attributionSource.getNext()));
+                } finally {
+                    Binder.restoreCallingIdentity(identity);
+                }
+            }
+            superImpl.apply(clientId, code, attributionSource);
+        }
+
         private boolean isTargetOp(int code) {
             // null permissions means all ops are targeted
             if (mPermissions == null) {
diff --git a/services/core/java/com/android/server/am/AppProfiler.java b/services/core/java/com/android/server/am/AppProfiler.java
index 31ea14a..074e8fe 100644
--- a/services/core/java/com/android/server/am/AppProfiler.java
+++ b/services/core/java/com/android/server/am/AppProfiler.java
@@ -1627,7 +1627,7 @@
         dropBuilder.append(catSw.toString());
         FrameworkStatsLog.write(FrameworkStatsLog.LOW_MEM_REPORTED);
         mService.addErrorToDropBox("lowmem", null, "system_server", null,
-                null, null, tag.toString(), dropBuilder.toString(), null, null);
+                null, null, tag.toString(), dropBuilder.toString(), null, null, null, null);
         synchronized (mService) {
             long now = SystemClock.uptimeMillis();
             if (mLastMemUsageReportTime < now) {
diff --git a/services/core/java/com/android/server/am/AssistDataRequester.java b/services/core/java/com/android/server/am/AssistDataRequester.java
index d8d6528..70a54cf 100644
--- a/services/core/java/com/android/server/am/AssistDataRequester.java
+++ b/services/core/java/com/android/server/am/AssistDataRequester.java
@@ -143,27 +143,45 @@
      * Request that autofill data be loaded asynchronously. The resulting data will be provided
      * through the {@link AssistDataRequesterCallbacks}.
      *
-     * See {@link #requestData(List, boolean, boolean, boolean, boolean, boolean, int, String)}.
+     * See {@link #requestData(List, boolean, boolean, boolean, boolean, boolean, int, String,
+     * boolean)}.
      */
     public void requestAutofillData(List<IBinder> activityTokens, int callingUid,
             String callingPackage) {
         requestData(activityTokens, true /* requestAutofillData */,
                 true /* fetchData */, false /* fetchScreenshot */,
                 true /* allowFetchData */, false /* allowFetchScreenshot */,
-                callingUid, callingPackage);
+                false /* ignoreTopActivityCheck */, callingUid, callingPackage);
     }
 
     /**
      * Request that assist data be loaded asynchronously. The resulting data will be provided
      * through the {@link AssistDataRequesterCallbacks}.
      *
-     * See {@link #requestData(List, boolean, boolean, boolean, boolean, boolean, int, String)}.
+     * See {@link #requestData(List, boolean, boolean, boolean, boolean, boolean, int, String,
+     * boolean)}.
      */
     public void requestAssistData(List<IBinder> activityTokens, final boolean fetchData,
             final boolean fetchScreenshot, boolean allowFetchData, boolean allowFetchScreenshot,
             int callingUid, String callingPackage) {
+        requestAssistData(activityTokens, fetchData, fetchScreenshot, allowFetchData,
+                allowFetchScreenshot, false /* ignoreTopActivityCheck */, callingUid,
+                callingPackage);
+    }
+
+    /**
+     * Request that assist data be loaded asynchronously. The resulting data will be provided
+     * through the {@link AssistDataRequesterCallbacks}.
+     *
+     * See {@link #requestData(List, boolean, boolean, boolean, boolean, boolean, int, String,
+     * boolean)}.
+     */
+    public void requestAssistData(List<IBinder> activityTokens, final boolean fetchData,
+            final boolean fetchScreenshot, boolean allowFetchData, boolean allowFetchScreenshot,
+            boolean ignoreTopActivityCheck, int callingUid, String callingPackage) {
         requestData(activityTokens, false /* requestAutofillData */, fetchData, fetchScreenshot,
-                allowFetchData, allowFetchScreenshot, callingUid, callingPackage);
+                allowFetchData, allowFetchScreenshot, ignoreTopActivityCheck, callingUid,
+                callingPackage);
     }
 
     /**
@@ -183,10 +201,13 @@
      *     is allowed to fetch the assist data
      * @param allowFetchScreenshot to be joined with other checks, determines whether or not the
      *     requester is allowed to fetch the assist screenshot
+     * @param ignoreTopActivityCheck overrides the check for whether the activity is in focus when
+     *     making the request. Used when passing an activity from Recents.
      */
     private void requestData(List<IBinder> activityTokens, final boolean requestAutofillData,
             final boolean fetchData, final boolean fetchScreenshot, boolean allowFetchData,
-            boolean allowFetchScreenshot, int callingUid, String callingPackage) {
+            boolean allowFetchScreenshot, boolean ignoreTopActivityCheck, int callingUid,
+            String callingPackage) {
         // TODO(b/34090158): Known issue, if the assist data is not allowed on the current activity,
         //                   then no assist data is requested for any of the other activities
 
@@ -230,7 +251,8 @@
                                         receiverExtras, topActivity, 0 /* flags */)
                                 : mActivityTaskManager.requestAssistContextExtras(
                                         ASSIST_CONTEXT_FULL, this, receiverExtras, topActivity,
-                                        /* focused= */ i == 0, /* newSessionId= */ i == 0);
+                                        /* checkActivityIsTop= */ (i == 0)
+                                        && !ignoreTopActivityCheck, /* newSessionId= */ i == 0);
                         if (result) {
                             mPendingDataCount++;
                         } else if (i == 0) {
diff --git a/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java b/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java
index e74c936..60e8d54 100644
--- a/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java
+++ b/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java
@@ -487,8 +487,10 @@
                 Slog.wtf(TAG, "Error updating external stats: ", e);
             }
 
-            synchronized (BatteryExternalStatsWorker.this) {
-                mLastCollectionTimeStamp = SystemClock.elapsedRealtime();
+            if ((updateFlags & UPDATE_ALL) == UPDATE_ALL) {
+                synchronized (BatteryExternalStatsWorker.this) {
+                    mLastCollectionTimeStamp = SystemClock.elapsedRealtime();
+                }
             }
         }
     };
@@ -658,6 +660,11 @@
                     mStats.updateDisplayMeasuredEnergyStatsLocked(displayChargeUC, screenState,
                             elapsedRealtime);
                 }
+
+                final long gnssChargeUC = measuredEnergyDeltas.gnssChargeUC;
+                if (gnssChargeUC != MeasuredEnergySnapshot.UNAVAILABLE) {
+                    mStats.updateGnssMeasuredEnergyStatsLocked(displayChargeUC, elapsedRealtime);
+                }
             }
             // Inform mStats about each applicable custom energy bucket.
             if (measuredEnergyDeltas != null
@@ -698,7 +705,10 @@
         }
 
         if (modemInfo != null) {
-            mStats.noteModemControllerActivity(modemInfo, elapsedRealtime, uptime);
+            final long mobileRadioChargeUC = measuredEnergyDeltas != null
+                    ? measuredEnergyDeltas.mobileRadioChargeUC : MeasuredEnergySnapshot.UNAVAILABLE;
+            mStats.noteModemControllerActivity(modemInfo, mobileRadioChargeUC, elapsedRealtime,
+                    uptime);
         }
 
         if (updateFlags == UPDATE_ALL) {
@@ -830,6 +840,12 @@
                 case EnergyConsumerType.CPU_CLUSTER:
                     buckets[MeasuredEnergyStats.POWER_BUCKET_CPU] = true;
                     break;
+                case EnergyConsumerType.GNSS:
+                    buckets[MeasuredEnergyStats.POWER_BUCKET_GNSS] = true;
+                    break;
+                case EnergyConsumerType.MOBILE_RADIO:
+                    buckets[MeasuredEnergyStats.POWER_BUCKET_MOBILE_RADIO] = true;
+                    break;
                 case EnergyConsumerType.DISPLAY:
                     buckets[MeasuredEnergyStats.POWER_BUCKET_SCREEN_ON] = true;
                     buckets[MeasuredEnergyStats.POWER_BUCKET_SCREEN_DOZE] = true;
@@ -883,6 +899,9 @@
         if ((flags & UPDATE_DISPLAY) != 0) {
             addEnergyConsumerIdLocked(energyConsumerIds, EnergyConsumerType.DISPLAY);
         }
+        if ((flags & UPDATE_RADIO) != 0) {
+            addEnergyConsumerIdLocked(energyConsumerIds, EnergyConsumerType.MOBILE_RADIO);
+        }
         if ((flags & UPDATE_WIFI) != 0) {
             addEnergyConsumerIdLocked(energyConsumerIds, EnergyConsumerType.WIFI);
         }
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index c3f97ad..5937a18 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -674,6 +674,13 @@
     public List<BatteryUsageStats> getBatteryUsageStats(List<BatteryUsageStatsQuery> queries) {
         mContext.enforceCallingPermission(
                 android.Manifest.permission.BATTERY_STATS, null);
+        awaitCompletion();
+
+        if (mBatteryUsageStatsProvider.shouldUpdateStats(queries,
+                mWorker.getLastCollectionTimeStamp())) {
+            syncStats("get-stats", BatteryExternalStatsWorker.UPDATE_ALL);
+        }
+
         return mBatteryUsageStatsProvider.getBatteryUsageStats(queries);
     }
 
@@ -1966,7 +1973,8 @@
             final long elapsedRealtime = SystemClock.elapsedRealtime();
             final long uptime = SystemClock.uptimeMillis();
             mHandler.post(() -> {
-                mStats.noteModemControllerActivity(info, elapsedRealtime, uptime);
+                mStats.noteModemControllerActivity(info, POWER_DATA_UNAVAILABLE, elapsedRealtime,
+                        uptime);
             });
         }
     }
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index e79f096..7f2eae8 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -45,8 +45,8 @@
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
-import android.os.PowerWhitelistManager;
-import android.os.PowerWhitelistManager.TempAllowListType;
+import android.os.PowerExemptionManager.ReasonCode;
+import android.os.PowerExemptionManager.TempAllowListType;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.SystemClock;
@@ -908,7 +908,7 @@
     }
 
     final void scheduleTempAllowlistLocked(int uid, long duration, BroadcastRecord r,
-            @TempAllowListType int type, @PowerWhitelistManager.ReasonCode int reasonCode,
+            @TempAllowListType int type, @ReasonCode int reasonCode,
             @Nullable String reason) {
         if (duration > Integer.MAX_VALUE) {
             duration = Integer.MAX_VALUE;
@@ -1544,7 +1544,7 @@
         }
         String targetProcess = info.activityInfo.processName;
         ProcessRecord app = mService.getProcessRecordLocked(targetProcess,
-                info.activityInfo.applicationInfo.uid, false);
+                info.activityInfo.applicationInfo.uid);
 
         if (!skip) {
             final int allowed = mService.getAppStartModeLOSP(
@@ -1678,7 +1678,7 @@
                 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
                 new HostingRecord("broadcast", r.curComponent), isActivityCapable
                 ? ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE : ZYGOTE_POLICY_FLAG_EMPTY,
-                (r.intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0, false, false);
+                (r.intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0, false);
         if (r.curApp == null) {
             // Ah, this recipient is unavailable.  Finish it if necessary,
             // and mark the broadcast record as ready for the next.
diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java
index c5f082a..1839e2a 100644
--- a/services/core/java/com/android/server/am/CachedAppOptimizer.java
+++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java
@@ -382,10 +382,13 @@
     @GuardedBy("mProcLock")
     void compactAppSome(ProcessRecord app) {
         app.mOptRecord.setReqCompactAction(COMPACT_PROCESS_SOME);
-        mPendingCompactionProcesses.add(app);
-        mCompactionHandler.sendMessage(
-                mCompactionHandler.obtainMessage(
-                COMPACT_PROCESS_MSG, app.mState.getSetAdj(), app.mState.getSetProcState()));
+        if (!app.mOptRecord.hasPendingCompact()) {
+            app.mOptRecord.setHasPendingCompact(true);
+            mPendingCompactionProcesses.add(app);
+            mCompactionHandler.sendMessage(
+                    mCompactionHandler.obtainMessage(
+                    COMPACT_PROCESS_MSG, app.mState.getSetAdj(), app.mState.getSetProcState()));
+        }
     }
 
     @GuardedBy("mProcLock")
@@ -396,10 +399,13 @@
                 && app.mState.getCurAdj() >= mCompactThrottleMinOomAdj
                 && app.mState.getCurAdj() <= mCompactThrottleMaxOomAdj) {
             app.mOptRecord.setReqCompactAction(COMPACT_PROCESS_FULL);
-            mPendingCompactionProcesses.add(app);
-            mCompactionHandler.sendMessage(
-                mCompactionHandler.obtainMessage(
-                    COMPACT_PROCESS_MSG, app.mState.getSetAdj(), app.mState.getSetProcState()));
+            if (!app.mOptRecord.hasPendingCompact()) {
+                app.mOptRecord.setHasPendingCompact(true);
+                mPendingCompactionProcesses.add(app);
+                mCompactionHandler.sendMessage(
+                        mCompactionHandler.obtainMessage(
+                        COMPACT_PROCESS_MSG, app.mState.getSetAdj(), app.mState.getSetProcState()));
+            }
         } else {
             if (DEBUG_COMPACTION) {
                 Slog.d(TAG_AM, "Skipping full compaction for " + app.processName
@@ -412,10 +418,13 @@
     @GuardedBy("mProcLock")
     void compactAppPersistent(ProcessRecord app) {
         app.mOptRecord.setReqCompactAction(COMPACT_PROCESS_PERSISTENT);
-        mPendingCompactionProcesses.add(app);
-        mCompactionHandler.sendMessage(
-                mCompactionHandler.obtainMessage(
+        if (!app.mOptRecord.hasPendingCompact()) {
+            app.mOptRecord.setHasPendingCompact(true);
+            mPendingCompactionProcesses.add(app);
+            mCompactionHandler.sendMessage(
+                    mCompactionHandler.obtainMessage(
                     COMPACT_PROCESS_MSG, app.mState.getCurAdj(), app.mState.getSetProcState()));
+        }
     }
 
     @GuardedBy("mProcLock")
@@ -427,10 +436,13 @@
     @GuardedBy("mProcLock")
     void compactAppBfgs(ProcessRecord app) {
         app.mOptRecord.setReqCompactAction(COMPACT_PROCESS_BFGS);
-        mPendingCompactionProcesses.add(app);
-        mCompactionHandler.sendMessage(
-                mCompactionHandler.obtainMessage(
+        if (!app.mOptRecord.hasPendingCompact()) {
+            app.mOptRecord.setHasPendingCompact(true);
+            mPendingCompactionProcesses.add(app);
+            mCompactionHandler.sendMessage(
+                    mCompactionHandler.obtainMessage(
                     COMPACT_PROCESS_MSG, app.mState.getCurAdj(), app.mState.getSetProcState()));
+        }
     }
 
     @GuardedBy("mProcLock")
@@ -954,6 +966,7 @@
                         pendingAction = opt.getReqCompactAction();
                         pid = proc.getPid();
                         name = proc.processName;
+                        opt.setHasPendingCompact(false);
 
                         // don't compact if the process has returned to perceptible
                         // and this is only a cached/home/prev compaction
diff --git a/services/core/java/com/android/server/am/ContentProviderHelper.java b/services/core/java/com/android/server/am/ContentProviderHelper.java
index 2c8794d..b44699b 100644
--- a/services/core/java/com/android/server/am/ContentProviderHelper.java
+++ b/services/core/java/com/android/server/am/ContentProviderHelper.java
@@ -33,6 +33,7 @@
 import android.app.ContentProviderHolder;
 import android.app.IApplicationThread;
 import android.app.usage.UsageEvents.Event;
+import android.content.AttributionSource;
 import android.content.ComponentName;
 import android.content.ContentProvider;
 import android.content.ContentResolver;
@@ -42,6 +43,7 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
 import android.content.pm.PathPermission;
 import android.content.pm.ProviderInfo;
 import android.database.ContentObserver;
@@ -67,7 +69,9 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.util.ArrayUtils;
+import com.android.server.LocalServices;
 import com.android.server.RescueParty;
+import com.android.server.pm.parsing.pkg.AndroidPackage;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -436,7 +440,7 @@
                         // Use existing process if already started
                         checkTime(startTime, "getContentProviderImpl: looking for process record");
                         ProcessRecord proc = mService.getProcessRecordLocked(
-                                cpi.processName, cpr.appInfo.uid, false);
+                                cpi.processName, cpr.appInfo.uid);
                         IApplicationThread thread;
                         if (proc != null && (thread = proc.getThread()) != null
                                 && !proc.isKilled()) {
@@ -459,7 +463,7 @@
                                     new HostingRecord("content provider",
                                         new ComponentName(
                                                 cpi.applicationInfo.packageName, cpi.name)),
-                                    Process.ZYGOTE_POLICY_FLAG_EMPTY, false, false, false);
+                                    Process.ZYGOTE_POLICY_FLAG_EMPTY, false, false);
                             checkTime(startTime, "getContentProviderImpl: after start process");
                             if (proc == null) {
                                 Slog.w(TAG, "Unable to launch app "
@@ -1037,7 +1041,19 @@
             holder = getContentProviderExternalUnchecked(name, null, callingUid,
                     "*checkContentProviderUriPermission*", userId);
             if (holder != null) {
-                return holder.provider.checkUriPermission(null, null, uri, callingUid, modeFlags);
+
+                final PackageManagerInternal packageManagerInt = LocalServices.getService(
+                        PackageManagerInternal.class);
+                final AndroidPackage androidPackage = packageManagerInt
+                        .getPackage(Binder.getCallingUid());
+                if (androidPackage == null) {
+                    return PackageManager.PERMISSION_DENIED;
+                }
+
+                final AttributionSource attributionSource = new AttributionSource(
+                        callingUid, androidPackage.getPackageName(), null);
+                return holder.provider.checkUriPermission(attributionSource, uri, callingUid,
+                        modeFlags);
             }
         } catch (RemoteException e) {
             Log.w(TAG, "Content provider dead retrieving " + uri, e);
diff --git a/services/core/java/com/android/server/am/MeasuredEnergySnapshot.java b/services/core/java/com/android/server/am/MeasuredEnergySnapshot.java
index 4c9ab63..f9296a0 100644
--- a/services/core/java/com/android/server/am/MeasuredEnergySnapshot.java
+++ b/services/core/java/com/android/server/am/MeasuredEnergySnapshot.java
@@ -118,6 +118,12 @@
         /** The chargeUC for {@link EnergyConsumerType#DISPLAY}. */
         public long displayChargeUC = UNAVAILABLE;
 
+        /** The chargeUC for {@link EnergyConsumerType#GNSS}. */
+        public long gnssChargeUC = UNAVAILABLE;
+
+        /** The chargeUC for {@link EnergyConsumerType#MOBILE_RADIO}. */
+        public long mobileRadioChargeUC = UNAVAILABLE;
+
         /** The chargeUC for {@link EnergyConsumerType#WIFI}. */
         public long wifiChargeUC = UNAVAILABLE;
 
@@ -217,6 +223,14 @@
                     output.displayChargeUC = deltaChargeUC;
                     break;
 
+                case EnergyConsumerType.GNSS:
+                    output.gnssChargeUC = deltaChargeUC;
+                    break;
+
+                case EnergyConsumerType.MOBILE_RADIO:
+                    output.mobileRadioChargeUC = deltaChargeUC;
+                    break;
+
                 case EnergyConsumerType.WIFI:
                     output.wifiChargeUC = deltaChargeUC;
                     break;
@@ -241,7 +255,7 @@
     /**
      * For a consumer of type {@link EnergyConsumerType#OTHER}, updates
      * {@link #mAttributionSnapshots} with freshly measured energies (per uid) and returns the
-     * charge consumed (in microcouloumbs) between the previously stored values and the passed-in
+     * charge consumed (in microcoulombs) between the previously stored values and the passed-in
      * values.
      *
      * @param consumerInfo a consumer of type {@link EnergyConsumerType#OTHER}.
@@ -341,11 +355,11 @@
         return numOrdinals;
     }
 
-    /** Calculate charge consumption (in microcouloumbs) from a given energy and voltage */
+    /** Calculate charge consumption (in microcoulombs) from a given energy and voltage */
     private long calculateChargeConsumedUC(long deltaEnergyUJ, int avgVoltageMV) {
         // To overflow, a 3.7V 10000mAh battery would need to completely drain 69244 times
-        // since the last snapshot. Round up to the nearest whole long.
-        return (deltaEnergyUJ * MILLIVOLTS_PER_VOLT + (avgVoltageMV + 1) / 2) / avgVoltageMV;
+        // since the last snapshot. Round off to the nearest whole long.
+        return (deltaEnergyUJ * MILLIVOLTS_PER_VOLT + (avgVoltageMV / 2)) / avgVoltageMV;
     }
 
 }
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index 5ae65ef..8ad11d1 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -1997,7 +1997,8 @@
                         // in this case unless they explicitly request it.
                         if ((cstate.getCurCapability() & PROCESS_CAPABILITY_NETWORK) != 0) {
                             if (clientProcState <= PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
-                                if ((cr.flags & Context.BIND_ALLOW_NETWORK_ACCESS) != 0) {
+                                if ((cr.flags & Context.BIND_BYPASS_POWER_NETWORK_RESTRICTIONS)
+                                        != 0) {
                                     capability |= PROCESS_CAPABILITY_NETWORK;
                                 }
                             } else {
diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java
index 51666ac..f7c777e 100644
--- a/services/core/java/com/android/server/am/PendingIntentRecord.java
+++ b/services/core/java/com/android/server/am/PendingIntentRecord.java
@@ -66,7 +66,7 @@
     /**
      * Map IBinder to duration specified as Pair<Long, Integer>, Long is allowlist duration in
      * milliseconds, Integer is allowlist type defined at
-     * {@link android.os.PowerWhitelistManager.TempAllowListType}
+     * {@link android.os.PowerExemptionManager.TempAllowListType}
      */
     private ArrayMap<IBinder, TempAllowListDuration> mAllowlistDuration;
     private RemoteCallbackList<IResultReceiver> mCancelCallbacks;
diff --git a/services/core/java/com/android/server/am/ProcessCachedOptimizerRecord.java b/services/core/java/com/android/server/am/ProcessCachedOptimizerRecord.java
index 4643610..f4ce723 100644
--- a/services/core/java/com/android/server/am/ProcessCachedOptimizerRecord.java
+++ b/services/core/java/com/android/server/am/ProcessCachedOptimizerRecord.java
@@ -47,6 +47,12 @@
     private int mLastCompactAction;
 
     /**
+     * This process has been scheduled for a memory compaction.
+     */
+    @GuardedBy("mProcLock")
+    private boolean mPendingCompact;
+
+    /**
      * True when the process is frozen.
      */
     @GuardedBy("mProcLock")
@@ -101,6 +107,16 @@
     }
 
     @GuardedBy("mProcLock")
+    boolean hasPendingCompact() {
+        return mPendingCompact;
+    }
+
+    @GuardedBy("mProcLock")
+    void setHasPendingCompact(boolean pendingCompact) {
+        mPendingCompact = pendingCompact;
+    }
+
+    @GuardedBy("mProcLock")
     boolean isFrozen() {
         return mFrozen;
     }
diff --git a/services/core/java/com/android/server/am/ProcessErrorStateRecord.java b/services/core/java/com/android/server/am/ProcessErrorStateRecord.java
index 93f30cc..ab4a2d5 100644
--- a/services/core/java/com/android/server/am/ProcessErrorStateRecord.java
+++ b/services/core/java/com/android/server/am/ProcessErrorStateRecord.java
@@ -300,9 +300,8 @@
         }
 
         // Check if package is still being loaded
-        boolean isIncremental = false;
         float loadingProgress = 1;
-        long millisSinceOldestPendingRead = 0;
+        IncrementalMetrics incrementalMetrics = null;
         final PackageManagerInternal packageManagerInternal = mService.getPackageManagerInternal();
         if (aInfo != null && aInfo.packageName != null) {
             IncrementalStatesInfo incrementalStatesInfo =
@@ -312,8 +311,7 @@
                 loadingProgress = incrementalStatesInfo.getProgress();
             }
             final String codePath = aInfo.getCodePath();
-            isIncremental = IncrementalManager.isIncrementalPath(codePath);
-            if (isIncremental) {
+            if (IncrementalManager.isIncrementalPath(codePath)) {
                 // Report in the main log that the incremental package is still loading
                 Slog.e(TAG, "App crashed on incremental package " + aInfo.packageName
                         + " which is " + ((int) (loadingProgress * 100)) + "% loaded.");
@@ -322,8 +320,7 @@
                 if (incrementalService != null) {
                     final IncrementalManager incrementalManager = new IncrementalManager(
                             IIncrementalService.Stub.asInterface(incrementalService));
-                    IncrementalMetrics metrics = incrementalManager.getMetrics(codePath);
-                    millisSinceOldestPendingRead = metrics.getMillisSinceOldestPendingRead();
+                    incrementalMetrics = incrementalManager.getMetrics(codePath);
                 }
             }
         }
@@ -345,7 +342,7 @@
             info.append("Parent: ").append(parentShortComponentName).append("\n");
         }
 
-        if (isIncremental) {
+        if (incrementalMetrics != null) {
             // Report in the main log about the incremental package
             info.append("Package is ").append((int) (loadingProgress * 100)).append("% loaded.\n");
         }
@@ -434,12 +431,14 @@
                         : FrameworkStatsLog.ANROCCURRED__FOREGROUND_STATE__BACKGROUND,
                 mApp.getProcessClassEnum(),
                 (mApp.info != null) ? mApp.info.packageName : "",
-                isIncremental, loadingProgress, millisSinceOldestPendingRead);
+                incrementalMetrics != null /* isIncremental */, loadingProgress,
+                incrementalMetrics != null ? incrementalMetrics.getMillisSinceOldestPendingRead()
+                        : -1);
         final ProcessRecord parentPr = parentProcess != null
                 ? (ProcessRecord) parentProcess.mOwner : null;
         mService.addErrorToDropBox("anr", mApp, mApp.processName, activityShortComponentName,
                 parentShortComponentName, parentPr, annotation, report.toString(), tracesFile,
-                null);
+                null, new Float(loadingProgress), incrementalMetrics);
 
         if (mApp.getWindowProcessController().appNotResponding(info.toString(),
                 () -> {
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 51bcde8..fae941d 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -36,7 +36,6 @@
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_NETWORK;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
@@ -54,7 +53,6 @@
 import static com.android.server.am.ActivityManagerService.TAG_NETWORK;
 import static com.android.server.am.ActivityManagerService.TAG_PROCESSES;
 import static com.android.server.am.ActivityManagerService.TAG_UID_OBSERVERS;
-import static com.android.server.am.AppProfiler.TAG_PSS;
 
 import android.annotation.NonNull;
 import android.app.ActivityManager;
@@ -687,6 +685,12 @@
     @GuardedBy("mService")
     final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
 
+    /**
+     * Processes that are killed by us and being waiting for the death notification.
+     */
+    @GuardedBy("mService")
+    final ProcessMap<ProcessRecord> mDyingProcesses = new ProcessMap<>();
+
     // Self locked with the inner lock within the RemoteCallbackList
     private final RemoteCallbackList<IProcessObserver> mProcessObservers =
             new RemoteCallbackList<>();
@@ -1501,8 +1505,7 @@
     }
 
     @GuardedBy("mService")
-    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean
-            keepIfLarge) {
+    ProcessRecord getProcessRecordLocked(String processName, int uid) {
         if (uid == SYSTEM_UID) {
             // The system gets to run in any process.  If there are multiple
             // processes with the same uid, just pick the first (this
@@ -1519,41 +1522,7 @@
                 return procs.valueAt(i);
             }
         }
-        ProcessRecord proc = mProcessNames.get(processName, uid);
-        if (false && proc != null && !keepIfLarge
-                && proc.mState.getSetProcState() >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
-                && proc.mProfile.getLastCachedPss() >= 4000) {
-            // Turn this condition on to cause killing to happen regularly, for testing.
-            synchronized (mService.mAppProfiler.mProfilerLock) {
-                proc.mProfile.reportCachedKill();
-            }
-            proc.killLocked(Long.toString(proc.mProfile.getLastCachedPss()) + "k from cached",
-                    ApplicationExitInfo.REASON_OTHER,
-                    ApplicationExitInfo.SUBREASON_LARGE_CACHED,
-                    true);
-        } else if (proc != null && !keepIfLarge
-                && !mService.mAppProfiler.isLastMemoryLevelNormal()
-                && proc.mState.getSetProcState() >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
-            final long lastCachedPss;
-            boolean doKilling = false;
-            synchronized (mService.mAppProfiler.mProfilerLock) {
-                lastCachedPss = proc.mProfile.getLastCachedPss();
-                if (lastCachedPss >= getCachedRestoreThresholdKb()) {
-                    proc.mProfile.reportCachedKill();
-                    doKilling = true;
-                }
-            }
-            if (DEBUG_PSS) {
-                Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + lastCachedPss);
-            }
-            if (doKilling) {
-                proc.killLocked(Long.toString(lastCachedPss) + "k from cached",
-                        ApplicationExitInfo.REASON_OTHER,
-                        ApplicationExitInfo.SUBREASON_LARGE_CACHED,
-                        true);
-            }
-        }
-        return proc;
+        return mProcessNames.get(processName, uid);
     }
 
     void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
@@ -1756,12 +1725,13 @@
 
     private boolean enableNativeHeapZeroInit(ProcessRecord app) {
         // Look at the process attribute first.
-        if (app.processInfo != null && app.processInfo.nativeHeapZeroInit != null) {
-            return app.processInfo.nativeHeapZeroInit;
+        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.isNativeHeapZeroInit() != null) {
-            return app.info.isNativeHeapZeroInit();
+        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)) {
@@ -1790,6 +1760,9 @@
             app.setPid(0);
             app.setStartSeq(0);
         }
+        // Clear any residual death recipient link as the ProcessRecord could be reused.
+        app.unlinkDeathRecipient();
+        app.setDyingPid(0);
 
         if (DEBUG_PROCESSES && mService.mProcessesOnHold.contains(app)) Slog.v(
                 TAG_PROCESSES,
@@ -2086,14 +2059,14 @@
         // If there is a preceding instance of the process, wait for its death with a timeout.
         // Use local reference since we are not using locks here
         final ProcessRecord predecessor = app.mPredecessor;
-        if (predecessor != null) {
-            final int pid = predecessor.getPid();
+        int prevPid;
+        if (predecessor != null && (prevPid = predecessor.getDyingPid()) > 0) {
             long now = System.currentTimeMillis();
             final long end = now + PROC_KILL_TIMEOUT;
             final int oldPolicy = StrictMode.getThreadPolicyMask();
             try {
                 StrictMode.setThreadPolicyMask(0);
-                Process.waitForProcessDeath(pid, PROC_KILL_TIMEOUT);
+                Process.waitForProcessDeath(prevPid, PROC_KILL_TIMEOUT);
                 // It's killed successfully, but we'd make sure the cleanup work is done.
                 synchronized (predecessor) {
                     if (app.mPredecessor != null) {
@@ -2103,17 +2076,22 @@
                                 predecessor.wait(end - now);
                             } catch (InterruptedException e) {
                             }
+                            if (System.currentTimeMillis() >= end) {
+                                Slog.w(TAG, predecessor + " " + prevPid
+                                        + " has died but its obituary delivery is slow.");
+                            }
                         }
                     }
-                    if (app.mPredecessor != null) {
+                    if (app.mPredecessor != null && app.mPredecessor.getPid() > 0) {
                         // The cleanup work hasn't be done yet, let's log it and continue.
-                        Slog.w(TAG, predecessor + " has died, but its cleanup isn't done");
+                        Slog.w(TAG, predecessor + " " + prevPid
+                                + " has died, but its cleanup isn't done");
                     }
                 }
             } catch (Exception e) {
                 // It's still alive... maybe blocked at uninterruptible sleep ?
-                Slog.wtf(TAG, predecessor.toString() + " refused to die, but we need to launch "
-                        + app, e);
+                Slog.wtf(TAG, predecessor.toString() + " " + prevPid
+                        + " refused to die, but we need to launch " + app, e);
             } finally {
                 StrictMode.setThreadPolicyMask(oldPolicy);
             }
@@ -2408,12 +2386,11 @@
     ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
             boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord,
             int zygotePolicyFlags, boolean allowWhileBooting, boolean isolated, int isolatedUid,
-            boolean keepIfLarge, String abiOverride, String entryPoint, String[] entryPointArgs,
-            Runnable crashHandler) {
+            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
         long startTime = SystemClock.uptimeMillis();
         ProcessRecord app;
         if (!isolated) {
-            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
+            app = getProcessRecordLocked(processName, info.uid);
             checkSlow(startTime, "startProcess: after getProcessRecord");
 
             if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
@@ -2476,12 +2453,8 @@
             ProcessList.killProcessGroup(app.uid, app.getPid());
             checkSlow(startTime, "startProcess: done killing old proc");
 
-            if (!app.isKilled()
-                    || mService.mAppProfiler.isLastMemoryLevelNormal()
-                    || app.mState.getSetProcState() < ActivityManager.PROCESS_STATE_CACHED_EMPTY
-                    || app.mProfile.getLastCachedPss() < getCachedRestoreThresholdKb()) {
-                // Throw a wtf if it's not killed, or killed but not because the system was in
-                // memory pressure + the app was in "cch-empty" and used large amount of memory
+            if (!app.isKilled()) {
+                // Throw a wtf if it's not killed
                 Slog.wtf(TAG_PROCESSES, app.toString() + " is attached to a previous process");
             } else {
                 Slog.w(TAG_PROCESSES, app.toString() + " is attached to a previous process");
@@ -2490,6 +2463,18 @@
             // routine of it yet, but we'd set it as the predecessor of the new process.
             predecessor = app;
             app = null;
+        } else if (!isolated) {
+            // This app may have been removed from process name maps, probably because we killed it
+            // and did the cleanup before the actual death notification. Check the dying processes.
+            predecessor = mDyingProcesses.get(processName, info.uid);
+            if (predecessor != null) {
+                if (app != null) {
+                    app.mPredecessor = predecessor;
+                    predecessor.mSuccessor = app;
+                }
+                Slog.w(TAG_PROCESSES, predecessor.toString() + " is attached to a previous process "
+                        + predecessor.getDyingPid());
+            }
         }
 
         if (app == null) {
@@ -2658,7 +2643,7 @@
                     + " belongs to another existing app:" + oldApp.processName
                     + " startSeq:" + oldApp.getStartSeq());
             mService.cleanUpApplicationRecordLocked(oldApp, pid, false, false, -1,
-                    true /*replacingPid*/);
+                    true /*replacingPid*/, false /* fromBinderDied */);
         }
         mService.addPidLocked(app);
         synchronized (mService.mPidsSelfLocked) {
@@ -2872,7 +2857,8 @@
                 }
             }
             app.killLocked(reason, reasonCode, subReason, true);
-            mService.handleAppDiedLocked(app, pid, willRestart, allowRestart);
+            mService.handleAppDiedLocked(app, pid, willRestart, allowRestart,
+                    false /* fromBinderDied */);
             if (willRestart) {
                 removeLruProcessLocked(app);
                 mService.addAppLocked(app.info, null, false, null /* ABI override */,
@@ -4903,6 +4889,55 @@
     }
 
     /**
+     * Handle the death notification if it's a dying app.
+     *
+     * @return {@code true} if it's a dying app that we were tracking.
+     */
+    @GuardedBy("mService")
+    boolean handleDyingAppDeathLocked(ProcessRecord app, int pid) {
+        if (mProcessNames.get(app.processName, app.uid) != app
+                && mDyingProcesses.get(app.processName, app.uid) == app) {
+            // App has been removed already, meaning cleanup has done.
+            Slog.v(TAG, "Got obituary of " + pid + ":" + app.processName);
+            app.unlinkDeathRecipient();
+            handlePrecedingAppDiedLocked(app);
+            // It's really gone now, let's remove from the dying process list.
+            mDyingProcesses.remove(app.processName, app.uid);
+            app.setDyingPid(0);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Handle the case where the given app is a preceding instance of another process instance.
+     *
+     * @return {@code false} if this given app should not be allowed to restart.
+     */
+    @GuardedBy("mService")
+    boolean handlePrecedingAppDiedLocked(ProcessRecord app) {
+        synchronized (app) {
+            if (app.mSuccessor != null) {
+                // We don't allow restart with this ProcessRecord now,
+                // because we have created a new one already.
+                // If it's persistent, add the successor to mPersistentStartingProcesses
+                if (app.isPersistent() && !app.isRemoved()) {
+                    if (mService.mPersistentStartingProcesses.indexOf(app.mSuccessor) < 0) {
+                        mService.mPersistentStartingProcesses.add(app.mSuccessor);
+                    }
+                }
+                // clean up the field so the successor's proc starter could proceed.
+                app.mSuccessor.mPredecessor = null;
+                app.mSuccessor = null;
+                // Notify if anyone is waiting for it.
+                app.notifyAll();
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
      * Called by ActivityManagerService when a process died.
      */
     @GuardedBy("mService")
@@ -4912,21 +4947,33 @@
         }
 
         Watchdog.getInstance().processDied(app.processName, app.getPid());
+        if (app.getDeathRecipient() == null) {
+            // If we've done unlinkDeathRecipient before calling into this, remove from dying list.
+            mDyingProcesses.remove(app.processName, app.uid);
+            app.setDyingPid(0);
+        }
         mAppExitInfoTracker.scheduleNoteProcessDied(app);
     }
 
     /**
      * Called by ActivityManagerService when it decides to kill an application process.
      */
+    @GuardedBy("mService")
     void noteAppKill(final ProcessRecord app, final @Reason int reason,
             final @SubReason int subReason, final String msg) {
         if (DEBUG_PROCESSES) {
             Slog.i(TAG, "note: " + app + " is being killed, reason: " + reason
                     + ", sub-reason: " + subReason + ", message: " + msg);
         }
+        if (app.getPid() > 0 && !app.isolated && app.getDeathRecipient() != null) {
+            // We are killing it, put it into the dying process list.
+            mDyingProcesses.put(app.processName, app.uid, app);
+            app.setDyingPid(app.getPid());
+        }
         mAppExitInfoTracker.scheduleNoteAppKill(app, reason, subReason, msg);
     }
 
+    @GuardedBy("mService")
     void noteAppKill(final int pid, final int uid, final @Reason int reason,
             final @SubReason int subReason, final String msg) {
         if (DEBUG_PROCESSES) {
@@ -4934,6 +4981,15 @@
                     + ", sub-reason: " + subReason + ", message: " + msg);
         }
 
+        final ProcessRecord app;
+        synchronized (mService.mPidsSelfLocked) {
+            app = mService.mPidsSelfLocked.get(pid);
+        }
+        if (app != null && app.uid == uid && !app.isolated && app.getDeathRecipient() != null) {
+            // We are killing it, put it into the dying process list.
+            mDyingProcesses.put(app.processName, uid, app);
+            app.setDyingPid(app.getPid());
+        }
         mAppExitInfoTracker.scheduleNoteAppKill(pid, uid, reason, subReason, msg);
     }
 
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index 42e7ff4..ed136af 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -107,6 +107,12 @@
     int mPid;
 
     /**
+     * The process ID which will be set when we're killing this process.
+     */
+    @GuardedBy("mService")
+    private int mDyingPid;
+
+    /**
      * The gids this process was launched with.
      */
     @GuardedBy("mService")
@@ -479,7 +485,7 @@
                 if (procInfo != null && procInfo.deniedPermissions == null
                         && procInfo.gwpAsanMode == ApplicationInfo.GWP_ASAN_DEFAULT
                         && procInfo.memtagMode == ApplicationInfo.MEMTAG_DEFAULT
-                        && procInfo.nativeHeapZeroInit == null) {
+                        && 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.
@@ -572,6 +578,16 @@
     }
 
     @GuardedBy("mService")
+    int getDyingPid() {
+        return mDyingPid;
+    }
+
+    @GuardedBy("mService")
+    void setDyingPid(int dyingPid) {
+        mDyingPid = dyingPid;
+    }
+
+    @GuardedBy("mService")
     int[] getGids() {
         return mGids;
     }
@@ -732,6 +748,11 @@
         mDeathRecipient = deathRecipient;
     }
 
+    @GuardedBy("mService")
+    IBinder.DeathRecipient getDeathRecipient() {
+        return mDeathRecipient;
+    }
+
     @GuardedBy({"mService", "mProcLock"})
     void setActiveInstrumentation(ActiveInstrumentation instr) {
         mInstr = instr;
@@ -896,11 +917,14 @@
     }
 
     @GuardedBy({"mService", "mProcLock"})
-    boolean onCleanupApplicationRecordLSP(ProcessStatsService processStats, boolean allowRestart) {
+    boolean onCleanupApplicationRecordLSP(ProcessStatsService processStats, boolean allowRestart,
+            boolean unlinkDeath) {
         mErrorState.onCleanupApplicationRecordLSP();
 
         resetPackageList(processStats);
-        unlinkDeathRecipient();
+        if (unlinkDeath) {
+            unlinkDeathRecipient();
+        }
         makeInactive(processStats);
         setWaitingToKill(null);
 
diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java
index 9cd9902..54c3512 100644
--- a/services/core/java/com/android/server/am/ServiceRecord.java
+++ b/services/core/java/com/android/server/am/ServiceRecord.java
@@ -165,9 +165,16 @@
     // allow the service becomes foreground service? Service started from background may not be
     // allowed to become a foreground service.
     @PowerWhitelistManager.ReasonCode int mAllowStartForeground = REASON_DENIED;
+    // Debug info why mAllowStartForeground is allowed or denied.
     String mInfoAllowStartForeground;
+    // Debug info if mAllowStartForeground is allowed because of a temp-allowlist.
     FgsStartTempAllowList.TempFgsAllowListEntry mInfoTempFgsAllowListReason;
+    // Is the same mInfoAllowStartForeground string has been logged before? Used for dedup.
     boolean mLoggedInfoAllowStartForeground;
+    // The number of times Service.startForeground() is called;
+    int mStartForegroundCount;
+    // Last time mAllowWhileInUsePermissionInFgs or mAllowStartForeground is set.
+    long mLastSetFgsRestrictionTime;
 
     String stringName;      // caching of toString
 
@@ -439,6 +446,8 @@
         pw.println(mRecentCallingUid);
         pw.print(prefix); pw.print("allowStartForeground=");
         pw.println(mAllowStartForeground);
+        pw.print(prefix); pw.print("startForegroundCount=");
+        pw.println(mStartForegroundCount);
         pw.print(prefix); pw.print("infoAllowStartForeground=");
         pw.println(mInfoAllowStartForeground);
         if (delayed) {
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index ec2020f..31183cac 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -334,13 +334,15 @@
     volatile boolean mBootCompleted;
 
     /**
-     * In this mode, user is always stopped when switched out but locking of user data is
+     * In this mode, user is always stopped when switched out (unless overridden by the
+     * {@code fw.stop_bg_users_on_switch} system property) but locking of user data is
      * postponed until total number of unlocked users in the system reaches mMaxRunningUsers.
      * Once total number of unlocked users reach mMaxRunningUsers, least recently used user
      * will be locked.
      */
     @GuardedBy("mLock")
     private boolean mDelayUserDataLocking;
+
     /**
      * Keep track of last active users for mDelayUserDataLocking.
      * The latest stopped user is placed in front while the least recently stopped user in back.
@@ -406,10 +408,9 @@
         }
     }
 
-    private boolean isDelayUserDataLockingEnabled() {
-        synchronized (mLock) {
-            return mDelayUserDataLocking;
-        }
+    private boolean shouldStopBackgroundUsersOnSwitch() {
+        int property = SystemProperties.getInt("fw.stop_bg_users_on_switch", -1);
+        return property == -1 ? mDelayUserDataLocking : property == 1;
     }
 
     void finishUserSwitch(UserState uss) {
@@ -1041,6 +1042,11 @@
 
     void finishUserStopped(UserState uss, boolean allowDelayedLocking) {
         final int userId = uss.mHandle.getIdentifier();
+        if (DEBUG_MU) {
+            Slog.i(TAG, "finishUserStopped(%d): allowDelayedLocking=%b", userId,
+                    allowDelayedLocking);
+        }
+
         EventLog.writeEvent(EventLogTags.UC_FINISH_USER_STOPPED, userId);
         final boolean stopped;
         boolean lockUser = true;
@@ -1153,11 +1159,9 @@
                 Slog.i(TAG, "finishUserStopped, stopping user:" + userId
                         + " lock user:" + userIdToLock);
             } else {
-                Slog.i(TAG, "finishUserStopped, user:" + userId
-                        + ",skip locking");
+                Slog.i(TAG, "finishUserStopped, user:" + userId + ", skip locking");
                 // do not lock
                 userIdToLock = UserHandle.USER_NULL;
-
             }
         }
         return userIdToLock;
@@ -1192,6 +1196,7 @@
     }
 
     private void forceStopUser(@UserIdInt int userId, String reason) {
+        if (DEBUG_MU) Slog.i(TAG, "forceStopUser(%d): %s", userId, reason);
         mInjector.activityManagerForceStopPackage(userId, reason);
         if (mInjector.getUserManager().isPreCreated(userId)) {
             // Don't fire intent for precreated.
@@ -1370,6 +1375,7 @@
 
     private boolean startUserInternal(@UserIdInt int userId, boolean foreground,
             @Nullable IProgressListener unlockListener, @NonNull TimingsTraceAndSlog t) {
+        if (DEBUG_MU) Slog.i(TAG, "Starting user %d%s", userId, foreground ? " in foreground" : "");
         EventLog.writeEvent(EventLogTags.UC_START_USER_INTERNAL, userId);
 
         final int callingUid = Binder.getCallingUid();
@@ -1635,6 +1641,13 @@
      * PIN or pattern.
      */
     private boolean maybeUnlockUser(final @UserIdInt int userId) {
+        if (mInjector.isFileEncryptedNativeOnly() && mLockPatternUtils.isSecure(userId)) {
+            // A token is needed, so don't bother trying to unlock without one.
+            // This keeps misleading error messages from being logged.
+            Slog.d(TAG, "Not unlocking user " + userId
+                    + "'s CE storage yet because a credential token is needed");
+            return false;
+        }
         // Try unlocking storage using empty token
         return unlockUserCleared(userId, null, null, null);
     }
@@ -1790,20 +1803,28 @@
         mUserSwitchObservers.finishBroadcast();
     }
 
-    private void stopBackgroundUsersIfEnforced(int oldUserId) {
+    private void stopBackgroundUsersOnSwitchIfEnforced(@UserIdInt int oldUserId) {
         // Never stop system user
         if (oldUserId == UserHandle.USER_SYSTEM) {
             return;
         }
-        // If running in background is disabled or mDelayUserDataLocking mode, stop the user.
-        boolean disallowRunInBg = hasUserRestriction(UserManager.DISALLOW_RUN_IN_BACKGROUND,
-                oldUserId) || isDelayUserDataLockingEnabled();
-        if (!disallowRunInBg) {
-            return;
-        }
+        boolean hasRestriction =
+                hasUserRestriction(UserManager.DISALLOW_RUN_IN_BACKGROUND, oldUserId);
         synchronized (mLock) {
-            if (DEBUG_MU) Slog.i(TAG, "stopBackgroundUsersIfEnforced stopping " + oldUserId
-                    + " and related users");
+            // If running in background is disabled or mStopBackgroundUsersOnSwitch mode,
+            // stop the user.
+            boolean disallowRunInBg = hasRestriction || shouldStopBackgroundUsersOnSwitch();
+            if (!disallowRunInBg) {
+                if (DEBUG_MU) {
+                    Slog.i(TAG, "stopBackgroundUsersIfEnforced() NOT stopping %d and related users",
+                            oldUserId);
+                }
+                return;
+            }
+            if (DEBUG_MU) {
+                Slog.i(TAG, "stopBackgroundUsersIfEnforced() stopping %d and related users",
+                        oldUserId);
+            }
             stopUsersLU(oldUserId, /* force= */ false, /* allowDelayedLocking= */ true,
                     null, null);
         }
@@ -1904,7 +1925,7 @@
         mHandler.removeMessages(REPORT_USER_SWITCH_COMPLETE_MSG);
         mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_COMPLETE_MSG, newUserId, 0));
         stopGuestOrEphemeralUserIfBackground(oldUserId);
-        stopBackgroundUsersIfEnforced(oldUserId);
+        stopBackgroundUsersOnSwitchIfEnforced(oldUserId);
     }
 
     private void moveUserToForeground(UserState uss, int oldUserId, int newUserId) {
@@ -2594,6 +2615,8 @@
             pw.println("  mTargetUserId:" + mTargetUserId);
             pw.println("  mLastActiveUsers:" + mLastActiveUsers);
             pw.println("  mDelayUserDataLocking:" + mDelayUserDataLocking);
+            pw.println("  shouldStopBackgroundUsersOnSwitch:"
+                    + shouldStopBackgroundUsersOnSwitch());
             pw.println("  mMaxRunningUsers:" + mMaxRunningUsers);
             pw.println("  mUserSwitchUiEnabled:" + mUserSwitchUiEnabled);
             pw.println("  mInitialized:" + mInitialized);
@@ -3085,5 +3108,11 @@
         protected IStorageManager getStorageManager() {
             return IStorageManager.Stub.asInterface(ServiceManager.getService("mount"));
         }
+
+        // This is needed because isFileEncryptedNativeOnly is a static method,
+        // but it needs to be mocked out in tests.
+        protected boolean isFileEncryptedNativeOnly() {
+            return StorageManager.isFileEncryptedNativeOnly();
+        }
     }
 }
diff --git a/services/core/java/com/android/server/app/GameManagerService.java b/services/core/java/com/android/server/app/GameManagerService.java
index 0eae661..57de708 100644
--- a/services/core/java/com/android/server/app/GameManagerService.java
+++ b/services/core/java/com/android/server/app/GameManagerService.java
@@ -16,6 +16,17 @@
 
 package com.android.server.app;
 
+import static android.content.Intent.ACTION_PACKAGE_ADDED;
+import static android.content.Intent.ACTION_PACKAGE_CHANGED;
+import static android.content.Intent.ACTION_PACKAGE_REMOVED;
+
+import static com.android.server.wm.CompatModePackages.DOWNSCALED;
+import static com.android.server.wm.CompatModePackages.DOWNSCALE_50;
+import static com.android.server.wm.CompatModePackages.DOWNSCALE_60;
+import static com.android.server.wm.CompatModePackages.DOWNSCALE_70;
+import static com.android.server.wm.CompatModePackages.DOWNSCALE_80;
+import static com.android.server.wm.CompatModePackages.DOWNSCALE_90;
+
 import android.Manifest;
 import android.annotation.NonNull;
 import android.annotation.RequiresPermission;
@@ -23,23 +34,42 @@
 import android.app.GameManager;
 import android.app.GameManager.GameMode;
 import android.app.IGameManagerService;
+import android.compat.Compatibility;
+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.PackageInfo;
 import android.content.pm.PackageManager;
+import android.net.Uri;
 import android.os.Binder;
 import android.os.Environment;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
 import android.os.Process;
+import android.os.RemoteException;
+import android.os.ResultReceiver;
+import android.os.ServiceManager;
+import android.os.ShellCallback;
+import android.provider.DeviceConfig;
+import android.provider.DeviceConfig.Properties;
 import android.util.ArrayMap;
-import android.util.Log;
+import android.util.KeyValueListParser;
 import android.util.Slog;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.compat.CompatibilityChangeConfig;
+import com.android.internal.compat.IPlatformCompat;
 import com.android.server.ServiceThread;
 import com.android.server.SystemService;
 
+import java.io.FileDescriptor;
+import java.util.HashSet;
+import java.util.List;
+
 /**
  * Service to manage game related features.
  *
@@ -55,13 +85,20 @@
 
     static final int WRITE_SETTINGS = 1;
     static final int REMOVE_SETTINGS = 2;
+    static final int POPULATE_GAME_MODE_SETTINGS = 3;
     static final int WRITE_SETTINGS_DELAY = 10 * 1000;  // 10 seconds
 
     private final Context mContext;
     private final Object mLock = new Object();
+    private final Object mDeviceConfigLock = new Object();
     private final Handler mHandler;
+    private final PackageManager mPackageManager;
+    private final IPlatformCompat mPlatformCompat;
+    private DeviceConfigListener mDeviceConfigListener;
     @GuardedBy("mLock")
     private final ArrayMap<Integer, GameManagerSettings> mSettings = new ArrayMap<>();
+    @GuardedBy("mDeviceConfigLock")
+    private final ArrayMap<String, GamePackageConfiguration> mConfigs = new ArrayMap<>();
 
     public GameManagerService(Context context) {
         this(context, createServiceThread().getLooper());
@@ -70,6 +107,15 @@
     GameManagerService(Context context, Looper looper) {
         mContext = context;
         mHandler = new SettingsHandler(looper);
+        mPackageManager = mContext.getPackageManager();
+        mPlatformCompat = IPlatformCompat.Stub.asInterface(
+                ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
+    }
+
+    @Override
+    public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
+            String[] args, ShellCallback callback, ResultReceiver result) {
+        new GameManagerShellCommand().exec(this, in, out, err, args, callback, result);
     }
 
     class SettingsHandler extends Handler {
@@ -130,10 +176,186 @@
                     }
                     break;
                 }
+                case POPULATE_GAME_MODE_SETTINGS: {
+                    removeMessages(POPULATE_GAME_MODE_SETTINGS, msg.obj);
+                    loadDeviceConfigLocked();
+                    break;
+                }
             }
         }
     }
 
+    private class DeviceConfigListener implements DeviceConfig.OnPropertiesChangedListener {
+
+        DeviceConfigListener() {
+            super();
+            DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_GAME_OVERLAY,
+                    mContext.getMainExecutor(), this);
+        }
+
+        @Override
+        public void onPropertiesChanged(Properties properties) {
+            synchronized (mDeviceConfigLock) {
+                for (String key : properties.getKeyset()) {
+                    try {
+                        // Check if the package is installed before caching it.
+                        final String packageName = keyToPackageName(key);
+                        mPackageManager.getPackageInfo(packageName, 0);
+                        final GamePackageConfiguration config =
+                                GamePackageConfiguration.fromProperties(key, properties);
+                        if (config.isValid()) {
+                            putConfig(config);
+                        } else {
+                            // This means that we received a bad config, or the config was deleted.
+                            Slog.i(TAG, "Removing config for: " + packageName);
+                            mConfigs.remove(packageName);
+                            disableCompatScale(packageName);
+                        }
+                    } catch (PackageManager.NameNotFoundException e) {
+                        if (DEBUG) {
+                            Slog.v(TAG, "Package name not found", e);
+                        }
+                    }
+                }
+            }
+        }
+
+        @Override
+        public void finalize() {
+            DeviceConfig.removeOnPropertiesChangedListener(this);
+        }
+    }
+
+    private static class GameModeConfiguration {
+        public static final String TAG = "GameManagerService_GameModeConfiguration";
+        public static final String MODE_KEY = "mode";
+        public static final String SCALING_KEY = "downscaleFactor";
+
+        private final @GameMode int mGameMode;
+        private final String mScaling;
+
+        private GameModeConfiguration(@NonNull int gameMode,
+                @NonNull String scaling) {
+            mGameMode = gameMode;
+            mScaling = scaling;
+        }
+
+        public static GameModeConfiguration fromKeyValueListParser(KeyValueListParser parser) {
+            return new GameModeConfiguration(
+                    parser.getInt(MODE_KEY, GameManager.GAME_MODE_UNSUPPORTED),
+                    parser.getString(SCALING_KEY, "1.0")
+            );
+        }
+
+        public int getGameMode() {
+            return mGameMode;
+        }
+
+        public String getScaling() {
+            return mScaling;
+        }
+
+        public boolean isValid() {
+            return (mGameMode == GameManager.GAME_MODE_PERFORMANCE
+                    || mGameMode == GameManager.GAME_MODE_BATTERY) && getCompatChangeId() != 0;
+        }
+
+        public String toString() {
+            return "[Game Mode:" + mGameMode + ",Scaling:" + mScaling + "]";
+        }
+
+        public long getCompatChangeId() {
+            switch (mScaling) {
+                case "0.5":
+                    return DOWNSCALE_50;
+                case "0.6":
+                    return DOWNSCALE_60;
+                case "0.7":
+                    return DOWNSCALE_70;
+                case "0.8":
+                    return DOWNSCALE_80;
+                case "0.9":
+                    return DOWNSCALE_90;
+            }
+            return 0;
+        }
+    }
+
+    private static class GamePackageConfiguration {
+        public static final String TAG = "GameManagerService_GamePackageConfiguration";
+
+        private final String mPackageName;
+        private final ArrayMap<Integer, GameModeConfiguration> mModeConfigs;
+
+        private GamePackageConfiguration(String keyName) {
+            mPackageName = keyToPackageName(keyName);
+            mModeConfigs = new ArrayMap<>();
+        }
+
+        public String getPackageName() {
+            return mPackageName;
+        }
+
+        public @GameMode int[] getAvailableGameModes() {
+            if (mModeConfigs.keySet().size() > 0) {
+                return mModeConfigs.keySet().stream()
+                            .mapToInt(Integer::intValue).toArray();
+            }
+            return new int[]{GameManager.GAME_MODE_UNSUPPORTED};
+        }
+
+        /**
+         * Get a GameModeConfiguration for a given game mode.
+         *
+         * @return The package's GameModeConfiguration for the provided mode or null if absent
+         */
+        public GameModeConfiguration getGameModeConfiguration(@GameMode int gameMode) {
+            return mModeConfigs.get(gameMode);
+        }
+
+        /**
+         * Insert a new GameModeConfiguration
+         */
+        public void addModeConfig(GameModeConfiguration config) {
+            if (config.isValid()) {
+                mModeConfigs.put(config.getGameMode(), config);
+            } else {
+                Slog.w(TAG, "Invalid game mode config for "
+                        + mPackageName + ":" + config.toString());
+            }
+        }
+
+        /**
+         * Create a new instance from a package name and DeviceConfig.Properties instance
+         */
+        public static GamePackageConfiguration fromProperties(String key,
+                Properties properties) {
+            final GamePackageConfiguration packageConfig = new GamePackageConfiguration(key);
+            final String configString = properties.getString(key, "");
+            final String[] gameModeConfigStrings = configString.split(":");
+            for (String gameModeConfigString : gameModeConfigStrings) {
+                try {
+                    final KeyValueListParser parser = new KeyValueListParser(',');
+                    parser.setString(gameModeConfigString);
+                    final GameModeConfiguration config =
+                            GameModeConfiguration.fromKeyValueListParser(parser);
+                    packageConfig.addModeConfig(config);
+                } catch (IllegalArgumentException e) {
+                    Slog.e(TAG, "Invalid config string");
+                }
+            }
+            return packageConfig;
+        }
+
+        public boolean isValid() {
+            return mModeConfigs.size() > 0;
+        }
+
+        public String toString() {
+            return "[Name:" + mPackageName + " Modes: " + mModeConfigs.toString() + "]";
+        }
+    }
+
     /**
      * SystemService lifecycle for GameService.
      *
@@ -150,6 +372,8 @@
         public void onStart() {
             mService = new GameManagerService(getContext());
             publishBinderService(Context.GAME_SERVICE, mService);
+            mService.registerDeviceConfigListener();
+            mService.registerPackageReceiver();
         }
 
         @Override
@@ -171,9 +395,8 @@
     }
 
     private boolean isValidPackageName(String packageName) {
-        final PackageManager pm = mContext.getPackageManager();
         try {
-            return pm.getPackageUid(packageName, 0) == Binder.getCallingUid();
+            return mPackageManager.getPackageUid(packageName, 0) == Binder.getCallingUid();
         } catch (PackageManager.NameNotFoundException e) {
             e.printStackTrace();
             return false;
@@ -188,10 +411,27 @@
         }
     }
 
+    /**
+     * Get an array of game modes available for a given package.
+     * Checks that the caller has {@link android.Manifest.permission#MANAGE_GAME_MODE}.
+     */
+    @Override
+    @RequiresPermission(Manifest.permission.MANAGE_GAME_MODE)
+    public @GameMode int[] getAvailableGameModes(String packageName) throws SecurityException {
+        checkPermission(Manifest.permission.MANAGE_GAME_MODE);
+        synchronized (mDeviceConfigLock) {
+            final GamePackageConfiguration config = mConfigs.get(packageName);
+            if (config == null) {
+                return new int[]{GameManager.GAME_MODE_UNSUPPORTED};
+            }
+            return config.getAvailableGameModes();
+        }
+    }
+
     private @GameMode int getGameModeFromSettings(String packageName, int userId) {
         synchronized (mLock) {
             if (!mSettings.containsKey(userId)) {
-                Log.w(TAG, "User ID '" + userId + "' does not have a Game Mode"
+                Slog.w(TAG, "User ID '" + userId + "' does not have a Game Mode"
                         + " selected for package: '" + packageName + "'");
                 return GameManager.GAME_MODE_UNSUPPORTED;
             }
@@ -208,16 +448,36 @@
     @Override
     public @GameMode int getGameMode(String packageName, int userId)
             throws SecurityException {
-        // TODO(b/178860939): Restrict to games only.
-
         userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
                 Binder.getCallingUid(), userId, false, true, "getGameMode",
                 "com.android.server.app.GameManagerService");
 
+        // Restrict to games only.
+        try {
+            final ApplicationInfo applicationInfo = mPackageManager
+                    .getApplicationInfoAsUser(packageName, PackageManager.MATCH_ALL, userId);
+            if (applicationInfo.category != ApplicationInfo.CATEGORY_GAME) {
+                Slog.e(TAG, "Ignoring attempt to get the Game Mode for '" + packageName
+                        + "' which is not categorized as a game: applicationInfo.flags = "
+                        + applicationInfo.flags + ", category = " + applicationInfo.category);
+                return GameManager.GAME_MODE_UNSUPPORTED;
+            }
+        } catch (PackageManager.NameNotFoundException e) {
+            e.printStackTrace();
+            return GameManager.GAME_MODE_UNSUPPORTED;
+        }
+
+        // This function handles two types of queries:
+        // 1.) A normal, non-privileged app querying its own Game Mode.
+        // 2.) A privileged system service querying the Game Mode of another package.
+        // The least privileged case is a normal app performing a query, so check that first and
+        // return a value if the package name is valid. Next, check if the caller has the necessary
+        // permission and return a value. Do this check last, since it can throw an exception.
         if (isValidPackageName(packageName)) {
             return getGameModeFromSettings(packageName, userId);
         }
 
+        // Since the package name doesn't match, check the caller has the necessary permission.
         checkPermission(Manifest.permission.MANAGE_GAME_MODE);
         return getGameModeFromSettings(packageName, userId);
     }
@@ -230,15 +490,28 @@
     @RequiresPermission(Manifest.permission.MANAGE_GAME_MODE)
     public void setGameMode(String packageName, @GameMode int gameMode, int userId)
             throws SecurityException {
-        // TODO(b/178860939): Restrict to games only.
-
         checkPermission(Manifest.permission.MANAGE_GAME_MODE);
 
-        userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
-                Binder.getCallingUid(), userId, false, true, "setGameMode",
-                "com.android.server.app.GameManagerService");
+        // Restrict to games only.
+        try {
+            final ApplicationInfo applicationInfo = mPackageManager
+                    .getApplicationInfoAsUser(packageName, PackageManager.MATCH_ALL, userId);
+            if (applicationInfo.category != ApplicationInfo.CATEGORY_GAME) {
+                Slog.e(TAG, "Ignoring attempt to set the Game Mode for '" + packageName
+                        + "' which is not categorized as a game: applicationInfo.flags = "
+                        + applicationInfo.flags + ", category = " + applicationInfo.category);
+                return;
+            }
+        } catch (PackageManager.NameNotFoundException e) {
+            e.printStackTrace();
+            return;
+        }
 
         synchronized (mLock) {
+            userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
+                    Binder.getCallingUid(), userId, false, true, "setGameMode",
+                    "com.android.server.app.GameManagerService");
+
             if (!mSettings.containsKey(userId)) {
                 return;
             }
@@ -250,6 +523,7 @@
                 mHandler.sendMessageDelayed(msg, WRITE_SETTINGS_DELAY);
             }
         }
+        updateCompatModeDownscale(packageName, gameMode);
     }
 
     /**
@@ -258,6 +532,8 @@
     @VisibleForTesting
     void onBootCompleted() {
         Slog.d(TAG, "onBootCompleted");
+        final Message msg = mHandler.obtainMessage(POPULATE_GAME_MODE_SETTINGS);
+        mHandler.sendMessage(msg);
     }
 
     void onUserStarting(int userId) {
@@ -284,6 +560,187 @@
         }
     }
 
+    private void loadDeviceConfigLocked() {
+        final List<PackageInfo> packages = mPackageManager.getInstalledPackages(0);
+        final String[] packageNames = packages.stream().map(e -> packageNameToKey(e.packageName))
+                .toArray(String[]::new);
+        synchronized (mDeviceConfigLock) {
+            final Properties properties = DeviceConfig.getProperties(
+                    DeviceConfig.NAMESPACE_GAME_OVERLAY, packageNames);
+            for (String key : properties.getKeyset()) {
+                final GamePackageConfiguration config =
+                        GamePackageConfiguration.fromProperties(key, properties);
+                putConfig(config);
+            }
+        }
+    }
+
+    private void disableCompatScale(String packageName) {
+        final long uid = Binder.clearCallingIdentity();
+        try {
+            final HashSet<Long> disabledSet = new HashSet<>();
+            disabledSet.add(DOWNSCALED);
+            final CompatibilityChangeConfig changeConfig = new CompatibilityChangeConfig(
+                    new Compatibility.ChangeConfig(new HashSet<>(), disabledSet));
+            // TODO: switch to new API provided by aosp/1599153 once merged
+            try {
+                mPlatformCompat.setOverridesForTest(changeConfig, packageName);
+            } catch (SecurityException e) {
+                Slog.e(TAG, "Missing compat override permission", e);
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Failed to call IPlatformCompat#setOverridesForTest", e);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(uid);
+        }
+    }
+
+    private void enableCompatScale(String packageName, long scaleId) {
+        final long uid = Binder.clearCallingIdentity();
+        try {
+            final HashSet<Long> disabledSet = new HashSet<>();
+            final HashSet<Long> enabledSet = new HashSet<>();
+            disabledSet.add(DOWNSCALE_50);
+            disabledSet.add(DOWNSCALE_60);
+            disabledSet.add(DOWNSCALE_70);
+            disabledSet.add(DOWNSCALE_80);
+            disabledSet.add(DOWNSCALE_90);
+            disabledSet.remove(scaleId);
+            enabledSet.add(DOWNSCALED);
+            enabledSet.add(scaleId);
+            final CompatibilityChangeConfig changeConfig = new CompatibilityChangeConfig(
+                    new Compatibility.ChangeConfig(enabledSet, disabledSet));
+            // TODO: switch to new API provided by aosp/1599153 once merged
+            try {
+                mPlatformCompat.setOverridesForTest(changeConfig, packageName);
+            } catch (SecurityException e) {
+                Slog.e(TAG, "Missing compat override permission", e);
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Failed to call IPlatformCompat#setOverridesForTest", e);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(uid);
+        }
+    }
+
+    private void updateCompatModeDownscale(String packageName, @GameMode int gameMode) {
+        synchronized (mDeviceConfigLock) {
+            if (gameMode == GameManager.GAME_MODE_STANDARD
+                    || gameMode == GameManager.GAME_MODE_UNSUPPORTED) {
+                disableCompatScale(packageName);
+                Slog.v(TAG, "Disabling downscale");
+                return;
+            }
+            if (DEBUG) {
+                Slog.v(TAG, dumpDeviceConfigs());
+            }
+            final GamePackageConfiguration packageConfig = mConfigs.get(packageName);
+            if (packageConfig == null) {
+                Slog.w(TAG, "Package configuration not found for " + packageName);
+                return;
+            }
+            final GameModeConfiguration modeConfig = packageConfig.getGameModeConfiguration(
+                    gameMode);
+            if (modeConfig == null) {
+                Slog.w(TAG, "Game mode " + gameMode + " not found for " + packageName);
+                return;
+            }
+            long scaleId = modeConfig.getCompatChangeId();
+            if (scaleId == 0) {
+                Slog.w(TAG, "Invalid downscaling change id " + scaleId + " for "
+                        + packageName);
+                return;
+            }
+            Slog.i(TAG, "Enabling downscale: " + scaleId + " for " + packageName);
+            enableCompatScale(packageName, scaleId);
+        }
+    }
+
+    private void putConfig(GamePackageConfiguration config) {
+        if (config.isValid()) {
+            if (DEBUG) {
+                Slog.i(TAG, "Adding config: " + config.toString());
+            }
+            mConfigs.put(config.getPackageName(), config);
+        } else {
+            Slog.w(TAG, "Invalid package config for "
+                    + config.getPackageName() + ":" + config.toString());
+        }
+    }
+
+    private void registerPackageReceiver() {
+        final IntentFilter packageFilter = new IntentFilter();
+        packageFilter.addAction(ACTION_PACKAGE_ADDED);
+        packageFilter.addAction(ACTION_PACKAGE_CHANGED);
+        packageFilter.addAction(ACTION_PACKAGE_REMOVED);
+        packageFilter.addDataScheme("package");
+        final BroadcastReceiver packageReceiver = new BroadcastReceiver() {
+            @Override
+            public void onReceive(@NonNull final Context context, @NonNull final Intent intent) {
+                final Uri data = intent.getData();
+                try {
+                    final String packageName = data.getSchemeSpecificPart();
+                    switch (intent.getAction()) {
+                        case ACTION_PACKAGE_ADDED:
+                        case ACTION_PACKAGE_CHANGED:
+                            synchronized (mDeviceConfigLock) {
+                                Properties properties = DeviceConfig.getProperties(
+                                        DeviceConfig.NAMESPACE_GAME_OVERLAY,
+                                        packageNameToKey(packageName));
+                                for (String key : properties.getKeyset()) {
+                                    GamePackageConfiguration config =
+                                            GamePackageConfiguration.fromProperties(key,
+                                                    properties);
+                                    putConfig(config);
+                                }
+                            }
+                            break;
+                        case ACTION_PACKAGE_REMOVED:
+                            disableCompatScale(packageName);
+                            mConfigs.remove(packageName);
+                            break;
+                        default:
+                            // do nothing
+                            break;
+                    }
+                } catch (NullPointerException e) {
+                    Slog.e(TAG, "Failed to get package name for new package", e);
+                }
+            }
+        };
+        mContext.registerReceiver(packageReceiver, packageFilter);
+    }
+
+    private void registerDeviceConfigListener() {
+        mDeviceConfigListener = new DeviceConfigListener();
+    }
+
+    /**
+     * Valid package name characters are [a-zA-Z0-9_] with a '.' delimiter. Policy keys can only use
+     * [a-zA-Z0-9_] so we must handle periods. We do this by appending a '_' to any existing
+     * sequence of '_', then we replace all '.' chars with '_';
+     */
+    private static String packageNameToKey(String name) {
+        return name.replaceAll("(_+)", "_$1").replaceAll("\\.", "_");
+    }
+
+    /**
+     * Replace the last '_' in a sequence with '.' (this can be one or more chars), then replace the
+     * resulting special case '_.' with just '_' to get the original package name.
+     */
+    private static String keyToPackageName(String key) {
+        return key.replaceAll("(_)(?!\\1)", ".").replaceAll("_\\.", "_");
+    }
+
+    private String dumpDeviceConfigs() {
+        StringBuilder out = new StringBuilder();
+        for (String key : mConfigs.keySet()) {
+            out.append("[\nName: ").append(key)
+                    .append("\nConfig: ").append(mConfigs.get(key).toString()).append("\n]");
+        }
+        return out.toString();
+    }
+
     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/GameManagerShellCommand.java b/services/core/java/com/android/server/app/GameManagerShellCommand.java
new file mode 100644
index 0000000..e4c0002
--- /dev/null
+++ b/services/core/java/com/android/server/app/GameManagerShellCommand.java
@@ -0,0 +1,136 @@
+/*
+ * 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.app;
+
+import android.compat.Compatibility;
+import android.content.Context;
+import android.os.ServiceManager;
+import android.os.ShellCommand;
+import android.util.ArraySet;
+
+import com.android.internal.compat.CompatibilityChangeConfig;
+import com.android.server.compat.PlatformCompat;
+import com.android.server.wm.CompatModePackages;
+
+import java.io.PrintWriter;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * ShellCommands for GameManagerService.
+ *
+ * Use with {@code adb shell cmd game ...}.
+ */
+public class GameManagerShellCommand extends ShellCommand {
+
+    public GameManagerShellCommand() {}
+
+    private static final ArraySet<Long> DOWNSCALE_CHANGE_IDS = new ArraySet<>(new Long[]{
+            CompatModePackages.DOWNSCALED,
+            CompatModePackages.DOWNSCALE_90,
+            CompatModePackages.DOWNSCALE_80,
+            CompatModePackages.DOWNSCALE_70,
+            CompatModePackages.DOWNSCALE_60,
+            CompatModePackages.DOWNSCALE_50});
+
+    @Override
+    public int onCommand(String cmd) {
+        if (cmd == null) {
+            return handleDefaultCommands(cmd);
+        }
+        final PrintWriter pw = getOutPrintWriter();
+        try {
+            switch (cmd) {
+                case "downscale":
+                    final String ratio = getNextArgRequired();
+                    final String packageName = getNextArgRequired();
+
+                    final long changeId;
+                    switch (ratio) {
+                        case "0.5":
+                            changeId = CompatModePackages.DOWNSCALE_50;
+                            break;
+                        case "0.6":
+                            changeId = CompatModePackages.DOWNSCALE_60;
+                            break;
+                        case "0.7":
+                            changeId = CompatModePackages.DOWNSCALE_70;
+                            break;
+                        case "0.8":
+                            changeId = CompatModePackages.DOWNSCALE_80;
+                            break;
+                        case "0.9":
+                            changeId = CompatModePackages.DOWNSCALE_90;
+                            break;
+                        case "disable":
+                            changeId = 0;
+                            break;
+                        default:
+                            changeId = -1;
+                            pw.println("Invalid scaling ratio '" + ratio + "'");
+                            break;
+                    }
+                    if (changeId == -1) {
+                        break;
+                    }
+
+                    Set<Long> enabled = new ArraySet<>();
+                    Set<Long> disabled;
+                    if (changeId == 0) {
+                        disabled = DOWNSCALE_CHANGE_IDS;
+                    } else {
+                        enabled.add(CompatModePackages.DOWNSCALED);
+                        enabled.add(changeId);
+                        disabled = DOWNSCALE_CHANGE_IDS.stream()
+                          .filter(it -> it != CompatModePackages.DOWNSCALED && it != changeId)
+                          .collect(Collectors.toSet());
+                    }
+
+                    final PlatformCompat platformCompat = (PlatformCompat)
+                            ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE);
+                    final CompatibilityChangeConfig overrides =
+                            new CompatibilityChangeConfig(
+                                new Compatibility.ChangeConfig(enabled, disabled));
+
+                    platformCompat.setOverrides(overrides, packageName);
+                    if (changeId == 0) {
+                        pw.println("Disable downscaling for " + packageName + ".");
+                    } else {
+                        pw.println("Enable downscaling ratio for " + packageName + " to " + ratio);
+                    }
+
+                    break;
+                default:
+                    return handleDefaultCommands(cmd);
+            }
+        } catch (Exception e) {
+            pw.println("Error: " + e);
+        }
+        return -1;
+    }
+
+
+    @Override
+    public void onHelp() {
+        PrintWriter pw = getOutPrintWriter();
+        pw.println("Game manager (game) commands:");
+        pw.println("  help");
+        pw.println("      Print this help text.");
+        pw.println("  downscale [0.5|0.6|0.7|0.8|0.9|disable] <PACKAGE_NAME>");
+        pw.println("      Force app to run at the specified scaling ratio.");
+    }
+}
diff --git a/services/core/java/com/android/server/apphibernation/AppHibernationService.java b/services/core/java/com/android/server/apphibernation/AppHibernationService.java
index ad5a65c..5a99e0e 100644
--- a/services/core/java/com/android/server/apphibernation/AppHibernationService.java
+++ b/services/core/java/com/android/server/apphibernation/AppHibernationService.java
@@ -38,6 +38,7 @@
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
 import android.os.Binder;
 import android.os.Environment;
 import android.os.RemoteException;
@@ -69,6 +70,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.Executor;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 
@@ -91,8 +93,10 @@
     private final Object mLock = new Object();
     private final Context mContext;
     private final IPackageManager mIPackageManager;
+    private final PackageManagerInternal mPackageManagerInternal;
     private final IActivityManager mIActivityManager;
     private final UserManager mUserManager;
+
     @GuardedBy("mLock")
     private final SparseArray<Map<String, UserLevelState>> mUserStates = new SparseArray<>();
     private final SparseArray<HibernationStateDiskStore<UserLevelState>> mUserDiskStores =
@@ -101,6 +105,7 @@
     private final Map<String, GlobalLevelState> mGlobalHibernationStates = new ArrayMap<>();
     private final HibernationStateDiskStore<GlobalLevelState> mGlobalLevelHibernationDiskStore;
     private final Injector mInjector;
+    private final Executor mBackgroundExecutor;
 
     @VisibleForTesting
     boolean mIsServiceEnabled;
@@ -123,9 +128,11 @@
         super(injector.getContext());
         mContext = injector.getContext();
         mIPackageManager = injector.getPackageManager();
+        mPackageManagerInternal = injector.getPackageManagerInternal();
         mIActivityManager = injector.getActivityManager();
         mUserManager = injector.getUserManager();
         mGlobalLevelHibernationDiskStore = injector.getGlobalLevelDiskStore();
+        mBackgroundExecutor = injector.getBackgroundExecutor();
         mInjector = injector;
 
         final Context userAllContext = mContext.createContextAsUser(UserHandle.ALL, 0 /* flags */);
@@ -147,11 +154,13 @@
     @Override
     public void onBootPhase(int phase) {
         if (phase == PHASE_BOOT_COMPLETED) {
-            List<GlobalLevelState> states =
-                    mGlobalLevelHibernationDiskStore.readHibernationStates();
-            synchronized (mLock) {
-                initializeGlobalHibernationStates(states);
-            }
+            mBackgroundExecutor.execute(() -> {
+                List<GlobalLevelState> states =
+                        mGlobalLevelHibernationDiskStore.readHibernationStates();
+                synchronized (mLock) {
+                    initializeGlobalHibernationStates(states);
+                }
+            });
         }
         if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
             mIsServiceEnabled = isAppHibernationEnabled();
@@ -170,16 +179,15 @@
      * @return true if package is hibernating for the user
      */
     boolean isHibernatingForUser(String packageName, int userId) {
-        if (!checkHibernationEnabled("isHibernatingForUser")) {
+        String methodName = "isHibernatingForUser";
+        if (!checkHibernationEnabled(methodName)) {
             return false;
         }
         getContext().enforceCallingOrSelfPermission(
                 android.Manifest.permission.MANAGE_APP_HIBERNATION,
                 "Caller does not have MANAGE_APP_HIBERNATION permission.");
-        userId = handleIncomingUser(userId, "isHibernating");
-        if (!mUserManager.isUserUnlockingOrUnlocked(userId)) {
-            Slog.e(TAG, "Attempt to get hibernation state of stopped or nonexistent user "
-                    + userId);
+        userId = handleIncomingUser(userId, methodName);
+        if (!checkUserStatesExist(userId, methodName)) {
             return false;
         }
         synchronized (mLock) {
@@ -210,8 +218,9 @@
         synchronized (mLock) {
             GlobalLevelState state = mGlobalHibernationStates.get(packageName);
             if (state == null) {
-                throw new IllegalArgumentException(
-                        String.format("Package %s is not installed", packageName));
+                // This API can be legitimately called before installation finishes as part of
+                // dex optimization, so we just return false here.
+                return false;
             }
             return state.hibernated;
         }
@@ -225,16 +234,15 @@
      * @param isHibernating new hibernation state
      */
     void setHibernatingForUser(String packageName, int userId, boolean isHibernating) {
-        if (!checkHibernationEnabled("setHibernatingForUser")) {
+        String methodName = "setHibernatingForUser";
+        if (!checkHibernationEnabled(methodName)) {
             return;
         }
         getContext().enforceCallingOrSelfPermission(
                 android.Manifest.permission.MANAGE_APP_HIBERNATION,
                 "Caller does not have MANAGE_APP_HIBERNATION permission.");
-        userId = handleIncomingUser(userId, "setHibernating");
-        if (!mUserManager.isUserUnlockingOrUnlocked(userId)) {
-            Slog.w(TAG, "Attempt to set hibernation state for a stopped or nonexistent user "
-                    + userId);
+        userId = handleIncomingUser(userId, methodName);
+        if (!checkUserStatesExist(userId, methodName)) {
             return;
         }
         synchronized (mLock) {
@@ -293,6 +301,34 @@
     }
 
     /**
+     * Get the hibernating packages for the given user. This is equivalent to the list of
+     * packages for the user that return true for {@link #isHibernatingForUser}.
+     */
+    @NonNull List<String> getHibernatingPackagesForUser(int userId) {
+        ArrayList<String> hibernatingPackages = new ArrayList<>();
+        String methodName = "getHibernatingPackagesForUser";
+        if (!checkHibernationEnabled(methodName)) {
+            return hibernatingPackages;
+        }
+        getContext().enforceCallingOrSelfPermission(
+                android.Manifest.permission.MANAGE_APP_HIBERNATION,
+                "Caller does not have MANAGE_APP_HIBERNATION permission.");
+        userId = handleIncomingUser(userId, methodName);
+        if (!checkUserStatesExist(userId, methodName)) {
+            return hibernatingPackages;
+        }
+        synchronized (mLock) {
+            Map<String, UserLevelState> userStates = mUserStates.get(userId);
+            for (UserLevelState state : userStates.values()) {
+                if (state.hibernated) {
+                    hibernatingPackages.add(state.packageName);
+                }
+            }
+            return hibernatingPackages;
+        }
+    }
+
+    /**
      * Put an app into hibernation for a given user, allowing user-level optimizations to occur.
      *
      * @param pkgState package hibernation state
@@ -335,7 +371,7 @@
     @GuardedBy("mLock")
     private void hibernatePackageGlobally(@NonNull String packageName, GlobalLevelState state) {
         Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "hibernatePackageGlobally");
-        // TODO(175830194): Delete vdex/odex when DexManager API is built out
+        mPackageManagerInternal.deleteOatArtifactsOfPackage(packageName);
         state.hibernated = true;
         Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
     }
@@ -439,10 +475,15 @@
         HibernationStateDiskStore<UserLevelState> diskStore =
                 mInjector.getUserLevelDiskStore(userId);
         mUserDiskStores.put(userId, diskStore);
-        List<UserLevelState> storedStates = diskStore.readHibernationStates();
-        synchronized (mLock) {
-            initializeUserHibernationStates(userId, storedStates);
-        }
+        mBackgroundExecutor.execute(() -> {
+            List<UserLevelState> storedStates = diskStore.readHibernationStates();
+            synchronized (mLock) {
+                // Ensure user hasn't stopped in the time to execute.
+                if (mUserManager.isUserUnlockingOrUnlocked(userId)) {
+                    initializeUserHibernationStates(userId, storedStates);
+                }
+            }
+        });
     }
 
     @Override
@@ -512,6 +553,20 @@
         }
     }
 
+    private boolean checkUserStatesExist(int userId, String methodName) {
+        if (!mUserManager.isUserUnlockingOrUnlocked(userId)) {
+            Slog.e(TAG, String.format(
+                    "Attempt to call %s on stopped or nonexistent user %d", methodName, userId));
+            return false;
+        }
+        if (!mUserStates.contains(userId)) {
+            Slog.w(TAG, String.format(
+                    "Attempt to call %s before states have been read from disk", methodName));
+            return false;
+        }
+        return true;
+    }
+
     private boolean checkHibernationEnabled(String methodName) {
         if (!mIsServiceEnabled) {
             Slog.w(TAG, String.format("Attempted to call %s on unsupported device.", methodName));
@@ -610,6 +665,11 @@
         }
 
         @Override
+        public List<String> getHibernatingPackagesForUser(int userId) {
+            return mService.getHibernatingPackagesForUser(userId);
+        }
+
+        @Override
         public void onShellCommand(@Nullable FileDescriptor in, @Nullable FileDescriptor out,
                 @Nullable FileDescriptor err, @NonNull String[] args,
                 @Nullable ShellCallback callback, @NonNull ResultReceiver resultReceiver) {
@@ -673,10 +733,14 @@
 
         IPackageManager getPackageManager();
 
+        PackageManagerInternal getPackageManagerInternal();
+
         IActivityManager getActivityManager();
 
         UserManager getUserManager();
 
+        Executor getBackgroundExecutor();
+
         HibernationStateDiskStore<GlobalLevelState> getGlobalLevelDiskStore();
 
         HibernationStateDiskStore<UserLevelState> getUserLevelDiskStore(int userId);
@@ -705,6 +769,11 @@
         }
 
         @Override
+        public PackageManagerInternal getPackageManagerInternal() {
+            return LocalServices.getService(PackageManagerInternal.class);
+        }
+
+        @Override
         public IActivityManager getActivityManager() {
             return ActivityManager.getService();
         }
@@ -715,6 +784,11 @@
         }
 
         @Override
+        public Executor getBackgroundExecutor() {
+            return mScheduledExecutorService;
+        }
+
+        @Override
         public HibernationStateDiskStore<GlobalLevelState> getGlobalLevelDiskStore() {
             File dir = new File(Environment.getDataSystemDirectory(), HIBERNATION_DIR_NAME);
             return new HibernationStateDiskStore<>(
diff --git a/services/core/java/com/android/server/apphibernation/HibernationStateDiskStore.java b/services/core/java/com/android/server/apphibernation/HibernationStateDiskStore.java
index c83659d..24cf433 100644
--- a/services/core/java/com/android/server/apphibernation/HibernationStateDiskStore.java
+++ b/services/core/java/com/android/server/apphibernation/HibernationStateDiskStore.java
@@ -109,6 +109,7 @@
      * @return the parsed list of hibernation states, null if file does not exist
      */
     @Nullable
+    @WorkerThread
     List<T> readHibernationStates() {
         synchronized (this) {
             if (!mHibernationFile.exists()) {
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 109ffe3..07ee5a2 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -94,6 +94,7 @@
 import android.app.RuntimeAppOpAccessMessage;
 import android.app.SyncNotedAppOp;
 import android.app.admin.DevicePolicyManagerInternal;
+import android.content.AttributionSource;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -131,6 +132,7 @@
 import android.util.ArraySet;
 import android.util.AtomicFile;
 import android.util.KeyValueListParser;
+import android.util.Log;
 import android.util.LongSparseArray;
 import android.util.Pair;
 import android.util.Pools;
@@ -159,6 +161,9 @@
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.Preconditions;
 import com.android.internal.util.XmlUtils;
+import com.android.internal.util.function.HeptFunction;
+import com.android.internal.util.function.QuintFunction;
+import com.android.internal.util.function.TriFunction;
 import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.server.LocalServices;
 import com.android.server.LockGuard;
@@ -1922,6 +1927,7 @@
         synchronized (this) {
             if (mWriteScheduled) {
                 mWriteScheduled = false;
+                mFastWriteScheduled = false;
                 mHandler.removeCallbacks(mWriteRunner);
                 doWrite = true;
             }
@@ -1998,8 +2004,10 @@
 
     @Override
     public List<AppOpsManager.PackageOps> getPackagesForOps(int[] ops) {
-        mContext.enforcePermission(android.Manifest.permission.GET_APP_OPS_STATS,
-                Binder.getCallingPid(), Binder.getCallingUid(), null);
+        final int callingUid = Binder.getCallingUid();
+        final boolean hasAllPackageAccess = mContext.checkPermission(
+                Manifest.permission.GET_APP_OPS_STATS, Binder.getCallingPid(),
+                Binder.getCallingUid(), null) == PackageManager.PERMISSION_GRANTED;
         ArrayList<AppOpsManager.PackageOps> res = null;
         synchronized (this) {
             final int uidStateCount = mUidStates.size();
@@ -2015,11 +2023,14 @@
                     ArrayList<AppOpsManager.OpEntry> resOps = collectOps(pkgOps, ops);
                     if (resOps != null) {
                         if (res == null) {
-                            res = new ArrayList<AppOpsManager.PackageOps>();
+                            res = new ArrayList<>();
                         }
                         AppOpsManager.PackageOps resPackage = new AppOpsManager.PackageOps(
                                 pkgOps.packageName, pkgOps.uidState.uid, resOps);
-                        res.add(resPackage);
+                        // Caller can always see their packages and with a permission all.
+                        if (hasAllPackageAccess || callingUid == pkgOps.uidState.uid) {
+                            res.add(resPackage);
+                        }
                     }
                 }
             }
@@ -2030,8 +2041,7 @@
     @Override
     public List<AppOpsManager.PackageOps> getOpsForPackage(int uid, String packageName,
             int[] ops) {
-        mContext.enforcePermission(android.Manifest.permission.GET_APP_OPS_STATS,
-                Binder.getCallingPid(), Binder.getCallingUid(), null);
+        enforceGetAppOpsStatsPermissionIfNeeded(uid,packageName);
         String resolvedPackageName = resolvePackageName(uid, packageName);
         if (resolvedPackageName == null) {
             return Collections.emptyList();
@@ -2053,6 +2063,22 @@
         }
     }
 
+    private void enforceGetAppOpsStatsPermissionIfNeeded(int uid, String packageName) {
+        final int callingUid = Binder.getCallingUid();
+        // We get to access everything
+        if (callingUid == Process.myPid()) {
+            return;
+        }
+        // Apps can access their own data
+        if (uid == callingUid && packageName != null
+                && checkPackage(uid, packageName) == MODE_ALLOWED) {
+            return;
+        }
+        // Otherwise, you need a permission...
+        mContext.enforcePermission(android.Manifest.permission.GET_APP_OPS_STATS,
+                Binder.getCallingPid(), callingUid, null);
+    }
+
     /**
      * Verify that historical appop request arguments are valid.
      */
@@ -3077,15 +3103,52 @@
     }
 
     @Override
-    public int noteProxyOperation(int code, int proxiedUid, String proxiedPackageName,
-            String proxiedAttributionTag, int proxyUid, String proxyPackageName,
-            String proxyAttributionTag, boolean shouldCollectAsyncNotedOp, String message,
-            boolean shouldCollectMessage) {
-        verifyIncomingUid(proxyUid);
+    public int noteProxyOperation(int code, AttributionSource attributionSource,
+            boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage,
+            boolean skipProxyOperation) {
+        final CheckOpsDelegate policy;
+        final CheckOpsDelegateDispatcher delegateDispatcher;
+        synchronized (AppOpsService.this) {
+            policy = mAppOpsPolicy;
+            delegateDispatcher = mCheckOpsDelegateDispatcher;
+        }
+        if (policy != null) {
+            if (delegateDispatcher != null) {
+                return policy.noteProxyOperation(code, attributionSource,
+                        shouldCollectAsyncNotedOp, message, shouldCollectMessage,
+                        skipProxyOperation, delegateDispatcher::noteProxyOperationImpl);
+            } else {
+                return policy.noteProxyOperation(code, attributionSource,
+                        shouldCollectAsyncNotedOp, message, shouldCollectMessage,
+                        skipProxyOperation, AppOpsService.this::noteProxyOperationImpl);
+            }
+        } else if (delegateDispatcher != null) {
+            delegateDispatcher.getCheckOpsDelegate().noteProxyOperation(code,
+                    attributionSource, shouldCollectAsyncNotedOp, message,
+                    shouldCollectMessage, skipProxyOperation,
+                    AppOpsService.this::noteProxyOperationImpl);
+        }
+        return noteProxyOperationImpl(code, attributionSource, shouldCollectAsyncNotedOp,
+                message, shouldCollectMessage,skipProxyOperation);
+    }
+
+    private int noteProxyOperationImpl(int code, AttributionSource attributionSource,
+            boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage,
+            boolean skipProxyOperation) {
+        final int proxyUid = attributionSource.getUid();
+        final String proxyPackageName = attributionSource.getPackageName();
+        final String proxyAttributionTag = attributionSource.getAttributionTag();
+        final int proxiedUid = attributionSource.getNextUid();
+        final String proxiedPackageName = attributionSource.getNextPackageName();
+        final String proxiedAttributionTag = attributionSource.getNextAttributionTag();
+
+        verifyIncomingProxyUid(attributionSource);
         verifyIncomingOp(code);
         verifyIncomingPackage(proxiedPackageName, UserHandle.getUserId(proxiedUid));
         verifyIncomingPackage(proxyPackageName, UserHandle.getUserId(proxyUid));
 
+        skipProxyOperation = resolveSkipProxyOperation(skipProxyOperation, attributionSource);
+
         String resolveProxyPackageName = resolvePackageName(proxyUid, proxyPackageName);
         if (resolveProxyPackageName == null) {
             return AppOpsManager.MODE_IGNORED;
@@ -3096,19 +3159,23 @@
                 Manifest.permission.UPDATE_APP_OPS_STATS, -1, proxyUid)
                 == PackageManager.PERMISSION_GRANTED || isSelfBlame;
 
-        final int proxyFlags = isProxyTrusted ? AppOpsManager.OP_FLAG_TRUSTED_PROXY
-                : AppOpsManager.OP_FLAG_UNTRUSTED_PROXY;
-        final int proxyMode = noteOperationUnchecked(code, proxyUid, resolveProxyPackageName,
-                proxyAttributionTag, Process.INVALID_UID, null, null, proxyFlags,
-                !isProxyTrusted, "proxy " + message, shouldCollectMessage);
-        if (proxyMode != AppOpsManager.MODE_ALLOWED) {
-            return proxyMode;
+        if (!skipProxyOperation) {
+            final int proxyFlags = isProxyTrusted ? AppOpsManager.OP_FLAG_TRUSTED_PROXY
+                    : AppOpsManager.OP_FLAG_UNTRUSTED_PROXY;
+
+            final int proxyMode = noteOperationUnchecked(code, proxyUid, resolveProxyPackageName,
+                    proxyAttributionTag, Process.INVALID_UID, null, null, proxyFlags,
+                    !isProxyTrusted, "proxy " + message, shouldCollectMessage);
+            if (proxyMode != AppOpsManager.MODE_ALLOWED) {
+                return proxyMode;
+            }
         }
 
         String resolveProxiedPackageName = resolvePackageName(proxiedUid, proxiedPackageName);
         if (resolveProxiedPackageName == null) {
             return AppOpsManager.MODE_IGNORED;
         }
+
         final int proxiedFlags = isProxyTrusted ? AppOpsManager.OP_FLAG_TRUSTED_PROXIED
                 : AppOpsManager.OP_FLAG_UNTRUSTED_PROXIED;
         return noteOperationUnchecked(code, proxiedUid, resolveProxiedPackageName,
@@ -3557,16 +3624,56 @@
     }
 
     @Override
-    public int startProxyOperation(IBinder clientId, int code, int proxiedUid,
-            String proxiedPackageName, @Nullable String proxiedAttributionTag, int proxyUid,
-            String proxyPackageName, @Nullable String proxyAttributionTag,
+    public int startProxyOperation(IBinder clientId, int code,
+            @NonNull AttributionSource attributionSource, boolean startIfModeDefault,
+            boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage,
+            boolean skipProxyOperation) {
+        final CheckOpsDelegate policy;
+        final CheckOpsDelegateDispatcher delegateDispatcher;
+        synchronized (AppOpsService.this) {
+            policy = mAppOpsPolicy;
+            delegateDispatcher = mCheckOpsDelegateDispatcher;
+        }
+        if (policy != null) {
+            if (delegateDispatcher != null) {
+                return policy.startProxyOperation(clientId, code, attributionSource,
+                        startIfModeDefault, shouldCollectAsyncNotedOp, message,
+                        shouldCollectMessage, skipProxyOperation,
+                        delegateDispatcher::startProxyOperationImpl);
+            } else {
+                return policy.startProxyOperation(clientId, code, attributionSource,
+                        startIfModeDefault, shouldCollectAsyncNotedOp, message,
+                        shouldCollectMessage, skipProxyOperation,
+                        AppOpsService.this::startProxyOperationImpl);
+            }
+        } else if (delegateDispatcher != null) {
+            delegateDispatcher.getCheckOpsDelegate().startProxyOperation(clientId, code,
+                    attributionSource, startIfModeDefault, shouldCollectAsyncNotedOp, message,
+                    shouldCollectMessage, skipProxyOperation,
+                    AppOpsService.this::startProxyOperationImpl);
+        }
+        return startProxyOperationImpl(clientId, code, attributionSource, startIfModeDefault,
+                shouldCollectAsyncNotedOp, message, shouldCollectMessage, skipProxyOperation);
+    }
+
+    private int startProxyOperationImpl(IBinder clientId, int code,
+            @NonNull AttributionSource attributionSource,
             boolean startIfModeDefault, boolean shouldCollectAsyncNotedOp, String message,
-            boolean shouldCollectMessage) {
-        verifyIncomingUid(proxyUid);
+            boolean shouldCollectMessage, boolean skipProxyOperation) {
+        final int proxyUid = attributionSource.getUid();
+        final String proxyPackageName = attributionSource.getPackageName();
+        final String proxyAttributionTag = attributionSource.getAttributionTag();
+        final int proxiedUid = attributionSource.getNextUid();
+        final String proxiedPackageName = attributionSource.getNextPackageName();
+        final String proxiedAttributionTag = attributionSource.getNextAttributionTag();
+
+        verifyIncomingProxyUid(attributionSource);
         verifyIncomingOp(code);
         verifyIncomingPackage(proxyPackageName, UserHandle.getUserId(proxyUid));
         verifyIncomingPackage(proxiedPackageName, UserHandle.getUserId(proxiedUid));
 
+        skipProxyOperation = resolveSkipProxyOperation(skipProxyOperation, attributionSource);
+
         String resolvedProxyPackageName = resolvePackageName(proxyUid, proxyPackageName);
         if (resolvedProxyPackageName == null) {
             return AppOpsManager.MODE_IGNORED;
@@ -3577,31 +3684,34 @@
                 Manifest.permission.UPDATE_APP_OPS_STATS, -1, proxyUid)
                 == PackageManager.PERMISSION_GRANTED || isSelfBlame;
 
-        final int proxyFlags = isProxyTrusted ? AppOpsManager.OP_FLAG_TRUSTED_PROXY
-                : AppOpsManager.OP_FLAG_UNTRUSTED_PROXY;
-
         String resolvedProxiedPackageName = resolvePackageName(proxiedUid, proxiedPackageName);
         if (resolvedProxiedPackageName == null) {
             return AppOpsManager.MODE_IGNORED;
         }
+
         final int proxiedFlags = isProxyTrusted ? AppOpsManager.OP_FLAG_TRUSTED_PROXIED
                 : AppOpsManager.OP_FLAG_UNTRUSTED_PROXIED;
 
-        // Test if the proxied operation will succeed before starting the proxy operation
-        final int testProxiedMode = startOperationUnchecked(clientId, code, proxiedUid,
-                resolvedProxiedPackageName, proxiedAttributionTag, proxyUid,
-                resolvedProxyPackageName, proxyAttributionTag, proxiedFlags, startIfModeDefault,
-                shouldCollectAsyncNotedOp, message, shouldCollectMessage, true);
-        if (!shouldStartForMode(testProxiedMode, startIfModeDefault)) {
-            return testProxiedMode;
-        }
+        if (!skipProxyOperation) {
+            // Test if the proxied operation will succeed before starting the proxy operation
+            final int testProxiedMode = startOperationUnchecked(clientId, code, proxiedUid,
+                    resolvedProxiedPackageName, proxiedAttributionTag, proxyUid,
+                    resolvedProxyPackageName, proxyAttributionTag, proxiedFlags, startIfModeDefault,
+                    shouldCollectAsyncNotedOp, message, shouldCollectMessage, true);
+            if (!shouldStartForMode(testProxiedMode, startIfModeDefault)) {
+                return testProxiedMode;
+            }
 
-        final int proxyMode = startOperationUnchecked(clientId, code, proxyUid,
-                resolvedProxyPackageName, proxyAttributionTag, Process.INVALID_UID, null, null,
-                proxyFlags, startIfModeDefault, !isProxyTrusted, "proxy " + message,
-                shouldCollectMessage, false);
-        if (!shouldStartForMode(proxyMode, startIfModeDefault)) {
-            return proxyMode;
+            final int proxyFlags = isProxyTrusted ? AppOpsManager.OP_FLAG_TRUSTED_PROXY
+                    : AppOpsManager.OP_FLAG_UNTRUSTED_PROXY;
+
+            final int proxyMode = startOperationUnchecked(clientId, code, proxyUid,
+                    resolvedProxyPackageName, proxyAttributionTag, Process.INVALID_UID, null, null,
+                    proxyFlags, startIfModeDefault, !isProxyTrusted, "proxy " + message,
+                    shouldCollectMessage, false);
+            if (!shouldStartForMode(proxyMode, startIfModeDefault)) {
+                return proxyMode;
+            }
         }
 
         return startOperationUnchecked(clientId, code, proxiedUid, resolvedProxiedPackageName,
@@ -3722,9 +3832,38 @@
     }
 
     @Override
-    public void finishProxyOperation(IBinder clientId, int code, int proxiedUid,
-            String proxiedPackageName, @Nullable String proxiedAttributionTag, int proxyUid,
-            @Nullable String proxyPackageName, @Nullable String proxyAttributionTag) {
+    public void finishProxyOperation(IBinder clientId, int code,
+            @NonNull AttributionSource attributionSource) {
+        final CheckOpsDelegate policy;
+        final CheckOpsDelegateDispatcher delegateDispatcher;
+        synchronized (AppOpsService.this) {
+            policy = mAppOpsPolicy;
+            delegateDispatcher = mCheckOpsDelegateDispatcher;
+        }
+        if (policy != null) {
+            if (delegateDispatcher != null) {
+                policy.finishProxyOperation(clientId, code, attributionSource,
+                        delegateDispatcher::finishProxyOperationImpl);
+            } else {
+                policy.finishProxyOperation(clientId, code, attributionSource,
+                        AppOpsService.this::finishProxyOperationImpl);
+            }
+        } else if (delegateDispatcher != null) {
+            delegateDispatcher.getCheckOpsDelegate().finishProxyOperation(clientId, code,
+                    attributionSource, AppOpsService.this::finishProxyOperationImpl);
+        }
+        finishProxyOperationImpl(clientId, code, attributionSource);
+    }
+
+    private Void finishProxyOperationImpl(IBinder clientId, int code,
+            @NonNull AttributionSource attributionSource) {
+        final int proxyUid = attributionSource.getUid();
+        final String proxyPackageName = attributionSource.getPackageName();
+        final String proxyAttributionTag = attributionSource.getAttributionTag();
+        final int proxiedUid = attributionSource.getNextUid();
+        final String proxiedPackageName = attributionSource.getNextPackageName();
+        final String proxiedAttributionTag = attributionSource.getNextAttributionTag();
+
         verifyIncomingUid(proxyUid);
         verifyIncomingOp(code);
         verifyIncomingPackage(proxyPackageName, UserHandle.getUserId(proxyUid));
@@ -3732,7 +3871,7 @@
 
         String resolvedProxyPackageName = resolvePackageName(proxyUid, proxyPackageName);
         if (resolvedProxyPackageName == null) {
-            return;
+            return null;
         }
 
         finishOperationUnchecked(clientId, code, proxyUid, resolvedProxyPackageName,
@@ -3740,11 +3879,13 @@
 
         String resolvedProxiedPackageName = resolvePackageName(proxiedUid, proxiedPackageName);
         if (resolvedProxiedPackageName == null) {
-            return;
+            return null;
         }
 
         finishOperationUnchecked(clientId, code, proxiedUid, resolvedProxiedPackageName,
                 proxiedAttributionTag);
+
+        return null;
     }
 
     private void finishOperationUnchecked(IBinder clientId, int code, int uid, String packageName,
@@ -3952,6 +4093,20 @@
                 || (permInfo.getProtectionFlags() & PROTECTION_FLAG_APPOP) != 0;
     }
 
+    private void verifyIncomingProxyUid(@NonNull AttributionSource attributionSource) {
+        if (attributionSource.getUid() == Binder.getCallingUid()) {
+            return;
+        }
+        if (Binder.getCallingPid() == Process.myPid()) {
+            return;
+        }
+        if (attributionSource.isTrusted(mContext)) {
+            return;
+        }
+        mContext.enforcePermission(android.Manifest.permission.UPDATE_APP_OPS_STATS,
+                Binder.getCallingPid(), Binder.getCallingUid(), null);
+    }
+
     private void verifyIncomingUid(int uid) {
         if (uid == Binder.getCallingUid()) {
             return;
@@ -3978,6 +4133,20 @@
         }
     }
 
+    private boolean resolveSkipProxyOperation(boolean requestsSkipProxyOperation,
+            @NonNull AttributionSource attributionSource) {
+        if (!requestsSkipProxyOperation) {
+            return false;
+        }
+        if (attributionSource.getUid() != Binder.getCallingUid()
+                && attributionSource.isTrusted(mContext)) {
+            return true;
+        }
+        return mContext.checkPermission(android.Manifest.permission.UPDATE_APP_OPS_STATS,
+                Binder.getCallingPid(), Binder.getCallingUid(), null)
+                == PackageManager.PERMISSION_GRANTED;
+    }
+
     private @Nullable UidState getUidStateLocked(int uid, boolean edit) {
         UidState uidState = mUidStates.get(uid);
         if (uidState == null) {
@@ -4097,7 +4266,6 @@
     /**
      * Create a restriction description matching the properties of the package.
      *
-     * @param context A context to use
      * @param pkg The package to create the restriction description for
      *
      * @return The restriction matching the package
@@ -4140,15 +4308,25 @@
 
         int callingUid = Binder.getCallingUid();
         int userId = UserHandle.getUserId(uid);
-
         RestrictionBypass bypass = null;
+
+        // Allow any attribution tag for resolvable uids
+        int pkgUid = resolveUid(packageName);
+        if (pkgUid != Process.INVALID_UID) {
+            // Special case for the shell which is a package but should be able
+            // to bypass app attribution tag restrictions.
+            if (pkgUid != UserHandle.getAppId(uid)) {
+                throw new SecurityException("Specified package " + packageName + " under uid "
+                        +  UserHandle.getAppId(uid) + " but it is really " + pkgUid);
+            }
+            return RestrictionBypass.UNRESTRICTED;
+        }
+
         final long ident = Binder.clearCallingIdentity();
         try {
-            int pkgUid;
-            AndroidPackage pkg = LocalServices.getService(PackageManagerInternal.class).getPackage(
-                    packageName);
             boolean isAttributionTagValid = false;
-
+            AndroidPackage pkg = LocalServices.getService(PackageManagerInternal.class)
+                    .getPackage(packageName);
             if (pkg != null) {
                 if (attributionTag == null) {
                     isAttributionTagValid = true;
@@ -4165,20 +4343,7 @@
 
                 pkgUid = UserHandle.getUid(userId, UserHandle.getAppId(pkg.getUid()));
                 bypass = getBypassforPackage(pkg);
-            } else {
-                // Allow any attribution tag for resolvable uids
-                isAttributionTagValid = true;
-
-                pkgUid = resolveUid(packageName);
-                if (pkgUid >= 0) {
-                    bypass = RestrictionBypass.UNRESTRICTED;
-                }
             }
-            if (pkgUid != uid) {
-                throw new SecurityException("Specified package " + packageName + " under uid " + uid
-                        + " but it is really " + pkgUid);
-            }
-
             if (!isAttributionTagValid) {
                 String msg = "attributionTag " + attributionTag + " not declared in"
                         + " manifest of " + packageName;
@@ -4186,7 +4351,7 @@
                     if (mPlatformCompat.isChangeEnabledByPackageName(
                             SECURITY_EXCEPTION_ON_INVALID_ATTRIBUTION_TAG_CHANGE, packageName,
                             userId) && mPlatformCompat.isChangeEnabledByUid(
-                            SECURITY_EXCEPTION_ON_INVALID_ATTRIBUTION_TAG_CHANGE, callingUid)) {
+                                    SECURITY_EXCEPTION_ON_INVALID_ATTRIBUTION_TAG_CHANGE, callingUid)) {
                         throw new SecurityException(msg);
                     } else {
                         Slog.e(TAG, msg);
@@ -4198,6 +4363,11 @@
             Binder.restoreCallingIdentity(ident);
         }
 
+        if (pkgUid != uid) {
+            throw new SecurityException("Specified package " + packageName + " under uid " + uid
+                    + " but it is really " + pkgUid);
+        }
+
         return bypass;
     }
 
@@ -6102,6 +6272,57 @@
     }
 
     @Override
+    public boolean isProxying(int op, @NonNull String proxyPackageName,
+            @NonNull String proxyAttributionTag, int proxiedUid,
+            @NonNull String proxiedPackageName) {
+        Objects.requireNonNull(proxyPackageName);
+        Objects.requireNonNull(proxiedPackageName);
+        Binder.withCleanCallingIdentity(() -> {
+            final List<AppOpsManager.PackageOps> packageOps = getOpsForPackage(proxiedUid,
+                    proxiedPackageName, new int[] {op});
+            if (packageOps == null || packageOps.isEmpty()) {
+                return false;
+            }
+            final List<OpEntry> opEntries = packageOps.get(0).getOps();
+            if (opEntries.isEmpty()) {
+                return false;
+            }
+            final OpEntry opEntry = opEntries.get(0);
+            if (!opEntry.isRunning()) {
+                return false;
+            }
+            final OpEventProxyInfo proxyInfo = opEntry.getLastProxyInfo(
+                    AppOpsManager.OP_FLAG_TRUSTED_PROXY
+                            | AppOpsManager.OP_FLAG_UNTRUSTED_PROXY);
+            return proxyInfo != null && Binder.getCallingUid() == proxyInfo.getUid()
+                    && proxyPackageName.equals(proxyInfo.getPackageName())
+                    && Objects.equals(proxyAttributionTag, proxyInfo.getAttributionTag());
+        });
+        return false;
+    }
+
+    @Override
+    public void resetPackageOpsNoHistory(@NonNull String packageName) {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_APPOPS,
+                "resetPackageOpsNoHistory");
+        synchronized (AppOpsService.this) {
+            final int uid = mPackageManagerInternal.getPackageUid(packageName, 0,
+                    UserHandle.getCallingUserId());
+            if (uid == Process.INVALID_UID) {
+                return;
+            }
+            UidState uidState = mUidStates.get(uid);
+            if (uidState == null || uidState.pkgOps == null) {
+                return;
+            }
+            Ops removedOps = uidState.pkgOps.remove(packageName);
+            if (removedOps != null) {
+                scheduleFastWriteLocked();
+            }
+        }
+    }
+
+    @Override
     public void setHistoryParameters(@AppOpsManager.HistoricalMode int mode,
             long baseSnapshotInterval, int compressionStep) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_APPOPS,
@@ -6454,6 +6675,7 @@
                 return Process.ROOT_UID;
             case "shell":
             case "dumpstate":
+            case "com.android.shell":
                 return Process.SHELL_UID;
             case "media":
                 return Process.MEDIA_UID;
@@ -6830,5 +7052,29 @@
                     shouldCollectAsyncNotedOp, message, shouldCollectMessage,
                     AppOpsService.this::noteOperationImpl);
         }
+
+        public int noteProxyOperationImpl(int code, @NonNull AttributionSource attributionSource,
+                boolean shouldCollectAsyncNotedOp, @Nullable String message,
+                boolean shouldCollectMessage, boolean skipProxyOperation) {
+            return mCheckOpsDelegate.noteProxyOperation(code, attributionSource,
+                    shouldCollectAsyncNotedOp, message, shouldCollectMessage, skipProxyOperation,
+                    AppOpsService.this::noteProxyOperationImpl);
+        }
+
+        public int startProxyOperationImpl(IBinder token, int code,
+                @NonNull AttributionSource attributionSource, boolean startIfModeDefault,
+                boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage,
+                boolean skipProxyOperation) {
+            return mCheckOpsDelegate.startProxyOperation(token, code, attributionSource,
+                    startIfModeDefault, shouldCollectAsyncNotedOp, message, shouldCollectMessage,
+                    skipProxyOperation, AppOpsService.this::startProxyOperationImpl);
+        }
+
+        public Void finishProxyOperationImpl(IBinder clientId, int code,
+                @NonNull AttributionSource attributionSource) {
+            mCheckOpsDelegate.finishProxyOperation(clientId, code, attributionSource,
+                    AppOpsService.this::finishProxyOperationImpl);
+            return null;
+        }
     }
 }
diff --git a/services/core/java/com/android/server/appop/DiscreteRegistry.java b/services/core/java/com/android/server/appop/DiscreteRegistry.java
index 2b0157c..e16a6cc 100644
--- a/services/core/java/com/android/server/appop/DiscreteRegistry.java
+++ b/services/core/java/com/android/server/appop/DiscreteRegistry.java
@@ -31,14 +31,18 @@
 import static android.app.AppOpsManager.flagsToString;
 import static android.app.AppOpsManager.getUidStateName;
 
+import static java.lang.Long.min;
 import static java.lang.Math.max;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.AppOpsManager;
+import android.os.AsyncTask;
+import android.os.Build;
 import android.os.Environment;
 import android.os.FileUtils;
 import android.os.Process;
+import android.provider.DeviceConfig;
 import android.util.ArrayMap;
 import android.util.Slog;
 import android.util.TypedXmlPullParser;
@@ -82,8 +86,16 @@
     static final String TIMELINE_FILE_SUFFIX = "tl";
     private static final String TAG = DiscreteRegistry.class.getSimpleName();
 
-    private static final long TIMELINE_HISTORY_CUTOFF = Duration.ofHours(24).toMillis();
-    private static final long TIMELINE_QUANTIZATION = Duration.ofMinutes(1).toMillis();
+    private static final String PROPERTY_DISCRETE_HISTORY_CUTOFF = "discrete_history_cutoff_millis";
+    private static final String PROPERTY_DISCRETE_HISTORY_QUANTIZATION =
+            "discrete_history_quantization_millis";
+    private static final long DEFAULT_DISCRETE_HISTORY_CUTOFF = Duration.ofHours(24).toMillis();
+    private static final long MAXIMUM_DISCRETE_HISTORY_CUTOFF = Duration.ofDays(30).toMillis();
+    private static final long DEFAULT_DISCRETE_HISTORY_QUANTIZATION =
+            Duration.ofMinutes(1).toMillis();
+
+    private static long sDiscreteHistoryCutoff;
+    private static long sDiscreteHistoryQuantization;
 
     private static final String TAG_HISTORY = "h";
     private static final String ATTR_VERSION = "v";
@@ -116,7 +128,7 @@
     private final @NonNull Object mInMemoryLock;
 
     @GuardedBy("mOnDiskLock")
-    private final File mDiscreteAccessDir;
+    private File mDiscreteAccessDir;
 
     @GuardedBy("mInMemoryLock")
     private DiscreteOps mDiscreteOps;
@@ -126,10 +138,42 @@
 
     DiscreteRegistry(Object inMemoryLock) {
         mInMemoryLock = inMemoryLock;
-        mDiscreteAccessDir = new File(new File(Environment.getDataSystemDirectory(), "appops"),
-                "discrete");
-        createDiscreteAccessDir();
-        mDiscreteOps = new DiscreteOps();
+    }
+
+    void systemReady() {
+        synchronized (mOnDiskLock) {
+            mDiscreteAccessDir = new File(new File(Environment.getDataSystemDirectory(), "appops"),
+                    "discrete");
+            createDiscreteAccessDirLocked();
+            mDiscreteOps = new DiscreteOps();
+        }
+        DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_PRIVACY,
+                AsyncTask.THREAD_POOL_EXECUTOR, (DeviceConfig.Properties p) -> {
+                    setDiscreteHistoryParameters(p);
+                });
+        sDiscreteHistoryCutoff = DeviceConfig.getLong(DeviceConfig.NAMESPACE_PRIVACY,
+                PROPERTY_DISCRETE_HISTORY_CUTOFF, DEFAULT_DISCRETE_HISTORY_CUTOFF);
+        sDiscreteHistoryQuantization = DeviceConfig.getLong(DeviceConfig.NAMESPACE_PRIVACY,
+                PROPERTY_DISCRETE_HISTORY_QUANTIZATION, DEFAULT_DISCRETE_HISTORY_QUANTIZATION);
+    }
+
+    private void setDiscreteHistoryParameters(DeviceConfig.Properties p) {
+        if (p.getKeyset().contains(PROPERTY_DISCRETE_HISTORY_CUTOFF)) {
+            sDiscreteHistoryCutoff = p.getLong(PROPERTY_DISCRETE_HISTORY_CUTOFF,
+                    DEFAULT_DISCRETE_HISTORY_CUTOFF);
+            if (!Build.IS_DEBUGGABLE) {
+                sDiscreteHistoryCutoff = min(MAXIMUM_DISCRETE_HISTORY_CUTOFF,
+                        sDiscreteHistoryCutoff);
+            }
+        }
+        if (p.getKeyset().contains(PROPERTY_DISCRETE_HISTORY_QUANTIZATION)) {
+            sDiscreteHistoryQuantization = p.getLong(PROPERTY_DISCRETE_HISTORY_QUANTIZATION,
+                    DEFAULT_DISCRETE_HISTORY_QUANTIZATION);
+            if (!Build.IS_DEBUGGABLE) {
+                sDiscreteHistoryQuantization = max(DEFAULT_DISCRETE_HISTORY_QUANTIZATION,
+                        sDiscreteHistoryQuantization);
+            }
+        }
     }
 
     private void createDiscreteAccessDir() {
@@ -142,6 +186,7 @@
         }
     }
 
+    /* can be called only after HistoricalRegistry.isPersistenceInitialized() check */
     void recordDiscreteAccess(int uid, String packageName, int op, @Nullable String attributionTag,
             @AppOpsManager.OpFlags int flags, @AppOpsManager.UidState int uidState, long accessTime,
             long accessDuration) {
@@ -156,6 +201,10 @@
 
     void writeAndClearAccessHistory() {
         synchronized (mOnDiskLock) {
+            if (mDiscreteAccessDir == null) {
+                Slog.e(TAG, "State not saved - persistence not initialized.");
+                return;
+            }
             final File[] files = mDiscreteAccessDir.listFiles();
             if (files != null && files.length > 0) {
                 for (File f : files) {
@@ -166,7 +215,7 @@
                     try {
                         long timestamp = Long.valueOf(fileName.substring(0,
                                 fileName.length() - TIMELINE_FILE_SUFFIX.length()));
-                        if (Instant.now().minus(TIMELINE_HISTORY_CUTOFF,
+                        if (Instant.now().minus(sDiscreteHistoryCutoff,
                                 ChronoUnit.MILLIS).toEpochMilli() > timestamp) {
                             f.delete();
                             Slog.e(TAG, "Deleting file " + fileName);
@@ -229,7 +278,7 @@
 
     private void readDiscreteOpsFromDisk(DiscreteOps discreteOps) {
         synchronized (mOnDiskLock) {
-            long beginTimeMillis = Instant.now().minus(TIMELINE_HISTORY_CUTOFF,
+            long beginTimeMillis = Instant.now().minus(sDiscreteHistoryCutoff,
                     ChronoUnit.MILLIS).toEpochMilli();
 
             final File[] files = mDiscreteAccessDir.listFiles();
@@ -423,6 +472,16 @@
         }
     }
 
+    private void createDiscreteAccessDirLocked() {
+        if (!mDiscreteAccessDir.exists()) {
+            if (!mDiscreteAccessDir.mkdirs()) {
+                Slog.e(TAG, "Failed to create DiscreteRegistry directory");
+            }
+            FileUtils.setPermissions(mDiscreteAccessDir.getPath(),
+                    FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IXOTH, -1, -1);
+        }
+    }
+
     private final class DiscreteUidOps {
         ArrayMap<String, DiscretePackageOps> mPackages;
 
@@ -663,7 +722,7 @@
                 long accessTime, long accessDuration) {
             List<DiscreteOpEvent> attributedOps = getOrCreateDiscreteOpEventsList(
                     attributionTag);
-            accessTime = accessTime / TIMELINE_QUANTIZATION * TIMELINE_QUANTIZATION;
+            accessTime = accessTime / sDiscreteHistoryQuantization * sDiscreteHistoryQuantization;
 
             int nAttributedOps = attributedOps.size();
             int i = nAttributedOps;
@@ -674,7 +733,7 @@
                 }
                 if (previousOp.mOpFlag == flags && previousOp.mUidState == uidState) {
                     if (accessDuration != previousOp.mNoteDuration
-                            && accessDuration > TIMELINE_QUANTIZATION) {
+                            && accessDuration > sDiscreteHistoryQuantization) {
                         break;
                     } else {
                         return;
diff --git a/services/core/java/com/android/server/appop/HistoricalRegistry.java b/services/core/java/com/android/server/appop/HistoricalRegistry.java
index 4435c47..9ff5492 100644
--- a/services/core/java/com/android/server/appop/HistoricalRegistry.java
+++ b/services/core/java/com/android/server/appop/HistoricalRegistry.java
@@ -246,6 +246,7 @@
                                     + " by which to push history on next write");
                         }
                     }
+                    mDiscreteRegistry.systemReady();
                 }
             }
         }
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index 88dca0c..282a12d 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -80,9 +80,12 @@
     private final @NonNull AudioService mAudioService;
     private final @NonNull Context mContext;
 
-    /** Forced device usage for communications sent to AudioSystem */
-    private AudioDeviceAttributes mPreferredCommunicationDevice;
+    /** ID for Communication strategy retrieved form audio policy manager */
     private int mCommunicationStrategyId = -1;
+    /** Active communication device reported by audio policy manager */
+    private AudioDeviceInfo mActiveCommunicationDevice;
+    /** Last preferred device set for communication strategy */
+    private AudioDeviceAttributes mPreferredCommunicationDevice;
 
     // Manages all connected devices, only ever accessed on the message loop
     private final AudioDeviceInventory mDeviceInventory;
@@ -153,8 +156,9 @@
     private void init() {
         setupMessaging(mContext);
 
-        mPreferredCommunicationDevice = null;
         initCommunicationStrategyId();
+        mPreferredCommunicationDevice = null;
+        updateActiveCommunicationDevice();
 
         mSystemServer.registerUserStartedReceiver(mContext);
     }
@@ -300,7 +304,6 @@
                                         + " from API: " + eventSource)).printLog(TAG));
 
         final boolean wasBtScoRequested = isBluetoothScoRequested();
-        final boolean wasSpeakerphoneRequested = isSpeakerphoneRequested();
         CommunicationRouteClient client;
 
 
@@ -341,16 +344,6 @@
             mBtHelper.stopBluetoothSco(eventSource);
         }
 
-        if (wasSpeakerphoneRequested != isSpeakerphoneRequested()) {
-            try {
-                mContext.sendBroadcastAsUser(
-                        new Intent(AudioManager.ACTION_SPEAKERPHONE_STATE_CHANGED)
-                                .setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY), UserHandle.ALL);
-            } catch (Exception e) {
-                Log.w(TAG, "failed to broadcast ACTION_SPEAKERPHONE_STATE_CHANGED: " + e);
-            }
-        }
-
         sendLMsgNoDelay(MSG_L_UPDATE_COMMUNICATION_ROUTE, SENDMSG_QUEUE, eventSource);
     }
 
@@ -386,66 +379,119 @@
      * Returns the device currently requested for communication use case.
      * @return AudioDeviceInfo the requested device for communication.
      */
-    AudioDeviceInfo getCommunicationDevice() {
+    /* package */ AudioDeviceInfo getCommunicationDevice() {
         synchronized (mDeviceStateLock) {
-            AudioDeviceAttributes device = requestedCommunicationDevice();
-            if (device == null) {
-                AudioAttributes attr =
-                        AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType(
-                                AudioSystem.STREAM_VOICE_CALL);
-                List<AudioDeviceAttributes> devices = AudioSystem.getDevicesForAttributes(attr);
-                if (devices.isEmpty()) {
-                    if (mAudioService.isPlatformVoice()) {
-                        Log.w(TAG, "getCommunicationDevice(): no device for phone strategy");
-                    }
-                    return null;
-                }
-                device = devices.get(0);
-            }
-            return AudioManager.getDeviceInfoFromTypeAndAddress(
-                    device.getType(), device.getAddress());
+            updateActiveCommunicationDevice();
+            return mActiveCommunicationDevice;
         }
     }
 
     /**
-     * Helper method on top of requestedCommunicationDevice() indicating if
+     * Updates currently active communication device (mActiveCommunicationDevice).
+     */
+    @GuardedBy("mDeviceStateLock")
+    void updateActiveCommunicationDevice() {
+        AudioDeviceAttributes device = preferredCommunicationDevice();
+        if (device == null) {
+            AudioAttributes attr =
+                    AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType(
+                            AudioSystem.STREAM_VOICE_CALL);
+            List<AudioDeviceAttributes> devices = AudioSystem.getDevicesForAttributes(attr);
+            if (devices.isEmpty()) {
+                if (mAudioService.isPlatformVoice()) {
+                    Log.w(TAG,
+                            "updateActiveCommunicationDevice(): no device for phone strategy");
+                }
+                mActiveCommunicationDevice = null;
+                return;
+            }
+            device = devices.get(0);
+        }
+        mActiveCommunicationDevice = AudioManager.getDeviceInfoFromTypeAndAddress(
+                device.getType(), device.getAddress());
+    }
+
+    /**
+     * Indicates if the device which type is passed as argument is currently resquested to be used
+     * for communication.
+     * @param deviceType the device type the query applies to.
+     * @return true if this device type is requested for communication.
+     */
+    private boolean isDeviceRequestedForCommunication(int deviceType) {
+        synchronized (mDeviceStateLock) {
+            AudioDeviceAttributes device = requestedCommunicationDevice();
+            return device != null && device.getType() == deviceType;
+        }
+    }
+
+    /**
+     * Indicates if the device which type is passed as argument is currently either resquested
+     * to be used for communication or selected for an other reason (e.g bluetooth SCO audio
+     * is active for SCO device).
+     * @param deviceType the device type the query applies to.
+     * @return true if this device type is requested for communication.
+     */
+    private boolean isDeviceOnForCommunication(int deviceType) {
+        synchronized (mDeviceStateLock) {
+            AudioDeviceAttributes device = preferredCommunicationDevice();
+            return device != null && device.getType() == deviceType;
+        }
+    }
+
+    /**
+     * Indicates if the device which type is passed as argument is active for communication.
+     * Active means not only currently used by audio policy manager for communication strategy
+     * but also explicitly requested for use by communication strategy.
+     * @param deviceType the device type the query applies to.
+     * @return true if this device type is requested for communication.
+     */
+    private boolean isDeviceActiveForCommunication(int deviceType) {
+        return mActiveCommunicationDevice != null
+                && mActiveCommunicationDevice.getType() == deviceType
+                && mPreferredCommunicationDevice != null
+                && mPreferredCommunicationDevice.getType() == deviceType;
+    }
+
+    /**
+     * Helper method on top of isDeviceRequestedForCommunication() indicating if
      * speakerphone ON is currently requested or not.
      * @return true if speakerphone ON requested, false otherwise.
      */
-
     private boolean isSpeakerphoneRequested() {
-        synchronized (mDeviceStateLock) {
-            AudioDeviceAttributes device = requestedCommunicationDevice();
-            return device != null
-                    && device.getType()
-                        == AudioDeviceInfo.TYPE_BUILTIN_SPEAKER;
-        }
+        return isDeviceRequestedForCommunication(AudioDeviceInfo.TYPE_BUILTIN_SPEAKER);
     }
 
     /**
-     * Indicates if active route selection for communication is speakerphone.
+     * Indicates if preferred route selection for communication is speakerphone.
      * @return true if speakerphone is active, false otherwise.
      */
     /*package*/ boolean isSpeakerphoneOn() {
-        AudioDeviceAttributes device = getPreferredCommunicationDevice();
-        if (device == null) {
-            return false;
-        }
-        return device.getInternalType() == AudioSystem.DEVICE_OUT_SPEAKER;
+        return isDeviceOnForCommunication(AudioDeviceInfo.TYPE_BUILTIN_SPEAKER);
+    }
+
+    private boolean isSpeakerphoneActive() {
+        return isDeviceActiveForCommunication(AudioDeviceInfo.TYPE_BUILTIN_SPEAKER);
     }
 
     /**
-     * Helper method on top of requestedCommunicationDevice() indicating if
+     * Helper method on top of isDeviceRequestedForCommunication() indicating if
      * Bluetooth SCO ON is currently requested or not.
      * @return true if Bluetooth SCO ON is requested, false otherwise.
      */
     /*package*/ boolean isBluetoothScoRequested() {
-        synchronized (mDeviceStateLock) {
-            AudioDeviceAttributes device = requestedCommunicationDevice();
-            return device != null
-                    && device.getType()
-                        == AudioDeviceInfo.TYPE_BLUETOOTH_SCO;
-        }
+        return isDeviceRequestedForCommunication(AudioDeviceInfo.TYPE_BLUETOOTH_SCO);
+    }
+
+    /**
+     * Indicates if preferred route selection for communication is Bluetooth SCO.
+     * @return true if Bluetooth SCO is preferred , false otherwise.
+     */
+    /*package*/ boolean isBluetoothScoOn() {
+        return isDeviceOnForCommunication(AudioDeviceInfo.TYPE_BLUETOOTH_SCO);
+    }
+
+    /*package*/ boolean isBluetoothScoActive() {
+        return isDeviceActiveForCommunication(AudioDeviceInfo.TYPE_BLUETOOTH_SCO);
     }
 
     /*package*/ void setWiredDeviceConnectionState(int type,
@@ -593,18 +639,6 @@
         }
     }
 
-    /**
-     * Indicates if active route selection for communication is Bluetooth SCO.
-     * @return true if Bluetooth SCO is active , false otherwise.
-     */
-    /*package*/ boolean isBluetoothScoOn() {
-        AudioDeviceAttributes device = getPreferredCommunicationDevice();
-        if (device == null) {
-            return false;
-        }
-        return AudioSystem.DEVICE_OUT_ALL_SCO_SET.contains(device.getInternalType());
-    }
-
     /*package*/ AudioRoutesInfo startWatchingRoutes(IAudioRoutesObserver observer) {
         synchronized (mDeviceStateLock) {
             return mDeviceInventory.startWatchingRoutes(observer);
@@ -748,8 +782,8 @@
 
     @GuardedBy("mDeviceStateLock")
     private void dispatchCommunicationDevice() {
-        AudioDeviceInfo device = getCommunicationDevice();
-        int portId = (device == null) ? 0 : device.getId();
+        int portId = (mActiveCommunicationDevice == null) ? 0
+                : mActiveCommunicationDevice.getId();
         if (portId == mCurCommunicationPortId) {
             return;
         }
@@ -1022,12 +1056,13 @@
             pw.println("  " + prefix + "pid: " + cl.getPid() + " device: "
                         + cl.getDevice() + " cb: " + cl.getBinder()); });
 
-        pw.println("\n" + prefix + "mPreferredCommunicationDevice: "
+        pw.println("\n" + prefix + "Computed Preferred communication device: "
+                +  preferredCommunicationDevice());
+        pw.println("\n" + prefix + "Applied Preferred communication device: "
                 +  mPreferredCommunicationDevice);
-
-        AudioDeviceInfo device = getCommunicationDevice();
-        pw.println(prefix + "Selected Communication Device: "
-                +  ((device == null) ? "None" : new AudioDeviceAttributes(device)));
+        pw.println(prefix + "Active communication device: "
+                +  ((mActiveCommunicationDevice == null) ? "None"
+                        : new AudioDeviceAttributes(mActiveCommunicationDevice)));
 
         pw.println(prefix + "mCommunicationStrategyId: "
                 +  mCommunicationStrategyId);
@@ -1128,6 +1163,7 @@
                     synchronized (mSetModeLock) {
                         synchronized (mDeviceStateLock) {
                             initCommunicationStrategyId();
+                            updateActiveCommunicationDevice();
                             mDeviceInventory.onRestoreDevices();
                             mBtHelper.onAudioServerDiedRestoreA2dp();
                             onUpdateCommunicationRoute("MSG_RESTORE_DEVICES");
@@ -1340,11 +1376,16 @@
                     final List<AudioDeviceAttributes> devices =
                             (List<AudioDeviceAttributes>) msg.obj;
                     setPreferredDevicesForStrategySync(strategy, devices);
-
+                    if (strategy == mCommunicationStrategyId) {
+                        onUpdatePhoneStrategyDevice(devices.isEmpty() ? null : devices.get(0));
+                    }
                 } break;
                 case MSG_I_REMOVE_PREF_DEVICES_FOR_STRATEGY: {
                     final int strategy = msg.arg1;
                     removePreferredDevicesForStrategySync(strategy);
+                    if (strategy == mCommunicationStrategyId) {
+                        onUpdatePhoneStrategyDevice(null);
+                    }
                 } break;
                 case MSG_CHECK_MUTE_MUSIC:
                     checkMessagesMuteMusic(0);
@@ -1672,14 +1713,14 @@
     }
 
     /**
-     * Determines which forced usage for communication should be sent to audio policy manager
+     * Determines which preferred device for phone strategy should be sent to audio policy manager
      * as a function of current SCO audio activation state and active communication route requests.
      * SCO audio state has the highest priority as it can result from external activation by
      * telephony service.
      * @return selected forced usage for communication.
      */
     @GuardedBy("mDeviceStateLock")
-    @Nullable private AudioDeviceAttributes getPreferredCommunicationDevice() {
+    @Nullable private AudioDeviceAttributes preferredCommunicationDevice() {
         boolean btSCoOn = mBluetoothScoOn && mBtHelper.isBluetoothScoOn();
         if (btSCoOn) {
             // Use the SCO device known to BtHelper so that it matches exactly
@@ -1692,8 +1733,7 @@
             }
         }
         AudioDeviceAttributes device = requestedCommunicationDevice();
-        if (device == null
-                || AudioSystem.DEVICE_OUT_ALL_SCO_SET.contains(device.getInternalType())) {
+        if (device == null || device.getType() == AudioDeviceInfo.TYPE_BLUETOOTH_SCO) {
             // Do not indicate BT SCO selection if SCO is requested but SCO is not ON
             return null;
         }
@@ -1707,30 +1747,49 @@
     // @GuardedBy("mSetModeLock")
     @GuardedBy("mDeviceStateLock")
     private void onUpdateCommunicationRoute(String eventSource) {
-        mPreferredCommunicationDevice = getPreferredCommunicationDevice();
+        AudioDeviceAttributes preferredCommunicationDevice = preferredCommunicationDevice();
         if (AudioService.DEBUG_COMM_RTE) {
-            Log.v(TAG, "onUpdateCommunicationRoute, mPreferredCommunicationDevice: "
-                    + mPreferredCommunicationDevice + " eventSource: " + eventSource);
+            Log.v(TAG, "onUpdateCommunicationRoute, preferredCommunicationDevice: "
+                    + preferredCommunicationDevice + " eventSource: " + eventSource);
         }
         AudioService.sDeviceLogger.log((new AudioEventLogger.StringEvent(
-                "onUpdateCommunicationRoute, mPreferredCommunicationDevice: "
-                + mPreferredCommunicationDevice + " eventSource: " + eventSource)));
+                "onUpdateCommunicationRoute, preferredCommunicationDevice: "
+                + preferredCommunicationDevice + " eventSource: " + eventSource)));
 
-        if (mPreferredCommunicationDevice == null
-                || !AudioSystem.DEVICE_OUT_ALL_SCO_SET.contains(
-                        mPreferredCommunicationDevice.getInternalType())) {
+        if (preferredCommunicationDevice == null
+                || preferredCommunicationDevice.getType() != AudioDeviceInfo.TYPE_BLUETOOTH_SCO) {
             AudioSystem.setParameters("BT_SCO=off");
         } else {
             AudioSystem.setParameters("BT_SCO=on");
         }
-        if (mPreferredCommunicationDevice == null) {
+        if (preferredCommunicationDevice == null) {
             postRemovePreferredDevicesForStrategy(mCommunicationStrategyId);
         } else {
             postSetPreferredDevicesForStrategy(
-                    mCommunicationStrategyId, Arrays.asList(mPreferredCommunicationDevice));
+                    mCommunicationStrategyId, Arrays.asList(preferredCommunicationDevice));
         }
-        mAudioService.postUpdateRingerModeServiceInt();
-        dispatchCommunicationDevice();
+    }
+
+    private void onUpdatePhoneStrategyDevice(AudioDeviceAttributes device) {
+        synchronized (mSetModeLock) {
+            synchronized (mDeviceStateLock) {
+                boolean wasSpeakerphoneActive = isSpeakerphoneActive();
+                mPreferredCommunicationDevice = device;
+                updateActiveCommunicationDevice();
+                if (wasSpeakerphoneActive != isSpeakerphoneActive()) {
+                    try {
+                        mContext.sendBroadcastAsUser(
+                                new Intent(AudioManager.ACTION_SPEAKERPHONE_STATE_CHANGED)
+                                        .setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY),
+                                                  UserHandle.ALL);
+                    } catch (Exception e) {
+                        Log.w(TAG, "failed to broadcast ACTION_SPEAKERPHONE_STATE_CHANGED: " + e);
+                    }
+                }
+                mAudioService.postUpdateRingerModeServiceInt();
+                dispatchCommunicationDevice();
+            }
+        }
     }
 
     private CommunicationRouteClient removeCommunicationRouteClient(
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 804550b..16a9626 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -1836,6 +1836,127 @@
         }
     }
 
+    /** @see AudioManager#isSurroundFormatEnabled(int) */
+    @Override
+    public boolean isSurroundFormatEnabled(int audioFormat) {
+        if (!isSurroundFormat(audioFormat)) {
+            Log.w(TAG, "audioFormat to enable is not a surround format.");
+            return false;
+        }
+        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.WRITE_SETTINGS)
+                != PackageManager.PERMISSION_GRANTED) {
+            throw new SecurityException("Missing WRITE_SETTINGS permission");
+        }
+
+        final long token = Binder.clearCallingIdentity();
+        try {
+            synchronized (mSettingsLock) {
+                HashSet<Integer> enabledFormats = getEnabledFormats();
+                return enabledFormats.contains(audioFormat);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    /** @see AudioManager#setSurroundFormatEnabled(int, boolean) */
+    @Override
+    public boolean setSurroundFormatEnabled(int audioFormat, boolean enabled) {
+        if (!isSurroundFormat(audioFormat)) {
+            Log.w(TAG, "audioFormat to enable is not a surround format.");
+            return false;
+        }
+        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.WRITE_SETTINGS)
+                != PackageManager.PERMISSION_GRANTED) {
+            throw new SecurityException("Missing WRITE_SETTINGS permission");
+        }
+
+        HashSet<Integer> enabledFormats = getEnabledFormats();
+        if (enabled) {
+            enabledFormats.add(audioFormat);
+        } else {
+            enabledFormats.remove(audioFormat);
+        }
+        final long token = Binder.clearCallingIdentity();
+        try {
+            synchronized (mSettingsLock) {
+                Settings.Global.putString(mContentResolver,
+                        Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS,
+                        TextUtils.join(",", enabledFormats));
+            }
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+        return true;
+    }
+
+    /** @see AudioManager#setEncodedSurroundMode(int) */
+    @Override
+    public boolean setEncodedSurroundMode(int mode) {
+        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.WRITE_SETTINGS)
+                != PackageManager.PERMISSION_GRANTED) {
+            throw new SecurityException("Missing WRITE_SETTINGS permission");
+        }
+
+        final long token = Binder.clearCallingIdentity();
+        try {
+            synchronized (mSettingsLock) {
+                Settings.Global.putInt(mContentResolver,
+                        Settings.Global.ENCODED_SURROUND_OUTPUT,
+                        mode);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+        return true;
+    }
+
+    /** @see AudioManager#getEncodedSurroundMode() */
+    @Override
+    public int getEncodedSurroundMode() {
+        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.WRITE_SETTINGS)
+                != PackageManager.PERMISSION_GRANTED) {
+            throw new SecurityException("Missing WRITE_SETTINGS permission");
+        }
+
+        final long token = Binder.clearCallingIdentity();
+        try {
+            synchronized (mSettingsLock) {
+                return Settings.Global.getInt(mContentResolver,
+                        Settings.Global.ENCODED_SURROUND_OUTPUT,
+                        AudioManager.ENCODED_SURROUND_OUTPUT_AUTO);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    /** @return the formats that are enabled in global settings */
+    private HashSet<Integer> getEnabledFormats() {
+        HashSet<Integer> formats = new HashSet<>();
+        String enabledFormats = Settings.Global.getString(mContentResolver,
+                Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS);
+        if (enabledFormats != null) {
+            try {
+                Arrays.stream(TextUtils.split(enabledFormats, ","))
+                        .mapToInt(Integer::parseInt)
+                        .forEach(formats::add);
+            } catch (NumberFormatException e) {
+                Log.w(TAG, "ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS misformatted.", e);
+            }
+        }
+        return formats;
+    }
+
+    private boolean isSurroundFormat(int audioFormat) {
+        for (int sf : AudioFormat.SURROUND_SOUND_ENCODING) {
+            if (sf == audioFormat) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     private void sendEnabledSurroundFormats(ContentResolver cr, boolean forceUpdate) {
         if (mEncodedSurroundMode != Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL) {
             // Manually enable surround formats only when the setting is in manual mode.
@@ -1860,14 +1981,7 @@
         for (String format : surroundFormats) {
             try {
                 int audioFormat = Integer.valueOf(format);
-                boolean isSurroundFormat = false;
-                for (int sf : AudioFormat.SURROUND_SOUND_ENCODING) {
-                    if (sf == audioFormat) {
-                        isSurroundFormat = true;
-                        break;
-                    }
-                }
-                if (isSurroundFormat && !formats.contains(audioFormat)) {
+                if (isSurroundFormat(audioFormat) && !formats.contains(audioFormat)) {
                     formats.add(audioFormat);
                 }
             } catch (Exception e) {
@@ -4078,7 +4192,7 @@
         final boolean ringerModeMute = ringerMode == AudioManager.RINGER_MODE_VIBRATE
                 || ringerMode == AudioManager.RINGER_MODE_SILENT;
         final boolean shouldRingSco = ringerMode == AudioManager.RINGER_MODE_VIBRATE
-                && mDeviceBroker.isBluetoothScoOn();
+                && mDeviceBroker.isBluetoothScoActive();
         // Ask audio policy engine to force use Bluetooth SCO channel if needed
         final String eventSource = "muteRingerModeStreams() from u/pid:" + Binder.getCallingUid()
                 + "/" + Binder.getCallingPid();
@@ -5486,7 +5600,7 @@
         switch (mPlatformType) {
         case AudioSystem.PLATFORM_VOICE:
             if (isInCommunication()) {
-                if (mDeviceBroker.isBluetoothScoOn()) {
+                if (mDeviceBroker.isBluetoothScoActive()) {
                     // Log.v(TAG, "getActiveStreamType: Forcing STREAM_BLUETOOTH_SCO...");
                     return AudioSystem.STREAM_BLUETOOTH_SCO;
                 } else {
@@ -5522,7 +5636,7 @@
             }
         default:
             if (isInCommunication()) {
-                if (mDeviceBroker.isBluetoothScoOn()) {
+                if (mDeviceBroker.isBluetoothScoActive()) {
                     if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_BLUETOOTH_SCO");
                     return AudioSystem.STREAM_BLUETOOTH_SCO;
                 } else {
@@ -7343,7 +7457,6 @@
                     Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO);
             mContentResolver.registerContentObserver(Settings.Global.getUriFor(
                     Settings.Global.ENCODED_SURROUND_OUTPUT), false, this);
-
             mEnabledSurroundFormats = Settings.Global.getString(
                     mContentResolver, Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS);
             mContentResolver.registerContentObserver(Settings.Global.getUriFor(
@@ -7794,7 +7907,24 @@
         mmi.record();
         return mMediaFocusControl.requestAudioFocus(aa, durationHint, cb, fd,
                 clientId, callingPackageName, flags, sdk,
-                forceFocusDuckingForAccessibility(aa, durationHint, uid));
+                forceFocusDuckingForAccessibility(aa, durationHint, uid), -1 /*testUid, ignored*/);
+    }
+
+    /** see {@link AudioManager#requestAudioFocusForTest(AudioFocusRequest, String, int, int)} */
+    public int requestAudioFocusForTest(AudioAttributes aa, int durationHint, IBinder cb,
+            IAudioFocusDispatcher fd, String clientId, String callingPackageName,
+            int fakeUid, int sdk) {
+        if (!enforceQueryAudioStateForTest("focus request")) {
+            return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
+        }
+        if (callingPackageName == null || clientId == null || aa == null) {
+            final String reason = "Invalid null parameter to request audio focus";
+            Log.e(TAG, reason);
+            return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
+        }
+        return mMediaFocusControl.requestAudioFocus(aa, durationHint, cb, fd,
+                clientId, callingPackageName, AudioManager.AUDIOFOCUS_FLAG_TEST,
+                sdk, false /*forceDuck*/, fakeUid);
     }
 
     public int abandonAudioFocus(IAudioFocusDispatcher fd, String clientId, AudioAttributes aa,
@@ -7814,6 +7944,15 @@
         return mMediaFocusControl.abandonAudioFocus(fd, clientId, aa, callingPackageName);
     }
 
+    /** see {@link AudioManager#abandonAudioFocusForTest(AudioFocusRequest, String)} */
+    public int abandonAudioFocusForTest(IAudioFocusDispatcher fd, String clientId,
+            AudioAttributes aa, String callingPackageName) {
+        if (!enforceQueryAudioStateForTest("focus abandon")) {
+            return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
+        }
+        return mMediaFocusControl.abandonAudioFocus(fd, clientId, aa, callingPackageName);
+    }
+
     public void unregisterAudioFocusClient(String clientId) {
         new MediaMetrics.Item(mMetricsId + "focus")
                 .set(MediaMetrics.Property.CLIENT_NAME, clientId)
@@ -7836,6 +7975,25 @@
         return mMediaFocusControl.hasAudioFocusUsers();
     }
 
+    /** see {@link AudioManager#getFadeOutDurationOnFocusLossMillis(AudioAttributes)} */
+    public long getFadeOutDurationOnFocusLossMillis(AudioAttributes aa) {
+        if (!enforceQueryAudioStateForTest("fade out duration")) {
+            return 0;
+        }
+        return mMediaFocusControl.getFadeOutDurationOnFocusLossMillis(aa);
+    }
+
+    private boolean enforceQueryAudioStateForTest(String mssg) {
+        if (PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission(
+                Manifest.permission.QUERY_AUDIO_STATE)) {
+            final String reason = "Doesn't have QUERY_AUDIO_STATE permission for "
+                    + mssg + " test API";
+            Log.e(TAG, reason, new Exception());
+            return false;
+        }
+        return true;
+    }
+
     //==========================================================================================
     private boolean readCameraSoundForced() {
         return SystemProperties.getBoolean("audio.camerasound.force", false) ||
diff --git a/services/core/java/com/android/server/audio/FadeOutManager.java b/services/core/java/com/android/server/audio/FadeOutManager.java
index 9f0a2ba..e08bd67 100644
--- a/services/core/java/com/android/server/audio/FadeOutManager.java
+++ b/services/core/java/com/android/server/audio/FadeOutManager.java
@@ -97,6 +97,16 @@
         return true;
     }
 
+    static long getFadeOutDurationOnFocusLossMillis(AudioAttributes aa) {
+        if (ArrayUtils.contains(UNFADEABLE_CONTENT_TYPES, aa.getContentType())) {
+            return 0;
+        }
+        if (!ArrayUtils.contains(FADEABLE_USAGES, aa.getUsage())) {
+            return 0;
+        }
+        return FADE_OUT_DURATION_MS;
+    }
+
     /**
      * Map of uid (key) to faded out apps (value)
      */
diff --git a/services/core/java/com/android/server/audio/MediaFocusControl.java b/services/core/java/com/android/server/audio/MediaFocusControl.java
index 1dcfdae..0310215 100644
--- a/services/core/java/com/android/server/audio/MediaFocusControl.java
+++ b/services/core/java/com/android/server/audio/MediaFocusControl.java
@@ -862,11 +862,13 @@
      * @param forceDuck only true if
      *     {@link android.media.AudioFocusRequest.Builder#setFocusGain(int)} was set to true for
      *                  accessibility.
+     * @param testUid ignored if flags is not AudioManager.AUDIOFOCUS_FLAG_TEST (strictly equals to)
+     *                otherwise the UID being injected for testing
      * @return
      */
     protected int requestAudioFocus(@NonNull AudioAttributes aa, int focusChangeHint, IBinder cb,
             IAudioFocusDispatcher fd, @NonNull String clientId, @NonNull String callingPackageName,
-            int flags, int sdk, boolean forceDuck) {
+            int flags, int sdk, boolean forceDuck, int testUid) {
         new MediaMetrics.Item(mMetricsId)
                 .setUid(Binder.getCallingUid())
                 .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackageName)
@@ -878,8 +880,13 @@
                 //.set(MediaMetrics.Property.SDK, sdk)
                 .record();
 
+        // when using the test API, a fake UID can be injected (testUid is ignored otherwise)
+        // note that the test on flags is not a mask test on purpose, AUDIOFOCUS_FLAG_TEST is
+        // supposed to be alone in bitfield
+        final int uid = (flags == AudioManager.AUDIOFOCUS_FLAG_TEST)
+                ? testUid : Binder.getCallingUid();
         mEventLogger.log((new AudioEventLogger.StringEvent(
-                "requestAudioFocus() from uid/pid " + Binder.getCallingUid()
+                "requestAudioFocus() from uid/pid " + uid
                     + "/" + Binder.getCallingPid()
                     + " clientId=" + clientId + " callingPack=" + callingPackageName
                     + " req=" + focusChangeHint
@@ -892,8 +899,10 @@
             return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
         }
 
-        if (mAppOps.noteOp(AppOpsManager.OP_TAKE_AUDIO_FOCUS, Binder.getCallingUid(),
-                callingPackageName) != AppOpsManager.MODE_ALLOWED) {
+        if ((flags != AudioManager.AUDIOFOCUS_FLAG_TEST)
+                // note we're using the real uid for appOp evaluation
+                && (mAppOps.noteOp(AppOpsManager.OP_TAKE_AUDIO_FOCUS, Binder.getCallingUid(),
+                        callingPackageName) != AppOpsManager.MODE_ALLOWED)) {
             return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
         }
 
@@ -910,7 +919,7 @@
             final AudioFocusInfo afiForExtPolicy;
             if (mFocusPolicy != null) {
                 // construct AudioFocusInfo as it will be communicated to audio focus policy
-                afiForExtPolicy = new AudioFocusInfo(aa, Binder.getCallingUid(),
+                afiForExtPolicy = new AudioFocusInfo(aa, uid,
                         clientId, callingPackageName, focusChangeHint, 0 /*lossReceived*/,
                         flags, sdk);
             } else {
@@ -980,7 +989,7 @@
             removeFocusStackEntry(clientId, false /* signal */, false /*notifyFocusFollowers*/);
 
             final FocusRequester nfr = new FocusRequester(aa, focusChangeHint, flags, fd, cb,
-                    clientId, afdh, callingPackageName, Binder.getCallingUid(), this, sdk);
+                    clientId, afdh, callingPackageName, uid, this, sdk);
 
             if (mMultiAudioFocusEnabled
                     && (focusChangeHint == AudioManager.AUDIOFOCUS_GAIN)) {
@@ -1143,6 +1152,13 @@
         return mMultiAudioFocusEnabled;
     }
 
+    /*package*/ long getFadeOutDurationOnFocusLossMillis(AudioAttributes aa) {
+        if (!ENFORCE_FADEOUT_FOR_FOCUS_LOSS) {
+            return 0;
+        }
+        return FadeOutManager.getFadeOutDurationOnFocusLossMillis(aa);
+    }
+
     private void dumpMultiAudioFocus(PrintWriter pw) {
         pw.println("Multi Audio Focus enabled :" + mMultiAudioFocusEnabled);
         if (!mMultiAudioFocusList.isEmpty()) {
diff --git a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
index 47c91e6..e71219f 100644
--- a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
+++ b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
@@ -704,6 +704,7 @@
         // find which players to fade out
         synchronized (mPlayerLock) {
             if (mPlayers.isEmpty()) {
+                if (DEBUG) { Log.v(TAG, "no players to fade out"); }
                 return false;
             }
             // check if this UID needs to be faded out (return false if not), and gather list of
@@ -731,8 +732,6 @@
                     apcsToFadeOut.add(apc);
                 }
             }
-            //###
-            //mDuckingManager.duckUid(loser.getClientUid(), apcsToFadeOut);
             if (loserHasActivePlayers) {
                 mFadingManager.fadeOutUid(loser.getClientUid(), apcsToFadeOut);
             }
diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java
index 63e7b4b..70f26ac 100644
--- a/services/core/java/com/android/server/biometrics/BiometricService.java
+++ b/services/core/java/com/android/server/biometrics/BiometricService.java
@@ -766,15 +766,18 @@
         public long[] getAuthenticatorIds(int callingUserId) {
             checkInternalPermission();
 
-            final List<Long> ids = new ArrayList<>();
+            final List<Long> authenticatorIds = new ArrayList<>();
             for (BiometricSensor sensor : mSensors) {
                 try {
-                    final long id = sensor.impl.getAuthenticatorId(callingUserId);
-                    if (Utils.isAtLeastStrength(sensor.getCurrentStrength(),
-                            Authenticators.BIOMETRIC_STRONG) && id != 0) {
-                        ids.add(id);
+                    final boolean hasEnrollments = sensor.impl.hasEnrolledTemplates(callingUserId,
+                            getContext().getOpPackageName());
+                    final long authenticatorId = sensor.impl.getAuthenticatorId(callingUserId);
+                    if (hasEnrollments && Utils.isAtLeastStrength(sensor.getCurrentStrength(),
+                            Authenticators.BIOMETRIC_STRONG)) {
+                        authenticatorIds.add(authenticatorId);
                     } else {
-                        Slog.d(TAG, "Sensor " + sensor + ", sensorId " + id
+                        Slog.d(TAG, "Sensor " + sensor + ", sensorId " + sensor.id
+                                + ", hasEnrollments: " + hasEnrollments
                                 + " cannot participate in Keystore operations");
                     }
                 } catch (RemoteException e) {
@@ -782,9 +785,9 @@
                 }
             }
 
-            long[] result = new long[ids.size()];
-            for (int i = 0; i < ids.size(); i++) {
-                result[i] = ids.get(i);
+            long[] result = new long[authenticatorIds.size()];
+            for (int i = 0; i < authenticatorIds.size(); i++) {
+                result[i] = authenticatorIds.get(i);
             }
             return result;
         }
diff --git a/services/core/java/com/android/server/biometrics/sensors/BaseClientMonitor.java b/services/core/java/com/android/server/biometrics/sensors/BaseClientMonitor.java
index 81ce2d5..677ea5d 100644
--- a/services/core/java/com/android/server/biometrics/sensors/BaseClientMonitor.java
+++ b/services/core/java/com/android/server/biometrics/sensors/BaseClientMonitor.java
@@ -52,7 +52,8 @@
          *
          * @param clientMonitor Reference of the ClientMonitor that is starting.
          */
-        default void onClientStarted(@NonNull BaseClientMonitor clientMonitor) {}
+        default void onClientStarted(@NonNull BaseClientMonitor clientMonitor) {
+        }
 
         /**
          * Invoked when the ClientMonitor operation is complete. This abstracts away asynchronous
@@ -63,10 +64,11 @@
          * @param clientMonitor Reference of the ClientMonitor that finished.
          * @param success True if the operation completed successfully.
          */
-        default void onClientFinished(@NonNull BaseClientMonitor clientMonitor, boolean success) {}
+        default void onClientFinished(@NonNull BaseClientMonitor clientMonitor, boolean success) {
+        }
     }
 
-    protected final int mSequentialId;
+    private final int mSequentialId;
     @NonNull private final Context mContext;
     private final int mTargetUserId;
     @NonNull private final String mOwner;
@@ -197,7 +199,7 @@
         return mListener;
     }
 
-    public final int getTargetUserId() {
+    public int getTargetUserId() {
         return mTargetUserId;
     }
 
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 20c25c3..6c480f1 100644
--- a/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java
+++ b/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java
@@ -55,7 +55,7 @@
 
     private static final String BASE_TAG = "BiometricScheduler";
     // Number of recent operations to keep in our logs for dumpsys
-    private static final int LOG_NUM_RECENT_OPERATIONS = 50;
+    protected static final int LOG_NUM_RECENT_OPERATIONS = 50;
 
     /**
      * Contains all the necessary information for a HAL operation.
@@ -196,10 +196,10 @@
         }
     }
 
-    @NonNull private final String mBiometricTag;
+    @NonNull protected final String mBiometricTag;
     @Nullable private final GestureAvailabilityDispatcher mGestureAvailabilityDispatcher;
     @NonNull private final IBiometricService mBiometricService;
-    @NonNull private final Handler mHandler = new Handler(Looper.getMainLooper());
+    @NonNull protected final Handler mHandler = new Handler(Looper.getMainLooper());
     @NonNull private final InternalCallback mInternalCallback;
     @VisibleForTesting @NonNull final Deque<Operation> mPendingOperations;
     @VisibleForTesting @Nullable Operation mCurrentOperation;
@@ -294,11 +294,11 @@
         return mInternalCallback;
     }
 
-    private String getTag() {
+    protected String getTag() {
         return BASE_TAG + "/" + mBiometricTag;
     }
 
-    private void startNextOperationIfIdle() {
+    protected void startNextOperationIfIdle() {
         if (mCurrentOperation != null) {
             Slog.v(getTag(), "Not idle, current operation: " + mCurrentOperation);
             return;
@@ -310,6 +310,7 @@
 
         mCurrentOperation = mPendingOperations.poll();
         final BaseClientMonitor currentClient = mCurrentOperation.mClientMonitor;
+        Slog.d(getTag(), "[Polled] " + mCurrentOperation);
 
         // If the operation at the front of the queue has been marked for cancellation, send
         // ERROR_CANCELED. No need to start this client.
diff --git a/services/core/java/com/android/server/biometrics/sensors/StartUserClient.java b/services/core/java/com/android/server/biometrics/sensors/StartUserClient.java
new file mode 100644
index 0000000..3d69326
--- /dev/null
+++ b/services/core/java/com/android/server/biometrics/sensors/StartUserClient.java
@@ -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.
+ */
+
+package com.android.server.biometrics.sensors;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.hardware.biometrics.BiometricsProtoEnums;
+import android.os.IBinder;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.biometrics.BiometricsProto;
+
+/**
+ * Abstract class for starting a new user.
+ * @param <T> Interface to request a new user.
+ * @param <U> Newly created user object.
+ */
+public abstract class StartUserClient<T, U>  extends HalClientMonitor<T> {
+
+    /**
+     * Invoked when the new user is started.
+     * @param <U> New user object.
+     */
+    public interface UserStartedCallback<U> {
+        void onUserStarted(int newUserId, U newUser);
+    }
+
+    @NonNull @VisibleForTesting
+    protected final UserStartedCallback<U> mUserStartedCallback;
+
+    public StartUserClient(@NonNull Context context, @NonNull LazyDaemon<T> lazyDaemon,
+            @Nullable IBinder token, int userId, int sensorId,
+            @NonNull UserStartedCallback<U> callback) {
+        super(context, lazyDaemon, token, null /* listener */, userId, context.getOpPackageName(),
+                0 /* cookie */, sensorId, BiometricsProtoEnums.MODALITY_UNKNOWN,
+                BiometricsProtoEnums.ACTION_UNKNOWN, BiometricsProtoEnums.CLIENT_UNKNOWN);
+        mUserStartedCallback = callback;
+    }
+
+    @Override
+    public int getProtoEnum() {
+        return BiometricsProto.CM_START_USER;
+    }
+}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/biometrics/sensors/StopUserClient.java b/services/core/java/com/android/server/biometrics/sensors/StopUserClient.java
new file mode 100644
index 0000000..1f6e1e9
--- /dev/null
+++ b/services/core/java/com/android/server/biometrics/sensors/StopUserClient.java
@@ -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.
+ */
+
+package com.android.server.biometrics.sensors;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.hardware.biometrics.BiometricsProtoEnums;
+import android.os.IBinder;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.biometrics.BiometricsProto;
+
+/**
+ * Abstract class for stopping a user.
+ * @param <T> Interface for stopping the user.
+ */
+public abstract class StopUserClient<T> extends HalClientMonitor<T> {
+
+    public interface UserStoppedCallback {
+        void onUserStopped();
+    }
+
+    @NonNull @VisibleForTesting
+    private final UserStoppedCallback mUserStoppedCallback;
+
+    public void onUserStopped() {
+        mUserStoppedCallback.onUserStopped();
+        getCallback().onClientFinished(this, true /* success */);
+    }
+
+    public StopUserClient(@NonNull Context context, @NonNull LazyDaemon<T> lazyDaemon,
+            @Nullable IBinder token, int userId, int sensorId,
+            @NonNull UserStoppedCallback callback) {
+        super(context, lazyDaemon, token, null /* listener */, userId, context.getOpPackageName(),
+                0 /* cookie */, sensorId, BiometricsProtoEnums.MODALITY_UNKNOWN,
+                BiometricsProtoEnums.ACTION_UNKNOWN, BiometricsProtoEnums.CLIENT_UNKNOWN);
+        mUserStoppedCallback = callback;
+    }
+
+    @Override
+    public int getProtoEnum() {
+        return BiometricsProto.CM_STOP_USER;
+    }
+}
diff --git a/services/core/java/com/android/server/biometrics/sensors/UserAwareBiometricScheduler.java b/services/core/java/com/android/server/biometrics/sensors/UserAwareBiometricScheduler.java
new file mode 100644
index 0000000..f015a80
--- /dev/null
+++ b/services/core/java/com/android/server/biometrics/sensors/UserAwareBiometricScheduler.java
@@ -0,0 +1,140 @@
+/*
+ * 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.biometrics.sensors;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.hardware.biometrics.IBiometricService;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+import android.util.Slog;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.biometrics.sensors.fingerprint.GestureAvailabilityDispatcher;
+
+/**
+ * A user-aware scheduler that requests user-switches based on scheduled operation's targetUserId.
+ */
+public class UserAwareBiometricScheduler extends BiometricScheduler {
+
+    private static final String BASE_TAG = "UaBiometricScheduler";
+
+    /**
+     * Interface to retrieve the owner's notion of the current userId. Note that even though
+     * the scheduler can determine this based on its history of processed clients, we should still
+     * query the owner since it may be cleared due to things like HAL death, etc.
+     */
+    public interface CurrentUserRetriever {
+        int getCurrentUserId();
+    }
+
+    public interface UserSwitchCallback {
+        @NonNull StopUserClient<?> getStopUserClient(int userId);
+        @NonNull StartUserClient<?, ?> getStartUserClient(int newUserId);
+    }
+
+    @NonNull private final CurrentUserRetriever mCurrentUserRetriever;
+    @NonNull private final UserSwitchCallback mUserSwitchCallback;
+    @NonNull @VisibleForTesting final ClientFinishedCallback mClientFinishedCallback;
+
+    @Nullable private StopUserClient<?> mStopUserClient;
+
+    @VisibleForTesting
+    class ClientFinishedCallback implements BaseClientMonitor.Callback {
+        @Override
+        public void onClientFinished(@NonNull BaseClientMonitor clientMonitor, boolean success) {
+            mHandler.post(() -> {
+                Slog.d(getTag(), "[Client finished] " + clientMonitor + ", success: " + success);
+
+                startNextOperationIfIdle();
+            });
+        }
+    }
+
+    @VisibleForTesting
+    UserAwareBiometricScheduler(@NonNull String tag,
+            @Nullable GestureAvailabilityDispatcher gestureAvailabilityDispatcher,
+            @NonNull IBiometricService biometricService,
+            @NonNull CurrentUserRetriever currentUserRetriever,
+            @NonNull UserSwitchCallback userSwitchCallback) {
+        super(tag, gestureAvailabilityDispatcher, biometricService, LOG_NUM_RECENT_OPERATIONS);
+
+        mCurrentUserRetriever = currentUserRetriever;
+        mUserSwitchCallback = userSwitchCallback;
+        mClientFinishedCallback = new ClientFinishedCallback();
+    }
+
+    public UserAwareBiometricScheduler(@NonNull String tag,
+            @Nullable GestureAvailabilityDispatcher gestureAvailabilityDispatcher,
+            @NonNull CurrentUserRetriever currentUserRetriever,
+            @NonNull UserSwitchCallback userSwitchCallback) {
+        this(tag, gestureAvailabilityDispatcher, IBiometricService.Stub.asInterface(
+                ServiceManager.getService(Context.BIOMETRIC_SERVICE)), currentUserRetriever,
+                userSwitchCallback);
+    }
+
+    @Override
+    protected String getTag() {
+        return BASE_TAG + "/" + mBiometricTag;
+    }
+
+    @Override
+    protected void startNextOperationIfIdle() {
+        if (mCurrentOperation != null) {
+            Slog.v(getTag(), "Not idle, current operation: " + mCurrentOperation);
+            return;
+        }
+        if (mPendingOperations.isEmpty()) {
+            Slog.d(getTag(), "No operations, returning to idle");
+            return;
+        }
+
+        final int currentUserId = mCurrentUserRetriever.getCurrentUserId();
+        final int nextUserId = mPendingOperations.getFirst().mClientMonitor.getTargetUserId();
+
+        if (nextUserId == currentUserId) {
+            super.startNextOperationIfIdle();
+        } else if (currentUserId == UserHandle.USER_NULL) {
+            final BaseClientMonitor startClient =
+                    mUserSwitchCallback.getStartUserClient(nextUserId);
+            Slog.d(getTag(), "[Starting User] " + startClient);
+            startClient.start(mClientFinishedCallback);
+        } else {
+            if (mStopUserClient != null) {
+                Slog.d(getTag(), "[Waiting for StopUser] " + mStopUserClient);
+            } else {
+                mStopUserClient = mUserSwitchCallback
+                        .getStopUserClient(currentUserId);
+                Slog.d(getTag(), "[Stopping User] current: " + currentUserId
+                        + ", next: " + nextUserId + ". " + mStopUserClient);
+                mStopUserClient.start(mClientFinishedCallback);
+            }
+        }
+    }
+
+    public void onUserStopped() {
+        if (mStopUserClient == null) {
+            Slog.e(getTag(), "Unexpected onUserStopped");
+            return;
+        }
+
+        Slog.d(getTag(), "[OnUserStopped]: " + mStopUserClient);
+        mStopUserClient.onUserStopped();
+        mStopUserClient = null;
+    }
+}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
index 9f5dc69..d10fd4f 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
@@ -502,9 +502,6 @@
                 return false;
             }
 
-            final boolean enrolled = provider.getEnrolledFaces(sensorId, userId).size() > 0;
-            Slog.d(TAG, "hasEnrolledFaces, sensor: " + sensorId + ", enrolled: " + enrolled);
-
             return provider.getEnrolledFaces(sensorId, userId).size() > 0;
         }
 
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java
index 07d173c..0c883b0 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java
@@ -92,7 +92,7 @@
     @Override
     protected void startHalOperation() {
         try {
-            mCancellationSignal = getFreshDaemon().authenticate(mSequentialId, mOperationId);
+            mCancellationSignal = getFreshDaemon().authenticate(mOperationId);
         } catch (RemoteException e) {
             Slog.e(TAG, "Remote exception when requesting auth", e);
             onError(BiometricFaceConstants.FACE_ERROR_HW_UNAVAILABLE, 0 /* vendorCode */);
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceEnrollClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceEnrollClient.java
index 0eb51fd..58eb3ba 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceEnrollClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceEnrollClient.java
@@ -160,7 +160,7 @@
                 features = new byte[0];
             }
 
-            mCancellationSignal = getFreshDaemon().enroll(mSequentialId,
+            mCancellationSignal = getFreshDaemon().enroll(
                     HardwareAuthTokenUtils.toHardwareAuthToken(mHardwareAuthToken),
                     EnrollmentType.DEFAULT, features, mPreviewSurface);
         } catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceGenerateChallengeClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceGenerateChallengeClient.java
index 7a846f5..8cbb896 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceGenerateChallengeClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceGenerateChallengeClient.java
@@ -42,7 +42,7 @@
     @Override
     protected void startHalOperation() {
         try {
-            getFreshDaemon().generateChallenge(mSequentialId);
+            getFreshDaemon().generateChallenge();
         } catch (RemoteException e) {
             Slog.e(TAG, "Unable to generateChallenge", e);
         }
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceGetAuthenticatorIdClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceGetAuthenticatorIdClient.java
index 773647b..af826c2 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceGetAuthenticatorIdClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceGetAuthenticatorIdClient.java
@@ -56,7 +56,7 @@
     @Override
     protected void startHalOperation() {
         try {
-            getFreshDaemon().getAuthenticatorId(mSequentialId);
+            getFreshDaemon().getAuthenticatorId();
         } catch (RemoteException e) {
             Slog.e(TAG, "Remote exception", e);
         }
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceInternalEnumerateClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceInternalEnumerateClient.java
index 75888a5..0ece884 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceInternalEnumerateClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceInternalEnumerateClient.java
@@ -48,7 +48,7 @@
     @Override
     protected void startHalOperation() {
         try {
-            getFreshDaemon().enumerateEnrollments(mSequentialId);
+            getFreshDaemon().enumerateEnrollments();
         } catch (RemoteException e) {
             Slog.e(TAG, "Remote exception when requesting enumerate", e);
             mCallback.onClientFinished(this, false /* success */);
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceInvalidationClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceInvalidationClient.java
index 855ee1d..405e2b2 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceInvalidationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceInvalidationClient.java
@@ -40,7 +40,7 @@
     @Override
     protected void startHalOperation() {
         try {
-            getFreshDaemon().invalidateAuthenticatorId(mSequentialId);
+            getFreshDaemon().invalidateAuthenticatorId();
         } catch (RemoteException e) {
             Slog.e(TAG, "Remote exception", e);
             mCallback.onClientFinished(this, false /* success */);
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java
index ca29057..a9be8e1 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java
@@ -78,7 +78,6 @@
     @NonNull private final String mHalInstanceName;
     @NonNull @VisibleForTesting
     final SparseArray<Sensor> mSensors; // Map of sensors that this HAL supports
-    @NonNull private final HalClientMonitor.LazyDaemon<IFace> mLazyDaemon;
     @NonNull private final Handler mHandler;
     @NonNull private final LockoutResetDispatcher mLockoutResetDispatcher;
     @NonNull private final UsageStats mUsageStats;
@@ -126,7 +125,6 @@
         mContext = context;
         mHalInstanceName = halInstanceName;
         mSensors = new SparseArray<>();
-        mLazyDaemon = this::getHalInstance;
         mHandler = new Handler(Looper.getMainLooper());
         mUsageStats = new UsageStats(context);
         mLockoutResetDispatcher = lockoutResetDispatcher;
@@ -163,7 +161,8 @@
     }
 
     @Nullable
-    private synchronized IFace getHalInstance() {
+    @VisibleForTesting
+    synchronized IFace getHalInstance() {
         if (mTestHalEnabled) {
             return new TestHal();
         }
@@ -214,22 +213,6 @@
         mSensors.get(sensorId).getScheduler().scheduleClientMonitor(client, callback);
     }
 
-    private void createNewSessionWithoutHandler(@NonNull IFace daemon, int sensorId,
-            int userId) throws RemoteException {
-        // Note that per IFace createSession contract, this method will block until all
-        // existing operations are canceled/finished. However, also note that this is fine, since
-        // this method "withoutHandler" means it should only ever be invoked from the worker thread,
-        // so callers will never be blocked.
-        mSensors.get(sensorId).createNewSession(daemon, sensorId, userId);
-
-        if (FaceUtils.getInstance(sensorId).isInvalidationInProgress(mContext, userId)) {
-            Slog.w(getTag(), "Scheduling unfinished invalidation request for sensor: " + sensorId
-                    + ", user: " + userId);
-            scheduleInvalidationRequest(sensorId, userId);
-        }
-    }
-
-
     private void scheduleLoadAuthenticatorIds(int sensorId) {
         for (UserInfo user : UserManager.get(mContext).getAliveUsers()) {
             scheduleLoadAuthenticatorIdsForUser(sensorId, user.id);
@@ -238,37 +221,21 @@
 
     private void scheduleLoadAuthenticatorIdsForUser(int sensorId, int userId) {
         mHandler.post(() -> {
-            final IFace daemon = getHalInstance();
-            if (daemon == null) {
-                Slog.e(getTag(), "Null daemon during loadAuthenticatorIds, sensorId: " + sensorId);
-                return;
-            }
+            final FaceGetAuthenticatorIdClient client = new FaceGetAuthenticatorIdClient(
+                    mContext, mSensors.get(sensorId).getLazySession(), userId,
+                    mContext.getOpPackageName(), sensorId,
+                    mSensors.get(sensorId).getAuthenticatorIds());
 
-            try {
-                if (!mSensors.get(sensorId).hasSessionForUser(userId)) {
-                    createNewSessionWithoutHandler(daemon, sensorId, userId);
-                }
-
-                final FaceGetAuthenticatorIdClient client = new FaceGetAuthenticatorIdClient(
-                        mContext, mSensors.get(sensorId).getLazySession(), userId,
-                        mContext.getOpPackageName(), sensorId,
-                        mSensors.get(sensorId).getAuthenticatorIds());
-
-                mSensors.get(sensorId).getScheduler().scheduleClientMonitor(client);
-            } catch (RemoteException e) {
-                Slog.e(getTag(), "Remote exception when scheduling loadAuthenticatorId"
-                        + ", sensorId: " + sensorId
-                        + ", userId: " + userId, e);
-            }
+            scheduleForSensor(sensorId, client);
         });
     }
 
-    private void scheduleInvalidationRequest(int sensorId, int userId) {
+    void scheduleInvalidationRequest(int sensorId, int userId) {
         mHandler.post(() -> {
             final InvalidationRequesterClient<Face> client =
                     new InvalidationRequesterClient<>(mContext, userId, sensorId,
                             FaceUtils.getInstance(sensorId));
-            mSensors.get(sensorId).getScheduler().scheduleClientMonitor(client);
+            scheduleForSensor(sensorId, client);
         });
     }
 
@@ -303,25 +270,10 @@
     public void scheduleInvalidateAuthenticatorId(int sensorId, int userId,
             @NonNull IInvalidationCallback callback) {
         mHandler.post(() -> {
-            final IFace daemon = getHalInstance();
-            if (daemon == null) {
-                Slog.e(getTag(), "Null daemon during scheduleInvalidateAuthenticatorId: "
-                        + sensorId);
-                return;
-            }
-
-            try {
-                if (!mSensors.get(sensorId).hasSessionForUser(userId)) {
-                    createNewSessionWithoutHandler(daemon, sensorId, userId);
-                }
-
-                final FaceInvalidationClient client = new FaceInvalidationClient(mContext,
-                        mSensors.get(sensorId).getLazySession(), userId, sensorId,
-                        mSensors.get(sensorId).getAuthenticatorIds(), callback);
-                mSensors.get(sensorId).getScheduler().scheduleClientMonitor(client);
-            } catch (RemoteException e) {
-                Slog.e(getTag(), "Remote exception", e);
-            }
+            final FaceInvalidationClient client = new FaceInvalidationClient(mContext,
+                    mSensors.get(sensorId).getLazySession(), userId, sensorId,
+                    mSensors.get(sensorId).getAuthenticatorIds(), callback);
+            scheduleForSensor(sensorId, client);
         });
     }
 
@@ -344,25 +296,10 @@
     public void scheduleGenerateChallenge(int sensorId, int userId, @NonNull IBinder token,
             @NonNull IFaceServiceReceiver receiver, String opPackageName) {
         mHandler.post(() -> {
-            final IFace daemon = getHalInstance();
-            if (daemon == null) {
-                Slog.e(getTag(), "Null daemon during generateChallenge, sensorId: " + sensorId);
-                return;
-            }
-
-            try {
-                if (!mSensors.get(sensorId).hasSessionForUser(userId)) {
-                    createNewSessionWithoutHandler(daemon, sensorId, userId);
-                }
-
-                final FaceGenerateChallengeClient client = new FaceGenerateChallengeClient(mContext,
-                        mSensors.get(sensorId).getLazySession(), token,
-                        new ClientMonitorCallbackConverter(receiver), opPackageName, sensorId);
-
-                scheduleForSensor(sensorId, client);
-            } catch (RemoteException e) {
-                Slog.e(getTag(), "Remote exception when scheduling generateChallenge", e);
-            }
+            final FaceGenerateChallengeClient client = new FaceGenerateChallengeClient(mContext,
+                    mSensors.get(sensorId).getLazySession(), token,
+                    new ClientMonitorCallbackConverter(receiver), opPackageName, sensorId);
+            scheduleForSensor(sensorId, client);
         });
     }
 
@@ -370,25 +307,10 @@
     public void scheduleRevokeChallenge(int sensorId, int userId, @NonNull IBinder token,
             @NonNull String opPackageName, long challenge) {
         mHandler.post(() -> {
-            final IFace daemon = getHalInstance();
-            if (daemon == null) {
-                Slog.e(getTag(), "Null daemon during revokeChallenge, sensorId: " + sensorId);
-                return;
-            }
-
-            try {
-                if (!mSensors.get(sensorId).hasSessionForUser(userId)) {
-                    createNewSessionWithoutHandler(daemon, sensorId, userId);
-                }
-
-                final FaceRevokeChallengeClient client = new FaceRevokeChallengeClient(mContext,
-                        mSensors.get(sensorId).getLazySession(), token, opPackageName, sensorId,
-                        challenge);
-
-                scheduleForSensor(sensorId, client);
-            } catch (RemoteException e) {
-                Slog.e(getTag(), "Remote exception when scheduling revokeChallenge", e);
-            }
+            final FaceRevokeChallengeClient client = new FaceRevokeChallengeClient(mContext,
+                    mSensors.get(sensorId).getLazySession(), token, opPackageName, sensorId,
+                    challenge);
+            scheduleForSensor(sensorId, client);
         });
     }
 
@@ -398,41 +320,24 @@
             @NonNull String opPackageName, @NonNull int[] disabledFeatures,
             @Nullable NativeHandle previewSurface, boolean debugConsent) {
         mHandler.post(() -> {
-            final IFace daemon = getHalInstance();
-            if (daemon == null) {
-                Slog.e(getTag(), "Null daemon during enroll, sensorId: " + sensorId);
-                // If this happens, we need to send HW_UNAVAILABLE after the scheduler gets to
-                // this operation. We should not send the callback yet, since the scheduler may
-                // be processing something else.
-                return;
-            }
-
-            try {
-                if (!mSensors.get(sensorId).hasSessionForUser(userId)) {
-                    createNewSessionWithoutHandler(daemon, sensorId, userId);
-                }
-
-                final int maxTemplatesPerUser = mSensors.get(
-                        sensorId).getSensorProperties().maxEnrollmentsPerUser;
-                final FaceEnrollClient client = new FaceEnrollClient(mContext,
-                        mSensors.get(sensorId).getLazySession(), token,
-                        new ClientMonitorCallbackConverter(receiver), userId, hardwareAuthToken,
-                        opPackageName, FaceUtils.getInstance(sensorId), disabledFeatures,
-                        ENROLL_TIMEOUT_SEC, previewSurface, sensorId, maxTemplatesPerUser,
-                        debugConsent);
-                scheduleForSensor(sensorId, client, new BaseClientMonitor.Callback() {
-                    @Override
-                    public void onClientFinished(@NonNull BaseClientMonitor clientMonitor,
-                            boolean success) {
-                        if (success) {
-                            scheduleLoadAuthenticatorIdsForUser(sensorId, userId);
-                            scheduleInvalidationRequest(sensorId, userId);
-                        }
+            final int maxTemplatesPerUser = mSensors.get(
+                    sensorId).getSensorProperties().maxEnrollmentsPerUser;
+            final FaceEnrollClient client = new FaceEnrollClient(mContext,
+                    mSensors.get(sensorId).getLazySession(), token,
+                    new ClientMonitorCallbackConverter(receiver), userId, hardwareAuthToken,
+                    opPackageName, FaceUtils.getInstance(sensorId), disabledFeatures,
+                    ENROLL_TIMEOUT_SEC, previewSurface, sensorId, maxTemplatesPerUser,
+                    debugConsent);
+            scheduleForSensor(sensorId, client, new BaseClientMonitor.Callback() {
+                @Override
+                public void onClientFinished(@NonNull BaseClientMonitor clientMonitor,
+                        boolean success) {
+                    if (success) {
+                        scheduleLoadAuthenticatorIdsForUser(sensorId, userId);
+                        scheduleInvalidationRequest(sensorId, userId);
                     }
-                });
-            } catch (RemoteException e) {
-                Slog.e(getTag(), "Remote exception when scheduling enroll", e);
-            }
+                }
+            });
         });
     }
 
@@ -447,31 +352,14 @@
             @NonNull String opPackageName, boolean restricted, int statsClient,
             boolean allowBackgroundAuthentication) {
         mHandler.post(() -> {
-            final IFace daemon = getHalInstance();
-            if (daemon == null) {
-                Slog.e(getTag(), "Null daemon during authenticate, sensorId: " + sensorId);
-                // If this happens, we need to send HW_UNAVAILABLE after the scheduler gets to
-                // this operation. We should not send the callback yet, since the scheduler may
-                // be processing something else.
-                return;
-            }
-
-            try {
-                if (!mSensors.get(sensorId).hasSessionForUser(userId)) {
-                    createNewSessionWithoutHandler(daemon, sensorId, userId);
-                }
-
-                final boolean isStrongBiometric = Utils.isStrongBiometric(sensorId);
-                final FaceAuthenticationClient client = new FaceAuthenticationClient(
-                        mContext, mSensors.get(sensorId).getLazySession(), token, callback, userId,
-                        operationId, restricted, opPackageName, cookie,
-                        false /* requireConfirmation */, sensorId, isStrongBiometric, statsClient,
-                        mUsageStats, mSensors.get(sensorId).getLockoutCache(),
-                        allowBackgroundAuthentication);
-                mSensors.get(sensorId).getScheduler().scheduleClientMonitor(client);
-            } catch (RemoteException e) {
-                Slog.e(getTag(), "Remote exception when scheduling authenticate", e);
-            }
+            final boolean isStrongBiometric = Utils.isStrongBiometric(sensorId);
+            final FaceAuthenticationClient client = new FaceAuthenticationClient(
+                    mContext, mSensors.get(sensorId).getLazySession(), token, callback, userId,
+                    operationId, restricted, opPackageName, cookie,
+                    false /* requireConfirmation */, sensorId, isStrongBiometric, statsClient,
+                    mUsageStats, mSensors.get(sensorId).getLockoutCache(),
+                    allowBackgroundAuthentication);
+            scheduleForSensor(sensorId, client);
         });
     }
 
@@ -503,56 +391,24 @@
     private void scheduleRemoveSpecifiedIds(int sensorId, @NonNull IBinder token, int[] faceIds,
             int userId, @NonNull IFaceServiceReceiver receiver, @NonNull String opPackageName) {
         mHandler.post(() -> {
-            final IFace daemon = getHalInstance();
-            if (daemon == null) {
-                Slog.e(getTag(), "Null daemon during remove, sensorId: " + sensorId);
-                // If this happens, we need to send HW_UNAVAILABLE after the scheduler gets to
-                // this operation. We should not send the callback yet, since the scheduler may
-                // be processing something else.
-                return;
-            }
-
-            try {
-                if (!mSensors.get(sensorId).hasSessionForUser(userId)) {
-                    createNewSessionWithoutHandler(daemon, sensorId, userId);
-                }
-
-                final FaceRemovalClient client = new FaceRemovalClient(mContext,
-                        mSensors.get(sensorId).getLazySession(), token,
-                        new ClientMonitorCallbackConverter(receiver), faceIds, userId,
-                        opPackageName, FaceUtils.getInstance(sensorId), sensorId,
-                        mSensors.get(sensorId).getAuthenticatorIds());
-
-                mSensors.get(sensorId).getScheduler().scheduleClientMonitor(client);
-            } catch (RemoteException e) {
-                Slog.e(getTag(), "Remote exception when scheduling remove", e);
-            }
+            final FaceRemovalClient client = new FaceRemovalClient(mContext,
+                    mSensors.get(sensorId).getLazySession(), token,
+                    new ClientMonitorCallbackConverter(receiver), faceIds, userId,
+                    opPackageName, FaceUtils.getInstance(sensorId), sensorId,
+                    mSensors.get(sensorId).getAuthenticatorIds());
+            scheduleForSensor(sensorId, client);
         });
     }
 
     @Override
     public void scheduleResetLockout(int sensorId, int userId, @NonNull byte[] hardwareAuthToken) {
         mHandler.post(() -> {
-            final IFace daemon = getHalInstance();
-            if (daemon == null) {
-                Slog.e(getTag(), "Null daemon during resetLockout, sensorId: " + sensorId);
-                return;
-            }
+            final FaceResetLockoutClient client = new FaceResetLockoutClient(
+                    mContext, mSensors.get(sensorId).getLazySession(), userId,
+                    mContext.getOpPackageName(), sensorId, hardwareAuthToken,
+                    mSensors.get(sensorId).getLockoutCache(), mLockoutResetDispatcher);
 
-            try {
-                if (!mSensors.get(sensorId).hasSessionForUser(userId)) {
-                    createNewSessionWithoutHandler(daemon, sensorId, userId);
-                }
-
-                final FaceResetLockoutClient client = new FaceResetLockoutClient(
-                        mContext, mSensors.get(sensorId).getLazySession(), userId,
-                        mContext.getOpPackageName(), sensorId, hardwareAuthToken,
-                        mSensors.get(sensorId).getLockoutCache(), mLockoutResetDispatcher);
-
-                scheduleForSensor(sensorId, client);
-            } catch (RemoteException e) {
-                Slog.e(getTag(), "Remote exception when scheduling resetLockout", e);
-            }
+            scheduleForSensor(sensorId, client);
         });
     }
 
@@ -580,29 +436,14 @@
     public void scheduleInternalCleanup(int sensorId, int userId,
             @Nullable BaseClientMonitor.Callback callback) {
         mHandler.post(() -> {
-            final IFace daemon = getHalInstance();
-            if (daemon == null) {
-                Slog.e(getTag(), "Null daemon during internal cleanup, sensorId: " + sensorId);
-                return;
-            }
-
-            try {
-                if (!mSensors.get(sensorId).hasSessionForUser(userId)) {
-                    createNewSessionWithoutHandler(daemon, sensorId, userId);
-                }
-
-                final List<Face> enrolledList = getEnrolledFaces(sensorId, userId);
-                final FaceInternalCleanupClient client =
-                        new FaceInternalCleanupClient(mContext,
-                                mSensors.get(sensorId).getLazySession(), userId,
-                                mContext.getOpPackageName(), sensorId, enrolledList,
-                                FaceUtils.getInstance(sensorId),
-                                mSensors.get(sensorId).getAuthenticatorIds());
-
-                mSensors.get(sensorId).getScheduler().scheduleClientMonitor(client, callback);
-            } catch (RemoteException e) {
-                Slog.e(getTag(), "Remote exception when scheduling internal cleanup", e);
-            }
+            final List<Face> enrolledList = getEnrolledFaces(sensorId, userId);
+            final FaceInternalCleanupClient client =
+                    new FaceInternalCleanupClient(mContext,
+                            mSensors.get(sensorId).getLazySession(), userId,
+                            mContext.getOpPackageName(), sensorId, enrolledList,
+                            FaceUtils.getInstance(sensorId),
+                            mSensors.get(sensorId).getAuthenticatorIds());
+            scheduleForSensor(sensorId, client);
         });
     }
 
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceRemovalClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceRemovalClient.java
index 48796c1..ba678f3 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceRemovalClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceRemovalClient.java
@@ -53,7 +53,7 @@
     @Override
     protected void startHalOperation() {
         try {
-            getFreshDaemon().removeEnrollments(mSequentialId, mBiometricIds);
+            getFreshDaemon().removeEnrollments(mBiometricIds);
         } catch (RemoteException e) {
             Slog.e(TAG, "Remote exception when requesting remove", e);
             mCallback.onClientFinished(this, false /* success */);
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceResetLockoutClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceResetLockoutClient.java
index ce728bc..5e57950 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceResetLockoutClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceResetLockoutClient.java
@@ -71,7 +71,7 @@
     @Override
     protected void startHalOperation() {
         try {
-            getFreshDaemon().resetLockout(mSequentialId, mHardwareAuthToken);
+            getFreshDaemon().resetLockout(mHardwareAuthToken);
         } catch (RemoteException e) {
             Slog.e(TAG, "Unable to reset lockout", e);
             mCallback.onClientFinished(this, false /* success */);
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceRevokeChallengeClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceRevokeChallengeClient.java
index 2863f9f..2294173 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceRevokeChallengeClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceRevokeChallengeClient.java
@@ -45,7 +45,7 @@
     @Override
     protected void startHalOperation() {
         try {
-            getFreshDaemon().revokeChallenge(mSequentialId, mChallenge);
+            getFreshDaemon().revokeChallenge(mChallenge);
         } catch (RemoteException e) {
             Slog.e(TAG, "Unable to revokeChallenge", e);
         }
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceStartUserClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceStartUserClient.java
new file mode 100644
index 0000000..c364dbb
--- /dev/null
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceStartUserClient.java
@@ -0,0 +1,67 @@
+/*
+ * 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.biometrics.sensors.face.aidl;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.hardware.biometrics.face.IFace;
+import android.hardware.biometrics.face.ISession;
+import android.hardware.biometrics.face.ISessionCallback;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Slog;
+
+import com.android.server.biometrics.sensors.StartUserClient;
+
+public class FaceStartUserClient extends StartUserClient<IFace, ISession> {
+    private static final String TAG = "FaceStartUserClient";
+
+    @NonNull private final ISessionCallback mSessionCallback;
+
+    public FaceStartUserClient(@NonNull Context context, @NonNull LazyDaemon<IFace> lazyDaemon,
+            @Nullable IBinder token, int userId, int sensorId,
+            @NonNull ISessionCallback sessionCallback,
+            @NonNull UserStartedCallback<ISession> callback) {
+        super(context, lazyDaemon, token, userId, sensorId, callback);
+        mSessionCallback = sessionCallback;
+    }
+
+    @Override
+    public void start(@NonNull Callback callback) {
+        super.start(callback);
+        startHalOperation();
+    }
+
+    @Override
+    protected void startHalOperation() {
+        try {
+            final ISession newSession = getFreshDaemon().createSession(getSensorId(),
+                    getTargetUserId(), mSessionCallback);
+            mUserStartedCallback.onUserStarted(getTargetUserId(), newSession);
+            getCallback().onClientFinished(this, true /* success */);
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Remote exception", e);
+            getCallback().onClientFinished(this, false /* success */);
+        }
+    }
+
+    @Override
+    public void unableToStart() {
+
+    }
+}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceStopUserClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceStopUserClient.java
new file mode 100644
index 0000000..06328e3
--- /dev/null
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceStopUserClient.java
@@ -0,0 +1,58 @@
+/*
+ * 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.biometrics.sensors.face.aidl;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.hardware.biometrics.face.ISession;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Slog;
+
+import com.android.server.biometrics.sensors.StopUserClient;
+
+public class FaceStopUserClient extends StopUserClient<ISession> {
+    private static final String TAG = "FaceStopUserClient";
+
+    public FaceStopUserClient(@NonNull Context context, @NonNull LazyDaemon<ISession> lazyDaemon,
+            @Nullable IBinder token, int userId, int sensorId,
+            @NonNull UserStoppedCallback callback) {
+        super(context, lazyDaemon, token, userId, sensorId, callback);
+    }
+
+    @Override
+    public void start(@NonNull Callback callback) {
+        super.start(callback);
+        startHalOperation();
+    }
+
+    @Override
+    protected void startHalOperation() {
+        try {
+            getFreshDaemon().close();
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Remote exception", e);
+            getCallback().onClientFinished(this, false /* success */);
+        }
+    }
+
+    @Override
+    public void unableToStart() {
+
+    }
+}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java
index c6f39aa..ee36775 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java
@@ -33,8 +33,11 @@
 import android.hardware.face.FaceManager;
 import android.hardware.face.FaceSensorPropertiesInternal;
 import android.hardware.keymaster.HardwareAuthToken;
+import android.os.Binder;
 import android.os.Handler;
+import android.os.IBinder;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.os.UserManager;
 import android.util.Slog;
 import android.util.proto.ProtoOutputStream;
@@ -54,6 +57,9 @@
 import com.android.server.biometrics.sensors.LockoutCache;
 import com.android.server.biometrics.sensors.LockoutConsumer;
 import com.android.server.biometrics.sensors.RemovalConsumer;
+import com.android.server.biometrics.sensors.StartUserClient;
+import com.android.server.biometrics.sensors.StopUserClient;
+import com.android.server.biometrics.sensors.UserAwareBiometricScheduler;
 import com.android.server.biometrics.sensors.face.FaceUtils;
 
 import java.util.ArrayList;
@@ -70,9 +76,10 @@
     @NonNull private final String mTag;
     @NonNull private final FaceProvider mProvider;
     @NonNull private final Context mContext;
+    @NonNull private final IBinder mToken;
     @NonNull private final Handler mHandler;
     @NonNull private final FaceSensorPropertiesInternal mSensorProperties;
-    @NonNull private final BiometricScheduler mScheduler;
+    @NonNull private final UserAwareBiometricScheduler mScheduler;
     @NonNull private final LockoutCache mLockoutCache;
     @NonNull private final Map<Integer, Long> mAuthenticatorIds;
     @NonNull private final HalClientMonitor.LazyDaemon<ISession> mLazySession;
@@ -112,14 +119,14 @@
         @NonNull
         private final String mTag;
         @NonNull
-        private final BiometricScheduler mScheduler;
+        private final UserAwareBiometricScheduler mScheduler;
         private final int mSensorId;
         private final int mUserId;
         @NonNull
         private final Callback mCallback;
 
         HalSessionCallback(@NonNull Context context, @NonNull Handler handler, @NonNull String tag,
-                @NonNull BiometricScheduler scheduler, int sensorId, int userId,
+                @NonNull UserAwareBiometricScheduler scheduler, int sensorId, int userId,
                 @NonNull Callback callback) {
             mContext = context;
             mHandler = handler;
@@ -131,11 +138,6 @@
         }
 
         @Override
-        public void onStateChanged(int cookie, byte state) {
-            // TODO(b/162973174)
-        }
-
-        @Override
         public void onChallengeGenerated(long challenge) {
             mHandler.post(() -> {
                 final BaseClientMonitor client = mScheduler.getCurrentClient();
@@ -424,6 +426,10 @@
             });
         }
 
+        @Override
+        public void onSessionClosed() {
+            mHandler.post(mScheduler::onUserStopped);
+        }
     }
 
     Sensor(@NonNull String tag, @NonNull FaceProvider provider, @NonNull Context context,
@@ -431,9 +437,53 @@
         mTag = tag;
         mProvider = provider;
         mContext = context;
+        mToken = new Binder();
         mHandler = handler;
         mSensorProperties = sensorProperties;
-        mScheduler = new BiometricScheduler(tag, null /* gestureAvailabilityDispatcher */);
+        mScheduler = new UserAwareBiometricScheduler(tag, null /* gestureAvailabilityDispatcher */,
+                () -> mCurrentSession != null ? mCurrentSession.mUserId : UserHandle.USER_NULL,
+                new UserAwareBiometricScheduler.UserSwitchCallback() {
+                    @NonNull
+                    @Override
+                    public StopUserClient<?> getStopUserClient(int userId) {
+                        return new FaceStopUserClient(mContext, mLazySession, mToken, userId,
+                                mSensorProperties.sensorId, () -> mCurrentSession = null);
+                    }
+
+                    @NonNull
+                    @Override
+                    public StartUserClient<?, ?> getStartUserClient(int newUserId) {
+                        final HalSessionCallback.Callback callback = () -> {
+                            Slog.e(mTag, "Got ERROR_HW_UNAVAILABLE");
+                            mCurrentSession = null;
+                        };
+
+                        final int sensorId = mSensorProperties.sensorId;
+
+                        final HalSessionCallback resultController = new HalSessionCallback(mContext,
+                                mHandler, mTag, mScheduler, sensorId, newUserId, callback);
+
+                        final StartUserClient.UserStartedCallback<ISession> userStartedCallback =
+                                (userIdStarted, newSession) -> {
+                                    mCurrentSession = new Session(mTag, newSession, userIdStarted,
+                                            resultController);
+                                    if (FaceUtils.getLegacyInstance(sensorId)
+                                            .isInvalidationInProgress(mContext, userIdStarted)) {
+                                        Slog.w(mTag,
+                                                "Scheduling unfinished invalidation request for "
+                                                        + "sensor: "
+                                                        + sensorId
+                                                        + ", user: " + userIdStarted);
+                                        provider.scheduleInvalidationRequest(sensorId,
+                                                userIdStarted);
+                                    }
+                                };
+
+                        return new FaceStartUserClient(mContext, provider::getHalInstance,
+                                mToken, newUserId, mSensorProperties.sensorId,
+                                resultController, userStartedCallback);
+                    }
+                });
         mLockoutCache = new LockoutCache();
         mAuthenticatorIds = new HashMap<>();
         mLazySession = () -> mCurrentSession != null ? mCurrentSession.mSession : null;
@@ -447,11 +497,6 @@
         return mSensorProperties;
     }
 
-    @SuppressWarnings("BooleanMethodIsAlwaysInverted")
-    boolean hasSessionForUser(int userId) {
-        return mCurrentSession != null && mCurrentSession.mUserId == userId;
-    }
-
     @Nullable Session getSessionForUser(int userId) {
         if (mCurrentSession != null && mCurrentSession.mUserId == userId) {
             return mCurrentSession;
@@ -465,20 +510,6 @@
                 mProvider, this);
     }
 
-    void createNewSession(@NonNull IFace daemon, int sensorId, int userId)
-            throws RemoteException {
-
-        final HalSessionCallback.Callback callback = () -> {
-            Slog.e(mTag, "Got ERROR_HW_UNAVAILABLE");
-            mCurrentSession = null;
-        };
-        final HalSessionCallback resultController = new HalSessionCallback(mContext, mHandler,
-                mTag, mScheduler, sensorId, userId, callback);
-
-        final ISession newSession = daemon.createSession(sensorId, userId, resultController);
-        mCurrentSession = new Session(mTag, newSession, userId, resultController);
-    }
-
     @NonNull BiometricScheduler getScheduler() {
         return mScheduler;
     }
@@ -499,7 +530,7 @@
                 if (mCurrentSession != null && mCurrentSession.mSession != null) {
                     // TODO(181984005): This should be scheduled instead of directly invoked
                     Slog.d(mTag, "Closing old session");
-                    mCurrentSession.mSession.close(888 /* cookie */);
+                    mCurrentSession.mSession.close();
                 }
             } catch (RemoteException e) {
                 Slog.e(mTag, "RemoteException", e);
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/TestHal.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/TestHal.java
index 4ca85d0..c63af7e 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/TestHal.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/TestHal.java
@@ -22,7 +22,6 @@
 import android.hardware.biometrics.face.ISession;
 import android.hardware.biometrics.face.ISessionCallback;
 import android.hardware.biometrics.face.SensorProps;
-import android.hardware.biometrics.face.SessionState;
 import android.hardware.common.NativeHandle;
 import android.hardware.keymaster.HardwareAuthToken;
 import android.os.RemoteException;
@@ -45,21 +44,21 @@
 
         return new ISession.Stub() {
             @Override
-            public void generateChallenge(int cookie) throws RemoteException {
-                Slog.w(TAG, "generateChallenge, cookie: " + cookie);
+            public void generateChallenge() throws RemoteException {
+                Slog.w(TAG, "generateChallenge");
                 cb.onChallengeGenerated(0L);
             }
 
             @Override
-            public void revokeChallenge(int cookie, long challenge) throws RemoteException {
-                Slog.w(TAG, "revokeChallenge: " + challenge + ", cookie: " + cookie);
+            public void revokeChallenge(long challenge) throws RemoteException {
+                Slog.w(TAG, "revokeChallenge: " + challenge);
                 cb.onChallengeRevoked(challenge);
             }
 
             @Override
-            public ICancellationSignal enroll(int cookie, HardwareAuthToken hat,
+            public ICancellationSignal enroll(HardwareAuthToken hat,
                     byte enrollmentType, byte[] features, NativeHandle previewSurface) {
-                Slog.w(TAG, "enroll, cookie: " + cookie);
+                Slog.w(TAG, "enroll");
                 return new ICancellationSignal.Stub() {
                     @Override
                     public void cancel() throws RemoteException {
@@ -69,8 +68,8 @@
             }
 
             @Override
-            public ICancellationSignal authenticate(int cookie, long operationId) {
-                Slog.w(TAG, "authenticate, cookie: " + cookie);
+            public ICancellationSignal authenticate(long operationId) {
+                Slog.w(TAG, "authenticate");
                 return new ICancellationSignal.Stub() {
                     @Override
                     public void cancel() throws RemoteException {
@@ -80,8 +79,8 @@
             }
 
             @Override
-            public ICancellationSignal detectInteraction(int cookie) {
-                Slog.w(TAG, "detectInteraction, cookie: " + cookie);
+            public ICancellationSignal detectInteraction() {
+                Slog.w(TAG, "detectInteraction");
                 return new ICancellationSignal.Stub() {
                     @Override
                     public void cancel() throws RemoteException {
@@ -91,51 +90,52 @@
             }
 
             @Override
-            public void enumerateEnrollments(int cookie) throws RemoteException {
-                Slog.w(TAG, "enumerateEnrollments, cookie: " + cookie);
+            public void enumerateEnrollments() throws RemoteException {
+                Slog.w(TAG, "enumerateEnrollments");
                 cb.onEnrollmentsEnumerated(new int[0]);
             }
 
             @Override
-            public void removeEnrollments(int cookie, int[] enrollmentIds) throws RemoteException {
-                Slog.w(TAG, "removeEnrollments, cookie: " + cookie);
+            public void removeEnrollments(int[] enrollmentIds) throws RemoteException {
+                Slog.w(TAG, "removeEnrollments");
                 cb.onEnrollmentsRemoved(enrollmentIds);
             }
 
             @Override
-            public void getFeatures(int cookie, int enrollmentId) throws RemoteException {
-                Slog.w(TAG, "getFeatures, cookie: " + cookie);
+            public void getFeatures(int enrollmentId) throws RemoteException {
+                Slog.w(TAG, "getFeatures");
                 cb.onFeaturesRetrieved(new byte[0], enrollmentId);
             }
 
             @Override
-            public void setFeature(int cookie, HardwareAuthToken hat, int enrollmentId,
+            public void setFeature(HardwareAuthToken hat, int enrollmentId,
                     byte feature, boolean enabled) throws RemoteException {
-                Slog.w(TAG, "setFeature, cookie: " + cookie);
+                Slog.w(TAG, "setFeature");
                 cb.onFeatureSet(enrollmentId, feature);
             }
 
             @Override
-            public void getAuthenticatorId(int cookie) throws RemoteException {
-                Slog.w(TAG, "getAuthenticatorId, cookie: " + cookie);
+            public void getAuthenticatorId() throws RemoteException {
+                Slog.w(TAG, "getAuthenticatorId");
                 cb.onAuthenticatorIdRetrieved(0L);
             }
 
             @Override
-            public void invalidateAuthenticatorId(int cookie) throws RemoteException {
-                Slog.w(TAG, "invalidateAuthenticatorId, cookie: " + cookie);
+            public void invalidateAuthenticatorId() throws RemoteException {
+                Slog.w(TAG, "invalidateAuthenticatorId");
                 cb.onAuthenticatorIdInvalidated(0L);
             }
 
             @Override
-            public void resetLockout(int cookie, HardwareAuthToken hat) throws RemoteException {
-                Slog.w(TAG, "resetLockout, cookie: " + cookie);
+            public void resetLockout(HardwareAuthToken hat) throws RemoteException {
+                Slog.w(TAG, "resetLockout");
                 cb.onLockoutCleared();
             }
 
             @Override
-            public void close(int cookie) throws RemoteException {
-                cb.onStateChanged(cookie, SessionState.CLOSED);
+            public void close() throws RemoteException {
+                Slog.w(TAG, "close");
+                cb.onSessionClosed();
             }
         };
     }
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java
index 50756c8..79e361f 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java
@@ -528,6 +528,8 @@
                 }
             }
 
+            scheduleUpdateActiveUserWithoutHandler(userId);
+
             final FaceGenerateChallengeClient client = new FaceGenerateChallengeClient(mContext,
                     mLazyDaemon, token, new ClientMonitorCallbackConverter(receiver), opPackageName,
                     mSensorId, mCurrentChallengeOwner);
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 76a47d3..4e5d12d 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
@@ -92,7 +92,7 @@
         UdfpsHelper.showUdfpsOverlay(getSensorId(), Utils.getUdfpsAuthReason(this),
                 mUdfpsOverlayController, this);
         try {
-            mCancellationSignal = getFreshDaemon().authenticate(mSequentialId, mOperationId);
+            mCancellationSignal = getFreshDaemon().authenticate(mOperationId);
         } catch (RemoteException e) {
             Slog.e(TAG, "Remote exception", e);
             onError(BiometricFingerprintConstants.FINGERPRINT_ERROR_HW_UNAVAILABLE,
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java
index 620a9cf..9e9d0ee 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java
@@ -74,7 +74,7 @@
                 IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD,
                 mUdfpsOverlayController, this);
         try {
-            mCancellationSignal = getFreshDaemon().detectInteraction(mSequentialId);
+            mCancellationSignal = getFreshDaemon().detectInteraction();
         } catch (RemoteException e) {
             Slog.e(TAG, "Remote exception when requesting finger detect", e);
             UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
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 63fa66c..fd4aece 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
@@ -123,7 +123,7 @@
                 UdfpsHelper.getReasonFromEnrollReason(mEnrollReason),
                 mUdfpsOverlayController, this);
         try {
-            mCancellationSignal = getFreshDaemon().enroll(mSequentialId,
+            mCancellationSignal = getFreshDaemon().enroll(
                     HardwareAuthTokenUtils.toHardwareAuthToken(mHardwareAuthToken));
         } catch (RemoteException e) {
             Slog.e(TAG, "Remote exception when requesting enroll", e);
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintGenerateChallengeClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintGenerateChallengeClient.java
index 3c9cced..83c6421 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintGenerateChallengeClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintGenerateChallengeClient.java
@@ -44,7 +44,7 @@
     @Override
     protected void startHalOperation() {
         try {
-            getFreshDaemon().generateChallenge(mSequentialId);
+            getFreshDaemon().generateChallenge();
         } catch (RemoteException e) {
             Slog.e(TAG, "Unable to generateChallenge", e);
         }
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintGetAuthenticatorIdClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintGetAuthenticatorIdClient.java
index ce1a318..ed2345e 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintGetAuthenticatorIdClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintGetAuthenticatorIdClient.java
@@ -56,7 +56,7 @@
     @Override
     protected void startHalOperation() {
         try {
-            getFreshDaemon().getAuthenticatorId(mSequentialId);
+            getFreshDaemon().getAuthenticatorId();
         } catch (RemoteException e) {
             Slog.e(TAG, "Remote exception", e);
         }
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintInternalEnumerateClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintInternalEnumerateClient.java
index c930360..e20544a 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintInternalEnumerateClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintInternalEnumerateClient.java
@@ -48,7 +48,7 @@
     @Override
     protected void startHalOperation() {
         try {
-            getFreshDaemon().enumerateEnrollments(mSequentialId);
+            getFreshDaemon().enumerateEnrollments();
         } catch (RemoteException e) {
             Slog.e(TAG, "Remote exception when requesting enumerate", e);
             mCallback.onClientFinished(this, false /* success */);
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintInvalidationClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintInvalidationClient.java
index 80d1a0f..6cd2ef1 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintInvalidationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintInvalidationClient.java
@@ -40,7 +40,7 @@
     @Override
     protected void startHalOperation() {
         try {
-            getFreshDaemon().invalidateAuthenticatorId(mSequentialId);
+            getFreshDaemon().invalidateAuthenticatorId();
         } catch (RemoteException e) {
             Slog.e(TAG, "Remote exception", e);
             mCallback.onClientFinished(this, false /* success */);
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
index 1b5def6..972071c 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
@@ -82,7 +82,6 @@
     @NonNull private final String mHalInstanceName;
     @NonNull @VisibleForTesting
     final SparseArray<Sensor> mSensors; // Map of sensors that this HAL supports
-    @NonNull private final HalClientMonitor.LazyDaemon<IFingerprint> mLazyDaemon;
     @NonNull private final Handler mHandler;
     @NonNull private final LockoutResetDispatcher mLockoutResetDispatcher;
     @NonNull private final ActivityTaskManager mActivityTaskManager;
@@ -131,7 +130,6 @@
         mContext = context;
         mHalInstanceName = halInstanceName;
         mSensors = new SparseArray<>();
-        mLazyDaemon = this::getHalInstance;
         mHandler = new Handler(Looper.getMainLooper());
         mLockoutResetDispatcher = lockoutResetDispatcher;
         mActivityTaskManager = ActivityTaskManager.getInstance();
@@ -169,7 +167,8 @@
     }
 
     @Nullable
-    private synchronized IFingerprint getHalInstance() {
+    @VisibleForTesting
+    synchronized IFingerprint getHalInstance() {
         if (mTestHalEnabled) {
             // Enabling the test HAL for a single sensor in a multi-sensor HAL currently enables
             // the test HAL for all sensors under that HAL. This can be updated in the future if
@@ -224,21 +223,6 @@
         mSensors.get(sensorId).getScheduler().scheduleClientMonitor(client, callback);
     }
 
-    private void createNewSessionWithoutHandler(@NonNull IFingerprint daemon, int sensorId,
-            int userId) throws RemoteException {
-        // Note that per IFingerprint createSession contract, this method will block until all
-        // existing operations are canceled/finished. However, also note that this is fine, since
-        // this method "withoutHandler" means it should only ever be invoked from the worker thread,
-        // so callers will never be blocked.
-        mSensors.get(sensorId).createNewSession(daemon, sensorId, userId);
-
-        if (FingerprintUtils.getInstance(sensorId).isInvalidationInProgress(mContext, userId)) {
-            Slog.w(getTag(), "Scheduling unfinished invalidation request for sensor: " + sensorId
-                    + ", user: " + userId);
-            scheduleInvalidationRequest(sensorId, userId);
-        }
-    }
-
     @Override
     public boolean containsSensor(int sensorId) {
         return mSensors.contains(sensorId);
@@ -275,62 +259,32 @@
 
     private void scheduleLoadAuthenticatorIdsForUser(int sensorId, int userId) {
         mHandler.post(() -> {
-            final IFingerprint daemon = getHalInstance();
-            if (daemon == null) {
-                Slog.e(getTag(), "Null daemon during loadAuthenticatorIds, sensorId: " + sensorId);
-                return;
-            }
-
-            try {
-                if (!mSensors.get(sensorId).hasSessionForUser(userId)) {
-                    createNewSessionWithoutHandler(daemon, sensorId, userId);
-                }
-
-                final FingerprintGetAuthenticatorIdClient client =
-                        new FingerprintGetAuthenticatorIdClient(mContext,
-                                mSensors.get(sensorId).getLazySession(), userId,
-                                mContext.getOpPackageName(), sensorId,
-                                mSensors.get(sensorId).getAuthenticatorIds());
-                mSensors.get(sensorId).getScheduler().scheduleClientMonitor(client);
-            } catch (RemoteException e) {
-                Slog.e(getTag(), "Remote exception when scheduling loadAuthenticatorId"
-                        + ", sensorId: " + sensorId
-                        + ", userId: " + userId, e);
-            }
+            final FingerprintGetAuthenticatorIdClient client =
+                    new FingerprintGetAuthenticatorIdClient(mContext,
+                            mSensors.get(sensorId).getLazySession(), userId,
+                            mContext.getOpPackageName(), sensorId,
+                            mSensors.get(sensorId).getAuthenticatorIds());
+            scheduleForSensor(sensorId, client);
         });
     }
 
-    private void scheduleInvalidationRequest(int sensorId, int userId) {
+    void scheduleInvalidationRequest(int sensorId, int userId) {
         mHandler.post(() -> {
             final InvalidationRequesterClient<Fingerprint> client =
                     new InvalidationRequesterClient<>(mContext, userId, sensorId,
                             FingerprintUtils.getInstance(sensorId));
-            mSensors.get(sensorId).getScheduler().scheduleClientMonitor(client);
+            scheduleForSensor(sensorId, client);
         });
     }
 
     @Override
     public void scheduleResetLockout(int sensorId, int userId, @Nullable byte[] hardwareAuthToken) {
         mHandler.post(() -> {
-            final IFingerprint daemon = getHalInstance();
-            if (daemon == null) {
-                Slog.e(getTag(), "Null daemon during resetLockout, sensorId: " + sensorId);
-                return;
-            }
-
-            try {
-                if (!mSensors.get(sensorId).hasSessionForUser(userId)) {
-                    createNewSessionWithoutHandler(daemon, sensorId, userId);
-                }
-
-                final FingerprintResetLockoutClient client = new FingerprintResetLockoutClient(
-                        mContext, mSensors.get(sensorId).getLazySession(), userId,
-                        mContext.getOpPackageName(), sensorId, hardwareAuthToken,
-                        mSensors.get(sensorId).getLockoutCache(), mLockoutResetDispatcher);
-                scheduleForSensor(sensorId, client);
-            } catch (RemoteException e) {
-                Slog.e(getTag(), "Remote exception when scheduling resetLockout", e);
-            }
+            final FingerprintResetLockoutClient client = new FingerprintResetLockoutClient(
+                    mContext, mSensors.get(sensorId).getLazySession(), userId,
+                    mContext.getOpPackageName(), sensorId, hardwareAuthToken,
+                    mSensors.get(sensorId).getLockoutCache(), mLockoutResetDispatcher);
+            scheduleForSensor(sensorId, client);
         });
     }
 
@@ -338,26 +292,12 @@
     public void scheduleGenerateChallenge(int sensorId, int userId, @NonNull IBinder token,
             @NonNull IFingerprintServiceReceiver receiver, String opPackageName) {
         mHandler.post(() -> {
-            final IFingerprint daemon = getHalInstance();
-            if (daemon == null) {
-                Slog.e(getTag(), "Null daemon during generateChallenge, sensorId: " + sensorId);
-                return;
-            }
-
-            try {
-                if (!mSensors.get(sensorId).hasSessionForUser(userId)) {
-                    createNewSessionWithoutHandler(daemon, sensorId, userId);
-                }
-
-                final FingerprintGenerateChallengeClient client =
-                        new FingerprintGenerateChallengeClient(mContext,
-                                mSensors.get(sensorId).getLazySession(), token,
-                                new ClientMonitorCallbackConverter(receiver), opPackageName,
-                                sensorId);
-                scheduleForSensor(sensorId, client);
-            } catch (RemoteException e) {
-                Slog.e(getTag(), "Remote exception when scheduling generateChallenge", e);
-            }
+            final FingerprintGenerateChallengeClient client =
+                    new FingerprintGenerateChallengeClient(mContext,
+                            mSensors.get(sensorId).getLazySession(), token,
+                            new ClientMonitorCallbackConverter(receiver), opPackageName,
+                            sensorId);
+            scheduleForSensor(sensorId, client);
         });
     }
 
@@ -365,25 +305,11 @@
     public void scheduleRevokeChallenge(int sensorId, int userId, @NonNull IBinder token,
             @NonNull String opPackageName, long challenge) {
         mHandler.post(() -> {
-            final IFingerprint daemon = getHalInstance();
-            if (daemon == null) {
-                Slog.e(getTag(), "Null daemon during revokeChallenge, sensorId: " + sensorId);
-                return;
-            }
-
-            try {
-                if (!mSensors.get(sensorId).hasSessionForUser(userId)) {
-                    createNewSessionWithoutHandler(daemon, sensorId, userId);
-                }
-
-                final FingerprintRevokeChallengeClient client =
-                        new FingerprintRevokeChallengeClient(mContext,
-                                mSensors.get(sensorId).getLazySession(), token,
-                                opPackageName, sensorId, challenge);
-                scheduleForSensor(sensorId, client);
-            } catch (RemoteException e) {
-                Slog.e(getTag(), "Remote exception when scheduling revokeChallenge", e);
-            }
+            final FingerprintRevokeChallengeClient client =
+                    new FingerprintRevokeChallengeClient(mContext,
+                            mSensors.get(sensorId).getLazySession(), token,
+                            opPackageName, sensorId, challenge);
+            scheduleForSensor(sensorId, client);
         });
     }
 
@@ -392,40 +318,23 @@
             int userId, @NonNull IFingerprintServiceReceiver receiver,
             @NonNull String opPackageName, @FingerprintManager.EnrollReason int enrollReason) {
         mHandler.post(() -> {
-            final IFingerprint daemon = getHalInstance();
-            if (daemon == null) {
-                Slog.e(getTag(), "Null daemon during enroll, sensorId: " + sensorId);
-                // If this happens, we need to send HW_UNAVAILABLE after the scheduler gets to
-                // this operation. We should not send the callback yet, since the scheduler may
-                // be processing something else.
-                return;
-            }
-
-            try {
-                if (!mSensors.get(sensorId).hasSessionForUser(userId)) {
-                    createNewSessionWithoutHandler(daemon, sensorId, userId);
-                }
-
-                final int maxTemplatesPerUser = mSensors.get(sensorId).getSensorProperties()
-                        .maxEnrollmentsPerUser;
-                final FingerprintEnrollClient client = new FingerprintEnrollClient(mContext,
-                        mSensors.get(sensorId).getLazySession(), token,
-                        new ClientMonitorCallbackConverter(receiver), userId, hardwareAuthToken,
-                        opPackageName, FingerprintUtils.getInstance(sensorId), sensorId,
-                        mUdfpsOverlayController, maxTemplatesPerUser, enrollReason);
-                scheduleForSensor(sensorId, client, new BaseClientMonitor.Callback() {
-                    @Override
-                    public void onClientFinished(@NonNull BaseClientMonitor clientMonitor,
-                            boolean success) {
-                        if (success) {
-                            scheduleLoadAuthenticatorIdsForUser(sensorId, userId);
-                            scheduleInvalidationRequest(sensorId, userId);
-                        }
+            final int maxTemplatesPerUser = mSensors.get(sensorId).getSensorProperties()
+                    .maxEnrollmentsPerUser;
+            final FingerprintEnrollClient client = new FingerprintEnrollClient(mContext,
+                    mSensors.get(sensorId).getLazySession(), token,
+                    new ClientMonitorCallbackConverter(receiver), userId, hardwareAuthToken,
+                    opPackageName, FingerprintUtils.getInstance(sensorId), sensorId,
+                    mUdfpsOverlayController, maxTemplatesPerUser, enrollReason);
+            scheduleForSensor(sensorId, client, new BaseClientMonitor.Callback() {
+                @Override
+                public void onClientFinished(@NonNull BaseClientMonitor clientMonitor,
+                        boolean success) {
+                    if (success) {
+                        scheduleLoadAuthenticatorIdsForUser(sensorId, userId);
+                        scheduleInvalidationRequest(sensorId, userId);
                     }
-                });
-            } catch (RemoteException e) {
-                Slog.e(getTag(), "Remote exception when scheduling enroll", e);
-            }
+                }
+            });
         });
     }
 
@@ -439,29 +348,12 @@
             @NonNull ClientMonitorCallbackConverter callback, @NonNull String opPackageName,
             int statsClient) {
         mHandler.post(() -> {
-            final IFingerprint daemon = getHalInstance();
-            if (daemon == null) {
-                Slog.e(getTag(), "Null daemon during finger detect, sensorId: " + sensorId);
-                // If this happens, we need to send HW_UNAVAILABLE after the scheduler gets to
-                // this operation. We should not send the callback yet, since the scheduler may
-                // be processing something else.
-                return;
-            }
-
-            try {
-                if (!mSensors.get(sensorId).hasSessionForUser(userId)) {
-                    createNewSessionWithoutHandler(daemon, sensorId, userId);
-                }
-
-                final boolean isStrongBiometric = Utils.isStrongBiometric(sensorId);
-                final FingerprintDetectClient client = new FingerprintDetectClient(mContext,
-                        mSensors.get(sensorId).getLazySession(), token, callback, userId,
-                        opPackageName, sensorId, mUdfpsOverlayController, isStrongBiometric,
-                        statsClient);
-                mSensors.get(sensorId).getScheduler().scheduleClientMonitor(client);
-            } catch (RemoteException e) {
-                Slog.e(getTag(), "Remote exception when scheduling finger detect", e);
-            }
+            final boolean isStrongBiometric = Utils.isStrongBiometric(sensorId);
+            final FingerprintDetectClient client = new FingerprintDetectClient(mContext,
+                    mSensors.get(sensorId).getLazySession(), token, callback, userId,
+                    opPackageName, sensorId, mUdfpsOverlayController, isStrongBiometric,
+                    statsClient);
+            scheduleForSensor(sensorId, client);
         });
     }
 
@@ -471,31 +363,14 @@
             @NonNull String opPackageName, boolean restricted, int statsClient,
             boolean allowBackgroundAuthentication) {
         mHandler.post(() -> {
-            final IFingerprint daemon = getHalInstance();
-            if (daemon == null) {
-                Slog.e(getTag(), "Null daemon during authenticate, sensorId: " + sensorId);
-                // If this happens, we need to send HW_UNAVAILABLE after the scheduler gets to
-                // this operation. We should not send the callback yet, since the scheduler may
-                // be processing something else.
-                return;
-            }
-
-            try {
-                if (!mSensors.get(sensorId).hasSessionForUser(userId)) {
-                    createNewSessionWithoutHandler(daemon, sensorId, userId);
-                }
-
-                final boolean isStrongBiometric = Utils.isStrongBiometric(sensorId);
-                final FingerprintAuthenticationClient client = new FingerprintAuthenticationClient(
-                        mContext, mSensors.get(sensorId).getLazySession(), token, callback, userId,
-                        operationId, restricted, opPackageName, cookie,
-                        false /* requireConfirmation */, sensorId, isStrongBiometric, statsClient,
-                        mTaskStackListener, mSensors.get(sensorId).getLockoutCache(),
-                        mUdfpsOverlayController, allowBackgroundAuthentication);
-                mSensors.get(sensorId).getScheduler().scheduleClientMonitor(client);
-            } catch (RemoteException e) {
-                Slog.e(getTag(), "Remote exception when scheduling authenticate", e);
-            }
+            final boolean isStrongBiometric = Utils.isStrongBiometric(sensorId);
+            final FingerprintAuthenticationClient client = new FingerprintAuthenticationClient(
+                    mContext, mSensors.get(sensorId).getLazySession(), token, callback, userId,
+                    operationId, restricted, opPackageName, cookie,
+                    false /* requireConfirmation */, sensorId, isStrongBiometric, statsClient,
+                    mTaskStackListener, mSensors.get(sensorId).getLockoutCache(),
+                    mUdfpsOverlayController, allowBackgroundAuthentication);
+            scheduleForSensor(sensorId, client);
         });
     }
 
@@ -535,29 +410,12 @@
             int[] fingerprintIds, int userId, @NonNull IFingerprintServiceReceiver receiver,
             @NonNull String opPackageName) {
         mHandler.post(() -> {
-            final IFingerprint daemon = getHalInstance();
-            if (daemon == null) {
-                Slog.e(getTag(), "Null daemon during remove, sensorId: " + sensorId);
-                // If this happens, we need to send HW_UNAVAILABLE after the scheduler gets to
-                // this operation. We should not send the callback yet, since the scheduler may
-                // be processing something else.
-                return;
-            }
-
-            try {
-                if (!mSensors.get(sensorId).hasSessionForUser(userId)) {
-                    createNewSessionWithoutHandler(daemon, sensorId, userId);
-                }
-
-                final FingerprintRemovalClient client = new FingerprintRemovalClient(mContext,
-                        mSensors.get(sensorId).getLazySession(), token,
-                        new ClientMonitorCallbackConverter(receiver), fingerprintIds, userId,
-                        opPackageName, FingerprintUtils.getInstance(sensorId), sensorId,
-                        mSensors.get(sensorId).getAuthenticatorIds());
-                mSensors.get(sensorId).getScheduler().scheduleClientMonitor(client);
-            } catch (RemoteException e) {
-                Slog.e(getTag(), "Remote exception when scheduling remove", e);
-            }
+            final FingerprintRemovalClient client = new FingerprintRemovalClient(mContext,
+                    mSensors.get(sensorId).getLazySession(), token,
+                    new ClientMonitorCallbackConverter(receiver), fingerprintIds, userId,
+                    opPackageName, FingerprintUtils.getInstance(sensorId), sensorId,
+                    mSensors.get(sensorId).getAuthenticatorIds());
+            scheduleForSensor(sensorId, client);
         });
     }
 
@@ -565,28 +423,14 @@
     public void scheduleInternalCleanup(int sensorId, int userId,
             @Nullable BaseClientMonitor.Callback callback) {
         mHandler.post(() -> {
-            final IFingerprint daemon = getHalInstance();
-            if (daemon == null) {
-                Slog.e(getTag(), "Null daemon during internal cleanup, sensorId: " + sensorId);
-                return;
-            }
-
-            try {
-                if (!mSensors.get(sensorId).hasSessionForUser(userId)) {
-                    createNewSessionWithoutHandler(daemon, sensorId, userId);
-                }
-
-                final List<Fingerprint> enrolledList = getEnrolledFingerprints(sensorId, userId);
-                final FingerprintInternalCleanupClient client =
-                        new FingerprintInternalCleanupClient(mContext,
-                                mSensors.get(sensorId).getLazySession(), userId,
-                                mContext.getOpPackageName(), sensorId, enrolledList,
-                                FingerprintUtils.getInstance(sensorId),
-                                mSensors.get(sensorId).getAuthenticatorIds());
-                mSensors.get(sensorId).getScheduler().scheduleClientMonitor(client, callback);
-            } catch (RemoteException e) {
-                Slog.e(getTag(), "Remote exception when scheduling internal cleanup", e);
-            }
+            final List<Fingerprint> enrolledList = getEnrolledFingerprints(sensorId, userId);
+            final FingerprintInternalCleanupClient client =
+                    new FingerprintInternalCleanupClient(mContext,
+                            mSensors.get(sensorId).getLazySession(), userId,
+                            mContext.getOpPackageName(), sensorId, enrolledList,
+                            FingerprintUtils.getInstance(sensorId),
+                            mSensors.get(sensorId).getAuthenticatorIds());
+            scheduleForSensor(sensorId, client);
         });
     }
 
@@ -611,26 +455,11 @@
     public void scheduleInvalidateAuthenticatorId(int sensorId, int userId,
             @NonNull IInvalidationCallback callback) {
         mHandler.post(() -> {
-            final IFingerprint daemon = getHalInstance();
-            if (daemon == null) {
-                Slog.e(getTag(), "Null daemon during scheduleInvalidateAuthenticatorId: "
-                        + sensorId);
-                return;
-            }
-
-            try {
-                if (!mSensors.get(sensorId).hasSessionForUser(userId)) {
-                    createNewSessionWithoutHandler(daemon, sensorId, userId);
-                }
-
-                final FingerprintInvalidationClient client =
-                        new FingerprintInvalidationClient(mContext,
-                                mSensors.get(sensorId).getLazySession(), userId, sensorId,
-                                mSensors.get(sensorId).getAuthenticatorIds(), callback);
-                mSensors.get(sensorId).getScheduler().scheduleClientMonitor(client);
-            } catch (RemoteException e) {
-                Slog.e(getTag(), "Remote exception", e);
-            }
+            final FingerprintInvalidationClient client =
+                    new FingerprintInvalidationClient(mContext,
+                            mSensors.get(sensorId).getLazySession(), userId, sensorId,
+                            mSensors.get(sensorId).getAuthenticatorIds(), callback);
+            scheduleForSensor(sensorId, client);
         });
     }
 
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintRemovalClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintRemovalClient.java
index c622208..9a9d6ab 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintRemovalClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintRemovalClient.java
@@ -54,7 +54,7 @@
     @Override
     protected void startHalOperation() {
         try {
-            getFreshDaemon().removeEnrollments(mSequentialId, mBiometricIds);
+            getFreshDaemon().removeEnrollments(mBiometricIds);
         } catch (RemoteException e) {
             Slog.e(TAG, "Remote exception when requesting remove", e);
             mCallback.onClientFinished(this, false /* success */);
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintResetLockoutClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintResetLockoutClient.java
index adffba2..b00c592 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintResetLockoutClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintResetLockoutClient.java
@@ -71,7 +71,7 @@
     @Override
     protected void startHalOperation() {
         try {
-            getFreshDaemon().resetLockout(mSequentialId, mHardwareAuthToken);
+            getFreshDaemon().resetLockout(mHardwareAuthToken);
         } catch (RemoteException e) {
             Slog.e(TAG, "Unable to reset lockout", e);
             mCallback.onClientFinished(this, false /* success */);
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintRevokeChallengeClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintRevokeChallengeClient.java
index ebb4fe6..d9bf1c3 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintRevokeChallengeClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintRevokeChallengeClient.java
@@ -45,7 +45,7 @@
     @Override
     protected void startHalOperation() {
         try {
-            getFreshDaemon().revokeChallenge(mSequentialId, mChallenge);
+            getFreshDaemon().revokeChallenge(mChallenge);
         } catch (RemoteException e) {
             Slog.e(TAG, "Unable to revokeChallenge", e);
         }
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintStartUserClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintStartUserClient.java
new file mode 100644
index 0000000..2d40c91
--- /dev/null
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintStartUserClient.java
@@ -0,0 +1,68 @@
+/*
+ * 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.biometrics.sensors.fingerprint.aidl;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.hardware.biometrics.fingerprint.IFingerprint;
+import android.hardware.biometrics.fingerprint.ISession;
+import android.hardware.biometrics.fingerprint.ISessionCallback;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Slog;
+
+import com.android.server.biometrics.sensors.StartUserClient;
+
+public class FingerprintStartUserClient extends StartUserClient<IFingerprint, ISession> {
+    private static final String TAG = "FingerprintStartUserClient";
+
+    @NonNull private final ISessionCallback mSessionCallback;
+
+    public FingerprintStartUserClient(@NonNull Context context,
+            @NonNull LazyDaemon<IFingerprint> lazyDaemon,
+            @Nullable IBinder token, int userId, int sensorId,
+            @NonNull ISessionCallback sessionCallback,
+            @NonNull UserStartedCallback<ISession> callback) {
+        super(context, lazyDaemon, token, userId, sensorId, callback);
+        mSessionCallback = sessionCallback;
+    }
+
+    @Override
+    public void start(@NonNull Callback callback) {
+        super.start(callback);
+        startHalOperation();
+    }
+
+    @Override
+    protected void startHalOperation() {
+        try {
+            final ISession newSession = getFreshDaemon().createSession(getSensorId(),
+                    getTargetUserId(), mSessionCallback);
+            mUserStartedCallback.onUserStarted(getTargetUserId(), newSession);
+            getCallback().onClientFinished(this, true /* success */);
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Remote exception", e);
+            getCallback().onClientFinished(this, false /* success */);
+        }
+    }
+
+    @Override
+    public void unableToStart() {
+
+    }
+}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintStopUserClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintStopUserClient.java
new file mode 100644
index 0000000..7055d65
--- /dev/null
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintStopUserClient.java
@@ -0,0 +1,58 @@
+/*
+ * 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.biometrics.sensors.fingerprint.aidl;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.hardware.biometrics.fingerprint.ISession;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Slog;
+
+import com.android.server.biometrics.sensors.StopUserClient;
+
+public class FingerprintStopUserClient extends StopUserClient<ISession> {
+    private static final String TAG = "FingerprintStopUserClient";
+
+    public FingerprintStopUserClient(@NonNull Context context,
+            @NonNull LazyDaemon<ISession> lazyDaemon, @Nullable IBinder token, int userId,
+            int sensorId, @NonNull UserStoppedCallback callback) {
+        super(context, lazyDaemon, token, userId, sensorId, callback);
+    }
+
+    @Override
+    public void start(@NonNull Callback callback) {
+        super.start(callback);
+        startHalOperation();
+    }
+
+    @Override
+    protected void startHalOperation() {
+        try {
+            getFreshDaemon().close();
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Remote exception", e);
+            getCallback().onClientFinished(this, false /* success */);
+        }
+    }
+
+    @Override
+    public void unableToStart() {
+
+    }
+}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java
index 5631647..4862d849 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java
@@ -24,15 +24,17 @@
 import android.hardware.biometrics.ITestSession;
 import android.hardware.biometrics.ITestSessionCallback;
 import android.hardware.biometrics.fingerprint.Error;
-import android.hardware.biometrics.fingerprint.IFingerprint;
 import android.hardware.biometrics.fingerprint.ISession;
 import android.hardware.biometrics.fingerprint.ISessionCallback;
 import android.hardware.fingerprint.Fingerprint;
 import android.hardware.fingerprint.FingerprintManager;
 import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
 import android.hardware.keymaster.HardwareAuthToken;
+import android.os.Binder;
 import android.os.Handler;
+import android.os.IBinder;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.os.UserManager;
 import android.util.Slog;
 import android.util.proto.ProtoOutputStream;
@@ -53,6 +55,9 @@
 import com.android.server.biometrics.sensors.LockoutCache;
 import com.android.server.biometrics.sensors.LockoutConsumer;
 import com.android.server.biometrics.sensors.RemovalConsumer;
+import com.android.server.biometrics.sensors.StartUserClient;
+import com.android.server.biometrics.sensors.StopUserClient;
+import com.android.server.biometrics.sensors.UserAwareBiometricScheduler;
 import com.android.server.biometrics.sensors.fingerprint.FingerprintUtils;
 import com.android.server.biometrics.sensors.fingerprint.GestureAvailabilityDispatcher;
 
@@ -72,9 +77,10 @@
     @NonNull private final String mTag;
     @NonNull private final FingerprintProvider mProvider;
     @NonNull private final Context mContext;
+    @NonNull private final IBinder mToken;
     @NonNull private final Handler mHandler;
     @NonNull private final FingerprintSensorPropertiesInternal mSensorProperties;
-    @NonNull private final BiometricScheduler mScheduler;
+    @NonNull private final UserAwareBiometricScheduler mScheduler;
     @NonNull private final LockoutCache mLockoutCache;
     @NonNull private final Map<Integer, Long> mAuthenticatorIds;
 
@@ -112,13 +118,13 @@
         @NonNull private final Context mContext;
         @NonNull private final Handler mHandler;
         @NonNull private final String mTag;
-        @NonNull private final BiometricScheduler mScheduler;
+        @NonNull private final UserAwareBiometricScheduler mScheduler;
         private final int mSensorId;
         private final int mUserId;
         @NonNull private final Callback mCallback;
 
         HalSessionCallback(@NonNull Context context, @NonNull Handler handler, @NonNull String tag,
-                @NonNull BiometricScheduler scheduler, int sensorId, int userId,
+                @NonNull UserAwareBiometricScheduler scheduler, int sensorId, int userId,
                 @NonNull Callback callback) {
             mContext = context;
             mHandler = handler;
@@ -130,11 +136,6 @@
         }
 
         @Override
-        public void onStateChanged(int cookie, byte state) {
-            // TODO(b/162973174)
-        }
-
-        @Override
         public void onChallengeGenerated(long challenge) {
             mHandler.post(() -> {
                 final BaseClientMonitor client = mScheduler.getCurrentClient();
@@ -403,6 +404,11 @@
                 invalidationClient.onAuthenticatorIdInvalidated(newAuthenticatorId);
             });
         }
+
+        @Override
+        public void onSessionClosed() {
+            mHandler.post(mScheduler::onUserStopped);
+        }
     }
 
     Sensor(@NonNull String tag, @NonNull FingerprintProvider provider, @NonNull Context context,
@@ -411,9 +417,53 @@
         mTag = tag;
         mProvider = provider;
         mContext = context;
+        mToken = new Binder();
         mHandler = handler;
         mSensorProperties = sensorProperties;
-        mScheduler = new BiometricScheduler(tag, gestureAvailabilityDispatcher);
+        mScheduler = new UserAwareBiometricScheduler(tag, gestureAvailabilityDispatcher,
+                () -> mCurrentSession != null ? mCurrentSession.mUserId : UserHandle.USER_NULL,
+                new UserAwareBiometricScheduler.UserSwitchCallback() {
+                    @NonNull
+                    @Override
+                    public StopUserClient<?> getStopUserClient(int userId) {
+                        return new FingerprintStopUserClient(mContext, mLazySession, mToken,
+                                userId, mSensorProperties.sensorId, () -> mCurrentSession = null);
+                    }
+
+                    @NonNull
+                    @Override
+                    public StartUserClient<?, ?> getStartUserClient(int newUserId) {
+                        final HalSessionCallback.Callback callback = () -> {
+                            Slog.e(mTag, "Got ERROR_HW_UNAVAILABLE");
+                            mCurrentSession = null;
+                        };
+
+                        final int sensorId = mSensorProperties.sensorId;
+
+                        final HalSessionCallback resultController = new HalSessionCallback(mContext,
+                                mHandler, mTag, mScheduler, sensorId, newUserId, callback);
+
+                        final StartUserClient.UserStartedCallback<ISession> userStartedCallback =
+                                (userIdStarted, newSession) -> {
+                                    mCurrentSession = new Session(mTag,
+                                            newSession, userIdStarted, resultController);
+                                    if (FingerprintUtils.getInstance(sensorId)
+                                            .isInvalidationInProgress(mContext, userIdStarted)) {
+                                        Slog.w(mTag,
+                                                "Scheduling unfinished invalidation request for "
+                                                        + "sensor: "
+                                                        + sensorId
+                                                        + ", user: " + userIdStarted);
+                                        provider.scheduleInvalidationRequest(sensorId,
+                                                userIdStarted);
+                                    }
+                                };
+
+                        return new FingerprintStartUserClient(mContext, provider::getHalInstance,
+                                mToken, newUserId, mSensorProperties.sensorId,
+                                resultController, userStartedCallback);
+                    }
+                });
         mLockoutCache = new LockoutCache();
         mAuthenticatorIds = new HashMap<>();
         mLazySession = () -> mCurrentSession != null ? mCurrentSession.mSession : null;
@@ -427,11 +477,6 @@
         return mSensorProperties;
     }
 
-    @SuppressWarnings("BooleanMethodIsAlwaysInverted")
-    boolean hasSessionForUser(int userId) {
-        return mCurrentSession != null && mCurrentSession.mUserId == userId;
-    }
-
     @Nullable Session getSessionForUser(int userId) {
         if (mCurrentSession != null && mCurrentSession.mUserId == userId) {
             return mCurrentSession;
@@ -445,20 +490,6 @@
                 mProvider, this);
     }
 
-    void createNewSession(@NonNull IFingerprint daemon, int sensorId, int userId)
-            throws RemoteException {
-
-        final HalSessionCallback.Callback callback = () -> {
-            Slog.e(mTag, "Got ERROR_HW_UNAVAILABLE");
-            mCurrentSession = null;
-        };
-        final HalSessionCallback resultController = new HalSessionCallback(mContext, mHandler,
-                mTag, mScheduler, sensorId, userId, callback);
-
-        final ISession newSession = daemon.createSession(sensorId, userId, resultController);
-        mCurrentSession = new Session(mTag, newSession, userId, resultController);
-    }
-
     @NonNull BiometricScheduler getScheduler() {
         return mScheduler;
     }
@@ -479,7 +510,7 @@
                 if (mCurrentSession != null && mCurrentSession.mSession != null) {
                     // TODO(181984005): This should be scheduled instead of directly invoked
                     Slog.d(mTag, "Closing old session");
-                    mCurrentSession.mSession.close(999 /* cookie */);
+                    mCurrentSession.mSession.close();
                 }
             } catch (RemoteException e) {
                 Slog.e(mTag, "RemoteException", e);
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/TestHal.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/TestHal.java
index 0b7f3ab..abc3597 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/TestHal.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/TestHal.java
@@ -22,7 +22,6 @@
 import android.hardware.biometrics.fingerprint.ISession;
 import android.hardware.biometrics.fingerprint.ISessionCallback;
 import android.hardware.biometrics.fingerprint.SensorProps;
-import android.hardware.biometrics.fingerprint.SessionState;
 import android.hardware.keymaster.HardwareAuthToken;
 import android.os.RemoteException;
 import android.util.Slog;
@@ -45,20 +44,20 @@
 
         return new ISession.Stub() {
             @Override
-            public void generateChallenge(int cookie) throws RemoteException {
-                Slog.w(TAG, "generateChallenge, cookie: " + cookie);
+            public void generateChallenge() throws RemoteException {
+                Slog.w(TAG, "generateChallenge");
                 cb.onChallengeGenerated(0L);
             }
 
             @Override
-            public void revokeChallenge(int cookie, long challenge) throws RemoteException {
-                Slog.w(TAG, "revokeChallenge: " + challenge + ", cookie: " + cookie);
+            public void revokeChallenge(long challenge) throws RemoteException {
+                Slog.w(TAG, "revokeChallenge: " + challenge);
                 cb.onChallengeRevoked(challenge);
             }
 
             @Override
-            public ICancellationSignal enroll(int cookie, HardwareAuthToken hat) {
-                Slog.w(TAG, "enroll, cookie: " + cookie);
+            public ICancellationSignal enroll(HardwareAuthToken hat) {
+                Slog.w(TAG, "enroll");
                 return new ICancellationSignal.Stub() {
                     @Override
                     public void cancel() throws RemoteException {
@@ -68,8 +67,8 @@
             }
 
             @Override
-            public ICancellationSignal authenticate(int cookie, long operationId) {
-                Slog.w(TAG, "authenticate, cookie: " + cookie);
+            public ICancellationSignal authenticate(long operationId) {
+                Slog.w(TAG, "authenticate");
                 return new ICancellationSignal.Stub() {
                     @Override
                     public void cancel() throws RemoteException {
@@ -79,8 +78,8 @@
             }
 
             @Override
-            public ICancellationSignal detectInteraction(int cookie) {
-                Slog.w(TAG, "detectInteraction, cookie: " + cookie);
+            public ICancellationSignal detectInteraction() {
+                Slog.w(TAG, "detectInteraction");
                 return new ICancellationSignal.Stub() {
                     @Override
                     public void cancel() throws RemoteException {
@@ -90,38 +89,39 @@
             }
 
             @Override
-            public void enumerateEnrollments(int cookie) throws RemoteException {
-                Slog.w(TAG, "enumerateEnrollments, cookie: " + cookie);
+            public void enumerateEnrollments() throws RemoteException {
+                Slog.w(TAG, "enumerateEnrollments");
                 cb.onEnrollmentsEnumerated(new int[0]);
             }
 
             @Override
-            public void removeEnrollments(int cookie, int[] enrollmentIds) throws RemoteException {
-                Slog.w(TAG, "removeEnrollments, cookie: " + cookie);
+            public void removeEnrollments(int[] enrollmentIds) throws RemoteException {
+                Slog.w(TAG, "removeEnrollments");
                 cb.onEnrollmentsRemoved(enrollmentIds);
             }
 
             @Override
-            public void getAuthenticatorId(int cookie) throws RemoteException {
-                Slog.w(TAG, "getAuthenticatorId, cookie: " + cookie);
+            public void getAuthenticatorId() throws RemoteException {
+                Slog.w(TAG, "getAuthenticatorId");
                 cb.onAuthenticatorIdRetrieved(0L);
             }
 
             @Override
-            public void invalidateAuthenticatorId(int cookie) throws RemoteException {
-                Slog.w(TAG, "invalidateAuthenticatorId, cookie: " + cookie);
+            public void invalidateAuthenticatorId() throws RemoteException {
+                Slog.w(TAG, "invalidateAuthenticatorId");
                 cb.onAuthenticatorIdInvalidated(0L);
             }
 
             @Override
-            public void resetLockout(int cookie, HardwareAuthToken hat) throws RemoteException {
-                Slog.w(TAG, "resetLockout, cookie: " + cookie);
+            public void resetLockout(HardwareAuthToken hat) throws RemoteException {
+                Slog.w(TAG, "resetLockout");
                 cb.onLockoutCleared();
             }
 
             @Override
-            public void close(int cookie) throws RemoteException {
-                cb.onStateChanged(cookie, SessionState.CLOSED);
+            public void close() throws RemoteException {
+                Slog.w(TAG, "close");
+                cb.onSessionClosed();
             }
 
             @Override
diff --git a/services/core/java/com/android/server/camera/CameraServiceProxy.java b/services/core/java/com/android/server/camera/CameraServiceProxy.java
index 40d2073..cd24576 100644
--- a/services/core/java/com/android/server/camera/CameraServiceProxy.java
+++ b/services/core/java/com/android/server/camera/CameraServiceProxy.java
@@ -15,17 +15,33 @@
  */
 package com.android.server.camera;
 
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+import static android.os.Build.VERSION_CODES.M;
+
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.ActivityManager;
+import android.app.ActivityTaskManager;
+import android.app.TaskStackListener;
 import android.content.BroadcastReceiver;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Configuration;
+import android.graphics.Rect;
 import android.hardware.CameraSessionStats;
 import android.hardware.CameraStreamStats;
 import android.hardware.ICameraService;
 import android.hardware.ICameraServiceProxy;
+import android.hardware.camera2.CameraMetadata;
+import android.hardware.display.DisplayManager;
 import android.media.AudioManager;
 import android.metrics.LogMaker;
 import android.nfc.INfcAdapter;
@@ -38,10 +54,13 @@
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.os.UserManager;
-import android.stats.camera.nano.CameraStreamProto;
+import android.stats.camera.nano.CameraProtos.CameraStreamProto;
 import android.util.ArrayMap;
 import android.util.ArraySet;
+import android.util.Log;
 import android.util.Slog;
+import android.view.Display;
+import android.view.Surface;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.framework.protobuf.nano.MessageNano;
@@ -61,6 +80,7 @@
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ScheduledThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
@@ -203,6 +223,63 @@
         }
     }
 
+    private final TaskStateHandler mTaskStackListener = new TaskStateHandler();
+
+    private final class TaskInfo {
+        private int frontTaskId;
+        private boolean isResizeable;
+        private boolean isFixedOrientationLandscape;
+        private boolean isFixedOrientationPortrait;
+        private int displayId;
+    }
+
+    private final class TaskStateHandler extends TaskStackListener {
+        private final Object mMapLock = new Object();
+
+        // maps the current top level task id to its corresponding package name
+        @GuardedBy("mMapLock")
+        private final ArrayMap<String, TaskInfo> mTaskInfoMap = new ArrayMap<>();
+
+        @Override
+        public void onTaskMovedToFront(ActivityManager.RunningTaskInfo taskInfo)
+                throws RemoteException {
+            synchronized (mMapLock) {
+                TaskInfo info = new TaskInfo();
+                info.frontTaskId = taskInfo.taskId;
+                info.isResizeable = taskInfo.isResizeable;
+                info.displayId = taskInfo.displayId;
+                info.isFixedOrientationLandscape = ActivityInfo.isFixedOrientationLandscape(
+                        taskInfo.topActivityInfo.screenOrientation);
+                info.isFixedOrientationPortrait = ActivityInfo.isFixedOrientationPortrait(
+                        taskInfo.topActivityInfo.screenOrientation);
+                mTaskInfoMap.put(taskInfo.topActivityInfo.packageName, info);
+            }
+        }
+
+        @Override
+        public void onTaskRemoved(int taskId) throws RemoteException {
+            synchronized (mMapLock) {
+                for (Map.Entry<String, TaskInfo> entry : mTaskInfoMap.entrySet()){
+                    if (entry.getValue().frontTaskId == taskId) {
+                        mTaskInfoMap.remove(entry.getKey());
+                        break;
+                    }
+                }
+            }
+        }
+
+        public @Nullable TaskInfo getFrontTaskInfo(String packageName) {
+            synchronized (mMapLock) {
+                if (mTaskInfoMap.containsKey(packageName)) {
+                    return mTaskInfoMap.get(packageName);
+                }
+            }
+
+            Log.e(TAG, "Top task with package name: " + packageName + " not found!");
+            return null;
+        }
+    };
+
     private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
@@ -229,6 +306,102 @@
     };
 
     private final ICameraServiceProxy.Stub mCameraServiceProxy = new ICameraServiceProxy.Stub() {
+        private boolean isMOrBelow(Context ctx, String packageName) {
+            try {
+                return ctx.getPackageManager().getPackageInfo(
+                        packageName, 0).applicationInfo.targetSdkVersion <= M;
+            } catch (PackageManager.NameNotFoundException e) {
+                Slog.e(TAG,"Package name not found!");
+            }
+            return false;
+        }
+
+        /**
+         * Gets whether crop-rotate-scale is needed.
+         */
+        private boolean getNeedCropRotateScale(Context ctx, String packageName,
+                @Nullable TaskInfo taskInfo, int sensorOrientation, int lensFacing) {
+            if (taskInfo == null) {
+                return false;
+            }
+
+            // External cameras do not need crop-rotate-scale.
+            if (lensFacing != CameraMetadata.LENS_FACING_FRONT
+                    && lensFacing != CameraMetadata.LENS_FACING_BACK) {
+                Log.v(TAG, "lensFacing=" + lensFacing + ". Crop-rotate-scale is disabled.");
+                return false;
+            }
+
+            // Only enable the crop-rotate-scale workaround if the app targets M or below and is not
+            // resizeable.
+            if ((ctx != null) && !isMOrBelow(ctx, packageName) && taskInfo.isResizeable) {
+                Slog.v(TAG,
+                        "The activity is N or above and claims to support resizeable-activity. "
+                                + "Crop-rotate-scale is disabled.");
+                return false;
+            }
+
+            DisplayManager displayManager = ctx.getSystemService(DisplayManager.class);
+            Display display = displayManager.getDisplay(taskInfo.displayId);
+            int rotation = display.getRotation();
+            int rotationDegree = 0;
+            switch (rotation) {
+                case Surface.ROTATION_0:
+                    rotationDegree = 0;
+                    break;
+                case Surface.ROTATION_90:
+                    rotationDegree = 90;
+                    break;
+                case Surface.ROTATION_180:
+                    rotationDegree = 180;
+                    break;
+                case Surface.ROTATION_270:
+                    rotationDegree = 270;
+                    break;
+            }
+
+            // Here we only need to know whether the camera is landscape or portrait. Therefore we
+            // don't need to consider whether it is a front or back camera. The formula works for
+            // both.
+            boolean landscapeCamera = ((rotationDegree + sensorOrientation) % 180 == 0);
+            Slog.v(TAG,
+                    "Display.getRotation()=" + rotationDegree
+                            + " CameraCharacteristics.SENSOR_ORIENTATION=" + sensorOrientation
+                            + " isFixedOrientationPortrait=" + taskInfo.isFixedOrientationPortrait
+                            + " isFixedOrientationLandscape=" +
+                            taskInfo.isFixedOrientationLandscape);
+            // We need to do crop-rotate-scale when camera is landscape and activity is portrait or
+            // vice versa.
+            if ((taskInfo.isFixedOrientationPortrait && landscapeCamera)
+                    || (taskInfo.isFixedOrientationLandscape && !landscapeCamera)) {
+                return true;
+            } else {
+                return false;
+            }
+        }
+
+        @Override
+        public boolean isRotateAndCropOverrideNeeded(String packageName, int sensorOrientation,
+                int lensFacing) {
+            if (Binder.getCallingUid() != Process.CAMERASERVER_UID) {
+                Slog.e(TAG, "Calling UID: " + Binder.getCallingUid() + " doesn't match expected " +
+                        " camera service UID!");
+                return false;
+            }
+
+            // A few remaining todos:
+            // 1) Do the same check when working in WM compatible mode. The sequence needs
+            //    to be adjusted and use orientation events as triggers for all active camera
+            //    clients.
+            // 2) Modify the sensor orientation in camera characteristics along with any 3A regions
+            //    in capture requests/results to account for thea physical rotation. The former
+            //    is somewhat tricky as it assumes that camera clients always check for the current
+            //    value by retrieving the camera characteristics from the camera device.
+            return getNeedCropRotateScale(mContext, packageName,
+                    mTaskStackListener.getFrontTaskInfo(packageName), sensorOrientation,
+                    lensFacing);
+        }
+
         @Override
         public void pingForUserUpdate() {
             if (Binder.getCallingUid() != Process.CAMERASERVER_UID) {
@@ -350,6 +523,12 @@
         publishBinderService(CAMERA_SERVICE_PROXY_BINDER_NAME, mCameraServiceProxy);
         publishLocalService(CameraServiceProxy.class, this);
 
+        try {
+            ActivityTaskManager.getService().registerTaskStackListener(mTaskStackListener);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to register task stack listener!");
+        }
+
         CameraStatsJobService.schedule(mContext);
     }
 
diff --git a/services/core/java/com/android/server/clipboard/ClipboardService.java b/services/core/java/com/android/server/clipboard/ClipboardService.java
index 71565301..e148775 100644
--- a/services/core/java/com/android/server/clipboard/ClipboardService.java
+++ b/services/core/java/com/android/server/clipboard/ClipboardService.java
@@ -106,16 +106,42 @@
         return bits;
     }
 
-    private void openPipe() {
+    private boolean openPipe() {
         try {
-            mPipe = new RandomAccessFile(PIPE_DEVICE, "rw");
-            mPipe.write(createOpenHandshake());
-        } catch (IOException e) {
+            final RandomAccessFile pipe = new RandomAccessFile(PIPE_DEVICE, "rw");
             try {
-                if (mPipe != null) mPipe.close();
-            } catch (IOException ee) {}
-            mPipe = null;
+                pipe.write(createOpenHandshake());
+                mPipe = pipe;
+                return true;
+            } catch (IOException ignore) {
+                pipe.close();
+            }
+        } catch (IOException ignore) {
         }
+        return false;
+    }
+
+    private void closePipe() {
+        try {
+            final RandomAccessFile pipe = mPipe;
+            mPipe = null;
+            if (pipe != null) {
+                pipe.close();
+            }
+        } catch (IOException ignore) {
+        }
+    }
+
+    private byte[] receiveMessage() throws IOException {
+        final int size = Integer.reverseBytes(mPipe.readInt());
+        final byte[] receivedData = new byte[size];
+        mPipe.readFully(receivedData);
+        return receivedData;
+    }
+
+    private void sendMessage(byte[] message) throws IOException {
+        mPipe.writeInt(Integer.reverseBytes(message.length));
+        mPipe.write(message);
     }
 
     public HostClipboardMonitor(HostClipboardCallback cb) {
@@ -129,21 +155,15 @@
                 // There's no guarantee that QEMU pipes will be ready at the moment
                 // this method is invoked. We simply try to get the pipe open and
                 // retry on failure indefinitely.
-                while (mPipe == null) {
-                    openPipe();
+                while ((mPipe == null) && !openPipe()) {
                     Thread.sleep(100);
                 }
-                int size = mPipe.readInt();
-                size = Integer.reverseBytes(size);
-                byte[] receivedData = new byte[size];
-                mPipe.readFully(receivedData);
+
+                final byte[] receivedData = receiveMessage();
                 mHostClipboardCallback.onHostClipboardUpdated(
                     new String(receivedData));
             } catch (IOException e) {
-                try {
-                    mPipe.close();
-                } catch (IOException ee) {}
-                mPipe = null;
+                closePipe();
             } catch (InterruptedException e) {}
         }
     }
@@ -151,8 +171,7 @@
     public void setHostClipboard(String content) {
         try {
             if (mPipe != null) {
-                mPipe.writeInt(Integer.reverseBytes(content.getBytes().length));
-                mPipe.write(content.getBytes());
+                sendMessage(content.getBytes());
             }
         } catch(IOException e) {
             Slog.e("HostClipboardMonitor",
@@ -460,7 +479,7 @@
             synchronized (mLock) {
                 addActiveOwnerLocked(intendingUid, pkg);
                 PerUserClipboard clipboard = getClipboardLocked(intendingUserId);
-                maybeNotifyLocked(pkg, intendingUid, intendingUserId, clipboard);
+                showAccessNotificationLocked(pkg, intendingUid, intendingUserId, clipboard);
                 return clipboard.primaryClip;
             }
         }
@@ -924,7 +943,7 @@
     private boolean clipboardAccessAllowed(int op, String callingPackage, int uid,
             @UserIdInt int userId, boolean shouldNoteOp) {
 
-        boolean allowed = false;
+        boolean allowed;
 
         // First, verify package ownership to ensure use below is safe.
         mAppOps.checkPackage(uid, callingPackage);
@@ -933,15 +952,9 @@
         if (mPm.checkPermission(android.Manifest.permission.READ_CLIPBOARD_IN_BACKGROUND,
                     callingPackage) == PackageManager.PERMISSION_GRANTED) {
             allowed = true;
-        }
-        // The default IME is always allowed to access the clipboard.
-        String defaultIme = Settings.Secure.getStringForUser(getContext().getContentResolver(),
-                Settings.Secure.DEFAULT_INPUT_METHOD, userId);
-        if (!TextUtils.isEmpty(defaultIme)) {
-            final String imePkg = ComponentName.unflattenFromString(defaultIme).getPackageName();
-            if (imePkg.equals(callingPackage)) {
-                allowed = true;
-            }
+        } else {
+            // The default IME is always allowed to access the clipboard.
+            allowed = isDefaultIme(userId, callingPackage);
         }
 
         switch (op) {
@@ -998,12 +1011,24 @@
         return appOpsResult == AppOpsManager.MODE_ALLOWED;
     }
 
+    private boolean isDefaultIme(int userId, String packageName) {
+        String defaultIme = Settings.Secure.getStringForUser(getContext().getContentResolver(),
+                Settings.Secure.DEFAULT_INPUT_METHOD, userId);
+        if (!TextUtils.isEmpty(defaultIme)) {
+            final String imePkg = ComponentName.unflattenFromString(defaultIme).getPackageName();
+            return imePkg.equals(packageName);
+        }
+        return false;
+    }
+
     /**
-     * Potentially notifies the user (via a toast) about an app accessing the clipboard.
-     * TODO(b/167676460): STOPSHIP as we don't want this code as-is to launch. Just an experiment.
+     * Shows a toast to inform the user that an app has accessed the clipboard. This is only done if
+     * the setting is enabled, and if the accessing app is not the source of the data and is not the
+     * IME, the content capture service, or the autofill service. The notification is also only
+     * shown once per clip for each app.
      */
     @GuardedBy("mLock")
-    private void maybeNotifyLocked(String callingPackage, int uid, @UserIdInt int userId,
+    private void showAccessNotificationLocked(String callingPackage, int uid, @UserIdInt int userId,
             PerUserClipboard clipboard) {
         if (clipboard.primaryClip == null) {
             return;
@@ -1019,15 +1044,9 @@
         if (UserHandle.isSameApp(uid, clipboard.primaryClipUid)) {
             return;
         }
-        // Exclude some special cases. It's a bit wasteful to check these again here, but for now
-        // beneficial to have all the logic contained in this single (probably temporary) method.
-        String defaultIme = Settings.Secure.getStringForUser(getContext().getContentResolver(),
-                Settings.Secure.DEFAULT_INPUT_METHOD, userId);
-        if (!TextUtils.isEmpty(defaultIme)) {
-            final String imePkg = ComponentName.unflattenFromString(defaultIme).getPackageName();
-            if (imePkg.equals(callingPackage)) {
-                return;
-            }
+        // Exclude special cases: IME, ContentCapture, Autofill.
+        if (isDefaultIme(userId, callingPackage)) {
+            return;
         }
         if (mContentCaptureInternal != null
                 && mContentCaptureInternal.isContentCaptureServiceForUser(uid, userId)) {
@@ -1044,27 +1063,16 @@
         clipboard.mNotifiedUids.put(uid, true);
 
         Binder.withCleanCallingIdentity(() -> {
-            // Retrieve the app label of the source of the clip data
-            CharSequence sourceAppLabel = null;
-            if (clipboard.mPrimaryClipPackage != null) {
-                try {
-                    sourceAppLabel = mPm.getApplicationLabel(mPm.getApplicationInfoAsUser(
-                            clipboard.mPrimaryClipPackage, 0, userId));
-                } catch (PackageManager.NameNotFoundException e) {
-                    // leave label as null
-                }
-            }
-
             try {
                 CharSequence callingAppLabel = mPm.getApplicationLabel(
                         mPm.getApplicationInfoAsUser(callingPackage, 0, userId));
                 String message;
-                if (sourceAppLabel != null) {
+                if (isText(clipboard.primaryClip)) {
                     message = getContext().getString(
-                            R.string.pasted_from_app, callingAppLabel, sourceAppLabel);
+                            R.string.pasted_text, callingAppLabel);
                 } else {
                     message = getContext().getString(
-                            R.string.pasted_from_clipboard, callingAppLabel);
+                            R.string.pasted_content, callingAppLabel);
                 }
                 Slog.i(TAG, message);
                 Toast.makeText(
@@ -1075,4 +1083,21 @@
             }
         });
     }
+
+    /**
+     * Returns true if the provided {@link ClipData} represents a single piece of text. That is, if
+     * there is only on {@link ClipData.Item}, and that item contains a non-empty piece of text and
+     * no URI or Intent. Note that HTML may be provided along with text so the presence of
+     * HtmlText in the clip does not prevent this method returning true.
+     */
+    private static boolean isText(@NonNull ClipData data) {
+        if (data.getItemCount() > 1) {
+            return false;
+        }
+        ClipData.Item item = data.getItemAt(0);
+
+        return !TextUtils.isEmpty(item.getText()) && item.getUri() == null
+                && item.getIntent() == null;
+    }
+
 }
diff --git a/services/core/java/com/android/server/compat/CompatChange.java b/services/core/java/com/android/server/compat/CompatChange.java
index ae9b001..d29a0c7 100644
--- a/services/core/java/com/android/server/compat/CompatChange.java
+++ b/services/core/java/com/android/server/compat/CompatChange.java
@@ -23,7 +23,9 @@
 import android.annotation.Nullable;
 import android.app.compat.PackageOverride;
 import android.compat.annotation.ChangeId;
+import android.compat.annotation.Disabled;
 import android.compat.annotation.EnabledSince;
+import android.compat.annotation.Overridable;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
@@ -60,6 +62,15 @@
     static final long CTS_SYSTEM_API_CHANGEID = 149391281; // This is a bug id.
 
     /**
+     * An overridable change ID to be used only in the CTS test for this SystemApi
+     */
+    @ChangeId
+    @Disabled
+    @Overridable
+    static final long CTS_SYSTEM_API_OVERRIDABLE_CHANGEID = 174043039; // This is a bug id.
+
+
+    /**
      * Callback listener for when compat changes are updated for a package.
      * See {@link #registerListener(ChangeListener)} for more details.
      */
@@ -211,6 +222,7 @@
     boolean hasPackageOverride(String pname) {
         return mRawOverrides.containsKey(pname);
     }
+
     /**
      * Remove any package override for the given package name, restoring the default behaviour.
      *
@@ -355,7 +367,7 @@
             override.setPackageName(entry.getKey());
             override.setMinVersionCode(entry.getValue().getMinVersionCode());
             override.setMaxVersionCode(entry.getValue().getMaxVersionCode());
-            override.setEnabled(entry.getValue().getEnabled());
+            override.setEnabled(entry.getValue().isEnabled());
             rawList.add(override);
         }
         changeOverrides.setRaw(rawOverrides);
diff --git a/services/core/java/com/android/server/compat/CompatConfig.java b/services/core/java/com/android/server/compat/CompatConfig.java
index ef86f42..55e2696 100644
--- a/services/core/java/com/android/server/compat/CompatConfig.java
+++ b/services/core/java/com/android/server/compat/CompatConfig.java
@@ -304,6 +304,16 @@
     }
 
     /**
+     * Returns whether the change is overridable.
+     */
+    boolean isOverridable(long changeId) {
+        synchronized (mChanges) {
+            CompatChange c = mChanges.get(changeId);
+            return c != null && c.getOverridable();
+        }
+    }
+
+    /**
      * Removes an override previously added via {@link #addOverride(long, String, boolean)}.
      *
      * <p>This restores the default behaviour for the given change and app, once any app processes
@@ -343,7 +353,7 @@
 
     /**
      * Removes all overrides previously added via {@link #addOverride(long, String, boolean)} or
-     * {@link #addOverrides(CompatibilityChangeConfig, String)} for a certain package.
+     * {@link #addOverrides(CompatibilityOverrideConfig, String)} for a certain package.
      *
      * <p>This restores the default behaviour for the given app.
      *
@@ -632,8 +642,11 @@
         }
         boolean shouldInvalidateCache = false;
         for (CompatChange c: changes) {
+            if (!c.hasPackageOverride(packageName)) {
+                continue;
+            }
             OverrideAllowedState allowedState =
-                    mOverrideValidator.getOverrideAllowedState(c.getId(), packageName);
+                    mOverrideValidator.getOverrideAllowedStateForRecheck(c.getId(), packageName);
             shouldInvalidateCache |= c.recheckOverride(packageName, allowedState, mContext);
         }
         if (shouldInvalidateCache) {
diff --git a/services/core/java/com/android/server/compat/OverrideValidatorImpl.java b/services/core/java/com/android/server/compat/OverrideValidatorImpl.java
index aa66a1a..b500691 100644
--- a/services/core/java/com/android/server/compat/OverrideValidatorImpl.java
+++ b/services/core/java/com/android/server/compat/OverrideValidatorImpl.java
@@ -16,6 +16,9 @@
 
 package com.android.server.compat;
 
+import static android.Manifest.permission.OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+
 import static com.android.internal.compat.OverrideAllowedState.ALLOWED;
 import static com.android.internal.compat.OverrideAllowedState.DEFERRED_VERIFICATION;
 import static com.android.internal.compat.OverrideAllowedState.DISABLED_NON_TARGET_SDK;
@@ -24,6 +27,7 @@
 import static com.android.internal.compat.OverrideAllowedState.LOGGING_ONLY_CHANGE;
 import static com.android.internal.compat.OverrideAllowedState.PLATFORM_TOO_OLD;
 
+import android.annotation.NonNull;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
@@ -69,8 +73,25 @@
         mForceNonDebuggableFinalBuild = false;
     }
 
+    /**
+     * Check the allowed state for the given changeId and packageName on a recheck.
+     *
+     * <p>Recheck happens when the given app is getting updated. In this case we cannot do a
+     * permission check on the caller, so we're using the fact that the override was present as
+     * proof that the original caller was allowed to set this override.
+     */
+    OverrideAllowedState getOverrideAllowedStateForRecheck(long changeId,
+            @NonNull String packageName) {
+        return getOverrideAllowedStateInternal(changeId, packageName, true);
+    }
+
     @Override
     public OverrideAllowedState getOverrideAllowedState(long changeId, String packageName) {
+        return getOverrideAllowedStateInternal(changeId, packageName, false);
+    }
+
+    private OverrideAllowedState getOverrideAllowedStateInternal(long changeId, String packageName,
+            boolean isRecheck) {
         if (mCompatConfig.isLoggingOnly(changeId)) {
             return new OverrideAllowedState(LOGGING_ONLY_CHANGE, -1, -1);
         }
@@ -99,6 +120,16 @@
         } catch (NameNotFoundException e) {
             return new OverrideAllowedState(DEFERRED_VERIFICATION, -1, -1);
         }
+        // If the change is annotated as @Overridable, apps with the specific permission can
+        // set the override even on production builds. When rechecking the override, e.g. during an
+        // app update we can bypass this check, as it wouldn't have been here in the first place.
+        if (mCompatConfig.isOverridable(changeId)
+                && (isRecheck
+                        || mContext.checkCallingOrSelfPermission(
+                                OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD)
+                                        == PERMISSION_GRANTED)) {
+            return new OverrideAllowedState(ALLOWED, -1, -1);
+        }
         int appTargetSdk = applicationInfo.targetSdkVersion;
         // Only allow overriding debuggable apps.
         if ((applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
@@ -130,5 +161,4 @@
     void forceNonDebuggableFinalForTest(boolean value) {
         mForceNonDebuggableFinalBuild = value;
     }
-
 }
diff --git a/services/core/java/com/android/server/compat/PlatformCompat.java b/services/core/java/com/android/server/compat/PlatformCompat.java
index 2be39aa..62de369 100644
--- a/services/core/java/com/android/server/compat/PlatformCompat.java
+++ b/services/core/java/com/android/server/compat/PlatformCompat.java
@@ -18,6 +18,7 @@
 
 import static android.Manifest.permission.LOG_COMPAT_CHANGE;
 import static android.Manifest.permission.OVERRIDE_COMPAT_CHANGE_CONFIG;
+import static android.Manifest.permission.OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD;
 import static android.Manifest.permission.READ_COMPAT_CHANGE_CONFIG;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.os.Process.SYSTEM_UID;
@@ -182,11 +183,12 @@
     }
 
     @Override
-    public void setOverridesFromInstaller(CompatibilityOverrideConfig overrides,
+    public void setOverridesOnReleaseBuilds(CompatibilityOverrideConfig overrides,
             String packageName) {
-        checkCompatChangeOverridePermission();
+        // TODO(b/183630314): Unify the permission enforcement with the other setOverrides* methods.
+        checkCompatChangeOverrideOverridablePermission();
+        checkAllCompatOverridesAreOverridable(overrides);
         mCompatConfig.addOverrides(overrides, packageName);
-        killPackage(packageName);
     }
 
     @Override
@@ -383,6 +385,26 @@
         }
     }
 
+    private void checkCompatChangeOverrideOverridablePermission() {
+        // Don't check for permissions within the system process
+        if (Binder.getCallingUid() == SYSTEM_UID) {
+            return;
+        }
+        if (mContext.checkCallingOrSelfPermission(OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD)
+                != PERMISSION_GRANTED) {
+            throw new SecurityException("Cannot override compat change");
+        }
+    }
+
+    private void checkAllCompatOverridesAreOverridable(CompatibilityOverrideConfig overrides) {
+        for (Long changeId : overrides.overrides.keySet()) {
+            if (!mCompatConfig.isOverridable(changeId)) {
+                throw new SecurityException("Only change ids marked as Overridable can be "
+                        + "overridden.");
+            }
+        }
+    }
+
     private void checkCompatChangeReadAndLogPermission() {
         checkCompatChangeReadPermission();
         checkCompatChangeLogPermission();
diff --git a/services/core/java/com/android/server/connectivity/FullScore.java b/services/core/java/com/android/server/connectivity/FullScore.java
index 028cfee..375d005 100644
--- a/services/core/java/com/android/server/connectivity/FullScore.java
+++ b/services/core/java/com/android/server/connectivity/FullScore.java
@@ -16,14 +16,17 @@
 
 package com.android.server.connectivity;
 
+import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
 import static android.net.NetworkCapabilities.TRANSPORT_VPN;
+import static android.net.NetworkScore.KEEP_CONNECTED_NONE;
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.net.NetworkAgentConfig;
 import android.net.NetworkCapabilities;
 import android.net.NetworkScore;
+import android.net.NetworkScore.KeepConnectedReason;
 
 import com.android.internal.annotations.VisibleForTesting;
 
@@ -94,9 +97,13 @@
     // Bitmask of all the policies applied to this score.
     private final long mPolicies;
 
-    FullScore(final int legacyInt, final long policies) {
+    private final int mKeepConnectedReason;
+
+    FullScore(final int legacyInt, final long policies,
+            @KeepConnectedReason final int keepConnectedReason) {
         mLegacyInt = legacyInt;
         mPolicies = policies;
+        mKeepConnectedReason = keepConnectedReason;
     }
 
     /**
@@ -109,13 +116,41 @@
      */
     public static FullScore fromNetworkScore(@NonNull final NetworkScore score,
             @NonNull final NetworkCapabilities caps, @NonNull final NetworkAgentConfig config) {
-        return withPolicies(score.getLegacyInt(), caps.hasCapability(NET_CAPABILITY_VALIDATED),
+        return withPolicies(score.getLegacyInt(), score.getKeepConnectedReason(),
+                caps.hasCapability(NET_CAPABILITY_VALIDATED),
                 caps.hasTransport(TRANSPORT_VPN),
                 config.explicitlySelected,
                 config.acceptUnvalidated);
     }
 
     /**
+     * Given a score supplied by a NetworkProvider, produce a prospective score for an offer.
+     *
+     * NetworkOffers have score filters that are compared to the scores of actual networks
+     * to see if they could possibly beat the current satisfier. Some things the agent can't
+     * know in advance ; a good example is the validation bit – some networks will validate,
+     * others won't. For comparison purposes, assume the best, so all possibly beneficial
+     * networks will be brought up.
+     *
+     * @param score the score supplied by the agent for this offer
+     * @param caps the capabilities supplied by the agent for this offer
+     * @return a FullScore appropriate for comparing to actual network's scores.
+     */
+    public static FullScore makeProspectiveScore(@NonNull final NetworkScore score,
+            @NonNull final NetworkCapabilities caps) {
+        // If the network offers Internet access, it may validate.
+        final boolean mayValidate = caps.hasCapability(NET_CAPABILITY_INTERNET);
+        // VPN transports are known in advance.
+        final boolean vpn = caps.hasTransport(TRANSPORT_VPN);
+        // The network hasn't been chosen by the user (yet, at least).
+        final boolean everUserSelected = false;
+        // Don't assume the user will accept unvalidated connectivity.
+        final boolean acceptUnvalidated = false;
+        return withPolicies(score.getLegacyInt(), KEEP_CONNECTED_NONE,
+                mayValidate, vpn, everUserSelected, acceptUnvalidated);
+    }
+
+    /**
      * Return a new score given updated caps and config.
      *
      * @param caps the NetworkCapabilities of the network
@@ -124,13 +159,15 @@
      */
     public FullScore mixInScore(@NonNull final NetworkCapabilities caps,
             @NonNull final NetworkAgentConfig config) {
-        return withPolicies(mLegacyInt, caps.hasCapability(NET_CAPABILITY_VALIDATED),
+        return withPolicies(mLegacyInt, mKeepConnectedReason,
+                caps.hasCapability(NET_CAPABILITY_VALIDATED),
                 caps.hasTransport(TRANSPORT_VPN),
                 config.explicitlySelected,
                 config.acceptUnvalidated);
     }
 
     private static FullScore withPolicies(@NonNull final int legacyInt,
+            @KeepConnectedReason final int keepConnectedReason,
             final boolean isValidated,
             final boolean isVpn,
             final boolean everUserSelected,
@@ -139,7 +176,8 @@
                 (isValidated         ? 1L << POLICY_IS_VALIDATED : 0)
                 | (isVpn             ? 1L << POLICY_IS_VPN : 0)
                 | (everUserSelected  ? 1L << POLICY_EVER_USER_SELECTED : 0)
-                | (acceptUnvalidated ? 1L << POLICY_ACCEPT_UNVALIDATED : 0));
+                | (acceptUnvalidated ? 1L << POLICY_ACCEPT_UNVALIDATED : 0),
+                keepConnectedReason);
     }
 
     /**
@@ -191,13 +229,21 @@
         return 0 != (mPolicies & (1L << policy));
     }
 
+    /**
+     * Returns the keep-connected reason, or KEEP_CONNECTED_NONE.
+     */
+    public int getKeepConnectedReason() {
+        return mKeepConnectedReason;
+    }
+
     // Example output :
     // Score(50 ; Policies : EVER_USER_SELECTED&IS_VALIDATED)
     @Override
     public String toString() {
         final StringJoiner sj = new StringJoiner(
                 "&", // delimiter
-                "Score(" + mLegacyInt + " ; Policies : ", // prefix
+                "Score(" + mLegacyInt + " ; KeepConnected : " + mKeepConnectedReason
+                        + " ; Policies : ", // prefix
                 ")"); // suffix
         for (int i = NetworkScore.MIN_AGENT_MANAGED_POLICY;
                 i <= NetworkScore.MAX_AGENT_MANAGED_POLICY; ++i) {
diff --git a/services/core/java/com/android/server/connectivity/KeepaliveTracker.java b/services/core/java/com/android/server/connectivity/KeepaliveTracker.java
index 7b20ded..acf39f0 100644
--- a/services/core/java/com/android/server/connectivity/KeepaliveTracker.java
+++ b/services/core/java/com/android/server/connectivity/KeepaliveTracker.java
@@ -26,6 +26,7 @@
 import static android.net.SocketKeepalive.ERROR_INVALID_IP_ADDRESS;
 import static android.net.SocketKeepalive.ERROR_INVALID_NETWORK;
 import static android.net.SocketKeepalive.ERROR_INVALID_SOCKET;
+import static android.net.SocketKeepalive.ERROR_NO_SUCH_SLOT;
 import static android.net.SocketKeepalive.ERROR_STOP_REASON_UNINITIALIZED;
 import static android.net.SocketKeepalive.ERROR_UNSUPPORTED;
 import static android.net.SocketKeepalive.MAX_INTERVAL_SEC;
@@ -36,6 +37,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Context;
+import android.net.ConnectivityResources;
 import android.net.ISocketKeepaliveCallback;
 import android.net.InetAddresses;
 import android.net.InvalidPacketException;
@@ -56,7 +58,7 @@
 import android.util.Log;
 import android.util.Pair;
 
-import com.android.internal.R;
+import com.android.connectivity.resources.R;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.net.module.util.HexDump;
 import com.android.net.module.util.IpUtils;
@@ -111,10 +113,19 @@
         mTcpController = new TcpKeepaliveController(handler);
         mContext = context;
         mSupportedKeepalives = KeepaliveUtils.getSupportedKeepalives(mContext);
-        mReservedPrivilegedSlots = mContext.getResources().getInteger(
-                R.integer.config_reservedPrivilegedKeepaliveSlots);
-        mAllowedUnprivilegedSlotsForUid = mContext.getResources().getInteger(
-                R.integer.config_allowedUnprivilegedKeepalivePerUid);
+
+        // TODO (b/183076074): stop reading legacy resources after migrating overlays
+        final int legacyReservedSlots = mContext.getResources().getInteger(
+                mContext.getResources().getIdentifier(
+                        "config_reservedPrivilegedKeepaliveSlots", "integer", "android"));
+        final int legacyAllowedSlots = mContext.getResources().getInteger(
+                mContext.getResources().getIdentifier(
+                        "config_allowedUnprivilegedKeepalivePerUid", "integer", "android"));
+        final ConnectivityResources res = new ConnectivityResources(mContext);
+        mReservedPrivilegedSlots = Math.min(legacyReservedSlots, res.get().getInteger(
+                R.integer.config_reservedPrivilegedKeepaliveSlots));
+        mAllowedUnprivilegedSlotsForUid = Math.min(legacyAllowedSlots, res.get().getInteger(
+                R.integer.config_allowedUnprivilegedKeepalivePerUid));
     }
 
     /**
@@ -518,6 +529,8 @@
             }
         } else if (reason == ERROR_STOP_REASON_UNINITIALIZED) {
             throw new IllegalStateException("Unexpected stop reason: " + reason);
+        } else if (reason == ERROR_NO_SUCH_SLOT) {
+            throw new IllegalStateException("No such slot: " + reason);
         } else {
             notifyErrorCallback(ki.mCallback, reason);
         }
diff --git a/services/core/java/com/android/server/connectivity/LingerMonitor.java b/services/core/java/com/android/server/connectivity/LingerMonitor.java
index adec7ad..032612c 100644
--- a/services/core/java/com/android/server/connectivity/LingerMonitor.java
+++ b/services/core/java/com/android/server/connectivity/LingerMonitor.java
@@ -24,6 +24,8 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.res.Resources;
+import android.net.ConnectivityResources;
 import android.net.NetworkCapabilities;
 import android.os.SystemClock;
 import android.os.UserHandle;
@@ -34,7 +36,7 @@
 import android.util.SparseBooleanArray;
 import android.util.SparseIntArray;
 
-import com.android.internal.R;
+import com.android.connectivity.resources.R;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.MessageUtils;
 import com.android.server.connectivity.NetworkNotificationManager.NotificationType;
@@ -72,6 +74,7 @@
             new Class[] { LingerMonitor.class }, new String[]{ "NOTIFY_TYPE_" });
 
     private final Context mContext;
+    final Resources mResources;
     private final NetworkNotificationManager mNotifier;
     private final int mDailyLimit;
     private final long mRateLimitMillis;
@@ -89,6 +92,7 @@
     public LingerMonitor(Context context, NetworkNotificationManager notifier,
             int dailyLimit, long rateLimitMillis) {
         mContext = context;
+        mResources = new ConnectivityResources(mContext).get();
         mNotifier = notifier;
         mDailyLimit = dailyLimit;
         mRateLimitMillis = rateLimitMillis;
@@ -128,8 +132,7 @@
     @VisibleForTesting
     public boolean isNotificationEnabled(NetworkAgentInfo fromNai, NetworkAgentInfo toNai) {
         // TODO: Evaluate moving to CarrierConfigManager.
-        String[] notifySwitches =
-                mContext.getResources().getStringArray(R.array.config_networkNotifySwitches);
+        String[] notifySwitches = mResources.getStringArray(R.array.config_networkNotifySwitches);
 
         if (VDBG) {
             Log.d(TAG, "Notify on network switches: " + Arrays.toString(notifySwitches));
@@ -178,8 +181,7 @@
 
     // Notify the user of a network switch using a notification or a toast.
     private void notify(NetworkAgentInfo fromNai, NetworkAgentInfo toNai, boolean forceToast) {
-        int notifyType =
-                mContext.getResources().getInteger(R.integer.config_networkNotifySwitchType);
+        int notifyType = mResources.getInteger(R.integer.config_networkNotifySwitchType);
         if (notifyType == NOTIFY_TYPE_NOTIFICATION && forceToast) {
             notifyType = NOTIFY_TYPE_TOAST;
         }
diff --git a/services/core/java/com/android/server/connectivity/NetdEventListenerService.java b/services/core/java/com/android/server/connectivity/NetdEventListenerService.java
index f3d2012..6ea84ce 100644
--- a/services/core/java/com/android/server/connectivity/NetdEventListenerService.java
+++ b/services/core/java/com/android/server/connectivity/NetdEventListenerService.java
@@ -18,12 +18,14 @@
 
 import static android.util.TimeUtils.NANOS_PER_MS;
 
+import android.annotation.Nullable;
 import android.content.Context;
 import android.net.ConnectivityManager;
 import android.net.INetdEventCallback;
 import android.net.MacAddress;
 import android.net.Network;
 import android.net.NetworkCapabilities;
+import android.net.NetworkRequest;
 import android.net.metrics.ConnectStats;
 import android.net.metrics.DnsEvent;
 import android.net.metrics.INetdEventListener;
@@ -98,6 +100,7 @@
     private final TokenBucket mConnectTb =
             new TokenBucket(CONNECT_LATENCY_FILL_RATE, CONNECT_LATENCY_BURST_LIMIT);
 
+    final TransportForNetIdNetworkCallback mCallback = new TransportForNetIdNetworkCallback();
 
     /**
      * There are only 3 possible callbacks.
@@ -158,6 +161,9 @@
     public NetdEventListenerService(ConnectivityManager cm) {
         // We are started when boot is complete, so ConnectivityService should already be running.
         mCm = cm;
+        // Clear all capabilities to listen all networks.
+        mCm.registerNetworkCallback(new NetworkRequest.Builder().clearCapabilities().build(),
+                mCallback);
     }
 
     private static long projectSnapshotTime(long timeMs) {
@@ -389,18 +395,13 @@
     }
 
     private long getTransports(int netId) {
-        // TODO: directly query ConnectivityService instead of going through Binder interface.
-        NetworkCapabilities nc = mCm.getNetworkCapabilities(new Network(netId));
+        final NetworkCapabilities nc = mCallback.getNetworkCapabilities(netId);
         if (nc == null) {
             return 0;
         }
         return BitUtils.packBits(nc.getTransportTypes());
     }
 
-    private static void maybeLog(String s, Object... args) {
-        if (DBG) Log.d(TAG, String.format(s, args));
-    }
-
     /** Helper class for buffering summaries of NetworkMetrics at regular time intervals */
     static class NetworkMetricsSnapshot {
 
@@ -428,4 +429,29 @@
             return String.format("%tT.%tL: %s", timeMs, timeMs, j.toString());
         }
     }
+
+    private class TransportForNetIdNetworkCallback extends ConnectivityManager.NetworkCallback {
+        private final SparseArray<NetworkCapabilities> mCapabilities = new SparseArray<>();
+
+        @Override
+        public void onCapabilitiesChanged(Network network, NetworkCapabilities nc) {
+            synchronized (mCapabilities) {
+                mCapabilities.put(network.getNetId(), nc);
+            }
+        }
+
+        @Override
+        public void onLost(Network network) {
+            synchronized (mCapabilities) {
+                mCapabilities.remove(network.getNetId());
+            }
+        }
+
+        @Nullable
+        public NetworkCapabilities getNetworkCapabilities(int netId) {
+            synchronized (mCapabilities) {
+                return mCapabilities.get(netId);
+            }
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index 103ab95..d16a2de 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -49,6 +49,7 @@
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.telephony.data.EpsBearerQosSessionAttributes;
+import android.telephony.data.NrQosSessionAttributes;
 import android.util.Log;
 import android.util.Pair;
 import android.util.SparseArray;
@@ -200,6 +201,9 @@
     // Set to true when partial connectivity was detected.
     public boolean partialConnectivity;
 
+    // Delay between when the network is disconnected and when the native network is destroyed.
+    public int teardownDelayMs;
+
     // Captive portal info of the network from RFC8908, if any.
     // Obtained by ConnectivityService and merged into NetworkAgent-provided information.
     public CaptivePortalData capportApiData;
@@ -576,6 +580,28 @@
         }
     }
 
+    /**
+     * Notify the NetworkAgent that the network is successfully connected.
+     */
+    public void onNetworkCreated() {
+        try {
+            networkAgent.onNetworkCreated();
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error sending network created event", e);
+        }
+    }
+
+    /**
+     * Notify the NetworkAgent that the native network has been destroyed.
+     */
+    public void onNetworkDestroyed() {
+        try {
+            networkAgent.onNetworkDestroyed();
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error sending network destroyed event", e);
+        }
+    }
+
     // TODO: consider moving out of NetworkAgentInfo into its own class
     private class NetworkAgentMessageHandler extends INetworkAgentRegistry.Stub {
         private final Handler mHandler;
@@ -633,7 +659,13 @@
         @Override
         public void sendEpsQosSessionAvailable(final int qosCallbackId, final QosSession session,
                 final EpsBearerQosSessionAttributes attributes) {
-            mQosCallbackTracker.sendEventQosSessionAvailable(qosCallbackId, session, attributes);
+            mQosCallbackTracker.sendEventEpsQosSessionAvailable(qosCallbackId, session, attributes);
+        }
+
+        @Override
+        public void sendNrQosSessionAvailable(final int qosCallbackId, final QosSession session,
+                final NrQosSessionAttributes attributes) {
+            mQosCallbackTracker.sendEventNrQosSessionAvailable(qosCallbackId, session, attributes);
         }
 
         @Override
@@ -646,6 +678,12 @@
                 @QosCallbackException.ExceptionType final int exceptionType) {
             mQosCallbackTracker.sendEventQosCallbackError(qosCallbackId, exceptionType);
         }
+
+        @Override
+        public void sendTeardownDelayMs(int teardownDelayMs) {
+            mHandler.obtainMessage(NetworkAgent.EVENT_TEARDOWN_DELAY_CHANGED,
+                    teardownDelayMs, 0, new Pair<>(NetworkAgentInfo.this, null)).sendToTarget();
+        }
     }
 
     /**
@@ -855,6 +893,10 @@
         return isWifi && !avoidBadWifi && everValidated;
     }
 
+    public FullScore getScore() {
+        return mScore;
+    }
+
     // Get the current score for this Network.  This may be modified from what the
     // NetworkAgent sent, as it has modifiers applied to it.
     public int getCurrentScore() {
diff --git a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
index 0c0d459..b57ad5d8 100644
--- a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
+++ b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
@@ -84,7 +84,7 @@
 
     // The context is for the current user (system server)
     private final Context mContext;
-    private final Resources mResources;
+    private final ConnectivityResources mResources;
     private final TelephonyManager mTelephonyManager;
     // The notification manager is created from a context for User.ALL, so notifications
     // will be sent to all users.
@@ -99,7 +99,7 @@
                 (NotificationManager) c.createContextAsUser(UserHandle.ALL, 0 /* flags */)
                         .getSystemService(Context.NOTIFICATION_SERVICE);
         mNotificationTypeMap = new SparseIntArray();
-        mResources = new ConnectivityResources(mContext).get();
+        mResources = new ConnectivityResources(mContext);
     }
 
     @VisibleForTesting
@@ -118,11 +118,11 @@
     }
 
     private String getTransportName(final int transportType) {
-        String[] networkTypes = mResources.getStringArray(R.array.network_switch_type_name);
+        String[] networkTypes = mResources.get().getStringArray(R.array.network_switch_type_name);
         try {
             return networkTypes[transportType];
         } catch (IndexOutOfBoundsException e) {
-            return mResources.getString(R.string.network_switch_type_name_unknown);
+            return mResources.get().getString(R.string.network_switch_type_name_unknown);
         }
     }
 
@@ -197,10 +197,11 @@
                     tag, nameOf(eventId), getTransportName(transportType), name, highPriority));
         }
 
-        final Resources r = mResources;
+        final Resources r = mResources.get();
         final CharSequence title;
         final CharSequence details;
-        Icon icon = Icon.createWithResource(r, getIcon(transportType));
+        Icon icon = Icon.createWithResource(
+                mResources.getResourcesContext(), getIcon(transportType));
         if (notifyType == NotificationType.NO_INTERNET && transportType == TRANSPORT_WIFI) {
             title = r.getString(R.string.wifi_no_internet, name);
             details = r.getString(R.string.wifi_no_internet_detailed);
@@ -355,7 +356,7 @@
     public void showToast(NetworkAgentInfo fromNai, NetworkAgentInfo toNai) {
         String fromTransport = getTransportName(approximateTransportType(fromNai));
         String toTransport = getTransportName(approximateTransportType(toNai));
-        String text = mResources.getString(
+        String text = mResources.get().getString(
                 R.string.network_switch_metered_toast, fromTransport, toTransport);
         Toast.makeText(mContext, text, Toast.LENGTH_LONG).show();
     }
diff --git a/services/core/java/com/android/server/connectivity/NetworkOffer.java b/services/core/java/com/android/server/connectivity/NetworkOffer.java
new file mode 100644
index 0000000..a0d3924
--- /dev/null
+++ b/services/core/java/com/android/server/connectivity/NetworkOffer.java
@@ -0,0 +1,134 @@
+/*
+ * 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.connectivity;
+
+import android.annotation.NonNull;
+import android.net.INetworkOfferCallback;
+import android.net.NetworkCapabilities;
+import android.net.NetworkRequest;
+import android.os.RemoteException;
+
+import java.util.HashSet;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * Represents an offer made by a NetworkProvider to create a network if a need arises.
+ *
+ * This class contains the prospective score and capabilities of the network. The provider
+ * is not obligated to caps able to create a network satisfying this, nor to build a network
+ * with the exact score and/or capabilities passed ; after all, not all providers know in
+ * advance what a network will look like after it's connected. Instead, this is meant as a
+ * filter to limit requests sent to the provider by connectivity to those that this offer stands
+ * a chance to fulfill.
+ *
+ * @see NetworkProvider#offerNetwork.
+ *
+ * @hide
+ */
+public class NetworkOffer {
+    @NonNull public final FullScore score;
+    @NonNull public final NetworkCapabilities caps;
+    @NonNull public final INetworkOfferCallback callback;
+    @NonNull public final int providerId;
+    // While this could, in principle, be deduced from the old values of the satisfying networks,
+    // doing so would add a lot of complexity and performance penalties. For each request, the
+    // ranker would have to run again to figure out if this offer used to be able to beat the
+    // previous satisfier to know if there is a change in whether this offer is now needed ;
+    // besides, there would be a need to handle an edge case when a new request comes online,
+    // where it's not satisfied before the first rematch, where starting to satisfy a request
+    // should not result in sending unneeded to this offer. This boolean, while requiring that
+    // the offers are only ever manipulated on the CS thread, is by far a simpler and
+    // economical solution.
+    private final Set<NetworkRequest> mCurrentlyNeeded = new HashSet<>();
+
+    public NetworkOffer(@NonNull final FullScore score,
+            @NonNull final NetworkCapabilities caps,
+            @NonNull final INetworkOfferCallback callback,
+            @NonNull final int providerId) {
+        this.score = Objects.requireNonNull(score);
+        this.caps = Objects.requireNonNull(caps);
+        this.callback = Objects.requireNonNull(callback);
+        this.providerId = providerId;
+    }
+
+    /**
+     * Tell the provider for this offer that the network is needed for a request.
+     * @param request the request for which the offer is needed
+     */
+    public void onNetworkNeeded(@NonNull final NetworkRequest request) {
+        if (mCurrentlyNeeded.contains(request)) {
+            throw new IllegalStateException("Network already needed");
+        }
+        mCurrentlyNeeded.add(request);
+        try {
+            callback.onNetworkNeeded(request);
+        } catch (final RemoteException e) {
+            // The provider is dead. It will be removed by the death recipient.
+        }
+    }
+
+    /**
+     * Tell the provider for this offer that the network is no longer needed for this request.
+     *
+     * onNetworkNeeded will have been called with the same request before.
+     *
+     * @param request the request
+     */
+    public void onNetworkUnneeded(@NonNull final NetworkRequest request) {
+        if (!mCurrentlyNeeded.contains(request)) {
+            throw new IllegalStateException("Network already unneeded");
+        }
+        mCurrentlyNeeded.remove(request);
+        try {
+            callback.onNetworkUnneeded(request);
+        } catch (final RemoteException e) {
+            // The provider is dead. It will be removed by the death recipient.
+        }
+    }
+
+    /**
+     * Returns whether this offer is currently needed for this request.
+     * @param request the request
+     * @return whether the offer is currently considered needed
+     */
+    public boolean neededFor(@NonNull final NetworkRequest request) {
+        return mCurrentlyNeeded.contains(request);
+    }
+
+    /**
+     * Migrate from, and take over, a previous offer.
+     *
+     * When an updated offer is sent from a provider, call this method on the new offer, passing
+     * the old one, to take over the state.
+     *
+     * @param previousOffer the previous offer
+     */
+    public void migrateFrom(@NonNull final NetworkOffer previousOffer) {
+        if (!callback.equals(previousOffer.callback)) {
+            throw new IllegalArgumentException("Can only migrate from a previous version of"
+                    + " the same offer");
+        }
+        mCurrentlyNeeded.clear();
+        mCurrentlyNeeded.addAll(previousOffer.mCurrentlyNeeded);
+    }
+
+    @Override
+    public String toString() {
+        return "NetworkOffer [ Score " + score + " ]";
+    }
+}
diff --git a/services/core/java/com/android/server/connectivity/NetworkRanker.java b/services/core/java/com/android/server/connectivity/NetworkRanker.java
index d0aabf95..0e4dda2 100644
--- a/services/core/java/com/android/server/connectivity/NetworkRanker.java
+++ b/services/core/java/com/android/server/connectivity/NetworkRanker.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.net.NetworkCapabilities;
 import android.net.NetworkRequest;
 
 import java.util.Collection;
@@ -47,4 +48,41 @@
         }
         return bestNetwork;
     }
+
+    /**
+     * Returns whether an offer has a chance to beat a champion network for a request.
+     *
+     * Offers are sent by network providers when they think they might be able to make a network
+     * with the characteristics contained in the offer. If the offer has no chance to beat
+     * the currently best network for a given request, there is no point in the provider spending
+     * power trying to find and bring up such a network.
+     *
+     * Note that having an offer up does not constitute a commitment from the provider part
+     * to be able to bring up a network with these characteristics, or a network at all for
+     * that matter. This is only used to save power by letting providers know when they can't
+     * beat a current champion.
+     *
+     * @param request The request to evaluate against.
+     * @param championScore The currently best network for this request.
+     * @param offer The offer.
+     * @return Whether the offer stands a chance to beat the champion.
+     */
+    public boolean mightBeat(@NonNull final NetworkRequest request,
+            @Nullable final FullScore championScore,
+            @NonNull final NetworkOffer offer) {
+        // If this network can't even satisfy the request then it can't beat anything, not
+        // even an absence of network. It can't satisfy it anyway.
+        if (!request.canBeSatisfiedBy(offer.caps)) return false;
+        // If there is no satisfying network, then this network can beat, because some network
+        // is always better than no network.
+        if (null == championScore) return true;
+        final int offerIntScore;
+        if (offer.caps.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
+            // If the offer might have Internet access, then it might validate.
+            offerIntScore = offer.score.getLegacyIntAsValidated();
+        } else {
+            offerIntScore = offer.score.getLegacyInt();
+        }
+        return championScore.getLegacyInt() < offerIntScore;
+    }
 }
diff --git a/services/core/java/com/android/server/connectivity/OsCompat.java b/services/core/java/com/android/server/connectivity/OsCompat.java
new file mode 100644
index 0000000..57e3dcd
--- /dev/null
+++ b/services/core/java/com/android/server/connectivity/OsCompat.java
@@ -0,0 +1,75 @@
+/*
+ * 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.connectivity;
+
+import android.system.ErrnoException;
+import android.system.Os;
+
+import java.io.FileDescriptor;
+
+/**
+ * Compatibility utility for android.system.Os core platform APIs.
+ *
+ * Connectivity has access to such APIs, but they are not part of the module_current stubs yet
+ * (only core_current). Most stable core platform APIs are included manually in the connectivity
+ * build rules, but because Os is also part of the base java SDK that is earlier on the
+ * classpath, the extra core platform APIs are not seen.
+ *
+ * TODO (b/157639992, b/183097033): remove as soon as core_current is part of system_server_current
+ * @hide
+ */
+public class OsCompat {
+    // This value should be correct on all architectures supported by Android, but hardcoding ioctl
+    // numbers should be avoided.
+    /**
+     * @see android.system.OsConstants#TIOCOUTQ
+     */
+    public static final int TIOCOUTQ = 0x5411;
+
+    /**
+     * @see android.system.Os#getsockoptInt(FileDescriptor, int, int)
+     */
+    public static int getsockoptInt(FileDescriptor fd, int level, int option) throws
+            ErrnoException {
+        try {
+            return (int) Os.class.getMethod(
+                    "getsockoptInt", FileDescriptor.class, int.class, int.class)
+                    .invoke(null, fd, level, option);
+        } catch (ReflectiveOperationException e) {
+            if (e.getCause() instanceof ErrnoException) {
+                throw (ErrnoException) e.getCause();
+            }
+            throw new IllegalStateException("Error calling getsockoptInt", e);
+        }
+    }
+
+    /**
+     * @see android.system.Os#ioctlInt(FileDescriptor, int)
+     */
+    public static int ioctlInt(FileDescriptor fd, int cmd) throws
+            ErrnoException {
+        try {
+            return (int) Os.class.getMethod(
+                    "ioctlInt", FileDescriptor.class, int.class).invoke(null, fd, cmd);
+        } catch (ReflectiveOperationException e) {
+            if (e.getCause() instanceof ErrnoException) {
+                throw (ErrnoException) e.getCause();
+            }
+            throw new IllegalStateException("Error calling ioctlInt", e);
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/connectivity/PermissionMonitor.java b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
index 488677a..3711679 100644
--- a/services/core/java/com/android/server/connectivity/PermissionMonitor.java
+++ b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
@@ -271,6 +271,13 @@
         return mApps.containsKey(uid);
     }
 
+    /**
+     * Returns whether the given uid has permission to use restricted networks.
+     */
+    public synchronized boolean hasRestrictedNetworksPermission(int uid) {
+        return Boolean.TRUE.equals(mApps.get(uid));
+    }
+
     private void update(Set<UserHandle> users, Map<Integer, Boolean> apps, boolean add) {
         List<Integer> network = new ArrayList<>();
         List<Integer> system = new ArrayList<>();
diff --git a/services/core/java/com/android/server/connectivity/QosCallbackAgentConnection.java b/services/core/java/com/android/server/connectivity/QosCallbackAgentConnection.java
index 0f5400d..534dbe7 100644
--- a/services/core/java/com/android/server/connectivity/QosCallbackAgentConnection.java
+++ b/services/core/java/com/android/server/connectivity/QosCallbackAgentConnection.java
@@ -27,6 +27,7 @@
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.telephony.data.EpsBearerQosSessionAttributes;
+import android.telephony.data.NrQosSessionAttributes;
 import android.util.Log;
 
 import java.util.Objects;
@@ -146,13 +147,23 @@
         mNetworkAgentInfo.onQosCallbackUnregistered(mAgentCallbackId);
     }
 
-    void sendEventQosSessionAvailable(final QosSession session,
+    void sendEventEpsQosSessionAvailable(final QosSession session,
             final EpsBearerQosSessionAttributes attributes) {
         try {
-            if (DBG) log("sendEventQosSessionAvailable: sending...");
+            if (DBG) log("sendEventEpsQosSessionAvailable: sending...");
             mCallback.onQosEpsBearerSessionAvailable(session, attributes);
         } catch (final RemoteException e) {
-            loge("sendEventQosSessionAvailable: remote exception", e);
+            loge("sendEventEpsQosSessionAvailable: remote exception", e);
+        }
+    }
+
+    void sendEventNrQosSessionAvailable(final QosSession session,
+            final NrQosSessionAttributes attributes) {
+        try {
+            if (DBG) log("sendEventNrQosSessionAvailable: sending...");
+            mCallback.onNrQosSessionAvailable(session, attributes);
+        } catch (final RemoteException e) {
+            loge("sendEventNrQosSessionAvailable: remote exception", e);
         }
     }
 
diff --git a/services/core/java/com/android/server/connectivity/QosCallbackTracker.java b/services/core/java/com/android/server/connectivity/QosCallbackTracker.java
index 8bda532..b6ab47b 100644
--- a/services/core/java/com/android/server/connectivity/QosCallbackTracker.java
+++ b/services/core/java/com/android/server/connectivity/QosCallbackTracker.java
@@ -27,6 +27,7 @@
 import android.os.Handler;
 import android.os.IBinder;
 import android.telephony.data.EpsBearerQosSessionAttributes;
+import android.telephony.data.NrQosSessionAttributes;
 import android.util.Log;
 
 import com.android.net.module.util.CollectionUtils;
@@ -179,17 +180,31 @@
     }
 
     /**
-     * Called when the NetworkAgent sends the qos session available event
+     * Called when the NetworkAgent sends the qos session available event for EPS
      *
      * @param qosCallbackId the callback id that the qos session is now available to
      * @param session the qos session that is now available
      * @param attributes the qos attributes that are now available on the qos session
      */
-    public void sendEventQosSessionAvailable(final int qosCallbackId,
+    public void sendEventEpsQosSessionAvailable(final int qosCallbackId,
             final QosSession session,
             final EpsBearerQosSessionAttributes attributes) {
-        runOnAgentConnection(qosCallbackId, "sendEventQosSessionAvailable: ",
-                ac -> ac.sendEventQosSessionAvailable(session, attributes));
+        runOnAgentConnection(qosCallbackId, "sendEventEpsQosSessionAvailable: ",
+                ac -> ac.sendEventEpsQosSessionAvailable(session, attributes));
+    }
+
+    /**
+     * Called when the NetworkAgent sends the qos session available event for NR
+     *
+     * @param qosCallbackId the callback id that the qos session is now available to
+     * @param session the qos session that is now available
+     * @param attributes the qos attributes that are now available on the qos session
+     */
+    public void sendEventNrQosSessionAvailable(final int qosCallbackId,
+            final QosSession session,
+            final NrQosSessionAttributes attributes) {
+        runOnAgentConnection(qosCallbackId, "sendEventNrQosSessionAvailable: ",
+                ac -> ac.sendEventNrQosSessionAvailable(session, attributes));
     }
 
     /**
diff --git a/services/core/java/com/android/server/connectivity/TcpKeepaliveController.java b/services/core/java/com/android/server/connectivity/TcpKeepaliveController.java
index c480594..73f3475 100644
--- a/services/core/java/com/android/server/connectivity/TcpKeepaliveController.java
+++ b/services/core/java/com/android/server/connectivity/TcpKeepaliveController.java
@@ -27,7 +27,8 @@
 import static android.system.OsConstants.IPPROTO_TCP;
 import static android.system.OsConstants.IP_TOS;
 import static android.system.OsConstants.IP_TTL;
-import static android.system.OsConstants.TIOCOUTQ;
+
+import static com.android.server.connectivity.OsCompat.TIOCOUTQ;
 
 import android.annotation.NonNull;
 import android.net.InvalidPacketException;
@@ -175,10 +176,10 @@
             }
             // Query write sequence number from SEND_QUEUE.
             Os.setsockoptInt(fd, IPPROTO_TCP, TCP_REPAIR_QUEUE, TCP_SEND_QUEUE);
-            tcpDetails.seq = Os.getsockoptInt(fd, IPPROTO_TCP, TCP_QUEUE_SEQ);
+            tcpDetails.seq = OsCompat.getsockoptInt(fd, IPPROTO_TCP, TCP_QUEUE_SEQ);
             // Query read sequence number from RECV_QUEUE.
             Os.setsockoptInt(fd, IPPROTO_TCP, TCP_REPAIR_QUEUE, TCP_RECV_QUEUE);
-            tcpDetails.ack = Os.getsockoptInt(fd, IPPROTO_TCP, TCP_QUEUE_SEQ);
+            tcpDetails.ack = OsCompat.getsockoptInt(fd, IPPROTO_TCP, TCP_QUEUE_SEQ);
             // Switch to NO_QUEUE to prevent illegal socket read/write in repair mode.
             Os.setsockoptInt(fd, IPPROTO_TCP, TCP_REPAIR_QUEUE, TCP_NO_QUEUE);
             // Finally, check if socket is still idle. TODO : this check needs to move to
@@ -198,9 +199,9 @@
             tcpDetails.rcvWndScale = trw.rcvWndScale;
             if (tcpDetails.srcAddress.length == 4 /* V4 address length */) {
                 // Query TOS.
-                tcpDetails.tos = Os.getsockoptInt(fd, IPPROTO_IP, IP_TOS);
+                tcpDetails.tos = OsCompat.getsockoptInt(fd, IPPROTO_IP, IP_TOS);
                 // Query TTL.
-                tcpDetails.ttl = Os.getsockoptInt(fd, IPPROTO_IP, IP_TTL);
+                tcpDetails.ttl = OsCompat.getsockoptInt(fd, IPPROTO_IP, IP_TTL);
             }
         } catch (ErrnoException e) {
             Log.e(TAG, "Exception reading TCP state from socket", e);
@@ -305,7 +306,7 @@
 
     private static boolean isReceiveQueueEmpty(FileDescriptor fd)
             throws ErrnoException {
-        final int result = Os.ioctlInt(fd, SIOCINQ);
+        final int result = OsCompat.ioctlInt(fd, SIOCINQ);
         if (result != 0) {
             Log.e(TAG, "Read queue has data");
             return false;
@@ -315,7 +316,7 @@
 
     private static boolean isSendQueueEmpty(FileDescriptor fd)
             throws ErrnoException {
-        final int result = Os.ioctlInt(fd, SIOCOUTQ);
+        final int result = OsCompat.ioctlInt(fd, SIOCOUTQ);
         if (result != 0) {
             Log.e(TAG, "Write queue has data");
             return false;
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index a4df43c..820198c 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -17,7 +17,6 @@
 package com.android.server.connectivity;
 
 import static android.Manifest.permission.BIND_VPN_SERVICE;
-import static android.net.ConnectivityManager.NETID_UNSET;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
 import static android.net.RouteInfo.RTN_THROW;
 import static android.net.RouteInfo.RTN_UNREACHABLE;
@@ -465,7 +464,7 @@
                 .addTransportType(NetworkCapabilities.TRANSPORT_VPN)
                 .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
-                .setTransportInfo(new VpnTransportInfo(VpnManager.TYPE_VPN_NONE))
+                .setTransportInfo(new VpnTransportInfo(VpnManager.TYPE_VPN_NONE, null))
                 .build();
 
         loadAlwaysOnPackage();
@@ -529,7 +528,7 @@
     private void resetNetworkCapabilities() {
         mNetworkCapabilities = new NetworkCapabilities.Builder(mNetworkCapabilities)
                 .setUids(null)
-                .setTransportInfo(new VpnTransportInfo(VpnManager.TYPE_VPN_NONE))
+                .setTransportInfo(new VpnTransportInfo(VpnManager.TYPE_VPN_NONE, null))
                 .build();
     }
 
@@ -1129,17 +1128,19 @@
     }
 
     /**
-     * Return netId of current running VPN network.
+     * Return Network of current running VPN network.
      *
-     * @return a netId if there is a running VPN network or NETID_UNSET if there is no running VPN
+     * @return a Network if there is a running VPN network or null if there is no running VPN
      *         network or network is null.
      */
-    public synchronized int getNetId() {
+    @VisibleForTesting
+    @Nullable
+    public synchronized Network getNetwork() {
         final NetworkAgent agent = mNetworkAgent;
-        if (null == agent) return NETID_UNSET;
+        if (null == agent) return null;
         final Network network = agent.getNetwork();
-        if (null == network) return NETID_UNSET;
-        return network.getNetId();
+        if (null == network) return null;
+        return network;
     }
 
     private LinkProperties makeLinkProperties() {
@@ -1249,15 +1250,16 @@
         mLegacyState = LegacyVpnInfo.STATE_CONNECTING;
         updateState(DetailedState.CONNECTING, "agentConnect");
 
-        NetworkAgentConfig networkAgentConfig = new NetworkAgentConfig.Builder().build();
-        networkAgentConfig.allowBypass = mConfig.allowBypass && !mLockdown;
+        final NetworkAgentConfig networkAgentConfig = new NetworkAgentConfig.Builder()
+                .setBypassableVpn(mConfig.allowBypass && !mLockdown)
+                .build();
 
         capsBuilder.setOwnerUid(mOwnerUID);
         capsBuilder.setAdministratorUids(new int[] {mOwnerUID});
         capsBuilder.setUids(createUserAndRestrictedProfilesRanges(mUserId,
                 mConfig.allowedApplications, mConfig.disallowedApplications));
 
-        capsBuilder.setTransportInfo(new VpnTransportInfo(getActiveVpnType()));
+        capsBuilder.setTransportInfo(new VpnTransportInfo(getActiveVpnType(), mConfig.session));
 
         // Only apps targeting Q and above can explicitly declare themselves as metered.
         // These VPNs are assumed metered unless they state otherwise.
@@ -1288,7 +1290,6 @@
         });
         mNetworkAgent.setUnderlyingNetworks((mConfig.underlyingNetworks != null)
                 ? Arrays.asList(mConfig.underlyingNetworks) : null);
-        mNetworkInfo.setIsAvailable(true);
         updateState(DetailedState.CONNECTED, "agentConnect");
     }
 
@@ -1860,22 +1861,13 @@
     /**
      * Updates underlying network set.
      */
-    public synchronized boolean setUnderlyingNetworks(Network[] networks) {
+    public synchronized boolean setUnderlyingNetworks(@Nullable Network[] networks) {
         if (!isCallerEstablishedOwnerLocked()) {
             return false;
         }
-        if (networks == null) {
-            mConfig.underlyingNetworks = null;
-        } else {
-            mConfig.underlyingNetworks = new Network[networks.length];
-            for (int i = 0; i < networks.length; ++i) {
-                if (networks[i] == null) {
-                    mConfig.underlyingNetworks[i] = null;
-                } else {
-                    mConfig.underlyingNetworks[i] = new Network(networks[i].getNetId());
-                }
-            }
-        }
+        // Make defensive copy since the content of array might be altered by the caller.
+        mConfig.underlyingNetworks =
+                (networks != null) ? Arrays.copyOf(networks, networks.length) : null;
         mNetworkAgent.setUnderlyingNetworks((mConfig.underlyingNetworks != null)
                 ? Arrays.asList(mConfig.underlyingNetworks) : null);
         return true;
diff --git a/services/core/java/com/android/server/content/SyncJobService.java b/services/core/java/com/android/server/content/SyncJobService.java
index aaf9cbc..1f46061 100644
--- a/services/core/java/com/android/server/content/SyncJobService.java
+++ b/services/core/java/com/android/server/content/SyncJobService.java
@@ -119,7 +119,7 @@
     public boolean onStopJob(JobParameters params) {
         if (Log.isLoggable(TAG, Log.VERBOSE)) {
             Slog.v(TAG, "onStopJob called " + params.getJobId() + ", reason: "
-                    + params.getStopReason());
+                    + params.getLegacyStopReason());
         }
         final SyncOperation op = SyncOperation.maybeCreateFromJobExtras(params.getExtras());
         if (op == null) {
@@ -161,9 +161,9 @@
         m.obj = op;
 
         // Reschedule if this job was NOT explicitly canceled.
-        m.arg1 = params.getStopReason() != JobParameters.REASON_CANCELED ? 1 : 0;
+        m.arg1 = params.getLegacyStopReason() != JobParameters.REASON_CANCELED ? 1 : 0;
         // Apply backoff only if stop is called due to timeout.
-        m.arg2 = params.getStopReason() == JobParameters.REASON_TIMEOUT ? 1 : 0;
+        m.arg2 = params.getLegacyStopReason() == JobParameters.REASON_TIMEOUT ? 1 : 0;
 
         SyncManager.sendMessage(m);
         return false;
@@ -204,7 +204,8 @@
             return "job:null";
         } else {
             return "job:#" + params.getJobId() + ":"
-                    + "sr=[" + params.getStopReason() + "/" + params.getDebugStopReason() + "]:"
+                    + "sr=[" + params.getLegacyStopReason()
+                    + "/" + params.getDebugStopReason() + "]:"
                     + SyncOperation.maybeCreateFromJobExtras(params.getExtras());
         }
     }
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index ac7e01e..1786a51 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -3978,6 +3978,9 @@
      * @return true if the provided key is used by the SyncManager in scheduling the sync.
      */
     private static boolean isSyncSetting(String key) {
+        if (key == null) {
+            return false;
+        }
         if (key.equals(ContentResolver.SYNC_EXTRAS_EXPEDITED)) {
             return true;
         }
diff --git a/services/core/java/com/android/server/display/BrightnessSetting.java b/services/core/java/com/android/server/display/BrightnessSetting.java
new file mode 100644
index 0000000..8ce7b66
--- /dev/null
+++ b/services/core/java/com/android/server/display/BrightnessSetting.java
@@ -0,0 +1,173 @@
+/*
+ * 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.display;
+
+import android.annotation.NonNull;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.PowerManager;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.util.Slog;
+import android.view.Display;
+
+import java.util.concurrent.CopyOnWriteArrayList;
+
+/**
+ * Saves brightness to a persistent data store, enabling each logical display to have its own
+ * brightness.
+ */
+public class BrightnessSetting {
+    private static final String TAG = "BrightnessSetting";
+
+    private static final int MSG_BRIGHTNESS_CHANGED = 1;
+    private static final Uri BRIGHTNESS_FLOAT_URI =
+            Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_FLOAT);
+    private final PersistentDataStore mPersistentDataStore;
+
+    private final boolean mIsDefaultDisplay;
+    private final Context mContext;
+    private final LogicalDisplay mLogicalDisplay;
+    private final Object mLock = new Object();
+
+    private final Handler mHandler = new Handler(Looper.getMainLooper()) {
+        @Override
+        public void handleMessage(Message msg) {
+            if (msg.what == MSG_BRIGHTNESS_CHANGED) {
+                float brightnessVal = Float.intBitsToFloat(msg.arg1);
+                notifyListeners(brightnessVal);
+            }
+        }
+    };
+
+    private final ContentObserver mBrightnessSettingsObserver = new ContentObserver(mHandler) {
+        @Override
+        public void onChange(boolean selfChange, Uri uri) {
+            if (selfChange) {
+                return;
+            }
+            if (BRIGHTNESS_FLOAT_URI.equals(uri)) {
+                float brightness = getScreenBrightnessSettingFloat();
+                setBrightness(brightness, true);
+            }
+        }
+    };
+
+    private final CopyOnWriteArrayList<BrightnessSettingListener> mListeners =
+            new CopyOnWriteArrayList<BrightnessSettingListener>();
+
+    private float mBrightness;
+
+    BrightnessSetting(@NonNull PersistentDataStore persistentDataStore,
+            @NonNull LogicalDisplay logicalDisplay,
+            @NonNull Context context) {
+        mPersistentDataStore = persistentDataStore;
+        mLogicalDisplay = logicalDisplay;
+        mContext = context;
+        mIsDefaultDisplay = mLogicalDisplay.getDisplayIdLocked() == Display.DEFAULT_DISPLAY;
+        mBrightness = mPersistentDataStore.getBrightness(
+                mLogicalDisplay.getPrimaryDisplayDeviceLocked());
+        if (mIsDefaultDisplay) {
+            mContext.getContentResolver().registerContentObserver(BRIGHTNESS_FLOAT_URI,
+                    false, mBrightnessSettingsObserver);
+        }
+    }
+
+    /**
+     * Returns the brightness from the brightness setting
+     *
+     * @return brightness for the current display
+     */
+    public float getBrightness() {
+        return mBrightness;
+    }
+
+    /**
+     * Registers listener for brightness setting change events.
+     */
+    public void registerListener(BrightnessSettingListener l) {
+        if (!mListeners.contains(l)) {
+            mListeners.add(l);
+        }
+    }
+
+    /**
+     * Unregisters listener for brightness setting change events.
+     *
+     * @param l listener
+     */
+    public void unregisterListener(BrightnessSettingListener l) {
+        mListeners.remove(l);
+    }
+
+    void setBrightness(float brightness) {
+        setBrightness(brightness, false);
+    }
+
+    private void setBrightness(float brightness, boolean isFromSystemSetting) {
+        if (brightness == mBrightness) {
+            return;
+        }
+        if (Float.isNaN(brightness)) {
+            Slog.w(TAG, "Attempting to set invalid brightness");
+            return;
+        }
+        synchronized (mLock) {
+
+            mBrightness = brightness;
+
+            // If it didn't come from us
+            if (mIsDefaultDisplay && !isFromSystemSetting) {
+                Settings.System.putFloatForUser(mContext.getContentResolver(),
+                        Settings.System.SCREEN_BRIGHTNESS_FLOAT, brightness,
+                        UserHandle.USER_CURRENT);
+            }
+            mPersistentDataStore.setBrightness(mLogicalDisplay.getPrimaryDisplayDeviceLocked(),
+                    brightness);
+            int toSend = Float.floatToIntBits(mBrightness);
+            Message msg = mHandler.obtainMessage(MSG_BRIGHTNESS_CHANGED, toSend, 0);
+            mHandler.sendMessage(msg);
+        }
+    }
+
+    private float getScreenBrightnessSettingFloat() {
+        return Settings.System.getFloatForUser(mContext.getContentResolver(),
+                Settings.System.SCREEN_BRIGHTNESS_FLOAT, PowerManager.BRIGHTNESS_INVALID_FLOAT,
+                UserHandle.USER_CURRENT);
+    }
+
+    private void notifyListeners(float brightness) {
+        for (BrightnessSettingListener l : mListeners) {
+            l.onBrightnessChanged(brightness);
+        }
+    }
+
+    /**
+     * Listener for changes to system brightness.
+     */
+    public interface BrightnessSettingListener {
+
+        /**
+         * Notify that the brightness has changed.
+         */
+        void onBrightnessChanged(float brightness);
+    }
+}
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index c010906..393a4eb 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -203,6 +203,8 @@
     private WindowManagerInternal mWindowManagerInternal;
     private InputManagerInternal mInputManagerInternal;
     private IMediaProjectionManager mProjectionService;
+    private int[] mUserDisabledHdrTypes = {};
+    private boolean mAreUserDisabledHdrTypesAllowed = true;
 
     // The synchronization root for the display manager.
     // This lock guards most of the display manager's state.
@@ -557,6 +559,8 @@
             recordTopInsetLocked(mLogicalDisplayMapper.getDisplayLocked(Display.DEFAULT_DISPLAY));
 
             updateSettingsLocked();
+
+            updateUserDisabledHdrTypesFromSettingsLocked();
         }
 
         mDisplayModeDirector.setDesiredDisplayModeSpecsListener(
@@ -566,6 +570,7 @@
         mHandler.sendEmptyMessage(MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS);
 
         mSettingsObserver = new SettingsObserver();
+
         mBrightnessSynchronizer.startSynchronizing();
     }
 
@@ -737,6 +742,42 @@
                 Settings.Secure.MINIMAL_POST_PROCESSING_ALLOWED, 1, UserHandle.USER_CURRENT) != 0;
     }
 
+    private void updateUserDisabledHdrTypesFromSettingsLocked() {
+        mAreUserDisabledHdrTypesAllowed = (Settings.Global.getInt(
+                mContext.getContentResolver(),
+                Settings.Global.ARE_USER_DISABLED_HDR_FORMATS_ALLOWED,
+                1) != 0);
+
+        String userDisabledHdrTypes = Settings.Global.getString(mContext.getContentResolver(),
+                Settings.Global.USER_DISABLED_HDR_FORMATS);
+
+        if (userDisabledHdrTypes != null) {
+            try {
+                String[] userDisabledHdrTypeStrings =
+                        TextUtils.split(userDisabledHdrTypes, ",");
+                mUserDisabledHdrTypes = new int[userDisabledHdrTypeStrings.length];
+                for (int i = 0; i < userDisabledHdrTypeStrings.length; i++) {
+                    mUserDisabledHdrTypes[i] = Integer.parseInt(userDisabledHdrTypeStrings[i]);
+                }
+            } catch (NumberFormatException e) {
+                Slog.e(TAG,
+                        "Failed to parse USER_DISABLED_HDR_FORMATS. "
+                                + "Clearing the setting.", e);
+                clearUserDisabledHdrTypesLocked();
+            }
+        } else {
+            clearUserDisabledHdrTypesLocked();
+        }
+    }
+
+    private void clearUserDisabledHdrTypesLocked() {
+        mUserDisabledHdrTypes = new int[]{};
+        synchronized (mSyncRoot) {
+            Settings.Global.putString(mContext.getContentResolver(),
+                    Settings.Global.USER_DISABLED_HDR_FORMATS, "");
+        }
+    }
+
     private DisplayInfo getDisplayInfoForFrameRateOverride(DisplayEventReceiver.FrameRateOverride[]
             frameRateOverrides, DisplayInfo info, int callingUid) {
         float frameRateHz = 0;
@@ -957,6 +998,61 @@
         }
     }
 
+    private void setUserDisabledHdrTypesInternal(int[] userDisabledHdrTypes) {
+        synchronized (mSyncRoot) {
+            if (userDisabledHdrTypes == null) {
+                Slog.e(TAG, "Null is not an expected argument to "
+                        + "setUserDisabledHdrTypesInternal");
+                return;
+            }
+            Arrays.sort(userDisabledHdrTypes);
+            if (Arrays.equals(mUserDisabledHdrTypes, userDisabledHdrTypes)) {
+                return;
+            }
+            String userDisabledFormatsString = "";
+            if (userDisabledHdrTypes.length != 0) {
+                userDisabledFormatsString = TextUtils.join(",",
+                        Arrays.stream(userDisabledHdrTypes).boxed().toArray());
+            }
+            Settings.Global.putString(mContext.getContentResolver(),
+                    Settings.Global.USER_DISABLED_HDR_FORMATS, userDisabledFormatsString);
+            mUserDisabledHdrTypes = userDisabledHdrTypes;
+            if (!mAreUserDisabledHdrTypesAllowed) {
+                mLogicalDisplayMapper.forEachLocked(
+                        display -> {
+                            display.setUserDisabledHdrTypes(userDisabledHdrTypes);
+                            handleLogicalDisplayChangedLocked(display);
+                        });
+            }
+        }
+    }
+
+    private void setAreUserDisabledHdrTypesAllowedInternal(
+            boolean areUserDisabledHdrTypesAllowed) {
+        synchronized (mSyncRoot) {
+            if (mAreUserDisabledHdrTypesAllowed == areUserDisabledHdrTypesAllowed) {
+                return;
+            }
+            mAreUserDisabledHdrTypesAllowed = areUserDisabledHdrTypesAllowed;
+            if (mUserDisabledHdrTypes.length == 0) {
+                return;
+            }
+            Settings.Global.putInt(mContext.getContentResolver(),
+                    Settings.Global.ARE_USER_DISABLED_HDR_FORMATS_ALLOWED,
+                    areUserDisabledHdrTypesAllowed ? 1 : 0);
+            int userDisabledHdrTypes[] = {};
+            if (!mAreUserDisabledHdrTypesAllowed) {
+                userDisabledHdrTypes = mUserDisabledHdrTypes;
+            }
+            int[] finalUserDisabledHdrTypes = userDisabledHdrTypes;
+            mLogicalDisplayMapper.forEachLocked(
+                    display -> {
+                        display.setUserDisabledHdrTypes(finalUserDisabledHdrTypes);
+                        handleLogicalDisplayChangedLocked(display);
+                    });
+        }
+    }
+
     private void requestColorModeInternal(int displayId, int colorMode) {
         synchronized (mSyncRoot) {
             final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId);
@@ -1130,17 +1226,16 @@
         final int displayId = display.getDisplayIdLocked();
         final boolean isDefault = displayId == Display.DEFAULT_DISPLAY;
         configureColorModeLocked(display, device);
+        if (!mAreUserDisabledHdrTypesAllowed) {
+            display.setUserDisabledHdrTypes(mUserDisabledHdrTypes);
+        }
         if (isDefault) {
             recordStableDisplayStatsIfNeededLocked(display);
             recordTopInsetLocked(display);
         }
-        final int groupId = mLogicalDisplayMapper.getDisplayGroupIdFromDisplayIdLocked(displayId);
-        if (groupId != Display.INVALID_DISPLAY_GROUP) {
-            addDisplayPowerControllerLocked(display);
-            mDisplayStates.append(displayId, Display.STATE_UNKNOWN);
-        } else {
-            mDisplayStates.append(displayId, Display.STATE_ON);
-        }
+        addDisplayPowerControllerLocked(display);
+        mDisplayStates.append(displayId, Display.STATE_UNKNOWN);
+
         mDisplayBrightnesses.append(displayId, display.getDisplayInfoLocked().brightnessDefault);
 
         DisplayManagerGlobal.invalidateLocalDisplayInfoCaches();
@@ -1814,6 +1909,14 @@
             pw.println("  mMinimumBrightnessCurve=" + mMinimumBrightnessCurve);
 
             pw.println();
+            if (!mAreUserDisabledHdrTypesAllowed) {
+                pw.println("  mUserDisabledHdrTypes: size=" + mUserDisabledHdrTypes.length);
+                for (int type : mUserDisabledHdrTypes) {
+                    pw.println("  " + type);
+                }
+            }
+
+            pw.println();
             final int displayStateCount = mDisplayStates.size();
             pw.println("Display States: size=" + displayStateCount);
             for (int i = 0; i < displayStateCount; i++) {
@@ -1943,8 +2046,7 @@
     }
 
     private void initializeDisplayPowerControllersLocked() {
-        mLogicalDisplayMapper.forEachLocked((logicalDisplay) -> addDisplayPowerControllerLocked(
-                logicalDisplay));
+        mLogicalDisplayMapper.forEachLocked(this::addDisplayPowerControllerLocked);
     }
 
     private void addDisplayPowerControllerLocked(LogicalDisplay display) {
@@ -1955,9 +2057,12 @@
         if (mBrightnessTracker == null) {
             mBrightnessTracker = new BrightnessTracker(mContext, null);
         }
+
+        final BrightnessSetting brightnessSetting = new BrightnessSetting(mPersistentDataStore,
+                display, mContext);
         final DisplayPowerController displayPowerController = new DisplayPowerController(
                 mContext, mDisplayPowerCallbacks, mPowerHandler, mSensorManager,
-                mDisplayBlanker, display, mBrightnessTracker);
+                mDisplayBlanker, display, mBrightnessTracker, brightnessSetting);
         mDisplayPowerControllers.append(display.getDisplayIdLocked(), displayPowerController);
     }
 
@@ -2339,6 +2444,45 @@
         }
 
         @Override // Binder call
+        public void setUserDisabledHdrTypes(int[] userDisabledFormats) {
+            mContext.enforceCallingOrSelfPermission(
+                    Manifest.permission.WRITE_SECURE_SETTINGS,
+                    "Permission required to write the user settings.");
+
+            final long token = Binder.clearCallingIdentity();
+            try {
+                setUserDisabledHdrTypesInternal(userDisabledFormats);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        @Override // Binder call
+        public void setAreUserDisabledHdrTypesAllowed(boolean areUserDisabledHdrTypesAllowed) {
+            mContext.enforceCallingOrSelfPermission(
+                    Manifest.permission.WRITE_SECURE_SETTINGS,
+                    "Permission required to write the user settings.");
+            final long token = Binder.clearCallingIdentity();
+            try {
+                setAreUserDisabledHdrTypesAllowedInternal(areUserDisabledHdrTypesAllowed);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        @Override // Binder call
+        public boolean areUserDisabledHdrTypesAllowed() {
+            synchronized (mSyncRoot) {
+                return mAreUserDisabledHdrTypesAllowed;
+            }
+        }
+
+        @Override // Binder call
+        public int[] getUserDisabledHdrTypes() {
+            return mUserDisabledHdrTypes;
+        }
+
+        @Override // Binder call
         public void requestColorMode(int displayId, int colorMode) {
             mContext.enforceCallingOrSelfPermission(
                     Manifest.permission.CONFIGURE_DISPLAY_COLOR_MODE,
@@ -2662,6 +2806,48 @@
         }
 
         @Override // Binder call
+        public void setBrightness(int displayId, float brightness) {
+            mContext.enforceCallingOrSelfPermission(
+                    Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS,
+                    "Permission required to set the display's brightness");
+            if (!isValidBrightness(brightness)) {
+                Slog.w(TAG, "Attempted to set invalid brightness" + brightness);
+                return;
+            }
+            final long token = Binder.clearCallingIdentity();
+            try {
+                synchronized (mSyncRoot) {
+                    DisplayPowerController dpc = mDisplayPowerControllers.get(displayId);
+                    if (dpc != null) {
+                        dpc.putScreenBrightnessSetting(brightness);
+                    }
+                }
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        @Override // Binder call
+        public float getBrightness(int displayId) {
+            float brightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
+            mContext.enforceCallingOrSelfPermission(
+                    Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS,
+                    "Permission required to set the display's brightness");
+            final long token = Binder.clearCallingIdentity();
+            try {
+                synchronized (mSyncRoot) {
+                    DisplayPowerController dpc = mDisplayPowerControllers.get(displayId);
+                    if (dpc != null) {
+                        brightness = dpc.getScreenBrightnessSetting();
+                    }
+                }
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+            return brightness;
+        }
+
+        @Override // Binder call
         public void setTemporaryAutoBrightnessAdjustment(float adjustment) {
             mContext.enforceCallingOrSelfPermission(
                     Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS,
@@ -2746,9 +2932,6 @@
 
         @Override // Binder call
         public int getRefreshRateSwitchingType() {
-            mContext.enforceCallingOrSelfPermission(
-                    Manifest.permission.MODIFY_REFRESH_RATE_SWITCHING_TYPE,
-                    "Permission required read refresh rate switching type.");
             final long token = Binder.clearCallingIdentity();
             try {
                 return getRefreshRateSwitchingTypeInternal();
@@ -2809,6 +2992,13 @@
             Slog.w(TAG, msg);
             return false;
         }
+
+    }
+
+    private static boolean isValidBrightness(float brightness) {
+        return !Float.isNaN(brightness)
+                && (brightness >= PowerManager.BRIGHTNESS_MIN)
+                && (brightness <= PowerManager.BRIGHTNESS_MAX);
     }
 
     private final class LocalService extends DisplayManagerInternal {
@@ -2839,10 +3029,16 @@
                 final int size = displayGroup.getSizeLocked();
                 boolean ready = true;
                 for (int i = 0; i < size; i++) {
-                    final DisplayPowerController displayPowerController =
-                            mDisplayPowerControllers.get(displayGroup.getIdLocked(i));
-                    ready &= displayPowerController.requestPowerState(request,
-                            waitForNegativeProximity);
+                    final int id = displayGroup.getIdLocked(i);
+                    final DisplayDevice displayDevice = mLogicalDisplayMapper.getDisplayLocked(
+                            id).getPrimaryDisplayDeviceLocked();
+                    final int flags = displayDevice.getDisplayDeviceInfoLocked().flags;
+                    if ((flags & DisplayDeviceInfo.FLAG_NEVER_BLANK) == 0) {
+                        final DisplayPowerController displayPowerController =
+                                mDisplayPowerControllers.get(id);
+                        ready &= displayPowerController.requestPowerState(request,
+                                waitForNegativeProximity);
+                    }
                 }
 
                 return ready;
diff --git a/services/core/java/com/android/server/display/DisplayManagerShellCommand.java b/services/core/java/com/android/server/display/DisplayManagerShellCommand.java
index d1d0496..48edb73 100644
--- a/services/core/java/com/android/server/display/DisplayManagerShellCommand.java
+++ b/services/core/java/com/android/server/display/DisplayManagerShellCommand.java
@@ -16,13 +16,11 @@
 
 package com.android.server.display;
 
-import android.Manifest;
 import android.content.Context;
 import android.content.Intent;
-import android.os.Binder;
+import android.hardware.display.DisplayManager;
 import android.os.ShellCommand;
-import android.os.UserHandle;
-import android.provider.Settings;
+import android.view.Display;
 
 import java.io.PrintWriter;
 
@@ -111,17 +109,8 @@
         }
 
         final Context context = mService.getContext();
-        context.enforceCallingOrSelfPermission(
-                Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS,
-                "Permission required to set the display's brightness");
-        final long token = Binder.clearCallingIdentity();
-        try {
-            Settings.System.putFloatForUser(context.getContentResolver(),
-                    Settings.System.SCREEN_BRIGHTNESS_FLOAT, brightness,
-                    UserHandle.USER_CURRENT);
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
+        final DisplayManager dm = context.getSystemService(DisplayManager.class);
+        dm.setBrightness(Display.DEFAULT_DISPLAY, brightness);
         return 0;
     }
 
diff --git a/services/core/java/com/android/server/display/DisplayModeDirector.java b/services/core/java/com/android/server/display/DisplayModeDirector.java
index 645ca7a..4bbd338 100644
--- a/services/core/java/com/android/server/display/DisplayModeDirector.java
+++ b/services/core/java/com/android/server/display/DisplayModeDirector.java
@@ -263,6 +263,8 @@
                 highestConsideredPriority = Vote.PRIORITY_APP_REQUEST_SIZE;
             }
 
+            // We try to find a range of priorities which define a non-empty set of allowed display
+            // modes. Each time we fail we increase the lowest priority.
             while (lowestConsideredPriority <= highestConsideredPriority) {
                 summarizeVotes(
                         votes, lowestConsideredPriority, highestConsideredPriority, primarySummary);
@@ -343,8 +345,15 @@
             }
 
             if (baseModeId == INVALID_DISPLAY_MODE_ID) {
-                throw new IllegalStateException("Can't select a base display mode for display "
-                        + displayId + ". The votes are " + mVotesByDisplay.valueAt(displayId));
+                Slog.w(TAG, "Can't find a set of allowed modes which satisfies the votes. Falling"
+                        + " back to the default mode. Display = " + displayId + ", votes = " + votes
+                        + ", supported modes = " + Arrays.toString(modes));
+
+                float fps = defaultMode.getRefreshRate();
+                return new DesiredDisplayModeSpecs(defaultMode.getModeId(),
+                        /*allowGroupSwitching */ false,
+                        new RefreshRateRange(fps, fps),
+                        new RefreshRateRange(fps, fps));
             }
 
             if (mModeSwitchingType == DisplayManager.SWITCHING_TYPE_NONE) {
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 7110d3e..cb8541e 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -122,6 +122,7 @@
     private static final int MSG_SET_TEMPORARY_AUTO_BRIGHTNESS_ADJUSTMENT = 7;
     private static final int MSG_IGNORE_PROXIMITY = 8;
     private static final int MSG_STOP = 9;
+    private static final int MSG_UPDATE_BRIGHTNESS = 10;
 
     private static final int PROXIMITY_UNKNOWN = -1;
     private static final int PROXIMITY_NEGATIVE = 0;
@@ -355,13 +356,14 @@
 
     private final HighBrightnessModeController mHbmController;
 
+    private final BrightnessSetting mBrightnessSetting;
+
     // A record of state for skipping brightness ramps.
     private int mSkipRampState = RAMP_STATE_SKIP_NONE;
 
     // The first autobrightness value set when entering RAMP_STATE_SKIP_INITIAL.
     private float mInitialAutoBrightness;
 
-
     // The controller for the automatic brightness level.
     private AutomaticBrightnessController mAutomaticBrightnessController;
 
@@ -410,6 +412,7 @@
     private ObjectAnimator mColorFadeOnAnimator;
     private ObjectAnimator mColorFadeOffAnimator;
     private RampAnimator<DisplayPowerState> mScreenBrightnessRampAnimator;
+    private BrightnessSetting.BrightnessSettingListener mBrightnessSettingListener;
 
     // True if this DisplayPowerController has been stopped and should no longer be running.
     private boolean mStopped;
@@ -420,7 +423,7 @@
     public DisplayPowerController(Context context,
             DisplayPowerCallbacks callbacks, Handler handler,
             SensorManager sensorManager, DisplayBlanker blanker, LogicalDisplay logicalDisplay,
-            BrightnessTracker brightnessTracker) {
+            BrightnessTracker brightnessTracker, BrightnessSetting brightnessSetting) {
         mLogicalDisplay = logicalDisplay;
         mDisplayId = mLogicalDisplay.getDisplayIdLocked();
         mHandler = new DisplayControllerHandler(handler.getLooper());
@@ -439,7 +442,7 @@
         mContext = context;
         mBrightnessTracker = brightnessTracker;
 
-
+        mBrightnessSetting = brightnessSetting;
         PowerManager pm = context.getSystemService(PowerManager.class);
 
         final Resources resources = context.getResources();
@@ -785,6 +788,10 @@
                 mAutomaticBrightnessController.stop();
             }
 
+            if (mBrightnessSetting != null) {
+                mBrightnessSetting.unregisterListener(mBrightnessSettingListener);
+            }
+
             mContext.getContentResolver().unregisterContentObserver(mSettingsObserver);
         }
     }
@@ -831,10 +838,12 @@
         if (brightness >= PowerManager.BRIGHTNESS_MIN) {
             mBrightnessTracker.start(brightness);
         }
+        mBrightnessSettingListener = brightnessValue -> {
+            Message msg = mHandler.obtainMessage(MSG_UPDATE_BRIGHTNESS, brightnessValue);
+            mHandler.sendMessage(msg);
+        };
 
-        mContext.getContentResolver().registerContentObserver(
-                Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_FLOAT),
-                false /*notifyForDescendants*/, mSettingsObserver, UserHandle.USER_ALL);
+        mBrightnessSetting.registerListener(mBrightnessSettingListener);
         mContext.getContentResolver().registerContentObserver(
                 Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_FOR_VR_FLOAT),
                 false /*notifyForDescendants*/, mSettingsObserver, UserHandle.USER_ALL);
@@ -865,6 +874,10 @@
     private void cleanupHandlerThreadAfterStop() {
         setProximitySensorEnabled(false);
         mHandler.removeCallbacksAndMessages(null);
+        if (mUnfinishedBusiness) {
+            mCallbacks.releaseSuspendBlocker();
+            mUnfinishedBusiness = false;
+        }
         if (mPowerState != null) {
             mPowerState.stop();
             mPowerState = null;
@@ -1150,7 +1163,7 @@
             // before applying the low power or dim transformations so that the slider
             // accurately represents the full possible range, even if they range changes what
             // it means in absolute terms.
-            putScreenBrightnessSetting(brightnessState);
+            putScreenBrightnessSetting(brightnessState, /* updateCurrent */ true);
         }
 
         // Apply dimming by at least some minimum amount when user activity
@@ -1692,12 +1705,7 @@
         }
     }
 
-    private final Runnable mCleanListener = new Runnable() {
-        @Override
-        public void run() {
-            sendUpdatePowerState();
-        }
-    };
+    private final Runnable mCleanListener = this::sendUpdatePowerState;
 
     private void setProximitySensorEnabled(boolean enable) {
         if (enable) {
@@ -1804,7 +1812,6 @@
 
     private void handleSettingsChange(boolean userSwitch) {
         mPendingScreenBrightnessSetting = getScreenBrightnessSetting();
-
         if (userSwitch) {
             // Don't treat user switches as user initiated change.
             mCurrentScreenBrightnessSetting = mPendingScreenBrightnessSetting;
@@ -1825,10 +1832,11 @@
         return Float.isNaN(adj) ? 0.0f : clampAutoBrightnessAdjustment(adj);
     }
 
-    private float getScreenBrightnessSetting() {
-        final float brightness = Settings.System.getFloatForUser(mContext.getContentResolver(),
-                Settings.System.SCREEN_BRIGHTNESS_FLOAT, mScreenBrightnessDefault,
-                UserHandle.USER_CURRENT);
+    float getScreenBrightnessSetting() {
+        float brightness = mBrightnessSetting.getBrightness();
+        if (Float.isNaN(brightness)) {
+            brightness = mScreenBrightnessDefault;
+        }
         return clampAbsoluteBrightness(brightness);
     }
 
@@ -1839,13 +1847,15 @@
         return clampScreenBrightnessForVr(brightnessFloat);
     }
 
-    private void putScreenBrightnessSetting(float brightnessValue) {
-        if (mDisplayId == Display.DEFAULT_DISPLAY) {
+    void putScreenBrightnessSetting(float brightnessValue) {
+        putScreenBrightnessSetting(brightnessValue, false);
+    }
+
+    private void putScreenBrightnessSetting(float brightnessValue, boolean updateCurrent) {
+        if (updateCurrent) {
             mCurrentScreenBrightnessSetting = brightnessValue;
-            Settings.System.putFloatForUser(mContext.getContentResolver(),
-                    Settings.System.SCREEN_BRIGHTNESS_FLOAT, brightnessValue,
-                    UserHandle.USER_CURRENT);
         }
+        mBrightnessSetting.setBrightness(brightnessValue);
     }
 
     private void putAutoBrightnessAdjustmentSetting(float adjustment) {
@@ -2175,7 +2185,7 @@
                     }
                     break;
                 case MSG_CONFIGURE_BRIGHTNESS:
-                    mBrightnessConfiguration = (BrightnessConfiguration)msg.obj;
+                    mBrightnessConfiguration = (BrightnessConfiguration) msg.obj;
                     updatePowerState();
                     break;
 
@@ -2197,6 +2207,12 @@
                 case MSG_STOP:
                     cleanupHandlerThreadAfterStop();
                     break;
+
+                case MSG_UPDATE_BRIGHTNESS:
+                    if (mStopped) {
+                        return;
+                    }
+                    handleSettingsChange(false /*userSwitch*/);
             }
         }
     }
diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java
index d9570c7..1589419 100644
--- a/services/core/java/com/android/server/display/LogicalDisplay.java
+++ b/services/core/java/com/android/server/display/LogicalDisplay.java
@@ -102,6 +102,8 @@
     private int mRequestedColorMode;
     private boolean mRequestedMinimalPostProcessing;
 
+    private int[] mUserDisabledHdrTypes = {};
+
     private DisplayModeDirector.DesiredDisplayModeSpecs mDesiredDisplayModeSpecs =
             new DisplayModeDirector.DesiredDisplayModeSpecs();
 
@@ -367,6 +369,7 @@
                     deviceInfo.supportedColorModes,
                     deviceInfo.supportedColorModes.length);
             mBaseDisplayInfo.hdrCapabilities = deviceInfo.hdrCapabilities;
+            mBaseDisplayInfo.userDisabledHdrTypes = mUserDisabledHdrTypes;
             mBaseDisplayInfo.minimalPostProcessingSupported =
                     deviceInfo.allmSupported || deviceInfo.gameContentTypeSupported;
             mBaseDisplayInfo.logicalDensityDpi = deviceInfo.densityDpi;
@@ -680,6 +683,14 @@
         mDisplayScalingDisabled = disableScaling;
     }
 
+    public void setUserDisabledHdrTypes(@NonNull int[] userDisabledHdrTypes) {
+        if (mUserDisabledHdrTypes != userDisabledHdrTypes) {
+            mUserDisabledHdrTypes = userDisabledHdrTypes;
+            mBaseDisplayInfo.userDisabledHdrTypes = userDisabledHdrTypes;
+            mInfo.set(null);
+        }
+    }
+
     /**
      * Swap the underlying {@link DisplayDevice} with the specified LogicalDisplay.
      *
diff --git a/services/core/java/com/android/server/display/LogicalDisplayMapper.java b/services/core/java/com/android/server/display/LogicalDisplayMapper.java
index 6c2e6eb..fcfa674 100644
--- a/services/core/java/com/android/server/display/LogicalDisplayMapper.java
+++ b/services/core/java/com/android/server/display/LogicalDisplayMapper.java
@@ -433,37 +433,31 @@
         final int displayId = display.getDisplayIdLocked();
 
         // Get current display group data
-        final int groupId = getDisplayGroupIdFromDisplayIdLocked(displayId);
+        int groupId = getDisplayGroupIdFromDisplayIdLocked(displayId);
         final DisplayGroup oldGroup = getDisplayGroupLocked(groupId);
 
         // Get the new display group if a change is needed
         final DisplayInfo info = display.getDisplayInfoLocked();
         final boolean needsOwnDisplayGroup = (info.flags & Display.FLAG_OWN_DISPLAY_GROUP) != 0;
         final boolean hasOwnDisplayGroup = groupId != Display.DEFAULT_DISPLAY_GROUP;
-        final boolean needsDisplayGroup = needsOwnDisplayGroup || info.type == Display.TYPE_INTERNAL
-                || info.type == Display.TYPE_EXTERNAL;
-        if (!needsDisplayGroup) {
-            if (oldGroup != null) {
-                oldGroup.removeDisplayLocked(display);
-            }
-            return;
-        }
         if (groupId == Display.INVALID_DISPLAY_GROUP
                 || hasOwnDisplayGroup != needsOwnDisplayGroup) {
+            groupId = assignDisplayGroupIdLocked(needsOwnDisplayGroup);
+        }
+
+        // Create a new group if needed
+        DisplayGroup newGroup = getDisplayGroupLocked(groupId);
+        if (newGroup == null) {
+            newGroup = new DisplayGroup(groupId);
+            mDisplayGroups.append(groupId, newGroup);
+        }
+        if (oldGroup != newGroup) {
             if (oldGroup != null) {
                 oldGroup.removeDisplayLocked(display);
             }
-
-            final int newGroupId = assignDisplayGroupIdLocked(needsOwnDisplayGroup);
-            // Create a new group if needed
-            DisplayGroup newGroup = getDisplayGroupLocked(newGroupId);
-            if (newGroup == null) {
-                newGroup = new DisplayGroup(newGroupId);
-                mDisplayGroups.append(newGroupId, newGroup);
-            }
             newGroup.addDisplayLocked(display);
-            display.updateDisplayGroupIdLocked(newGroupId);
-            Slog.i(TAG, "Setting new display group " + newGroupId + " for display "
+            display.updateDisplayGroupIdLocked(groupId);
+            Slog.i(TAG, "Setting new display group " + groupId + " for display "
                     + displayId + ", from previous group: "
                     + (oldGroup != null ? oldGroup.getGroupId() : "null"));
         }
diff --git a/services/core/java/com/android/server/display/PersistentDataStore.java b/services/core/java/com/android/server/display/PersistentDataStore.java
index a62642b..c90ddf4 100644
--- a/services/core/java/com/android/server/display/PersistentDataStore.java
+++ b/services/core/java/com/android/server/display/PersistentDataStore.java
@@ -62,6 +62,7 @@
  *   &lt;display-states>
  *      &lt;display unique-id="XXXXXXX">
  *          &lt;color-mode>0&lt;/color-mode>
+ *          &lt;brightness-value>0&lt;/brightness-value>
  *      &lt;/display>
  *  &lt;/display-states>
  *  &lt;stable-device-values>
@@ -82,7 +83,7 @@
  * TODO: refactor this to extract common code shared with the input manager's data store
  */
 final class PersistentDataStore {
-    static final String TAG = "DisplayManager";
+    static final String TAG = "DisplayManager.PersistentDataStore";
 
     private static final String TAG_DISPLAY_MANAGER_STATE = "display-manager-state";
 
@@ -95,6 +96,7 @@
     private static final String TAG_DISPLAY_STATES = "display-states";
     private static final String TAG_DISPLAY = "display";
     private static final String TAG_COLOR_MODE = "color-mode";
+    private static final String TAG_BRIGHTNESS_VALUE = "brightness-value";
     private static final String ATTR_UNIQUE_ID = "unique-id";
 
     private static final String TAG_STABLE_DEVICE_VALUES = "stable-device-values";
@@ -255,6 +257,30 @@
         return false;
     }
 
+    public float getBrightness(DisplayDevice device) {
+        if (device == null || !device.hasStableUniqueId()) {
+            return Float.NaN;
+        }
+        final DisplayState state = getDisplayState(device.getUniqueId(), false);
+        if (state == null) {
+            return Float.NaN;
+        }
+        return state.getBrightness();
+    }
+
+    public boolean setBrightness(DisplayDevice displayDevice, float brightness) {
+        final String displayDeviceUniqueId = displayDevice.getUniqueId();
+        if (!displayDevice.hasStableUniqueId() || displayDeviceUniqueId == null) {
+            return false;
+        }
+        final DisplayState state = getDisplayState(displayDeviceUniqueId, true);
+        if (state.setBrightness(brightness)) {
+            setDirty();
+            return true;
+        }
+        return false;
+    }
+
     public Point getStableDisplaySize() {
         loadIfNeeded();
         return mStableDeviceValues.getDisplaySize();
@@ -473,6 +499,7 @@
 
     private static final class DisplayState {
         private int mColorMode;
+        private float mBrightness;
 
         public boolean setColorMode(int colorMode) {
             if (colorMode == mColorMode) {
@@ -486,14 +513,33 @@
             return mColorMode;
         }
 
+        public boolean setBrightness(float brightness) {
+            if (brightness == mBrightness) {
+                return false;
+            }
+            mBrightness = brightness;
+            return true;
+        }
+
+        public float getBrightness() {
+            return mBrightness;
+        }
+
+
         public void loadFromXml(TypedXmlPullParser parser)
                 throws IOException, XmlPullParserException {
             final int outerDepth = parser.getDepth();
 
             while (XmlUtils.nextElementWithin(parser, outerDepth)) {
-                if (parser.getName().equals(TAG_COLOR_MODE)) {
-                    String value = parser.nextText();
-                    mColorMode = Integer.parseInt(value);
+                switch (parser.getName()) {
+                    case TAG_COLOR_MODE:
+                        String value = parser.nextText();
+                        mColorMode = Integer.parseInt(value);
+                        break;
+                    case TAG_BRIGHTNESS_VALUE:
+                        String brightness = parser.nextText();
+                        mBrightness = Float.parseFloat(brightness);
+                        break;
                 }
             }
         }
@@ -502,10 +548,15 @@
             serializer.startTag(null, TAG_COLOR_MODE);
             serializer.text(Integer.toString(mColorMode));
             serializer.endTag(null, TAG_COLOR_MODE);
+            serializer.startTag(null, TAG_BRIGHTNESS_VALUE);
+            serializer.text(Float.toString(mBrightness));
+            serializer.endTag(null, TAG_BRIGHTNESS_VALUE);
+
         }
 
         public void dump(final PrintWriter pw, final String prefix) {
             pw.println(prefix + "ColorMode=" + mColorMode);
+            pw.println(prefix + "BrightnessValue=" + mBrightness);
         }
     }
 
diff --git a/services/core/java/com/android/server/graphics/fonts/UpdatableFontDir.java b/services/core/java/com/android/server/graphics/fonts/UpdatableFontDir.java
index 4f95d27..7518130 100644
--- a/services/core/java/com/android/server/graphics/fonts/UpdatableFontDir.java
+++ b/services/core/java/com/android/server/graphics/fonts/UpdatableFontDir.java
@@ -41,11 +41,11 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.security.SecureRandom;
-import java.time.Instant;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.function.Supplier;
 
 /**
  * Manages set of updatable font files.
@@ -109,6 +109,7 @@
     private final FsverityUtil mFsverityUtil;
     private final File mConfigFile;
     private final File mTmpConfigFile;
+    private final Supplier<Long> mCurrentTimeSupplier;
 
     private long mLastModifiedMillis;
     private int mConfigVersion = 1;
@@ -128,18 +129,20 @@
 
     UpdatableFontDir(File filesDir, List<File> preinstalledFontDirs, FontFileParser parser,
             FsverityUtil fsverityUtil) {
-        this(filesDir, preinstalledFontDirs, parser, fsverityUtil, new File(CONFIG_XML_FILE));
+        this(filesDir, preinstalledFontDirs, parser, fsverityUtil, new File(CONFIG_XML_FILE),
+                () -> System.currentTimeMillis());
     }
 
     // For unit testing
     UpdatableFontDir(File filesDir, List<File> preinstalledFontDirs, FontFileParser parser,
-            FsverityUtil fsverityUtil, File configFile) {
+            FsverityUtil fsverityUtil, File configFile, Supplier<Long> currentTimeSupplier) {
         mFilesDir = filesDir;
         mPreinstalledFontDirs = preinstalledFontDirs;
         mParser = parser;
         mFsverityUtil = fsverityUtil;
         mConfigFile = configFile;
         mTmpConfigFile = new File(configFile.getAbsoluteFile() + ".tmp");
+        mCurrentTimeSupplier = currentTimeSupplier;
     }
 
     /* package */ void loadFontFileMap() {
@@ -209,7 +212,7 @@
         FileUtils.deleteContents(mFilesDir);
         mFontFamilyMap.clear();
 
-        mLastModifiedMillis = System.currentTimeMillis();
+        mLastModifiedMillis = mCurrentTimeSupplier.get();
         try (FileOutputStream fos = new FileOutputStream(mConfigFile)) {
             PersistentSystemFontConfig.writeToXml(fos, createPersistentConfig());
         } catch (Exception e) {
@@ -245,7 +248,7 @@
             }
 
             // Write config file.
-            mLastModifiedMillis = Instant.now().getEpochSecond();
+            mLastModifiedMillis = mCurrentTimeSupplier.get();
             try (FileOutputStream fos = new FileOutputStream(mTmpConfigFile)) {
                 PersistentSystemFontConfig.writeToXml(fos, createPersistentConfig());
             } catch (Exception e) {
diff --git a/services/core/java/com/android/server/hdmi/Constants.java b/services/core/java/com/android/server/hdmi/Constants.java
index d0e7e45..58308d8 100644
--- a/services/core/java/com/android/server/hdmi/Constants.java
+++ b/services/core/java/com/android/server/hdmi/Constants.java
@@ -250,7 +250,19 @@
 
     @Retention(RetentionPolicy.SOURCE)
     @IntDef({
-        ABORT_NO_ERROR,
+            NOT_HANDLED,
+            HANDLED,
+            ABORT_UNRECOGNIZED_OPCODE,
+            ABORT_NOT_IN_CORRECT_MODE,
+            ABORT_CANNOT_PROVIDE_SOURCE,
+            ABORT_INVALID_OPERAND,
+            ABORT_REFUSED,
+            ABORT_UNABLE_TO_DETERMINE,
+    })
+    public @interface HandleMessageResult {}
+
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({
         ABORT_UNRECOGNIZED_OPCODE,
         ABORT_NOT_IN_CORRECT_MODE,
         ABORT_CANNOT_PROVIDE_SOURCE,
@@ -260,8 +272,11 @@
     })
     public @interface AbortReason {}
 
-    // Internal abort error code. It's the same as success.
-    static final int ABORT_NO_ERROR = -1;
+    // Indicates that a message was not handled, but could be handled by another local device.
+    // If no local devices handle the message, we send <Feature Abort>[Unrecognized Opcode].
+    static final int NOT_HANDLED = -2;
+    // Indicates that a message has been handled successfully; no feature abort needed.
+    static final int HANDLED = -1;
     // Constants related to operands of HDMI CEC commands.
     // Refer to CEC Table 29 in HDMI Spec v1.4b.
     // [Abort Reason]
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecController.java b/services/core/java/com/android/server/hdmi/HdmiCecController.java
index 1643ec1..ad2ef2a 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecController.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecController.java
@@ -565,19 +565,24 @@
     }
 
     @ServiceThreadOnly
-    private void onReceiveCommand(HdmiCecMessage message) {
+    @VisibleForTesting
+    void onReceiveCommand(HdmiCecMessage message) {
         assertRunOnServiceThread();
-        if ((isAcceptableAddress(message.getDestination())
-            || !mService.isAddressAllocated())
-            && mService.handleCecCommand(message)) {
+        if (mService.isAddressAllocated() && !isAcceptableAddress(message.getDestination())) {
             return;
         }
-        // Not handled message, so we will reply it with <Feature Abort>.
-        maySendFeatureAbortCommand(message, Constants.ABORT_UNRECOGNIZED_OPCODE);
+        @Constants.HandleMessageResult int messageState = mService.handleCecCommand(message);
+        if (messageState == Constants.NOT_HANDLED) {
+            // Message was not handled
+            maySendFeatureAbortCommand(message, Constants.ABORT_UNRECOGNIZED_OPCODE);
+        } else if (messageState != Constants.HANDLED) {
+            // Message handler wants to send a feature abort
+            maySendFeatureAbortCommand(message, messageState);
+        }
     }
 
     @ServiceThreadOnly
-    void maySendFeatureAbortCommand(HdmiCecMessage message, int reason) {
+    void maySendFeatureAbortCommand(HdmiCecMessage message, @Constants.AbortReason int reason) {
         assertRunOnServiceThread();
         // Swap the source and the destination.
         int src = message.getDestination();
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
index bdc4e66..505e743 100755
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
@@ -248,11 +248,13 @@
      * @return true if consumed a message; otherwise, return false.
      */
     @ServiceThreadOnly
-    boolean dispatchMessage(HdmiCecMessage message) {
+    @VisibleForTesting
+    @Constants.HandleMessageResult
+    protected int dispatchMessage(HdmiCecMessage message) {
         assertRunOnServiceThread();
         int dest = message.getDestination();
         if (dest != mAddress && dest != Constants.ADDR_BROADCAST) {
-            return false;
+            return Constants.NOT_HANDLED;
         }
         // Cache incoming message if it is included in the list of cacheable opcodes.
         mCecMessageCache.cacheMessage(message);
@@ -260,10 +262,11 @@
     }
 
     @ServiceThreadOnly
-    protected final boolean onMessage(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected final int onMessage(HdmiCecMessage message) {
         assertRunOnServiceThread();
         if (dispatchMessageToAction(message)) {
-            return true;
+            return Constants.HANDLED;
         }
         switch (message.getOpcode()) {
             case Constants.MESSAGE_ACTIVE_SOURCE:
@@ -357,7 +360,7 @@
             case Constants.MESSAGE_GIVE_FEATURES:
                 return handleGiveFeatures(message);
             default:
-                return false;
+                return Constants.NOT_HANDLED;
         }
     }
 
@@ -375,7 +378,8 @@
     }
 
     @ServiceThreadOnly
-    protected boolean handleGivePhysicalAddress(@Nullable SendMessageCallback callback) {
+    @Constants.HandleMessageResult
+    protected int handleGivePhysicalAddress(@Nullable SendMessageCallback callback) {
         assertRunOnServiceThread();
 
         int physicalAddress = mService.getPhysicalAddress();
@@ -383,76 +387,83 @@
                 HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
                         mAddress, physicalAddress, mDeviceType);
         mService.sendCecCommand(cecMessage, callback);
-        return true;
+        return Constants.HANDLED;
     }
 
     @ServiceThreadOnly
-    protected boolean handleGiveDeviceVendorId(@Nullable SendMessageCallback callback) {
+    @Constants.HandleMessageResult
+    protected int handleGiveDeviceVendorId(@Nullable SendMessageCallback callback) {
         assertRunOnServiceThread();
         int vendorId = mService.getVendorId();
         HdmiCecMessage cecMessage =
                 HdmiCecMessageBuilder.buildDeviceVendorIdCommand(mAddress, vendorId);
         mService.sendCecCommand(cecMessage, callback);
-        return true;
+        return Constants.HANDLED;
     }
 
     @ServiceThreadOnly
-    protected boolean handleGetCecVersion(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleGetCecVersion(HdmiCecMessage message) {
         assertRunOnServiceThread();
         int version = mService.getCecVersion();
         HdmiCecMessage cecMessage =
                 HdmiCecMessageBuilder.buildCecVersion(
                         message.getDestination(), message.getSource(), version);
         mService.sendCecCommand(cecMessage);
-        return true;
+        return Constants.HANDLED;
     }
 
     @ServiceThreadOnly
-    private boolean handleCecVersion() {
+    @Constants.HandleMessageResult
+    protected int handleCecVersion() {
         assertRunOnServiceThread();
 
         // Return true to avoid <Feature Abort> responses. Cec Version is tracked in HdmiCecNetwork.
-        return true;
+        return Constants.HANDLED;
     }
 
     @ServiceThreadOnly
-    protected boolean handleActiveSource(HdmiCecMessage message) {
-        return false;
+    @Constants.HandleMessageResult
+    protected int handleActiveSource(HdmiCecMessage message) {
+        return Constants.NOT_HANDLED;
     }
 
     @ServiceThreadOnly
-    protected boolean handleInactiveSource(HdmiCecMessage message) {
-        return false;
+    @Constants.HandleMessageResult
+    protected int handleInactiveSource(HdmiCecMessage message) {
+        return Constants.NOT_HANDLED;
     }
 
     @ServiceThreadOnly
-    protected boolean handleRequestActiveSource(HdmiCecMessage message) {
-        return false;
+    @Constants.HandleMessageResult
+    protected int handleRequestActiveSource(HdmiCecMessage message) {
+        return Constants.NOT_HANDLED;
     }
 
     @ServiceThreadOnly
-    protected boolean handleGetMenuLanguage(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleGetMenuLanguage(HdmiCecMessage message) {
         assertRunOnServiceThread();
         Slog.w(TAG, "Only TV can handle <Get Menu Language>:" + message.toString());
-        // 'return false' will cause to reply with <Feature Abort>.
-        return false;
+        return Constants.NOT_HANDLED;
     }
 
     @ServiceThreadOnly
-    protected boolean handleSetMenuLanguage(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleSetMenuLanguage(HdmiCecMessage message) {
         assertRunOnServiceThread();
         Slog.w(TAG, "Only Playback device can handle <Set Menu Language>:" + message.toString());
-        // 'return false' will cause to reply with <Feature Abort>.
-        return false;
+        return Constants.NOT_HANDLED;
     }
 
     @ServiceThreadOnly
-    protected boolean handleGiveOsdName(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleGiveOsdName(HdmiCecMessage message) {
         assertRunOnServiceThread();
         // Note that since this method is called after logical address allocation is done,
         // mDeviceInfo should not be null.
         buildAndSendSetOsdName(message.getSource());
-        return true;
+        return Constants.HANDLED;
     }
 
     protected void buildAndSendSetOsdName(int dest) {
@@ -475,18 +486,21 @@
 
     // Audio System device with no Playback device type
     // needs to refactor this function if it's also a switch
-    protected boolean handleRoutingChange(HdmiCecMessage message) {
-        return false;
+    @Constants.HandleMessageResult
+    protected int handleRoutingChange(HdmiCecMessage message) {
+        return Constants.NOT_HANDLED;
     }
 
     // Audio System device with no Playback device type
     // needs to refactor this function if it's also a switch
-    protected boolean handleRoutingInformation(HdmiCecMessage message) {
-        return false;
+    @Constants.HandleMessageResult
+    protected int handleRoutingInformation(HdmiCecMessage message) {
+        return Constants.NOT_HANDLED;
     }
 
     @CallSuper
-    protected boolean handleReportPhysicalAddress(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleReportPhysicalAddress(HdmiCecMessage message) {
         // <Report Physical Address>  is also handled in HdmiCecNetwork to update the local network
         // state
 
@@ -495,7 +509,7 @@
         // Ignore if [Device Discovery Action] is going on.
         if (hasAction(DeviceDiscoveryAction.class)) {
             Slog.i(TAG, "Ignored while Device Discovery Action is in progress: " + message);
-            return true;
+            return Constants.HANDLED;
         }
 
         HdmiDeviceInfo cecDeviceInfo = mService.getHdmiCecNetwork().getCecDeviceInfo(address);
@@ -506,63 +520,77 @@
                     HdmiCecMessageBuilder.buildGiveOsdNameCommand(mAddress, address));
         }
 
-        return true;
+        return Constants.HANDLED;
     }
 
-    protected boolean handleSystemAudioModeStatus(HdmiCecMessage message) {
-        return false;
+    @Constants.HandleMessageResult
+    protected int handleSystemAudioModeStatus(HdmiCecMessage message) {
+        return Constants.NOT_HANDLED;
     }
 
-    protected boolean handleGiveSystemAudioModeStatus(HdmiCecMessage message) {
-        return false;
+    @Constants.HandleMessageResult
+    protected int handleGiveSystemAudioModeStatus(HdmiCecMessage message) {
+        return Constants.NOT_HANDLED;
     }
 
-    protected boolean handleSetSystemAudioMode(HdmiCecMessage message) {
-        return false;
+    @Constants.HandleMessageResult
+    protected int handleSetSystemAudioMode(HdmiCecMessage message) {
+        return Constants.NOT_HANDLED;
     }
 
-    protected boolean handleSystemAudioModeRequest(HdmiCecMessage message) {
-        return false;
+    @Constants.HandleMessageResult
+    protected int handleSystemAudioModeRequest(HdmiCecMessage message) {
+        return Constants.NOT_HANDLED;
     }
 
-    protected boolean handleTerminateArc(HdmiCecMessage message) {
-        return false;
+    @Constants.HandleMessageResult
+    protected int handleTerminateArc(HdmiCecMessage message) {
+        return Constants.NOT_HANDLED;
     }
 
-    protected boolean handleInitiateArc(HdmiCecMessage message) {
-        return false;
+    @Constants.HandleMessageResult
+    protected int handleInitiateArc(HdmiCecMessage message) {
+        return Constants.NOT_HANDLED;
     }
 
-    protected boolean handleRequestArcInitiate(HdmiCecMessage message) {
-        return false;
+    @Constants.HandleMessageResult
+    protected int handleRequestArcInitiate(HdmiCecMessage message) {
+        return Constants.NOT_HANDLED;
     }
 
-    protected boolean handleRequestArcTermination(HdmiCecMessage message) {
-        return false;
+    @Constants.HandleMessageResult
+    protected int handleRequestArcTermination(HdmiCecMessage message) {
+        return Constants.NOT_HANDLED;
     }
 
-    protected boolean handleReportArcInitiate(HdmiCecMessage message) {
-        return false;
+    @Constants.HandleMessageResult
+    protected int handleReportArcInitiate(HdmiCecMessage message) {
+        return Constants.NOT_HANDLED;
     }
 
-    protected boolean handleReportArcTermination(HdmiCecMessage message) {
-        return false;
+    @Constants.HandleMessageResult
+    protected int handleReportArcTermination(HdmiCecMessage message) {
+        return Constants.NOT_HANDLED;
     }
 
-    protected boolean handleReportAudioStatus(HdmiCecMessage message) {
-        return false;
+    @Constants.HandleMessageResult
+    protected int handleReportAudioStatus(HdmiCecMessage message) {
+        return Constants.NOT_HANDLED;
     }
 
-    protected boolean handleGiveAudioStatus(HdmiCecMessage message) {
-        return false;
+    @Constants.HandleMessageResult
+    protected int handleGiveAudioStatus(HdmiCecMessage message) {
+        return Constants.NOT_HANDLED;
     }
 
-    protected boolean handleRequestShortAudioDescriptor(HdmiCecMessage message) {
-        return false;
+    @Constants.HandleMessageResult
+    protected int handleRequestShortAudioDescriptor(HdmiCecMessage message) {
+        return Constants.NOT_HANDLED;
     }
 
-    protected boolean handleReportShortAudioDescriptor(HdmiCecMessage message) {
-        return false;
+    @Constants.HandleMessageResult
+    protected int handleReportShortAudioDescriptor(HdmiCecMessage message) {
+        return Constants.NOT_HANDLED;
     }
 
     @Constants.RcProfile
@@ -572,13 +600,14 @@
 
     protected abstract List<Integer> getDeviceFeatures();
 
-    protected boolean handleGiveFeatures(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleGiveFeatures(HdmiCecMessage message) {
         if (mService.getCecVersion() < HdmiControlManager.HDMI_CEC_VERSION_2_0) {
-            return false;
+            return Constants.ABORT_UNRECOGNIZED_OPCODE;
         }
 
         reportFeatures();
-        return true;
+        return Constants.HANDLED;
     }
 
     protected void reportFeatures() {
@@ -598,32 +627,34 @@
     }
 
     @ServiceThreadOnly
-    protected boolean handleStandby(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleStandby(HdmiCecMessage message) {
         assertRunOnServiceThread();
         // Seq #12
         if (mService.isControlEnabled()
                 && !mService.isProhibitMode()
                 && mService.isPowerOnOrTransient()) {
             mService.standby();
-            return true;
+            return Constants.HANDLED;
         }
-        return false;
+        return Constants.ABORT_NOT_IN_CORRECT_MODE;
     }
 
     @ServiceThreadOnly
-    protected boolean handleUserControlPressed(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleUserControlPressed(HdmiCecMessage message) {
         assertRunOnServiceThread();
         mHandler.removeMessages(MSG_USER_CONTROL_RELEASE_TIMEOUT);
         if (mService.isPowerOnOrTransient() && isPowerOffOrToggleCommand(message)) {
             mService.standby();
-            return true;
+            return Constants.HANDLED;
         } else if (mService.isPowerStandbyOrTransient() && isPowerOnOrToggleCommand(message)) {
             mService.wakeUp();
-            return true;
+            return Constants.HANDLED;
         } else if (mService.getHdmiCecVolumeControl()
                 == HdmiControlManager.VOLUME_CONTROL_DISABLED && isVolumeOrMuteCommand(
                 message)) {
-            return false;
+            return Constants.ABORT_REFUSED;
         }
 
         if (isPowerOffOrToggleCommand(message) || isPowerOnOrToggleCommand(message)) {
@@ -631,7 +662,7 @@
             // keycode to Android keycode.
             // Do not <Feature Abort> as the local device should already be in the correct power
             // state.
-            return true;
+            return Constants.HANDLED;
         }
 
         final long downTime = SystemClock.uptimeMillis();
@@ -653,15 +684,15 @@
             mHandler.sendMessageDelayed(
                     Message.obtain(mHandler, MSG_USER_CONTROL_RELEASE_TIMEOUT),
                     FOLLOWER_SAFETY_TIMEOUT);
-            return true;
+            return Constants.HANDLED;
         }
 
-        mService.maySendFeatureAbortCommand(message, Constants.ABORT_INVALID_OPERAND);
-        return true;
+        return Constants.ABORT_INVALID_OPERAND;
     }
 
     @ServiceThreadOnly
-    protected boolean handleUserControlReleased() {
+    @Constants.HandleMessageResult
+    protected int handleUserControlReleased() {
         assertRunOnServiceThread();
         mHandler.removeMessages(MSG_USER_CONTROL_RELEASE_TIMEOUT);
         mLastKeyRepeatCount = 0;
@@ -670,7 +701,7 @@
             injectKeyEvent(upTime, KeyEvent.ACTION_UP, mLastKeycode, 0);
             mLastKeycode = HdmiCecKeycode.UNSUPPORTED_KEYCODE;
         }
-        return true;
+        return Constants.HANDLED;
     }
 
     static void injectKeyEvent(long time, int action, int keycode, int repeat) {
@@ -717,38 +748,45 @@
                     || params[0] == HdmiCecKeycode.CEC_KEYCODE_RESTORE_VOLUME_FUNCTION);
     }
 
-    protected boolean handleTextViewOn(HdmiCecMessage message) {
-        return false;
+    @Constants.HandleMessageResult
+    protected int handleTextViewOn(HdmiCecMessage message) {
+        return Constants.NOT_HANDLED;
     }
 
-    protected boolean handleImageViewOn(HdmiCecMessage message) {
-        return false;
+    @Constants.HandleMessageResult
+    protected int handleImageViewOn(HdmiCecMessage message) {
+        return Constants.NOT_HANDLED;
     }
 
-    protected boolean handleSetStreamPath(HdmiCecMessage message) {
-        return false;
+    @Constants.HandleMessageResult
+    protected int handleSetStreamPath(HdmiCecMessage message) {
+        return Constants.NOT_HANDLED;
     }
 
-    protected boolean handleGiveDevicePowerStatus(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleGiveDevicePowerStatus(HdmiCecMessage message) {
         mService.sendCecCommand(
                 HdmiCecMessageBuilder.buildReportPowerStatus(
                         mAddress, message.getSource(), mService.getPowerStatus()));
-        return true;
+        return Constants.HANDLED;
     }
 
-    protected boolean handleMenuRequest(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleMenuRequest(HdmiCecMessage message) {
         // Always report menu active to receive Remote Control.
         mService.sendCecCommand(
                 HdmiCecMessageBuilder.buildReportMenuStatus(
                         mAddress, message.getSource(), Constants.MENU_STATE_ACTIVATED));
-        return true;
+        return Constants.HANDLED;
     }
 
-    protected boolean handleMenuStatus(HdmiCecMessage message) {
-        return false;
+    @Constants.HandleMessageResult
+    protected int handleMenuStatus(HdmiCecMessage message) {
+        return Constants.NOT_HANDLED;
     }
 
-    protected boolean handleVendorCommand(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleVendorCommand(HdmiCecMessage message) {
         if (!mService.invokeVendorCommandListenersOnReceived(
                 mDeviceType,
                 message.getSource(),
@@ -757,57 +795,64 @@
                 false)) {
             // Vendor command listener may not have been registered yet. Respond with
             // <Feature Abort> [Refused] so that the sender can try again later.
-            mService.maySendFeatureAbortCommand(message, Constants.ABORT_REFUSED);
+            return Constants.ABORT_REFUSED;
         }
-        return true;
+        return Constants.HANDLED;
     }
 
-    protected boolean handleVendorCommandWithId(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleVendorCommandWithId(HdmiCecMessage message) {
         byte[] params = message.getParams();
         int vendorId = HdmiUtils.threeBytesToInt(params);
         if (vendorId == mService.getVendorId()) {
             if (!mService.invokeVendorCommandListenersOnReceived(
                     mDeviceType, message.getSource(), message.getDestination(), params, true)) {
-                mService.maySendFeatureAbortCommand(message, Constants.ABORT_REFUSED);
+                return Constants.ABORT_REFUSED;
             }
         } else if (message.getDestination() != Constants.ADDR_BROADCAST
                 && message.getSource() != Constants.ADDR_UNREGISTERED) {
             Slog.v(TAG, "Wrong direct vendor command. Replying with <Feature Abort>");
-            mService.maySendFeatureAbortCommand(message, Constants.ABORT_UNRECOGNIZED_OPCODE);
+            return Constants.ABORT_UNRECOGNIZED_OPCODE;
         } else {
             Slog.v(TAG, "Wrong broadcast vendor command. Ignoring");
         }
-        return true;
+        return Constants.HANDLED;
     }
 
     protected void sendStandby(int deviceId) {
         // Do nothing.
     }
 
-    protected boolean handleSetOsdName(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleSetOsdName(HdmiCecMessage message) {
         // <Set OSD name> is also handled in HdmiCecNetwork to update the local network state
-        return true;
+        return Constants.HANDLED;
     }
 
-    protected boolean handleRecordTvScreen(HdmiCecMessage message) {
-        return false;
+    @Constants.HandleMessageResult
+    protected int handleRecordTvScreen(HdmiCecMessage message) {
+        return Constants.NOT_HANDLED;
     }
 
-    protected boolean handleTimerClearedStatus(HdmiCecMessage message) {
-        return false;
+    @Constants.HandleMessageResult
+    protected int handleTimerClearedStatus(HdmiCecMessage message) {
+        return Constants.NOT_HANDLED;
     }
 
-    protected boolean handleReportPowerStatus(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleReportPowerStatus(HdmiCecMessage message) {
         // <Report Power Status> is also handled in HdmiCecNetwork to update the local network state
-        return true;
+        return Constants.HANDLED;
     }
 
-    protected boolean handleTimerStatus(HdmiCecMessage message) {
-        return false;
+    @Constants.HandleMessageResult
+    protected int handleTimerStatus(HdmiCecMessage message) {
+        return Constants.NOT_HANDLED;
     }
 
-    protected boolean handleRecordStatus(HdmiCecMessage message) {
-        return false;
+    @Constants.HandleMessageResult
+    protected int handleRecordStatus(HdmiCecMessage message) {
+        return Constants.NOT_HANDLED;
     }
 
     @ServiceThreadOnly
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
index bf5bf8b..790c067 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
@@ -316,7 +316,8 @@
 
     @Override
     @ServiceThreadOnly
-    protected boolean handleActiveSource(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleActiveSource(HdmiCecMessage message) {
         assertRunOnServiceThread();
         int logicalAddress = message.getSource();
         int physicalAddress = HdmiUtils.twoBytesToInt(message.getParams());
@@ -339,52 +340,56 @@
             mDelayedMessageBuffer.removeActiveSource();
             return super.handleActiveSource(message);
         }
-        return true;
+        return Constants.HANDLED;
     }
 
     @Override
     @ServiceThreadOnly
-    protected boolean handleInitiateArc(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleInitiateArc(HdmiCecMessage message) {
         assertRunOnServiceThread();
         // TODO(amyjojo): implement initiate arc handler
         HdmiLogger.debug(TAG + "Stub handleInitiateArc");
-        return true;
+        return Constants.HANDLED;
     }
 
     @Override
     @ServiceThreadOnly
-    protected boolean handleReportArcInitiate(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleReportArcInitiate(HdmiCecMessage message) {
         assertRunOnServiceThread();
         // TODO(amyjojo): implement report arc initiate handler
         HdmiLogger.debug(TAG + "Stub handleReportArcInitiate");
-        return true;
+        return Constants.HANDLED;
     }
 
     @Override
     @ServiceThreadOnly
-    protected boolean handleReportArcTermination(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleReportArcTermination(HdmiCecMessage message) {
         assertRunOnServiceThread();
         // TODO(amyjojo): implement report arc terminate handler
         HdmiLogger.debug(TAG + "Stub handleReportArcTermination");
-        return true;
+        return Constants.HANDLED;
     }
 
     @Override
     @ServiceThreadOnly
-    protected boolean handleGiveAudioStatus(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleGiveAudioStatus(HdmiCecMessage message) {
         assertRunOnServiceThread();
         if (isSystemAudioControlFeatureEnabled() && mService.getHdmiCecVolumeControl()
                 == HdmiControlManager.VOLUME_CONTROL_ENABLED) {
             reportAudioStatus(message.getSource());
-        } else {
-            mService.maySendFeatureAbortCommand(message, Constants.ABORT_REFUSED);
+            return Constants.HANDLED;
         }
-        return true;
+        return Constants.ABORT_REFUSED;
     }
 
     @Override
     @ServiceThreadOnly
-    protected boolean handleGiveSystemAudioModeStatus(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleGiveSystemAudioModeStatus(HdmiCecMessage message) {
         assertRunOnServiceThread();
         // If the audio system is initiating the system audio mode on and TV asks the sam status at
         // the same time, respond with true. Since we know TV supports sam in this situation.
@@ -399,52 +404,53 @@
         mService.sendCecCommand(
                 HdmiCecMessageBuilder.buildReportSystemAudioMode(
                         mAddress, message.getSource(), isSystemAudioModeOnOrTurningOn));
-        return true;
+        return Constants.HANDLED;
     }
 
     @Override
     @ServiceThreadOnly
-    protected boolean handleRequestArcInitiate(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleRequestArcInitiate(HdmiCecMessage message) {
         assertRunOnServiceThread();
         removeAction(ArcInitiationActionFromAvr.class);
         if (!mService.readBooleanSystemProperty(Constants.PROPERTY_ARC_SUPPORT, true)) {
-            mService.maySendFeatureAbortCommand(message, Constants.ABORT_UNRECOGNIZED_OPCODE);
+            return Constants.ABORT_UNRECOGNIZED_OPCODE;
         } else if (!isDirectConnectToTv()) {
             HdmiLogger.debug("AVR device is not directly connected with TV");
-            mService.maySendFeatureAbortCommand(message, Constants.ABORT_NOT_IN_CORRECT_MODE);
+            return Constants.ABORT_NOT_IN_CORRECT_MODE;
         } else {
             addAndStartAction(new ArcInitiationActionFromAvr(this));
+            return Constants.HANDLED;
         }
-        return true;
     }
 
     @Override
     @ServiceThreadOnly
-    protected boolean handleRequestArcTermination(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleRequestArcTermination(HdmiCecMessage message) {
         assertRunOnServiceThread();
         if (!SystemProperties.getBoolean(Constants.PROPERTY_ARC_SUPPORT, true)) {
-            mService.maySendFeatureAbortCommand(message, Constants.ABORT_UNRECOGNIZED_OPCODE);
+            return Constants.ABORT_UNRECOGNIZED_OPCODE;
         } else if (!isArcEnabled()) {
             HdmiLogger.debug("ARC is not established between TV and AVR device");
-            mService.maySendFeatureAbortCommand(message, Constants.ABORT_NOT_IN_CORRECT_MODE);
+            return Constants.ABORT_NOT_IN_CORRECT_MODE;
         } else {
             removeAction(ArcTerminationActionFromAvr.class);
             addAndStartAction(new ArcTerminationActionFromAvr(this));
+            return Constants.HANDLED;
         }
-        return true;
     }
 
     @ServiceThreadOnly
-    protected boolean handleRequestShortAudioDescriptor(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleRequestShortAudioDescriptor(HdmiCecMessage message) {
         assertRunOnServiceThread();
         HdmiLogger.debug(TAG + "Stub handleRequestShortAudioDescriptor");
         if (!isSystemAudioControlFeatureEnabled()) {
-            mService.maySendFeatureAbortCommand(message, Constants.ABORT_REFUSED);
-            return true;
+            return Constants.ABORT_REFUSED;
         }
         if (!isSystemAudioActivated()) {
-            mService.maySendFeatureAbortCommand(message, Constants.ABORT_NOT_IN_CORRECT_MODE);
-            return true;
+            return Constants.ABORT_NOT_IN_CORRECT_MODE;
         }
 
         List<DeviceConfig> config = null;
@@ -468,21 +474,20 @@
         } else {
             AudioDeviceInfo deviceInfo = getSystemAudioDeviceInfo();
             if (deviceInfo == null) {
-                mService.maySendFeatureAbortCommand(message, Constants.ABORT_UNABLE_TO_DETERMINE);
-                return true;
+                return Constants.ABORT_UNABLE_TO_DETERMINE;
             }
 
             sadBytes = getSupportedShortAudioDescriptors(deviceInfo, audioFormatCodes);
         }
 
         if (sadBytes.length == 0) {
-            mService.maySendFeatureAbortCommand(message, Constants.ABORT_INVALID_OPERAND);
+            return Constants.ABORT_INVALID_OPERAND;
         } else {
             mService.sendCecCommand(
                     HdmiCecMessageBuilder.buildReportShortAudioDescriptor(
                             mAddress, message.getSource(), sadBytes));
+            return Constants.HANDLED;
         }
-        return true;
     }
 
     private byte[] getSupportedShortAudioDescriptors(
@@ -624,7 +629,8 @@
 
     @Override
     @ServiceThreadOnly
-    protected boolean handleSystemAudioModeRequest(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleSystemAudioModeRequest(HdmiCecMessage message) {
         assertRunOnServiceThread();
         boolean systemAudioStatusOn = message.getParams().length != 0;
         // Check if the request comes from a non-TV device.
@@ -632,8 +638,7 @@
         // if non-TV device tries to turn on the feature
         if (message.getSource() != Constants.ADDR_TV) {
             if (systemAudioStatusOn) {
-                handleSystemAudioModeOnFromNonTvDevice(message);
-                return true;
+                return handleSystemAudioModeOnFromNonTvDevice(message);
             }
         } else {
             // If TV request the feature on
@@ -644,8 +649,7 @@
         // If TV or Audio System does not support the feature,
         // will send abort command.
         if (!checkSupportAndSetSystemAudioMode(systemAudioStatusOn)) {
-            mService.maySendFeatureAbortCommand(message, Constants.ABORT_REFUSED);
-            return true;
+            return Constants.ABORT_REFUSED;
         }
 
         mService.sendCecCommand(
@@ -660,7 +664,7 @@
             if (HdmiUtils.getLocalPortFromPhysicalAddress(
                     sourcePhysicalAddress, getDeviceInfo().getPhysicalAddress())
                             != HdmiUtils.TARGET_NOT_UNDER_LOCAL_DEVICE) {
-                return true;
+                return Constants.HANDLED;
             }
             HdmiDeviceInfo safeDeviceInfoByPath =
                     mService.getHdmiCecNetwork().getSafeDeviceInfoByPath(sourcePhysicalAddress);
@@ -668,29 +672,31 @@
                 switchInputOnReceivingNewActivePath(sourcePhysicalAddress);
             }
         }
-        return true;
+        return Constants.HANDLED;
     }
 
     @Override
     @ServiceThreadOnly
-    protected boolean handleSetSystemAudioMode(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleSetSystemAudioMode(HdmiCecMessage message) {
         assertRunOnServiceThread();
         if (!checkSupportAndSetSystemAudioMode(
                 HdmiUtils.parseCommandParamSystemAudioStatus(message))) {
-            mService.maySendFeatureAbortCommand(message, Constants.ABORT_REFUSED);
+            return Constants.ABORT_REFUSED;
         }
-        return true;
+        return Constants.HANDLED;
     }
 
     @Override
     @ServiceThreadOnly
-    protected boolean handleSystemAudioModeStatus(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleSystemAudioModeStatus(HdmiCecMessage message) {
         assertRunOnServiceThread();
         if (!checkSupportAndSetSystemAudioMode(
                 HdmiUtils.parseCommandParamSystemAudioStatus(message))) {
-            mService.maySendFeatureAbortCommand(message, Constants.ABORT_REFUSED);
+            return Constants.ABORT_REFUSED;
         }
-        return true;
+        return Constants.HANDLED;
     }
 
     @ServiceThreadOnly
@@ -948,13 +954,13 @@
     /**
      * Handler of System Audio Mode Request on from non TV device
      */
-    void handleSystemAudioModeOnFromNonTvDevice(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    int handleSystemAudioModeOnFromNonTvDevice(HdmiCecMessage message) {
         if (!isSystemAudioControlFeatureEnabled()) {
             HdmiLogger.debug(
                     "Cannot turn on" + "system audio mode "
                             + "because the System Audio Control feature is disabled.");
-            mService.maySendFeatureAbortCommand(message, Constants.ABORT_REFUSED);
-            return;
+            return Constants.ABORT_REFUSED;
         }
         // Wake up device
         mService.wakeUp();
@@ -967,7 +973,7 @@
             mService.sendCecCommand(
                 HdmiCecMessageBuilder.buildSetSystemAudioMode(
                     mAddress, Constants.ADDR_BROADCAST, true));
-            return;
+            return Constants.HANDLED;
         }
         // Check if TV supports System Audio Control.
         // Handle broadcasting setSystemAudioMode on or aborting message on callback.
@@ -983,6 +989,7 @@
                 }
             }
         });
+        return Constants.HANDLED;
     }
 
     void setTvSystemAudioModeSupport(boolean supported) {
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
index 2995252..10f6948f 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
@@ -251,7 +251,8 @@
     }
 
     @ServiceThreadOnly
-    protected boolean handleUserControlPressed(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleUserControlPressed(HdmiCecMessage message) {
         assertRunOnServiceThread();
         wakeUpIfActiveSource();
         return super.handleUserControlPressed(message);
@@ -270,10 +271,11 @@
     }
 
     @ServiceThreadOnly
-    protected boolean handleSetMenuLanguage(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleSetMenuLanguage(HdmiCecMessage message) {
         assertRunOnServiceThread();
         if (!SET_MENU_LANGUAGE) {
-            return false;
+            return Constants.ABORT_UNRECOGNIZED_OPCODE;
         }
 
         try {
@@ -283,7 +285,7 @@
                 // Do not switch language if the new language is the same as the current one.
                 // This helps avoid accidental country variant switching from en_US to en_AU
                 // due to the limitation of CEC. See the warning below.
-                return true;
+                return Constants.HANDLED;
             }
 
             // Don't use Locale.getAvailableLocales() since it returns a locale
@@ -298,36 +300,38 @@
                     // will always be mapped to en-AU among other variants like en-US, en-GB,
                     // an en-IN, which may not be the expected one.
                     LocalePicker.updateLocale(localeInfo.getLocale());
-                    return true;
+                    return Constants.HANDLED;
                 }
             }
             Slog.w(TAG, "Can't handle <Set Menu Language> of " + iso3Language);
-            return false;
+            return Constants.ABORT_INVALID_OPERAND;
         } catch (UnsupportedEncodingException e) {
             Slog.w(TAG, "Can't handle <Set Menu Language>", e);
-            return false;
+            return Constants.ABORT_INVALID_OPERAND;
         }
     }
 
     @Override
-    protected boolean handleSetSystemAudioMode(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleSetSystemAudioMode(HdmiCecMessage message) {
         // System Audio Mode only turns on/off when Audio System broadcasts on/off message.
         // For device with type 4 and 5, it can set system audio mode on/off
         // when there is another audio system device connected into the system first.
         if (message.getDestination() != Constants.ADDR_BROADCAST
                 || message.getSource() != Constants.ADDR_AUDIO_SYSTEM
                 || mService.audioSystem() != null) {
-            return true;
+            return Constants.HANDLED;
         }
         boolean setSystemAudioModeOn = HdmiUtils.parseCommandParamSystemAudioStatus(message);
         if (mService.isSystemAudioActivated() != setSystemAudioModeOn) {
             mService.setSystemAudioActivated(setSystemAudioModeOn);
         }
-        return true;
+        return Constants.HANDLED;
     }
 
     @Override
-    protected boolean handleSystemAudioModeStatus(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleSystemAudioModeStatus(HdmiCecMessage message) {
         // Only directly addressed System Audio Mode Status message can change internal
         // system audio mode status.
         if (message.getDestination() == mAddress
@@ -337,25 +341,27 @@
                 mService.setSystemAudioActivated(setSystemAudioModeOn);
             }
         }
-        return true;
+        return Constants.HANDLED;
     }
 
     @Override
     @ServiceThreadOnly
-    protected boolean handleRoutingChange(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleRoutingChange(HdmiCecMessage message) {
         assertRunOnServiceThread();
         int physicalAddress = HdmiUtils.twoBytesToInt(message.getParams(), 2);
         handleRoutingChangeAndInformation(physicalAddress, message);
-        return true;
+        return Constants.HANDLED;
     }
 
     @Override
     @ServiceThreadOnly
-    protected boolean handleRoutingInformation(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleRoutingInformation(HdmiCecMessage message) {
         assertRunOnServiceThread();
         int physicalAddress = HdmiUtils.twoBytesToInt(message.getParams());
         handleRoutingChangeAndInformation(physicalAddress, message);
-        return true;
+        return Constants.HANDLED;
     }
 
     @Override
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java
index 2ed8481..979a1d4 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java
@@ -203,7 +203,8 @@
     }
 
     @ServiceThreadOnly
-    protected boolean handleActiveSource(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleActiveSource(HdmiCecMessage message) {
         assertRunOnServiceThread();
         int logicalAddress = message.getSource();
         int physicalAddress = HdmiUtils.twoBytesToInt(message.getParams());
@@ -215,20 +216,22 @@
         if (isRoutingControlFeatureEnabled()) {
             switchInputOnReceivingNewActivePath(physicalAddress);
         }
-        return true;
+        return Constants.HANDLED;
     }
 
     @Override
     @ServiceThreadOnly
-    protected boolean handleRequestActiveSource(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleRequestActiveSource(HdmiCecMessage message) {
         assertRunOnServiceThread();
         maySendActiveSource(message.getSource());
-        return true;
+        return Constants.HANDLED;
     }
 
     @Override
     @ServiceThreadOnly
-    protected boolean handleSetStreamPath(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleSetStreamPath(HdmiCecMessage message) {
         assertRunOnServiceThread();
         int physicalAddress = HdmiUtils.twoBytesToInt(message.getParams());
         // If current device is the target path, set to Active Source.
@@ -242,12 +245,13 @@
             setActiveSource(physicalAddress, "HdmiCecLocalDeviceSource#handleSetStreamPath()");
         }
         switchInputOnReceivingNewActivePath(physicalAddress);
-        return true;
+        return Constants.HANDLED;
     }
 
     @Override
     @ServiceThreadOnly
-    protected boolean handleRoutingChange(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleRoutingChange(HdmiCecMessage message) {
         assertRunOnServiceThread();
         int physicalAddress = HdmiUtils.twoBytesToInt(message.getParams(), 2);
         if (physicalAddress != mService.getPhysicalAddress() || !isActiveSource()) {
@@ -256,16 +260,16 @@
             setActiveSource(physicalAddress, "HdmiCecLocalDeviceSource#handleRoutingChange()");
         }
         if (!isRoutingControlFeatureEnabled()) {
-            mService.maySendFeatureAbortCommand(message, Constants.ABORT_REFUSED);
-            return true;
+            return Constants.ABORT_REFUSED;
         }
         handleRoutingChangeAndInformation(physicalAddress, message);
-        return true;
+        return Constants.HANDLED;
     }
 
     @Override
     @ServiceThreadOnly
-    protected boolean handleRoutingInformation(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleRoutingInformation(HdmiCecMessage message) {
         assertRunOnServiceThread();
         int physicalAddress = HdmiUtils.twoBytesToInt(message.getParams());
         if (physicalAddress != mService.getPhysicalAddress() || !isActiveSource()) {
@@ -274,11 +278,10 @@
             setActiveSource(physicalAddress, "HdmiCecLocalDeviceSource#handleRoutingInformation()");
         }
         if (!isRoutingControlFeatureEnabled()) {
-            mService.maySendFeatureAbortCommand(message, Constants.ABORT_REFUSED);
-            return true;
+            return Constants.ABORT_REFUSED;
         }
         handleRoutingChangeAndInformation(physicalAddress, message);
-        return true;
+        return Constants.HANDLED;
     }
 
     // Method to switch Input with the new Active Path.
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
index 90d6433..03fb3a4 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -47,6 +47,7 @@
 import android.util.SparseBooleanArray;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.hdmi.DeviceDiscoveryAction.DeviceDiscoveryCallback;
 import com.android.server.hdmi.HdmiAnnotations.ServiceThreadOnly;
@@ -210,11 +211,13 @@
 
     @Override
     @ServiceThreadOnly
-    boolean dispatchMessage(HdmiCecMessage message) {
+    @VisibleForTesting
+    @Constants.HandleMessageResult
+    protected int dispatchMessage(HdmiCecMessage message) {
         assertRunOnServiceThread();
         if (mService.isPowerStandby() && !mService.isWakeUpMessageReceived()
                 && mStandbyHandler.handleCommand(message)) {
-            return true;
+            return Constants.HANDLED;
         }
         return super.onMessage(message);
     }
@@ -409,7 +412,8 @@
 
     @Override
     @ServiceThreadOnly
-    protected boolean handleActiveSource(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleActiveSource(HdmiCecMessage message) {
         assertRunOnServiceThread();
         int logicalAddress = message.getSource();
         int physicalAddress = HdmiUtils.twoBytesToInt(message.getParams());
@@ -429,21 +433,22 @@
             HdmiLogger.debug("Input not ready for device: %X; buffering the command", info.getId());
             mDelayedMessageBuffer.add(message);
         }
-        return true;
+        return Constants.HANDLED;
     }
 
     @Override
     @ServiceThreadOnly
-    protected boolean handleInactiveSource(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleInactiveSource(HdmiCecMessage message) {
         assertRunOnServiceThread();
         // Seq #10
 
         // Ignore <Inactive Source> from non-active source device.
         if (getActiveSource().logicalAddress != message.getSource()) {
-            return true;
+            return Constants.HANDLED;
         }
         if (isProhibitMode()) {
-            return true;
+            return Constants.HANDLED;
         }
         int portId = getPrevPortId();
         if (portId != Constants.INVALID_PORT_ID) {
@@ -452,10 +457,10 @@
             HdmiDeviceInfo inactiveSource = mService.getHdmiCecNetwork().getCecDeviceInfo(
                     message.getSource());
             if (inactiveSource == null) {
-                return true;
+                return Constants.HANDLED;
             }
             if (mService.pathToPortId(inactiveSource.getPhysicalAddress()) == portId) {
-                return true;
+                return Constants.HANDLED;
             }
             // TODO: Switch the TV freeze mode off
 
@@ -468,29 +473,31 @@
             setActivePath(Constants.INVALID_PHYSICAL_ADDRESS);
             mService.invokeInputChangeListener(HdmiDeviceInfo.INACTIVE_DEVICE);
         }
-        return true;
+        return Constants.HANDLED;
     }
 
     @Override
     @ServiceThreadOnly
-    protected boolean handleRequestActiveSource(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleRequestActiveSource(HdmiCecMessage message) {
         assertRunOnServiceThread();
         // Seq #19
         if (mAddress == getActiveSource().logicalAddress) {
             mService.sendCecCommand(
                     HdmiCecMessageBuilder.buildActiveSource(mAddress, getActivePath()));
         }
-        return true;
+        return Constants.HANDLED;
     }
 
     @Override
     @ServiceThreadOnly
-    protected boolean handleGetMenuLanguage(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleGetMenuLanguage(HdmiCecMessage message) {
         assertRunOnServiceThread();
         if (!broadcastMenuLanguage(mService.getLanguage())) {
             Slog.w(TAG, "Failed to respond to <Get Menu Language>: " + message.toString());
         }
-        return true;
+        return Constants.HANDLED;
     }
 
     @ServiceThreadOnly
@@ -506,7 +513,8 @@
     }
 
     @Override
-    protected boolean handleReportPhysicalAddress(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleReportPhysicalAddress(HdmiCecMessage message) {
         super.handleReportPhysicalAddress(message);
         int path = HdmiUtils.twoBytesToInt(message.getParams());
         int address = message.getSource();
@@ -516,19 +524,21 @@
             handleNewDeviceAtTheTailOfActivePath(path);
         }
         startNewDeviceAction(ActiveSource.of(address, path), type);
-        return true;
+        return Constants.HANDLED;
     }
 
     @Override
-    protected boolean handleTimerStatus(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleTimerStatus(HdmiCecMessage message) {
         // Do nothing.
-        return true;
+        return Constants.HANDLED;
     }
 
     @Override
-    protected boolean handleRecordStatus(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleRecordStatus(HdmiCecMessage message) {
         // Do nothing.
-        return true;
+        return Constants.HANDLED;
     }
 
     void startNewDeviceAction(ActiveSource activeSource, int deviceType) {
@@ -546,8 +556,10 @@
             }
         }
 
-        addAndStartAction(new NewDeviceAction(this, activeSource.logicalAddress,
-                activeSource.physicalAddress, deviceType));
+        if (!mService.isPowerStandbyOrTransient()) {
+            addAndStartAction(new NewDeviceAction(this, activeSource.logicalAddress,
+                    activeSource.physicalAddress, deviceType));
+        }
     }
 
     private boolean handleNewDeviceAtTheTailOfActivePath(int path) {
@@ -590,7 +602,8 @@
 
     @Override
     @ServiceThreadOnly
-    protected boolean handleRoutingChange(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleRoutingChange(HdmiCecMessage message) {
         assertRunOnServiceThread();
         // Seq #21
         byte[] params = message.getParams();
@@ -601,27 +614,29 @@
             int newPath = HdmiUtils.twoBytesToInt(params, 2);
             addAndStartAction(new RoutingControlAction(this, newPath, true, null));
         }
-        return true;
+        return Constants.HANDLED;
     }
 
     @Override
     @ServiceThreadOnly
-    protected boolean handleReportAudioStatus(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleReportAudioStatus(HdmiCecMessage message) {
         assertRunOnServiceThread();
         if (mService.getHdmiCecVolumeControl()
                 == HdmiControlManager.VOLUME_CONTROL_DISABLED) {
-            return false;
+            return Constants.ABORT_REFUSED;
         }
 
         boolean mute = HdmiUtils.isAudioStatusMute(message);
         int volume = HdmiUtils.getAudioStatusVolume(message);
         setAudioStatus(mute, volume);
-        return true;
+        return Constants.HANDLED;
     }
 
     @Override
     @ServiceThreadOnly
-    protected boolean handleTextViewOn(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleTextViewOn(HdmiCecMessage message) {
         assertRunOnServiceThread();
 
         // Note that <Text View On> (and <Image View On>) command won't be handled here in
@@ -634,12 +649,13 @@
         if (mService.isPowerStandbyOrTransient() && getAutoWakeup()) {
             mService.wakeUp();
         }
-        return true;
+        return Constants.HANDLED;
     }
 
     @Override
     @ServiceThreadOnly
-    protected boolean handleImageViewOn(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleImageViewOn(HdmiCecMessage message) {
         assertRunOnServiceThread();
         // Currently, it's the same as <Text View On>.
         return handleTextViewOn(message);
@@ -695,10 +711,12 @@
     @ServiceThreadOnly
     void onNewAvrAdded(HdmiDeviceInfo avr) {
         assertRunOnServiceThread();
-        addAndStartAction(new SystemAudioAutoInitiationAction(this, avr.getLogicalAddress()));
-        if (isConnected(avr.getPortId()) && isArcFeatureEnabled(avr.getPortId())
-                && !hasAction(SetArcTransmissionStateAction.class)) {
-            startArcAction(true);
+        if (!mService.isPowerStandbyOrTransient()) {
+            addAndStartAction(new SystemAudioAutoInitiationAction(this, avr.getLogicalAddress()));
+            if (isConnected(avr.getPortId()) && isArcFeatureEnabled(avr.getPortId())
+                    && !hasAction(SetArcTransmissionStateAction.class)) {
+                startArcAction(true);
+            }
         }
     }
 
@@ -977,7 +995,8 @@
 
     @Override
     @ServiceThreadOnly
-    protected boolean handleInitiateArc(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleInitiateArc(HdmiCecMessage message) {
         assertRunOnServiceThread();
 
         if (!canStartArcUpdateAction(message.getSource(), true)) {
@@ -985,13 +1004,12 @@
             if (avrDeviceInfo == null) {
                 // AVR may not have been discovered yet. Delay the message processing.
                 mDelayedMessageBuffer.add(message);
-                return true;
+                return Constants.HANDLED;
             }
-            mService.maySendFeatureAbortCommand(message, Constants.ABORT_REFUSED);
             if (!isConnectedToArcPort(avrDeviceInfo.getPhysicalAddress())) {
                 displayOsd(OSD_MESSAGE_ARC_CONNECTED_INVALID_PORT);
             }
-            return true;
+            return Constants.ABORT_REFUSED;
         }
 
         // In case where <Initiate Arc> is started by <Request ARC Initiation>
@@ -1000,7 +1018,7 @@
         SetArcTransmissionStateAction action = new SetArcTransmissionStateAction(this,
                 message.getSource(), true);
         addAndStartAction(action);
-        return true;
+        return Constants.HANDLED;
     }
 
     private boolean canStartArcUpdateAction(int avrAddress, boolean enabled) {
@@ -1022,11 +1040,12 @@
 
     @Override
     @ServiceThreadOnly
-    protected boolean handleTerminateArc(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleTerminateArc(HdmiCecMessage message) {
         assertRunOnServiceThread();
         if (mService .isPowerStandbyOrTransient()) {
             setArcStatus(false);
-            return true;
+            return Constants.HANDLED;
         }
         // Do not check ARC configuration since the AVR might have been already removed.
         // Clean up RequestArcTerminationAction in case <Terminate Arc> was started by
@@ -1035,12 +1054,13 @@
         SetArcTransmissionStateAction action = new SetArcTransmissionStateAction(this,
                 message.getSource(), false);
         addAndStartAction(action);
-        return true;
+        return Constants.HANDLED;
     }
 
     @Override
     @ServiceThreadOnly
-    protected boolean handleSetSystemAudioMode(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleSetSystemAudioMode(HdmiCecMessage message) {
         assertRunOnServiceThread();
         boolean systemAudioStatus = HdmiUtils.parseCommandParamSystemAudioStatus(message);
         if (!isMessageForSystemAudio(message)) {
@@ -1049,30 +1069,29 @@
                 mDelayedMessageBuffer.add(message);
             } else {
                 HdmiLogger.warning("Invalid <Set System Audio Mode> message:" + message);
-                mService.maySendFeatureAbortCommand(message, Constants.ABORT_REFUSED);
+                return Constants.ABORT_REFUSED;
             }
-            return true;
         } else if (systemAudioStatus && !isSystemAudioControlFeatureEnabled()) {
             HdmiLogger.debug("Ignoring <Set System Audio Mode> message "
                     + "because the System Audio Control feature is disabled: %s", message);
-            mService.maySendFeatureAbortCommand(message, Constants.ABORT_REFUSED);
-            return true;
+            return Constants.ABORT_REFUSED;
         }
         removeAction(SystemAudioAutoInitiationAction.class);
         SystemAudioActionFromAvr action = new SystemAudioActionFromAvr(this,
                 message.getSource(), systemAudioStatus, null);
         addAndStartAction(action);
-        return true;
+        return Constants.HANDLED;
     }
 
     @Override
     @ServiceThreadOnly
-    protected boolean handleSystemAudioModeStatus(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleSystemAudioModeStatus(HdmiCecMessage message) {
         assertRunOnServiceThread();
         if (!isMessageForSystemAudio(message)) {
             HdmiLogger.warning("Invalid <System Audio Mode Status> message:" + message);
             // Ignore this message.
-            return true;
+            return Constants.HANDLED;
         }
         boolean tvSystemAudioMode = isSystemAudioControlFeatureEnabled();
         boolean avrSystemAudioMode = HdmiUtils.parseCommandParamSystemAudioStatus(message);
@@ -1089,13 +1108,14 @@
             setSystemAudioMode(tvSystemAudioMode);
         }
 
-        return true;
+        return Constants.HANDLED;
     }
 
     // Seq #53
     @Override
     @ServiceThreadOnly
-    protected boolean handleRecordTvScreen(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleRecordTvScreen(HdmiCecMessage message) {
         List<OneTouchRecordAction> actions = getActions(OneTouchRecordAction.class);
         if (!actions.isEmpty()) {
             // Assumes only one OneTouchRecordAction.
@@ -1107,25 +1127,21 @@
             }
             // The default behavior of <Record TV Screen> is replying <Feature Abort> with
             // "Cannot provide source".
-            mService.maySendFeatureAbortCommand(message, Constants.ABORT_CANNOT_PROVIDE_SOURCE);
-            return true;
+            return Constants.ABORT_CANNOT_PROVIDE_SOURCE;
         }
 
         int recorderAddress = message.getSource();
         byte[] recordSource = mService.invokeRecordRequestListener(recorderAddress);
-        int reason = startOneTouchRecord(recorderAddress, recordSource);
-        if (reason != Constants.ABORT_NO_ERROR) {
-            mService.maySendFeatureAbortCommand(message, reason);
-        }
-        return true;
+        return startOneTouchRecord(recorderAddress, recordSource);
     }
 
     @Override
-    protected boolean handleTimerClearedStatus(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleTimerClearedStatus(HdmiCecMessage message) {
         byte[] params = message.getParams();
         int timerClearedStatusData = params[0] & 0xFF;
         announceTimerRecordingResult(message.getSource(), timerClearedStatusData);
-        return true;
+        return Constants.HANDLED;
     }
 
     void announceOneTouchRecordResult(int recorderAddress, int result) {
@@ -1251,6 +1267,7 @@
         // Remove recording actions.
         removeAction(OneTouchRecordAction.class);
         removeAction(TimerRecordingAction.class);
+        removeAction(NewDeviceAction.class);
 
         disableSystemAudioIfExist();
         disableArcIfExist();
@@ -1291,12 +1308,20 @@
         setArcStatus(false);
 
         // Seq #44.
-        removeAction(RequestArcInitiationAction.class);
+        removeAllRunningArcAction();
         if (!hasAction(RequestArcTerminationAction.class) && isArcEstablished()) {
             addAndStartAction(new RequestArcTerminationAction(this, avr.getLogicalAddress()));
         }
     }
 
+    @ServiceThreadOnly
+    private void removeAllRunningArcAction() {
+        // Running or pending actions make TV fail to broadcast <Standby> to connected devices
+        removeAction(RequestArcTerminationAction.class);
+        removeAction(RequestArcInitiationAction.class);
+        removeAction(SetArcTransmissionStateAction.class);
+    }
+
     @Override
     @ServiceThreadOnly
     protected void onStandby(boolean initiatedByCec, int standbyAction) {
@@ -1337,6 +1362,7 @@
 
     // Seq #54 and #55
     @ServiceThreadOnly
+    @Constants.HandleMessageResult
     int startOneTouchRecord(int recorderAddress, byte[] recordSource) {
         assertRunOnServiceThread();
         if (!mService.isControlEnabled()) {
@@ -1362,7 +1388,7 @@
         addAndStartAction(new OneTouchRecordAction(this, recorderAddress, recordSource));
         Slog.i(TAG, "Start new [One Touch Record]-Target:" + recorderAddress + ", recordSource:"
                 + Arrays.toString(recordSource));
-        return Constants.ABORT_NO_ERROR;
+        return Constants.HANDLED;
     }
 
     @ServiceThreadOnly
@@ -1494,9 +1520,10 @@
     }
 
     @Override
-    protected boolean handleMenuStatus(HdmiCecMessage message) {
+    @Constants.HandleMessageResult
+    protected int handleMenuStatus(HdmiCecMessage message) {
         // Do nothing and just return true not to prevent from responding <Feature Abort>.
-        return true;
+        return Constants.HANDLED;
     }
 
     @Constants.RcProfile
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 03a8338..031c057 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -372,8 +372,7 @@
 
     private HdmiCecMessageValidator mMessageValidator;
 
-    private final HdmiCecPowerStatusController mPowerStatusController =
-            new HdmiCecPowerStatusController(this);
+    private HdmiCecPowerStatusController mPowerStatusController;
 
     @ServiceThreadOnly
     private String mMenuLanguage = localeToMenuLanguage(Locale.getDefault());
@@ -427,7 +426,7 @@
     // Use getAtomWriter() instead of accessing directly, to allow dependency injection for testing.
     private HdmiCecAtomWriter mAtomWriter = new HdmiCecAtomWriter();
 
-    private CecMessageBuffer mCecMessageBuffer = new CecMessageBuffer(this);
+    private CecMessageBuffer mCecMessageBuffer;
 
     private final SelectRequestBuffer mSelectRequestBuffer = new SelectRequestBuffer();
 
@@ -493,6 +492,9 @@
             mIoLooper = mIoThread.getLooper();
         }
 
+        if (mPowerStatusController == null) {
+            mPowerStatusController = new HdmiCecPowerStatusController(this);
+        }
         mPowerStatusController.setPowerStatus(getInitialPowerStatus());
         mProhibitMode = false;
         mHdmiControlEnabled = mHdmiCecConfig.getIntValue(
@@ -501,6 +503,9 @@
                 HdmiControlManager.CEC_SETTING_NAME_VOLUME_CONTROL_MODE));
         mMhlInputChangeEnabled = readBooleanSetting(Global.MHL_INPUT_SWITCHING_ENABLED, true);
 
+        if (mCecMessageBuffer == null) {
+            mCecMessageBuffer = new CecMessageBuffer(this);
+        }
         if (mCecController == null) {
             mCecController = HdmiCecController.create(this, getAtomWriter());
         }
@@ -948,11 +953,10 @@
 
     /**
      * Returns {@link Looper} for IO operation.
-     *
-     * <p>Declared as package-private.
      */
     @Nullable
-    Looper getIoLooper() {
+    @VisibleForTesting
+    protected Looper getIoLooper() {
         return mIoLooper;
     }
 
@@ -974,10 +978,9 @@
     /**
      * Returns {@link Looper} of main thread. Use this {@link Looper} instance
      * for tasks that are running on main service thread.
-     *
-     * <p>Declared as package-private.
      */
-    Looper getServiceLooper() {
+    @VisibleForTesting
+    protected Looper getServiceLooper() {
         return mHandler.getLooper();
     }
 
@@ -1015,8 +1018,9 @@
     /**
      * Returns version of CEC.
      */
+    @VisibleForTesting
     @HdmiControlManager.HdmiCecVersion
-    int getCecVersion() {
+    protected int getCecVersion() {
         return mCecVersion;
     }
 
@@ -1087,23 +1091,30 @@
     }
 
     @ServiceThreadOnly
-    boolean handleCecCommand(HdmiCecMessage message) {
+    @VisibleForTesting
+    @Constants.HandleMessageResult
+    protected int handleCecCommand(HdmiCecMessage message) {
         assertRunOnServiceThread();
         int errorCode = mMessageValidator.isValid(message);
         if (errorCode != HdmiCecMessageValidator.OK) {
             // We'll not response on the messages with the invalid source or destination
             // or with parameter length shorter than specified in the standard.
             if (errorCode == HdmiCecMessageValidator.ERROR_PARAMETER) {
-                maySendFeatureAbortCommand(message, Constants.ABORT_INVALID_OPERAND);
+                return Constants.ABORT_INVALID_OPERAND;
             }
-            return true;
+            return Constants.HANDLED;
         }
         getHdmiCecNetwork().handleCecMessage(message);
-        if (dispatchMessageToLocalDevice(message)) {
-            return true;
+
+        @Constants.HandleMessageResult int handleMessageResult =
+                dispatchMessageToLocalDevice(message);
+        if (handleMessageResult == Constants.NOT_HANDLED
+                && !mAddressAllocated
+                && mCecMessageBuffer.bufferMessage(message)) {
+            return Constants.HANDLED;
         }
 
-        return (!mAddressAllocated) ? mCecMessageBuffer.bufferMessage(message) : false;
+        return handleMessageResult;
     }
 
     void enableAudioReturnChannel(int portId, boolean enabled) {
@@ -1111,19 +1122,25 @@
     }
 
     @ServiceThreadOnly
-    private boolean dispatchMessageToLocalDevice(HdmiCecMessage message) {
+    @VisibleForTesting
+    @Constants.HandleMessageResult
+    protected int dispatchMessageToLocalDevice(HdmiCecMessage message) {
         assertRunOnServiceThread();
         for (HdmiCecLocalDevice device : mHdmiCecNetwork.getLocalDeviceList()) {
-            if (device.dispatchMessage(message)
+            @Constants.HandleMessageResult int messageResult = device.dispatchMessage(message);
+            if (messageResult != Constants.NOT_HANDLED
                     && message.getDestination() != Constants.ADDR_BROADCAST) {
-                return true;
+                return messageResult;
             }
         }
 
-        if (message.getDestination() != Constants.ADDR_BROADCAST) {
+        // We should never respond <Feature Abort> to a broadcast message
+        if (message.getDestination() == Constants.ADDR_BROADCAST) {
+            return Constants.HANDLED;
+        } else {
             HdmiLogger.warning("Unhandled cec command:" + message);
+            return Constants.NOT_HANDLED;
         }
-        return false;
     }
 
     /**
@@ -2970,7 +2987,7 @@
     }
 
     @VisibleForTesting
-    boolean isStandbyMessageReceived() {
+    protected boolean isStandbyMessageReceived() {
         return mStandbyMessageReceived;
     }
 
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 0925027..0f13741 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -76,6 +76,8 @@
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.VibrationEffect;
+import android.os.vibrator.StepSegment;
+import android.os.vibrator.VibrationEffectSegment;
 import android.provider.DeviceConfig;
 import android.provider.Settings;
 import android.provider.Settings.SettingNotFoundException;
@@ -1917,9 +1919,9 @@
     }
 
     private static class VibrationInfo {
-        private long[] mPattern = new long[0];
-        private int[] mAmplitudes = new int[0];
-        private int mRepeat = -1;
+        private final long[] mPattern;
+        private final int[] mAmplitudes;
+        private final int mRepeat;
 
         public long[] getPattern() {
             return mPattern;
@@ -1934,40 +1936,55 @@
         }
 
         VibrationInfo(VibrationEffect effect) {
-            // First replace prebaked effects with its fallback, if any available.
-            if (effect instanceof VibrationEffect.Prebaked) {
-                VibrationEffect fallback = ((VibrationEffect.Prebaked) effect).getFallbackEffect();
-                if (fallback != null) {
-                    effect = fallback;
+            long[] pattern = null;
+            int[] amplitudes = null;
+            int patternRepeatIndex = -1;
+            int amplitudeCount = -1;
+
+            if (effect instanceof VibrationEffect.Composed) {
+                VibrationEffect.Composed composed = (VibrationEffect.Composed) effect;
+                int segmentCount = composed.getSegments().size();
+                pattern = new long[segmentCount];
+                amplitudes = new int[segmentCount];
+                patternRepeatIndex = composed.getRepeatIndex();
+                amplitudeCount = 0;
+                for (int i = 0; i < segmentCount; i++) {
+                    VibrationEffectSegment segment = composed.getSegments().get(i);
+                    if (composed.getRepeatIndex() == i) {
+                        patternRepeatIndex = amplitudeCount;
+                    }
+                    if (!(segment instanceof StepSegment)) {
+                        Slog.w(TAG, "Input devices don't support segment " + segment);
+                        amplitudeCount = -1;
+                        break;
+                    }
+                    float amplitude = ((StepSegment) segment).getAmplitude();
+                    if (Float.compare(amplitude, VibrationEffect.DEFAULT_AMPLITUDE) == 0) {
+                        amplitudes[amplitudeCount] = DEFAULT_VIBRATION_MAGNITUDE;
+                    } else {
+                        amplitudes[amplitudeCount] =
+                                (int) (amplitude * VibrationEffect.MAX_AMPLITUDE);
+                    }
+                    pattern[amplitudeCount++] = segment.getDuration();
                 }
             }
-            if (effect instanceof VibrationEffect.OneShot) {
-                VibrationEffect.OneShot oneShot = (VibrationEffect.OneShot) effect;
-                mPattern = new long[] { 0, oneShot.getDuration() };
-                int amplitude = oneShot.getAmplitude();
-                // android framework uses DEFAULT_AMPLITUDE to signal that the vibration
-                // should use some built-in default value, denoted here as
-                // DEFAULT_VIBRATION_MAGNITUDE
-                if (amplitude == VibrationEffect.DEFAULT_AMPLITUDE) {
-                    amplitude = DEFAULT_VIBRATION_MAGNITUDE;
-                }
-                mAmplitudes = new int[] { 0, amplitude };
+
+            if (amplitudeCount < 0) {
+                Slog.w(TAG, "Only oneshot and step waveforms are supported on input devices");
+                mPattern = new long[0];
+                mAmplitudes = new int[0];
                 mRepeat = -1;
-            } else if (effect instanceof VibrationEffect.Waveform) {
-                VibrationEffect.Waveform waveform = (VibrationEffect.Waveform) effect;
-                mPattern = waveform.getTimings();
-                mAmplitudes = waveform.getAmplitudes();
-                for (int i = 0; i < mAmplitudes.length; i++) {
-                    if (mAmplitudes[i] == VibrationEffect.DEFAULT_AMPLITUDE) {
-                        mAmplitudes[i] = DEFAULT_VIBRATION_MAGNITUDE;
-                    }
-                }
-                mRepeat = waveform.getRepeatIndex();
-                if (mRepeat >= mPattern.length) {
-                    throw new ArrayIndexOutOfBoundsException();
-                }
             } else {
-                Slog.w(TAG, "Pre-baked and composed effects aren't supported on input devices");
+                mRepeat = patternRepeatIndex;
+                mPattern = new long[amplitudeCount];
+                mAmplitudes = new int[amplitudeCount];
+                System.arraycopy(pattern, 0, mPattern, 0, amplitudeCount);
+                System.arraycopy(amplitudes, 0, mAmplitudes, 0, amplitudeCount);
+                if (mRepeat >= mPattern.length) {
+                    throw new ArrayIndexOutOfBoundsException("Repeat index " + mRepeat
+                            + " must be within the bounds of the pattern.length "
+                            + mPattern.length);
+                }
             }
         }
     }
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index ffb532e..27f8fd3 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -17,6 +17,7 @@
 
 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;
 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
 import static android.server.inputmethod.InputMethodManagerServiceProto.ACCESSIBILITY_REQUESTING_NO_SOFT_KEYBOARD;
@@ -175,11 +176,9 @@
 import com.android.internal.inputmethod.UnbindReason;
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
 import com.android.internal.notification.SystemNotificationChannels;
-import com.android.internal.os.BackgroundThread;
 import com.android.internal.os.HandlerCaller;
 import com.android.internal.os.SomeArgs;
 import com.android.internal.os.TransferPipe;
-import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.DumpUtils;
 import com.android.internal.view.IInlineSuggestionsRequestCallback;
 import com.android.internal.view.IInlineSuggestionsResponseCallback;
@@ -199,6 +198,7 @@
 import com.android.server.inputmethod.InputMethodUtils.InputMethodSettings;
 import com.android.server.pm.UserManagerInternal;
 import com.android.server.statusbar.StatusBarManagerService;
+import com.android.server.utils.PriorityDump;
 import com.android.server.wm.WindowManagerInternal;
 
 import java.io.FileDescriptor;
@@ -256,7 +256,6 @@
     static final int MSG_SET_ACTIVE = 3020;
     static final int MSG_SET_INTERACTIVE = 3030;
     static final int MSG_REPORT_FULLSCREEN_MODE = 3045;
-    static final int MSG_APPLY_IME_VISIBILITY = 3070;
 
     static final int MSG_HARD_KEYBOARD_SWITCH_CHANGED = 4000;
 
@@ -1567,7 +1566,7 @@
             LocalServices.addService(InputMethodManagerInternal.class,
                     new LocalServiceImpl(mService));
             publishBinderService(Context.INPUT_METHOD_SERVICE, mService, false /*allowIsolated*/,
-                    DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);
+                    DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);
         }
 
         @Override
@@ -3201,7 +3200,7 @@
     boolean showCurrentInputLocked(IBinder windowToken, int flags, ResultReceiver resultReceiver,
             @SoftInputShowHideReason int reason) {
         mShowRequested = true;
-        if (mAccessibilityRequestingNoSoftKeyboard) {
+        if (mAccessibilityRequestingNoSoftKeyboard || mImeHiddenByDisplayPolicy) {
             return false;
         }
 
@@ -4102,7 +4101,6 @@
      */
     @BinderThread
     @Override
-    @GuardedBy("mMethodMap")
     public void startProtoDump(byte[] protoDump, int source, String where,
             IVoidResultCallback resultCallback) {
         CallbackUtils.onResult(resultCallback, () -> {
@@ -4199,7 +4197,6 @@
         });
     }
 
-    @GuardedBy("mMethodMap")
     private void dumpDebug(ProtoOutputStream proto, long fieldId) {
         synchronized (mMethodMap) {
             final long token = proto.start(fieldId);
@@ -4603,18 +4600,6 @@
                 }
                 return true;
             }
-            case MSG_APPLY_IME_VISIBILITY: {
-                final boolean setVisible = msg.arg1 != 0;
-                final ClientState clientState = (ClientState) msg.obj;
-                try {
-                    clientState.client.applyImeVisibility(setVisible);
-                } catch (RemoteException e) {
-                    Slog.w(TAG, "Got RemoteException sending "
-                            + "applyImeVisibility(" + setVisible + ") notification to pid="
-                            + clientState.pid + " uid=" + clientState.uid);
-                }
-                return true;
-            }
 
             // --------------------------------------------------------------
             case MSG_HARD_KEYBOARD_SWITCH_CHANGED:
@@ -4845,6 +4830,9 @@
                 setInputMethodEnabledLocked(defaultImiId, true);
             }
         }
+
+        updateDefaultVoiceImeIfNeededLocked();
+
         // Here is not the perfect place to reset the switching controller. Ideally
         // mSwitchingController and mSettings should be able to share the same state.
         // TODO: Make sure that mSwitchingController and mSettings are sharing the
@@ -4857,6 +4845,37 @@
                 mSettings.getCurrentUserId(), 0 /* unused */, inputMethodList).sendToTarget();
     }
 
+    @GuardedBy("mMethodMap")
+    private void updateDefaultVoiceImeIfNeededLocked() {
+        final String systemSpeechRecognizer =
+                mContext.getString(com.android.internal.R.string.config_systemSpeechRecognizer);
+        final String currentDefaultVoiceImeId = mSettings.getDefaultVoiceInputMethod();
+        final InputMethodInfo newSystemVoiceIme = InputMethodUtils.chooseSystemVoiceIme(
+                mMethodMap, systemSpeechRecognizer, currentDefaultVoiceImeId);
+        if (newSystemVoiceIme == null) {
+            if (DEBUG) {
+                Slog.i(TAG, "Found no valid default Voice IME. If the user is still locked,"
+                        + " this may be expected.");
+            }
+            // Clear DEFAULT_VOICE_INPUT_METHOD when necessary.  Note that InputMethodSettings
+            // does not update the actual Secure Settings until the user is unlocked.
+            if (!TextUtils.isEmpty(currentDefaultVoiceImeId)) {
+                mSettings.putDefaultVoiceInputMethod("");
+                // We don't support disabling the voice ime when a package is removed from the
+                // config.
+            }
+            return;
+        }
+        if (TextUtils.equals(currentDefaultVoiceImeId, newSystemVoiceIme.getId())) {
+            return;
+        }
+        if (DEBUG) {
+            Slog.i(TAG, "Enabling the default Voice IME:" + newSystemVoiceIme);
+        }
+        setInputMethodEnabledLocked(newSystemVoiceIme.getId(), true);
+        mSettings.putDefaultVoiceInputMethod(newSystemVoiceIme.getId());
+    }
+
     // ----------------------------------------------------------------------
 
     private void showInputMethodAndSubtypeEnabler(String inputMethodId) {
@@ -5240,26 +5259,71 @@
         }
     }
 
+    private final PriorityDump.PriorityDumper mPriorityDumper = new PriorityDump.PriorityDumper() {
+        /**
+         * {@inheritDoc}
+         */
+        @BinderThread
+        @Override
+        public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args,
+                boolean asProto) {
+            if (asProto) {
+                dumpAsProtoNoCheck(fd);
+            } else {
+                dumpAsStringNoCheck(fd, pw, args, true /* isCritical */);
+            }
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @BinderThread
+        @Override
+        public void dumpHigh(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
+            dumpNormal(fd, pw, args, asProto);
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @BinderThread
+        @Override
+        public void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
+            if (asProto) {
+                dumpAsProtoNoCheck(fd);
+            } else {
+                dumpAsStringNoCheck(fd, pw, args, false /* isCritical */);
+            }
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @BinderThread
+        @Override
+        public void dump(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
+            dumpNormal(fd, pw, args, asProto);
+        }
+
+        @BinderThread
+        private void dumpAsProtoNoCheck(FileDescriptor fd) {
+            final ProtoOutputStream proto = new ProtoOutputStream(fd);
+            dumpDebug(proto, InputMethodManagerServiceTraceProto.INPUT_METHOD_MANAGER_SERVICE);
+            proto.flush();
+        }
+    };
+
+    @BinderThread
     @Override
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
 
-        if (ArrayUtils.contains(args, PROTO_ARG)) {
-            final ImeTracing imeTracing = ImeTracing.getInstance();
-            if (imeTracing.isEnabled()) {
-                imeTracing.stopTrace(null, false /* writeToFile */);
-                BackgroundThread.getHandler().post(() -> {
-                    imeTracing.writeTracesToFiles();
-                    imeTracing.startTrace(null);
-                });
-            }
+        PriorityDump.dump(mPriorityDumper, fd, pw, args);
+    }
 
-            final ProtoOutputStream proto = new ProtoOutputStream(fd);
-            dumpDebug(proto, InputMethodManagerServiceTraceProto.INPUT_METHOD_MANAGER_SERVICE);
-            proto.flush();
-            return;
-        }
-
+    @BinderThread
+    private void dumpAsStringNoCheck(FileDescriptor fd, PrintWriter pw, String[] args,
+            boolean isCritical) {
         IInputMethod method;
         ClientState client;
         ClientState focusedWindowClient;
@@ -5323,6 +5387,11 @@
             mSoftInputShowHideHistory.dump(pw, "   ");
         }
 
+        // Exit here for critical dump, as remaining sections require IPCs to other processes.
+        if (isCritical) {
+            return;
+        }
+
         p.println(" ");
         if (client != null) {
             pw.flush();
@@ -5831,7 +5900,7 @@
     }
 
     /**
-     * Handles {@code adb shell ime tracing start/stop}.
+     * Handles {@code adb shell cmd input_method tracing start/stop/save-for-bugreport}.
      * @param shellCommand {@link ShellCommand} object that is handling this command.
      * @return Exit code of the command.
      */
@@ -5843,16 +5912,19 @@
         switch (cmd) {
             case "start":
                 ImeTracing.getInstance().getInstance().startTrace(pw);
-                break;
+                break;  // proceed to the next step to update the IME client processes.
             case "stop":
                 ImeTracing.getInstance().stopTrace(pw);
-                break;
+                break;  // proceed to the next step to update the IME client processes.
+            case "save-for-bugreport":
+                ImeTracing.getInstance().saveForBugreport(pw);
+                return ShellCommandResult.SUCCESS;  // no need to update the IME client processes.
             default:
                 pw.println("Unknown command: " + cmd);
                 pw.println("Input method trace options:");
                 pw.println("  start: Start tracing");
                 pw.println("  stop: Stop tracing");
-                return ShellCommandResult.FAILURE;
+                return ShellCommandResult.FAILURE;  // no need to update the IME client processes.
         }
         boolean isImeTraceEnabled = ImeTracing.getInstance().isEnabled();
         ArrayMap<IBinder, ClientState> clients;
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodUtils.java b/services/core/java/com/android/server/inputmethod/InputMethodUtils.java
index 0e908d4..ac3c31d 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodUtils.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodUtils.java
@@ -337,6 +337,52 @@
         return getDefaultEnabledImes(context, imis, false /* onlyMinimum */);
     }
 
+    /**
+     * Chooses an eligible system voice IME from the given IMEs.
+     *
+     * @param methodMap Map from the IME ID to {@link InputMethodInfo}.
+     * @param systemSpeechRecognizerPackageName System speech recognizer configured by the system
+     *                                          config.
+     * @param currentDefaultVoiceImeId IME ID currently set to
+     *                                 {@link Settings.Secure#DEFAULT_VOICE_INPUT_METHOD}
+     * @return {@link InputMethodInfo} that is found in {@code methodMap} and most suitable for
+     *                                 the system voice IME.
+     */
+    @Nullable
+    static InputMethodInfo chooseSystemVoiceIme(
+            @NonNull ArrayMap<String, InputMethodInfo> methodMap,
+            @Nullable String systemSpeechRecognizerPackageName,
+            @Nullable String currentDefaultVoiceImeId) {
+        if (TextUtils.isEmpty(systemSpeechRecognizerPackageName)) {
+            return null;
+        }
+        final InputMethodInfo defaultVoiceIme = methodMap.get(currentDefaultVoiceImeId);
+        // If the config matches the package of the setting, use the current one.
+        if (defaultVoiceIme != null && defaultVoiceIme.isSystem()
+                && defaultVoiceIme.getPackageName().equals(systemSpeechRecognizerPackageName)) {
+            return defaultVoiceIme;
+        }
+        InputMethodInfo firstMatchingIme = null;
+        final int methodCount = methodMap.size();
+        for (int i = 0; i < methodCount; ++i) {
+            final InputMethodInfo imi = methodMap.valueAt(i);
+            if (!imi.isSystem()) {
+                continue;
+            }
+            if (!TextUtils.equals(imi.getPackageName(), systemSpeechRecognizerPackageName)) {
+                continue;
+            }
+            if (firstMatchingIme != null) {
+                Slog.e(TAG, "At most one InputMethodService can be published in "
+                        + "systemSpeechRecognizer: " + systemSpeechRecognizerPackageName
+                        + ". Ignoring all of them.");
+                return null;
+            }
+            firstMatchingIme = imi;
+        }
+        return firstMatchingIme;
+    }
+
     static boolean containsSubtypeOf(InputMethodInfo imi, @Nullable Locale locale,
             boolean checkCountry, String mode) {
         if (locale == null) {
@@ -1233,6 +1279,22 @@
             return imi;
         }
 
+        void putDefaultVoiceInputMethod(String imeId) {
+            if (DEBUG) {
+                Slog.d(TAG, "putDefaultVoiceInputMethodStr: " + imeId + ", " + mCurrentUserId);
+            }
+            putString(Settings.Secure.DEFAULT_VOICE_INPUT_METHOD, imeId);
+        }
+
+        @Nullable
+        String getDefaultVoiceInputMethod() {
+            final String imi = getString(Settings.Secure.DEFAULT_VOICE_INPUT_METHOD, null);
+            if (DEBUG) {
+                Slog.d(TAG, "getDefaultVoiceInputMethodStr: " + imi);
+            }
+            return imi;
+        }
+
         boolean isSubtypeSelected() {
             return getSelectedInputMethodSubtypeHashCode() != NOT_A_SUBTYPE_ID;
         }
diff --git a/services/core/java/com/android/server/location/GeocoderProxy.java b/services/core/java/com/android/server/location/GeocoderProxy.java
index c93c4b1..dc3596b 100644
--- a/services/core/java/com/android/server/location/GeocoderProxy.java
+++ b/services/core/java/com/android/server/location/GeocoderProxy.java
@@ -24,6 +24,7 @@
 import android.os.IBinder;
 import android.os.RemoteException;
 
+import com.android.server.servicewatcher.CurrentUserServiceSupplier;
 import com.android.server.servicewatcher.ServiceWatcher;
 
 import java.util.Collections;
@@ -54,9 +55,11 @@
     private final ServiceWatcher mServiceWatcher;
 
     private GeocoderProxy(Context context) {
-        mServiceWatcher = new ServiceWatcher(context, SERVICE_ACTION, null, null,
-                com.android.internal.R.bool.config_enableGeocoderOverlay,
-                com.android.internal.R.string.config_geocoderProviderPackageName);
+        mServiceWatcher = ServiceWatcher.create(context, "GeocoderProxy",
+                new CurrentUserServiceSupplier(context, SERVICE_ACTION,
+                        com.android.internal.R.bool.config_enableGeocoderOverlay,
+                        com.android.internal.R.string.config_geocoderProviderPackageName),
+                null);
     }
 
     private boolean register() {
@@ -72,7 +75,7 @@
      */
     public void getFromLocation(double latitude, double longitude, int maxResults,
             GeocoderParams params, IGeocodeListener listener) {
-        mServiceWatcher.runOnBinder(new ServiceWatcher.BinderRunner() {
+        mServiceWatcher.runOnBinder(new ServiceWatcher.BinderOperation() {
             @Override
             public void run(IBinder binder) throws RemoteException {
                 IGeocodeProvider provider = IGeocodeProvider.Stub.asInterface(binder);
@@ -97,7 +100,7 @@
             double lowerLeftLatitude, double lowerLeftLongitude,
             double upperRightLatitude, double upperRightLongitude, int maxResults,
             GeocoderParams params, IGeocodeListener listener) {
-        mServiceWatcher.runOnBinder(new ServiceWatcher.BinderRunner() {
+        mServiceWatcher.runOnBinder(new ServiceWatcher.BinderOperation() {
             @Override
             public void run(IBinder binder) throws RemoteException {
                 IGeocodeProvider provider = IGeocodeProvider.Stub.asInterface(binder);
diff --git a/services/core/java/com/android/server/location/HardwareActivityRecognitionProxy.java b/services/core/java/com/android/server/location/HardwareActivityRecognitionProxy.java
index e1c8700..6ac6e77 100644
--- a/services/core/java/com/android/server/location/HardwareActivityRecognitionProxy.java
+++ b/services/core/java/com/android/server/location/HardwareActivityRecognitionProxy.java
@@ -25,15 +25,15 @@
 import android.os.RemoteException;
 import android.util.Log;
 
+import com.android.server.servicewatcher.CurrentUserServiceSupplier;
+import com.android.server.servicewatcher.CurrentUserServiceSupplier.BoundServiceInfo;
 import com.android.server.servicewatcher.ServiceWatcher;
-import com.android.server.servicewatcher.ServiceWatcher.BoundService;
+import com.android.server.servicewatcher.ServiceWatcher.ServiceListener;
 
 /**
  * Proxy class to bind GmsCore to the ActivityRecognitionHardware.
- *
- * @hide
  */
-public class HardwareActivityRecognitionProxy {
+public class HardwareActivityRecognitionProxy implements ServiceListener<BoundServiceInfo> {
 
     private static final String TAG = "ARProxy";
     private static final String SERVICE_ACTION =
@@ -66,12 +66,16 @@
             mInstance = null;
         }
 
-        mServiceWatcher = new ServiceWatcher(context,
-                SERVICE_ACTION,
-                this::onBind,
-                null,
-                com.android.internal.R.bool.config_enableActivityRecognitionHardwareOverlay,
-                com.android.internal.R.string.config_activityRecognitionHardwarePackageName);
+        int useOverlayResId =
+                com.android.internal.R.bool.config_enableActivityRecognitionHardwareOverlay;
+        int nonOverlayPackageResId =
+                com.android.internal.R.string.config_activityRecognitionHardwarePackageName;
+
+        mServiceWatcher = ServiceWatcher.create(context,
+                "HardwareActivityRecognitionProxy",
+                new CurrentUserServiceSupplier(context, SERVICE_ACTION, useOverlayResId,
+                        nonOverlayPackageResId),
+                this);
     }
 
     private boolean register() {
@@ -82,7 +86,8 @@
         return resolves;
     }
 
-    private void onBind(IBinder binder, BoundService service) throws RemoteException {
+    @Override
+    public void onBind(IBinder binder, BoundServiceInfo boundServiceInfo) throws RemoteException {
         String descriptor = binder.getInterfaceDescriptor();
 
         if (IActivityRecognitionHardwareWatcher.class.getCanonicalName().equals(descriptor)) {
@@ -99,4 +104,7 @@
             Log.e(TAG, "Unknown descriptor: " + descriptor);
         }
     }
+
+    @Override
+    public void onUnbind() {}
 }
diff --git a/services/core/java/com/android/server/location/LocationManagerService.java b/services/core/java/com/android/server/location/LocationManagerService.java
index 2920ddb..864aa33 100644
--- a/services/core/java/com/android/server/location/LocationManagerService.java
+++ b/services/core/java/com/android/server/location/LocationManagerService.java
@@ -31,6 +31,7 @@
 
 import static com.android.server.location.LocationPermissions.PERMISSION_COARSE;
 import static com.android.server.location.LocationPermissions.PERMISSION_FINE;
+import static com.android.server.location.eventlog.LocationEventLog.EVENT_LOG;
 
 import static java.util.concurrent.TimeUnit.NANOSECONDS;
 
@@ -158,10 +159,9 @@
 
         public Lifecycle(Context context) {
             super(context);
-            LocationEventLog eventLog = new LocationEventLog();
             mUserInfoHelper = new LifecycleUserInfoHelper(context);
-            mSystemInjector = new SystemInjector(context, mUserInfoHelper, eventLog);
-            mService = new LocationManagerService(context, mSystemInjector, eventLog);
+            mSystemInjector = new SystemInjector(context, mUserInfoHelper);
+            mService = new LocationManagerService(context, mSystemInjector);
         }
 
         @Override
@@ -233,7 +233,6 @@
 
     private final Context mContext;
     private final Injector mInjector;
-    private final LocationEventLog mEventLog;
     private final LocalService mLocalService;
 
     private final GeofenceManager mGeofenceManager;
@@ -261,18 +260,20 @@
     @GuardedBy("mLock")
     private @Nullable OnProviderLocationTagsChangeListener mOnProviderLocationTagsChangeListener;
 
-    LocationManagerService(Context context, Injector injector, LocationEventLog eventLog) {
+    LocationManagerService(Context context, Injector injector) {
         mContext = context.createAttributionContext(ATTRIBUTION_TAG);
         mInjector = injector;
-        mEventLog = eventLog;
         mLocalService = new LocalService();
         LocalServices.addService(LocationManagerInternal.class, mLocalService);
 
         mGeofenceManager = new GeofenceManager(mContext, injector);
 
+        mInjector.getSettingsHelper().addOnLocationEnabledChangedListener(
+                this::onLocationModeChanged);
+
         // set up passive provider first since it will be required for all other location providers,
         // which are loaded later once the system is ready.
-        mPassiveManager = new PassiveLocationProviderManager(mContext, injector, mEventLog);
+        mPassiveManager = new PassiveLocationProviderManager(mContext, injector);
         addLocationProviderManager(mPassiveManager, new PassiveLocationProvider(mContext));
 
         // TODO: load the gps provider here as well, which will require refactoring
@@ -313,7 +314,7 @@
             }
 
             LocationProviderManager manager = new LocationProviderManager(mContext, mInjector,
-                    mEventLog, providerName, mPassiveManager);
+                    providerName, mPassiveManager);
             addLocationProviderManager(manager, null);
             return manager;
         }
@@ -335,7 +336,7 @@
                             Settings.Global.LOCATION_ENABLE_STATIONARY_THROTTLE, 1) != 0;
                     if (enableStationaryThrottling) {
                         realProvider = new StationaryThrottlingLocationProvider(manager.getName(),
-                                mInjector, realProvider, mEventLog);
+                                mInjector, realProvider);
                     }
                 }
                 manager.setRealProvider(realProvider);
@@ -355,9 +356,6 @@
     }
 
     void onSystemReady() {
-        mInjector.getSettingsHelper().addOnLocationEnabledChangedListener(
-                this::onLocationModeChanged);
-
         if (Build.IS_DEBUGGABLE) {
             // on debug builds, watch for location noteOps while location is off. there are some
             // scenarios (emergency location) where this is expected, but generally this should
@@ -380,12 +378,13 @@
         // provider has unfortunate hard dependencies on the network provider
         ProxyLocationProvider networkProvider = ProxyLocationProvider.create(
                 mContext,
+                NETWORK_PROVIDER,
                 ACTION_NETWORK_PROVIDER,
                 com.android.internal.R.bool.config_enableNetworkLocationOverlay,
                 com.android.internal.R.string.config_networkLocationProviderPackageName);
         if (networkProvider != null) {
             LocationProviderManager networkManager = new LocationProviderManager(mContext,
-                    mInjector, mEventLog, NETWORK_PROVIDER, mPassiveManager);
+                    mInjector, NETWORK_PROVIDER, mPassiveManager);
             addLocationProviderManager(networkManager, networkProvider);
         } else {
             Log.w(TAG, "no network location provider found");
@@ -399,12 +398,13 @@
 
         ProxyLocationProvider fusedProvider = ProxyLocationProvider.create(
                 mContext,
+                FUSED_PROVIDER,
                 ACTION_FUSED_PROVIDER,
                 com.android.internal.R.bool.config_enableFusedLocationOverlay,
                 com.android.internal.R.string.config_fusedLocationProviderPackageName);
         if (fusedProvider != null) {
             LocationProviderManager fusedManager = new LocationProviderManager(mContext, mInjector,
-                    mEventLog, FUSED_PROVIDER, mPassiveManager);
+                    FUSED_PROVIDER, mPassiveManager);
             addLocationProviderManager(fusedManager, fusedProvider);
         } else {
             Log.wtf(TAG, "no fused location provider found");
@@ -419,7 +419,7 @@
             mGnssManagerService.onSystemReady();
 
             LocationProviderManager gnssManager = new LocationProviderManager(mContext, mInjector,
-                    mEventLog, GPS_PROVIDER, mPassiveManager);
+                    GPS_PROVIDER, mPassiveManager);
             addLocationProviderManager(gnssManager, mGnssManagerService.getGnssLocationProvider());
         }
 
@@ -476,7 +476,7 @@
             Log.d(TAG, "[u" + userId + "] location enabled = " + enabled);
         }
 
-        mEventLog.logLocationEnabled(userId, enabled);
+        EVENT_LOG.logLocationEnabled(userId, enabled);
 
         Intent intent = new Intent(LocationManager.MODE_CHANGED_ACTION)
                 .putExtra(LocationManager.EXTRA_LOCATION_ENABLED, enabled)
@@ -1268,7 +1268,7 @@
 
                 ipw.println("Event Log:");
                 ipw.increaseIndent();
-                mEventLog.iterate(manager.getName(), ipw::println);
+                EVENT_LOG.iterate(manager.getName(), ipw::println);
                 ipw.decreaseIndent();
                 return;
             }
@@ -1313,7 +1313,7 @@
         ipw.println("Historical Aggregate Location Provider Data:");
         ipw.increaseIndent();
         ArrayMap<String, ArrayMap<CallerIdentity, LocationEventLog.AggregateStats>> aggregateStats =
-                mEventLog.copyAggregateStats();
+                EVENT_LOG.copyAggregateStats();
         for (int i = 0; i < aggregateStats.size(); i++) {
             ipw.print(aggregateStats.keyAt(i));
             ipw.println(":");
@@ -1344,7 +1344,7 @@
 
         ipw.println("Event Log:");
         ipw.increaseIndent();
-        mEventLog.iterate(ipw::println);
+        EVENT_LOG.iterate(ipw::println);
         ipw.decreaseIndent();
     }
 
@@ -1456,7 +1456,7 @@
         @GuardedBy("this")
         private boolean mSystemReady;
 
-        SystemInjector(Context context, UserInfoHelper userInfoHelper, LocationEventLog eventLog) {
+        SystemInjector(Context context, UserInfoHelper userInfoHelper) {
             mContext = context;
 
             mUserInfoHelper = userInfoHelper;
@@ -1466,7 +1466,7 @@
                     mAppOpsHelper);
             mSettingsHelper = new SystemSettingsHelper(context);
             mAppForegroundHelper = new SystemAppForegroundHelper(context);
-            mLocationPowerSaveModeHelper = new SystemLocationPowerSaveModeHelper(context, eventLog);
+            mLocationPowerSaveModeHelper = new SystemLocationPowerSaveModeHelper(context);
             mScreenInteractiveHelper = new SystemScreenInteractiveHelper(context);
             mDeviceStationaryHelper = new SystemDeviceStationaryHelper();
             mDeviceIdleHelper = new SystemDeviceIdleHelper(context);
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubService.java b/services/core/java/com/android/server/location/contexthub/ContextHubService.java
index c44089b..4d302b1 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubService.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubService.java
@@ -259,13 +259,16 @@
             BroadcastReceiver wifiReceiver = new BroadcastReceiver() {
                 @Override
                 public void onReceive(Context context, Intent intent) {
-                    if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(intent.getAction())) {
+                    if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(intent.getAction())
+                            || WifiManager.ACTION_WIFI_SCAN_AVAILABILITY_CHANGED.equals(
+                                intent.getAction())) {
                         sendWifiSettingUpdate(false /* forceUpdate */);
                     }
                 }
             };
             IntentFilter filter = new IntentFilter();
             filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
+            filter.addAction(WifiManager.ACTION_WIFI_SCAN_AVAILABILITY_CHANGED);
             mContext.registerReceiver(wifiReceiver, filter);
 
             mContext.getContentResolver().registerContentObserver(
@@ -298,7 +301,7 @@
             mSensorPrivacyManagerInternal.addSensorPrivacyListenerForAllUsers(
                     SensorPrivacyManager.Sensors.MICROPHONE, (userId, enabled) -> {
                         if (userId == getCurrentUserId()) {
-                            Log.d(TAG, "User: " + userId + " enabled: " + enabled);
+                            Log.d(TAG, "User: " + userId + "mic privacy: " + enabled);
                             sendMicrophoneDisableSettingUpdate(enabled);
                         }
                 });
@@ -691,6 +694,7 @@
             sendLocationSettingUpdate();
             sendWifiSettingUpdate(true /* forceUpdate */);
             sendAirplaneModeSettingUpdate();
+            sendMicrophoneDisableSettingUpdateForCurrentUser();
 
             mTransactionManager.onHubReset();
             queryNanoAppsInternal(contextHubId);
@@ -1123,6 +1127,7 @@
      */
     public void onUserChanged() {
         Log.d(TAG, "User changed to id: " + getCurrentUserId());
+        sendLocationSettingUpdate();
         sendMicrophoneDisableSettingUpdateForCurrentUser();
     }
 }
diff --git a/services/core/java/com/android/server/location/contexthub/IContextHubWrapper.java b/services/core/java/com/android/server/location/contexthub/IContextHubWrapper.java
index 3245fdf..7be47a4 100644
--- a/services/core/java/com/android/server/location/contexthub/IContextHubWrapper.java
+++ b/services/core/java/com/android/server/location/contexthub/IContextHubWrapper.java
@@ -324,8 +324,11 @@
         }
 
         public void onMicrophoneDisableSettingChanged(boolean enabled) {
-            sendSettingChanged(android.hardware.contexthub.V1_2.Setting.GLOBAL_MIC_DISABLE,
-                    enabled ? SettingValue.ENABLED : SettingValue.DISABLED);
+            // The SensorPrivacyManager reports if microphone privacy was enabled,
+            // which translates to microphone access being disabled (and vice-versa).
+            // With this in mind, we flip the argument before piping it to CHRE.
+            sendSettingChanged(android.hardware.contexthub.V1_2.Setting.MICROPHONE,
+                    enabled ? SettingValue.DISABLED : SettingValue.ENABLED);
         }
 
         private void sendSettingChanged(byte setting, byte newValue) {
diff --git a/services/core/java/com/android/server/location/eventlog/LocationEventLog.java b/services/core/java/com/android/server/location/eventlog/LocationEventLog.java
index 29ce378..045e06d0 100644
--- a/services/core/java/com/android/server/location/eventlog/LocationEventLog.java
+++ b/services/core/java/com/android/server/location/eventlog/LocationEventLog.java
@@ -44,6 +44,8 @@
 /** In memory event log for location events. */
 public class LocationEventLog extends LocalEventLog {
 
+    public static final LocationEventLog EVENT_LOG = new LocationEventLog();
+
     private static int getLogSize() {
         if (Build.IS_DEBUGGABLE || D) {
             return 500;
@@ -52,16 +54,17 @@
         }
     }
 
-    private static final int EVENT_LOCATION_ENABLED = 1;
-    private static final int EVENT_PROVIDER_ENABLED = 2;
-    private static final int EVENT_PROVIDER_MOCKED = 3;
-    private static final int EVENT_PROVIDER_REGISTER_CLIENT = 4;
-    private static final int EVENT_PROVIDER_UNREGISTER_CLIENT = 5;
-    private static final int EVENT_PROVIDER_UPDATE_REQUEST = 6;
-    private static final int EVENT_PROVIDER_RECEIVE_LOCATION = 7;
-    private static final int EVENT_PROVIDER_DELIVER_LOCATION = 8;
-    private static final int EVENT_PROVIDER_STATIONARY_THROTTLED = 9;
-    private static final int EVENT_LOCATION_POWER_SAVE_MODE_CHANGE = 10;
+    private static final int EVENT_USER_SWITCHED = 1;
+    private static final int EVENT_LOCATION_ENABLED = 2;
+    private static final int EVENT_PROVIDER_ENABLED = 3;
+    private static final int EVENT_PROVIDER_MOCKED = 4;
+    private static final int EVENT_PROVIDER_REGISTER_CLIENT = 5;
+    private static final int EVENT_PROVIDER_UNREGISTER_CLIENT = 6;
+    private static final int EVENT_PROVIDER_UPDATE_REQUEST = 7;
+    private static final int EVENT_PROVIDER_RECEIVE_LOCATION = 8;
+    private static final int EVENT_PROVIDER_DELIVER_LOCATION = 9;
+    private static final int EVENT_PROVIDER_STATIONARY_THROTTLED = 10;
+    private static final int EVENT_LOCATION_POWER_SAVE_MODE_CHANGE = 11;
 
     @GuardedBy("mAggregateStats")
     private final ArrayMap<String, ArrayMap<CallerIdentity, AggregateStats>> mAggregateStats;
@@ -90,19 +93,24 @@
                 packageMap = new ArrayMap<>(2);
                 mAggregateStats.put(provider, packageMap);
             }
-            CallerIdentity stripped = identity.stripListenerId();
-            AggregateStats stats = packageMap.get(stripped);
+            CallerIdentity aggregate = CallerIdentity.forAggregation(identity);
+            AggregateStats stats = packageMap.get(aggregate);
             if (stats == null) {
                 stats = new AggregateStats();
-                packageMap.put(stripped, stats);
+                packageMap.put(aggregate, stats);
             }
             return stats;
         }
     }
 
+    /** Logs a user switched event. */
+    public void logUserSwitched(int userIdFrom, int userIdTo) {
+        addLogEvent(EVENT_USER_SWITCHED, userIdFrom, userIdTo);
+    }
+
     /** Logs a location enabled/disabled event. */
     public void logLocationEnabled(int userId, boolean enabled) {
-        addLogEvent(EVENT_LOCATION_POWER_SAVE_MODE_CHANGE, userId, enabled);
+        addLogEvent(EVENT_LOCATION_ENABLED, userId, enabled);
     }
 
     /** Logs a location provider enabled/disabled event. */
@@ -183,8 +191,10 @@
     @Override
     protected LogEvent createLogEvent(long timeDelta, int event, Object... args) {
         switch (event) {
+            case EVENT_USER_SWITCHED:
+                return new UserSwitchedEvent(timeDelta, (Integer) args[0], (Integer) args[1]);
             case EVENT_LOCATION_ENABLED:
-                return new LocationEnabledEvent(timeDelta, (Integer) args[1], (Boolean) args[2]);
+                return new LocationEnabledEvent(timeDelta, (Integer) args[0], (Boolean) args[1]);
             case EVENT_PROVIDER_ENABLED:
                 return new ProviderEnabledEvent(timeDelta, (String) args[0], (Integer) args[1],
                         (Boolean) args[2]);
@@ -397,6 +407,23 @@
         }
     }
 
+    private static final class UserSwitchedEvent extends LogEvent {
+
+        private final int mUserIdFrom;
+        private final int mUserIdTo;
+
+        UserSwitchedEvent(long timeDelta, int userIdFrom, int userIdTo) {
+            super(timeDelta);
+            mUserIdFrom = userIdFrom;
+            mUserIdTo = userIdTo;
+        }
+
+        @Override
+        public String getLogString() {
+            return "current user switched from u" + mUserIdFrom + " to u" + mUserIdTo;
+        }
+    }
+
     private static final class LocationEnabledEvent extends LogEvent {
 
         private final int mUserId;
@@ -410,7 +437,7 @@
 
         @Override
         public String getLogString() {
-            return "[u" + mUserId + "] location setting " + (mEnabled ? "enabled" : "disabled");
+            return "location [u" + mUserId + "] " + (mEnabled ? "enabled" : "disabled");
         }
     }
 
diff --git a/services/core/java/com/android/server/location/geofence/GeofenceProxy.java b/services/core/java/com/android/server/location/geofence/GeofenceProxy.java
index c707149..90b446e 100644
--- a/services/core/java/com/android/server/location/geofence/GeofenceProxy.java
+++ b/services/core/java/com/android/server/location/geofence/GeofenceProxy.java
@@ -29,14 +29,17 @@
 import android.os.UserHandle;
 import android.util.Log;
 
+import com.android.server.servicewatcher.CurrentUserServiceSupplier;
+import com.android.server.servicewatcher.CurrentUserServiceSupplier.BoundServiceInfo;
 import com.android.server.servicewatcher.ServiceWatcher;
+import com.android.server.servicewatcher.ServiceWatcher.ServiceListener;
 
 import java.util.Objects;
 
 /**
  * @hide
  */
-public final class GeofenceProxy {
+public final class GeofenceProxy implements ServiceListener<BoundServiceInfo> {
 
     private static final String TAG = "GeofenceProxy";
     private static final String SERVICE_ACTION = "com.android.location.service.GeofenceProvider";
@@ -62,10 +65,12 @@
 
     private GeofenceProxy(Context context, IGpsGeofenceHardware gpsGeofence) {
         mGpsGeofenceHardware = Objects.requireNonNull(gpsGeofence);
-        mServiceWatcher = new ServiceWatcher(context, SERVICE_ACTION,
-                (binder, service) -> updateGeofenceHardware(binder), null,
-                com.android.internal.R.bool.config_enableGeofenceOverlay,
-                com.android.internal.R.string.config_geofenceProviderPackageName);
+        mServiceWatcher = ServiceWatcher.create(context,
+                "GeofenceProxy",
+                new CurrentUserServiceSupplier(context, SERVICE_ACTION,
+                        com.android.internal.R.bool.config_enableGeofenceOverlay,
+                        com.android.internal.R.string.config_geofenceProviderPackageName),
+                this);
 
         mGeofenceHardware = null;
     }
@@ -87,6 +92,14 @@
         return resolves;
     }
 
+    @Override
+    public void onBind(IBinder binder, BoundServiceInfo boundServiceInfo) throws RemoteException {
+        updateGeofenceHardware(binder);
+    }
+
+    @Override
+    public void onUnbind() {}
+
     private class GeofenceProxyServiceConnection implements ServiceConnection {
 
         GeofenceProxyServiceConnection() {}
diff --git a/services/core/java/com/android/server/location/gnss/GnssManagerService.java b/services/core/java/com/android/server/location/gnss/GnssManagerService.java
index bcdfed4..21946ca 100644
--- a/services/core/java/com/android/server/location/gnss/GnssManagerService.java
+++ b/services/core/java/com/android/server/location/gnss/GnssManagerService.java
@@ -81,7 +81,7 @@
         mGnssNative = gnssNative;
 
         mGnssMetrics = new GnssMetrics(mContext, IBatteryStats.Stub.asInterface(
-                ServiceManager.getService(BatteryStats.SERVICE_NAME)));
+                ServiceManager.getService(BatteryStats.SERVICE_NAME)), mGnssNative);
 
         mGnssLocationProvider = new GnssLocationProvider(mContext, injector, mGnssNative,
                 mGnssMetrics);
diff --git a/services/core/java/com/android/server/location/gnss/GnssMetrics.java b/services/core/java/com/android/server/location/gnss/GnssMetrics.java
index c7d8144..dbc903d 100644
--- a/services/core/java/com/android/server/location/gnss/GnssMetrics.java
+++ b/services/core/java/com/android/server/location/gnss/GnssMetrics.java
@@ -35,6 +35,7 @@
 import com.android.internal.location.nano.GnssLogsProto.PowerMetrics;
 import com.android.internal.util.ConcurrentUtils;
 import com.android.internal.util.FrameworkStatsLog;
+import com.android.server.location.gnss.hal.GnssNative;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -52,11 +53,14 @@
 
     /** Default time between location fixes (in millisecs) */
     private static final int DEFAULT_TIME_BETWEEN_FIXES_MILLISECS = 1000;
+    private static final int CONVERT_MILLI_TO_MICRO = 1000;
+    private static final int VENDOR_SPECIFIC_POWER_MODES_SIZE = 10;
 
     /** Frequency range of GPS L5, Galileo E5a, QZSS J5 frequency band */
     private static final double L5_CARRIER_FREQ_RANGE_LOW_HZ = 1164 * 1e6;
     private static final double L5_CARRIER_FREQ_RANGE_HIGH_HZ = 1189 * 1e6;
 
+
     private long mLogStartInElapsedRealtimeMs;
 
     GnssPowerMetrics mGnssPowerMetrics;
@@ -88,8 +92,10 @@
     long mL5SvStatusReportsUsedInFix;
 
     private final StatsManager mStatsManager;
+    private final GnssNative mGnssNative;
 
-    public GnssMetrics(Context context, IBatteryStats stats) {
+    public GnssMetrics(Context context, IBatteryStats stats, GnssNative gnssNative) {
+        mGnssNative = gnssNative;
         mGnssPowerMetrics = new GnssPowerMetrics(stats);
         mLocationFailureStatistics = new Statistics();
         mTimeToFirstFixSecStatistics = new Statistics();
@@ -189,8 +195,8 @@
     }
 
     /**
-    * Logs sv status data
-    */
+     * Logs sv status data
+     */
     public void logSvStatus(GnssStatus status) {
         boolean isL5;
         // Calculate SvStatus Information
@@ -216,8 +222,8 @@
     }
 
     /**
-    * Logs CN0 when at least 4 SVs are available L5 Only
-    */
+     * Logs CN0 when at least 4 SVs are available L5 Only
+     */
     private void logCn0L5(GnssStatus gnssStatus) {
         if (gnssStatus.getSatelliteCount() == 0) {
             return;
@@ -432,7 +438,8 @@
         private double mSumSquare;
         private long mLongSum;
 
-        Statistics() {}
+        Statistics() {
+        }
 
         /** Resets statistics */
         public synchronized void reset() {
@@ -498,7 +505,7 @@
         GnssPowerMetrics(IBatteryStats stats) {
             mBatteryStats = stats;
             // Used to initialize the variable to a very small value (unachievable in practice)
-          // so that
+            // so that
             // the first CNO report will trigger an update to BatteryStats
             mLastAverageCn0 = -100.0;
             mLastSignalLevel = GnssSignalQuality.GNSS_SIGNAL_QUALITY_UNKNOWN;
@@ -585,6 +592,10 @@
                 FrameworkStatsLog.GNSS_STATS,
                 null, // use default PullAtomMetadata values
                 ConcurrentUtils.DIRECT_EXECUTOR, pullAtomCallback);
+        mStatsManager.setPullAtomCallback(
+                FrameworkStatsLog.GNSS_POWER_STATS,
+                null, // use default PullAtomMetadata values
+                ConcurrentUtils.DIRECT_EXECUTOR, pullAtomCallback);
     }
 
     /**
@@ -593,26 +604,68 @@
      */
     private class StatsPullAtomCallbackImpl implements StatsManager.StatsPullAtomCallback {
 
-        StatsPullAtomCallbackImpl() {}
+        StatsPullAtomCallbackImpl() {
+        }
 
         @Override
         public int onPullAtom(int atomTag, List<StatsEvent> data) {
-            if (atomTag != FrameworkStatsLog.GNSS_STATS) {
+            if (atomTag == FrameworkStatsLog.GNSS_STATS) {
+                data.add(FrameworkStatsLog.buildStatsEvent(atomTag,
+                        mLocationFailureReportsStatistics.getCount(),
+                        mLocationFailureReportsStatistics.getLongSum(),
+                        mTimeToFirstFixMilliSReportsStatistics.getCount(),
+                        mTimeToFirstFixMilliSReportsStatistics.getLongSum(),
+                        mPositionAccuracyMetersReportsStatistics.getCount(),
+                        mPositionAccuracyMetersReportsStatistics.getLongSum(),
+                        mTopFourAverageCn0DbmHzReportsStatistics.getCount(),
+                        mTopFourAverageCn0DbmHzReportsStatistics.getLongSum(),
+                        mL5TopFourAverageCn0DbmHzReportsStatistics.getCount(),
+                        mL5TopFourAverageCn0DbmHzReportsStatistics.getLongSum(), mSvStatusReports,
+                        mSvStatusReportsUsedInFix, mL5SvStatusReports,
+                        mL5SvStatusReportsUsedInFix));
+            } else if (atomTag == FrameworkStatsLog.GNSS_POWER_STATS) {
+                mGnssNative.requestPowerStats();
+                GnssPowerStats gnssPowerStats = mGnssNative.getPowerStats();
+                if (gnssPowerStats == null) {
+                    return StatsManager.PULL_SKIP;
+                }
+                double[] otherModesEnergyMilliJoule = new double[VENDOR_SPECIFIC_POWER_MODES_SIZE];
+                double[] tempGnssPowerStatsOtherModes =
+                        gnssPowerStats.getOtherModesEnergyMilliJoule();
+                if (tempGnssPowerStatsOtherModes.length < VENDOR_SPECIFIC_POWER_MODES_SIZE) {
+                    System.arraycopy(tempGnssPowerStatsOtherModes, 0,
+                            otherModesEnergyMilliJoule, 0,
+                            tempGnssPowerStatsOtherModes.length);
+                } else {
+                    System.arraycopy(tempGnssPowerStatsOtherModes, 0,
+                            otherModesEnergyMilliJoule, 0,
+                            VENDOR_SPECIFIC_POWER_MODES_SIZE);
+                }
+                data.add(FrameworkStatsLog.buildStatsEvent(atomTag,
+                        (long) (gnssPowerStats.getElapsedRealtimeUncertaintyNanos()),
+                        (long) (gnssPowerStats.getTotalEnergyMilliJoule() * CONVERT_MILLI_TO_MICRO),
+                        (long) (gnssPowerStats.getSinglebandTrackingModeEnergyMilliJoule()
+                                * CONVERT_MILLI_TO_MICRO),
+                        (long) (gnssPowerStats.getMultibandTrackingModeEnergyMilliJoule()
+                                * CONVERT_MILLI_TO_MICRO),
+                        (long) (gnssPowerStats.getSinglebandAcquisitionModeEnergyMilliJoule()
+                                * CONVERT_MILLI_TO_MICRO),
+                        (long) (gnssPowerStats.getMultibandAcquisitionModeEnergyMilliJoule()
+                                * CONVERT_MILLI_TO_MICRO),
+                        (long) (otherModesEnergyMilliJoule[0] * CONVERT_MILLI_TO_MICRO),
+                        (long) (otherModesEnergyMilliJoule[1] * CONVERT_MILLI_TO_MICRO),
+                        (long) (otherModesEnergyMilliJoule[2] * CONVERT_MILLI_TO_MICRO),
+                        (long) (otherModesEnergyMilliJoule[3] * CONVERT_MILLI_TO_MICRO),
+                        (long) (otherModesEnergyMilliJoule[4] * CONVERT_MILLI_TO_MICRO),
+                        (long) (otherModesEnergyMilliJoule[5] * CONVERT_MILLI_TO_MICRO),
+                        (long) (otherModesEnergyMilliJoule[6] * CONVERT_MILLI_TO_MICRO),
+                        (long) (otherModesEnergyMilliJoule[7] * CONVERT_MILLI_TO_MICRO),
+                        (long) (otherModesEnergyMilliJoule[8] * CONVERT_MILLI_TO_MICRO),
+                        (long) (otherModesEnergyMilliJoule[9] * CONVERT_MILLI_TO_MICRO)));
+            } else {
                 throw new UnsupportedOperationException("Unknown tagId = " + atomTag);
             }
-            data.add(FrameworkStatsLog.buildStatsEvent(atomTag,
-                    mLocationFailureReportsStatistics.getCount(),
-                    mLocationFailureReportsStatistics.getLongSum(),
-                    mTimeToFirstFixMilliSReportsStatistics.getCount(),
-                    mTimeToFirstFixMilliSReportsStatistics.getLongSum(),
-                    mPositionAccuracyMetersReportsStatistics.getCount(),
-                    mPositionAccuracyMetersReportsStatistics.getLongSum(),
-                    mTopFourAverageCn0DbmHzReportsStatistics.getCount(),
-                    mTopFourAverageCn0DbmHzReportsStatistics.getLongSum(),
-                    mL5TopFourAverageCn0DbmHzReportsStatistics.getCount(),
-                    mL5TopFourAverageCn0DbmHzReportsStatistics.getLongSum(), mSvStatusReports,
-                    mSvStatusReportsUsedInFix, mL5SvStatusReports, mL5SvStatusReportsUsedInFix));
             return StatsManager.PULL_SUCCESS;
         }
     }
-}
+}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/location/injector/LocationPowerSaveModeHelper.java b/services/core/java/com/android/server/location/injector/LocationPowerSaveModeHelper.java
index cc00d56..53407d9 100644
--- a/services/core/java/com/android/server/location/injector/LocationPowerSaveModeHelper.java
+++ b/services/core/java/com/android/server/location/injector/LocationPowerSaveModeHelper.java
@@ -20,12 +20,11 @@
 
 import static com.android.server.location.LocationManagerService.D;
 import static com.android.server.location.LocationManagerService.TAG;
+import static com.android.server.location.eventlog.LocationEventLog.EVENT_LOG;
 
 import android.os.PowerManager.LocationPowerSaveMode;
 import android.util.Log;
 
-import com.android.server.location.eventlog.LocationEventLog;
-
 import java.util.concurrent.CopyOnWriteArrayList;
 
 /**
@@ -43,11 +42,9 @@
         void onLocationPowerSaveModeChanged(@LocationPowerSaveMode int locationPowerSaveMode);
     }
 
-    private final LocationEventLog mLocationEventLog;
     private final CopyOnWriteArrayList<LocationPowerSaveModeChangedListener> mListeners;
 
-    public LocationPowerSaveModeHelper(LocationEventLog locationEventLog) {
-        mLocationEventLog = locationEventLog;
+    public LocationPowerSaveModeHelper() {
         mListeners = new CopyOnWriteArrayList<>();
     }
 
@@ -72,7 +69,7 @@
             Log.d(TAG, "location power save mode is now " + locationPowerSaveModeToString(
                     locationPowerSaveMode));
         }
-        mLocationEventLog.logLocationPowerSaveMode(locationPowerSaveMode);
+        EVENT_LOG.logLocationPowerSaveMode(locationPowerSaveMode);
 
         for (LocationPowerSaveModeChangedListener listener : mListeners) {
             listener.onLocationPowerSaveModeChanged(locationPowerSaveMode);
diff --git a/services/core/java/com/android/server/location/injector/SystemLocationPowerSaveModeHelper.java b/services/core/java/com/android/server/location/injector/SystemLocationPowerSaveModeHelper.java
index c47a64d..a675f54 100644
--- a/services/core/java/com/android/server/location/injector/SystemLocationPowerSaveModeHelper.java
+++ b/services/core/java/com/android/server/location/injector/SystemLocationPowerSaveModeHelper.java
@@ -25,7 +25,6 @@
 import com.android.internal.util.Preconditions;
 import com.android.server.FgThread;
 import com.android.server.LocalServices;
-import com.android.server.location.eventlog.LocationEventLog;
 
 import java.util.Objects;
 import java.util.function.Consumer;
@@ -42,8 +41,7 @@
     @LocationPowerSaveMode
     private volatile int mLocationPowerSaveMode;
 
-    public SystemLocationPowerSaveModeHelper(Context context, LocationEventLog locationEventLog) {
-        super(locationEventLog);
+    public SystemLocationPowerSaveModeHelper(Context context) {
         mContext = context;
     }
 
diff --git a/services/core/java/com/android/server/location/injector/SystemSettingsHelper.java b/services/core/java/com/android/server/location/injector/SystemSettingsHelper.java
index 3f7345e..632ed6e 100644
--- a/services/core/java/com/android/server/location/injector/SystemSettingsHelper.java
+++ b/services/core/java/com/android/server/location/injector/SystemSettingsHelper.java
@@ -35,6 +35,7 @@
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Handler;
+import android.os.RemoteException;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.text.TextUtils;
@@ -348,31 +349,73 @@
      */
     @Override
     public void dump(FileDescriptor fd, IndentingPrintWriter ipw, String[] args) {
-        int userId = ActivityManager.getCurrentUser();
+        int[] userIds;
+        try {
+            userIds = ActivityManager.getService().getRunningUserIds();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
 
-        ipw.print("Location Enabled: ");
-        ipw.println(isLocationEnabled(userId));
-
-        List<String> locationPackageBlacklist = mLocationPackageBlacklist.getValueForUser(userId);
-        if (!locationPackageBlacklist.isEmpty()) {
-            ipw.println("Location Deny Packages:");
-            ipw.increaseIndent();
-            for (String packageName : locationPackageBlacklist) {
-                ipw.println(packageName);
+        ipw.print("Location Setting: ");
+        ipw.increaseIndent();
+        if (userIds.length > 1) {
+            ipw.println();
+            for (int userId : userIds) {
+                ipw.print("[u");
+                ipw.print(userId);
+                ipw.print("] ");
+                ipw.println(isLocationEnabled(userId));
             }
-            ipw.decreaseIndent();
+        } else {
+            ipw.println(isLocationEnabled(userIds[0]));
+        }
+        ipw.decreaseIndent();
 
-            List<String> locationPackageWhitelist = mLocationPackageWhitelist.getValueForUser(
-                    userId);
-            if (!locationPackageWhitelist.isEmpty()) {
-                ipw.println("Location Allow Packages:");
+        ipw.println("Location Allow/Deny Packages:");
+        ipw.increaseIndent();
+        if (userIds.length > 1) {
+            for (int userId : userIds) {
+                List<String> locationPackageBlacklist = mLocationPackageBlacklist.getValueForUser(
+                        userId);
+                if (locationPackageBlacklist.isEmpty()) {
+                    continue;
+                }
+
+                ipw.print("user ");
+                ipw.print(userId);
+                ipw.println(":");
                 ipw.increaseIndent();
-                for (String packageName : locationPackageWhitelist) {
+
+                for (String packageName : locationPackageBlacklist) {
+                    ipw.print("[deny] ");
                     ipw.println(packageName);
                 }
+
+                List<String> locationPackageWhitelist = mLocationPackageWhitelist.getValueForUser(
+                        userId);
+                for (String packageName : locationPackageWhitelist) {
+                    ipw.print("[allow] ");
+                    ipw.println(packageName);
+                }
+
                 ipw.decreaseIndent();
             }
+        } else {
+            List<String> locationPackageBlacklist = mLocationPackageBlacklist.getValueForUser(
+                    userIds[0]);
+            for (String packageName : locationPackageBlacklist) {
+                ipw.print("[deny] ");
+                ipw.println(packageName);
+            }
+
+            List<String> locationPackageWhitelist = mLocationPackageWhitelist.getValueForUser(
+                    userIds[0]);
+            for (String packageName : locationPackageWhitelist) {
+                ipw.print("[allow] ");
+                ipw.println(packageName);
+            }
         }
+        ipw.decreaseIndent();
 
         Set<String> backgroundThrottlePackageWhitelist =
                 mBackgroundThrottlePackageWhitelist.getValue();
diff --git a/services/core/java/com/android/server/location/injector/SystemUserInfoHelper.java b/services/core/java/com/android/server/location/injector/SystemUserInfoHelper.java
index d4a8fbd..ed1e654 100644
--- a/services/core/java/com/android/server/location/injector/SystemUserInfoHelper.java
+++ b/services/core/java/com/android/server/location/injector/SystemUserInfoHelper.java
@@ -155,6 +155,11 @@
      */
     @Override
     public void dump(FileDescriptor fd, IndentingPrintWriter pw, String[] args) {
+        int[] runningUserIds = getRunningUserIds();
+        if (runningUserIds.length > 1) {
+            pw.println("running users: u" + Arrays.toString(runningUserIds));
+        }
+
         ActivityManagerInternal activityManagerInternal = getActivityManagerInternal();
         if (activityManagerInternal == null) {
             return;
diff --git a/services/core/java/com/android/server/location/injector/UserInfoHelper.java b/services/core/java/com/android/server/location/injector/UserInfoHelper.java
index 0fcc1ec..c835370 100644
--- a/services/core/java/com/android/server/location/injector/UserInfoHelper.java
+++ b/services/core/java/com/android/server/location/injector/UserInfoHelper.java
@@ -18,6 +18,7 @@
 
 import static com.android.server.location.LocationManagerService.D;
 import static com.android.server.location.LocationManagerService.TAG;
+import static com.android.server.location.eventlog.LocationEventLog.EVENT_LOG;
 import static com.android.server.location.injector.UserInfoHelper.UserListener.CURRENT_USER_CHANGED;
 import static com.android.server.location.injector.UserInfoHelper.UserListener.USER_STARTED;
 import static com.android.server.location.injector.UserInfoHelper.UserListener.USER_STOPPED;
@@ -105,6 +106,7 @@
             Log.d(TAG, "current user changed from u" + Arrays.toString(fromUserIds) + " to u"
                     + Arrays.toString(toUserIds));
         }
+        EVENT_LOG.logUserSwitched(fromUserId, toUserId);
 
         for (UserListener listener : mListeners) {
             for (int userId : fromUserIds) {
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 dc8b1d0..102263b 100644
--- a/services/core/java/com/android/server/location/provider/LocationProviderManager.java
+++ b/services/core/java/com/android/server/location/provider/LocationProviderManager.java
@@ -37,6 +37,7 @@
 import static com.android.server.location.LocationPermissions.PERMISSION_COARSE;
 import static com.android.server.location.LocationPermissions.PERMISSION_FINE;
 import static com.android.server.location.LocationPermissions.PERMISSION_NONE;
+import static com.android.server.location.eventlog.LocationEventLog.EVENT_LOG;
 
 import static java.lang.Math.max;
 import static java.lang.Math.min;
@@ -94,7 +95,6 @@
 import com.android.server.LocalServices;
 import com.android.server.location.LocationPermissions;
 import com.android.server.location.LocationPermissions.PermissionLevel;
-import com.android.server.location.eventlog.LocationEventLog;
 import com.android.server.location.fudger.LocationFudger;
 import com.android.server.location.injector.AlarmHelper;
 import com.android.server.location.injector.AppForegroundHelper;
@@ -333,7 +333,7 @@
                         + getRequest());
             }
 
-            mEventLog.logProviderClientRegistered(mName, getIdentity(), super.getRequest());
+            EVENT_LOG.logProviderClientRegistered(mName, getIdentity(), super.getRequest());
 
             // initialization order is important as there are ordering dependencies
             mPermitted = mLocationPermissionsHelper.hasLocationPermissions(mPermissionLevel,
@@ -345,7 +345,7 @@
             onProviderListenerRegister();
 
             if (mForeground) {
-                mEventLog.logProviderClientForeground(mName, getIdentity());
+                EVENT_LOG.logProviderClientForeground(mName, getIdentity());
             }
         }
 
@@ -358,7 +358,7 @@
 
             onProviderListenerUnregister();
 
-            mEventLog.logProviderClientUnregistered(mName, getIdentity());
+            EVENT_LOG.logProviderClientUnregistered(mName, getIdentity());
 
             if (D) {
                 Log.d(TAG, mName + " provider removed registration from " + getIdentity());
@@ -383,7 +383,7 @@
                 Preconditions.checkState(Thread.holdsLock(mLock));
             }
 
-            mEventLog.logProviderClientActive(mName, getIdentity());
+            EVENT_LOG.logProviderClientActive(mName, getIdentity());
 
             if (!getRequest().isHiddenFromAppOps()) {
                 mLocationAttributionHelper.reportLocationStart(getIdentity(), getName(), getKey());
@@ -406,7 +406,7 @@
 
             onProviderListenerInactive();
 
-            mEventLog.logProviderClientInactive(mName, getIdentity());
+            EVENT_LOG.logProviderClientInactive(mName, getIdentity());
         }
 
         /**
@@ -543,9 +543,9 @@
                 mForeground = foreground;
 
                 if (mForeground) {
-                    mEventLog.logProviderClientForeground(mName, getIdentity());
+                    EVENT_LOG.logProviderClientForeground(mName, getIdentity());
                 } else {
-                    mEventLog.logProviderClientBackground(mName, getIdentity());
+                    EVENT_LOG.logProviderClientBackground(mName, getIdentity());
                 }
 
                 // note that onProviderLocationRequestChanged() is always called
@@ -654,7 +654,7 @@
     protected abstract class LocationRegistration extends Registration implements
             OnAlarmListener, ProviderEnabledListener {
 
-        private final PowerManager.WakeLock mWakeLock;
+        final PowerManager.WakeLock mWakeLock;
 
         private volatile ProviderTransport mProviderTransport;
         private int mNumLocationsDelivered = 0;
@@ -879,7 +879,7 @@
 
                     listener.deliverOnLocationChanged(deliverLocationResult,
                             mUseWakeLock ? mWakeLock::release : null);
-                    mEventLog.logProviderDeliveredLocations(mName, locationResult.size(),
+                    EVENT_LOG.logProviderDeliveredLocations(mName, locationResult.size(),
                             getIdentity());
                 }
 
@@ -1178,7 +1178,7 @@
 
                     // we currently don't hold a wakelock for getCurrentLocation deliveries
                     listener.deliverOnLocationChanged(deliverLocationResult, null);
-                    mEventLog.logProviderDeliveredLocations(mName,
+                    EVENT_LOG.logProviderDeliveredLocations(mName,
                             locationResult != null ? locationResult.size() : 0, getIdentity());
                 }
 
@@ -1247,7 +1247,6 @@
 
     private final CopyOnWriteArrayList<IProviderRequestListener> mProviderRequestListeners;
 
-    protected final LocationEventLog mEventLog;
     protected final LocationManagerInternal mLocationManagerInternal;
     protected final SettingsHelper mSettingsHelper;
     protected final UserInfoHelper mUserHelper;
@@ -1300,7 +1299,7 @@
     @GuardedBy("mLock")
     private @Nullable OnProviderLocationTagsChangeListener mOnLocationTagsChangeListener;
 
-    public LocationProviderManager(Context context, Injector injector, LocationEventLog eventLog,
+    public LocationProviderManager(Context context, Injector injector,
             String name, @Nullable PassiveLocationProviderManager passiveManager) {
         mContext = context;
         mName = Objects.requireNonNull(name);
@@ -1312,7 +1311,6 @@
         mEnabledListeners = new ArrayList<>();
         mProviderRequestListeners = new CopyOnWriteArrayList<>();
 
-        mEventLog = eventLog;
         mLocationManagerInternal = Objects.requireNonNull(
                 LocalServices.getService(LocationManagerInternal.class));
         mSettingsHelper = injector.getSettingsHelper();
@@ -1477,7 +1475,7 @@
         synchronized (mLock) {
             Preconditions.checkState(mState != STATE_STOPPED);
 
-            mEventLog.logProviderMocked(mName, provider != null);
+            EVENT_LOG.logProviderMocked(mName, provider != null);
 
             final long identity = Binder.clearCallingIdentity();
             try {
@@ -1966,8 +1964,8 @@
     }
 
     @GuardedBy("mLock")
-    private void setProviderRequest(ProviderRequest request) {
-        mEventLog.logProviderUpdateRequest(mName, request);
+    void setProviderRequest(ProviderRequest request) {
+        EVENT_LOG.logProviderUpdateRequest(mName, request);
         mProvider.getController().setRequest(request);
 
         FgThread.getHandler().post(() -> {
@@ -2324,7 +2322,7 @@
             }
 
             // don't log location received for passive provider because it's spammy
-            mEventLog.logProviderReceivedLocations(mName, filtered.size());
+            EVENT_LOG.logProviderReceivedLocations(mName, filtered.size());
         } else {
             // passive provider should get already filtered results as input
             filtered = locationResult;
@@ -2424,7 +2422,7 @@
             if (D) {
                 Log.d(TAG, "[u" + userId + "] " + mName + " provider enabled = " + enabled);
             }
-            mEventLog.logProviderEnabled(mName, userId, enabled);
+            EVENT_LOG.logProviderEnabled(mName, userId, enabled);
         }
 
         // clear last locations if we become disabled
@@ -2464,7 +2462,7 @@
         updateRegistrations(registration -> registration.getIdentity().getUserId() == userId);
     }
 
-    private @Nullable Location getPermittedLocation(@Nullable Location fineLocation,
+    @Nullable Location getPermittedLocation(@Nullable Location fineLocation,
             @PermissionLevel int permissionLevel) {
         switch (permissionLevel) {
             case PERMISSION_FINE:
@@ -2477,7 +2475,7 @@
         }
     }
 
-    private @Nullable LocationResult getPermittedLocationResult(
+    @Nullable LocationResult getPermittedLocationResult(
             @Nullable LocationResult fineLocationResult, @PermissionLevel int permissionLevel) {
         switch (permissionLevel) {
             case PERMISSION_FINE:
@@ -2538,6 +2536,8 @@
         private @Nullable Location mFineBypassLocation;
         private @Nullable Location mCoarseBypassLocation;
 
+        LastLocation() {}
+
         public void clearMock() {
             if (mFineLocation != null && mFineLocation.isFromMockProvider()) {
                 mFineLocation = null;
diff --git a/services/core/java/com/android/server/location/provider/PassiveLocationProviderManager.java b/services/core/java/com/android/server/location/provider/PassiveLocationProviderManager.java
index 027f4e9..b35af4f 100644
--- a/services/core/java/com/android/server/location/provider/PassiveLocationProviderManager.java
+++ b/services/core/java/com/android/server/location/provider/PassiveLocationProviderManager.java
@@ -24,7 +24,6 @@
 import android.os.Binder;
 
 import com.android.internal.util.Preconditions;
-import com.android.server.location.eventlog.LocationEventLog;
 import com.android.server.location.injector.Injector;
 
 import java.util.Collection;
@@ -34,9 +33,8 @@
  */
 public class PassiveLocationProviderManager extends LocationProviderManager {
 
-    public PassiveLocationProviderManager(Context context, Injector injector,
-            LocationEventLog eventLog) {
-        super(context, injector, eventLog, LocationManager.PASSIVE_PROVIDER, null);
+    public PassiveLocationProviderManager(Context context, Injector injector) {
+        super(context, injector, LocationManager.PASSIVE_PROVIDER, null);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/location/provider/StationaryThrottlingLocationProvider.java b/services/core/java/com/android/server/location/provider/StationaryThrottlingLocationProvider.java
index 6f4aa64..ab7e526 100644
--- a/services/core/java/com/android/server/location/provider/StationaryThrottlingLocationProvider.java
+++ b/services/core/java/com/android/server/location/provider/StationaryThrottlingLocationProvider.java
@@ -21,6 +21,7 @@
 import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR;
 import static com.android.server.location.LocationManagerService.D;
 import static com.android.server.location.LocationManagerService.TAG;
+import static com.android.server.location.eventlog.LocationEventLog.EVENT_LOG;
 
 import android.annotation.Nullable;
 import android.location.Location;
@@ -33,7 +34,6 @@
 import com.android.internal.util.Preconditions;
 import com.android.server.DeviceIdleInternal;
 import com.android.server.FgThread;
-import com.android.server.location.eventlog.LocationEventLog;
 import com.android.server.location.injector.DeviceIdleHelper;
 import com.android.server.location.injector.DeviceStationaryHelper;
 import com.android.server.location.injector.Injector;
@@ -54,12 +54,11 @@
 
     private static final long MAX_STATIONARY_LOCATION_AGE_MS = 30000;
 
-    private final Object mLock = new Object();
+    final Object mLock = new Object();
 
     private final String mName;
     private final DeviceIdleHelper mDeviceIdleHelper;
     private final DeviceStationaryHelper mDeviceStationaryHelper;
-    private final LocationEventLog mEventLog;
 
     @GuardedBy("mLock")
     private boolean mDeviceIdle = false;
@@ -72,21 +71,19 @@
     @GuardedBy("mLock")
     private ProviderRequest mOutgoingRequest = ProviderRequest.EMPTY_REQUEST;
     @GuardedBy("mLock")
-    private long mThrottlingIntervalMs = INTERVAL_DISABLED;
+    long mThrottlingIntervalMs = INTERVAL_DISABLED;
     @GuardedBy("mLock")
-    private @Nullable DeliverLastLocationRunnable mDeliverLastLocationCallback = null;
-
+    @Nullable DeliverLastLocationRunnable mDeliverLastLocationCallback = null;
     @GuardedBy("mLock")
-    private @Nullable Location mLastLocation;
+    @Nullable Location mLastLocation;
 
     public StationaryThrottlingLocationProvider(String name, Injector injector,
-            AbstractLocationProvider delegate, LocationEventLog eventLog) {
+            AbstractLocationProvider delegate) {
         super(DIRECT_EXECUTOR, delegate);
 
         mName = name;
         mDeviceIdleHelper = injector.getDeviceIdleHelper();
         mDeviceStationaryHelper = injector.getDeviceStationaryHelper();
-        mEventLog = eventLog;
 
         // must be last statement in the constructor because reference is escaping
         initializeDelegate();
@@ -209,7 +206,7 @@
                 if (D) {
                     Log.d(TAG, mName + " provider stationary throttled");
                 }
-                mEventLog.logProviderStationaryThrottled(mName, true);
+                EVENT_LOG.logProviderStationaryThrottled(mName, true);
             }
 
             if (mDeliverLastLocationCallback != null) {
@@ -227,7 +224,7 @@
             }
         } else {
             if (oldThrottlingIntervalMs != INTERVAL_DISABLED) {
-                mEventLog.logProviderStationaryThrottled(mName, false);
+                EVENT_LOG.logProviderStationaryThrottled(mName, false);
                 if (D) {
                     Log.d(TAG, mName + " provider stationary unthrottled");
                 }
@@ -257,6 +254,9 @@
     }
 
     private class DeliverLastLocationRunnable implements Runnable {
+
+        DeliverLastLocationRunnable() {}
+
         @Override
         public void run() {
             Location location;
diff --git a/services/core/java/com/android/server/location/provider/proxy/ProxyLocationProvider.java b/services/core/java/com/android/server/location/provider/proxy/ProxyLocationProvider.java
index c86e49b..5df7870 100644
--- a/services/core/java/com/android/server/location/provider/proxy/ProxyLocationProvider.java
+++ b/services/core/java/com/android/server/location/provider/proxy/ProxyLocationProvider.java
@@ -19,7 +19,6 @@
 import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR;
 
 import android.annotation.Nullable;
-import android.content.ComponentName;
 import android.content.Context;
 import android.location.Location;
 import android.location.LocationResult;
@@ -28,42 +27,46 @@
 import android.location.provider.ProviderProperties;
 import android.location.provider.ProviderRequest;
 import android.location.util.identity.CallerIdentity;
-import android.os.Binder;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.text.TextUtils;
 import android.util.ArraySet;
 
 import com.android.internal.annotations.GuardedBy;
-import com.android.internal.util.ArrayUtils;
+import com.android.server.FgThread;
 import com.android.server.location.provider.AbstractLocationProvider;
+import com.android.server.servicewatcher.CurrentUserServiceSupplier;
+import com.android.server.servicewatcher.CurrentUserServiceSupplier.BoundServiceInfo;
 import com.android.server.servicewatcher.ServiceWatcher;
-import com.android.server.servicewatcher.ServiceWatcher.BoundService;
+import com.android.server.servicewatcher.ServiceWatcher.ServiceListener;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
-import java.util.Objects;
 
 /**
  * Proxy for ILocationProvider implementations.
  */
-public class ProxyLocationProvider extends AbstractLocationProvider {
+public class ProxyLocationProvider extends AbstractLocationProvider implements
+        ServiceListener<BoundServiceInfo> {
 
-    private static final String KEY_EXTRA_ATTRIBUTION_TAGS = "android:location_allow_listed_tags";
-    private static final String EXTRA_ATTRIBUTION_TAGS_SEPARATOR = ";";
+    private static final String EXTRA_LOCATION_TAGS = "android:location_allow_listed_tags";
+    private static final String LOCATION_TAGS_SEPARATOR = ";";
+
+    private static final long RESET_DELAY_MS = 1000;
 
     /**
      * Creates and registers this proxy. If no suitable service is available for the proxy, returns
      * null.
      */
     @Nullable
-    public static ProxyLocationProvider create(Context context, String action,
+    public static ProxyLocationProvider create(Context context, String provider, String action,
             int enableOverlayResId, int nonOverlayPackageResId) {
-        ProxyLocationProvider proxy = new ProxyLocationProvider(context, action, enableOverlayResId,
-                nonOverlayPackageResId);
+        ProxyLocationProvider proxy = new ProxyLocationProvider(context, provider, action,
+                enableOverlayResId, nonOverlayPackageResId);
         if (proxy.checkServiceResolves()) {
             return proxy;
         } else {
@@ -80,21 +83,24 @@
     final ArrayList<Runnable> mFlushListeners = new ArrayList<>(0);
 
     @GuardedBy("mLock")
-    Proxy mProxy;
+    @Nullable Runnable mResetter;
     @GuardedBy("mLock")
-    @Nullable ComponentName mService;
+    @Nullable Proxy mProxy;
+    @GuardedBy("mLock")
+    @Nullable BoundServiceInfo mBoundServiceInfo;
 
     private volatile ProviderRequest mRequest;
 
-    private ProxyLocationProvider(Context context, String action, int enableOverlayResId,
-            int nonOverlayPackageResId) {
+    private ProxyLocationProvider(Context context, String provider, String action,
+            int enableOverlayResId, int nonOverlayPackageResId) {
         // safe to use direct executor since our locks are not acquired in a code path invoked by
         // our owning provider
         super(DIRECT_EXECUTOR, null, null, Collections.emptySet());
 
         mContext = context;
-        mServiceWatcher = new ServiceWatcher(context, action, this::onBind,
-                this::onUnbind, enableOverlayResId, nonOverlayPackageResId);
+        mServiceWatcher = ServiceWatcher.create(context, provider,
+                new CurrentUserServiceSupplier(context, action, enableOverlayResId,
+                        nonOverlayPackageResId), this);
 
         mProxy = null;
         mRequest = ProviderRequest.EMPTY_REQUEST;
@@ -104,21 +110,13 @@
         return mServiceWatcher.checkServiceResolves();
     }
 
-    private void onBind(IBinder binder, BoundService boundService) throws RemoteException {
+    @Override
+    public void onBind(IBinder binder, BoundServiceInfo boundServiceInfo) throws RemoteException {
         ILocationProvider provider = ILocationProvider.Stub.asInterface(binder);
 
         synchronized (mLock) {
             mProxy = new Proxy();
-            mService = boundService.component;
-
-            // update extra attribution tag info from manifest
-            if (boundService.metadata != null) {
-                String tagsList = boundService.metadata.getString(KEY_EXTRA_ATTRIBUTION_TAGS);
-                if (tagsList != null) {
-                    setExtraAttributionTags(
-                            new ArraySet<>(tagsList.split(EXTRA_ATTRIBUTION_TAGS_SEPARATOR)));
-                }
-            }
+            mBoundServiceInfo = boundServiceInfo;
 
             provider.setLocationProviderManager(mProxy);
 
@@ -129,12 +127,30 @@
         }
     }
 
-    private void onUnbind() {
+    @Override
+    public void onUnbind() {
         Runnable[] flushListeners;
         synchronized (mLock) {
             mProxy = null;
-            mService = null;
-            setState(prevState -> State.EMPTY_STATE);
+            mBoundServiceInfo = null;
+
+            // we need to clear the state - but most disconnections are very temporary. we give a
+            // grace period where we don't clear the state immediately so that transient
+            // interruptions are not necessarily visible to downstream clients
+            if (mResetter == null) {
+                mResetter = new Runnable() {
+                    @Override
+                    public void run() {
+                        synchronized (mLock) {
+                            if (mResetter == this) {
+                                setState(prevState -> State.EMPTY_STATE);
+                            }
+                        }
+                    }
+                };
+                FgThread.getHandler().postDelayed(mResetter, RESET_DELAY_MS);
+            }
+
             flushListeners = mFlushListeners.toArray(new Runnable[0]);
             mFlushListeners.clear();
         }
@@ -166,7 +182,7 @@
 
     @Override
     protected void onFlush(Runnable callback) {
-        mServiceWatcher.runOnBinder(new ServiceWatcher.BinderRunner() {
+        mServiceWatcher.runOnBinder(new ServiceWatcher.BinderOperation() {
             @Override
             public void run(IBinder binder) throws RemoteException {
                 ILocationProvider provider = ILocationProvider.Stub.asInterface(binder);
@@ -206,20 +222,7 @@
 
     @Override
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        mServiceWatcher.dump(fd, pw, args);
-    }
-
-    private static String guessPackageName(Context context, int uid, String packageName) {
-        String[] packageNames = context.getPackageManager().getPackagesForUid(uid);
-        if (packageNames == null || packageNames.length == 0) {
-            // illegal state exception will propagate back through binders
-            throw new IllegalStateException(
-                    "location provider from uid " + uid + " has no package information");
-        } else if (ArrayUtils.contains(packageNames, packageName)) {
-            return packageName;
-        } else {
-            return packageNames[0];
-        }
+        mServiceWatcher.dump(pw);
     }
 
     private class Proxy extends ILocationProviderManager.Stub {
@@ -229,26 +232,37 @@
         // executed on binder thread
         @Override
         public void onInitialize(boolean allowed, ProviderProperties properties,
-                @Nullable String packageName, @Nullable String attributionTag) {
+                @Nullable String attributionTag) {
             synchronized (mLock) {
                 if (mProxy != this) {
                     return;
                 }
 
-                CallerIdentity identity;
-                if (packageName == null) {
-                    packageName = guessPackageName(mContext, Binder.getCallingUid(),
-                            Objects.requireNonNull(mService).getPackageName());
-                    // unsafe is ok since the package is coming direct from the package manager here
-                    identity = CallerIdentity.fromBinderUnsafe(packageName, attributionTag);
-                } else {
-                    identity = CallerIdentity.fromBinder(mContext, packageName, attributionTag);
+                if (mResetter != null) {
+                    FgThread.getHandler().removeCallbacks(mResetter);
+                    mResetter = null;
                 }
 
-                setState(prevState -> prevState
+                // set extra attribution tags from manifest if necessary
+                String[] attributionTags = new String[0];
+                if (mBoundServiceInfo.getMetadata() != null) {
+                    String tagsStr = mBoundServiceInfo.getMetadata().getString(EXTRA_LOCATION_TAGS);
+                    if (!TextUtils.isEmpty(tagsStr)) {
+                        attributionTags = tagsStr.split(LOCATION_TAGS_SEPARATOR);
+                    }
+                }
+                ArraySet<String> extraAttributionTags = new ArraySet<>(attributionTags);
+
+                // unsafe is ok since we trust the package name already
+                CallerIdentity identity = CallerIdentity.fromBinderUnsafe(
+                        mBoundServiceInfo.getComponentName().getPackageName(),
+                        attributionTag);
+
+                setState(prevState -> State.EMPTY_STATE
                         .withAllowed(allowed)
                         .withProperties(properties)
-                        .withIdentity(identity));
+                        .withIdentity(identity)
+                        .withExtraAttributionTags(extraAttributionTags));
             }
         }
 
diff --git a/services/core/java/com/android/server/locksettings/BiometricDeferredQueue.java b/services/core/java/com/android/server/locksettings/BiometricDeferredQueue.java
index 6201b94..5abc438 100644
--- a/services/core/java/com/android/server/locksettings/BiometricDeferredQueue.java
+++ b/services/core/java/com/android/server/locksettings/BiometricDeferredQueue.java
@@ -52,7 +52,8 @@
 
     // Entries added by LockSettingsService once a user's synthetic password is known. At this point
     // things are still keyed by userId.
-    @NonNull private final ArrayList<UserAuthInfo> mPendingResetLockouts;
+    @NonNull private final ArrayList<UserAuthInfo> mPendingResetLockoutsForFingerprint;
+    @NonNull private final ArrayList<UserAuthInfo> mPendingResetLockoutsForFace;
 
     /**
      * Authentication info for a successful user unlock via Synthetic Password. This can be used to
@@ -151,7 +152,8 @@
         mContext = context;
         mSpManager = spManager;
         mHandler = handler;
-        mPendingResetLockouts = new ArrayList<>();
+        mPendingResetLockoutsForFingerprint = new ArrayList<>();
+        mPendingResetLockoutsForFace = new ArrayList<>();
     }
 
     public void systemReady(@Nullable FingerprintManager fingerprintManager,
@@ -173,17 +175,34 @@
      */
     void addPendingLockoutResetForUser(int userId, @NonNull byte[] gatekeeperPassword) {
         mHandler.post(() -> {
-            Slog.d(TAG, "addPendingLockoutResetForUser: " + userId);
-            mPendingResetLockouts.add(new UserAuthInfo(userId, gatekeeperPassword));
+            if (mFaceManager != null && mFaceManager.hasEnrolledTemplates(userId)) {
+                Slog.d(TAG, "Face addPendingLockoutResetForUser: " + userId);
+                mPendingResetLockoutsForFace.add(new UserAuthInfo(userId, gatekeeperPassword));
+            }
+
+            if (mFingerprintManager != null
+                    && mFingerprintManager.hasEnrolledFingerprints(userId)) {
+                Slog.d(TAG, "Fingerprint addPendingLockoutResetForUser: " + userId);
+                mPendingResetLockoutsForFingerprint.add(new UserAuthInfo(userId,
+                        gatekeeperPassword));
+            }
         });
     }
 
     void processPendingLockoutResets() {
         mHandler.post(() -> {
-            Slog.d(TAG, "processPendingLockoutResets: " + mPendingResetLockouts.size());
-            processPendingLockoutsForFingerprint(new ArrayList<>(mPendingResetLockouts));
-            processPendingLockoutsForFace(new ArrayList<>(mPendingResetLockouts));
-            mPendingResetLockouts.clear();
+            if (!mPendingResetLockoutsForFace.isEmpty()) {
+                Slog.d(TAG, "Processing pending resetLockout for face");
+                processPendingLockoutsForFace(new ArrayList<>(mPendingResetLockoutsForFace));
+                mPendingResetLockoutsForFace.clear();
+            }
+
+            if (!mPendingResetLockoutsForFingerprint.isEmpty()) {
+                Slog.d(TAG, "Processing pending resetLockout for fingerprint");
+                processPendingLockoutsForFingerprint(
+                        new ArrayList<>(mPendingResetLockoutsForFingerprint));
+                mPendingResetLockoutsForFingerprint.clear();
+            }
         });
     }
 
diff --git a/services/core/java/com/android/server/locksettings/RebootEscrowManager.java b/services/core/java/com/android/server/locksettings/RebootEscrowManager.java
index 6e99cba..76ecc1a 100644
--- a/services/core/java/com/android/server/locksettings/RebootEscrowManager.java
+++ b/services/core/java/com/android/server/locksettings/RebootEscrowManager.java
@@ -15,14 +15,17 @@
  */
 
 package com.android.server.locksettings;
+
 import static android.os.UserHandle.USER_SYSTEM;
 
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.UserIdInt;
 import android.content.Context;
 import android.content.pm.UserInfo;
 import android.os.Handler;
 import android.os.SystemClock;
+import android.os.SystemProperties;
 import android.os.UserManager;
 import android.provider.DeviceConfig;
 import android.provider.Settings;
@@ -35,6 +38,8 @@
 import com.android.internal.widget.RebootEscrowListener;
 
 import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Date;
@@ -65,6 +70,22 @@
     public static final String REBOOT_ESCROW_ARMED_KEY = "reboot_escrow_armed_count";
 
     static final String REBOOT_ESCROW_KEY_ARMED_TIMESTAMP = "reboot_escrow_key_stored_timestamp";
+    static final String REBOOT_ESCROW_KEY_PROVIDER = "reboot_escrow_key_provider";
+
+    /**
+     * The verified boot 2.0 vbmeta digest of the current slot, the property value is always
+     * available after boot.
+     */
+    static final String VBMETA_DIGEST_PROP_NAME = "ro.boot.vbmeta.digest";
+    /**
+     * The system prop contains vbmeta digest of the inactive slot. The build property is set after
+     * an OTA update. RebootEscrowManager will store it in disk before the OTA reboot, so the value
+     * is available for vbmeta digest verification after the device reboots.
+     */
+    static final String OTHER_VBMETA_DIGEST_PROP_NAME = "ota.other.vbmeta_digest";
+    static final String REBOOT_ESCROW_KEY_VBMETA_DIGEST = "reboot_escrow_key_vbmeta_digest";
+    static final String REBOOT_ESCROW_KEY_OTHER_VBMETA_DIGEST =
+            "reboot_escrow_key_other_vbmeta_digest";
 
     /**
      * Number of boots until we consider the escrow data to be stale for the purposes of metrics.
@@ -86,6 +107,31 @@
     private static final int DEFAULT_LOAD_ESCROW_DATA_RETRY_COUNT = 3;
     private static final int DEFAULT_LOAD_ESCROW_DATA_RETRY_INTERVAL_SECONDS = 30;
 
+    @IntDef(prefix = {"ERROR_"}, value = {
+            ERROR_NONE,
+            ERROR_UNKNOWN,
+            ERROR_NO_PROVIDER,
+            ERROR_LOAD_ESCROW_KEY,
+            ERROR_RETRY_COUNT_EXHAUSTED,
+            ERROR_UNLOCK_ALL_USERS,
+            ERROR_PROVIDER_MISMATCH,
+            ERROR_KEYSTORE_FAILURE,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    @interface RebootEscrowErrorCode {
+    }
+
+    static final int ERROR_NONE = 0;
+    static final int ERROR_UNKNOWN = 1;
+    static final int ERROR_NO_PROVIDER = 2;
+    static final int ERROR_LOAD_ESCROW_KEY = 3;
+    static final int ERROR_RETRY_COUNT_EXHAUSTED = 4;
+    static final int ERROR_UNLOCK_ALL_USERS = 5;
+    static final int ERROR_PROVIDER_MISMATCH = 6;
+    static final int ERROR_KEYSTORE_FAILURE = 7;
+
+    private @RebootEscrowErrorCode int mLoadEscrowDataErrorCode = ERROR_NONE;
+
     /**
      * Logs events for later debugging in bugreports.
      */
@@ -199,6 +245,10 @@
                     0);
         }
 
+        public long getCurrentTimeMillis() {
+            return System.currentTimeMillis();
+        }
+
         public int getLoadEscrowDataRetryLimit() {
             return DeviceConfig.getInt(DeviceConfig.NAMESPACE_OTA,
                     "load_escrow_data_retry_count", DEFAULT_LOAD_ESCROW_DATA_RETRY_COUNT);
@@ -221,6 +271,11 @@
         public RebootEscrowEventLog getEventLog() {
             return new RebootEscrowEventLog();
         }
+
+        public String getVbmetaDigest(boolean other) {
+            return other ? SystemProperties.get(OTHER_VBMETA_DIGEST_PROP_NAME)
+                    : SystemProperties.get(VBMETA_DIGEST_PROP_NAME);
+        }
     }
 
     RebootEscrowManager(Context context, Callbacks callbacks, LockSettingsStorage storage) {
@@ -261,6 +316,7 @@
         if (rebootEscrowUsers.isEmpty()) {
             Slog.i(TAG, "No reboot escrow data found for users,"
                     + " skipping loading escrow data");
+            clearMetricsStorage();
             return;
         }
 
@@ -284,6 +340,7 @@
         }
 
         Slog.w(TAG, "Failed to load reboot escrow data after " + attemptNumber + " attempts");
+        mLoadEscrowDataErrorCode = ERROR_RETRY_COUNT_EXHAUSTED;
         onGetRebootEscrowKeyFailed(users, attemptNumber);
     }
 
@@ -307,6 +364,17 @@
         }
 
         if (escrowKey == null) {
+            if (mLoadEscrowDataErrorCode == ERROR_NONE) {
+                // Specifically check if the RoR provider has changed after reboot.
+                int providerType = mInjector.serverBasedResumeOnReboot()
+                        ? RebootEscrowProviderInterface.TYPE_SERVER_BASED
+                        : RebootEscrowProviderInterface.TYPE_HAL;
+                if (providerType != mStorage.getInt(REBOOT_ESCROW_KEY_PROVIDER, -1, USER_SYSTEM)) {
+                    mLoadEscrowDataErrorCode = ERROR_PROVIDER_MISMATCH;
+                } else {
+                    mLoadEscrowDataErrorCode = ERROR_LOAD_ESCROW_KEY;
+                }
+            }
             onGetRebootEscrowKeyFailed(users, attemptNumber + 1);
             return;
         }
@@ -321,9 +389,49 @@
         // Clear the old key in keystore. A new key will be generated by new RoR requests.
         mKeyStoreManager.clearKeyStoreEncryptionKey();
 
+        if (!allUsersUnlocked && mLoadEscrowDataErrorCode == ERROR_NONE) {
+            mLoadEscrowDataErrorCode = ERROR_UNLOCK_ALL_USERS;
+        }
         onEscrowRestoreComplete(allUsersUnlocked, attemptNumber + 1);
     }
 
+    private void clearMetricsStorage() {
+        mStorage.removeKey(REBOOT_ESCROW_ARMED_KEY, USER_SYSTEM);
+        mStorage.removeKey(REBOOT_ESCROW_KEY_ARMED_TIMESTAMP, USER_SYSTEM);
+        mStorage.removeKey(REBOOT_ESCROW_KEY_VBMETA_DIGEST, USER_SYSTEM);
+        mStorage.removeKey(REBOOT_ESCROW_KEY_OTHER_VBMETA_DIGEST, USER_SYSTEM);
+        mStorage.removeKey(REBOOT_ESCROW_KEY_PROVIDER, USER_SYSTEM);
+    }
+
+    private int getVbmetaDigestStatusOnRestoreComplete() {
+        String currentVbmetaDigest = mInjector.getVbmetaDigest(false);
+        String vbmetaDigestStored = mStorage.getString(REBOOT_ESCROW_KEY_VBMETA_DIGEST,
+                "", USER_SYSTEM);
+        String vbmetaDigestOtherStored = mStorage.getString(REBOOT_ESCROW_KEY_OTHER_VBMETA_DIGEST,
+                "", USER_SYSTEM);
+
+        // The other vbmeta digest is never set, assume no slot switch is attempted.
+        if (vbmetaDigestOtherStored.isEmpty()) {
+            if (currentVbmetaDigest.equals(vbmetaDigestStored)) {
+                return FrameworkStatsLog
+                        .REBOOT_ESCROW_RECOVERY_REPORTED__VBMETA_DIGEST_STATUS__MATCH_EXPECTED_SLOT;
+            }
+            return FrameworkStatsLog
+                    .REBOOT_ESCROW_RECOVERY_REPORTED__VBMETA_DIGEST_STATUS__MISMATCH;
+        }
+
+        // The other vbmeta digest is set, we expect to boot into the new slot.
+        if (currentVbmetaDigest.equals(vbmetaDigestOtherStored)) {
+            return FrameworkStatsLog
+                    .REBOOT_ESCROW_RECOVERY_REPORTED__VBMETA_DIGEST_STATUS__MATCH_EXPECTED_SLOT;
+        } else if (currentVbmetaDigest.equals(vbmetaDigestStored)) {
+            return FrameworkStatsLog
+                    .REBOOT_ESCROW_RECOVERY_REPORTED__VBMETA_DIGEST_STATUS__MATCH_FALLBACK_SLOT;
+        }
+        return FrameworkStatsLog
+                .REBOOT_ESCROW_RECOVERY_REPORTED__VBMETA_DIGEST_STATUS__MISMATCH;
+    }
+
     private void reportMetricOnRestoreComplete(boolean success, int attemptCount) {
         int serviceType = mInjector.serverBasedResumeOnReboot()
                 ? FrameworkStatsLog.REBOOT_ESCROW_RECOVERY_REPORTED__TYPE__SERVER_BASED
@@ -331,26 +439,32 @@
 
         long armedTimestamp = mStorage.getLong(REBOOT_ESCROW_KEY_ARMED_TIMESTAMP, -1,
                 USER_SYSTEM);
-        mStorage.removeKey(REBOOT_ESCROW_KEY_ARMED_TIMESTAMP, USER_SYSTEM);
-        int escrowDurationInSeconds = armedTimestamp != -1
-                ? (int) (System.currentTimeMillis() - armedTimestamp) / 1000 : -1;
+        int escrowDurationInSeconds = -1;
+        long currentTimeStamp = mInjector.getCurrentTimeMillis();
+        if (armedTimestamp != -1 && currentTimeStamp > armedTimestamp) {
+            escrowDurationInSeconds = (int) (currentTimeStamp - armedTimestamp) / 1000;
+        }
 
-        // TODO(b/179105110) design error code; and report the true value for other fields.
-        int vbmetaDigestStatus = FrameworkStatsLog
-                .REBOOT_ESCROW_RECOVERY_REPORTED__VBMETA_DIGEST_STATUS__MATCH_EXPECTED_SLOT;
+        int vbmetaDigestStatus = getVbmetaDigestStatusOnRestoreComplete();
+        if (!success && mLoadEscrowDataErrorCode == ERROR_NONE) {
+            mLoadEscrowDataErrorCode = ERROR_UNKNOWN;
+        }
 
-        mInjector.reportMetric(success, 0 /* error code */, serviceType, attemptCount,
+        // TODO(179105110) report the duration since boot complete.
+        mInjector.reportMetric(success, mLoadEscrowDataErrorCode, serviceType, attemptCount,
                 escrowDurationInSeconds, vbmetaDigestStatus, -1);
+
+        mLoadEscrowDataErrorCode = ERROR_NONE;
     }
 
     private void onEscrowRestoreComplete(boolean success, int attemptCount) {
         int previousBootCount = mStorage.getInt(REBOOT_ESCROW_ARMED_KEY, -1, USER_SYSTEM);
-        mStorage.removeKey(REBOOT_ESCROW_ARMED_KEY, USER_SYSTEM);
 
         int bootCountDelta = mInjector.getBootCount() - previousBootCount;
         if (success || (previousBootCount != -1 && bootCountDelta <= BOOT_COUNT_TOLERANCE)) {
             reportMetricOnRestoreComplete(success, attemptCount);
         }
+        clearMetricsStorage();
     }
 
     private RebootEscrowKey getAndClearRebootEscrowKey(SecretKey kk) throws IOException {
@@ -358,6 +472,14 @@
         if (rebootEscrowProvider == null) {
             Slog.w(TAG,
                     "Had reboot escrow data for users, but RebootEscrowProvider is unavailable");
+            mLoadEscrowDataErrorCode = ERROR_NO_PROVIDER;
+            return null;
+        }
+
+        // Server based RoR always need the decryption key from keystore.
+        if (rebootEscrowProvider.getType() == RebootEscrowProviderInterface.TYPE_SERVER_BASED
+                && kk == null) {
+            mLoadEscrowDataErrorCode = ERROR_KEYSTORE_FAILURE;
             return null;
         }
 
@@ -463,7 +585,7 @@
             return;
         }
 
-        mStorage.removeKey(REBOOT_ESCROW_ARMED_KEY, USER_SYSTEM);
+        clearMetricsStorage();
         rebootEscrowProvider.clearRebootEscrowKey();
 
         List<UserInfo> users = mUserManager.getUsers();
@@ -486,6 +608,9 @@
             return false;
         }
 
+        int actualProviderType = rebootEscrowProvider.getType();
+        // TODO(b/183140900) Fail the reboot if provider type mismatches.
+
         RebootEscrowKey escrowKey;
         synchronized (mKeyGenerationLock) {
             escrowKey = mPendingRebootEscrowKey;
@@ -505,8 +630,14 @@
         boolean armedRebootEscrow = rebootEscrowProvider.storeRebootEscrowKey(escrowKey, kk);
         if (armedRebootEscrow) {
             mStorage.setInt(REBOOT_ESCROW_ARMED_KEY, mInjector.getBootCount(), USER_SYSTEM);
-            mStorage.setLong(REBOOT_ESCROW_KEY_ARMED_TIMESTAMP, System.currentTimeMillis(),
+            mStorage.setLong(REBOOT_ESCROW_KEY_ARMED_TIMESTAMP, mInjector.getCurrentTimeMillis(),
                     USER_SYSTEM);
+            // Store the vbmeta digest of both slots.
+            mStorage.setString(REBOOT_ESCROW_KEY_VBMETA_DIGEST, mInjector.getVbmetaDigest(false),
+                    USER_SYSTEM);
+            mStorage.setString(REBOOT_ESCROW_KEY_OTHER_VBMETA_DIGEST,
+                    mInjector.getVbmetaDigest(true), USER_SYSTEM);
+            mStorage.setInt(REBOOT_ESCROW_KEY_PROVIDER, actualProviderType, USER_SYSTEM);
             mEventLog.addEntry(RebootEscrowEvent.SET_ARMED_STATUS);
         }
 
diff --git a/services/core/java/com/android/server/locksettings/RebootEscrowProviderHalImpl.java b/services/core/java/com/android/server/locksettings/RebootEscrowProviderHalImpl.java
index 4b00772..e8f6f4a 100644
--- a/services/core/java/com/android/server/locksettings/RebootEscrowProviderHalImpl.java
+++ b/services/core/java/com/android/server/locksettings/RebootEscrowProviderHalImpl.java
@@ -60,6 +60,11 @@
     }
 
     @Override
+    public int getType() {
+        return TYPE_HAL;
+    }
+
+    @Override
     public boolean hasRebootEscrowSupport() {
         return mInjector.getRebootEscrow() != null;
     }
diff --git a/services/core/java/com/android/server/locksettings/RebootEscrowProviderInterface.java b/services/core/java/com/android/server/locksettings/RebootEscrowProviderInterface.java
index af6faad..e106d81 100644
--- a/services/core/java/com/android/server/locksettings/RebootEscrowProviderInterface.java
+++ b/services/core/java/com/android/server/locksettings/RebootEscrowProviderInterface.java
@@ -16,7 +16,11 @@
 
 package com.android.server.locksettings;
 
+import android.annotation.IntDef;
+
 import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 
 import javax.crypto.SecretKey;
 
@@ -28,6 +32,21 @@
  * @hide
  */
 public interface RebootEscrowProviderInterface {
+    @IntDef(prefix = {"TYPE_"}, value = {
+            TYPE_HAL,
+            TYPE_SERVER_BASED,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    @interface RebootEscrowProviderType {
+    }
+    int TYPE_HAL = 0;
+    int TYPE_SERVER_BASED = 1;
+
+    /**
+     * Returns the reboot escrow provider type.
+     */
+    @RebootEscrowProviderType int getType();
+
     /**
      * Returns true if the secure store/discard of reboot escrow key is supported.
      */
diff --git a/services/core/java/com/android/server/locksettings/RebootEscrowProviderServerBasedImpl.java b/services/core/java/com/android/server/locksettings/RebootEscrowProviderServerBasedImpl.java
index 697bf08..2866987 100644
--- a/services/core/java/com/android/server/locksettings/RebootEscrowProviderServerBasedImpl.java
+++ b/services/core/java/com/android/server/locksettings/RebootEscrowProviderServerBasedImpl.java
@@ -95,6 +95,11 @@
     }
 
     @Override
+    public int getType() {
+        return TYPE_SERVER_BASED;
+    }
+
+    @Override
     public boolean hasRebootEscrowSupport() {
         return mInjector.getServiceConnection() != null;
     }
diff --git a/services/core/java/com/android/server/media/MediaButtonReceiverHolder.java b/services/core/java/com/android/server/media/MediaButtonReceiverHolder.java
index cb0a6688..bb996a0 100644
--- a/services/core/java/com/android/server/media/MediaButtonReceiverHolder.java
+++ b/services/core/java/com/android/server/media/MediaButtonReceiverHolder.java
@@ -64,13 +64,6 @@
     private static final int PACKAGE_MANAGER_COMMON_FLAGS =
             PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
 
-    /**
-     * Denotes the duration during which a media button receiver will be exempted from
-     * FGS-from-BG restriction and so will be allowed to start an FGS even if it is in the
-     * background state while it receives a media key event.
-     */
-    private static final long FGS_STARTS_TEMP_ALLOWLIST_DURATION_MS = 10_000;
-
     private final int mUserId;
     private final PendingIntent mPendingIntent;
     private final ComponentName mComponentName;
@@ -185,10 +178,13 @@
      *                           Ignored if there's no valid pending intent.
      * @param handler handler to be used to call onFinishedListener
      *                Ignored if there's no valid pending intent.
+     * @param fgsAllowlistDurationMs duration for which the media button receiver will be
+     *                               allowed to start FGS from BG.
      * @see PendingIntent#send(Context, int, Intent, PendingIntent.OnFinished, Handler)
      */
     public boolean send(Context context, KeyEvent keyEvent, String callingPackageName,
-            int resultCode, PendingIntent.OnFinished onFinishedListener, Handler handler) {
+            int resultCode, PendingIntent.OnFinished onFinishedListener, Handler handler,
+            long fgsAllowlistDurationMs) {
         Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
         mediaButtonIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
         mediaButtonIntent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
@@ -196,7 +192,7 @@
         mediaButtonIntent.putExtra(Intent.EXTRA_PACKAGE_NAME, callingPackageName);
 
         final BroadcastOptions options = BroadcastOptions.makeBasic();
-        options.setTemporaryAppAllowlist(FGS_STARTS_TEMP_ALLOWLIST_DURATION_MS,
+        options.setTemporaryAppAllowlist(fgsAllowlistDurationMs,
                 PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
                 PowerWhitelistManager.REASON_MEDIA_BUTTON, "");
         if (mPendingIntent != null) {
diff --git a/services/core/java/com/android/server/media/MediaSessionDeviceConfig.java b/services/core/java/com/android/server/media/MediaSessionDeviceConfig.java
new file mode 100644
index 0000000..9bb8e2e
--- /dev/null
+++ b/services/core/java/com/android/server/media/MediaSessionDeviceConfig.java
@@ -0,0 +1,101 @@
+/*
+ * 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.media;
+
+import android.content.Context;
+import android.provider.DeviceConfig;
+import android.text.TextUtils;
+
+import java.io.PrintWriter;
+import java.util.Set;
+
+class MediaSessionDeviceConfig {
+    /**
+     * Denotes the duration for which a media button receiver will be exempted from
+     * FGS-from-BG restriction and so will be allowed to start an FGS even if it is in the
+     * background state while it receives a media key event.
+     */
+    private static final String KEY_MEDIA_BUTTON_RECEIVER_FGS_ALLOWLIST_DURATION_MS =
+            "media_button_receiver_fgs_allowlist_duration_ms";
+    private static final long DEFAULT_MEDIA_BUTTON_RECEIVER_FGS_ALLOWLIST_DURATION_MS = 10_000;
+    private static volatile long sMediaButtonReceiverFgsAllowlistDurationMs =
+            DEFAULT_MEDIA_BUTTON_RECEIVER_FGS_ALLOWLIST_DURATION_MS;
+
+    /**
+     * Denotes the duration for which an app receiving a media session callback will be
+     * exempted from FGS-from-BG restriction and so will be allowed to start an FGS even if
+     * it is in the background state while it receives a media session callback.
+     */
+    private static final String KEY_MEDIA_SESSION_CALLBACK_FGS_ALLOWLIST_DURATION_MS =
+            "media_session_calback_fgs_allowlist_duration_ms";
+    private static final long DEFAULT_MEDIA_SESSION_CALLBACK_FGS_ALLOWLIST_DURATION_MS = 10_000;
+    private static volatile long sMediaSessionCallbackFgsAllowlistDurationMs =
+            DEFAULT_MEDIA_SESSION_CALLBACK_FGS_ALLOWLIST_DURATION_MS;
+
+    private static void refresh(DeviceConfig.Properties properties) {
+        final Set<String> keys = properties.getKeyset();
+        properties.getKeyset().forEach(key -> {
+            switch (key) {
+                case KEY_MEDIA_BUTTON_RECEIVER_FGS_ALLOWLIST_DURATION_MS:
+                    sMediaButtonReceiverFgsAllowlistDurationMs = properties.getLong(key,
+                            DEFAULT_MEDIA_BUTTON_RECEIVER_FGS_ALLOWLIST_DURATION_MS);
+                    break;
+                case KEY_MEDIA_SESSION_CALLBACK_FGS_ALLOWLIST_DURATION_MS:
+                    sMediaSessionCallbackFgsAllowlistDurationMs = properties.getLong(key,
+                            DEFAULT_MEDIA_SESSION_CALLBACK_FGS_ALLOWLIST_DURATION_MS);
+                    break;
+            }
+        });
+    }
+
+    public static void initialize(Context context) {
+        DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_MEDIA,
+                context.getMainExecutor(), properties -> refresh(properties));
+        refresh(DeviceConfig.getProperties(DeviceConfig.NAMESPACE_MEDIA));
+    }
+
+    /**
+     * Returns the duration for which a media button receiver will be exempted from
+     * FGS-from-BG restriction and so will be allowed to start an FGS even if it is in the
+     * background state while it receives a media key event.
+     */
+    public static long getMediaButtonReceiverFgsAllowlistDurationMs() {
+        return sMediaButtonReceiverFgsAllowlistDurationMs;
+    }
+
+    /**
+     * Returns the duration for which an app receiving a media session callback will be
+     * exempted from FGS-from-BG restriction and so will be allowed to start an FGS even if
+     * it is in the background state while it receives a media session callback.
+     */
+    public static long getMediaSessionCallbackFgsAllowlistDurationMs() {
+        return sMediaSessionCallbackFgsAllowlistDurationMs;
+    }
+
+    public static void dump(PrintWriter pw, String prefix) {
+        pw.println("Media session config:");
+        final String dumpFormat = prefix + "  %s: [cur: %s, def: %s]";
+        pw.println(TextUtils.formatSimple(dumpFormat,
+                KEY_MEDIA_BUTTON_RECEIVER_FGS_ALLOWLIST_DURATION_MS,
+                sMediaButtonReceiverFgsAllowlistDurationMs,
+                DEFAULT_MEDIA_BUTTON_RECEIVER_FGS_ALLOWLIST_DURATION_MS));
+        pw.println(TextUtils.formatSimple(dumpFormat,
+                KEY_MEDIA_SESSION_CALLBACK_FGS_ALLOWLIST_DURATION_MS,
+                sMediaSessionCallbackFgsAllowlistDurationMs,
+                DEFAULT_MEDIA_SESSION_CALLBACK_FGS_ALLOWLIST_DURATION_MS));
+    }
+}
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index 46ece74..50cfe1f 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -117,13 +117,6 @@
      */
     private static final String MEDIA_BUTTON_RECEIVER = "media_button_receiver";
 
-    /**
-     * Denotes the duration during which an app receiving a media session callback will be
-     * exempted from FGS-from-BG restriction and so will be allowed to start an FGS even if it is
-     * in the background state while it receives a media session callback.
-     */
-    private static final long FGS_STARTS_TEMP_ALLOWLIST_DURATION_MS = 10_000;
-
     private final Context mContext;
     private final SessionManagerImpl mSessionManagerImpl;
     private final MessageHandler mHandler = new MessageHandler();
@@ -244,6 +237,9 @@
                 mCommunicationManager.registerSessionCallback(new HandlerExecutor(mHandler),
                         mSession2TokenCallback);
                 break;
+            case PHASE_ACTIVITY_MANAGER_READY:
+                MediaSessionDeviceConfig.initialize(mContext);
+                break;
         }
     }
 
@@ -563,8 +559,8 @@
                 final PowerExemptionManager powerExemptionManager = userContext.getSystemService(
                         PowerExemptionManager.class);
                 powerExemptionManager.addToTemporaryAllowList(targetPackage,
-                        FGS_STARTS_TEMP_ALLOWLIST_DURATION_MS,
-                        PowerExemptionManager.REASON_MEDIA_SESSION_CALLBACK, reason);
+                        PowerExemptionManager.REASON_MEDIA_SESSION_CALLBACK, reason,
+                        MediaSessionDeviceConfig.getMediaSessionCallbackFgsAllowlistDurationMs());
             }
         } finally {
             Binder.restoreCallingIdentity(token);
@@ -1225,6 +1221,70 @@
         }
 
         @Override
+        public MediaSession.Token getMediaKeyEventSession() {
+            final int pid = Binder.getCallingPid();
+            final int uid = Binder.getCallingUid();
+            final int userId = UserHandle.getUserHandleForUid(uid).getIdentifier();
+            final long token = Binder.clearCallingIdentity();
+            try {
+                if (!hasMediaControlPermission(pid, uid)) {
+                    throw new SecurityException("MEDIA_CONTENT_CONTROL permission is required to"
+                            + " get the media key event session");
+                }
+                MediaSessionRecordImpl record;
+                synchronized (mLock) {
+                    FullUserRecord user = getFullUserRecordLocked(userId);
+                    if (user == null) {
+                        Log.w(TAG, "No matching user record to get the media key event session"
+                                + ", userId=" + userId);
+                        return null;
+                    }
+                    record = user.getMediaButtonSessionLocked();
+                }
+                if (record instanceof MediaSessionRecord) {
+                    return ((MediaSessionRecord) record).getSessionToken();
+                }
+                //TODO: Handle media session 2 case
+                return null;
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        @Override
+        public String getMediaKeyEventSessionPackageName() {
+            final int pid = Binder.getCallingPid();
+            final int uid = Binder.getCallingUid();
+            final int userId = UserHandle.getUserHandleForUid(uid).getIdentifier();
+            final long token = Binder.clearCallingIdentity();
+            try {
+                if (!hasMediaControlPermission(pid, uid)) {
+                    throw new SecurityException("MEDIA_CONTENT_CONTROL permission is required to"
+                            + " get the media key event session package");
+                }
+                MediaSessionRecordImpl record;
+                synchronized (mLock) {
+                    FullUserRecord user = getFullUserRecordLocked(userId);
+                    if (user == null) {
+                        Log.w(TAG, "No matching user record to get the media key event session"
+                                + " package , userId=" + userId);
+                        return "";
+                    }
+                    record = user.getMediaButtonSessionLocked();
+                    if (record instanceof MediaSessionRecord) {
+                        return record.getPackageName();
+                    //TODO: Handle media session 2 case
+                    } else if (user.mLastMediaButtonReceiverHolder != null) {
+                        return user.mLastMediaButtonReceiverHolder.getPackageName();
+                    }
+                }
+                return "";
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        @Override
         public void addSessionsListener(IActiveSessionsListener listener,
                 ComponentName componentName, int userId) throws RemoteException {
             final int pid = Binder.getCallingPid();
@@ -1915,6 +1975,7 @@
                 }
                 mAudioPlayerStateMonitor.dump(mContext, pw, "");
             }
+            MediaSessionDeviceConfig.dump(pw, "");
         }
 
         /**
@@ -2198,7 +2259,8 @@
                 boolean sent = mediaButtonReceiverHolder.send(
                         mContext, keyEvent, callingPackageName,
                         needWakeLock ? mKeyEventReceiver.mLastTimeoutId : -1, mKeyEventReceiver,
-                        mHandler);
+                        mHandler,
+                        MediaSessionDeviceConfig.getMediaButtonReceiverFgsAllowlistDurationMs());
                 if (sent) {
                     String pkgName = mediaButtonReceiverHolder.getPackageName();
                     for (FullUserRecord.OnMediaKeyEventDispatchedListenerRecord cr
diff --git a/services/core/java/com/android/server/media/metrics/MediaMetricsManagerService.java b/services/core/java/com/android/server/media/metrics/MediaMetricsManagerService.java
index 23195bb..1e0142c 100644
--- a/services/core/java/com/android/server/media/metrics/MediaMetricsManagerService.java
+++ b/services/core/java/com/android/server/media/metrics/MediaMetricsManagerService.java
@@ -75,6 +75,8 @@
                     .writeLong(metrics.getNetworkBytesRead())
                     .writeLong(metrics.getLocalBytesRead())
                     .writeLong(metrics.getNetworkTransferDurationMillis())
+                    // Raw bytes type not allowed in atoms
+                    .writeString(Base64.encodeToString(metrics.getDrmSessionId(), Base64.DEFAULT))
                     .usePooledBuffer()
                     .build();
             StatsLog.write(statsEvent);
@@ -154,9 +156,10 @@
                     .writeString(event.getLanguage())
                     .writeString(event.getLanguageRegion())
                     .writeInt(event.getChannelCount())
-                    .writeInt(event.getSampleRate())
+                    .writeInt(event.getAudioSampleRate())
                     .writeInt(event.getWidth())
                     .writeInt(event.getHeight())
+                    .writeFloat(event.getVideoFrameRate())
                     .usePooledBuffer()
                     .build();
             StatsLog.write(statsEvent);
diff --git a/services/core/java/com/android/server/net/IpConfigStore.java b/services/core/java/com/android/server/net/IpConfigStore.java
index cc3a002..df1eb6d 100644
--- a/services/core/java/com/android/server/net/IpConfigStore.java
+++ b/services/core/java/com/android/server/net/IpConfigStore.java
@@ -22,7 +22,6 @@
 import android.net.IpConfiguration.ProxySettings;
 import android.net.LinkAddress;
 import android.net.ProxyInfo;
-import android.net.RouteInfo;
 import android.net.StaticIpConfiguration;
 import android.net.Uri;
 import android.util.ArrayMap;
@@ -42,6 +41,8 @@
 import java.io.InputStream;
 import java.net.Inet4Address;
 import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.List;
 
 public class IpConfigStore {
     private static final String TAG = "IpConfigStore";
@@ -83,25 +84,25 @@
         boolean written = false;
 
         try {
-            switch (config.ipAssignment) {
+            switch (config.getIpAssignment()) {
                 case STATIC:
                     out.writeUTF(IP_ASSIGNMENT_KEY);
-                    out.writeUTF(config.ipAssignment.toString());
-                    StaticIpConfiguration staticIpConfiguration = config.staticIpConfiguration;
+                    out.writeUTF(config.getIpAssignment().toString());
+                    StaticIpConfiguration staticIpConfiguration = config.getStaticIpConfiguration();
                     if (staticIpConfiguration != null) {
-                        if (staticIpConfiguration.ipAddress != null) {
-                            LinkAddress ipAddress = staticIpConfiguration.ipAddress;
+                        if (staticIpConfiguration.getIpAddress() != null) {
+                            LinkAddress ipAddress = staticIpConfiguration.getIpAddress();
                             out.writeUTF(LINK_ADDRESS_KEY);
                             out.writeUTF(ipAddress.getAddress().getHostAddress());
                             out.writeInt(ipAddress.getPrefixLength());
                         }
-                        if (staticIpConfiguration.gateway != null) {
+                        if (staticIpConfiguration.getGateway() != null) {
                             out.writeUTF(GATEWAY_KEY);
                             out.writeInt(0);  // Default route.
                             out.writeInt(1);  // Have a gateway.
-                            out.writeUTF(staticIpConfiguration.gateway.getHostAddress());
+                            out.writeUTF(staticIpConfiguration.getGateway().getHostAddress());
                         }
-                        for (InetAddress inetAddr : staticIpConfiguration.dnsServers) {
+                        for (InetAddress inetAddr : staticIpConfiguration.getDnsServers()) {
                             out.writeUTF(DNS_KEY);
                             out.writeUTF(inetAddr.getHostAddress());
                         }
@@ -110,7 +111,7 @@
                     break;
                 case DHCP:
                     out.writeUTF(IP_ASSIGNMENT_KEY);
-                    out.writeUTF(config.ipAssignment.toString());
+                    out.writeUTF(config.getIpAssignment().toString());
                     written = true;
                     break;
                 case UNASSIGNED:
@@ -121,13 +122,13 @@
                     break;
             }
 
-            switch (config.proxySettings) {
+            switch (config.getProxySettings()) {
                 case STATIC:
-                    ProxyInfo proxyProperties = config.httpProxy;
+                    ProxyInfo proxyProperties = config.getHttpProxy();
                     String exclusionList = ProxyUtils.exclusionListAsString(
                             proxyProperties.getExclusionList());
                     out.writeUTF(PROXY_SETTINGS_KEY);
-                    out.writeUTF(config.proxySettings.toString());
+                    out.writeUTF(config.getProxySettings().toString());
                     out.writeUTF(PROXY_HOST_KEY);
                     out.writeUTF(proxyProperties.getHost());
                     out.writeUTF(PROXY_PORT_KEY);
@@ -139,16 +140,16 @@
                     written = true;
                     break;
                 case PAC:
-                    ProxyInfo proxyPacProperties = config.httpProxy;
+                    ProxyInfo proxyPacProperties = config.getHttpProxy();
                     out.writeUTF(PROXY_SETTINGS_KEY);
-                    out.writeUTF(config.proxySettings.toString());
+                    out.writeUTF(config.getProxySettings().toString());
                     out.writeUTF(PROXY_PAC_FILE);
                     out.writeUTF(proxyPacProperties.getPacFileUrl().toString());
                     written = true;
                     break;
                 case NONE:
                     out.writeUTF(PROXY_SETTINGS_KEY);
-                    out.writeUTF(config.proxySettings.toString());
+                    out.writeUTF(config.getProxySettings().toString());
                     written = true;
                     break;
                 case UNASSIGNED:
@@ -267,11 +268,14 @@
                 IpAssignment ipAssignment = IpAssignment.DHCP;
                 ProxySettings proxySettings = ProxySettings.NONE;
                 StaticIpConfiguration staticIpConfiguration = new StaticIpConfiguration();
+                LinkAddress linkAddress = null;
+                InetAddress gatewayAddress = null;
                 String proxyHost = null;
                 String pacFileUrl = null;
                 int proxyPort = -1;
                 String exclusionList = null;
                 String key;
+                final List<InetAddress> dnsServers = new ArrayList<>();
 
                 do {
                     key = in.readUTF();
@@ -286,15 +290,15 @@
                         } else if (key.equals(IP_ASSIGNMENT_KEY)) {
                             ipAssignment = IpAssignment.valueOf(in.readUTF());
                         } else if (key.equals(LINK_ADDRESS_KEY)) {
-                            LinkAddress linkAddr =
+                            LinkAddress parsedLinkAddress =
                                     new LinkAddress(
                                             InetAddresses.parseNumericAddress(in.readUTF()),
                                             in.readInt());
-                            if (linkAddr.getAddress() instanceof Inet4Address &&
-                                    staticIpConfiguration.ipAddress == null) {
-                                staticIpConfiguration.ipAddress = linkAddr;
+                            if (parsedLinkAddress.getAddress() instanceof Inet4Address
+                                    && linkAddress == null) {
+                                linkAddress = parsedLinkAddress;
                             } else {
-                                loge("Non-IPv4 or duplicate address: " + linkAddr);
+                                loge("Non-IPv4 or duplicate address: " + parsedLinkAddress);
                             }
                         } else if (key.equals(GATEWAY_KEY)) {
                             LinkAddress dest = null;
@@ -302,8 +306,8 @@
                             if (version == 1) {
                                 // only supported default gateways - leave the dest/prefix empty
                                 gateway = InetAddresses.parseNumericAddress(in.readUTF());
-                                if (staticIpConfiguration.gateway == null) {
-                                    staticIpConfiguration.gateway = gateway;
+                                if (gatewayAddress == null) {
+                                    gatewayAddress = gateway;
                                 } else {
                                     loge("Duplicate gateway: " + gateway.getHostAddress());
                                 }
@@ -317,17 +321,18 @@
                                 if (in.readInt() == 1) {
                                     gateway = InetAddresses.parseNumericAddress(in.readUTF());
                                 }
-                                RouteInfo route = new RouteInfo(dest, gateway);
-                                if (route.isIPv4Default() &&
-                                        staticIpConfiguration.gateway == null) {
-                                    staticIpConfiguration.gateway = gateway;
+                                // If the destination is a default IPv4 route, use the gateway
+                                // address unless already set.
+                                if (dest.getAddress() instanceof Inet4Address
+                                        && dest.getPrefixLength() == 0 && gatewayAddress == null) {
+                                    gatewayAddress = gateway;
                                 } else {
-                                    loge("Non-IPv4 default or duplicate route: " + route);
+                                    loge("Non-IPv4 default or duplicate route: "
+                                            + dest.getAddress());
                                 }
                             }
                         } else if (key.equals(DNS_KEY)) {
-                            staticIpConfiguration.dnsServers.add(
-                                    InetAddresses.parseNumericAddress(in.readUTF()));
+                            dnsServers.add(InetAddresses.parseNumericAddress(in.readUTF()));
                         } else if (key.equals(PROXY_SETTINGS_KEY)) {
                             proxySettings = ProxySettings.valueOf(in.readUTF());
                         } else if (key.equals(PROXY_HOST_KEY)) {
@@ -348,25 +353,31 @@
                     }
                 } while (true);
 
+                staticIpConfiguration = new StaticIpConfiguration.Builder()
+                    .setIpAddress(linkAddress)
+                    .setGateway(gatewayAddress)
+                    .setDnsServers(dnsServers)
+                    .build();
+
                 if (uniqueToken != null) {
                     IpConfiguration config = new IpConfiguration();
                     networks.put(uniqueToken, config);
 
                     switch (ipAssignment) {
                         case STATIC:
-                            config.staticIpConfiguration = staticIpConfiguration;
-                            config.ipAssignment = ipAssignment;
+                            config.setStaticIpConfiguration(staticIpConfiguration);
+                            config.setIpAssignment(ipAssignment);
                             break;
                         case DHCP:
-                            config.ipAssignment = ipAssignment;
+                            config.setIpAssignment(ipAssignment);
                             break;
                         case UNASSIGNED:
                             loge("BUG: Found UNASSIGNED IP on file, use DHCP");
-                            config.ipAssignment = IpAssignment.DHCP;
+                            config.setIpAssignment(IpAssignment.DHCP);
                             break;
                         default:
                             loge("Ignore invalid ip assignment while reading.");
-                            config.ipAssignment = IpAssignment.UNASSIGNED;
+                            config.setIpAssignment(IpAssignment.UNASSIGNED);
                             break;
                     }
 
@@ -374,25 +385,25 @@
                         case STATIC:
                             ProxyInfo proxyInfo = ProxyInfo.buildDirectProxy(proxyHost, proxyPort,
                                     ProxyUtils.exclusionStringAsList(exclusionList));
-                            config.proxySettings = proxySettings;
-                            config.httpProxy = proxyInfo;
+                            config.setProxySettings(proxySettings);
+                            config.setHttpProxy(proxyInfo);
                             break;
                         case PAC:
                             ProxyInfo proxyPacProperties =
                                     ProxyInfo.buildPacProxy(Uri.parse(pacFileUrl));
-                            config.proxySettings = proxySettings;
-                            config.httpProxy = proxyPacProperties;
+                            config.setProxySettings(proxySettings);
+                            config.setHttpProxy(proxyPacProperties);
                             break;
                         case NONE:
-                            config.proxySettings = proxySettings;
+                            config.setProxySettings(proxySettings);
                             break;
                         case UNASSIGNED:
                             loge("BUG: Found UNASSIGNED proxy on file, use NONE");
-                            config.proxySettings = ProxySettings.NONE;
+                            config.setProxySettings(ProxySettings.NONE);
                             break;
                         default:
                             loge("Ignore invalid proxy settings while reading");
-                            config.proxySettings = ProxySettings.UNASSIGNED;
+                            config.setProxySettings(ProxySettings.UNASSIGNED);
                             break;
                     }
                 } else {
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java b/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java
index 39ed7e8..2e4d41c 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java
@@ -96,9 +96,10 @@
 
     /**
      *  Notifies that the specified {@link NetworkStatsProvider} has reached its quota
-     *  which was set through {@link NetworkStatsProvider#onSetLimit(String, long)}.
+     *  which was set through {@link NetworkStatsProvider#onSetLimit(String, long)} or
+     *  {@link NetworkStatsProvider#onSetWarningAndLimit(String, long, long)}.
      *
      * @param tag the human readable identifier of the custom network stats provider.
      */
-    public abstract void onStatsProviderLimitReached(@NonNull String tag);
+    public abstract void onStatsProviderWarningOrLimitReached(@NonNull String tag);
 }
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 350563f..40eefca 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -40,6 +40,15 @@
 import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_ADMIN_DISABLED;
+import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_DATA_SAVER;
+import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_MASK;
+import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_USER_RESTRICTED;
+import static android.net.ConnectivityManager.BLOCKED_REASON_APP_STANDBY;
+import static android.net.ConnectivityManager.BLOCKED_REASON_BATTERY_SAVER;
+import static android.net.ConnectivityManager.BLOCKED_REASON_DOZE;
+import static android.net.ConnectivityManager.BLOCKED_REASON_NONE;
+import static android.net.ConnectivityManager.BLOCKED_REASON_RESTRICTED_MODE;
 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
 import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED;
 import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED;
@@ -58,7 +67,9 @@
 import static android.net.NetworkPolicy.LIMIT_DISABLED;
 import static android.net.NetworkPolicy.SNOOZE_NEVER;
 import static android.net.NetworkPolicy.WARNING_DISABLED;
+import static android.net.NetworkPolicyManager.ALLOWED_METERED_REASON_FOREGROUND;
 import static android.net.NetworkPolicyManager.ALLOWED_METERED_REASON_MASK;
+import static android.net.NetworkPolicyManager.ALLOWED_METERED_REASON_SYSTEM;
 import static android.net.NetworkPolicyManager.ALLOWED_METERED_REASON_USER_EXEMPTED;
 import static android.net.NetworkPolicyManager.ALLOWED_REASON_FOREGROUND;
 import static android.net.NetworkPolicyManager.ALLOWED_REASON_NONE;
@@ -66,15 +77,6 @@
 import static android.net.NetworkPolicyManager.ALLOWED_REASON_POWER_SAVE_EXCEPT_IDLE_ALLOWLIST;
 import static android.net.NetworkPolicyManager.ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS;
 import static android.net.NetworkPolicyManager.ALLOWED_REASON_SYSTEM;
-import static android.net.NetworkPolicyManager.BLOCKED_METERED_REASON_ADMIN_DISABLED;
-import static android.net.NetworkPolicyManager.BLOCKED_METERED_REASON_DATA_SAVER;
-import static android.net.NetworkPolicyManager.BLOCKED_METERED_REASON_MASK;
-import static android.net.NetworkPolicyManager.BLOCKED_METERED_REASON_USER_RESTRICTED;
-import static android.net.NetworkPolicyManager.BLOCKED_REASON_APP_STANDBY;
-import static android.net.NetworkPolicyManager.BLOCKED_REASON_BATTERY_SAVER;
-import static android.net.NetworkPolicyManager.BLOCKED_REASON_DOZE;
-import static android.net.NetworkPolicyManager.BLOCKED_REASON_NONE;
-import static android.net.NetworkPolicyManager.BLOCKED_REASON_RESTRICTED_MODE;
 import static android.net.NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE;
 import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT;
 import static android.net.NetworkPolicyManager.MASK_ALL_NETWORKS;
@@ -178,7 +180,6 @@
 import android.net.INetworkPolicyListener;
 import android.net.INetworkPolicyManager;
 import android.net.INetworkStatsService;
-import android.net.LinkProperties;
 import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.net.NetworkIdentity;
@@ -421,15 +422,15 @@
     private static final int MSG_LIMIT_REACHED = 5;
     private static final int MSG_RESTRICT_BACKGROUND_CHANGED = 6;
     private static final int MSG_ADVISE_PERSIST_THRESHOLD = 7;
-    private static final int MSG_UPDATE_INTERFACE_QUOTA = 10;
-    private static final int MSG_REMOVE_INTERFACE_QUOTA = 11;
+    private static final int MSG_UPDATE_INTERFACE_QUOTAS = 10;
+    private static final int MSG_REMOVE_INTERFACE_QUOTAS = 11;
     private static final int MSG_POLICIES_CHANGED = 13;
     private static final int MSG_RESET_FIREWALL_RULES_BY_UID = 15;
     private static final int MSG_SUBSCRIPTION_OVERRIDE = 16;
     private static final int MSG_METERED_RESTRICTED_PACKAGES_CHANGED = 17;
     private static final int MSG_SET_NETWORK_TEMPLATE_ENABLED = 18;
     private static final int MSG_SUBSCRIPTION_PLANS_CHANGED = 19;
-    private static final int MSG_STATS_PROVIDER_LIMIT_REACHED = 20;
+    private static final int MSG_STATS_PROVIDER_WARNING_OR_LIMIT_REACHED = 20;
     // TODO: Add similar docs for other messages.
     /**
      * Message to indicate that reasons for why an uid is blocked changed.
@@ -1919,16 +1920,7 @@
      * Collect all ifaces from a {@link NetworkStateSnapshot} into the given set.
      */
     private static void collectIfaces(ArraySet<String> ifaces, NetworkStateSnapshot snapshot) {
-        final String baseIface = snapshot.linkProperties.getInterfaceName();
-        if (baseIface != null) {
-            ifaces.add(baseIface);
-        }
-        for (LinkProperties stackedLink : snapshot.linkProperties.getStackedLinks()) {
-            final String stackedIface = stackedLink.getInterfaceName();
-            if (stackedIface != null) {
-                ifaces.add(stackedIface);
-            }
-        }
+        ifaces.addAll(snapshot.linkProperties.getAllInterfaceNames());
     }
 
     /**
@@ -2042,39 +2034,45 @@
 
             final boolean hasWarning = policy.warningBytes != LIMIT_DISABLED;
             final boolean hasLimit = policy.limitBytes != LIMIT_DISABLED;
-            if (hasLimit || policy.metered) {
-                final long quotaBytes;
-                if (hasLimit && policy.hasCycle()) {
-                    final Pair<ZonedDateTime, ZonedDateTime> cycle = NetworkPolicyManager
-                            .cycleIterator(policy).next();
-                    final long start = cycle.first.toInstant().toEpochMilli();
-                    final long end = cycle.second.toInstant().toEpochMilli();
-                    final long totalBytes = getTotalBytes(policy.template, start, end);
+            long limitBytes = Long.MAX_VALUE;
+            long warningBytes = Long.MAX_VALUE;
+            if ((hasLimit || hasWarning) && policy.hasCycle()) {
+                final Pair<ZonedDateTime, ZonedDateTime> cycle = NetworkPolicyManager
+                        .cycleIterator(policy).next();
+                final long start = cycle.first.toInstant().toEpochMilli();
+                final long end = cycle.second.toInstant().toEpochMilli();
+                final long totalBytes = getTotalBytes(policy.template, start, end);
 
-                    if (policy.lastLimitSnooze >= start) {
-                        // snoozing past quota, but we still need to restrict apps,
-                        // so push really high quota.
-                        quotaBytes = Long.MAX_VALUE;
-                    } else {
-                        // remaining "quota" bytes are based on total usage in
-                        // current cycle. kernel doesn't like 0-byte rules, so we
-                        // set 1-byte quota and disable the radio later.
-                        quotaBytes = Math.max(1, policy.limitBytes - totalBytes);
-                    }
-                } else {
-                    // metered network, but no policy limit; we still need to
-                    // restrict apps, so push really high quota.
-                    quotaBytes = Long.MAX_VALUE;
+                // If the limit notification is not snoozed, the limit quota needs to be calculated.
+                if (hasLimit && policy.lastLimitSnooze < start) {
+                    // remaining "quota" bytes are based on total usage in
+                    // current cycle. kernel doesn't like 0-byte rules, so we
+                    // set 1-byte quota and disable the radio later.
+                    limitBytes = Math.max(1, policy.limitBytes - totalBytes);
                 }
 
+                // If the warning notification was snoozed by user, or the service already knows
+                // it is over warning bytes, doesn't need to calculate warning bytes.
+                if (hasWarning && policy.lastWarningSnooze < start
+                        && !policy.isOverWarning(totalBytes)) {
+                    warningBytes = Math.max(1, policy.warningBytes - totalBytes);
+                }
+            }
+
+            if (hasWarning || hasLimit || policy.metered) {
                 if (matchingIfaces.size() > 1) {
                     // TODO: switch to shared quota once NMS supports
                     Slog.w(TAG, "shared quota unsupported; generating rule for each iface");
                 }
 
+                // Set the interface warning and limit. For interfaces which has no cycle,
+                // or metered with no policy quotas, or snoozed notification; we still need to put
+                // iptables rule hooks to restrict apps for data saver, so push really high quota.
+                // TODO: Push NetworkStatsProvider.QUOTA_UNLIMITED instead of Long.MAX_VALUE to
+                //  providers.
                 for (int j = matchingIfaces.size() - 1; j >= 0; j--) {
                     final String iface = matchingIfaces.valueAt(j);
-                    setInterfaceQuotaAsync(iface, quotaBytes);
+                    setInterfaceQuotasAsync(iface, warningBytes, limitBytes);
                     newMeteredIfaces.add(iface);
                 }
             }
@@ -2097,7 +2095,7 @@
                 for (int j = matchingIfaces.size() - 1; j >= 0; j--) {
                     final String iface = matchingIfaces.valueAt(j);
                     if (!newMeteredIfaces.contains(iface)) {
-                        setInterfaceQuotaAsync(iface, Long.MAX_VALUE);
+                        setInterfaceQuotasAsync(iface, Long.MAX_VALUE, Long.MAX_VALUE);
                         newMeteredIfaces.add(iface);
                     }
                 }
@@ -2109,7 +2107,7 @@
             for (int i = mMeteredIfaces.size() - 1; i >= 0; i--) {
                 final String iface = mMeteredIfaces.valueAt(i);
                 if (!newMeteredIfaces.contains(iface)) {
-                    removeInterfaceQuotaAsync(iface);
+                    removeInterfaceQuotasAsync(iface);
                 }
             }
             mMeteredIfaces = newMeteredIfaces;
@@ -4634,8 +4632,8 @@
         newBlockedReasons |= (mRestrictBackground ? BLOCKED_METERED_REASON_DATA_SAVER : 0);
         newBlockedReasons |= (isDenied ? BLOCKED_METERED_REASON_USER_RESTRICTED : 0);
 
-        newAllowedReasons |= (isSystem(uid) ? ALLOWED_REASON_SYSTEM : 0);
-        newAllowedReasons |= (isForeground ? ALLOWED_REASON_FOREGROUND : 0);
+        newAllowedReasons |= (isSystem(uid) ? ALLOWED_METERED_REASON_SYSTEM : 0);
+        newAllowedReasons |= (isForeground ? ALLOWED_METERED_REASON_FOREGROUND : 0);
         newAllowedReasons |= (isAllowed ? ALLOWED_METERED_REASON_USER_EXEMPTED : 0);
 
         if (LOGV) {
@@ -4709,18 +4707,18 @@
 
             // Dispatch changed rule to existing listeners.
             mHandler.obtainMessage(MSG_RULES_CHANGED, uid, newUidRules).sendToTarget();
+        }
 
-            final int oldEffectiveBlockedReasons = uidBlockedState.effectiveBlockedReasons;
-            uidBlockedState.blockedReasons = (uidBlockedState.blockedReasons
-                    & ~BLOCKED_METERED_REASON_MASK) | newBlockedReasons;
-            uidBlockedState.allowedReasons = (uidBlockedState.allowedReasons
-                    & ~ALLOWED_METERED_REASON_MASK) | newAllowedReasons;
-            uidBlockedState.updateEffectiveBlockedReasons();
-            if (oldEffectiveBlockedReasons != uidBlockedState.effectiveBlockedReasons) {
-                mHandler.obtainMessage(MSG_BLOCKED_REASON_CHANGED, uid,
-                        uidBlockedState.effectiveBlockedReasons, oldEffectiveBlockedReasons)
-                        .sendToTarget();
-            }
+        final int oldEffectiveBlockedReasons = uidBlockedState.effectiveBlockedReasons;
+        uidBlockedState.blockedReasons = (uidBlockedState.blockedReasons
+                & ~BLOCKED_METERED_REASON_MASK) | newBlockedReasons;
+        uidBlockedState.allowedReasons = (uidBlockedState.allowedReasons
+                & ~ALLOWED_METERED_REASON_MASK) | newAllowedReasons;
+        uidBlockedState.updateEffectiveBlockedReasons();
+        if (oldEffectiveBlockedReasons != uidBlockedState.effectiveBlockedReasons) {
+            mHandler.obtainMessage(MSG_BLOCKED_REASON_CHANGED, uid,
+                    uidBlockedState.effectiveBlockedReasons, oldEffectiveBlockedReasons)
+                    .sendToTarget();
         }
     }
 
@@ -4978,7 +4976,7 @@
                     mListeners.finishBroadcast();
                     return true;
                 }
-                case MSG_STATS_PROVIDER_LIMIT_REACHED: {
+                case MSG_STATS_PROVIDER_WARNING_OR_LIMIT_REACHED: {
                     mNetworkStats.forceUpdate();
 
                     synchronized (mNetworkPoliciesSecondLock) {
@@ -5049,19 +5047,20 @@
                     mNetworkStats.advisePersistThreshold(persistThreshold);
                     return true;
                 }
-                case MSG_UPDATE_INTERFACE_QUOTA: {
-                    final String iface = (String) msg.obj;
-                    // int params need to be stitched back into a long
-                    final long quota = ((long) msg.arg1 << 32) | (msg.arg2 & 0xFFFFFFFFL);
-                    removeInterfaceQuota(iface);
-                    setInterfaceQuota(iface, quota);
-                    mNetworkStats.setStatsProviderLimitAsync(iface, quota);
+                case MSG_UPDATE_INTERFACE_QUOTAS: {
+                    final IfaceQuotas val = (IfaceQuotas) msg.obj;
+                    // TODO: Consider set a new limit before removing the original one.
+                    removeInterfaceLimit(val.iface);
+                    setInterfaceLimit(val.iface, val.limit);
+                    mNetworkStats.setStatsProviderWarningAndLimitAsync(val.iface, val.warning,
+                            val.limit);
                     return true;
                 }
-                case MSG_REMOVE_INTERFACE_QUOTA: {
+                case MSG_REMOVE_INTERFACE_QUOTAS: {
                     final String iface = (String) msg.obj;
-                    removeInterfaceQuota(iface);
-                    mNetworkStats.setStatsProviderLimitAsync(iface, QUOTA_UNLIMITED);
+                    removeInterfaceLimit(iface);
+                    mNetworkStats.setStatsProviderWarningAndLimitAsync(iface, QUOTA_UNLIMITED,
+                            QUOTA_UNLIMITED);
                     return true;
                 }
                 case MSG_RESET_FIREWALL_RULES_BY_UID: {
@@ -5209,15 +5208,32 @@
         }
     }
 
-    private void setInterfaceQuotaAsync(String iface, long quotaBytes) {
-        // long quotaBytes split up into two ints to fit in message
-        mHandler.obtainMessage(MSG_UPDATE_INTERFACE_QUOTA, (int) (quotaBytes >> 32),
-                (int) (quotaBytes & 0xFFFFFFFF), iface).sendToTarget();
+    private static final class IfaceQuotas {
+        @NonNull public final String iface;
+        // Warning and limit bytes of interface qutoas, could be QUOTA_UNLIMITED or Long.MAX_VALUE
+        // if not set. 0 is not acceptable since kernel doesn't like 0-byte rules.
+        public final long warning;
+        public final long limit;
+
+        private IfaceQuotas(@NonNull String iface, long warning, long limit) {
+            this.iface = iface;
+            this.warning = warning;
+            this.limit = limit;
+        }
     }
 
-    private void setInterfaceQuota(String iface, long quotaBytes) {
+    private void setInterfaceQuotasAsync(@NonNull String iface,
+            long warningBytes, long limitBytes) {
+        mHandler.obtainMessage(MSG_UPDATE_INTERFACE_QUOTAS,
+                new IfaceQuotas(iface, warningBytes, limitBytes)).sendToTarget();
+    }
+
+    private void setInterfaceLimit(String iface, long limitBytes) {
         try {
-            mNetworkManager.setInterfaceQuota(iface, quotaBytes);
+            // For legacy design the data warning is covered by global alert, where the
+            // kernel will notify upper layer for a small amount of change of traffic
+            // statistics. Thus, passing warning is not needed.
+            mNetworkManager.setInterfaceQuota(iface, limitBytes);
         } catch (IllegalStateException e) {
             Log.wtf(TAG, "problem setting interface quota", e);
         } catch (RemoteException e) {
@@ -5225,11 +5241,11 @@
         }
     }
 
-    private void removeInterfaceQuotaAsync(String iface) {
-        mHandler.obtainMessage(MSG_REMOVE_INTERFACE_QUOTA, iface).sendToTarget();
+    private void removeInterfaceQuotasAsync(String iface) {
+        mHandler.obtainMessage(MSG_REMOVE_INTERFACE_QUOTAS, iface).sendToTarget();
     }
 
-    private void removeInterfaceQuota(String iface) {
+    private void removeInterfaceLimit(String iface) {
         try {
             mNetworkManager.removeInterfaceQuota(iface);
         } catch (IllegalStateException e) {
@@ -5734,9 +5750,9 @@
         }
 
         @Override
-        public void onStatsProviderLimitReached(@NonNull String tag) {
-            Log.v(TAG, "onStatsProviderLimitReached: " + tag);
-            mHandler.obtainMessage(MSG_STATS_PROVIDER_LIMIT_REACHED).sendToTarget();
+        public void onStatsProviderWarningOrLimitReached(@NonNull String tag) {
+            Log.v(TAG, "onStatsProviderWarningOrLimitReached: " + tag);
+            mHandler.obtainMessage(MSG_STATS_PROVIDER_WARNING_OR_LIMIT_REACHED).sendToTarget();
         }
     }
 
@@ -5868,12 +5884,17 @@
                 return;
             }
             if ((allowedReasons & ALLOWED_REASON_SYSTEM) != 0) {
-                effectiveBlockedReasons = BLOCKED_REASON_NONE;
+                effectiveBlockedReasons = (blockedReasons & ALLOWED_METERED_REASON_MASK);
+            }
+            if ((allowedReasons & ALLOWED_METERED_REASON_SYSTEM) != 0) {
+                effectiveBlockedReasons = (blockedReasons & ~ALLOWED_METERED_REASON_MASK);
             }
             if ((allowedReasons & ALLOWED_REASON_FOREGROUND) != 0) {
                 effectiveBlockedReasons &= ~BLOCKED_REASON_BATTERY_SAVER;
                 effectiveBlockedReasons &= ~BLOCKED_REASON_DOZE;
                 effectiveBlockedReasons &= ~BLOCKED_REASON_APP_STANDBY;
+            }
+            if ((allowedReasons & ALLOWED_METERED_REASON_FOREGROUND) != 0) {
                 effectiveBlockedReasons &= ~BLOCKED_METERED_REASON_DATA_SAVER;
                 effectiveBlockedReasons &= ~BLOCKED_METERED_REASON_USER_RESTRICTED;
             }
diff --git a/services/core/java/com/android/server/net/NetworkStatsManagerInternal.java b/services/core/java/com/android/server/net/NetworkStatsManagerInternal.java
index 0cb0bc2c..0e9a9da 100644
--- a/services/core/java/com/android/server/net/NetworkStatsManagerInternal.java
+++ b/services/core/java/com/android/server/net/NetworkStatsManagerInternal.java
@@ -37,8 +37,9 @@
     public abstract void forceUpdate();
 
     /**
-     * Set the quota limit to all registered custom network stats providers.
+     * Set the warning and limit to all registered custom network stats providers.
      * Note that invocation of any interface will be sent to all providers.
      */
-    public abstract void setStatsProviderLimitAsync(@NonNull String iface, long quota);
+    public abstract void setStatsProviderWarningAndLimitAsync(@NonNull String iface, long warning,
+            long limit);
 }
diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java
index 7b376847..19f5e3c 100644
--- a/services/core/java/com/android/server/net/NetworkStatsService.java
+++ b/services/core/java/com/android/server/net/NetworkStatsService.java
@@ -24,6 +24,7 @@
 import static android.content.Intent.ACTION_USER_REMOVED;
 import static android.content.Intent.EXTRA_UID;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
 import static android.net.NetworkIdentity.SUBTYPE_COMBINED;
 import static android.net.NetworkStack.checkNetworkStackPermission;
 import static android.net.NetworkStats.DEFAULT_NETWORK_ALL;
@@ -65,6 +66,7 @@
 import static android.provider.Settings.Global.NETSTATS_UID_TAG_DELETE_AGE;
 import static android.provider.Settings.Global.NETSTATS_UID_TAG_PERSIST_BYTES;
 import static android.provider.Settings.Global.NETSTATS_UID_TAG_ROTATE_AGE;
+import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
 import static android.text.format.DateUtils.DAY_IN_MILLIS;
 import static android.text.format.DateUtils.HOUR_IN_MILLIS;
 import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
@@ -92,7 +94,6 @@
 import android.net.INetworkManagementEventObserver;
 import android.net.INetworkStatsService;
 import android.net.INetworkStatsSession;
-import android.net.LinkProperties;
 import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.net.NetworkIdentity;
@@ -101,7 +102,9 @@
 import android.net.NetworkStats;
 import android.net.NetworkStats.NonMonotonicObserver;
 import android.net.NetworkStatsHistory;
+import android.net.NetworkSpecifier;
 import android.net.NetworkTemplate;
+import android.net.TelephonyNetworkSpecifier;
 import android.net.TrafficStats;
 import android.net.UnderlyingNetworkInfo;
 import android.net.Uri;
@@ -131,6 +134,7 @@
 import android.service.NetworkStatsServiceDumpProto;
 import android.telephony.PhoneStateListener;
 import android.telephony.SubscriptionPlan;
+import android.text.TextUtils;
 import android.text.format.DateUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
@@ -1320,8 +1324,9 @@
                             ident.getSubType(), ident.getSubscriberId(), ident.getNetworkId(),
                             ident.getRoaming(), true /* metered */,
                             true /* onDefaultNetwork */, ident.getOemManaged());
-                    findOrCreateNetworkIdentitySet(mActiveIfaces, IFACE_VT).add(vtIdent);
-                    findOrCreateNetworkIdentitySet(mActiveUidIfaces, IFACE_VT).add(vtIdent);
+                    final String ifaceVt = IFACE_VT + getSubIdForMobile(snapshot);
+                    findOrCreateNetworkIdentitySet(mActiveIfaces, ifaceVt).add(vtIdent);
+                    findOrCreateNetworkIdentitySet(mActiveUidIfaces, ifaceVt).add(vtIdent);
                 }
 
                 if (isMobile) {
@@ -1358,17 +1363,18 @@
             // (or non eBPF offloaded) TX they would appear on both, however egress interface
             // accounting is explicitly bypassed for traffic from the clat uid.
             //
-            final List<LinkProperties> stackedLinks = snapshot.linkProperties.getStackedLinks();
-            for (LinkProperties stackedLink : stackedLinks) {
-                final String stackedIface = stackedLink.getInterfaceName();
-                if (stackedIface != null) {
-                    findOrCreateNetworkIdentitySet(mActiveIfaces, stackedIface).add(ident);
-                    findOrCreateNetworkIdentitySet(mActiveUidIfaces, stackedIface).add(ident);
+            // TODO: This code might be combined to above code.
+            for (String iface : snapshot.linkProperties.getAllInterfaceNames()) {
+                // baseIface has been handled, so ignore it.
+                if (TextUtils.equals(baseIface, iface)) continue;
+                if (iface != null) {
+                    findOrCreateNetworkIdentitySet(mActiveIfaces, iface).add(ident);
+                    findOrCreateNetworkIdentitySet(mActiveUidIfaces, iface).add(ident);
                     if (isMobile) {
-                        mobileIfaces.add(stackedIface);
+                        mobileIfaces.add(iface);
                     }
 
-                    mStatsFactory.noteStackedIface(stackedIface, baseIface);
+                    mStatsFactory.noteStackedIface(iface, baseIface);
                 }
             }
         }
@@ -1376,6 +1382,20 @@
         mMobileIfaces = mobileIfaces.toArray(new String[mobileIfaces.size()]);
     }
 
+    private static int getSubIdForMobile(@NonNull NetworkStateSnapshot state) {
+        if (!state.networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
+            throw new IllegalArgumentException("Mobile state need capability TRANSPORT_CELLULAR");
+        }
+
+        final NetworkSpecifier spec = state.networkCapabilities.getNetworkSpecifier();
+        if (spec instanceof TelephonyNetworkSpecifier) {
+             return ((TelephonyNetworkSpecifier) spec).getSubscriptionId();
+        } else {
+            Slog.wtf(TAG, "getSubIdForState invalid NetworkSpecifier");
+            return INVALID_SUBSCRIPTION_ID;
+        }
+    }
+
     /**
      * For networks with {@code TRANSPORT_CELLULAR}, get subType that was obtained through
      * {@link PhoneStateListener}. Otherwise, return 0 given that other networks with different
@@ -1673,9 +1693,14 @@
         }
 
         @Override
-        public void setStatsProviderLimitAsync(@NonNull String iface, long quota) {
-            if (LOGV) Slog.v(TAG, "setStatsProviderLimitAsync(" + iface + "," + quota + ")");
-            invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.onSetLimit(iface, quota));
+        public void setStatsProviderWarningAndLimitAsync(
+                @NonNull String iface, long warning, long limit) {
+            if (LOGV) {
+                Slog.v(TAG, "setStatsProviderWarningAndLimitAsync("
+                        + iface + "," + warning + "," + limit + ")");
+            }
+            invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.onSetWarningAndLimit(iface,
+                    warning, limit));
         }
     }
 
@@ -2070,10 +2095,10 @@
         }
 
         @Override
-        public void notifyLimitReached() {
-            Log.d(TAG, mTag + ": onLimitReached");
+        public void notifyWarningOrLimitReached() {
+            Log.d(TAG, mTag + ": notifyWarningOrLimitReached");
             LocalServices.getService(NetworkPolicyManagerInternal.class)
-                    .onStatsProviderLimitReached(mTag);
+                    .onStatsProviderWarningOrLimitReached(mTag);
         }
 
         @Override
diff --git a/services/core/java/com/android/server/notification/ConditionProviders.java b/services/core/java/com/android/server/notification/ConditionProviders.java
index 78c1a95..3238f1f 100644
--- a/services/core/java/com/android/server/notification/ConditionProviders.java
+++ b/services/core/java/com/android/server/notification/ConditionProviders.java
@@ -25,6 +25,7 @@
 import android.net.Uri;
 import android.os.IBinder;
 import android.os.IInterface;
+import android.os.Process;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.provider.Settings;
@@ -41,8 +42,6 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.server.notification.NotificationManagerService.DumpFilter;
 
-import org.xmlpull.v1.XmlSerializer;
-
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -78,8 +77,8 @@
     public void addSystemProvider(SystemConditionProviderService service) {
         mSystemConditionProviders.add(service);
         service.attachBase(mContext);
-        registerSystemService(
-                service.asInterface(), service.getComponent(), UserHandle.USER_SYSTEM);
+        registerSystemService(service.asInterface(), service.getComponent(), UserHandle.USER_SYSTEM,
+                Process.SYSTEM_UID);
     }
 
     public Iterable<SystemConditionProviderService> getSystemProviders() {
diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java
index bbdcac2..c4a59c2 100644
--- a/services/core/java/com/android/server/notification/ManagedServices.java
+++ b/services/core/java/com/android/server/notification/ManagedServices.java
@@ -287,6 +287,7 @@
                                     && !mDefaultComponents.contains(currentComponent)) {
                                 if (approved.remove(currentComponent.flattenToString())) {
                                     disabledComponents.add(currentComponent);
+                                    clearUserSetFlagLocked(currentComponent, userId);
                                     changed = true;
                                 }
                             }
@@ -309,6 +310,12 @@
         return changes;
     }
 
+    private boolean clearUserSetFlagLocked(ComponentName component, int userId) {
+        String approvedValue = getApprovedValue(component.flattenToString());
+        ArraySet<String> userSet = mUserSetServices.get(userId);
+        return userSet != null && userSet.remove(approvedValue);
+    }
+
     protected int getBindFlags() {
         return BIND_AUTO_CREATE | BIND_FOREGROUND_SERVICE | BIND_ALLOW_WHITELIST_MANAGEMENT;
     }
@@ -317,9 +324,9 @@
 
     private ManagedServiceInfo newServiceInfo(IInterface service,
             ComponentName component, int userId, boolean isSystem, ServiceConnection connection,
-            int targetSdkVersion) {
+            int targetSdkVersion, int uid) {
         return new ManagedServiceInfo(service, component, userId, isSystem, connection,
-                targetSdkVersion);
+                targetSdkVersion, uid);
     }
 
     public void onBootPhaseAppsCanStart() {}
@@ -974,10 +981,11 @@
         unregisterServiceImpl(service, userid);
     }
 
-    public void registerSystemService(IInterface service, ComponentName component, int userid) {
+    public void registerSystemService(IInterface service, ComponentName component, int userid,
+            int uid) {
         checkNotNull(service);
         ManagedServiceInfo info = registerServiceImpl(
-                service, component, userid, Build.VERSION_CODES.CUR_DEVELOPMENT);
+                service, component, userid, Build.VERSION_CODES.CUR_DEVELOPMENT, uid);
         if (info != null) {
             onServiceAdded(info);
         }
@@ -1441,6 +1449,7 @@
         }
         final int targetSdkVersion =
             appInfo != null ? appInfo.targetSdkVersion : Build.VERSION_CODES.BASE;
+        final int uid = appInfo != null ? appInfo.uid : -1;
 
         try {
             Slog.v(TAG, "binding: " + intent);
@@ -1457,7 +1466,7 @@
                         try {
                             mService = asInterface(binder);
                             info = newServiceInfo(mService, name,
-                                userid, isSystem, this, targetSdkVersion);
+                                userid, isSystem, this, targetSdkVersion, uid);
                             binder.linkToDeath(info, 0);
                             added = mServices.add(info);
                         } catch (RemoteException e) {
@@ -1576,9 +1585,9 @@
     }
 
     private ManagedServiceInfo registerServiceImpl(final IInterface service,
-            final ComponentName component, final int userid, int targetSdk) {
+            final ComponentName component, final int userid, int targetSdk, int uid) {
         ManagedServiceInfo info = newServiceInfo(service, component, userid,
-                true /*isSystem*/, null /*connection*/, targetSdk);
+                true /*isSystem*/, null /*connection*/, targetSdk, uid);
         return registerServiceImpl(info);
     }
 
@@ -1624,15 +1633,18 @@
         public ServiceConnection connection;
         public int targetSdkVersion;
         public Pair<ComponentName, Integer> mKey;
+        public int uid;
 
         public ManagedServiceInfo(IInterface service, ComponentName component,
-                int userid, boolean isSystem, ServiceConnection connection, int targetSdkVersion) {
+                int userid, boolean isSystem, ServiceConnection connection, int targetSdkVersion,
+                int uid) {
             this.service = service;
             this.component = component;
             this.userid = userid;
             this.isSystem = isSystem;
             this.connection = connection;
             this.targetSdkVersion = targetSdkVersion;
+            this.uid = uid;
             mKey = Pair.create(component, userid);
         }
 
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index eb4f9d3..68990ba 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -60,7 +60,6 @@
 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-import static android.media.AudioAttributes.FLAG_BYPASS_INTERRUPTION_POLICY;
 import static android.media.AudioAttributes.USAGE_NOTIFICATION_RINGTONE;
 import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_CRITICAL;
 import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_NORMAL;
@@ -85,6 +84,8 @@
 import static android.service.notification.NotificationListenerService.REASON_CANCEL;
 import static android.service.notification.NotificationListenerService.REASON_CANCEL_ALL;
 import static android.service.notification.NotificationListenerService.REASON_CHANNEL_BANNED;
+import static android.service.notification.NotificationListenerService.REASON_CHANNEL_REMOVED;
+import static android.service.notification.NotificationListenerService.REASON_CLEAR_DATA;
 import static android.service.notification.NotificationListenerService.REASON_CLICK;
 import static android.service.notification.NotificationListenerService.REASON_ERROR;
 import static android.service.notification.NotificationListenerService.REASON_GROUP_SUMMARY_CANCELED;
@@ -456,6 +457,13 @@
     private static final long NOTIFICATION_TRAMPOLINE_BLOCK = 167676448L;
 
     /**
+     * Whether a notification listeners can understand new, more specific, cancellation reasons.
+     */
+    @ChangeId
+    @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.R)
+    private static final long NOTIFICATION_CANCELLATION_REASONS = 175319604L;
+
+    /**
      * Rate limit showing toasts, on a per package basis.
      *
      * It limits the number of {@link android.widget.Toast#show()} calls to prevent overburdening
@@ -3599,7 +3607,7 @@
             }
             enforceDeletingChannelHasNoFgService(pkg, callingUser, channelId);
             cancelAllNotificationsInt(MY_UID, MY_PID, pkg, channelId, 0, 0, true,
-                    callingUser, REASON_CHANNEL_BANNED, null);
+                    callingUser, REASON_CHANNEL_REMOVED, null);
             mPreferencesHelper.deleteNotificationChannel(pkg, callingUid, channelId);
             mListeners.notifyNotificationChannelChanged(pkg,
                     UserHandle.getUserHandleForUid(callingUid),
@@ -3609,34 +3617,6 @@
         }
 
         @Override
-        public void deleteConversationNotificationChannels(String pkg, int uid,
-                String conversationId) {
-            checkCallerIsSystem();
-            List<NotificationChannel> channels =
-                    mPreferencesHelper.getNotificationChannelsByConversationId(
-                            pkg, uid, conversationId);
-            if (!channels.isEmpty()) {
-                // Preflight for fg service notifications in these channels:  do nothing
-                // unless they're all eligible
-                final int appUserId = UserHandle.getUserId(uid);
-                for (NotificationChannel nc : channels) {
-                    final String channelId = nc.getId();
-                    mAmi.stopForegroundServicesForChannel(pkg, appUserId, channelId);
-                    cancelAllNotificationsInt(MY_UID, MY_PID, pkg, nc.getId(), 0, 0, true,
-                            appUserId, REASON_CHANNEL_BANNED, null);
-                    mPreferencesHelper.deleteNotificationChannel(pkg, uid, channelId);
-                    mListeners.notifyNotificationChannelChanged(pkg,
-                            UserHandle.getUserHandleForUid(uid),
-                            mPreferencesHelper.getNotificationChannel(
-                                    pkg, uid, channelId, true),
-                            NOTIFICATION_CHANNEL_OR_GROUP_DELETED);
-                }
-                handleSavePolicyFile();
-            }
-        }
-
-
-        @Override
         public NotificationChannelGroup getNotificationChannelGroup(String pkg, String groupId) {
             checkCallerIsSystemOrSameApp(pkg);
             return mPreferencesHelper.getNotificationChannelGroupWithChannels(
@@ -3672,7 +3652,7 @@
                     final NotificationChannel deletedChannel = deletedChannels.get(i);
                     cancelAllNotificationsInt(MY_UID, MY_PID, pkg, deletedChannel.getId(), 0, 0,
                             true,
-                            userId, REASON_CHANNEL_BANNED,
+                            userId, REASON_CHANNEL_REMOVED,
                             null);
                     mListeners.notifyNotificationChannelChanged(pkg,
                             UserHandle.getUserHandleForUid(callingUid),
@@ -3852,7 +3832,7 @@
             // Cancel posted notifications
             final int userId = UserHandle.getUserId(uid);
             cancelAllNotificationsInt(MY_UID, MY_PID, packageName, null, 0, 0, true,
-                    UserHandle.getUserId(Binder.getCallingUid()), REASON_CHANNEL_BANNED, null);
+                    UserHandle.getUserId(Binder.getCallingUid()), REASON_CLEAR_DATA, null);
 
             // Zen
             packagesChanged |=
@@ -4128,7 +4108,7 @@
         public void registerListener(final INotificationListener listener,
                 final ComponentName component, final int userid) {
             enforceSystemOrSystemUI("INotificationManager.registerListener");
-            mListeners.registerSystemService(listener, component, userid);
+            mListeners.registerSystemService(listener, component, userid, Binder.getCallingUid());
         }
 
         /**
@@ -6075,7 +6055,7 @@
                 mPreferencesHelper.deleteConversations(pkg, uid, shortcuts);
         for (String channelId : deletedChannelIds) {
             cancelAllNotificationsInt(MY_UID, MY_PID, pkg, channelId, 0, 0, true,
-                    UserHandle.getUserId(uid), REASON_CHANNEL_BANNED,
+                    UserHandle.getUserId(uid), REASON_CHANNEL_REMOVED,
                     null);
         }
         handleSavePolicyFile();
@@ -7482,9 +7462,11 @@
             boolean rateLimitingEnabled =
                     !mToastRateLimitingDisabledUids.contains(record.uid);
             boolean isWithinQuota =
-                    mToastRateLimiter.isWithinQuota(userId, record.pkg, TOAST_QUOTA_TAG);
+                    mToastRateLimiter.isWithinQuota(userId, record.pkg, TOAST_QUOTA_TAG)
+                            || isExemptFromRateLimiting(record.pkg, userId);
 
-            if (tryShowToast(record, rateLimitingEnabled, isWithinQuota)) {
+            if (tryShowToast(
+                    record, rateLimitingEnabled, isWithinQuota)) {
                 scheduleDurationReachedLocked(record, lastToastWasTextRecord);
                 mIsCurrentToastShown = true;
                 if (rateLimitingEnabled) {
@@ -7518,6 +7500,18 @@
         return record.show();
     }
 
+    private boolean isExemptFromRateLimiting(String pkg, int userId) {
+        boolean isExemptFromRateLimiting = false;
+        try {
+            isExemptFromRateLimiting = mPackageManager.checkPermission(
+                    android.Manifest.permission.UNLIMITED_TOASTS, pkg, userId)
+                    == PackageManager.PERMISSION_GRANTED;
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Failed to connect with package manager");
+        }
+        return isExemptFromRateLimiting;
+    }
+
     /** Reports rate limiting toasts compat change (used when the toast was blocked). */
     private void reportCompatRateLimitingToastsChange(int uid) {
         final long id = Binder.clearCallingIdentity();
@@ -10324,6 +10318,10 @@
             final INotificationListener listener = (INotificationListener) info.service;
             StatusBarNotificationHolder sbnHolder = new StatusBarNotificationHolder(sbn);
             try {
+                if (!CompatChanges.isChangeEnabled(NOTIFICATION_CANCELLATION_REASONS, info.uid)
+                        && (reason == REASON_CHANNEL_REMOVED || reason == REASON_CLEAR_DATA)) {
+                    reason = REASON_CHANNEL_BANNED;
+                }
                 listener.onNotificationRemoved(sbnHolder, rankingUpdate, stats, reason);
             } catch (RemoteException ex) {
                 Slog.e(TAG, "unable to notify listener (removed): " + info, ex);
@@ -10649,8 +10647,6 @@
      * TODO(b/161957908): Remove dogfooder toast.
      */
     private class NotificationTrampolineCallback implements BackgroundActivityStartCallback {
-        private final Set<String> mPackagesShown = new ArraySet<>();
-
         @Override
         public boolean isActivityStartAllowed(Collection<IBinder> tokens, int uid,
                 String packageName) {
@@ -10663,16 +10659,12 @@
             }
             String logcatMessage =
                     "Indirect notification activity start (trampoline) from " + packageName;
-            // Call to toast() method is posted to mHandler below to offload PM lookup from the
-            // activity start path
             if (CompatChanges.isChangeEnabled(NOTIFICATION_TRAMPOLINE_BLOCK, uid)) {
-                mHandler.post(() -> toast(packageName, uid, /* blocked */ true));
+                // Post toast() call to mHandler to offload PM lookup from the activity start path
+                mHandler.post(() -> toast(packageName, uid));
                 Slog.e(TAG, logcatMessage + " blocked");
                 return false;
             } else {
-                if (mPackagesShown.add(packageName)) {
-                    mHandler.post(() -> toast(packageName, uid, /* blocked */ false));
-                }
                 Slog.w(TAG, logcatMessage + ", this should be avoided for performance reasons");
                 return true;
             }
@@ -10687,7 +10679,7 @@
                     && !CompatChanges.isChangeEnabled(NOTIFICATION_TRAMPOLINE_BLOCK, uid);
         }
 
-        private void toast(String packageName, int uid, boolean blocked) {
+        private void toast(String packageName, int uid) {
             final CharSequence label;
             try {
                 label = mPackageManagerClient.getApplicationLabel(
@@ -10698,8 +10690,7 @@
                 return;
             }
             mUiHandler.post(() -> Toast.makeText(getUiContext(),
-                    label + " launch " + (blocked ? "blocked" : "will be blocked")
-                            + "\ng.co/dev/trampolines", Toast.LENGTH_LONG).show());
+                    label + " launch blocked\ng.co/dev/trampolines", Toast.LENGTH_LONG).show());
         }
     }
 }
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index 619fc4e..dc3b78a 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -33,6 +33,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.UserIdInt;
+import android.app.ActivityManager;
 import android.app.AppOpsManager;
 import android.app.Notification;
 import android.app.NotificationChannel;
@@ -73,7 +74,6 @@
 import org.json.JSONObject;
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
 
 import java.io.IOException;
 import java.io.PrintWriter;
@@ -184,6 +184,8 @@
 
     private Map<String, List<String>> mOemLockedApps = new HashMap();
 
+    private int mCurrentUserId = UserHandle.USER_NULL;
+
     public PreferencesHelper(Context context, PackageManager pm, RankingHandler rankingHandler,
             ZenModeHelper zenHelper, NotificationChannelLogger notificationChannelLogger,
             AppOpsManager appOpsManager,
@@ -199,7 +201,8 @@
         updateBadgingEnabled();
         updateBubblesEnabled();
         updateMediaNotificationFilteringEnabled();
-        syncChannelsBypassingDnd(mContext.getUserId());
+        mCurrentUserId = ActivityManager.getCurrentUser();
+        syncChannelsBypassingDnd();
     }
 
     public void readXml(TypedXmlPullParser parser, boolean forRestore, int userId)
@@ -806,7 +809,7 @@
                     // but the system can
                     if (group.isBlocked() != oldGroup.isBlocked()) {
                         group.lockFields(NotificationChannelGroup.USER_LOCKED_BLOCKED_STATE);
-                        updateChannelsBypassingDnd(mContext.getUserId());
+                        updateChannelsBypassingDnd();
                     }
                 }
             }
@@ -888,13 +891,13 @@
                 // fields on the channel yet
                 if (existing.getUserLockedFields() == 0 && hasDndAccess) {
                     boolean bypassDnd = channel.canBypassDnd();
-                    if (bypassDnd != existing.canBypassDnd()) {
+                    if (bypassDnd != existing.canBypassDnd() || wasUndeleted) {
                         existing.setBypassDnd(bypassDnd);
                         needsPolicyFileChange = true;
 
                         if (bypassDnd != mAreChannelsBypassingDnd
                                 || previousExistingImportance != existing.getImportance()) {
-                            updateChannelsBypassingDnd(mContext.getUserId());
+                            updateChannelsBypassingDnd();
                         }
                     }
                 }
@@ -958,7 +961,7 @@
 
             r.channels.put(channel.getId(), channel);
             if (channel.canBypassDnd() != mAreChannelsBypassingDnd) {
-                updateChannelsBypassingDnd(mContext.getUserId());
+                updateChannelsBypassingDnd();
             }
             MetricsLogger.action(getChannelLog(channel, pkg).setType(
                     com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_OPEN));
@@ -1047,7 +1050,7 @@
 
             if (updatedChannel.canBypassDnd() != mAreChannelsBypassingDnd
                     || channel.getImportance() != updatedChannel.getImportance()) {
-                updateChannelsBypassingDnd(mContext.getUserId());
+                updateChannelsBypassingDnd();
             }
         }
         updateConfig();
@@ -1145,7 +1148,7 @@
             mNotificationChannelLogger.logNotificationChannelDeleted(channel, uid, pkg);
 
             if (mAreChannelsBypassingDnd && channel.canBypassDnd()) {
-                updateChannelsBypassingDnd(mContext.getUserId());
+                updateChannelsBypassingDnd();
             }
         }
     }
@@ -1512,7 +1515,7 @@
                 }
             }
             if (!deletedChannelIds.isEmpty() && mAreChannelsBypassingDnd) {
-                updateChannelsBypassingDnd(mContext.getUserId());
+                updateChannelsBypassingDnd();
             }
             return deletedChannelIds;
         }
@@ -1658,29 +1661,29 @@
     }
 
     /**
-     * Syncs {@link #mAreChannelsBypassingDnd} with the user's notification policy before
+     * Syncs {@link #mAreChannelsBypassingDnd} with the current user's notification policy before
      * updating
-     * @param userId
      */
-    private void syncChannelsBypassingDnd(int userId) {
+    private void syncChannelsBypassingDnd() {
         mAreChannelsBypassingDnd = (mZenModeHelper.getNotificationPolicy().state
                 & NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND) == 1;
-        updateChannelsBypassingDnd(userId);
+        updateChannelsBypassingDnd();
     }
 
     /**
-     * Updates the user's NotificationPolicy based on whether the given userId
+     * Updates the user's NotificationPolicy based on whether the current userId
      * has channels bypassing DND
      * @param userId
      */
-    private void updateChannelsBypassingDnd(int userId) {
+    private void updateChannelsBypassingDnd() {
         synchronized (mPackagePreferences) {
             final int numPackagePreferences = mPackagePreferences.size();
             for (int i = 0; i < numPackagePreferences; i++) {
                 final PackagePreferences r = mPackagePreferences.valueAt(i);
-                // Package isn't associated with this userId or notifications from this package are
-                // blocked
-                if (userId != UserHandle.getUserId(r.uid) || r.importance == IMPORTANCE_NONE) {
+                // Package isn't associated with the current userId or notifications from this
+                // package are blocked
+                if (mCurrentUserId != UserHandle.getUserId(r.uid)
+                        || r.importance == IMPORTANCE_NONE) {
                     continue;
                 }
 
@@ -2226,14 +2229,16 @@
      * Called when user switches
      */
     public void onUserSwitched(int userId) {
-        syncChannelsBypassingDnd(userId);
+        mCurrentUserId = userId;
+        syncChannelsBypassingDnd();
     }
 
     /**
      * Called when user is unlocked
      */
     public void onUserUnlocked(int userId) {
-        syncChannelsBypassingDnd(userId);
+        mCurrentUserId = userId;
+        syncChannelsBypassingDnd();
     }
 
     public void onUserRemoved(int userId) {
diff --git a/services/core/java/com/android/server/os/NativeTombstoneManager.java b/services/core/java/com/android/server/os/NativeTombstoneManager.java
index 9c4c510..cc6a824 100644
--- a/services/core/java/com/android/server/os/NativeTombstoneManager.java
+++ b/services/core/java/com/android/server/os/NativeTombstoneManager.java
@@ -411,8 +411,13 @@
                             processName = stream.readString(Tombstone.PROCESS_NAME);
                             break;
 
-                        case (int) Tombstone.CAUSE:
-                            long token = stream.start(Tombstone.CAUSE);
+                        case (int) Tombstone.CAUSES:
+                            if (!crashReason.equals("")) {
+                                // Causes appear in decreasing order of likelihood. For now we only
+                                // want the most likely crash reason here, so ignore all others.
+                                break;
+                            }
+                            long token = stream.start(Tombstone.CAUSES);
                         cause:
                             while (stream.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
                                 switch (stream.getFieldNumber()) {
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index 044e186..27e0ffc 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -18,6 +18,7 @@
 
 import static android.app.ActivityOptions.KEY_SPLASH_SCREEN_THEME;
 import static android.app.PendingIntent.FLAG_IMMUTABLE;
+import static android.app.PendingIntent.FLAG_MUTABLE;
 import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
 import static android.content.pm.LauncherApps.FLAG_CACHE_BUBBLE_SHORTCUTS;
@@ -648,6 +649,43 @@
             }
         }
 
+        /**
+         * Returns the intents for a specific shortcut.
+         */
+        @Nullable
+        @Override
+        public PendingIntent getShortcutIntent(@NonNull final String callingPackage,
+                @NonNull final String packageName, @NonNull final String shortcutId,
+                @Nullable final Bundle opts, @NonNull final UserHandle user)
+                throws RemoteException {
+            Objects.requireNonNull(callingPackage);
+            Objects.requireNonNull(packageName);
+            Objects.requireNonNull(shortcutId);
+            Objects.requireNonNull(user);
+
+            ensureShortcutPermission(callingPackage);
+            if (!canAccessProfile(user.getIdentifier(), "Cannot get shortcuts")) {
+                return null;
+            }
+
+            final Intent[] intents = mShortcutServiceInternal.createShortcutIntents(
+                    getCallingUserId(), callingPackage, packageName, shortcutId,
+                    user.getIdentifier(), injectBinderCallingPid(), injectBinderCallingUid());
+            if (intents == null || intents.length == 0) {
+                return null;
+            }
+            final long ident = Binder.clearCallingIdentity();
+            try {
+                return injectCreatePendingIntent(mContext.createPackageContextAsUser(packageName,
+                        0, user), 0 /* requestCode */, intents, FLAG_MUTABLE, opts, user);
+            } catch (PackageManager.NameNotFoundException e) {
+                Slog.e(TAG, "Cannot create pending intent from shortcut " + shortcutId, e);
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+            return null;
+        }
+
         @Override
         public boolean isPackageEnabled(String callingPackage, String packageName, UserHandle user)
                 throws RemoteException {
@@ -756,6 +794,13 @@
                     callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
         }
 
+        @VisibleForTesting
+        PendingIntent injectCreatePendingIntent(Context context, int requestCode,
+                @NonNull Intent[] intents, int flags, Bundle options, UserHandle user) {
+            return PendingIntent.getActivitiesAsUser(context, requestCode, intents, flags, options,
+                    user);
+        }
+
         @Override
         public ParceledListSlice getShortcuts(@NonNull final String callingPackage,
                 @NonNull final ShortcutQueryWrapper query, @NonNull final UserHandle targetUser) {
diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
index 7aaab0c..b02b8f2 100644
--- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java
+++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
@@ -258,22 +258,22 @@
                         packageStats, options.isDowngrade(), profileName, dexMetadataPath,
                         options.getCompilationReason());
 
-                // Only report metrics for base apk for now.
-                // TODO: add ISA and APK type to metrics.
-                if (pkg.getBaseApkPath().equals(path)) {
+                // OTAPreopt doesn't have stats so don't report in that case.
+                if (packageStats != null) {
                     Trace.traceBegin(Trace.TRACE_TAG_PACKAGE_MANAGER, "dex2oat-metrics");
                     try {
                         long sessionId = Math.randomLongInternal();
                         ArtStatsLogUtils.writeStatsLog(
                                 mArtStatsLogger,
                                 sessionId,
-                                path,
                                 compilerFilter,
                                 sharedGid,
                                 packageStats.getCompileTime(path),
                                 dexMetadataPath,
                                 options.getCompilationReason(),
-                                newResult);
+                                newResult,
+                                ArtStatsLogUtils.getApkType(path),
+                                dexCodeIsa);
                     } finally {
                         Trace.traceEnd(Trace.TRACE_TAG_PACKAGE_MANAGER);
                     }
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index a5e28f1..0a484e2 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -88,7 +88,6 @@
 import com.android.server.SystemService;
 import com.android.server.SystemServiceManager;
 import com.android.server.pm.parsing.PackageParser2;
-import com.android.server.pm.permission.PermissionManagerServiceInternal;
 
 import libcore.io.IoUtils;
 
@@ -145,7 +144,6 @@
     private final PackageManagerService mPm;
     private final ApexManager mApexManager;
     private final StagingManager mStagingManager;
-    private final PermissionManagerServiceInternal mPermissionManager;
 
     private AppOpsManager mAppOps;
 
@@ -226,7 +224,6 @@
             Supplier<PackageParser2> apexParserSupplier) {
         mContext = context;
         mPm = pm;
-        mPermissionManager = LocalServices.getService(PermissionManagerServiceInternal.class);
 
         mInstallThread = new HandlerThread(TAG);
         mInstallThread.start();
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index bafe987..2e6c57c 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -46,6 +46,7 @@
 import static com.android.server.pm.PackageInstallerService.prepareStageDir;
 
 import android.Manifest;
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.AppOpsManager;
@@ -71,6 +72,7 @@
 import android.content.pm.IPackageInstallerSession;
 import android.content.pm.IPackageInstallerSessionFileSystemConnector;
 import android.content.pm.IPackageLoadingProgressCallback;
+import android.content.pm.InstallSourceInfo;
 import android.content.pm.InstallationFile;
 import android.content.pm.InstallationFileParcel;
 import android.content.pm.PackageInfo;
@@ -92,6 +94,7 @@
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.os.Binder;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.FileBridge;
 import android.os.FileUtils;
@@ -896,6 +899,14 @@
                 mInstallSource.installerPackageName, mInstallerUid);
     }
 
+    private static final int USER_ACTION_NOT_NEEDED = 0;
+    private static final int USER_ACTION_REQUIRED = 1;
+    private static final int USER_ACTION_PENDING_APK_PARSING = 2;
+
+    @IntDef({USER_ACTION_NOT_NEEDED, USER_ACTION_REQUIRED, USER_ACTION_PENDING_APK_PARSING})
+    @interface
+    UserActionRequirement {}
+
     /**
      * Checks if the permissions still need to be confirmed.
      *
@@ -904,15 +915,22 @@
      *
      * @return {@code true} iff we need to ask to confirm the permissions?
      */
-    private boolean needToAskForPermissions() {
+    @UserActionRequirement
+    private int computeUserActionRequirement() {
         final String packageName;
         synchronized (mLock) {
             if (mPermissionsManuallyAccepted) {
-                return false;
+                return USER_ACTION_NOT_NEEDED;
             }
             packageName = mPackageName;
         }
 
+        final boolean forcePermissionPrompt =
+                (params.installFlags & PackageManager.INSTALL_FORCE_PERMISSION_PROMPT) != 0
+                        || params.requireUserAction == Boolean.TRUE;
+        if (forcePermissionPrompt) {
+            return USER_ACTION_REQUIRED;
+        }
         // It is safe to access mInstallerUid and mInstallSource without lock
         // because they are immutable after sealing.
         final boolean isInstallPermissionGranted =
@@ -924,19 +942,47 @@
         final boolean isUpdatePermissionGranted =
                 (mPm.checkUidPermission(android.Manifest.permission.INSTALL_PACKAGE_UPDATES,
                         mInstallerUid) == PackageManager.PERMISSION_GRANTED);
+        final boolean isUpdateWithoutUserActionPermissionGranted = (mPm.checkUidPermission(
+                android.Manifest.permission.UPDATE_PACKAGES_WITHOUT_USER_ACTION, mInstallerUid)
+                == PackageManager.PERMISSION_GRANTED);
         final int targetPackageUid = mPm.getPackageUid(packageName, 0, userId);
+        final boolean isUpdate = targetPackageUid != -1;
+        final InstallSourceInfo installSourceInfo = isUpdate
+                ? mPm.getInstallSourceInfo(packageName)
+                : null;
+        final String installerPackageName = installSourceInfo != null
+                ? installSourceInfo.getInstallingPackageName()
+                : null;
+        final boolean isInstallerOfRecord = isUpdate
+                && Objects.equals(installerPackageName, getInstallerPackageName());
+        final boolean isSelfUpdate = targetPackageUid == mInstallerUid;
         final boolean isPermissionGranted = isInstallPermissionGranted
-                || (isUpdatePermissionGranted && targetPackageUid != -1)
-                || (isSelfUpdatePermissionGranted && targetPackageUid == mInstallerUid);
+                || (isUpdatePermissionGranted && isUpdate)
+                || (isSelfUpdatePermissionGranted && isSelfUpdate);
         final boolean isInstallerRoot = (mInstallerUid == Process.ROOT_UID);
         final boolean isInstallerSystem = (mInstallerUid == Process.SYSTEM_UID);
-        final boolean forcePermissionPrompt =
-                (params.installFlags & PackageManager.INSTALL_FORCE_PERMISSION_PROMPT) != 0;
 
         // Device owners and affiliated profile owners  are allowed to silently install packages, so
         // the permission check is waived if the installer is the device owner.
-        return forcePermissionPrompt || !(isPermissionGranted || isInstallerRoot
-                || isInstallerSystem || isInstallerDeviceOwnerOrAffiliatedProfileOwner());
+        final boolean noUserActionNecessary = isPermissionGranted || isInstallerRoot
+                || isInstallerSystem || isInstallerDeviceOwnerOrAffiliatedProfileOwner();
+
+        if (noUserActionNecessary) {
+            return USER_ACTION_NOT_NEEDED;
+        }
+
+        if (mPm.isInstallDisabledForPackage(installerPackageName, mInstallerUid, userId)) {
+            // show the installer to account for device poslicy or unknown sources use cases
+            return USER_ACTION_REQUIRED;
+        }
+
+        if (params.requireUserAction == Boolean.FALSE
+                && isUpdateWithoutUserActionPermissionGranted
+                && (isInstallerOfRecord || isSelfUpdate)) {
+            return USER_ACTION_PENDING_APK_PARSING;
+        }
+
+        return USER_ACTION_REQUIRED;
     }
 
     public PackageInstallerSession(PackageInstallerService.InternalCallback callback,
@@ -1109,6 +1155,7 @@
                     getStagedSessionErrorMessage());
             info.createdMillis = createdMillis;
             info.updatedMillis = updatedMillis;
+            info.requireUserAction = params.requireUserAction;
         }
         return info;
     }
@@ -1212,12 +1259,18 @@
             mProgress = MathUtils.constrain(mClientProgress * 0.8f, 0f, 0.8f)
                     + MathUtils.constrain(mInternalProgress * 0.2f, 0f, 0.2f);
         } else {
-            // For incremental installs, continue publishing the install progress during committing.
-            mProgress = mIncrementalProgress;
+            // For incremental install, continue to publish incremental progress during committing.
+            if (isIncrementalInstallation() && (mIncrementalProgress - mProgress) >= 0.01) {
+                // It takes some time for data loader to write to incremental file system, so at the
+                // beginning of the commit, the incremental progress might be very small.
+                // Wait till the incremental progress is larger than what's already displayed.
+                // This way we don't see the progress ring going backwards.
+                mProgress = mIncrementalProgress;
+            }
         }
 
         // Only publish when meaningful change
-        if (forcePublish || Math.abs(mProgress - mReportedProgress) >= 0.01) {
+        if (forcePublish || (mProgress - mReportedProgress) >= 0.01) {
             mReportedProgress = mProgress;
             mCallback.onSessionProgressChanged(this, mProgress);
         }
@@ -2188,7 +2241,7 @@
     private void verifyNonStaged()
             throws PackageManagerException {
         final PackageManagerService.VerificationParams verifyingSession =
-                makeVerificationParams();
+                prepareForVerification();
         if (verifyingSession == null) {
             return;
         }
@@ -2205,7 +2258,7 @@
                 final PackageInstallerSession session = childSessions.get(i);
                 try {
                     final PackageManagerService.VerificationParams verifyingChildSession =
-                            session.makeVerificationParams();
+                            session.prepareForVerification();
                     if (verifyingChildSession != null) {
                         verifyingChildSessions.add(verifyingChildSession);
                     }
@@ -2292,51 +2345,78 @@
      * in case permissions need to be requested before verification can proceed.
      */
     @Nullable
-    private PackageManagerService.VerificationParams makeVerificationParams()
+    private PackageManagerService.VerificationParams prepareForVerification()
             throws PackageManagerException {
         assertNotLocked("makeSessionActive");
 
+        @UserActionRequirement
+        int userActionRequirement = USER_ACTION_NOT_NEEDED;
         // TODO(b/159331446): Move this to makeSessionActiveForInstall and update javadoc
-        if (!params.isMultiPackage && needToAskForPermissions()) {
-            // User needs to confirm installation;
-            // give installer an intent they can use to involve
-            // user.
-            final Intent intent = new Intent(PackageInstaller.ACTION_CONFIRM_INSTALL);
-            intent.setPackage(mPm.getPackageInstallerPackageName());
-            intent.putExtra(PackageInstaller.EXTRA_SESSION_ID, sessionId);
-
-            final IntentSender statusReceiver;
-            synchronized (mLock) {
-                statusReceiver = mRemoteStatusReceiver;
-            }
-            sendOnUserActionRequired(mContext, statusReceiver, sessionId, intent);
-
-            // Commit was keeping session marked as active until now; release
-            // that extra refcount so session appears idle.
-            closeInternal(false);
-            return null;
+        if (!params.isMultiPackage) {
+            userActionRequirement = computeUserActionRequirement();
+            if (userActionRequirement == USER_ACTION_REQUIRED) {
+                sendPendingUserActionIntent();
+                return null;
+            } // else, we'll wait until we parse to determine if we need to
         }
 
         synchronized (mLock) {
+            if (mRelinquished) {
+                throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
+                        "Session relinquished");
+            }
+            if (mDestroyed) {
+                throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
+                        "Session destroyed");
+            }
+            if (!mSealed) {
+                throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
+                        "Session not sealed");
+            }
+            PackageLite result = parseApkLite();
+            if (result != null) {
+                mPackageLite = result;
+                mInternalProgress = 0.5f;
+                computeProgressLocked(true);
+
+                extractNativeLibraries(
+                        mPackageLite, stageDir, params.abiOverride, mayInheritNativeLibs());
+
+                if (userActionRequirement == USER_ACTION_PENDING_APK_PARSING
+                        && (result.getTargetSdk() < Build.VERSION_CODES.Q)) {
+                    sendPendingUserActionIntent();
+                    return null;
+                }
+            }
             return makeVerificationParamsLocked();
         }
     }
 
-    @GuardedBy("mLock")
-    private PackageManagerService.VerificationParams makeVerificationParamsLocked()
-            throws PackageManagerException {
-        if (mRelinquished) {
-            throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
-                    "Session relinquished");
+    private void sendPendingUserActionIntent() {
+        // User needs to confirm installation;
+        // give installer an intent they can use to involve
+        // user.
+        final Intent intent = new Intent(PackageInstaller.ACTION_CONFIRM_INSTALL);
+        intent.setPackage(mPm.getPackageInstallerPackageName());
+        intent.putExtra(PackageInstaller.EXTRA_SESSION_ID, sessionId);
+
+        final IntentSender statusReceiver;
+        synchronized (mLock) {
+            statusReceiver = mRemoteStatusReceiver;
         }
-        if (mDestroyed) {
-            throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
-                    "Session destroyed");
-        }
-        if (!mSealed) {
-            throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
-                    "Session not sealed");
-        }
+        sendOnUserActionRequired(mContext, statusReceiver, sessionId, intent);
+
+        // Commit was keeping session marked as active until now; release
+        // that extra refcount so session appears idle.
+        closeInternal(false);
+    }
+
+    /**
+     * Prepares staged directory with any inherited APKs and returns the parsed package.
+     */
+    @Nullable
+    private PackageLite parseApkLite() throws PackageManagerException {
+
 
         // TODO(b/136257624): Some logic in this if block probably belongs in
         //  makeInstallParams().
@@ -2345,8 +2425,8 @@
             Objects.requireNonNull(mSigningDetails);
             Objects.requireNonNull(mResolvedBaseFile);
 
-            // Inherit any packages and native libraries from existing install that
-            // haven't been overridden.
+            // If we haven't already parsed, inherit any packages and native libraries from existing
+            // install that haven't been overridden.
             if (params.mode == SessionParams.MODE_INHERIT_EXISTING) {
                 try {
                     final List<File> fromFiles = mResolvedInheritedFiles;
@@ -2398,16 +2478,17 @@
             // above block. Therefore, we need to parse the complete package in stage dir here.
             // Besides, PackageLite may be null for staged sessions that don't complete pre-reboot
             // verification.
-            mPackageLite = getOrParsePackageLiteLocked(stageDir, /* flags */ 0);
-
-            // TODO: surface more granular state from dexopt
-            mInternalProgress = 0.5f;
-            computeProgressLocked(true);
-
-            extractNativeLibraries(mPackageLite, stageDir, params.abiOverride,
-                    mayInheritNativeLibs());
+            return getOrParsePackageLiteLocked(stageDir, /* flags */ 0);
         }
+        return null;
+    }
 
+    @GuardedBy("mLock")
+    @Nullable
+    /**
+     * Returns a {@link com.android.server.pm.PackageManagerService.VerificationParams}
+     */
+    private PackageManagerService.VerificationParams makeVerificationParamsLocked() {
         final IPackageInstallObserver2 localObserver;
         if (!hasParentSessionId()) {
             // Avoid attaching this observer to child session since they won't use it.
@@ -2707,9 +2788,10 @@
      * <p>
      * Note that upgrade compatibility is still performed by
      * {@link PackageManagerService}.
+     * @return a {@link PackageLite} representation of the validated APK(s).
      */
     @GuardedBy("mLock")
-    private void validateApkInstallLocked() throws PackageManagerException {
+    private PackageLite validateApkInstallLocked() throws PackageManagerException {
         ApkLite baseApk = null;
         PackageLite packageLite = null;
         mPackageLite = null;
@@ -2731,6 +2813,7 @@
             throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
                     "Missing existing base package");
         }
+
         // Default to require only if existing base apk has fs-verity.
         mVerityFoundForApks = PackageManagerServiceUtils.isApkVerityEnabled()
                 && params.mode == SessionParams.MODE_INHERIT_EXISTING
@@ -3017,6 +3100,7 @@
                 mIncrementalFileStorages.disallowReadLogs();
             }
         }
+        return packageLite;
     }
 
     @GuardedBy("mLock")
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index ff042c2..550e9f8 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -252,7 +252,6 @@
 import android.content.pm.parsing.component.ParsedProcess;
 import android.content.pm.parsing.component.ParsedProvider;
 import android.content.pm.parsing.component.ParsedService;
-import android.content.pm.parsing.component.ParsedUsesPermission;
 import android.content.pm.parsing.result.ParseResult;
 import android.content.pm.parsing.result.ParseTypeImpl;
 import android.content.res.Resources;
@@ -371,6 +370,7 @@
 import com.android.server.SystemServerInitThreadPool;
 import com.android.server.Watchdog;
 import com.android.server.apphibernation.AppHibernationManagerInternal;
+import com.android.server.apphibernation.AppHibernationService;
 import com.android.server.compat.CompatChange;
 import com.android.server.compat.PlatformCompat;
 import com.android.server.net.NetworkPolicyManagerInternal;
@@ -778,16 +778,6 @@
 
     private static final String COMPANION_PACKAGE_NAME = "com.android.companiondevicemanager";
 
-    /** Canonical intent used to identify what counts as a "web browser" app */
-    private static final Intent sBrowserIntent;
-    static {
-        sBrowserIntent = new Intent();
-        sBrowserIntent.setAction(Intent.ACTION_VIEW);
-        sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE);
-        sBrowserIntent.setData(Uri.parse("http:"));
-        sBrowserIntent.addFlags(Intent.FLAG_IGNORE_EPHEMERAL);
-    }
-
     // Compilation reasons.
     public static final int REASON_UNKNOWN = -1;
     public static final int REASON_FIRST_BOOT = 0;
@@ -5636,7 +5626,7 @@
             // Work that needs to happen on first install within each user
             if (firstUserIds != null && firstUserIds.length > 0) {
                 for (int userId : firstUserIds) {
-                    clearRolesAndRestorePermissionsForNewUserInstall(packageName,
+                    restorePermissionsAndUpdateRolesForNewUserInstall(packageName,
                             pkgSetting.getInstallReason(userId), userId);
                 }
             }
@@ -7131,7 +7121,7 @@
         // once we have a booted system.
         mInstaller.setWarnIfHeld(mLock);
 
-        PackageParser.readConfigUseRoundIcon(mContext.getResources());
+        ParsingPackageUtils.readConfigUseRoundIcon(mContext.getResources());
 
         mServiceStartWithDelay = SystemClock.uptimeMillis() + (60 * 1000L);
 
@@ -7752,19 +7742,6 @@
         return matches.get(0).getComponentInfo().getComponentName();
     }
 
-    private boolean packageIsBrowser(String packageName, int userId) {
-        List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
-                PackageManager.MATCH_ALL, userId);
-        final int N = list.size();
-        for (int i = 0; i < N; i++) {
-            ResolveInfo info = list.get(i);
-            if (info.priority >= 0 && packageName.equals(info.activityInfo.packageName)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
     @Override
     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
             throws RemoteException {
@@ -8504,7 +8481,8 @@
             int flags, int userId) {
         if (!mUserManager.exists(userId)) return null;
         Preconditions.checkArgumentNonnegative(userId, "userId must be >= 0");
-        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+        final int callingUid = Binder.getCallingUid();
+        if (getInstantAppPackageName(callingUid) != null) {
             return null;
         }
 
@@ -8515,8 +8493,7 @@
                         == PERMISSION_GRANTED
                 || mContext.checkCallingOrSelfPermission(DELETE_PACKAGES)
                         == PERMISSION_GRANTED
-                || canRequestPackageInstallsInternal(packageName,
-                        PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId,
+                || canRequestPackageInstallsInternal(packageName, callingUid, userId,
                         false  /* throwIfPermNotDeclared*/)
                 || mContext.checkCallingOrSelfPermission(REQUEST_DELETE_PACKAGES)
                         == PERMISSION_GRANTED
@@ -12304,9 +12281,15 @@
 
     public ArraySet<String> getOptimizablePackages() {
         ArraySet<String> pkgs = new ArraySet<>();
+        final boolean hibernationEnabled = AppHibernationService.isAppHibernationEnabled();
+        AppHibernationManagerInternal appHibernationManager =
+                mInjector.getLocalService(AppHibernationManagerInternal.class);
         synchronized (mLock) {
             for (AndroidPackage p : mPackages.values()) {
-                if (PackageDexOptimizer.canOptimizePackage(p)) {
+                // Checking hibernation state is an inexpensive call.
+                boolean isHibernating = hibernationEnabled
+                        && appHibernationManager.isHibernatingGlobally(p.getPackageName());
+                if (PackageDexOptimizer.canOptimizePackage(p) && !isHibernating) {
                     pkgs.add(p.getPackageName());
                 }
             }
@@ -15459,16 +15442,55 @@
                 null);
     }
 
-    private void sendPackagesSuspendedForUser(String[] pkgList, int[] uidList, int userId,
+    @VisibleForTesting(visibility = Visibility.PRIVATE)
+    void sendPackagesSuspendedForUser(String[] pkgList, int[] uidList, int userId,
             boolean suspended) {
-        final Bundle extras = new Bundle(3);
-        extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
-        extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidList);
-        sendPackageBroadcast(
-                suspended ? Intent.ACTION_PACKAGES_SUSPENDED
-                        : Intent.ACTION_PACKAGES_UNSUSPENDED,
-                null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null,
-                new int[] {userId}, null, null, null);
+        final List<List<String>> pkgsToSend = new ArrayList(pkgList.length);
+        final List<IntArray> uidsToSend = new ArrayList(pkgList.length);
+        final List<SparseArray<int[]>> allowListsToSend = new ArrayList(pkgList.length);
+        final int[] userIds = new int[] {userId};
+        // Get allow lists for the pkg in the pkgList. Merge into the existed pkgs and uids if
+        // allow lists are the same.
+        synchronized (mLock) {
+            for (int i = 0; i < pkgList.length; i++) {
+                final String pkgName = pkgList[i];
+                final int uid = uidList[i];
+                SparseArray<int[]> allowList = mAppsFilter.getVisibilityAllowList(
+                        getPackageSettingInternal(pkgName, Process.SYSTEM_UID),
+                        userIds, mSettings.getPackagesLocked());
+                if (allowList == null) {
+                    allowList = new SparseArray<>(0);
+                }
+                boolean merged = false;
+                for (int j = 0; j < allowListsToSend.size(); j++) {
+                    if (Arrays.equals(allowListsToSend.get(j).get(userId), allowList.get(userId))) {
+                        pkgsToSend.get(j).add(pkgName);
+                        uidsToSend.get(j).add(uid);
+                        merged = true;
+                        break;
+                    }
+                }
+                if (!merged) {
+                    pkgsToSend.add(new ArrayList<>(Arrays.asList(pkgName)));
+                    uidsToSend.add(IntArray.wrap(new int[] {uid}));
+                    allowListsToSend.add(allowList);
+                }
+            }
+        }
+
+        for (int i = 0; i < pkgsToSend.size(); i++) {
+            final Bundle extras = new Bundle(3);
+            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST,
+                    pkgsToSend.get(i).toArray(new String[pkgsToSend.get(i).size()]));
+            extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidsToSend.get(i).toArray());
+            final SparseArray<int[]> allowList = allowListsToSend.get(i).size() == 0
+                    ? null : allowListsToSend.get(i);
+            sendPackageBroadcast(
+                    suspended ? Intent.ACTION_PACKAGES_SUSPENDED
+                            : Intent.ACTION_PACKAGES_UNSUSPENDED,
+                    null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null,
+                    userIds, null, allowList, null);
+        }
     }
 
     /**
@@ -15612,7 +15634,7 @@
 
                 PostInstallData postInstallData =
                         new PostInstallData(null, res, () -> {
-                            clearRolesAndRestorePermissionsForNewUserInstall(packageName,
+                            restorePermissionsAndUpdateRolesForNewUserInstall(packageName,
                                     pkgSetting.getInstallReason(userId), userId);
                             if (intentSender != null) {
                                 onRestoreComplete(res.returnCode, mContext, intentSender);
@@ -21182,7 +21204,6 @@
                 final SparseBooleanArray changedUsers = new SparseBooleanArray();
                 synchronized (mLock) {
                     mDomainVerificationManager.clearPackage(deletedPs.name);
-                    clearDefaultBrowserIfNeeded(packageName);
                     mSettings.getKeySetManagerService().removeAppKeySetDataLPw(packageName);
                     mAppsFilter.removePackage(getPackageSetting(packageName));
                     removedAppId = mSettings.removePackageLPw(packageName);
@@ -21740,7 +21761,6 @@
                 destroyAppDataLIF(pkg, nextUserId,
                         FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL);
             }
-            clearDefaultBrowserIfNeededForUser(ps.name, nextUserId);
             removeKeystoreDataIfNeeded(mInjector.getUserManagerInternal(), nextUserId, ps.appId);
             clearPackagePreferredActivities(ps.name, nextUserId);
             mPermissionManager.onPackageUninstalled(ps.name, ps.appId, pkg, sharedUserPkgs,
@@ -22257,36 +22277,8 @@
         mSettings.clearPackagePreferredActivities(packageName, outUserChanged, userId);
     }
 
-    /** Clears state for all users, and touches intent filter verification policy */
-    void clearDefaultBrowserIfNeeded(String packageName) {
-        for (int oneUserId : mUserManager.getUserIds()) {
-            clearDefaultBrowserIfNeededForUser(packageName, oneUserId);
-        }
-    }
-
-    private void clearDefaultBrowserIfNeededForUser(String packageName, int userId) {
-        final String defaultBrowserPackageName = mDefaultAppProvider.getDefaultBrowser(userId);
-        if (!TextUtils.isEmpty(defaultBrowserPackageName)) {
-            if (packageName.equals(defaultBrowserPackageName)) {
-                mDefaultAppProvider.setDefaultBrowser(null, true, userId);
-            }
-        }
-    }
-
-    private void clearRolesAndRestorePermissionsForNewUserInstall(String packageName,
+    private void restorePermissionsAndUpdateRolesForNewUserInstall(String packageName,
             int installReason, @UserIdInt int userId) {
-        // If this app is a browser and it's newly-installed for some
-        // users, clear any default-browser state in those users. The
-        // app's nature doesn't depend on the user, so we can just check
-        // its browser nature in any user and generalize.
-        if (packageIsBrowser(packageName, userId)) {
-            // If this browser is restored from user's backup, do not clear
-            // default-browser state for this user
-            if (installReason != PackageManager.INSTALL_REASON_DEVICE_RESTORE) {
-                mDefaultAppProvider.setDefaultBrowser(null, true, userId);
-            }
-        }
-
         // We may also need to apply pending (restored) runtime permission grants
         // within these users.
         mPermissionManager.restoreDelayedRuntimePermissions(packageName, userId);
@@ -22320,11 +22312,6 @@
                 }
             }
             updateDefaultHomeNotLocked(userId);
-            // TODO: We have to reset the default SMS and Phone. This requires
-            // significant refactoring to keep all default apps in the package
-            // manager (cleaner but more work) or have the services provide
-            // callbacks to the package manager to request a default app reset.
-            mDefaultAppProvider.setDefaultBrowser(null, true, userId);
             resetNetworkPolicies(userId);
             synchronized (mLock) {
                 scheduleWritePackageRestrictionsLocked(userId);
@@ -22903,9 +22890,14 @@
 
     @Override
     public String getWellbeingPackageName() {
-        return CollectionUtils.firstOrNull(
-                mContext.getSystemService(RoleManager.class).getRoleHolders(
-                        RoleManager.ROLE_SYSTEM_WELLBEING));
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            return CollectionUtils.firstOrNull(
+                    mContext.getSystemService(RoleManager.class).getRoleHolders(
+                            RoleManager.ROLE_SYSTEM_WELLBEING));
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
     }
 
     @Override
@@ -27326,29 +27318,11 @@
         }
 
         @Override
-        public boolean isPackageUsesPermissionNeverForLocation(@NonNull String packageName,
-                @NonNull String permissionName) {
-            Objects.requireNonNull(packageName);
-            Objects.requireNonNull(permissionName);
-            final AndroidPackage pkg;
-            synchronized (mLock) {
-                pkg = mPackages.get(packageName);
-            }
-            if (pkg == null) return false;
-            final List<ParsedUsesPermission> usesPermissions = pkg.getUsesPermissions();
-            final int size = usesPermissions.size();
-            for (int i = 0; i < size; i++) {
-                final ParsedUsesPermission usesPermission = usesPermissions.get(i);
-                if (Objects.equals(usesPermission.name, permissionName)) {
-                    return (usesPermission.usesPermissionFlags
-                            & ParsedUsesPermission.FLAG_NEVER_FOR_LOCATION) != 0;
-                }
-            }
-            return false;
+        public void deleteOatArtifactsOfPackage(String packageName) {
+            PackageManagerService.this.deleteOatArtifactsOfPackage(packageName);
         }
     }
 
-
     @GuardedBy("mLock")
     private SparseArray<String> getAppsWithSharedUserIdsLocked() {
         final SparseArray<String> sharedUserIds = new SparseArray<>();
@@ -27540,51 +27514,60 @@
 
     @Override
     public boolean canRequestPackageInstalls(String packageName, int userId) {
-        return canRequestPackageInstallsInternal(packageName, 0, userId,
+        return canRequestPackageInstallsInternal(packageName, Binder.getCallingUid(), userId,
                 true /* throwIfPermNotDeclared*/);
     }
 
-    private boolean canRequestPackageInstallsInternal(String packageName, int flags, int userId,
-            boolean throwIfPermNotDeclared) {
-        int callingUid = Binder.getCallingUid();
-        int uid = getPackageUid(packageName, 0, userId);
+    private boolean canRequestPackageInstallsInternal(String packageName, int callingUid,
+            int userId, boolean throwIfPermNotDeclared) {
+        int uid = getPackageUidInternal(packageName, 0, userId, callingUid);
         if (callingUid != uid && callingUid != Process.ROOT_UID
                 && callingUid != Process.SYSTEM_UID) {
             throw new SecurityException(
                     "Caller uid " + callingUid + " does not own package " + packageName);
         }
-        if (isInstantApp(packageName, userId)) {
+        if (isInstantAppInternal(packageName, userId, callingUid)) {
             return false;
         }
+        final AndroidPackage pkg;
         synchronized (mLock) {
-            final AndroidPackage pkg = mPackages.get(packageName);
-            if (pkg == null) {
+            pkg = mPackages.get(packageName);
+        }
+        if (pkg == null) {
+            return false;
+        }
+        if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.O) {
+            return false;
+        }
+        if (!pkg.getRequestedPermissions().contains(
+                android.Manifest.permission.REQUEST_INSTALL_PACKAGES)) {
+            final String message = "Need to declare "
+                    + android.Manifest.permission.REQUEST_INSTALL_PACKAGES
+                    + " to call this api";
+            if (throwIfPermNotDeclared) {
+                throw new SecurityException(message);
+            } else {
+                Slog.e(TAG, message);
                 return false;
             }
-            if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.O) {
-                return false;
-            }
-            if (!pkg.getRequestedPermissions().contains(
-                    android.Manifest.permission.REQUEST_INSTALL_PACKAGES)) {
-                final String message = "Need to declare "
-                        + android.Manifest.permission.REQUEST_INSTALL_PACKAGES
-                        + " to call this api";
-                if (throwIfPermNotDeclared) {
-                    throw new SecurityException(message);
-                } else {
-                    Slog.e(TAG, message);
-                    return false;
-                }
-            }
         }
+
+        return !isInstallDisabledForPackage(packageName, uid, userId);
+    }
+
+    /**
+     * Returns true if the system or user is explicitly preventing an otherwise valid installer to
+     * complete an install. This includes checks like unknown sources and user restrictions.
+     */
+    public boolean isInstallDisabledForPackage(String packageName, int uid, int userId) {
         if (mUserManager.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, userId)
-                  || mUserManager.hasUserRestriction(
-                        UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY, userId)) {
-            return false;
+                || mUserManager.hasUserRestriction(
+                UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY, userId)) {
+            return true;
         }
         if (mExternalSourcesPolicy != null) {
             int isTrusted = mExternalSourcesPolicy.getPackageTrustedToInstallApps(packageName, uid);
-            return isTrusted == PackageManagerInternal.ExternalSourcesPolicy.USER_TRUSTED;
+            return isTrusted != PackageManagerInternal.ExternalSourcesPolicy.USER_TRUSTED;
         }
         return false;
     }
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index b5765b5..853b6a7 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -104,8 +104,8 @@
 import com.android.server.LocalServices;
 import com.android.server.SystemConfig;
 import com.android.server.pm.PackageManagerShellCommandDataLoader.Metadata;
-import com.android.server.pm.verify.domain.DomainVerificationShell;
 import com.android.server.pm.permission.LegacyPermissionManagerInternal;
+import com.android.server.pm.verify.domain.DomainVerificationShell;
 
 import dalvik.system.DexFile;
 
@@ -561,7 +561,7 @@
                 }
                 final ApkLite apkLite = apkLiteResult.getResult();
                 final PackageLite pkgLite = new PackageLite(null, apkLite.getPath(), apkLite, null,
-                        null, null, null, null, null);
+                        null, null, null, null, null, apkLite.getTargetSdkVersion());
                 sessionSize += PackageHelper.calculateInstalledSize(pkgLite,
                         params.sessionParams.abiOverride, fd.getFileDescriptor());
             } catch (IOException e) {
@@ -2251,8 +2251,8 @@
             }
         }
 
-        final String packageName = getNextArg();
-        if (packageName == null) {
+        final List<String> packageNames = getRemainingArgs();
+        if (packageNames.isEmpty()) {
             pw.println("Error: package name not specified");
             return 1;
         }
@@ -2270,12 +2270,15 @@
         try {
             final int translatedUserId =
                     translateUserId(userId, UserHandle.USER_NULL, "runSuspend");
-            mInterface.setPackagesSuspendedAsUser(new String[]{packageName}, suspendedState,
-                    ((appExtras.size() > 0) ? appExtras : null),
+            mInterface.setPackagesSuspendedAsUser(packageNames.toArray(new String[] {}),
+                    suspendedState, ((appExtras.size() > 0) ? appExtras : null),
                     ((launcherExtras.size() > 0) ? launcherExtras : null),
                     info, callingPackage, translatedUserId);
-            pw.println("Package " + packageName + " new suspended state: "
-                    + mInterface.isPackageSuspendedForUser(packageName, translatedUserId));
+            for (int i = 0; i < packageNames.size(); i++) {
+                final String packageName = packageNames.get(i);
+                pw.println("Package " + packageName + " new suspended state: "
+                        + mInterface.isPackageSuspendedForUser(packageName, translatedUserId));
+            }
             return 0;
         } catch (RemoteException | IllegalArgumentException e) {
             pw.println(e.toString());
@@ -3643,11 +3646,11 @@
         pw.println("  hide [--user USER_ID] PACKAGE_OR_COMPONENT");
         pw.println("  unhide [--user USER_ID] PACKAGE_OR_COMPONENT");
         pw.println("");
-        pw.println("  suspend [--user USER_ID] TARGET-PACKAGE");
-        pw.println("    Suspends the specified package (as user).");
+        pw.println("  suspend [--user USER_ID] PACKAGE [PACKAGE...]");
+        pw.println("    Suspends the specified package(s) (as user).");
         pw.println("");
-        pw.println("  unsuspend [--user USER_ID] TARGET-PACKAGE");
-        pw.println("    Unsuspends the specified package (as user).");
+        pw.println("  unsuspend [--user USER_ID] PACKAGE [PACKAGE...]");
+        pw.println("    Unsuspends the specified package(s) (as user).");
         pw.println("");
         pw.println("  grant [--user USER_ID] PACKAGE PERMISSION");
         pw.println("  revoke [--user USER_ID] PACKAGE PERMISSION");
diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java
index 302e657..fd8ec7f 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackage.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackage.java
@@ -20,8 +20,17 @@
 import android.annotation.UserIdInt;
 import android.app.Person;
 import android.app.appsearch.AppSearchManager;
+import android.app.appsearch.AppSearchResult;
 import android.app.appsearch.AppSearchSession;
+import android.app.appsearch.GenericDocument;
+import android.app.appsearch.GetByUriRequest;
 import android.app.appsearch.PackageIdentifier;
+import android.app.appsearch.PutDocumentsRequest;
+import android.app.appsearch.RemoveByUriRequest;
+import android.app.appsearch.ReportUsageRequest;
+import android.app.appsearch.SearchResult;
+import android.app.appsearch.SearchResults;
+import android.app.appsearch.SearchSpec;
 import android.app.appsearch.SetSchemaRequest;
 import android.content.ComponentName;
 import android.content.Intent;
@@ -36,6 +45,7 @@
 import android.graphics.drawable.Icon;
 import android.os.Binder;
 import android.os.PersistableBundle;
+import android.os.StrictMode;
 import android.text.format.Formatter;
 import android.util.ArrayMap;
 import android.util.ArraySet;
@@ -48,6 +58,7 @@
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.infra.AndroidFuture;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.CollectionUtils;
 import com.android.internal.util.ConcurrentUtils;
@@ -70,13 +81,15 @@
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
-import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.CompletableFuture;
 import java.util.function.Consumer;
 import java.util.function.Function;
 import java.util.function.Predicate;
@@ -145,9 +158,9 @@
     private static final String KEY_BITMAP_BYTES = "bitmapBytes";
 
     /**
-     * All the shortcuts from the package, keyed on IDs.
+     * An temp in-memory copy of shortcuts for this package that was loaded from xml, keyed on IDs.
      */
-    final private ArrayMap<String, ShortcutInfo> mShortcuts = new ArrayMap<>();
+    final ArraySet<ShortcutInfo> mShortcuts = new ArraySet<>();
 
     /**
      * All the share targets from the package
@@ -207,7 +220,9 @@
     }
 
     public int getShortcutCount() {
-        return mShortcuts.size();
+        final int[] count = new int[1];
+        forEachShortcut(si -> count[0]++);
+        return count[0];
     }
 
     @Override
@@ -221,17 +236,20 @@
         // - Unshadow all shortcuts.
         // - Set disabled reason.
         // - Disable if needed.
-        for (int i = mShortcuts.size() - 1; i >= 0; i--) {
-            ShortcutInfo si = mShortcuts.valueAt(i);
-            mutateShortcut(si.getId(), si, shortcut -> {
-                shortcut.clearFlags(ShortcutInfo.FLAG_SHADOW);
+        forEachShortcutMutateIf(si -> {
+            if (!si.hasFlags(ShortcutInfo.FLAG_SHADOW)
+                    && si.getDisabledReason() == restoreBlockReason
+                    && restoreBlockReason == ShortcutInfo.DISABLED_REASON_NOT_DISABLED) {
+                return false;
+            }
+            si.clearFlags(ShortcutInfo.FLAG_SHADOW);
 
-                shortcut.setDisabledReason(restoreBlockReason);
-                if (restoreBlockReason != ShortcutInfo.DISABLED_REASON_NOT_DISABLED) {
-                    shortcut.addFlags(ShortcutInfo.FLAG_DISABLED);
-                }
-            });
-        }
+            si.setDisabledReason(restoreBlockReason);
+            if (restoreBlockReason != ShortcutInfo.DISABLED_REASON_NOT_DISABLED) {
+                si.addFlags(ShortcutInfo.FLAG_DISABLED);
+            }
+            return true;
+        });
         // Because some launchers may not have been restored (e.g. allowBackup=false),
         // we need to re-calculate the pinned shortcuts.
         refreshPinnedFlags();
@@ -242,7 +260,7 @@
      */
     @Nullable
     public ShortcutInfo findShortcutById(String id) {
-        return mShortcuts.get(id);
+        return getShortcutById(id);
     }
 
     public boolean isShortcutExistsAndInvisibleToPublisher(String id) {
@@ -265,7 +283,7 @@
     }
 
     public void ensureNotImmutable(@NonNull String id, boolean ignoreInvisible) {
-        ensureNotImmutable(mShortcuts.get(id), ignoreInvisible);
+        ensureNotImmutable(findShortcutById(id), ignoreInvisible);
     }
 
     public void ensureImmutableShortcutsNotIncludedWithIds(@NonNull List<String> shortcutIds,
@@ -308,8 +326,9 @@
      * Delete a shortcut by ID. This will *always* remove it even if it's immutable or invisible.
      */
     private ShortcutInfo forceDeleteShortcutInner(@NonNull String id) {
-        final ShortcutInfo shortcut = mShortcuts.remove(id);
+        final ShortcutInfo shortcut = getShortcutById(id);
         if (shortcut != null) {
+            removeShortcut(id);
             mShortcutUser.mService.removeIconLocked(shortcut);
             shortcut.clearFlags(ShortcutInfo.FLAG_DYNAMIC | ShortcutInfo.FLAG_PINNED
                     | ShortcutInfo.FLAG_MANIFEST | ShortcutInfo.FLAG_CACHED_ALL);
@@ -326,10 +345,10 @@
 
         forceDeleteShortcutInner(newShortcut.getId());
 
-        // Extract Icon and update the icon res ID and the bitmap path.
         s.saveIconAndFixUpShortcutLocked(newShortcut);
         s.fixUpShortcutResourceNamesAndValues(newShortcut);
-        mShortcuts.put(newShortcut.getId(), newShortcut);
+
+        saveShortcut(newShortcut);
     }
 
     /**
@@ -347,7 +366,7 @@
 
         newShortcut.addFlags(ShortcutInfo.FLAG_DYNAMIC);
 
-        final ShortcutInfo oldShortcut = mShortcuts.get(newShortcut.getId());
+        final ShortcutInfo oldShortcut = findShortcutById(newShortcut.getId());
         if (oldShortcut != null) {
             // It's an update case.
             // Make sure the target is updatable. (i.e. should be mutable.)
@@ -379,7 +398,7 @@
         newShortcut.addFlags(ShortcutInfo.FLAG_DYNAMIC);
 
         changedShortcuts.clear();
-        final ShortcutInfo oldShortcut = mShortcuts.get(newShortcut.getId());
+        final ShortcutInfo oldShortcut = findShortcutById(newShortcut.getId());
         boolean deleted = false;
 
         if (oldShortcut == null) {
@@ -418,6 +437,16 @@
         }
 
         forceReplaceShortcutInner(newShortcut);
+        // TODO: Report usage can be filed async
+        runInAppSearch(session -> {
+            final AndroidFuture<Boolean> future = new AndroidFuture<>();
+            session.reportUsage(
+                    new ReportUsageRequest.Builder(getPackageName())
+                            .setUri(newShortcut.getId()).build(),
+                    mShortcutUser.mExecutor, result -> future.complete(result.isSuccess()));
+            return future;
+        });
+
         return deleted;
     }
 
@@ -427,19 +456,12 @@
      * @return List of removed shortcuts.
      */
     private List<ShortcutInfo> removeOrphans() {
-        List<ShortcutInfo> removeList = null;
-
-        for (int i = mShortcuts.size() - 1; i >= 0; i--) {
-            final ShortcutInfo si = mShortcuts.valueAt(i);
-
-            if (si.isAlive()) continue;
-
-            if (removeList == null) {
-                removeList = new ArrayList<>();
-            }
+        final List<ShortcutInfo> removeList = new ArrayList<>(1);
+        forEachShortcut(si -> {
+            if (si.isAlive()) return;
             removeList.add(si);
-        }
-        if (removeList != null) {
+        });
+        if (!removeList.isEmpty()) {
             for (int i = removeList.size() - 1; i >= 0; i--) {
                 forceDeleteShortcutInner(removeList.get(i).getId());
             }
@@ -456,20 +478,19 @@
     public List<ShortcutInfo> deleteAllDynamicShortcuts(boolean ignoreInvisible) {
         final long now = mShortcutUser.mService.injectCurrentTimeMillis();
 
-        boolean changed = false;
-        for (int i = mShortcuts.size() - 1; i >= 0; i--) {
-            final ShortcutInfo si = mShortcuts.valueAt(i);
+        final boolean[] changed = new boolean[1];
+        forEachShortcutMutateIf(si -> {
             if (si.isDynamic() && (!ignoreInvisible || si.isVisibleToPublisher())) {
-                changed = true;
+                changed[0] = true;
 
-                mutateShortcut(si.getId(), si, shortcut -> {
-                    shortcut.setTimestamp(now);
-                    shortcut.clearFlags(ShortcutInfo.FLAG_DYNAMIC);
-                    shortcut.setRank(0); // It may still be pinned, so clear the rank.
-                });
+                si.setTimestamp(now);
+                si.clearFlags(ShortcutInfo.FLAG_DYNAMIC);
+                si.setRank(0); // It may still be pinned, so clear the rank.
+                return true;
             }
-        }
-        if (changed) {
+            return false;
+        });
+        if (changed[0]) {
             return removeOrphans();
         }
         return null;
@@ -508,7 +529,7 @@
      * @return The deleted shortcut, or null if it was not actually removed because it's pinned.
      */
     public ShortcutInfo deleteLongLivedWithId(@NonNull String shortcutId, boolean ignoreInvisible) {
-        final ShortcutInfo shortcut = mShortcuts.get(shortcutId);
+        final ShortcutInfo shortcut = findShortcutById(shortcutId);
         if (shortcut != null) {
             mutateShortcut(shortcutId, null, si -> si.clearFlags(ShortcutInfo.FLAG_CACHED_ALL));
         }
@@ -551,7 +572,7 @@
         Preconditions.checkState(
                 (disable == (disabledReason != ShortcutInfo.DISABLED_REASON_NOT_DISABLED)),
                 "disable and disabledReason disagree: " + disable + " vs " + disabledReason);
-        final ShortcutInfo oldShortcut = mShortcuts.get(shortcutId);
+        final ShortcutInfo oldShortcut = findShortcutById(shortcutId);
 
         if (oldShortcut == null || !oldShortcut.isEnabled()
                 && (ignoreInvisible && !oldShortcut.isVisibleToPublisher())) {
@@ -567,7 +588,7 @@
                 si.clearFlags(ShortcutInfo.FLAG_DYNAMIC | ShortcutInfo.FLAG_MANIFEST);
                 if (disable) {
                     si.addFlags(ShortcutInfo.FLAG_DISABLED);
-                    // Do not overwrite the disabled reason if one is alreay set.
+                    // Do not overwrite the disabled reason if one is already set.
                     if (si.getDisabledReason() == ShortcutInfo.DISABLED_REASON_NOT_DISABLED) {
                         si.setDisabledReason(disabledReason);
                     }
@@ -579,7 +600,6 @@
                     si.setActivity(null);
                 }
             });
-
             return null;
         } else {
             forceDeleteShortcutInner(shortcutId);
@@ -596,7 +616,7 @@
     }
 
     public void updateInvisibleShortcutForPinRequestWith(@NonNull ShortcutInfo shortcut) {
-        final ShortcutInfo source = mShortcuts.get(shortcut.getId());
+        final ShortcutInfo source = findShortcutById(shortcut.getId());
         Objects.requireNonNull(source);
 
         mShortcutUser.mService.validateShortcutForPinRequest(shortcut);
@@ -615,13 +635,6 @@
      * <p>Then remove all shortcuts that are not dynamic and no longer pinned either.
      */
     public void refreshPinnedFlags() {
-        // TODO: rewrite this function with proper query (i.e. fetch only pinned shortcuts and
-        //  unpin if it's no longer pinned by any launcher and vice versa)
-        final List<ShortcutInfo> shortcuts = new ArrayList<>(mShortcuts.values());
-        final Map<String, ShortcutInfo> shortcutMap = new ArrayMap<>(shortcuts.size());
-        for (ShortcutInfo si : shortcuts) {
-            shortcutMap.put(si.getId(), si);
-        }
         final Set<String> pinnedShortcuts = new ArraySet<>();
 
         // First, for the pinned set for each launcher, keep track of their id one by one.
@@ -631,31 +644,20 @@
             if (pinned == null || pinned.size() == 0) {
                 return;
             }
-            for (int i = pinned.size() - 1; i >= 0; i--) {
-                final String id = pinned.valueAt(i);
-                final ShortcutInfo si = shortcutMap.get(id);
-                if (si == null) {
-                    // This happens if a launcher pinned shortcuts from this package, then backup&
-                    // restored, but this package doesn't allow backing up.
-                    // In that case the launcher ends up having a dangling pinned shortcuts.
-                    // That's fine, when the launcher is restored, we'll fix it.
-                    continue;
-                }
-                pinnedShortcuts.add(si.getId());
-            }
+            pinnedShortcuts.addAll(pinned);
         });
         // Then, update the pinned state if necessary
-        for (int i = shortcuts.size() - 1; i >= 0; i--) {
-            final ShortcutInfo si = shortcuts.get(i);
+        forEachShortcutMutateIf(si -> {
             if (pinnedShortcuts.contains(si.getId()) && !si.isPinned()) {
-                mutateShortcut(si.getId(), si,
-                        shortcut -> shortcut.addFlags(ShortcutInfo.FLAG_PINNED));
+                si.addFlags(ShortcutInfo.FLAG_PINNED);
+                return true;
             }
             if (!pinnedShortcuts.contains(si.getId()) && si.isPinned()) {
-                mutateShortcut(si.getId(), si, shortcut ->
-                        shortcut.clearFlags(ShortcutInfo.FLAG_PINNED));
+                si.clearFlags(ShortcutInfo.FLAG_PINNED);
+                return true;
             }
-        }
+            return false;
+        });
 
         // Lastly, remove the ones that are no longer pinned, cached nor dynamic.
         removeOrphans();
@@ -764,17 +766,13 @@
             // Restored and the app not installed yet, so don't return any.
             return;
         }
-
         final ShortcutService s = mShortcutUser.mService;
 
         // Set of pinned shortcuts by the calling launcher.
         final ArraySet<String> pinnedByCallerSet = (callingLauncher == null) ? null
                 : s.getLauncherShortcutsLocked(callingLauncher, getPackageUserId(), launcherUserId)
-                    .getPinnedShortcutIds(getPackageName(), getPackageUserId());
-
-        for (int i = 0; i < mShortcuts.size(); i++) {
-            final ShortcutInfo si = mShortcuts.valueAt(i);
-
+                        .getPinnedShortcutIds(getPackageName(), getPackageUserId());
+        forEachShortcut(si -> {
             // Need to adjust PINNED flag depending on the caller.
             // Basically if the caller is a launcher (callingLauncher != null) and the launcher
             // isn't pinning it, then we need to clear PINNED for this caller.
@@ -784,7 +782,7 @@
             if (!getPinnedByAnyLauncher) {
                 if (si.isFloating() && !si.isCached()) {
                     if (!isPinnedByCaller) {
-                        continue;
+                        return;
                     }
                 }
             }
@@ -804,7 +802,7 @@
                 }
                 result.add(clone);
             }
-        }
+        });
     }
 
     public void resetThrottling() {
@@ -874,7 +872,7 @@
      * the app's Xml resource.
      */
     int getSharingShortcutCount() {
-        if (mShortcuts.isEmpty() || mShareTargets.isEmpty()) {
+        if (getShortcutCount() == 0 || mShareTargets.isEmpty()) {
             return 0;
         }
 
@@ -912,14 +910,12 @@
      * Return the filenames (excluding path names) of icon bitmap files from this package.
      */
     public ArraySet<String> getUsedBitmapFiles() {
-        final ArraySet<String> usedFiles = new ArraySet<>(mShortcuts.size());
-
-        for (int i = mShortcuts.size() - 1; i >= 0; i--) {
-            final ShortcutInfo si = mShortcuts.valueAt(i);
+        final ArraySet<String> usedFiles = new ArraySet<>(1);
+        forEachShortcut(si -> {
             if (si.getBitmapPath() != null) {
                 usedFiles.add(getFileName(si.getBitmapPath()));
             }
-        }
+        });
         return usedFiles;
     }
 
@@ -936,30 +932,29 @@
      * @return false if any of the target activities are no longer enabled.
      */
     private boolean areAllActivitiesStillEnabled() {
-        if (mShortcuts.size() == 0) {
-            return true;
-        }
         final ShortcutService s = mShortcutUser.mService;
 
         // Normally the number of target activities is 1 or so, so no need to use a complex
         // structure like a set.
         final ArrayList<ComponentName> checked = new ArrayList<>(4);
+        final boolean[] reject = new boolean[1];
 
-        for (int i = mShortcuts.size() - 1; i >= 0; i--) {
-            final ShortcutInfo si = mShortcuts.valueAt(i);
+        forEachShortcutStopWhen(si -> {
             final ComponentName activity = si.getActivity();
 
             if (checked.contains(activity)) {
-                continue; // Already checked.
+                return false; // Already checked.
             }
             checked.add(activity);
 
             if ((activity != null)
                     && !s.injectIsActivityEnabledAndExported(activity, getOwnerUserId())) {
-                return false;
+                reject[0] = true;
+                return true; // Found at least 1 activity is disabled, so skip the rest.
             }
-        }
-        return true;
+            return false;
+        });
+        return !reject[0];
     }
 
     /**
@@ -1042,33 +1037,32 @@
 
         // See if there are any shortcuts that were prevented restoring because the app was of a
         // lower version, and re-enable them.
-        for (int i = mShortcuts.size() - 1; i >= 0; i--) {
-            final ShortcutInfo si = mShortcuts.valueAt(i);
+        forEachShortcutMutateIf(si -> {
             if (si.getDisabledReason() != ShortcutInfo.DISABLED_REASON_VERSION_LOWER) {
-                continue;
+                return false;
             }
             if (getPackageInfo().getBackupSourceVersionCode() > newVersionCode) {
                 if (ShortcutService.DEBUG) {
                     Slog.d(TAG, String.format("Shortcut %s require version %s, still not restored.",
                             si.getId(), getPackageInfo().getBackupSourceVersionCode()));
                 }
-                continue;
+                return false;
             }
             Slog.i(TAG, String.format("Restoring shortcut: %s", si.getId()));
-            mutateShortcut(si.getId(), si, shortcut -> {
-                shortcut.clearFlags(ShortcutInfo.FLAG_DISABLED);
-                shortcut.setDisabledReason(ShortcutInfo.DISABLED_REASON_NOT_DISABLED);
-            });
-        }
+            if (si.hasFlags(ShortcutInfo.FLAG_DISABLED)
+                    || si.getDisabledReason() != ShortcutInfo.DISABLED_REASON_NOT_DISABLED) {
+                si.clearFlags(ShortcutInfo.FLAG_DISABLED);
+                si.setDisabledReason(ShortcutInfo.DISABLED_REASON_NOT_DISABLED);
+                return true;
+            }
+            return false;
+        });
 
         // For existing shortcuts, update timestamps if they have any resources.
         // Also check if shortcuts' activities are still main activities.  Otherwise, disable them.
         if (!isNewApp) {
-            Resources publisherRes = null;
-
-            for (int i = mShortcuts.size() - 1; i >= 0; i--) {
-                final ShortcutInfo si = mShortcuts.valueAt(i);
-
+            final Resources publisherRes = getPackageResources();
+            forEachShortcutMutateIf(si -> {
                 // Disable dynamic shortcuts whose target activity is gone.
                 if (si.isDynamic()) {
                     if (si.getActivity() == null) {
@@ -1081,33 +1075,26 @@
                                 getPackageName(), si.getId()));
                         if (disableDynamicWithId(si.getId(), /*ignoreInvisible*/ false,
                                 ShortcutInfo.DISABLED_REASON_APP_CHANGED) != null) {
-                            continue; // Actually removed.
+                            return false; // Actually removed.
                         }
                         // Still pinned, so fall-through and possibly update the resources.
                     }
                 }
 
-                if (si.hasAnyResources()) {
-                    if (publisherRes == null) {
-                        publisherRes = getPackageResources();
-                        if (publisherRes == null) {
-                            break; // Resources couldn't be loaded.
-                        }
-                    }
-
-                    final Resources res = publisherRes;
-                    mutateShortcut(si.getId(), si, shortcut -> {
-                        if (!shortcut.isOriginallyFromManifest()) {
-                            shortcut.lookupAndFillInResourceIds(res);
-                        }
-
-                        // If this shortcut is not from a manifest, then update all resource IDs
-                        // from resource names.  (We don't allow resource strings for
-                        // non-manifest at the moment, but icons can still be resources.)
-                        shortcut.setTimestamp(s.injectCurrentTimeMillis());
-                    });
+                if (!si.hasAnyResources() || publisherRes == null) {
+                    return false;
                 }
-            }
+
+                if (!si.isOriginallyFromManifest()) {
+                    si.lookupAndFillInResourceIds(publisherRes);
+                }
+
+                // If this shortcut is not from a manifest, then update all resource IDs
+                // from resource names.  (We don't allow resource strings for
+                // non-manifest at the moment, but icons can still be resources.)
+                si.setTimestamp(s.injectCurrentTimeMillis());
+                return true;
+            });
         }
 
         // (Re-)publish manifest shortcut.
@@ -1133,17 +1120,12 @@
         boolean changed = false;
 
         // Keep the previous IDs.
-        ArraySet<String> toDisableList = null;
-        for (int i = mShortcuts.size() - 1; i >= 0; i--) {
-            final ShortcutInfo si = mShortcuts.valueAt(i);
-
+        final ArraySet<String> toDisableList = new ArraySet<>(1);
+        forEachShortcut(si -> {
             if (si.isManifestShortcut()) {
-                if (toDisableList == null) {
-                    toDisableList = new ArraySet<>();
-                }
                 toDisableList.add(si.getId());
             }
-        }
+        });
 
         // Publish new ones.
         if (newManifestShortcutList != null) {
@@ -1156,7 +1138,7 @@
                 final boolean newDisabled = !newShortcut.isEnabled();
 
                 final String id = newShortcut.getId();
-                final ShortcutInfo oldShortcut = mShortcuts.get(id);
+                final ShortcutInfo oldShortcut = findShortcutById(id);
 
                 boolean wasPinned = false;
 
@@ -1183,7 +1165,7 @@
                 // regardless.
                 forceReplaceShortcutInner(newShortcut); // This will clean up the old one too.
 
-                if (!newDisabled && toDisableList != null) {
+                if (!newDisabled && !toDisableList.isEmpty()) {
                     // Still alive, don't remove.
                     toDisableList.remove(id);
                 }
@@ -1191,7 +1173,7 @@
         }
 
         // Disable the previous manifest shortcuts that are no longer in the manifest.
-        if (toDisableList != null) {
+        if (!toDisableList.isEmpty()) {
             if (ShortcutService.DEBUG) {
                 Slog.d(TAG, String.format(
                         "Package %s: disabling %d stale shortcuts", getPackageName(),
@@ -1206,8 +1188,9 @@
                         /* overrideImmutable=*/ true, /*ignoreInvisible=*/ false,
                         ShortcutInfo.DISABLED_REASON_APP_CHANGED);
             }
-            removeOrphans();
         }
+        removeOrphans();
+
         adjustRanks();
         return changed;
     }
@@ -1279,25 +1262,21 @@
     private ArrayMap<ComponentName, ArrayList<ShortcutInfo>> sortShortcutsToActivities() {
         final ArrayMap<ComponentName, ArrayList<ShortcutInfo>> activitiesToShortcuts
                 = new ArrayMap<>();
-        for (int i = mShortcuts.size() - 1; i >= 0; i--) {
-            final ShortcutInfo si = mShortcuts.valueAt(i);
+        forEachShortcut(si -> {
             if (si.isFloating()) {
-                continue; // Ignore floating shortcuts, which are not tied to any activities.
+                return; // Ignore floating shortcuts, which are not tied to any activities.
             }
 
             final ComponentName activity = si.getActivity();
             if (activity == null) {
                 mShortcutUser.mService.wtf("null activity detected.");
-                continue;
+                return;
             }
 
-            ArrayList<ShortcutInfo> list = activitiesToShortcuts.get(activity);
-            if (list == null) {
-                list = new ArrayList<>();
-                activitiesToShortcuts.put(activity, list);
-            }
+            ArrayList<ShortcutInfo> list = activitiesToShortcuts.computeIfAbsent(activity,
+                    k -> new ArrayList<>());
             list.add(si);
-        }
+        });
         return activitiesToShortcuts;
     }
 
@@ -1333,15 +1312,13 @@
         // (If it's for update, then don't count dynamic shortcuts, since they'll be replaced
         // anyway.)
         final ArrayMap<ComponentName, Integer> counts = new ArrayMap<>(4);
-        for (int i = mShortcuts.size() - 1; i >= 0; i--) {
-            final ShortcutInfo shortcut = mShortcuts.valueAt(i);
-
+        forEachShortcut(shortcut -> {
             if (shortcut.isManifestShortcut()) {
                 incrementCountForActivity(counts, shortcut.getActivity(), 1);
             } else if (shortcut.isDynamic() && (operation != ShortcutService.OPERATION_SET)) {
                 incrementCountForActivity(counts, shortcut.getActivity(), 1);
             }
-        }
+        });
 
         for (int i = newList.size() - 1; i >= 0; i--) {
             final ShortcutInfo newShortcut = newList.get(i);
@@ -1354,7 +1331,7 @@
                 continue; // Activity can be null for update.
             }
 
-            final ShortcutInfo original = mShortcuts.get(newShortcut.getId());
+            final ShortcutInfo original = findShortcutById(newShortcut.getId());
             if (original == null) {
                 if (operation == ShortcutService.OPERATION_UPDATE) {
                     continue; // When updating, ignore if there's no target.
@@ -1391,34 +1368,19 @@
      * For all the text fields, refresh the string values if they're from resources.
      */
     public void resolveResourceStrings() {
-        // TODO: update resource strings in AppSearch
         final ShortcutService s = mShortcutUser.mService;
 
-        List<ShortcutInfo> changedShortcuts = null;
+        final Resources publisherRes = getPackageResources();
+        final List<ShortcutInfo> changedShortcuts = new ArrayList<>(1);
 
-        Resources publisherRes = null;
-        for (int i = mShortcuts.size() - 1; i >= 0; i--) {
-            final ShortcutInfo si = mShortcuts.valueAt(i);
-
-            if (si.hasStringResources()) {
-                if (publisherRes == null) {
-                    publisherRes = getPackageResources();
-                    if (publisherRes == null) {
-                        break; // Resources couldn't be loaded.
-                    }
-                }
-
-                final Resources res = publisherRes;
-                mutateShortcut(si.getId(), si, shortcut -> {
-                    shortcut.resolveResourceStrings(res);
-                    shortcut.setTimestamp(s.injectCurrentTimeMillis());
-                });
-
-                if (changedShortcuts == null) {
-                    changedShortcuts = new ArrayList<>(1);
-                }
+        if (publisherRes != null) {
+            forEachShortcutMutateIf(si -> {
+                if (!si.hasStringResources()) return false;
+                si.resolveResourceStrings(publisherRes);
+                si.setTimestamp(s.injectCurrentTimeMillis());
                 changedShortcuts.add(si);
-            }
+                return true;
+            });
         }
         if (!CollectionUtils.isEmpty(changedShortcuts)) {
             s.packageShortcutsChanged(getPackageName(), getPackageUserId(), changedShortcuts, null);
@@ -1427,10 +1389,7 @@
 
     /** Clears the implicit ranks for all shortcuts. */
     public void clearAllImplicitRanks() {
-        for (int i = mShortcuts.size() - 1; i >= 0; i--) {
-            final ShortcutInfo si = mShortcuts.valueAt(i);
-            mutateShortcut(si.getId(), si, ShortcutInfo::clearImplicitRankAndRankChangedFlag);
-        }
+        forEachShortcutMutate(ShortcutInfo::clearImplicitRankAndRankChangedFlag);
     }
 
     /**
@@ -1470,17 +1429,16 @@
         final long now = s.injectCurrentTimeMillis();
 
         // First, clear ranks for floating shortcuts.
-        for (int i = mShortcuts.size() - 1; i >= 0; i--) {
-            final ShortcutInfo si = mShortcuts.valueAt(i);
+        forEachShortcutMutateIf(si -> {
             if (si.isFloating()) {
                 if (si.getRank() != 0) {
-                    mutateShortcut(si.getId(), si, shortcut -> {
-                        shortcut.setTimestamp(now);
-                        shortcut.setRank(0);
-                    });
+                    si.setTimestamp(now);
+                    si.setRank(0);
+                    return true;
                 }
             }
-        }
+            return false;
+        });
 
         // Then adjust ranks.  Ranks are unique for each activity, so we first need to sort
         // shortcuts to each activity.
@@ -1505,7 +1463,7 @@
                 }
                 // At this point, it must be dynamic.
                 if (!si.isDynamic()) {
-                    s.wtf("Non-dynamic shortcut found.");
+                    s.wtf("Non-dynamic shortcut found.:  " + si.toInsecureString());
                     continue;
                 }
                 final int thisRank = rank++;
@@ -1521,13 +1479,15 @@
 
     /** @return true if there's any shortcuts that are not manifest shortcuts. */
     public boolean hasNonManifestShortcuts() {
-        for (int i = mShortcuts.size() - 1; i >= 0; i--) {
-            final ShortcutInfo si = mShortcuts.valueAt(i);
+        final boolean[] condition = new boolean[1];
+        forEachShortcutStopWhen(si -> {
             if (!si.isDeclaredInManifest()) {
+                condition[0] = true;
                 return true;
             }
-        }
-        return false;
+            return false;
+        });
+        return condition[0];
     }
 
     public void dump(@NonNull PrintWriter pw, @NonNull String prefix, DumpFilter filter) {
@@ -1567,11 +1527,8 @@
 
         pw.print(prefix);
         pw.println("  Shortcuts:");
-        long totalBitmapSize = 0;
-        final ArrayMap<String, ShortcutInfo> shortcuts = mShortcuts;
-        final int size = shortcuts.size();
-        for (int i = 0; i < size; i++) {
-            final ShortcutInfo si = shortcuts.valueAt(i);
+        final long[] totalBitmapSize = new long[1];
+        forEachShortcut(si -> {
             pw.println(si.toDumpString(prefix + "    "));
             if (si.getBitmapPath() != null) {
                 final long len = new File(si.getBitmapPath()).length();
@@ -1580,15 +1537,15 @@
                 pw.print("bitmap size=");
                 pw.println(len);
 
-                totalBitmapSize += len;
+                totalBitmapSize[0] += len;
             }
-        }
+        });
         pw.print(prefix);
         pw.print("  ");
         pw.print("Total bitmap size: ");
-        pw.print(totalBitmapSize);
+        pw.print(totalBitmapSize[0]);
         pw.print(" (");
-        pw.print(Formatter.formatFileSize(mShortcutUser.mService.mContext, totalBitmapSize));
+        pw.print(Formatter.formatFileSize(mShortcutUser.mService.mContext, totalBitmapSize[0]));
         pw.println(")");
     }
 
@@ -1603,46 +1560,39 @@
                 | (matchManifest ? ShortcutInfo.FLAG_MANIFEST : 0)
                 | (matchCached ? ShortcutInfo.FLAG_CACHED_ALL : 0);
 
-        final ArrayMap<String, ShortcutInfo> shortcuts = mShortcuts;
-        final int size = shortcuts.size();
-        for (int i = 0; i < size; i++) {
-            final ShortcutInfo si = shortcuts.valueAt(i);
+        forEachShortcut(si -> {
             if ((si.getFlags() & shortcutFlags) != 0) {
                 pw.println(si.toDumpString(""));
             }
-        }
+        });
     }
 
     @Override
     public JSONObject dumpCheckin(boolean clear) throws JSONException {
         final JSONObject result = super.dumpCheckin(clear);
 
-        int numDynamic = 0;
-        int numPinned = 0;
-        int numManifest = 0;
-        int numBitmaps = 0;
-        long totalBitmapSize = 0;
+        final int[] numDynamic = new int[1];
+        final int[] numPinned = new int[1];
+        final int[] numManifest = new int[1];
+        final int[] numBitmaps = new int[1];
+        final long[] totalBitmapSize = new long[1];
 
-        final ArrayMap<String, ShortcutInfo> shortcuts = mShortcuts;
-        final int size = shortcuts.size();
-        for (int i = 0; i < size; i++) {
-            final ShortcutInfo si = shortcuts.valueAt(i);
-
-            if (si.isDynamic()) numDynamic++;
-            if (si.isDeclaredInManifest()) numManifest++;
-            if (si.isPinned()) numPinned++;
+        forEachShortcut(si -> {
+            if (si.isDynamic()) numDynamic[0]++;
+            if (si.isDeclaredInManifest()) numManifest[0]++;
+            if (si.isPinned()) numPinned[0]++;
 
             if (si.getBitmapPath() != null) {
-                numBitmaps++;
-                totalBitmapSize += new File(si.getBitmapPath()).length();
+                numBitmaps[0]++;
+                totalBitmapSize[0] += new File(si.getBitmapPath()).length();
             }
-        }
+        });
 
-        result.put(KEY_DYNAMIC, numDynamic);
-        result.put(KEY_MANIFEST, numManifest);
-        result.put(KEY_PINNED, numPinned);
-        result.put(KEY_BITMAPS, numBitmaps);
-        result.put(KEY_BITMAP_BYTES, totalBitmapSize);
+        result.put(KEY_DYNAMIC, numDynamic[0]);
+        result.put(KEY_MANIFEST, numManifest[0]);
+        result.put(KEY_PINNED, numPinned[0]);
+        result.put(KEY_BITMAPS, numBitmaps[0]);
+        result.put(KEY_BITMAP_BYTES, totalBitmapSize[0]);
 
         // TODO Log update frequency too.
 
@@ -1652,7 +1602,7 @@
     @Override
     public void saveToXml(@NonNull TypedXmlSerializer out, boolean forBackup)
             throws IOException, XmlPullParserException {
-        final int size = mShortcuts.size();
+        final int size = getShortcutCount();
         final int shareTargetSize = mShareTargets.size();
 
         if (size == 0 && shareTargetSize == 0 && mApiCallCount == 0) {
@@ -1666,9 +1616,15 @@
         ShortcutService.writeAttr(out, ATTR_LAST_RESET, mLastResetTime);
         getPackageInfo().saveToXml(mShortcutUser.mService, out, forBackup);
 
-        for (int j = 0; j < size; j++) {
-            saveShortcut(out, mShortcuts.valueAt(j), forBackup,
-                    getPackageInfo().isBackupAllowed());
+        if (forBackup) {
+            // Shortcuts are persisted in AppSearch, xml is only needed for backup.
+            forEachShortcut(si -> {
+                try {
+                    saveShortcut(out, si, forBackup, getPackageInfo().isBackupAllowed());
+                } catch (IOException | XmlPullParserException e) {
+                    throw new RuntimeException(e);
+                }
+            });
         }
 
         if (!forBackup) {
@@ -1785,12 +1741,14 @@
             }
             final Intent[] intentsNoExtras = si.getIntentsNoExtras();
             final PersistableBundle[] intentsExtras = si.getIntentPersistableExtrases();
-            final int numIntents = intentsNoExtras.length;
-            for (int i = 0; i < numIntents; i++) {
-                out.startTag(null, TAG_INTENT);
-                ShortcutService.writeAttr(out, ATTR_INTENT_NO_EXTRA, intentsNoExtras[i]);
-                ShortcutService.writeTagExtra(out, TAG_EXTRAS, intentsExtras[i]);
-                out.endTag(null, TAG_INTENT);
+            if (intentsNoExtras != null && intentsExtras != null) {
+                final int numIntents = intentsNoExtras.length;
+                for (int i = 0; i < numIntents; i++) {
+                    out.startTag(null, TAG_INTENT);
+                    ShortcutService.writeAttr(out, ATTR_INTENT_NO_EXTRA, intentsNoExtras[i]);
+                    ShortcutService.writeTagExtra(out, TAG_EXTRAS, intentsExtras[i]);
+                    out.endTag(null, TAG_INTENT);
+                }
             }
 
             ShortcutService.writeTagExtra(out, TAG_EXTRAS, si.getExtras());
@@ -1877,9 +1835,8 @@
                     case TAG_SHORTCUT:
                         final ShortcutInfo si = parseShortcut(parser, packageName,
                                 shortcutUser.getUserId(), fromBackup);
-
                         // Don't use addShortcut(), we don't need to save the icon.
-                        ret.mShortcuts.put(si.getId(), si);
+                        ret.mShortcuts.add(si);
                         continue;
                     case TAG_SHARE_TARGET:
                         ret.mShareTargets.add(ShareTargetInfo.loadFromXml(parser));
@@ -2075,7 +2032,9 @@
 
     @VisibleForTesting
     List<ShortcutInfo> getAllShortcutsForTest() {
-        return new ArrayList<>(mShortcuts.values());
+        final List<ShortcutInfo> ret = new ArrayList<>(1);
+        forEachShortcut(ret::add);
+        return ret;
     }
 
     @VisibleForTesting
@@ -2087,7 +2046,7 @@
     public void verifyStates() {
         super.verifyStates();
 
-        boolean failed = false;
+        final boolean[] failed = new boolean[1];
 
         final ShortcutService s = mShortcutUser.mService;
 
@@ -2098,7 +2057,7 @@
         for (int outer = all.size() - 1; outer >= 0; outer--) {
             final ArrayList<ShortcutInfo> list = all.valueAt(outer);
             if (list.size() > mShortcutUser.mService.getMaxActivityShortcuts()) {
-                failed = true;
+                failed[0] = true;
                 Log.e(TAG_VERIFY, "Package " + getPackageName() + ": activity " + all.keyAt(outer)
                         + " has " + all.valueAt(outer).size() + " shortcuts.");
             }
@@ -2118,61 +2077,60 @@
         }
 
         // Verify each shortcut's status.
-        for (int i = mShortcuts.size() - 1; i >= 0; i--) {
-            final ShortcutInfo si = mShortcuts.valueAt(i);
+        forEachShortcut(si -> {
             if (!(si.isDeclaredInManifest() || si.isDynamic() || si.isPinned() || si.isCached())) {
-                failed = true;
+                failed[0] = true;
                 Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
                         + " is not manifest, dynamic or pinned.");
             }
             if (si.isDeclaredInManifest() && si.isDynamic()) {
-                failed = true;
+                failed[0] = true;
                 Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
                         + " is both dynamic and manifest at the same time.");
             }
             if (si.getActivity() == null && !si.isFloating()) {
-                failed = true;
+                failed[0] = true;
                 Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
                         + " has null activity, but not floating.");
             }
             if ((si.isDynamic() || si.isManifestShortcut()) && !si.isEnabled()) {
-                failed = true;
+                failed[0] = true;
                 Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
                         + " is not floating, but is disabled.");
             }
             if (si.isFloating() && si.getRank() != 0) {
-                failed = true;
+                failed[0] = true;
                 Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
                         + " is floating, but has rank=" + si.getRank());
             }
             if (si.getIcon() != null) {
-                failed = true;
+                failed[0] = true;
                 Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
                         + " still has an icon");
             }
             if (si.hasAdaptiveBitmap() && !(si.hasIconFile() || si.hasIconUri())) {
-                failed = true;
+                failed[0] = true;
                 Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
                         + " has adaptive bitmap but was not saved to a file nor has icon uri.");
             }
             if (si.hasIconFile() && si.hasIconResource()) {
-                failed = true;
+                failed[0] = true;
                 Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
                         + " has both resource and bitmap icons");
             }
             if (si.hasIconFile() && si.hasIconUri()) {
-                failed = true;
+                failed[0] = true;
                 Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
                         + " has both url and bitmap icons");
             }
             if (si.hasIconUri() && si.hasIconResource()) {
-                failed = true;
+                failed[0] = true;
                 Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
                         + " has both url and resource icons");
             }
             if (si.isEnabled()
                     != (si.getDisabledReason() == ShortcutInfo.DISABLED_REASON_NOT_DISABLED)) {
-                failed = true;
+                failed[0] = true;
                 Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
                         + " isEnabled() and getDisabledReason() disagree: "
                         + si.isEnabled() + " vs " + si.getDisabledReason());
@@ -2180,18 +2138,18 @@
             if ((si.getDisabledReason() == ShortcutInfo.DISABLED_REASON_VERSION_LOWER)
                     && (getPackageInfo().getBackupSourceVersionCode()
                     == ShortcutInfo.VERSION_CODE_UNKNOWN)) {
-                failed = true;
+                failed[0] = true;
                 Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
                         + " RESTORED_VERSION_LOWER with no backup source version code.");
             }
             if (s.isDummyMainActivity(si.getActivity())) {
-                failed = true;
+                failed[0] = true;
                 Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
                         + " has a dummy target activity");
             }
-        }
+        });
 
-        if (failed) {
+        if (failed[0]) {
             throw new IllegalStateException("See logcat for errors");
         }
     }
@@ -2202,7 +2160,7 @@
         } else {
             mPackageIdentifiers.remove(packageName);
         }
-        resetAppSearch(null);
+        resetAppSearch(session -> AndroidFuture.completedFuture(true));
     }
 
     void mutateShortcut(@NonNull final String id, @Nullable final ShortcutInfo shortcut,
@@ -2212,23 +2170,284 @@
         synchronized (mLock) {
             if (shortcut != null) {
                 transform.accept(shortcut);
-            } else {
-                transform.accept(findShortcutById(id));
             }
-            // TODO: Load ShortcutInfo from AppSearch, apply transformation logic and save
+            final ShortcutInfo si = getShortcutById(id);
+            if (si == null) {
+                return;
+            }
+            transform.accept(si);
+            saveShortcut(si);
         }
     }
 
+    private void saveShortcut(@NonNull final ShortcutInfo... shortcuts) {
+        Objects.requireNonNull(shortcuts);
+        saveShortcut(Arrays.asList(shortcuts));
+    }
+
+    private void saveShortcut(@NonNull final Collection<ShortcutInfo> shortcuts) {
+        Objects.requireNonNull(shortcuts);
+        ConcurrentUtils.waitForFutureNoInterrupt(
+                runInAppSearch(session -> {
+                    final AndroidFuture<Boolean> future = new AndroidFuture<>();
+                    session.put(new PutDocumentsRequest.Builder()
+                                    .addGenericDocuments(
+                                            AppSearchShortcutInfo.toGenericDocuments(shortcuts))
+                                    .build(),
+                            mShortcutUser.mExecutor,
+                            result -> {
+                                if (!result.isSuccess()) {
+                                    for (AppSearchResult<Void> k : result.getFailures().values()) {
+                                        Slog.e(TAG, k.getErrorMessage());
+                                    }
+                                    future.completeExceptionally(new RuntimeException(
+                                            "failed to save shortcuts"));
+                                    return;
+                                }
+                                future.complete(true);
+                            });
+                    return future;
+                }),
+                "saving shortcut");
+    }
+
     /**
      * Removes shortcuts from AppSearch.
      */
     void removeShortcuts() {
+        awaitInAppSearch("removing shortcuts", session -> {
+            final AndroidFuture<Boolean> future = new AndroidFuture<>();
+            session.remove("",
+                    new SearchSpec.Builder()
+                            .addFilterSchemas(AppSearchShortcutInfo.SCHEMA_TYPE)
+                            .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
+                            .build(),
+                    mShortcutUser.mExecutor, result -> {
+                        if (!result.isSuccess()) {
+                            future.completeExceptionally(new RuntimeException(
+                                    "Failed to cleanup shortcuts " + result.getErrorMessage()));
+                            return;
+                        }
+                        future.complete(true);
+                    });
+            return future;
+        });
+    }
+
+    private void removeShortcut(@NonNull final String id) {
+        Objects.requireNonNull(id);
+        awaitInAppSearch("removing shortcut with id=" + id, session -> {
+            final AndroidFuture<Boolean> future = new AndroidFuture<>();
+            session.remove(new RemoveByUriRequest.Builder(getPackageName()).addUris(id).build(),
+                    mShortcutUser.mExecutor, result -> {
+                        if (!result.isSuccess()) {
+                            final Map<String, AppSearchResult<Void>> failures =
+                                    result.getFailures();
+                            for (String key : failures.keySet()) {
+                                Slog.e(TAG, "Failed deleting " + key + ", error message:"
+                                        + failures.get(key).getErrorMessage());
+                            }
+                            future.completeExceptionally(new RuntimeException(
+                                    "Failed to delete shortcut: " + id));
+                            return;
+                        }
+                        future.complete(true);
+                    });
+            return future;
+        });
+    }
+
+    private ShortcutInfo getShortcutById(String id) {
+        return awaitInAppSearch("getting shortcut with id=" + id, session -> {
+            final AndroidFuture<ShortcutInfo> future = new AndroidFuture<>();
+            session.getByUri(
+                    new GetByUriRequest.Builder(getPackageName()).addUris(id).build(),
+                    mShortcutUser.mExecutor,
+                    results -> {
+                        if (results.isSuccess()) {
+                            Map<String, GenericDocument> documents = results.getSuccesses();
+                            for (GenericDocument doc : documents.values()) {
+                                final ShortcutInfo info = new AppSearchShortcutInfo(doc)
+                                        .toShortcutInfo(mShortcutUser.getUserId());
+                                future.complete(info);
+                                return;
+                            }
+                        }
+                        future.complete(null);
+                    });
+            return future;
+        });
+    }
+
+    private void forEachShortcut(
+            @NonNull final Consumer<ShortcutInfo> cb) {
+        forEachShortcutStopWhen(si -> {
+            cb.accept(si);
+            return false;
+        });
+    }
+
+    private void forEachShortcutMutate(@NonNull final Consumer<ShortcutInfo> cb) {
+        forEachShortcutMutateIf(si -> {
+            cb.accept(si);
+            return true;
+        });
+    }
+
+    private void forEachShortcutMutateIf(@NonNull final Function<ShortcutInfo, Boolean> cb) {
+        final SearchResults res = awaitInAppSearch("mutating shortcuts", session ->
+                AndroidFuture.completedFuture(session.search("", new SearchSpec.Builder()
+                        .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY).build())));
+        if (res == null) return;
+        List<ShortcutInfo> shortcuts = getNextPage(res);
+        while (!shortcuts.isEmpty()) {
+            final List<ShortcutInfo> changed = new ArrayList<>(1);
+            for (ShortcutInfo si : shortcuts) {
+                if (cb.apply(si)) changed.add(si);
+            }
+            saveShortcut(changed);
+            shortcuts = getNextPage(res);
+        }
+    }
+
+    private void forEachShortcutStopWhen(
+            @NonNull final Function<ShortcutInfo, Boolean> cb) {
+        forEachShortcutStopWhen("", cb);
+    }
+
+    private void forEachShortcutStopWhen(
+            @NonNull final String query, @NonNull final Function<ShortcutInfo, Boolean> cb) {
+        final SearchResults res = awaitInAppSearch("iterating shortcuts", session ->
+                AndroidFuture.completedFuture(session.search(query, new SearchSpec.Builder()
+                        .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY).build())));
+        if (res == null) return;
+        List<ShortcutInfo> shortcuts = getNextPage(res);
+        while (!shortcuts.isEmpty()) {
+            for (ShortcutInfo si : shortcuts) {
+                if (cb.apply(si)) return;
+            }
+            shortcuts = getNextPage(res);
+        }
+    }
+
+    private List<ShortcutInfo> getNextPage(@NonNull final SearchResults res) {
+        final AndroidFuture<List<ShortcutInfo>> future = new AndroidFuture<>();
+        final List<ShortcutInfo> ret = new ArrayList<>();
+        final long callingIdentity = Binder.clearCallingIdentity();
+        try {
+            res.getNextPage(mShortcutUser.mExecutor, nextPage -> {
+                if (!nextPage.isSuccess()) {
+                    future.complete(ret);
+                    return;
+                }
+                final List<SearchResult> results = nextPage.getResultValue();
+                if (results.isEmpty()) {
+                    future.complete(ret);
+                    return;
+                }
+                final List<ShortcutInfo> page = new ArrayList<>(results.size());
+                for (SearchResult result : results) {
+                    final ShortcutInfo si = new AppSearchShortcutInfo(result.getGenericDocument())
+                            .toShortcutInfo(mShortcutUser.getUserId());
+                    page.add(si);
+                }
+                ret.addAll(page);
+                future.complete(ret);
+            });
+            return ConcurrentUtils.waitForFutureNoInterrupt(future,
+                    "getting next batch of shortcuts");
+        } finally {
+            Binder.restoreCallingIdentity(callingIdentity);
+        }
+    }
+
+    @Nullable
+    private <T> T awaitInAppSearch(
+            @NonNull final String description,
+            @NonNull final Function<AppSearchSession, CompletableFuture<T>> cb) {
+        return ConcurrentUtils.waitForFutureNoInterrupt(runInAppSearch(cb), description);
+    }
+
+    @Nullable
+    private <T> CompletableFuture<T> runInAppSearch(
+            @NonNull final Function<AppSearchSession, CompletableFuture<T>> cb) {
+        synchronized (mLock) {
+            final StrictMode.ThreadPolicy oldPolicy = StrictMode.getThreadPolicy();
+            try {
+                StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
+                        .detectAll()
+                        .penaltyLog() // TODO: change this to penaltyDeath to fix the call-site
+                        .build());
+                if (mAppSearchSession != null) {
+                    final long callingIdentity = Binder.clearCallingIdentity();
+                    try {
+                        return AndroidFuture.supply(() -> mAppSearchSession).thenCompose(cb);
+                    } finally {
+                        Binder.restoreCallingIdentity(callingIdentity);
+                    }
+                } else {
+                    return resetAppSearch(cb);
+                }
+            } finally {
+                StrictMode.setThreadPolicy(oldPolicy);
+            }
+        }
+    }
+
+    private <T> CompletableFuture<T> resetAppSearch(
+            @NonNull final Function<AppSearchSession, CompletableFuture<T>> cb) {
+        final long callingIdentity = Binder.clearCallingIdentity();
+        final AppSearchManager.SearchContext searchContext =
+                new AppSearchManager.SearchContext.Builder(getPackageName()).build();
+        final AppSearchSession session;
+        try {
+            session = ConcurrentUtils.waitForFutureNoInterrupt(
+                    mShortcutUser.getAppSearch(searchContext), "resetting app search");
+            ConcurrentUtils.waitForFutureNoInterrupt(setupSchema(session), "setting up schema");
+            mAppSearchSession = session;
+            return cb.apply(mAppSearchSession);
+        } catch (Exception e) {
+            Slog.e(TAG, "Failed to initiate app search for shortcut package "
+                    + getPackageName() + " user " + mShortcutUser.getUserId(), e);
+            return AndroidFuture.completedFuture(null);
+        } finally {
+            Binder.restoreCallingIdentity(callingIdentity);
+        }
+    }
+
+    @NonNull
+    private AndroidFuture<AppSearchSession> setupSchema(
+            @NonNull final AppSearchSession session) {
+        SetSchemaRequest.Builder schemaBuilder = new SetSchemaRequest.Builder()
+                .addSchemas(AppSearchPerson.SCHEMA, AppSearchShortcutInfo.SCHEMA);
+        for (PackageIdentifier pi : mPackageIdentifiers.values()) {
+            schemaBuilder = schemaBuilder
+                    .setSchemaTypeVisibilityForPackage(
+                            AppSearchPerson.SCHEMA_TYPE, true, pi)
+                    .setSchemaTypeVisibilityForPackage(
+                            AppSearchShortcutInfo.SCHEMA_TYPE, true, pi);
+        }
+        final AndroidFuture<AppSearchSession> future = new AndroidFuture<>();
+        session.setSchema(
+                schemaBuilder.build(), mShortcutUser.mExecutor, mShortcutUser.mExecutor, result -> {
+            if (!result.isSuccess()) {
+                future.completeExceptionally(
+                        new IllegalArgumentException(result.getErrorMessage()));
+                return;
+            }
+            future.complete(session);
+        });
+        return future;
     }
 
     /**
      * Merge/replace shortcuts parsed from xml file.
      */
     void restoreParsedShortcuts(final boolean replace) {
+        if (replace) {
+            removeShortcuts();
+        }
+        saveShortcut(mShortcuts);
     }
 
     private boolean verifyRanksSequential(List<ShortcutInfo> list) {
@@ -2239,133 +2458,9 @@
             if (si.getRank() != i) {
                 failed = true;
                 Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
-                        + " rank=" + si.getRank() + " but expected to be "+ i);
+                        + " rank=" + si.getRank() + " but expected to be " + i);
             }
         }
         return failed;
     }
-
-    private void runInAppSearch(
-            Function<SearchSessionObservable, Consumer<AppSearchSession>>... observers) {
-        if (mShortcutUser == null) {
-            Slog.w(TAG, "shortcut user is null");
-            return;
-        }
-        synchronized (mLock) {
-            if (mAppSearchSession != null) {
-                final CountDownLatch latch = new CountDownLatch(1);
-                final long callingIdentity = Binder.clearCallingIdentity();
-                try {
-                    final SearchSessionObservable upstream =
-                            new SearchSessionObservable(mAppSearchSession, latch);
-                    for (Function<SearchSessionObservable, Consumer<AppSearchSession>> observer
-                            : observers) {
-                        upstream.map(observer);
-                    }
-                    upstream.next();
-                } finally {
-                    Binder.restoreCallingIdentity(callingIdentity);
-                }
-                ConcurrentUtils.waitForCountDownNoInterrupt(latch, 500,
-                        "timeout accessing shortcut");
-            } else {
-                resetAppSearch(observers);
-            }
-        }
-    }
-
-    private void resetAppSearch(
-            Function<SearchSessionObservable, Consumer<AppSearchSession>>... observers) {
-        final CountDownLatch latch = new CountDownLatch(1);
-        final AppSearchManager.SearchContext searchContext =
-                new AppSearchManager.SearchContext.Builder()
-                        .setDatabaseName(getPackageName()).build();
-        mShortcutUser.runInAppSearch(searchContext, result -> {
-            if (!result.isSuccess()) {
-                Slog.e(TAG, "error getting search session during lazy init, "
-                        + result.getErrorMessage());
-                latch.countDown();
-                return;
-            }
-            // TODO: Flatten callback chain with proper async framework
-            final SearchSessionObservable upstream =
-                    new SearchSessionObservable(result.getResultValue(), latch)
-                            .map(this::setupSchema);
-            if (observers != null) {
-                for (Function<SearchSessionObservable, Consumer<AppSearchSession>> observer
-                        : observers) {
-                    upstream.map(observer);
-                }
-            }
-            upstream.map(observable -> session -> {
-                mAppSearchSession = session;
-                observable.next();
-            });
-            upstream.next();
-        });
-        ConcurrentUtils.waitForCountDownNoInterrupt(latch, 1500,
-                "timeout accessing shortcut during lazy initialization");
-    }
-
-    /**
-     * creates the schema for shortcut in the database
-     */
-    private Consumer<AppSearchSession> setupSchema(SearchSessionObservable observable) {
-        return session -> {
-            SetSchemaRequest.Builder schemaBuilder = new SetSchemaRequest.Builder()
-                            .addSchemas(AppSearchPerson.SCHEMA, AppSearchShortcutInfo.SCHEMA);
-            for (PackageIdentifier pi : mPackageIdentifiers.values()) {
-                schemaBuilder = schemaBuilder
-                        .setSchemaTypeVisibilityForPackage(
-                                AppSearchPerson.SCHEMA_TYPE, true, pi)
-                        .setSchemaTypeVisibilityForPackage(
-                                AppSearchShortcutInfo.SCHEMA_TYPE, true, pi);
-            }
-            session.setSchema(schemaBuilder.build(), mShortcutUser.mExecutor, result -> {
-                if (!result.isSuccess()) {
-                    observable.error("failed to instantiate app search schema: "
-                            + result.getErrorMessage());
-                    return;
-                }
-                observable.next();
-            });
-        };
-    }
-
-    /**
-     * TODO: Replace this temporary implementation with proper async framework
-     */
-    private class SearchSessionObservable {
-
-        final AppSearchSession mSession;
-        final CountDownLatch mLatch;
-        final ArrayList<Consumer<AppSearchSession>> mObservers = new ArrayList<>(1);
-
-        SearchSessionObservable(@NonNull final AppSearchSession session,
-                @NonNull final CountDownLatch latch) {
-            mSession = session;
-            mLatch = latch;
-        }
-
-        SearchSessionObservable map(
-                Function<SearchSessionObservable, Consumer<AppSearchSession>> observer) {
-            mObservers.add(observer.apply(this));
-            return this;
-        }
-
-        void next() {
-            if (mObservers.isEmpty()) {
-                mLatch.countDown();
-                return;
-            }
-            mObservers.remove(0).accept(mSession);
-        }
-
-        void error(@Nullable final String errorMessage) {
-            if (errorMessage != null) {
-                Slog.e(TAG, errorMessage);
-            }
-            mLatch.countDown();
-        }
-    }
 }
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index 38cba4c..d86438b 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -270,6 +270,7 @@
     final Context mContext;
 
     private final Object mLock = new Object();
+    private final Object mNonPersistentUsersLock = new Object();
 
     private static List<ResolveInfo> EMPTY_RESOLVE_INFO = new ArrayList<>(0);
 
@@ -310,8 +311,10 @@
 
     /**
      * User ID -> ShortcutNonPersistentUser
+     *
+     * Note we use a fine-grained lock for {@link #mShortcutNonPersistentUsers} due to b/183618378.
      */
-    @GuardedBy("mLock")
+    @GuardedBy("mNonPersistentUsersLock")
     private final SparseArray<ShortcutNonPersistentUser> mShortcutNonPersistentUsers =
             new SparseArray<>();
 
@@ -342,7 +345,7 @@
 
     private final IPackageManager mIPackageManager;
     private final PackageManagerInternal mPackageManagerInternal;
-    private final UserManagerInternal mUserManagerInternal;
+    final UserManagerInternal mUserManagerInternal;
     private final UsageStatsManagerInternal mUsageStatsManagerInternal;
     private final ActivityManagerInternal mActivityManagerInternal;
     private final IUriGrantsManager mUriGrantsManager;
@@ -1308,7 +1311,7 @@
     }
 
     /** Return the non-persistent per-user state. */
-    @GuardedBy("mLock")
+    @GuardedBy("mNonPersistentUsersLock")
     @NonNull
     ShortcutNonPersistentUser getNonPersistentUserLocked(@UserIdInt int userId) {
         ShortcutNonPersistentUser ret = mShortcutNonPersistentUsers.get(userId);
@@ -2590,7 +2593,6 @@
 
         final ShortcutPackage ps = getPackageShortcutsForPublisherLocked(packageName, userId);
         ps.findAll(ret, query, cloneFlags);
-
         return new ParceledListSlice<>(setReturnedByServer(ret));
     }
 
@@ -2749,7 +2751,7 @@
         if (injectHasAccessShortcutsPermission(callingPid, callingUid)) {
             return true;
         }
-        synchronized (mLock) {
+        synchronized (mNonPersistentUsersLock) {
             return getNonPersistentUserLocked(userId).hasHostPackage(callingPackage);
         }
     }
@@ -2832,7 +2834,7 @@
 
     public void setShortcutHostPackage(@NonNull String type, @Nullable String packageName,
             int userId) {
-        synchronized (mLock) {
+        synchronized (mNonPersistentUsersLock) {
             getNonPersistentUserLocked(userId).setShortcutHostPackage(type, packageName);
         }
     }
@@ -5078,6 +5080,17 @@
     }
 
     @VisibleForTesting
+    void updatePackageShortcutForTest(String packageName, String shortcutId, int userId,
+            Consumer<ShortcutInfo> cb) {
+        synchronized (mLock) {
+            final ShortcutPackage pkg = getPackageShortcutForTest(packageName, userId);
+            if (pkg == null) return;
+
+            pkg.mutateShortcut(shortcutId, null, cb);
+        }
+    }
+
+    @VisibleForTesting
     ShortcutLauncher getLauncherShortcutForTest(String packageName, int userId) {
         synchronized (mLock) {
             final ShortcutUser user = mUsers.get(userId);
diff --git a/services/core/java/com/android/server/pm/ShortcutUser.java b/services/core/java/com/android/server/pm/ShortcutUser.java
index ec784d0..5f0aa03 100644
--- a/services/core/java/com/android/server/pm/ShortcutUser.java
+++ b/services/core/java/com/android/server/pm/ShortcutUser.java
@@ -19,7 +19,6 @@
 import android.annotation.Nullable;
 import android.annotation.UserIdInt;
 import android.app.appsearch.AppSearchManager;
-import android.app.appsearch.AppSearchResult;
 import android.app.appsearch.AppSearchSession;
 import android.content.pm.ShortcutManager;
 import android.metrics.LogMaker;
@@ -35,6 +34,7 @@
 import android.util.TypedXmlSerializer;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.infra.AndroidFuture;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.server.FgThread;
@@ -333,10 +333,7 @@
 
         if (!shortcutPackage.rescanPackageIfNeeded(isNewApp, forceRescan)) {
             if (isNewApp) {
-                final ShortcutPackage sp = mPackages.remove(packageName);
-                if (sp != null) {
-                    sp.removeShortcuts();
-                }
+                mPackages.remove(packageName);
             }
         }
     }
@@ -715,17 +712,32 @@
                 .setSubtype(totalSharingShortcutCount));
     }
 
-    void runInAppSearch(@NonNull final AppSearchManager.SearchContext searchContext,
-            @NonNull final Consumer<AppSearchResult<AppSearchSession>> callback) {
+    AndroidFuture<AppSearchSession> getAppSearch(
+            @NonNull final AppSearchManager.SearchContext searchContext) {
+        final AndroidFuture<AppSearchSession> future = new AndroidFuture<>();
         if (mAppSearchManager == null) {
-            Slog.e(TAG, "app search manager is null");
-            return;
+            future.completeExceptionally(new RuntimeException("app search manager is null"));
+            return future;
+        }
+        if (!mService.mUserManagerInternal.isUserUnlockingOrUnlocked(getUserId())) {
+            // In rare cases the user might be stopped immediate after it started, in these cases
+            // any on-going session will need to be abandoned.
+            future.completeExceptionally(new RuntimeException("User " + getUserId() + " is "));
+            return future;
         }
         final long callingIdentity = Binder.clearCallingIdentity();
         try {
-            mAppSearchManager.createSearchSession(searchContext, mExecutor, callback);
+            mAppSearchManager.createSearchSession(searchContext, mExecutor, result -> {
+                if (!result.isSuccess()) {
+                    future.completeExceptionally(
+                            new RuntimeException(result.getErrorMessage()));
+                    return;
+                }
+                future.complete(result.getResultValue());
+            });
         } finally {
             Binder.restoreCallingIdentity(callingIdentity);
         }
+        return future;
     }
 }
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 8283ac6..2a0257d 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -1507,6 +1507,26 @@
     }
 
     @Override
+    public boolean isCloneProfile(@UserIdInt int userId) {
+        checkManageOrInteractPermissionIfCallerInOtherProfileGroup(userId, "isCloneProfile");
+        synchronized (mUsersLock) {
+            UserInfo userInfo = getUserInfoLU(userId);
+            return userInfo != null && userInfo.isCloneProfile();
+        }
+    }
+
+    @Override
+    public boolean sharesMediaWithParent(@UserIdInt int userId) {
+        checkManageOrInteractPermissionIfCallerInOtherProfileGroup(userId,
+                "sharesMediaWithParent");
+        synchronized (mUsersLock) {
+            UserTypeDetails userTypeDetails = getUserTypeDetailsNoChecks(userId);
+            return userTypeDetails != null ? userTypeDetails.isProfile()
+                    && userTypeDetails.sharesMediaWithParent() : false;
+        }
+    }
+
+    @Override
     public boolean isUserUnlockingOrUnlocked(@UserIdInt int userId) {
         checkManageOrInteractPermissionIfCallerInOtherProfileGroup(userId,
                 "isUserUnlockingOrUnlocked");
@@ -2861,6 +2881,100 @@
         }
     }
 
+    @GuardedBy("mUsersLock")
+    @VisibleForTesting
+    void upgradeUserTypesLU(@NonNull List<UserTypeFactory.UserTypeUpgrade> upgradeOps,
+            @NonNull ArrayMap<String, UserTypeDetails> userTypes,
+            final int formerUserTypeVersion,
+            @NonNull Set<Integer> userIdsToWrite) {
+        for (UserTypeFactory.UserTypeUpgrade userTypeUpgrade : upgradeOps) {
+            if (DBG) {
+                Slog.i(LOG_TAG, "Upgrade: " + userTypeUpgrade.getFromType() + " to: "
+                        + userTypeUpgrade.getToType() + " maxVersion: "
+                        + userTypeUpgrade.getUpToVersion());
+            }
+
+            // upgrade user type if version up to getUpToVersion()
+            if (formerUserTypeVersion <= userTypeUpgrade.getUpToVersion()) {
+                for (int i = 0; i < mUsers.size(); i++) {
+                    UserData userData = mUsers.valueAt(i);
+                    if (userTypeUpgrade.getFromType().equals(userData.info.userType)) {
+                        final UserTypeDetails newUserType = userTypes.get(
+                                userTypeUpgrade.getToType());
+
+                        if (newUserType == null) {
+                            throw new IllegalStateException(
+                                    "Upgrade destination user type not defined: "
+                                            + userTypeUpgrade.getToType());
+                        }
+
+                        upgradeProfileToTypeLU(userData.info, newUserType);
+                        userIdsToWrite.add(userData.info.id);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Changes the user type of a profile to a new user type.
+     * @param userInfo    The user to be updated.
+     * @param newUserType The new user type.
+     */
+    @GuardedBy("mUsersLock")
+    @VisibleForTesting
+    void upgradeProfileToTypeLU(@NonNull UserInfo userInfo, @NonNull UserTypeDetails newUserType) {
+        Slog.i(LOG_TAG, "Upgrading user " + userInfo.id
+                + " from " + userInfo.userType
+                + " to " + newUserType.getName());
+
+        if (!userInfo.isProfile()) {
+            throw new IllegalStateException(
+                    "Can only upgrade profile types. " + userInfo.userType
+                            + " is not a profile type.");
+        }
+
+        // Exceeded maximum profiles for parent user: log error, but allow upgrade
+        if (!canAddMoreProfilesToUser(newUserType.getName(), userInfo.profileGroupId, false)) {
+            Slog.w(LOG_TAG,
+                    "Exceeded maximum profiles of type " + newUserType.getName() + " for user "
+                            + userInfo.id + ". Maximum allowed= "
+                            + newUserType.getMaxAllowedPerParent());
+        }
+
+        final UserTypeDetails oldUserType = mUserTypes.get(userInfo.userType);
+        final int oldFlags;
+        if (oldUserType != null) {
+            oldFlags = oldUserType.getDefaultUserInfoFlags();
+        } else {
+            // if oldUserType is missing from config_user_types.xml -> can only assume FLAG_PROFILE
+            oldFlags = UserInfo.FLAG_PROFILE;
+        }
+
+        //convert userData to newUserType
+        userInfo.userType = newUserType.getName();
+        // remove old default flags and add newUserType's default flags
+        userInfo.flags = newUserType.getDefaultUserInfoFlags() | (userInfo.flags ^ oldFlags);
+
+        // merge existing base restrictions with the new type's default restrictions
+        synchronized (mRestrictionsLock) {
+            if (!BundleUtils.isEmpty(newUserType.getDefaultRestrictions())) {
+                final Bundle newRestrictions = BundleUtils.clone(
+                        mBaseUserRestrictions.getRestrictions(userInfo.id));
+                UserRestrictionsUtils.merge(newRestrictions,
+                        newUserType.getDefaultRestrictions());
+                updateUserRestrictionsInternalLR(newRestrictions, userInfo.id);
+                if (DBG) {
+                    Slog.i(LOG_TAG, "Updated user " + userInfo.id
+                            + " restrictions to " + newRestrictions);
+                }
+            }
+        }
+
+        // re-compute badge index
+        userInfo.profileBadge = getFreeProfileBadgeLU(userInfo.profileGroupId, userInfo.userType);
+    }
+
     @GuardedBy({"mPackagesLock", "mRestrictionsLock"})
     private void fallbackToSingleUserLP() {
         int flags = UserInfo.FLAG_SYSTEM | UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_ADMIN
@@ -5759,98 +5873,4 @@
         }
         return mDevicePolicyManagerInternal;
     }
-
-    @GuardedBy("mUsersLock")
-    @VisibleForTesting
-    void upgradeUserTypesLU(@NonNull List<UserTypeFactory.UserTypeUpgrade> upgradeOps,
-            @NonNull ArrayMap<String, UserTypeDetails> userTypes,
-            final int formerUserTypeVersion,
-            @NonNull Set<Integer> userIdsToWrite) {
-        for (UserTypeFactory.UserTypeUpgrade userTypeUpgrade : upgradeOps) {
-            if (DBG) {
-                Slog.i(LOG_TAG, "Upgrade: " + userTypeUpgrade.getFromType() + " to: "
-                        + userTypeUpgrade.getToType() + " maxVersion: "
-                        + userTypeUpgrade.getUpToVersion());
-            }
-
-            // upgrade user type if version up to getUpToVersion()
-            if (formerUserTypeVersion <= userTypeUpgrade.getUpToVersion()) {
-                for (int i = 0; i < mUsers.size(); i++) {
-                    UserData userData = mUsers.valueAt(i);
-                    if (userTypeUpgrade.getFromType().equals(userData.info.userType)) {
-                        final UserTypeDetails newUserType = userTypes.get(
-                                userTypeUpgrade.getToType());
-
-                        if (newUserType == null) {
-                            throw new IllegalStateException(
-                                    "Upgrade destination user type not defined: "
-                                            + userTypeUpgrade.getToType());
-                        }
-
-                        upgradeProfileToTypeLU(userData.info, newUserType);
-                        userIdsToWrite.add(userData.info.id);
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Changes the user type of a profile to a new user type.
-     * @param userInfo    The user to be updated.
-     * @param newUserType The new user type.
-     */
-    @GuardedBy("mUsersLock")
-    @VisibleForTesting
-    void upgradeProfileToTypeLU(@NonNull UserInfo userInfo, @NonNull UserTypeDetails newUserType) {
-        Slog.i(LOG_TAG, "Upgrading user " + userInfo.id
-                + " from " + userInfo.userType
-                + " to " + newUserType.getName());
-
-        if (!userInfo.isProfile()) {
-            throw new IllegalStateException(
-                    "Can only upgrade profile types. " + userInfo.userType
-                            + " is not a profile type.");
-        }
-
-        // Exceeded maximum profiles for parent user: log error, but allow upgrade
-        if (!canAddMoreProfilesToUser(newUserType.getName(), userInfo.profileGroupId, false)) {
-            Slog.w(LOG_TAG,
-                    "Exceeded maximum profiles of type " + newUserType.getName() + " for user "
-                            + userInfo.id + ". Maximum allowed= "
-                            + newUserType.getMaxAllowedPerParent());
-        }
-
-        final UserTypeDetails oldUserType = mUserTypes.get(userInfo.userType);
-        final int oldFlags;
-        if (oldUserType != null) {
-            oldFlags = oldUserType.getDefaultUserInfoFlags();
-        } else {
-            // if oldUserType is missing from config_user_types.xml -> can only assume FLAG_PROFILE
-            oldFlags = UserInfo.FLAG_PROFILE;
-        }
-
-        //convert userData to newUserType
-        userInfo.userType = newUserType.getName();
-        // remove old default flags and add newUserType's default flags
-        userInfo.flags = newUserType.getDefaultUserInfoFlags() | (userInfo.flags ^ oldFlags);
-
-        // merge existing base restrictions with the new type's default restrictions
-        synchronized (mRestrictionsLock) {
-            if (!BundleUtils.isEmpty(newUserType.getDefaultRestrictions())) {
-                final Bundle newRestrictions = BundleUtils.clone(
-                        mBaseUserRestrictions.getRestrictions(userInfo.id));
-                UserRestrictionsUtils.merge(newRestrictions,
-                        newUserType.getDefaultRestrictions());
-                updateUserRestrictionsInternalLR(newRestrictions, userInfo.id);
-                if (DBG) {
-                    Slog.i(LOG_TAG, "Updated user " + userInfo.id
-                            + " restrictions to " + newRestrictions);
-                }
-            }
-        }
-
-        // re-compute badge index
-        userInfo.profileBadge = getFreeProfileBadgeLU(userInfo.profileGroupId, userInfo.userType);
-    }
 }
diff --git a/services/core/java/com/android/server/pm/UserTypeDetails.java b/services/core/java/com/android/server/pm/UserTypeDetails.java
index 17ce386..6824f7d 100644
--- a/services/core/java/com/android/server/pm/UserTypeDetails.java
+++ b/services/core/java/com/android/server/pm/UserTypeDetails.java
@@ -149,6 +149,13 @@
      */
     private final @Nullable int[] mDarkThemeBadgeColors;
 
+    /**
+     * Denotes if the user shares media with its parent user.
+     *
+     * <p> Default value is false
+     */
+    private final boolean mSharesMediaWithParent;
+
     private UserTypeDetails(@NonNull String name, boolean enabled, int maxAllowed,
             @UserInfoFlag int baseType, @UserInfoFlag int defaultUserInfoPropertyFlags, int label,
             int maxAllowedPerParent,
@@ -158,7 +165,8 @@
             @Nullable Bundle defaultRestrictions,
             @Nullable Bundle defaultSystemSettings,
             @Nullable Bundle defaultSecureSettings,
-            @Nullable List<DefaultCrossProfileIntentFilter> defaultCrossProfileIntentFilters) {
+            @Nullable List<DefaultCrossProfileIntentFilter> defaultCrossProfileIntentFilters,
+            boolean sharesMediaWithParent) {
         this.mName = name;
         this.mEnabled = enabled;
         this.mMaxAllowed = maxAllowed;
@@ -177,6 +185,7 @@
         this.mBadgeLabels = badgeLabels;
         this.mBadgeColors = badgeColors;
         this.mDarkThemeBadgeColors = darkThemeBadgeColors;
+        this.mSharesMediaWithParent = sharesMediaWithParent;
     }
 
     /**
@@ -291,6 +300,13 @@
         return (mBaseType & UserInfo.FLAG_SYSTEM) != 0;
     }
 
+    /**
+     * Returns true if the user has shared media with parent user or false otherwise.
+     */
+    public boolean sharesMediaWithParent() {
+        return mSharesMediaWithParent;
+    }
+
     /** Returns a {@link Bundle} representing the default user restrictions. */
     @NonNull Bundle getDefaultRestrictions() {
         return BundleUtils.clone(mDefaultRestrictions);
@@ -318,7 +334,6 @@
                 : Collections.emptyList();
     }
 
-
     /** Dumps details of the UserTypeDetails. Do not parse this. */
     public void dump(PrintWriter pw, String prefix) {
         pw.print(prefix); pw.print("mName: "); pw.println(mName);
@@ -383,6 +398,7 @@
         private @DrawableRes int mIconBadge = Resources.ID_NULL;
         private @DrawableRes int mBadgePlain = Resources.ID_NULL;
         private @DrawableRes int mBadgeNoBackground = Resources.ID_NULL;
+        private boolean mSharesMediaWithParent = false;
 
         public Builder setName(String name) {
             mName = name;
@@ -473,6 +489,15 @@
             return this;
         }
 
+        /**
+         * Sets shared media property for the user.
+         * @param sharesMediaWithParent the value to be set, true or false
+         */
+        public Builder setSharesMediaWithParent(boolean sharesMediaWithParent) {
+            mSharesMediaWithParent = sharesMediaWithParent;
+            return this;
+        }
+
         @UserInfoFlag int getBaseType() {
             return mBaseType;
         }
@@ -502,7 +527,7 @@
                     mIconBadge, mBadgePlain, mBadgeNoBackground, mBadgeLabels, mBadgeColors,
                     mDarkThemeBadgeColors == null ? mBadgeColors : mDarkThemeBadgeColors,
                     mDefaultRestrictions, mDefaultSystemSettings, mDefaultSecureSettings,
-                    mDefaultCrossProfileIntentFilters);
+                    mDefaultCrossProfileIntentFilters, mSharesMediaWithParent);
         }
 
         private boolean hasBadge() {
diff --git a/services/core/java/com/android/server/pm/UserTypeFactory.java b/services/core/java/com/android/server/pm/UserTypeFactory.java
index 6aac0b2..e8421a5 100644
--- a/services/core/java/com/android/server/pm/UserTypeFactory.java
+++ b/services/core/java/com/android/server/pm/UserTypeFactory.java
@@ -29,6 +29,7 @@
 import static android.os.UserManager.USER_TYPE_FULL_RESTRICTED;
 import static android.os.UserManager.USER_TYPE_FULL_SECONDARY;
 import static android.os.UserManager.USER_TYPE_FULL_SYSTEM;
+import static android.os.UserManager.USER_TYPE_PROFILE_CLONE;
 import static android.os.UserManager.USER_TYPE_PROFILE_MANAGED;
 import static android.os.UserManager.USER_TYPE_PROFILE_TEST;
 import static android.os.UserManager.USER_TYPE_SYSTEM_HEADLESS;
@@ -100,6 +101,7 @@
         builders.put(USER_TYPE_FULL_DEMO, getDefaultTypeFullDemo());
         builders.put(USER_TYPE_FULL_RESTRICTED, getDefaultTypeFullRestricted());
         builders.put(USER_TYPE_SYSTEM_HEADLESS, getDefaultTypeSystemHeadless());
+        builders.put(USER_TYPE_PROFILE_CLONE, getDefaultTypeProfileClone());
         if (Build.IS_DEBUGGABLE) {
             builders.put(USER_TYPE_PROFILE_TEST, getDefaultTypeProfileTest());
         }
@@ -108,6 +110,21 @@
     }
 
     /**
+     * Returns the Builder for the default {@link UserManager#USER_TYPE_PROFILE_CLONE}
+     * configuration.
+     */
+    // TODO(b/182396009): Add default restrictions, if needed for clone user type.
+    private static UserTypeDetails.Builder getDefaultTypeProfileClone() {
+        return new UserTypeDetails.Builder()
+                .setName(USER_TYPE_PROFILE_CLONE)
+                .setBaseType(FLAG_PROFILE)
+                .setMaxAllowedPerParent(1)
+                .setLabel(0)
+                .setDefaultRestrictions(null)
+                .setSharesMediaWithParent(true);
+    }
+
+    /**
      * Returns the Builder for the default {@link UserManager#USER_TYPE_PROFILE_MANAGED}
      * configuration.
      */
diff --git a/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java b/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java
index c8dc1b1..f99a3c3 100644
--- a/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java
+++ b/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java
@@ -39,6 +39,7 @@
     private static final String TAG = ArtStatsLogUtils.class.getSimpleName();
     private static final String PROFILE_DEX_METADATA = "primary.prof";
     private static final String VDEX_DEX_METADATA = "primary.vdex";
+    private static final String BASE_APK= "base.apk";
 
 
     private static final int ART_COMPILATION_REASON_INSTALL_BULK_SECONDARY =
@@ -122,16 +123,34 @@
                 ART_COMPILATION_FILTER_FAKE_RUN_FROM_VDEX_FALLBACK);
     }
 
+    private static final Map<String, Integer> ISA_MAP = new HashMap();
+
+    static {
+        COMPILE_FILTER_MAP.put("arm", ArtStatsLog.
+                ART_DATUM_REPORTED__ISA__ART_ISA_ARM);
+        COMPILE_FILTER_MAP.put("arm64", ArtStatsLog.
+                ART_DATUM_REPORTED__ISA__ART_ISA_ARM64);
+        COMPILE_FILTER_MAP.put("x86", ArtStatsLog.
+                ART_DATUM_REPORTED__ISA__ART_ISA_X86);
+        COMPILE_FILTER_MAP.put("x86_64", ArtStatsLog.
+                ART_DATUM_REPORTED__ISA__ART_ISA_X86_64);
+        COMPILE_FILTER_MAP.put("mips", ArtStatsLog.
+                ART_DATUM_REPORTED__ISA__ART_ISA_MIPS);
+        COMPILE_FILTER_MAP.put("mips64", ArtStatsLog.
+                ART_DATUM_REPORTED__ISA__ART_ISA_MIPS64);
+    }
+
     public static void writeStatsLog(
             ArtStatsLogger logger,
             long sessionId,
-            String path,
             String compilerFilter,
             int uid,
             long compileTime,
             String dexMetadataPath,
             int compilationReason,
-            int result) {
+            int result,
+            int apkType,
+            String isa) {
         int dexMetadataType = getDexMetadataType(dexMetadataPath);
         logger.write(
                 sessionId,
@@ -140,7 +159,9 @@
                 compilerFilter,
                 ArtStatsLog.ART_DATUM_REPORTED__KIND__ART_DATUM_DEX2OAT_RESULT_CODE,
                 result,
-                dexMetadataType);
+                dexMetadataType,
+                apkType,
+                isa);
         logger.write(
                 sessionId,
                 uid,
@@ -148,7 +169,16 @@
                 compilerFilter,
                 ArtStatsLog.ART_DATUM_REPORTED__KIND__ART_DATUM_DEX2OAT_TOTAL_TIME,
                 compileTime,
-                dexMetadataType);
+                dexMetadataType,
+                apkType,
+                isa);
+    }
+
+    public static int getApkType(String path) {
+        if (path.equals(BASE_APK)) {
+            return ArtStatsLog.ART_DATUM_REPORTED__APK_TYPE__ART_APK_TYPE_BASE;
+        }
+        return ArtStatsLog.ART_DATUM_REPORTED__APK_TYPE__ART_APK_TYPE_SPLIT;
     }
 
     private static int getDexMetadataType(String dexMetadataPath) {
@@ -207,7 +237,9 @@
                 String compilerFilter,
                 int kind,
                 long value,
-                int dexMetadataType) {
+                int dexMetadataType,
+                int apkType,
+                String isa) {
             ArtStatsLog.write(
                     ArtStatsLog.ART_DATUM_REPORTED,
                     sessionId,
@@ -220,7 +252,10 @@
                     ArtStatsLog.ART_DATUM_REPORTED__THREAD_TYPE__ART_THREAD_MAIN,
                     kind,
                     value,
-                    dexMetadataType);
+                    dexMetadataType,
+                    apkType,
+                    ISA_MAP.getOrDefault(isa,
+                            ArtStatsLog.ART_DATUM_REPORTED__ISA__ART_ISA_UNKNOWN));
         }
     }
 }
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 629f120..21e44ab 100644
--- a/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java
+++ b/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java
@@ -407,7 +407,7 @@
             retProcs.put(proc.getName(),
                     new ProcessInfo(proc.getName(), new ArraySet<>(proc.getDeniedPermissions()),
                             proc.getGwpAsanMode(), proc.getMemtagMode(),
-                            proc.getNativeHeapZeroInit()));
+                            proc.getNativeHeapZeroInitialized()));
         }
         return retProcs;
     }
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 27bf8a13..9bc9d9f 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -206,6 +206,12 @@
         STORAGE_PERMISSIONS.add(Manifest.permission.ACCESS_MEDIA_LOCATION);
     }
 
+    private static final Set<String> NEARBY_DEVICES_PERMISSIONS = new ArraySet<>();
+    static {
+        NEARBY_DEVICES_PERMISSIONS.add(Manifest.permission.BLUETOOTH_CONNECT);
+        NEARBY_DEVICES_PERMISSIONS.add(Manifest.permission.BLUETOOTH_SCAN);
+    }
+
     private static final int MSG_READ_DEFAULT_PERMISSION_EXCEPTIONS = 1;
 
     private static final String ACTION_TRACK = "com.android.fitness.TRACK";
@@ -272,7 +278,7 @@
             try {
                 return mContext.getPackageManager().getPermissionInfo(permissionName, 0);
             } catch (NameNotFoundException e) {
-                Slog.e(TAG, "Permission not found: " + permissionName);
+                Slog.w(TAG, "Permission not found: " + permissionName);
                 return null;
             }
         }
@@ -731,7 +737,7 @@
                 grantPermissionsToSystemPackage(pm, packageName, userId,
                         CONTACTS_PERMISSIONS, CALENDAR_PERMISSIONS, MICROPHONE_PERMISSIONS,
                         PHONE_PERMISSIONS, SMS_PERMISSIONS, CAMERA_PERMISSIONS,
-                        SENSORS_PERMISSIONS, STORAGE_PERMISSIONS);
+                        SENSORS_PERMISSIONS, STORAGE_PERMISSIONS, NEARBY_DEVICES_PERMISSIONS);
                 grantSystemFixedPermissionsToSystemPackage(pm, packageName, userId,
                         ALWAYS_LOCATION_PERMISSIONS, ACTIVITY_RECOGNITION_PERMISSIONS);
             }
@@ -740,7 +746,7 @@
             // Also grant location and activity recognition permission to location extra packages.
             for (String packageName : locationExtraPackageNames) {
                 grantPermissionsToSystemPackage(pm, packageName, userId,
-                        ALWAYS_LOCATION_PERMISSIONS);
+                        ALWAYS_LOCATION_PERMISSIONS, NEARBY_DEVICES_PERMISSIONS);
                 grantSystemFixedPermissionsToSystemPackage(pm, packageName, userId,
                         ACTIVITY_RECOGNITION_PERMISSIONS);
             }
@@ -809,7 +815,7 @@
         // Companion devices
         grantSystemFixedPermissionsToSystemPackage(pm,
                 CompanionDeviceManager.COMPANION_DEVICE_DISCOVERY_PACKAGE_NAME, userId,
-                ALWAYS_LOCATION_PERMISSIONS);
+                ALWAYS_LOCATION_PERMISSIONS, NEARBY_DEVICES_PERMISSIONS);
 
         // Ringtone Picker
         grantSystemFixedPermissionsToSystemPackage(pm,
@@ -1722,6 +1728,14 @@
         @Override
         public void grantPermission(@NonNull String permission, @NonNull PackageInfo pkg,
                 @NonNull UserHandle user) {
+            if (PermissionManager.DEBUG_TRACE_GRANTS
+                    && PermissionManager.shouldTraceGrant(
+                    pkg.packageName, permission, user.getIdentifier())) {
+                Log.i(PermissionManager.LOG_TAG_TRACE_GRANTS,
+                        "PregrantPolicy is granting " + pkg.packageName + " "
+                                + permission + " for user " + user.getIdentifier(),
+                        new RuntimeException());
+            }
             PermissionState state = getPermissionState(permission, pkg, user);
             state.initGranted();
             state.newGranted = true;
diff --git a/services/core/java/com/android/server/pm/permission/Permission.java b/services/core/java/com/android/server/pm/permission/Permission.java
index b421cfc..cda4806 100644
--- a/services/core/java/com/android/server/pm/permission/Permission.java
+++ b/services/core/java/com/android/server/pm/permission/Permission.java
@@ -435,11 +435,12 @@
                 }
             }
         }
+        boolean wasNonRuntime = permission != null && permission.mType != TYPE_CONFIG
+                && !permission.isRuntime();
         if (permission == null) {
             permission = new Permission(permissionInfo.name, permissionInfo.packageName,
                     TYPE_MANIFEST);
         }
-        boolean wasNonRuntime = !permission.isRuntime();
         StringBuilder r = null;
         if (!permission.mReconciled) {
             if (permission.mPermissionInfo.packageName == null
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index 616058f..142b36e 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -35,6 +35,7 @@
 import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
 import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKED_COMPAT;
 import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_WHEN_REQUESTED;
+import static android.content.pm.PackageManager.FLAG_PERMISSION_SELECTED_LOCATION_ACCURACY;
 import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
@@ -84,11 +85,13 @@
 import android.content.pm.permission.SplitPermissionInfoParcelable;
 import android.metrics.LogMaker;
 import android.os.AsyncTask;
+import android.content.AttributionSource;
 import android.os.Binder;
 import android.os.Build;
 import android.os.Debug;
 import android.os.Handler;
 import android.os.HandlerThread;
+import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
 import android.os.Process;
@@ -158,6 +161,7 @@
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
+import java.util.WeakHashMap;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
@@ -253,6 +257,10 @@
     @NonNull
     private final PermissionRegistry mRegistry = new PermissionRegistry();
 
+    @NonNull
+    private final AttributionSourceRegistry mAttributionSourceRegistry =
+            new AttributionSourceRegistry();
+
     @GuardedBy("mLock")
     @Nullable
     private ArraySet<String> mPrivappPermissionsViolations;
@@ -1337,7 +1345,7 @@
             boolean overridePolicy, int callingUid, final int userId, PermissionCallback callback) {
         if (PermissionManager.DEBUG_TRACE_GRANTS
                 && PermissionManager.shouldTraceGrant(packageName, permName, userId)) {
-            Log.i(TAG, "System is granting " + packageName + " "
+            Log.i(PermissionManager.LOG_TAG_TRACE_GRANTS, "System is granting " + packageName + " "
                     + permName + " for user " + userId + " on behalf of uid " + callingUid
                     + " " + mPackageManagerInt.getNameForUid(callingUid),
                     new RuntimeException());
@@ -1657,7 +1665,8 @@
                 | FLAG_PERMISSION_USER_FIXED
                 | FLAG_PERMISSION_REVOKED_COMPAT
                 | FLAG_PERMISSION_REVIEW_REQUIRED
-                | FLAG_PERMISSION_ONE_TIME;
+                | FLAG_PERMISSION_ONE_TIME
+                | FLAG_PERMISSION_SELECTED_LOCATION_ACCURACY;
 
         final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
                 | FLAG_PERMISSION_POLICY_FIXED;
@@ -1796,9 +1805,12 @@
                 // PermissionPolicyService will handle the app op for runtime permissions later.
                 grantRuntimePermissionInternal(packageName, permName, false,
                         Process.SYSTEM_UID, userId, delayingPermCallback);
-            // If permission review is enabled the permissions for a legacy apps
-            // are represented as constantly granted runtime ones, so don't revoke.
-            } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
+            // In certain cases we should leave the state unchanged:
+            // -- If permission review is enabled the permissions for a legacy apps
+            // are represented as constantly granted runtime ones
+            // -- If the permission was split from a non-runtime permission
+            } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0
+                    && !isPermissionSplitFromNonRuntime(permName, targetSdk)) {
                 // Otherwise, reset the permission.
                 revokeRuntimePermissionInternal(packageName, permName, false, Process.SYSTEM_UID,
                         userId, null, delayingPermCallback);
@@ -1831,6 +1843,27 @@
     }
 
     /**
+     * Determine if the given permission should be treated as split from a
+     * non-runtime permission for an application targeting the given SDK level.
+     */
+    private boolean isPermissionSplitFromNonRuntime(String permName, int targetSdk) {
+        final List<PermissionManager.SplitPermissionInfo> splitPerms = getSplitPermissionInfos();
+        final int size = splitPerms.size();
+        for (int i = 0; i < size; i++) {
+            final PermissionManager.SplitPermissionInfo splitPerm = splitPerms.get(i);
+            if (targetSdk < splitPerm.getTargetSdk()
+                    && splitPerm.getNewPermissions().contains(permName)) {
+                synchronized (mLock) {
+                    final Permission perm =
+                            mRegistry.getPermission(splitPerm.getSplitPermission());
+                    return perm != null && !perm.isRuntime();
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
      * This change makes it so that apps are told to show rationale for asking for background
      * location access every time they request.
      */
@@ -2937,7 +2970,8 @@
                 >= Build.VERSION_CODES.M;
 
         for (String permission : ps.getGrantedPermissions()) {
-            if (!pkg.getImplicitPermissions().contains(permission)) {
+            if (pkg.getRequestedPermissions().contains(permission)
+                    && !pkg.getImplicitPermissions().contains(permission)) {
                 Permission bp = mRegistry.getPermission(permission);
                 if (bp != null && bp.isRuntime()) {
                     int flags = ps.getPermissionFlags(permission);
@@ -3204,6 +3238,16 @@
     }
 
     @Override
+    public @NonNull AttributionSource registerAttributionSource(@NonNull AttributionSource source) {
+        return mAttributionSourceRegistry.registerAttributionSource(source);
+    }
+
+    @Override
+    public boolean isRegisteredAttributionSource(@NonNull AttributionSource source) {
+        return mAttributionSourceRegistry.isRegisteredAttributionSource(source);
+    }
+
+    @Override
     public List<String> getAutoRevokeExemptionRequestedPackages(int userId) {
         return getPackagesWithAutoRevokePolicy(AUTO_REVOKE_DISCOURAGED, userId);
     }
@@ -5238,4 +5282,73 @@
                     || mDelegatedPermissionNames.contains(permissionName);
         }
     }
+
+    private static final class AttributionSourceRegistry {
+        private final Object mLock = new Object();
+
+        private final WeakHashMap<IBinder, AttributionSource> mAttributions = new WeakHashMap<>();
+
+        public @NonNull AttributionSource registerAttributionSource(
+                @NonNull AttributionSource source) {
+            //   Here we keep track of attribution sources that were created by an app
+            // from an attribution chain that called into the app and the apps's
+            // own attribution source. An app can register an attribution chain up
+            // to itself inclusive if and only if it is adding a node for itself which
+            // optionally points to an attribution chain that was created by each
+            // preceding app recursively up to the beginning of the chain.
+            //   The only special case is when the first app in the attribution chain
+            // creates a source that points to another app (not a chain of apps). We
+            // allow this even if the source the app points to is not registered since
+            // in app ops we allow every app to blame every other app (untrusted if not
+            // holding a special permission).
+            //  This technique ensures that a bad actor in the middle of the attribution
+            // chain can neither prepend nor append an invalid attribution sequence, i.e.
+            // a sequence that is not constructed by trusted sources up to the that bad
+            // actor's app.
+            //   Note that passing your attribution source to another app means you allow
+            // it to blame private data access on your app. This can be mediated by the OS
+            // in, which case security is already enforced; by other app's code running in
+            // your process calling into the other app, in which case it can already access
+            // the private data in your process; or by you explicitly calling to another
+            // app passing the source, in which case you must trust the other side;
+
+            final int callingUid = Binder.getCallingUid();
+            if (source.getUid() != callingUid) {
+                throw new SecurityException("Cannot register attribution source for uid:"
+                        + source.getUid() + " from uid:" + callingUid);
+            }
+
+            final PackageManagerInternal packageManagerInternal = LocalServices.getService(
+                    PackageManagerInternal.class);
+            if (packageManagerInternal.getPackageUid(source.getPackageName(), 0,
+                    UserHandle.getUserId(callingUid)) != source.getUid()) {
+                throw new SecurityException("Cannot register attribution source for package:"
+                        + source.getPackageName() + " from uid:" + callingUid);
+            }
+
+            final AttributionSource next = source.getNext();
+            if (next != null && next.getNext() != null
+                    && !isRegisteredAttributionSource(next)) {
+                throw new SecurityException("Cannot register forged attribution source:"
+                        + source);
+            }
+
+            synchronized (mLock) {
+                final IBinder token = new Binder();
+                final AttributionSource result = source.withToken(token);
+                mAttributions.put(token, result);
+                return result;
+            }
+        }
+
+        public boolean isRegisteredAttributionSource(@NonNull AttributionSource source) {
+            synchronized (mLock) {
+                final AttributionSource cachedSource = mAttributions.get(source.getToken());
+                if (cachedSource != null) {
+                    return cachedSource.equals(source);
+                }
+                return false;
+            }
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/pm/verify/domain/DomainVerificationEnforcer.java b/services/core/java/com/android/server/pm/verify/domain/DomainVerificationEnforcer.java
index f4bcd3e..0b48b5c 100644
--- a/services/core/java/com/android/server/pm/verify/domain/DomainVerificationEnforcer.java
+++ b/services/core/java/com/android/server/pm/verify/domain/DomainVerificationEnforcer.java
@@ -70,11 +70,8 @@
                 break;
             default:
                 if (!proxy.isCallerVerifier(callingUid)) {
-                    mContext.enforcePermission(
-                            android.Manifest.permission.UPDATE_DOMAIN_VERIFICATION_USER_SELECTION,
-                            Binder.getCallingPid(), callingUid,
-                            "Caller " + callingUid
-                                    + " is not allowed to query domain verification state");
+                    throw new SecurityException(
+                            "Caller is not allowed to query domain verification state");
                 }
 
                 mContext.enforcePermission(android.Manifest.permission.QUERY_ALL_PACKAGES,
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 a0e252a..63515b9 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
@@ -24,7 +24,6 @@
 import android.annotation.Nullable;
 import android.annotation.UserIdInt;
 import android.compat.annotation.ChangeId;
-import android.compat.annotation.Disabled;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.IntentFilterVerificationInfo;
@@ -92,7 +91,6 @@
      * commands.
      */
     @ChangeId
-    @Disabled
     private static final long SETTINGS_API_V2 = 178111421;
 
     /**
@@ -148,6 +146,8 @@
     @NonNull
     private DomainVerificationProxy mProxy = new DomainVerificationProxyUnavailable();
 
+    private boolean mCanSendBroadcasts;
+
     public DomainVerificationService(@NonNull Context context, @NonNull SystemConfig systemConfig,
             @NonNull PlatformCompat platformCompat) {
         super(context);
@@ -181,11 +181,18 @@
     @Override
     public void onBootPhase(int phase) {
         super.onBootPhase(phase);
-        if (phase != SystemService.PHASE_BOOT_COMPLETED || !hasRealVerifier()) {
+        if (!hasRealVerifier()) {
             return;
         }
 
-        verifyPackages(null, false);
+        switch (phase) {
+            case PHASE_ACTIVITY_MANAGER_READY:
+                mCanSendBroadcasts = true;
+                break;
+            case PHASE_BOOT_COMPLETED:
+                verifyPackages(null, false);
+                break;
+        }
     }
 
     @Override
@@ -284,7 +291,8 @@
             int state) throws NameNotFoundException {
         if (state < DomainVerificationState.STATE_FIRST_VERIFIER_DEFINED) {
             if (state != DomainVerificationState.STATE_SUCCESS) {
-                return DomainVerificationManager.ERROR_INVALID_STATE_CODE;
+                throw new IllegalArgumentException(
+                        "Caller is not allowed to set state code " + state);
             }
         }
 
@@ -857,7 +865,7 @@
         }
 
         if (sendBroadcast) {
-            sendBroadcastForPackage(pkgName);
+            sendBroadcast(pkgName);
         }
     }
 
@@ -936,7 +944,7 @@
         }
 
         if (sendBroadcast && hasAutoVerifyDomains) {
-            sendBroadcastForPackage(pkgName);
+            sendBroadcast(pkgName);
         }
     }
 
@@ -1097,8 +1105,19 @@
         return mCollector;
     }
 
-    private void sendBroadcastForPackage(@NonNull String packageName) {
-        mProxy.sendBroadcastForPackages(Collections.singleton(packageName));
+    private void sendBroadcast(@NonNull String packageName) {
+        sendBroadcast(Collections.singleton(packageName));
+    }
+
+    private void sendBroadcast(@NonNull Set<String> packageNames) {
+        if (!mCanSendBroadcasts) {
+            // If the system cannot send broadcasts, it's probably still in boot, so dropping this
+            // request should be fine. The verification agent should re-scan packages once boot
+            // completes.
+            return;
+        }
+
+        mProxy.sendBroadcastForPackages(packageNames);
     }
 
     private boolean hasRealVerifier() {
@@ -1119,7 +1138,7 @@
             @NonNull Set<String> domains, boolean forAutoVerify, int callingUid,
             @Nullable Integer userIdForFilter) throws NameNotFoundException {
         if (domainSetId == null) {
-            return GetAttachedResult.error(DomainVerificationManager.ERROR_DOMAIN_SET_ID_NULL);
+            throw new IllegalArgumentException("domainSetId cannot be null");
         }
 
         DomainVerificationPkgState pkgState = mAttachedPkgStates.get(domainSetId);
@@ -1140,9 +1159,9 @@
         }
 
         if (CollectionUtils.isEmpty(domains)) {
-            return GetAttachedResult.error(
-                    DomainVerificationManager.ERROR_DOMAIN_SET_NULL_OR_EMPTY);
+            throw new IllegalArgumentException("Provided domain set cannot be empty");
         }
+
         AndroidPackage pkg = pkgSetting.getPkg();
         ArraySet<String> declaredDomains = forAutoVerify
                 ? mCollector.collectValidAutoVerifyDomains(pkg)
@@ -1182,7 +1201,7 @@
         }
 
         if (!packagesToBroadcast.isEmpty()) {
-            mProxy.sendBroadcastForPackages(packagesToBroadcast);
+            sendBroadcast(packagesToBroadcast);
         }
     }
 
diff --git a/services/core/java/com/android/server/pm/verify/domain/DomainVerificationUtils.java b/services/core/java/com/android/server/pm/verify/domain/DomainVerificationUtils.java
index cb3b5c9..44ff3eb 100644
--- a/services/core/java/com/android/server/pm/verify/domain/DomainVerificationUtils.java
+++ b/services/core/java/com/android/server/pm/verify/domain/DomainVerificationUtils.java
@@ -22,7 +22,6 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
-import android.os.Binder;
 
 import com.android.internal.util.CollectionUtils;
 import com.android.server.compat.PlatformCompat;
@@ -77,9 +76,7 @@
 
     static boolean isChangeEnabled(PlatformCompat platformCompat, AndroidPackage pkg,
             long changeId) {
-        //noinspection ConstantConditions
-        return Binder.withCleanCallingIdentity(
-                () -> platformCompat.isChangeEnabled(changeId, buildMockAppInfo(pkg)));
+        return  platformCompat.isChangeEnabledInternalNoLogging(changeId, buildMockAppInfo(pkg));
     }
 
     /**
diff --git a/services/core/java/com/android/server/policy/AppOpsPolicy.java b/services/core/java/com/android/server/policy/AppOpsPolicy.java
index c965390..5db63c6 100644
--- a/services/core/java/com/android/server/policy/AppOpsPolicy.java
+++ b/services/core/java/com/android/server/policy/AppOpsPolicy.java
@@ -20,13 +20,18 @@
 import android.annotation.Nullable;
 import android.app.AppOpsManager;
 import android.app.AppOpsManagerInternal;
+import android.content.AttributionSource;
 import android.location.LocationManagerInternal;
+import android.os.IBinder;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.function.HeptFunction;
+import com.android.internal.util.function.HexFunction;
+import com.android.internal.util.function.OctFunction;
 import com.android.internal.util.function.QuadFunction;
+import com.android.internal.util.function.TriFunction;
 import com.android.server.LocalServices;
 
 import java.util.Set;
@@ -52,7 +57,7 @@
     @GuardedBy("mLock - writes only - see above")
     @NonNull
     private final ConcurrentHashMap<Integer, ArrayMap<String, ArraySet<String>>> mLocationTags =
-            new ConcurrentHashMap();
+            new ConcurrentHashMap<>();
 
     public AppOpsPolicy() {
         final LocationManagerInternal locationManagerInternal = LocalServices.getService(
@@ -112,22 +117,59 @@
 
     @Override
     public int noteOperation(int code, int uid, @Nullable String packageName,
-            @Nullable String featureId, boolean shouldCollectAsyncNotedOp, @Nullable String message,
-            boolean shouldCollectMessage, @NonNull HeptFunction<Integer, Integer, String, String,
-                    Boolean, String, Boolean, Integer> superImpl) {
-        if (isHandledOp(code)) {
+            @Nullable String attributionTag, boolean shouldCollectAsyncNotedOp, @Nullable
+            String message, boolean shouldCollectMessage, @NonNull HeptFunction<Integer, Integer,
+                    String, String, Boolean, String, Boolean, Integer> superImpl) {
+        return superImpl.apply(resolveOpCode(code, uid, packageName, attributionTag), uid,
+                packageName, attributionTag, shouldCollectAsyncNotedOp,
+                message, shouldCollectMessage);
+    }
+
+    @Override
+    public int noteProxyOperation(int code, @NonNull AttributionSource attributionSource,
+            boolean shouldCollectAsyncNotedOp, @Nullable String message,
+            boolean shouldCollectMessage, boolean skipProxyOperation, @NonNull HexFunction<Integer,
+                    AttributionSource, Boolean, String, Boolean, Boolean, Integer> superImpl) {
+        return superImpl.apply(resolveOpCode(code, attributionSource.getUid(),
+                attributionSource.getPackageName(), attributionSource.getAttributionTag()),
+                attributionSource, shouldCollectAsyncNotedOp, message, shouldCollectMessage,
+                skipProxyOperation);
+    }
+
+    @Override
+    public int startProxyOperation(IBinder token, int code,
+            @NonNull AttributionSource attributionSource, boolean startIfModeDefault,
+            boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage,
+            boolean skipProxyOperation, @NonNull OctFunction<IBinder, Integer, AttributionSource,
+                    Boolean, Boolean, String, Boolean, Boolean, Integer> superImpl) {
+        return superImpl.apply(token, resolveOpCode(code, attributionSource.getUid(),
+                attributionSource.getPackageName(), attributionSource.getAttributionTag()),
+                attributionSource, startIfModeDefault, shouldCollectAsyncNotedOp, message,
+                shouldCollectMessage, skipProxyOperation);
+    }
+
+    @Override
+    public void finishProxyOperation(IBinder clientId, int code,
+            @NonNull AttributionSource attributionSource,
+            @NonNull TriFunction<IBinder, Integer, AttributionSource, Void> superImpl) {
+        superImpl.apply(clientId, resolveOpCode(code, attributionSource.getUid(),
+                attributionSource.getPackageName(), attributionSource.getAttributionTag()),
+                attributionSource);
+    }
+
+    private int resolveOpCode(int code, int uid, @NonNull String packageName,
+            @Nullable String attributionTag) {
+        if (isHandledOp(code) && attributionTag != null) {
             // Only a single lookup from the underlying concurrent data structure
             final ArrayMap<String, ArraySet<String>> uidTags = mLocationTags.get(uid);
             if (uidTags != null) {
                 final ArraySet<String> packageTags = uidTags.get(packageName);
-                if (packageTags != null && packageTags.contains(featureId)) {
-                    return superImpl.apply(resolveLocationOp(code), uid, packageName, featureId,
-                            shouldCollectAsyncNotedOp, message, shouldCollectMessage);
+                if (packageTags != null && packageTags.contains(attributionTag)) {
+                    return resolveHandledOp(code);
                 }
             }
         }
-        return superImpl.apply(code, uid, packageName, featureId, shouldCollectAsyncNotedOp,
-                message, shouldCollectMessage);
+        return code;
     }
 
     private static boolean isHandledOp(int code) {
@@ -139,7 +181,7 @@
         return false;
     }
 
-    private static int resolveLocationOp(int code) {
+    private static int resolveHandledOp(int code) {
         switch (code) {
             case AppOpsManager.OP_FINE_LOCATION:
                 return AppOpsManager.OP_FINE_LOCATION_SOURCE;
diff --git a/services/core/java/com/android/server/policy/KeyCombinationManager.java b/services/core/java/com/android/server/policy/KeyCombinationManager.java
index 7f55723..268de3e 100644
--- a/services/core/java/com/android/server/policy/KeyCombinationManager.java
+++ b/services/core/java/com/android/server/policy/KeyCombinationManager.java
@@ -18,11 +18,13 @@
 import static android.view.KeyEvent.KEYCODE_POWER;
 
 import android.os.SystemClock;
+import android.util.Log;
 import android.util.SparseLongArray;
 import android.view.KeyEvent;
 
 import com.android.internal.util.ToBooleanFunction;
 
+import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.function.Consumer;
 
@@ -89,8 +91,8 @@
 
         @Override
         public String toString() {
-            return "KeyCode1 = " + KeyEvent.keyCodeToString(mKeyCode1)
-                    + ", KeyCode2 = " +  KeyEvent.keyCodeToString(mKeyCode2);
+            return KeyEvent.keyCodeToString(mKeyCode1) + " + "
+                    + KeyEvent.keyCodeToString(mKeyCode2);
         }
     }
 
@@ -151,6 +153,7 @@
                     if (!rule.shouldInterceptKeys(mDownTimes)) {
                         return false;
                     }
+                    Log.v(TAG, "Performing combination rule : " + rule);
                     rule.execute();
                     mTriggeredRule = rule;
                     return true;
@@ -230,4 +233,11 @@
         }
         return false;
     }
+
+    void dump(String prefix, PrintWriter pw) {
+        pw.println(prefix + "KeyCombination rules:");
+        forAllRules(mRules, (rule)-> {
+            pw.println(prefix + "  " + rule);
+        });
+    }
 }
diff --git a/services/core/java/com/android/server/policy/PermissionPolicyService.java b/services/core/java/com/android/server/policy/PermissionPolicyService.java
index 9077433..89d5415 100644
--- a/services/core/java/com/android/server/policy/PermissionPolicyService.java
+++ b/services/core/java/com/android/server/policy/PermissionPolicyService.java
@@ -578,7 +578,7 @@
         private final @NonNull AppOpsManager mAppOpsManager;
         private final @NonNull AppOpsManagerInternal mAppOpsManagerInternal;
 
-        private final @NonNull ArrayMap<String, PermissionInfo> mRuntimePermissionInfos;
+        private final @NonNull ArrayMap<String, PermissionInfo> mRuntimeAndTheirBgPermissionInfos;
 
         /**
          * All ops that need to be flipped to allow.
@@ -618,7 +618,7 @@
             mAppOpsManager = context.getSystemService(AppOpsManager.class);
             mAppOpsManagerInternal = LocalServices.getService(AppOpsManagerInternal.class);
 
-            mRuntimePermissionInfos = new ArrayMap<>();
+            mRuntimeAndTheirBgPermissionInfos = new ArrayMap<>();
             PermissionManagerServiceInternal permissionManagerInternal = LocalServices.getService(
                     PermissionManagerServiceInternal.class);
             List<PermissionInfo> permissionInfos =
@@ -627,7 +627,30 @@
             int permissionInfosSize = permissionInfos.size();
             for (int i = 0; i < permissionInfosSize; i++) {
                 PermissionInfo permissionInfo = permissionInfos.get(i);
-                mRuntimePermissionInfos.put(permissionInfo.name, permissionInfo);
+                mRuntimeAndTheirBgPermissionInfos.put(permissionInfo.name, permissionInfo);
+                // Make sure we scoop up all background permissions as they may not be runtime
+                if (permissionInfo.backgroundPermission != null) {
+                    String backgroundNonRuntimePermission = permissionInfo.backgroundPermission;
+                    for (int j = 0; j < permissionInfosSize; j++) {
+                        PermissionInfo bgPermissionCandidate = permissionInfos.get(j);
+                        if (permissionInfo.backgroundPermission.equals(
+                                bgPermissionCandidate.name)) {
+                            backgroundNonRuntimePermission = null;
+                            break;
+                        }
+                    }
+                    if (backgroundNonRuntimePermission != null) {
+                        try {
+                            PermissionInfo backgroundPermissionInfo = mPackageManager
+                                    .getPermissionInfo(backgroundNonRuntimePermission, 0);
+                            mRuntimeAndTheirBgPermissionInfos.put(backgroundPermissionInfo.name,
+                                    backgroundPermissionInfo);
+                        } catch (NameNotFoundException e) {
+                            Slog.w(LOG_TAG, "Unknown background permission: "
+                                    + backgroundNonRuntimePermission);
+                        }
+                    }
+                }
             }
         }
 
@@ -691,7 +714,7 @@
          */
         private void addAppOps(@NonNull PackageInfo packageInfo, @NonNull AndroidPackage pkg,
                 @NonNull String permissionName) {
-            PermissionInfo permissionInfo = mRuntimePermissionInfos.get(permissionName);
+            PermissionInfo permissionInfo = mRuntimeAndTheirBgPermissionInfos.get(permissionName);
             if (permissionInfo == null) {
                 return;
             }
@@ -726,7 +749,7 @@
             boolean shouldGrantAppOp = shouldGrantAppOp(packageInfo, pkg, permissionInfo);
             if (shouldGrantAppOp) {
                 if (permissionInfo.backgroundPermission != null) {
-                    PermissionInfo backgroundPermissionInfo = mRuntimePermissionInfos.get(
+                    PermissionInfo backgroundPermissionInfo = mRuntimeAndTheirBgPermissionInfos.get(
                             permissionInfo.backgroundPermission);
                     boolean shouldGrantBackgroundAppOp = backgroundPermissionInfo != null
                             && shouldGrantAppOp(packageInfo, pkg, backgroundPermissionInfo);
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index d0aa28b..f931df8 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -434,7 +434,6 @@
     // to hold wakelocks during dispatch and eliminating the critical path.
     volatile boolean mPowerKeyHandled;
     volatile boolean mBackKeyHandled;
-    volatile boolean mBeganFromNonInteractive;
     volatile boolean mEndCallKeyHandled;
     volatile boolean mCameraGestureTriggeredDuringGoingToSleep;
 
@@ -876,16 +875,6 @@
         if (!mPowerKeyHandled) {
             if (!interactive) {
                 wakeUpFromPowerKey(event.getDownTime());
-                if (mSupportLongPressPowerWhenNonInteractive && hasLongPressOnPowerBehavior()) {
-                    mBeganFromNonInteractive = true;
-                } else {
-                    final int maxCount = getMaxMultiPressPowerCount();
-                    if (maxCount <= 1) {
-                        mPowerKeyHandled = true;
-                    } else {
-                        mBeganFromNonInteractive = true;
-                    }
-                }
             }
         } else {
             // handled by another power key policy.
@@ -895,7 +884,7 @@
         }
     }
 
-    private void interceptPowerKeyUp(KeyEvent event, boolean interactive, boolean canceled) {
+    private void interceptPowerKeyUp(KeyEvent event, boolean canceled) {
         final boolean handled = canceled || mPowerKeyHandled;
 
         if (!handled) {
@@ -906,33 +895,36 @@
         } else {
             // handled by single key or another power key policy.
             mSingleKeyGestureDetector.reset();
-            finishPowerKeyPress();
         }
+
+        finishPowerKeyPress();
     }
 
     private void finishPowerKeyPress() {
-        mBeganFromNonInteractive = false;
         mPowerKeyHandled = false;
         if (mPowerKeyWakeLock.isHeld()) {
             mPowerKeyWakeLock.release();
         }
     }
 
-    private void powerPress(long eventTime, boolean interactive, int count) {
+    private void powerPress(long eventTime, int count, boolean beganFromNonInteractive) {
         if (mDefaultDisplayPolicy.isScreenOnEarly() && !mDefaultDisplayPolicy.isScreenOnFully()) {
             Slog.i(TAG, "Suppressed redundant power key press while "
                     + "already in the process of turning the screen on.");
             return;
         }
+
+        final boolean interactive = Display.isOnState(mDefaultDisplay.getState());
+
         Slog.d(TAG, "powerPress: eventTime=" + eventTime + " interactive=" + interactive
-                + " count=" + count + " beganFromNonInteractive=" + mBeganFromNonInteractive +
-                " mShortPressOnPowerBehavior=" + mShortPressOnPowerBehavior);
+                + " count=" + count + " beganFromNonInteractive=" + beganFromNonInteractive
+                + " mShortPressOnPowerBehavior=" + mShortPressOnPowerBehavior);
 
         if (count == 2) {
             powerMultiPressAction(eventTime, interactive, mDoublePressOnPowerBehavior);
         } else if (count == 3) {
             powerMultiPressAction(eventTime, interactive, mTriplePressOnPowerBehavior);
-        } else if (interactive && !mBeganFromNonInteractive) {
+        } else if (interactive && !beganFromNonInteractive) {
             switch (mShortPressOnPowerBehavior) {
                 case SHORT_PRESS_POWER_NOTHING:
                     break;
@@ -1906,12 +1898,19 @@
 
         @Override
         void onPress(long downTime) {
-            powerPress(downTime, true, 1 /*count*/);
+            powerPress(downTime, 1 /*count*/,
+                    mSingleKeyGestureDetector.beganFromNonInteractive());
             finishPowerKeyPress();
         }
 
         @Override
         void onLongPress(long eventTime) {
+            if (mSingleKeyGestureDetector.beganFromNonInteractive()
+                    && !mSupportLongPressPowerWhenNonInteractive) {
+                Slog.v(TAG, "Not support long press power when device is not interactive.");
+                return;
+            }
+
             powerLongPress(eventTime);
         }
 
@@ -1923,7 +1922,7 @@
 
         @Override
         void onMultiPress(long downTime, int count) {
-            powerPress(downTime, true, count);
+            powerPress(downTime, count, mSingleKeyGestureDetector.beganFromNonInteractive());
             finishPowerKeyPress();
         }
     }
@@ -2341,8 +2340,6 @@
             params.packageName = packageName;
             params.windowAnimations = win.getWindowStyle().getResourceId(
                     com.android.internal.R.styleable.Window_windowAnimationStyle, 0);
-            params.privateFlags |=
-                    WindowManager.LayoutParams.PRIVATE_FLAG_FAKE_HARDWARE_ACCELERATED;
             params.privateFlags |= WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS;
             // Setting as trusted overlay to let touches pass through. This is safe because this
             // window is controlled by the system.
@@ -2624,23 +2621,19 @@
                                 Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL,
                                 UserHandle.USER_CURRENT_OR_SELF);
                     }
-                    float minFloat = mPowerManager.getBrightnessConstraint(
+                    float min = mPowerManager.getBrightnessConstraint(
                             PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MINIMUM);
-                    float maxFloat = mPowerManager.getBrightnessConstraint(
+                    float max = mPowerManager.getBrightnessConstraint(
                             PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MAXIMUM);
-                    float stepFloat = (maxFloat - minFloat) / BRIGHTNESS_STEPS * direction;
-                    float brightnessFloat = Settings.System.getFloatForUser(
-                            mContext.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS_FLOAT,
-                            mContext.getDisplay().getBrightnessDefault(),
-                            UserHandle.USER_CURRENT_OR_SELF);
-                    brightnessFloat += stepFloat;
+                    float step = (max - min) / BRIGHTNESS_STEPS * direction;
+                    int screenDisplayId = displayId < 0 ? DEFAULT_DISPLAY : displayId;
+                    float brightness = mDisplayManager.getBrightness(screenDisplayId);
+                    brightness += step;
                     // Make sure we don't go beyond the limits.
-                    brightnessFloat = Math.min(maxFloat, brightnessFloat);
-                    brightnessFloat = Math.max(minFloat, brightnessFloat);
+                    brightness = Math.min(max, brightness);
+                    brightness = Math.max(min, brightness);
 
-                    Settings.System.putFloatForUser(mContext.getContentResolver(),
-                            Settings.System.SCREEN_BRIGHTNESS_FLOAT, brightnessFloat,
-                            UserHandle.USER_CURRENT_OR_SELF);
+                    mDisplayManager.setBrightness(screenDisplayId, brightness);
                     startActivityAsUser(new Intent(Intent.ACTION_SHOW_BRIGHTNESS_DIALOG),
                             UserHandle.CURRENT_OR_SELF);
                 }
@@ -3568,7 +3561,7 @@
                 if (down) {
                     interceptPowerKeyDown(event, interactiveAndOn);
                 } else {
-                    interceptPowerKeyUp(event, interactiveAndOn, canceled);
+                    interceptPowerKeyUp(event, canceled);
                 }
                 break;
             }
@@ -3758,7 +3751,7 @@
             }
         }
 
-        mSingleKeyGestureDetector.interceptKey(event);
+        mSingleKeyGestureDetector.interceptKey(event, interactive);
     }
 
     // The camera gesture will be detected by GestureLauncherService.
@@ -5236,6 +5229,8 @@
                 pw.print(" mLockScreenTimerActive="); pw.println(mLockScreenTimerActive);
 
         mGlobalKeyManager.dump(prefix, pw);
+        mKeyCombinationManager.dump(prefix, pw);
+        mSingleKeyGestureDetector.dump(prefix, pw);
 
         if (mWakeGestureListener != null) {
             mWakeGestureListener.dump(pw, prefix);
diff --git a/services/core/java/com/android/server/policy/SingleKeyGestureDetector.java b/services/core/java/com/android/server/policy/SingleKeyGestureDetector.java
index cae2093..3f4d920 100644
--- a/services/core/java/com/android/server/policy/SingleKeyGestureDetector.java
+++ b/services/core/java/com/android/server/policy/SingleKeyGestureDetector.java
@@ -25,6 +25,7 @@
 import android.view.KeyEvent;
 import android.view.ViewConfiguration;
 
+import java.io.PrintWriter;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
@@ -37,7 +38,7 @@
 
 public final class SingleKeyGestureDetector {
     private static final String TAG = "SingleKeyGesture";
-    private static final boolean DEBUG = false;
+    private static final boolean DEBUG = PhoneWindowManager.DEBUG_INPUT;
 
     private static final int MSG_KEY_LONG_PRESS = 0;
     private static final int MSG_KEY_VERY_LONG_PRESS = 1;
@@ -47,6 +48,7 @@
     private final long mVeryLongPressTimeout;
 
     private volatile int mKeyPressCounter;
+    private boolean mBeganFromNonInteractive = false;
 
     private final ArrayList<SingleKeyRule> mRules = new ArrayList();
     private SingleKeyRule mActiveRule = null;
@@ -57,7 +59,6 @@
     private final Handler mHandler;
     private static final long MULTI_PRESS_TIMEOUT = ViewConfiguration.getMultiPressTimeout();
 
-
     /** Supported gesture flags */
     public static final int KEY_LONGPRESS = 1 << 1;
     public static final int KEY_VERYLONGPRESS = 1 << 2;
@@ -143,10 +144,10 @@
 
         @Override
         public String toString() {
-            return "KeyCode = " + KeyEvent.keyCodeToString(mKeyCode)
-                    + ", long press : " + supportLongPress()
-                    + ", very Long press : " + supportVeryLongPress()
-                    + ", max multi press count : " + getMaxMultiPressCount();
+            return "KeyCode=" + KeyEvent.keyCodeToString(mKeyCode)
+                    + ", LongPress=" + supportLongPress()
+                    + ", VeryLongPress=" + supportVeryLongPress()
+                    + ", MaxMultiPressCount=" + getMaxMultiPressCount();
         }
     }
 
@@ -161,8 +162,12 @@
         mRules.add(rule);
     }
 
-    void interceptKey(KeyEvent event) {
+    void interceptKey(KeyEvent event, boolean interactive) {
         if (event.getAction() == KeyEvent.ACTION_DOWN) {
+            // Store the non interactive state when first down.
+            if (mDownKeyCode == KeyEvent.KEYCODE_UNKNOWN || mDownKeyCode != event.getKeyCode()) {
+                mBeganFromNonInteractive = !interactive;
+            }
             interceptKeyDown(event);
         } else {
             interceptKeyUp(event);
@@ -268,6 +273,7 @@
                     Log.i(TAG, "press key " + KeyEvent.keyCodeToString(event.getKeyCode()));
                 }
                 mActiveRule.onPress(downTime);
+                reset();
                 return true;
             }
 
@@ -316,6 +322,17 @@
         return false;
     }
 
+    boolean beganFromNonInteractive() {
+        return mBeganFromNonInteractive;
+    }
+
+    void dump(String prefix, PrintWriter pw) {
+        pw.println(prefix + "SingleKey rules:");
+        for (SingleKeyRule rule : mRules) {
+            pw.println(prefix + "  " + rule);
+        }
+    }
+
     private class KeyHandler extends Handler {
         KeyHandler() {
             super(Looper.getMainLooper());
@@ -354,7 +371,7 @@
                     } else {
                         mActiveRule.onMultiPress(eventTime, mKeyPressCounter);
                     }
-                    mKeyPressCounter = 0;
+                    reset();
                     break;
             }
         }
diff --git a/services/core/java/com/android/server/power/DisplayGroupPowerStateMapper.java b/services/core/java/com/android/server/power/DisplayGroupPowerStateMapper.java
index 2fcd178..ea93324 100644
--- a/services/core/java/com/android/server/power/DisplayGroupPowerStateMapper.java
+++ b/services/core/java/com/android/server/power/DisplayGroupPowerStateMapper.java
@@ -125,6 +125,10 @@
         return mDisplayGroupIds;
     }
 
+    int getDisplayGroupCountLocked() {
+        return mDisplayGroupIds.length;
+    }
+
     int getWakefulnessLocked(int groupId) {
         return mDisplayGroupInfos.get(groupId).wakefulness;
     }
@@ -248,6 +252,38 @@
         return false;
     }
 
+    long getLastUserActivityTimeLocked(int groupId) {
+        return mDisplayGroupInfos.get(groupId).lastUserActivityTime;
+    }
+
+    long getLastUserActivityTimeNoChangeLightsLocked(int groupId) {
+        return mDisplayGroupInfos.get(groupId).lastUserActivityTimeNoChangeLights;
+    }
+
+    int getUserActivitySummaryLocked(int groupId) {
+        return mDisplayGroupInfos.get(groupId).userActivitySummary;
+    }
+
+    void setLastUserActivityTimeLocked(int groupId, long time) {
+        mDisplayGroupInfos.get(groupId).lastUserActivityTime = time;
+    }
+
+    void setLastUserActivityTimeNoChangeLightsLocked(int groupId, long time) {
+        mDisplayGroupInfos.get(groupId).lastUserActivityTimeNoChangeLights = time;
+    }
+
+    void setUserActivitySummaryLocked(int groupId, int summary) {
+        mDisplayGroupInfos.get(groupId).userActivitySummary = summary;
+    }
+
+    int getWakeLockSummaryLocked(int groupId) {
+        return mDisplayGroupInfos.get(groupId).wakeLockSummary;
+    }
+
+    void setWakeLockSummaryLocked(int groupId, int summary) {
+        mDisplayGroupInfos.get(groupId).wakeLockSummary = summary;
+    }
+
     /**
      * Interface through which an interested party may be informed of {@link DisplayGroup} events.
      */
@@ -265,6 +301,10 @@
         public boolean ready;
         public long lastPowerOnTime;
         public boolean sandmanSummoned;
+        public long lastUserActivityTime;
+        public long lastUserActivityTimeNoChangeLights;
+        public int userActivitySummary;
+        public int wakeLockSummary;
 
         /** {@code true} if this DisplayGroup supports dreaming; otherwise {@code false}. */
         public boolean supportsSandman;
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index d2a4cd6..8052522 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -29,6 +29,7 @@
 import static android.os.PowerManagerInternal.WAKEFULNESS_AWAKE;
 import static android.os.PowerManagerInternal.WAKEFULNESS_DOZING;
 import static android.os.PowerManagerInternal.WAKEFULNESS_DREAMING;
+import static android.os.PowerManagerInternal.wakefulnessToString;
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
@@ -92,6 +93,7 @@
 import android.util.TimeUtils;
 import android.util.proto.ProtoOutputStream;
 import android.view.Display;
+import android.view.DisplayInfo;
 import android.view.KeyEvent;
 
 import com.android.internal.annotations.GuardedBy;
@@ -180,8 +182,8 @@
     private static final int DIRTY_VR_MODE_CHANGED = 1 << 13;
     // Dirty bit: attentive timer may have timed out
     private static final int DIRTY_ATTENTIVE = 1 << 14;
-    // Dirty bit: display group power state has changed
-    private static final int DIRTY_DISPLAY_GROUP_POWER_UPDATED = 1 << 16;
+    // Dirty bit: display group wakefulness has changed
+    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;
@@ -338,10 +340,6 @@
     private @WakeReason int mLastWakeReason;
     private int mLastSleepReason;
 
-    // Timestamp of the last call to user activity.
-    private long mLastUserActivityTime;
-    private long mLastUserActivityTimeNoChangeLights;
-
     // Timestamp of last time power boost interaction was sent.
     private long mLastInteractivePowerHintTime;
 
@@ -349,9 +347,6 @@
     private long mLastScreenBrightnessBoostTime;
     private boolean mScreenBrightnessBoostInProgress;
 
-    // A bitfield that summarizes the effect of the user activity timer.
-    private int mUserActivitySummary;
-
     // Manages the desired power state of displays. The actual state may lag behind the
     // requested because it is updated asynchronously by the display power controller.
     private DisplayGroupPowerStateMapper mDisplayGroupPowerStateMapper;
@@ -634,6 +629,13 @@
         public void onDisplayGroupEventLocked(int event, int groupId) {
             final int oldWakefulness = getWakefulnessLocked();
             final int newWakefulness = mDisplayGroupPowerStateMapper.getGlobalWakefulnessLocked();
+
+            if (event == DISPLAY_GROUP_ADDED && newWakefulness == WAKEFULNESS_AWAKE) {
+                // Kick user activity to prevent newly added group from timing out instantly.
+                userActivityNoUpdateLocked(groupId, mClock.uptimeMillis(),
+                        PowerManager.USER_ACTIVITY_EVENT_OTHER, /* flags= */ 0, Process.SYSTEM_UID);
+            }
+
             if (oldWakefulness != newWakefulness) {
                 final int reason;
                 switch (newWakefulness) {
@@ -656,7 +658,7 @@
                         mContext.getOpPackageName(), "groupId: " + groupId);
             }
 
-            mDirty |= DIRTY_DISPLAY_GROUP_POWER_UPDATED;
+            mDirty |= DIRTY_DISPLAY_GROUP_WAKEFULNESS;
             updatePowerStateLocked();
         }
     }
@@ -1059,6 +1061,10 @@
     private void onFlip(boolean isFaceDown) {
         long millisUntilNormalTimeout = 0;
         synchronized (mLock) {
+            if (!mBootCompleted) {
+                return;
+            }
+
             mIsFaceDown = isFaceDown;
             if (isFaceDown) {
                 final long currentTime = mClock.uptimeMillis();
@@ -1066,8 +1072,9 @@
                 final long sleepTimeout = getSleepTimeoutLocked(-1L);
                 final long screenOffTimeout = getScreenOffTimeoutLocked(sleepTimeout, -1L);
                 millisUntilNormalTimeout =
-                        mLastUserActivityTime + screenOffTimeout - mClock.uptimeMillis();
-                userActivityInternal(mClock.uptimeMillis(),
+                        mDisplayGroupPowerStateMapper.getLastUserActivityTimeLocked(
+                                Display.DEFAULT_DISPLAY_GROUP) + screenOffTimeout - currentTime;
+                userActivityInternal(Display.DEFAULT_DISPLAY, currentTime,
                         PowerManager.USER_ACTIVITY_EVENT_FACE_DOWN, /* flags= */0,
                         Process.SYSTEM_UID);
             }
@@ -1341,9 +1348,20 @@
         updatePowerStateLocked();
     }
 
-    private void acquireWakeLockInternal(IBinder lock, int flags, String tag, String packageName,
-            WorkSource ws, String historyTag, int uid, int pid) {
+    private void acquireWakeLockInternal(IBinder lock, int displayId, int flags, String tag,
+            String packageName, WorkSource ws, String historyTag, int uid, int pid) {
         synchronized (mLock) {
+            if (displayId != Display.INVALID_DISPLAY) {
+                final DisplayInfo displayInfo =
+                        mSystemReady ? mDisplayManagerInternal.getDisplayInfo(displayId) : null;
+                if (displayInfo == null) {
+                    Slog.wtf(TAG, "Tried to acquire wake lock for invalid display: " + displayId);
+                    return;
+                } else if (!displayInfo.hasAccess(uid)) {
+                    throw new SecurityException("Caller does not have access to display");
+                }
+            }
+
             if (DEBUG_SPEW) {
                 Slog.d(TAG, "acquireWakeLockInternal: lock=" + Objects.hashCode(lock)
                         + ", flags=0x" + Integer.toHexString(flags)
@@ -1370,8 +1388,8 @@
                     mUidState.put(uid, state);
                 }
                 state.mNumWakeLocks++;
-                wakeLock = new WakeLock(lock, flags, tag, packageName, ws, historyTag, uid, pid,
-                        state);
+                wakeLock = new WakeLock(lock, displayId, flags, tag, packageName, ws, historyTag,
+                        uid, pid, state);
                 try {
                     lock.linkToDeath(wakeLock, 0);
                 } catch (RemoteException ex) {
@@ -1645,12 +1663,28 @@
 
     // Called from native code.
     private void userActivityFromNative(long eventTime, int event, int displayId, int flags) {
-        userActivityInternal(eventTime, event, flags, Process.SYSTEM_UID);
+        userActivityInternal(displayId, eventTime, event, flags, Process.SYSTEM_UID);
     }
 
-    private void userActivityInternal(long eventTime, int event, int flags, int uid) {
+    private void userActivityInternal(int displayId, long eventTime, int event, int flags,
+            int uid) {
         synchronized (mLock) {
-            if (userActivityNoUpdateLocked(eventTime, event, flags, uid)) {
+            if (displayId == Display.INVALID_DISPLAY) {
+                if (userActivityNoUpdateLocked(eventTime, event, flags, uid)) {
+                    updatePowerStateLocked();
+                }
+                return;
+            }
+
+            final DisplayInfo displayInfo = mDisplayManagerInternal.getDisplayInfo(displayId);
+            if (displayInfo == null) {
+                return;
+            }
+            final int groupId = displayInfo.displayGroupId;
+            if (groupId == Display.INVALID_DISPLAY_GROUP) {
+                return;
+            }
+            if (userActivityNoUpdateLocked(groupId, eventTime, event, flags, uid)) {
                 updatePowerStateLocked();
             }
         }
@@ -1658,7 +1692,7 @@
 
     private void onUserAttention() {
         synchronized (mLock) {
-            if (userActivityNoUpdateLocked(mClock.uptimeMillis(),
+            if (userActivityNoUpdateLocked(Display.DEFAULT_DISPLAY_GROUP, mClock.uptimeMillis(),
                     PowerManager.USER_ACTIVITY_EVENT_ATTENTION, 0 /* flags */,
                     Process.SYSTEM_UID)) {
                 updatePowerStateLocked();
@@ -1667,10 +1701,22 @@
     }
 
     private boolean userActivityNoUpdateLocked(long eventTime, int event, int flags, int uid) {
+        boolean updatePowerState = false;
+        for (int id : mDisplayGroupPowerStateMapper.getDisplayGroupIdsLocked()) {
+            if (userActivityNoUpdateLocked(id, eventTime, event, flags, uid)) {
+                updatePowerState = true;
+            }
+        }
+
+        return updatePowerState;
+    }
+
+    private boolean userActivityNoUpdateLocked(int groupId, long eventTime, int event, int flags,
+            int uid) {
         if (DEBUG_SPEW) {
-            Slog.d(TAG, "userActivityNoUpdateLocked: eventTime=" + eventTime
-                    + ", event=" + event + ", flags=0x" + Integer.toHexString(flags)
-                    + ", uid=" + uid);
+            Slog.d(TAG, "userActivityNoUpdateLocked: groupId=" + groupId
+                    + ", eventTime=" + eventTime + ", event=" + event
+                    + ", flags=0x" + Integer.toHexString(flags) + ", uid=" + uid);
         }
 
         if (eventTime < mLastSleepTime || eventTime < mLastWakeTime || !mSystemReady) {
@@ -1692,8 +1738,9 @@
                 mOverriddenTimeout = -1;
             }
 
-            if (getWakefulnessLocked() == WAKEFULNESS_ASLEEP
-                    || getWakefulnessLocked() == WAKEFULNESS_DOZING
+            final int wakefulness = mDisplayGroupPowerStateMapper.getWakefulnessLocked(groupId);
+            if (wakefulness == WAKEFULNESS_ASLEEP
+                    || wakefulness == WAKEFULNESS_DOZING
                     || (flags & PowerManager.USER_ACTIVITY_FLAG_INDIRECT) != 0) {
                 return false;
             }
@@ -1701,9 +1748,13 @@
             maybeUpdateForegroundProfileLastActivityLocked(eventTime);
 
             if ((flags & PowerManager.USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS) != 0) {
-                if (eventTime > mLastUserActivityTimeNoChangeLights
-                        && eventTime > mLastUserActivityTime) {
-                    mLastUserActivityTimeNoChangeLights = eventTime;
+                if (eventTime
+                        > mDisplayGroupPowerStateMapper.getLastUserActivityTimeNoChangeLightsLocked(
+                        groupId)
+                        && eventTime > mDisplayGroupPowerStateMapper.getLastUserActivityTimeLocked(
+                        groupId)) {
+                    mDisplayGroupPowerStateMapper.setLastUserActivityTimeNoChangeLightsLocked(
+                            groupId, eventTime);
                     mDirty |= DIRTY_USER_ACTIVITY;
                     if (event == PowerManager.USER_ACTIVITY_EVENT_BUTTON) {
                         mDirty |= DIRTY_QUIESCENT;
@@ -1712,8 +1763,9 @@
                     return true;
                 }
             } else {
-                if (eventTime > mLastUserActivityTime) {
-                    mLastUserActivityTime = eventTime;
+                if (eventTime > mDisplayGroupPowerStateMapper.getLastUserActivityTimeLocked(
+                        groupId)) {
+                    mDisplayGroupPowerStateMapper.setLastUserActivityTimeLocked(groupId, eventTime);
                     mDirty |= DIRTY_USER_ACTIVITY;
                     if (event == PowerManager.USER_ACTIVITY_EVENT_BUTTON) {
                         mDirty |= DIRTY_QUIESCENT;
@@ -1778,7 +1830,6 @@
             setWakefulnessLocked(groupId, WAKEFULNESS_AWAKE, eventTime, uid, reason, opUid,
                     opPackageName, details);
             mDisplayGroupPowerStateMapper.setLastPowerOnTimeLocked(groupId, eventTime);
-            mDirty |= DIRTY_DISPLAY_GROUP_POWER_UPDATED;
         } finally {
             Trace.traceEnd(Trace.TRACE_TAG_POWER);
         }
@@ -1829,7 +1880,6 @@
             if ((flags & PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE) != 0) {
                 reallySleepDisplayGroupNoUpdateLocked(groupId, eventTime, uid);
             }
-            mDirty |= DIRTY_DISPLAY_GROUP_POWER_UPDATED;
         } finally {
             Trace.traceEnd(Trace.TRACE_TAG_POWER);
         }
@@ -1862,7 +1912,6 @@
             mDisplayGroupPowerStateMapper.setSandmanSummoned(groupId, true);
             setWakefulnessLocked(groupId, WAKEFULNESS_DREAMING, eventTime, uid, /* reason= */
                     0, /* opUid= */ 0, /* opPackageName= */ null, /* details= */ null);
-            mDirty |= DIRTY_DISPLAY_GROUP_POWER_UPDATED;
 
         } finally {
             Trace.traceEnd(Trace.TRACE_TAG_POWER);
@@ -1890,7 +1939,6 @@
             setWakefulnessLocked(groupId, WAKEFULNESS_ASLEEP, eventTime, uid,
                     PowerManager.GO_TO_SLEEP_REASON_TIMEOUT,  /* opUid= */ 0,
                     /* opPackageName= */ null, /* details= */ null);
-            mDirty |= DIRTY_DISPLAY_GROUP_POWER_UPDATED;
         } finally {
             Trace.traceEnd(Trace.TRACE_TAG_POWER);
         }
@@ -1901,8 +1949,14 @@
     void setWakefulnessLocked(int groupId, int wakefulness, long eventTime, int uid, int reason,
             int opUid, String opPackageName, String details) {
         if (mDisplayGroupPowerStateMapper.setWakefulnessLocked(groupId, wakefulness)) {
+            mDirty |= DIRTY_DISPLAY_GROUP_WAKEFULNESS;
             setGlobalWakefulnessLocked(mDisplayGroupPowerStateMapper.getGlobalWakefulnessLocked(),
                     eventTime, reason, uid, opUid, opPackageName, details);
+            if (wakefulness == WAKEFULNESS_AWAKE) {
+                // Kick user activity to prevent newly awake group from timing out instantly.
+                userActivityNoUpdateLocked(
+                        groupId, eventTime, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, uid);
+            }
         }
     }
 
@@ -1972,8 +2026,6 @@
             switch (wakefulness) {
                 case WAKEFULNESS_AWAKE:
                     mNotifier.onWakeUp(reason, details, uid, opPackageName, opUid);
-                    userActivityNoUpdateLocked(
-                            eventTime, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, uid);
                     if (sQuiescent) {
                         mDirty |= DIRTY_QUIESCENT;
                     }
@@ -2006,6 +2058,11 @@
         return mWakefulnessRaw;
     }
 
+    @VisibleForTesting
+    int getWakefulnessLocked(int groupId) {
+        return mDisplayGroupPowerStateMapper.getWakefulnessLocked(groupId);
+    }
+
     /**
      * Logs the time the device would have spent awake before user activity timeout,
      * had the system not been told the user was inactive.
@@ -2163,8 +2220,9 @@
                             "android.server.power:PLUGGED:" + mIsPowered, Process.SYSTEM_UID,
                             mContext.getOpPackageName(), Process.SYSTEM_UID);
                 }
-                userActivityNoUpdateLocked(
-                        now, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
+
+                userActivityNoUpdateLocked(Display.DEFAULT_DISPLAY_GROUP, now,
+                        PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
 
                 // only play charging sounds if boot is completed so charging sounds don't play
                 // with potential notification sounds
@@ -2251,7 +2309,9 @@
      */
     @SuppressWarnings("deprecation")
     private void updateWakeLockSummaryLocked(int dirty) {
-        if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_WAKEFULNESS)) != 0) {
+        if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_WAKEFULNESS | DIRTY_DISPLAY_GROUP_WAKEFULNESS))
+                != 0) {
+
             mWakeLockSummary = 0;
 
             final int numProfiles = mProfilePowerState.size();
@@ -2259,11 +2319,28 @@
                 mProfilePowerState.valueAt(i).mWakeLockSummary = 0;
             }
 
+            for (int groupId : mDisplayGroupPowerStateMapper.getDisplayGroupIdsLocked()) {
+                mDisplayGroupPowerStateMapper.setWakeLockSummaryLocked(groupId, 0);
+            }
+
+            int invalidGroupWakeLockSummary = 0;
             final int numWakeLocks = mWakeLocks.size();
             for (int i = 0; i < numWakeLocks; i++) {
                 final WakeLock wakeLock = mWakeLocks.get(i);
                 final int wakeLockFlags = getWakeLockSummaryFlags(wakeLock);
                 mWakeLockSummary |= wakeLockFlags;
+
+                final int groupId = wakeLock.getDisplayGroupId();
+                if (groupId != Display.INVALID_DISPLAY_GROUP) {
+                    int wakeLockSummary = mDisplayGroupPowerStateMapper.getWakeLockSummaryLocked(
+                            groupId);
+                    wakeLockSummary |= wakeLockFlags;
+                    mDisplayGroupPowerStateMapper.setWakeLockSummaryLocked(groupId,
+                            wakeLockSummary);
+                } else {
+                    invalidGroupWakeLockSummary |= wakeLockFlags;
+                }
+
                 for (int j = 0; j < numProfiles; j++) {
                     final ProfilePowerState profile = mProfilePowerState.valueAt(j);
                     if (wakeLockAffectsUser(wakeLock, profile.mUserId)) {
@@ -2272,10 +2349,21 @@
                 }
             }
 
-            mWakeLockSummary = adjustWakeLockSummaryLocked(mWakeLockSummary);
+            for (int groupId : mDisplayGroupPowerStateMapper.getDisplayGroupIdsLocked()) {
+                final int wakeLockSummary = adjustWakeLockSummaryLocked(
+                        mDisplayGroupPowerStateMapper.getWakefulnessLocked(groupId),
+                        invalidGroupWakeLockSummary
+                                | mDisplayGroupPowerStateMapper.getWakeLockSummaryLocked(groupId));
+                mDisplayGroupPowerStateMapper.setWakeLockSummaryLocked(groupId, wakeLockSummary);
+            }
+
+            mWakeLockSummary = adjustWakeLockSummaryLocked(getWakefulnessLocked(),
+                    mWakeLockSummary);
+
             for (int i = 0; i < numProfiles; i++) {
                 final ProfilePowerState profile = mProfilePowerState.valueAt(i);
-                profile.mWakeLockSummary = adjustWakeLockSummaryLocked(profile.mWakeLockSummary);
+                profile.mWakeLockSummary = adjustWakeLockSummaryLocked(getWakefulnessLocked(),
+                        profile.mWakeLockSummary);
             }
 
             if (DEBUG_SPEW) {
@@ -2286,25 +2374,25 @@
         }
     }
 
-    private int adjustWakeLockSummaryLocked(int wakeLockSummary) {
+    private static int adjustWakeLockSummaryLocked(int wakefulness, int wakeLockSummary) {
         // Cancel wake locks that make no sense based on the current state.
-        if (getWakefulnessLocked() != WAKEFULNESS_DOZING) {
+        if (wakefulness != WAKEFULNESS_DOZING) {
             wakeLockSummary &= ~(WAKE_LOCK_DOZE | WAKE_LOCK_DRAW);
         }
-        if (getWakefulnessLocked() == WAKEFULNESS_ASLEEP
+        if (wakefulness == WAKEFULNESS_ASLEEP
                 || (wakeLockSummary & WAKE_LOCK_DOZE) != 0) {
             wakeLockSummary &= ~(WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_SCREEN_DIM
                     | WAKE_LOCK_BUTTON_BRIGHT);
-            if (getWakefulnessLocked() == WAKEFULNESS_ASLEEP) {
+            if (wakefulness == WAKEFULNESS_ASLEEP) {
                 wakeLockSummary &= ~WAKE_LOCK_PROXIMITY_SCREEN_OFF;
             }
         }
 
         // Infer implied wake locks where necessary based on the current state.
         if ((wakeLockSummary & (WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_SCREEN_DIM)) != 0) {
-            if (getWakefulnessLocked() == WAKEFULNESS_AWAKE) {
+            if (wakefulness == WAKEFULNESS_AWAKE) {
                 wakeLockSummary |= WAKE_LOCK_CPU | WAKE_LOCK_STAY_AWAKE;
-            } else if (getWakefulnessLocked() == WAKEFULNESS_DREAMING) {
+            } else if (wakefulness == WAKEFULNESS_DREAMING) {
                 wakeLockSummary |= WAKE_LOCK_CPU;
             }
         }
@@ -2407,106 +2495,124 @@
      */
     private void updateUserActivitySummaryLocked(long now, int dirty) {
         // Update the status of the user activity timeout timer.
-        if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY
-                | DIRTY_WAKEFULNESS | DIRTY_SETTINGS)) != 0) {
-            mHandler.removeMessages(MSG_USER_ACTIVITY_TIMEOUT);
+        if ((dirty & (DIRTY_DISPLAY_GROUP_WAKEFULNESS | DIRTY_WAKE_LOCKS
+                | DIRTY_USER_ACTIVITY | DIRTY_WAKEFULNESS | DIRTY_SETTINGS)) == 0) {
+            return;
+        }
+        mHandler.removeMessages(MSG_USER_ACTIVITY_TIMEOUT);
 
-            long nextTimeout = 0;
-            if (getWakefulnessLocked() == WAKEFULNESS_AWAKE
-                    || getWakefulnessLocked() == WAKEFULNESS_DREAMING
-                    || getWakefulnessLocked() == WAKEFULNESS_DOZING) {
-                final long attentiveTimeout = getAttentiveTimeoutLocked();
-                final long sleepTimeout = getSleepTimeoutLocked(attentiveTimeout);
-                long screenOffTimeout = getScreenOffTimeoutLocked(sleepTimeout,
-                        attentiveTimeout);
-                final long screenDimDuration = getScreenDimDurationLocked(screenOffTimeout);
-                screenOffTimeout =
-                        getScreenOffTimeoutWithFaceDownLocked(screenOffTimeout, screenDimDuration);
-                final boolean userInactiveOverride = mUserInactiveOverrideFromWindowManager;
-                final long nextProfileTimeout = getNextProfileTimeoutLocked(now);
-
-                mUserActivitySummary = 0;
-                if (mLastUserActivityTime >= mLastWakeTime) {
-                    nextTimeout = mLastUserActivityTime
-                            + screenOffTimeout - screenDimDuration;
-                    if (now < nextTimeout) {
-                        mUserActivitySummary = USER_ACTIVITY_SCREEN_BRIGHT;
+        final long attentiveTimeout = getAttentiveTimeoutLocked();
+        final long sleepTimeout = getSleepTimeoutLocked(attentiveTimeout);
+        long screenOffTimeout = getScreenOffTimeoutLocked(sleepTimeout,
+                attentiveTimeout);
+        final long screenDimDuration = getScreenDimDurationLocked(screenOffTimeout);
+        screenOffTimeout =
+                getScreenOffTimeoutWithFaceDownLocked(screenOffTimeout, screenDimDuration);
+        final boolean userInactiveOverride = mUserInactiveOverrideFromWindowManager;
+        long nextTimeout = -1;
+        boolean hasUserActivitySummary = false;
+        for (int groupId : mDisplayGroupPowerStateMapper.getDisplayGroupIdsLocked()) {
+            int groupUserActivitySummary = 0;
+            long groupNextTimeout = 0;
+            if (mDisplayGroupPowerStateMapper.getWakefulnessLocked(groupId) != WAKEFULNESS_ASLEEP) {
+                final long lastUserActivityTime =
+                        mDisplayGroupPowerStateMapper.getLastUserActivityTimeLocked(groupId);
+                final long lastUserActivityTimeNoChangeLights =
+                        mDisplayGroupPowerStateMapper.getLastUserActivityTimeNoChangeLightsLocked(
+                                groupId);
+                if (lastUserActivityTime >= mLastWakeTime) {
+                    groupNextTimeout = lastUserActivityTime + screenOffTimeout - screenDimDuration;
+                    if (now < groupNextTimeout) {
+                        groupUserActivitySummary = USER_ACTIVITY_SCREEN_BRIGHT;
                     } else {
-                        nextTimeout = mLastUserActivityTime + screenOffTimeout;
-                        if (now < nextTimeout) {
-                            mUserActivitySummary = USER_ACTIVITY_SCREEN_DIM;
+                        groupNextTimeout = lastUserActivityTime + screenOffTimeout;
+                        if (now < groupNextTimeout) {
+                            groupUserActivitySummary = USER_ACTIVITY_SCREEN_DIM;
                         }
                     }
                 }
-                if (mUserActivitySummary == 0
-                        && mLastUserActivityTimeNoChangeLights >= mLastWakeTime) {
-                    nextTimeout = mLastUserActivityTimeNoChangeLights + screenOffTimeout;
-                    if (now < nextTimeout) {
+                if (groupUserActivitySummary == 0
+                        && lastUserActivityTimeNoChangeLights >= mLastWakeTime) {
+                    groupNextTimeout = lastUserActivityTimeNoChangeLights + screenOffTimeout;
+                    if (now < groupNextTimeout) {
                         final DisplayPowerRequest displayPowerRequest =
-                                mDisplayGroupPowerStateMapper.getPowerRequestLocked(
-                                        Display.DEFAULT_DISPLAY_GROUP);
+                                mDisplayGroupPowerStateMapper.getPowerRequestLocked(groupId);
                         if (displayPowerRequest.policy == DisplayPowerRequest.POLICY_BRIGHT
                                 || displayPowerRequest.policy == DisplayPowerRequest.POLICY_VR) {
-                            mUserActivitySummary = USER_ACTIVITY_SCREEN_BRIGHT;
+                            groupUserActivitySummary = USER_ACTIVITY_SCREEN_BRIGHT;
                         } else if (displayPowerRequest.policy == DisplayPowerRequest.POLICY_DIM) {
-                            mUserActivitySummary = USER_ACTIVITY_SCREEN_DIM;
+                            groupUserActivitySummary = USER_ACTIVITY_SCREEN_DIM;
                         }
                     }
                 }
 
-                if (mUserActivitySummary == 0) {
+                if (groupUserActivitySummary == 0) {
                     if (sleepTimeout >= 0) {
-                        final long anyUserActivity = Math.max(mLastUserActivityTime,
-                                mLastUserActivityTimeNoChangeLights);
+                        final long anyUserActivity = Math.max(lastUserActivityTime,
+                                lastUserActivityTimeNoChangeLights);
                         if (anyUserActivity >= mLastWakeTime) {
-                            nextTimeout = anyUserActivity + sleepTimeout;
-                            if (now < nextTimeout) {
-                                mUserActivitySummary = USER_ACTIVITY_SCREEN_DREAM;
+                            groupNextTimeout = anyUserActivity + sleepTimeout;
+                            if (now < groupNextTimeout) {
+                                groupUserActivitySummary = USER_ACTIVITY_SCREEN_DREAM;
                             }
                         }
                     } else {
-                        mUserActivitySummary = USER_ACTIVITY_SCREEN_DREAM;
-                        nextTimeout = -1;
+                        groupUserActivitySummary = USER_ACTIVITY_SCREEN_DREAM;
+                        groupNextTimeout = -1;
                     }
                 }
 
-                if (mUserActivitySummary != USER_ACTIVITY_SCREEN_DREAM && userInactiveOverride) {
-                    if ((mUserActivitySummary &
+                if (groupUserActivitySummary != USER_ACTIVITY_SCREEN_DREAM
+                        && userInactiveOverride) {
+                    if ((groupUserActivitySummary &
                             (USER_ACTIVITY_SCREEN_BRIGHT | USER_ACTIVITY_SCREEN_DIM)) != 0) {
                         // Device is being kept awake by recent user activity
-                        if (nextTimeout >= now && mOverriddenTimeout == -1) {
+                        if (mOverriddenTimeout == -1) {
                             // Save when the next timeout would have occurred
-                            mOverriddenTimeout = nextTimeout;
+                            mOverriddenTimeout = groupNextTimeout;
                         }
                     }
-                    mUserActivitySummary = USER_ACTIVITY_SCREEN_DREAM;
-                    nextTimeout = -1;
+                    groupUserActivitySummary = USER_ACTIVITY_SCREEN_DREAM;
+                    groupNextTimeout = -1;
                 }
 
-                if ((mUserActivitySummary & USER_ACTIVITY_SCREEN_BRIGHT) != 0
-                        && (mWakeLockSummary & WAKE_LOCK_STAY_AWAKE) == 0) {
-                    nextTimeout = mAttentionDetector.updateUserActivity(nextTimeout,
+                if ((groupUserActivitySummary & USER_ACTIVITY_SCREEN_BRIGHT) != 0
+                        && (mDisplayGroupPowerStateMapper.getWakeLockSummaryLocked(groupId)
+                        & WAKE_LOCK_STAY_AWAKE) == 0) {
+                    groupNextTimeout = mAttentionDetector.updateUserActivity(groupNextTimeout,
                             screenDimDuration);
                 }
 
-                if (nextProfileTimeout > 0) {
-                    nextTimeout = Math.min(nextTimeout, nextProfileTimeout);
-                }
+                hasUserActivitySummary |= groupUserActivitySummary != 0;
 
-                if (mUserActivitySummary != 0 && nextTimeout >= 0) {
-                    scheduleUserInactivityTimeout(nextTimeout);
+                if (nextTimeout == -1) {
+                    nextTimeout = groupNextTimeout;
+                } else if (groupNextTimeout != -1) {
+                    nextTimeout = Math.min(nextTimeout, groupNextTimeout);
                 }
-            } else {
-                mUserActivitySummary = 0;
             }
 
+            mDisplayGroupPowerStateMapper.setUserActivitySummaryLocked(groupId,
+                    groupUserActivitySummary);
+
             if (DEBUG_SPEW) {
-                Slog.d(TAG, "updateUserActivitySummaryLocked: mWakefulness="
-                        + PowerManagerInternal.wakefulnessToString(getWakefulnessLocked())
-                        + ", mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary)
-                        + ", nextTimeout=" + TimeUtils.formatUptime(nextTimeout));
+                Slog.d(TAG, "updateUserActivitySummaryLocked: groupId=" + groupId
+                        + ", mWakefulness=" + wakefulnessToString(
+                        mDisplayGroupPowerStateMapper.getWakefulnessLocked(groupId))
+                        + ", mUserActivitySummary=0x" + Integer.toHexString(
+                        groupUserActivitySummary)
+                        + ", nextTimeout=" + TimeUtils.formatUptime(groupNextTimeout));
             }
         }
+
+        final long nextProfileTimeout = getNextProfileTimeoutLocked(now);
+        if (nextProfileTimeout > 0) {
+            nextTimeout = Math.min(nextTimeout, nextProfileTimeout);
+        }
+
+        if (hasUserActivitySummary && nextTimeout >= 0) {
+            scheduleUserInactivityTimeout(nextTimeout);
+        }
     }
 
     private void scheduleUserInactivityTimeout(long timeMs) {
@@ -2539,15 +2645,20 @@
 
     private void updateAttentiveStateLocked(long now, int dirty) {
         long attentiveTimeout = getAttentiveTimeoutLocked();
-        long goToSleepTime = mLastUserActivityTime + attentiveTimeout;
+        if (attentiveTimeout < 0) {
+            return;
+        }
+        // Attentive state only applies to the default display group.
+        long goToSleepTime = mDisplayGroupPowerStateMapper.getLastUserActivityTimeLocked(
+                Display.DEFAULT_DISPLAY_GROUP) + attentiveTimeout;
         long showWarningTime = goToSleepTime - mAttentiveWarningDurationConfig;
 
         boolean warningDismissed = maybeHideInattentiveSleepWarningLocked(now, showWarningTime);
 
-        if (attentiveTimeout >= 0 && (warningDismissed
-                || (dirty & (DIRTY_ATTENTIVE | DIRTY_STAY_ON | DIRTY_SCREEN_BRIGHTNESS_BOOST
-                | DIRTY_PROXIMITY_POSITIVE | DIRTY_WAKEFULNESS | DIRTY_BOOT_COMPLETED
-                | DIRTY_SETTINGS)) != 0)) {
+        if (warningDismissed ||
+                (dirty & (DIRTY_ATTENTIVE | DIRTY_STAY_ON | DIRTY_SCREEN_BRIGHTNESS_BOOST
+                        | DIRTY_PROXIMITY_POSITIVE | DIRTY_WAKEFULNESS | DIRTY_BOOT_COMPLETED
+                        | DIRTY_SETTINGS)) != 0) {
             if (DEBUG_SPEW) {
                 Slog.d(TAG, "Updating attentive state");
             }
@@ -2601,9 +2712,12 @@
         return false;
     }
 
-    private boolean isAttentiveTimeoutExpired(long now) {
+    private boolean isAttentiveTimeoutExpired(int groupId, long now) {
         long attentiveTimeout = getAttentiveTimeoutLocked();
-        return attentiveTimeout >= 0 && now >= mLastUserActivityTime + attentiveTimeout;
+        // Attentive state only applies to the default display group.
+        return groupId == Display.DEFAULT_DISPLAY_GROUP && attentiveTimeout >= 0
+                && now >= mDisplayGroupPowerStateMapper.getLastUserActivityTimeLocked(groupId)
+                + attentiveTimeout;
     }
 
     /**
@@ -2703,26 +2817,20 @@
                 | DIRTY_WAKEFULNESS | DIRTY_STAY_ON | DIRTY_PROXIMITY_POSITIVE
                 | DIRTY_DOCK_STATE | DIRTY_ATTENTIVE | DIRTY_SETTINGS
                 | DIRTY_SCREEN_BRIGHTNESS_BOOST)) != 0) {
-            if (getWakefulnessLocked() == WAKEFULNESS_AWAKE && isItBedTimeYetLocked()) {
-                if (DEBUG_SPEW) {
-                    Slog.d(TAG, "updateWakefulnessLocked: Bed time...");
-                }
-                final long time = mClock.uptimeMillis();
-                if (isAttentiveTimeoutExpired(time)) {
-                    // TODO (b/175764389): Support per-display timeouts.
-                    for (int id : mDisplayGroupPowerStateMapper.getDisplayGroupIdsLocked()) {
+            final long time = mClock.uptimeMillis();
+            for (int id : mDisplayGroupPowerStateMapper.getDisplayGroupIdsLocked()) {
+                if (mDisplayGroupPowerStateMapper.getWakefulnessLocked(id) == WAKEFULNESS_AWAKE
+                        && isItBedTimeYetLocked(id)) {
+                    if (DEBUG_SPEW) {
+                        Slog.d(TAG, "updateWakefulnessLocked: Bed time for group " + id);
+                    }
+                    if (isAttentiveTimeoutExpired(id, time)) {
                         changed = sleepDisplayGroupNoUpdateLocked(id, time,
                                 PowerManager.GO_TO_SLEEP_REASON_TIMEOUT,
                                 PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE, Process.SYSTEM_UID);
-                    }
-                } else if (shouldNapAtBedTimeLocked()) {
-                    // TODO (b/175764389): Support per-display timeouts.
-                    for (int id : mDisplayGroupPowerStateMapper.getDisplayGroupIdsLocked()) {
+                    } else if (shouldNapAtBedTimeLocked()) {
                         changed = dreamDisplayGroupNoUpdateLocked(id, time, Process.SYSTEM_UID);
-                    }
-                } else {
-                    // TODO (b/175764389): Support per-display timeouts.
-                    for (int id : mDisplayGroupPowerStateMapper.getDisplayGroupIdsLocked()) {
+                    } else {
                         changed = sleepDisplayGroupNoUpdateLocked(id, time,
                                 PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, 0, Process.SYSTEM_UID);
                     }
@@ -2743,51 +2851,51 @@
     }
 
     /**
-     * Returns true if the device should go to sleep now.
-     * Also used when exiting a dream to determine whether we should go back
-     * to being fully awake or else go to sleep for good.
+     * Returns true if the DisplayGroup with the provided {@code groupId} should go to sleep now.
+     * Also used when exiting a dream to determine whether we should go back to being fully awake or
+     * else go to sleep for good.
      */
-    private boolean isItBedTimeYetLocked() {
+    private boolean isItBedTimeYetLocked(int groupId) {
         if (!mBootCompleted) {
             return false;
         }
 
         long now = mClock.uptimeMillis();
-        if (isAttentiveTimeoutExpired(now)) {
-            return !isBeingKeptFromInattentiveSleepLocked();
+        if (isAttentiveTimeoutExpired(groupId, now)) {
+            return !isBeingKeptFromInattentiveSleepLocked(groupId);
         } else {
-            return !isBeingKeptAwakeLocked();
+            return !isBeingKeptAwakeLocked(groupId);
         }
     }
 
     /**
-     * Returns true if the device is being kept awake by a wake lock, user activity
-     * or the stay on while powered setting.  We also keep the phone awake when
-     * the proximity sensor returns a positive result so that the device does not
-     * lock while in a phone call.  This function only controls whether the device
-     * will go to sleep or dream which is independent of whether it will be allowed
-     * to suspend.
+     * Returns true if the DisplayGroup with the provided {@code groupId} is being kept awake by a
+     * wake lock, user activity or the stay on while powered setting.  We also keep the phone awake
+     * when the proximity sensor returns a positive result so that the device does not lock while in
+     * a phone call.  This function only controls whether the device will go to sleep or dream which
+     * is independent of whether it will be allowed to suspend.
      */
-    private boolean isBeingKeptAwakeLocked() {
+    private boolean isBeingKeptAwakeLocked(int groupId) {
         return mStayOn
                 || mProximityPositive
-                || (mWakeLockSummary & WAKE_LOCK_STAY_AWAKE) != 0
-                || (mUserActivitySummary & (USER_ACTIVITY_SCREEN_BRIGHT
-                        | USER_ACTIVITY_SCREEN_DIM)) != 0
+                || (mDisplayGroupPowerStateMapper.getWakeLockSummaryLocked(groupId)
+                & WAKE_LOCK_STAY_AWAKE) != 0
+                || (mDisplayGroupPowerStateMapper.getUserActivitySummaryLocked(groupId) & (
+                USER_ACTIVITY_SCREEN_BRIGHT | USER_ACTIVITY_SCREEN_DIM)) != 0
                 || mScreenBrightnessBoostInProgress;
     }
 
     /**
-     * Returns true if the device is prevented from going into inattentive sleep by the stay on
-     * while powered setting. We also keep the device awake when the proximity sensor returns a
-     * positive result so that the device does not lock while in a phone call. This function only
-     * controls whether the device will go to sleep which is independent of whether it will be
-     * allowed to suspend.
+     * Returns true if the DisplayGroup with the provided {@code groupId} is prevented from going
+     * into inattentive sleep by the stay on while powered setting. We also keep the device awake
+     * when the proximity sensor returns a positive result so that the device does not lock while in
+     * a phone call. This function only controls whether the device will go to sleep which is
+     * independent of whether it will be allowed to suspend.
      */
-    private boolean isBeingKeptFromInattentiveSleepLocked() {
+    private boolean isBeingKeptFromInattentiveSleepLocked(int groupId) {
         return mStayOn || mScreenBrightnessBoostInProgress || mProximityPositive
-                || (mUserActivitySummary & (USER_ACTIVITY_SCREEN_BRIGHT
-                | USER_ACTIVITY_SCREEN_DIM)) != 0;
+                || (mDisplayGroupPowerStateMapper.getUserActivitySummaryLocked(groupId) & (
+                USER_ACTIVITY_SCREEN_BRIGHT | USER_ACTIVITY_SCREEN_DIM)) != 0;
     }
 
     private boolean isBeingKeptFromShowingInattentiveSleepWarningLocked() {
@@ -2902,7 +3010,7 @@
                     if (mDreamsBatteryLevelDrainCutoffConfig >= 0
                             && mBatteryLevel < mBatteryLevelWhenDreamStarted
                                     - mDreamsBatteryLevelDrainCutoffConfig
-                            && !isBeingKeptAwakeLocked()) {
+                            && !isBeingKeptAwakeLocked(groupId)) {
                         // If the user activity timeout expired and the battery appears
                         // to be draining faster than it is charging then stop dreaming
                         // and go to sleep.
@@ -2917,18 +3025,17 @@
                 }
 
                 // Dream has ended or will be stopped.  Update the power state.
-                if (isItBedTimeYetLocked()) {
-                    final int flags = isAttentiveTimeoutExpired(now)
+                if (isItBedTimeYetLocked(groupId)) {
+                    final int flags = isAttentiveTimeoutExpired(groupId, now)
                             ? PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE : 0;
                     sleepDisplayGroupNoUpdateLocked(groupId, now,
                             PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, flags, Process.SYSTEM_UID);
-                    updatePowerStateLocked();
                 } else {
                     wakeDisplayGroupNoUpdateLocked(groupId, now, PowerManager.WAKE_REASON_UNKNOWN,
                             "android.server.power:DREAM_FINISHED", Process.SYSTEM_UID,
                             mContext.getOpPackageName(), Process.SYSTEM_UID);
-                    updatePowerStateLocked();
                 }
+                updatePowerStateLocked();
             } else if (wakefulness == WAKEFULNESS_DOZING) {
                 if (isDreaming) {
                     return; // continue dozing
@@ -2952,17 +3059,18 @@
     private boolean canDreamLocked(int groupId) {
         final DisplayPowerRequest displayPowerRequest =
                 mDisplayGroupPowerStateMapper.getPowerRequestLocked(groupId);
-        if (getWakefulnessLocked() != WAKEFULNESS_DREAMING
+        if (!mBootCompleted
+                || getWakefulnessLocked() != WAKEFULNESS_DREAMING
                 || !mDreamsSupportedConfig
                 || !mDreamsEnabledSetting
                 || !displayPowerRequest.isBrightOrDim()
                 || displayPowerRequest.isVr()
-                || (mUserActivitySummary & (USER_ACTIVITY_SCREEN_BRIGHT
-                        | USER_ACTIVITY_SCREEN_DIM | USER_ACTIVITY_SCREEN_DREAM)) == 0
-                || !mBootCompleted) {
+                || (mDisplayGroupPowerStateMapper.getUserActivitySummaryLocked(groupId) & (
+                USER_ACTIVITY_SCREEN_BRIGHT | USER_ACTIVITY_SCREEN_DIM
+                        | USER_ACTIVITY_SCREEN_DREAM)) == 0) {
             return false;
         }
-        if (!isBeingKeptAwakeLocked()) {
+        if (!isBeingKeptAwakeLocked(groupId)) {
             if (!mIsPowered && !mDreamsEnabledOnBatteryConfig) {
                 return false;
             }
@@ -2971,11 +3079,9 @@
                     && mBatteryLevel < mDreamsBatteryLevelMinimumWhenNotPoweredConfig) {
                 return false;
             }
-            if (mIsPowered
-                    && mDreamsBatteryLevelMinimumWhenPoweredConfig >= 0
-                    && mBatteryLevel < mDreamsBatteryLevelMinimumWhenPoweredConfig) {
-                return false;
-            }
+            return !mIsPowered
+                    || mDreamsBatteryLevelMinimumWhenPoweredConfig < 0
+                    || mBatteryLevel >= mDreamsBatteryLevelMinimumWhenPoweredConfig;
         }
         return true;
     }
@@ -3002,7 +3108,7 @@
         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_POWER_UPDATED)) != 0) {
+                DIRTY_QUIESCENT | DIRTY_DISPLAY_GROUP_WAKEFULNESS)) != 0) {
             if ((dirty & DIRTY_QUIESCENT) != 0) {
                 if (mDisplayGroupPowerStateMapper.areAllDisplaysReadyLocked()) {
                     sQuiescent = false;
@@ -3043,8 +3149,8 @@
 
                 if (displayPowerRequest.policy == DisplayPowerRequest.POLICY_DOZE) {
                     displayPowerRequest.dozeScreenState = mDozeScreenStateOverrideFromDreamManager;
-                    if ((mWakeLockSummary & WAKE_LOCK_DRAW) != 0
-                            && !mDrawWakeLockOverrideFromSidekick) {
+                    if ((mDisplayGroupPowerStateMapper.getWakeLockSummaryLocked(groupId)
+                            & WAKE_LOCK_DRAW) != 0 && !mDrawWakeLockOverrideFromSidekick) {
                         if (displayPowerRequest.dozeScreenState == Display.STATE_DOZE_SUSPEND) {
                             displayPowerRequest.dozeScreenState = Display.STATE_DOZE;
                         }
@@ -3070,9 +3176,10 @@
                             + ", mWakefulness="
                             + PowerManagerInternal.wakefulnessToString(
                             mDisplayGroupPowerStateMapper.getWakefulnessLocked(groupId))
-                            + ", mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary)
+                            + ", mWakeLockSummary=0x" + Integer.toHexString(
+                            mDisplayGroupPowerStateMapper.getWakeLockSummaryLocked(groupId))
                             + ", mUserActivitySummary=0x" + Integer.toHexString(
-                            mUserActivitySummary)
+                            mDisplayGroupPowerStateMapper.getUserActivitySummaryLocked(groupId))
                             + ", mBootCompleted=" + mBootCompleted
                             + ", screenBrightnessOverride="
                             + displayPowerRequest.screenBrightnessOverride
@@ -3135,10 +3242,11 @@
     @VisibleForTesting
     int getDesiredScreenPolicyLocked(int groupId) {
         final int wakefulness = mDisplayGroupPowerStateMapper.getWakefulnessLocked(groupId);
+        final int wakeLockSummary = mDisplayGroupPowerStateMapper.getWakeLockSummaryLocked(groupId);
         if (wakefulness == WAKEFULNESS_ASLEEP || sQuiescent) {
             return DisplayPowerRequest.POLICY_OFF;
         } else if (wakefulness == WAKEFULNESS_DOZING) {
-            if ((mWakeLockSummary & WAKE_LOCK_DOZE) != 0) {
+            if ((wakeLockSummary & WAKE_LOCK_DOZE) != 0) {
                 return DisplayPowerRequest.POLICY_DOZE;
             }
             if (mDozeAfterScreenOff) {
@@ -3155,9 +3263,10 @@
             return DisplayPowerRequest.POLICY_VR;
         }
 
-        if ((mWakeLockSummary & WAKE_LOCK_SCREEN_BRIGHT) != 0
-                || (mUserActivitySummary & USER_ACTIVITY_SCREEN_BRIGHT) != 0
+        if ((wakeLockSummary & WAKE_LOCK_SCREEN_BRIGHT) != 0
                 || !mBootCompleted
+                || (mDisplayGroupPowerStateMapper.getUserActivitySummaryLocked(groupId)
+                & USER_ACTIVITY_SCREEN_BRIGHT) != 0
                 || mScreenBrightnessBoostInProgress) {
             return DisplayPowerRequest.POLICY_BRIGHT;
         }
@@ -3190,7 +3299,7 @@
             synchronized (mLock) {
                 mProximityPositive = false;
                 mDirty |= DIRTY_PROXIMITY_POSITIVE;
-                userActivityNoUpdateLocked(mClock.uptimeMillis(),
+                userActivityNoUpdateLocked(Display.DEFAULT_DISPLAY_GROUP, mClock.uptimeMillis(),
                         PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
                 updatePowerStateLocked();
             }
@@ -3233,7 +3342,9 @@
     };
 
     private boolean shouldUseProximitySensorLocked() {
-        return !mIsVrModeEnabled && (mWakeLockSummary & WAKE_LOCK_PROXIMITY_SCREEN_OFF) != 0;
+        // Use default display group for proximity sensor.
+        return !mIsVrModeEnabled && (mDisplayGroupPowerStateMapper.getWakeLockSummaryLocked(
+                Display.DEFAULT_DISPLAY_GROUP) & WAKE_LOCK_PROXIMITY_SCREEN_OFF) != 0;
     }
 
     /**
@@ -3758,7 +3869,7 @@
             mScreenBrightnessBoostInProgress = true;
             mDirty |= DIRTY_SCREEN_BRIGHTNESS_BOOST;
 
-            userActivityNoUpdateLocked(eventTime,
+            userActivityNoUpdateLocked(Display.DEFAULT_DISPLAY_GROUP, eventTime,
                     PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, uid);
             updatePowerStateLocked();
         }
@@ -3863,14 +3974,16 @@
     @VisibleForTesting
     boolean wasDeviceIdleForInternal(long ms) {
         synchronized (mLock) {
-            return mLastUserActivityTime + ms < mClock.uptimeMillis();
+            return mDisplayGroupPowerStateMapper.getLastUserActivityTimeLocked(
+                    Display.DEFAULT_DISPLAY_GROUP) + ms < mClock.uptimeMillis();
         }
     }
 
     @VisibleForTesting
     void onUserActivity() {
         synchronized (mLock) {
-            mLastUserActivityTime = mClock.uptimeMillis();
+            mDisplayGroupPowerStateMapper.setLastUserActivityTimeLocked(
+                    Display.DEFAULT_DISPLAY_GROUP, mClock.uptimeMillis());
         }
     }
 
@@ -4024,7 +4137,6 @@
                 TimeUtils.formatDuration(mNotifyLongNextCheck, mClock.uptimeMillis(), pw);
             }
             pw.println();
-            pw.println("  mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary));
             pw.println("  mRequestWaitForNegativeProximity=" + mRequestWaitForNegativeProximity);
             pw.println("  mSandmanScheduled=" + mSandmanScheduled);
             pw.println("  mBatteryLevelLow=" + mBatteryLevelLow);
@@ -4035,9 +4147,6 @@
             pw.println("  mLastWakeTime=" + TimeUtils.formatUptime(mLastWakeTime));
             pw.println("  mLastSleepTime=" + TimeUtils.formatUptime(mLastSleepTime));
             pw.println("  mLastSleepReason=" + PowerManager.sleepReasonToString(mLastSleepReason));
-            pw.println("  mLastUserActivityTime=" + TimeUtils.formatUptime(mLastUserActivityTime));
-            pw.println("  mLastUserActivityTimeNoChangeLights="
-                    + TimeUtils.formatUptime(mLastUserActivityTimeNoChangeLights));
             pw.println("  mLastInteractivePowerHintTime="
                     + TimeUtils.formatUptime(mLastInteractivePowerHintTime));
             pw.println("  mLastScreenBrightnessBoostTime="
@@ -4181,6 +4290,20 @@
                 pw.println(profile.mLockingNotified);
             }
 
+            pw.println("Display Group User Activity:");
+            for (int id : mDisplayGroupPowerStateMapper.getDisplayGroupIdsLocked()) {
+                pw.println("  displayGroupId=" + id);
+                pw.println("  userActivitySummary=0x" + Integer.toHexString(
+                        mDisplayGroupPowerStateMapper.getUserActivitySummaryLocked(id)));
+                pw.println("  lastUserActivityTime=" + TimeUtils.formatUptime(
+                        mDisplayGroupPowerStateMapper.getLastUserActivityTimeLocked(id)));
+                pw.println("  lastUserActivityTimeNoChangeLights=" + TimeUtils.formatUptime(
+                        mDisplayGroupPowerStateMapper.getLastUserActivityTimeNoChangeLightsLocked(
+                                id)));
+                pw.println("  mWakeLockSummary=0x" + Integer.toHexString(
+                        mDisplayGroupPowerStateMapper.getWakeLockSummaryLocked(id)));
+            }
+
             wcd = mWirelessChargerDetector;
         }
 
@@ -4266,17 +4389,27 @@
             proto.write(PowerManagerServiceDumpProto.NOTIFY_LONG_DISPATCHED_MS, mNotifyLongDispatched);
             proto.write(PowerManagerServiceDumpProto.NOTIFY_LONG_NEXT_CHECK_MS, mNotifyLongNextCheck);
 
-            final long userActivityToken = proto.start(PowerManagerServiceDumpProto.USER_ACTIVITY);
-            proto.write(
-                    PowerManagerServiceDumpProto.UserActivityProto.IS_SCREEN_BRIGHT,
-                    (mUserActivitySummary & USER_ACTIVITY_SCREEN_BRIGHT) != 0);
-            proto.write(
-                    PowerManagerServiceDumpProto.UserActivityProto.IS_SCREEN_DIM,
-                    (mUserActivitySummary & USER_ACTIVITY_SCREEN_DIM) != 0);
-            proto.write(
-                    PowerManagerServiceDumpProto.UserActivityProto.IS_SCREEN_DREAM,
-                    (mUserActivitySummary & USER_ACTIVITY_SCREEN_DREAM) != 0);
-            proto.end(userActivityToken);
+            for (int id : mDisplayGroupPowerStateMapper.getDisplayGroupIdsLocked()) {
+                final long userActivityToken = proto.start(
+                        PowerManagerServiceDumpProto.USER_ACTIVITY);
+                proto.write(PowerManagerServiceDumpProto.UserActivityProto.DISPLAY_GROUP_ID, id);
+                final long userActivitySummary =
+                        mDisplayGroupPowerStateMapper.getUserActivitySummaryLocked(id);
+                proto.write(PowerManagerServiceDumpProto.UserActivityProto.IS_SCREEN_BRIGHT,
+                        (userActivitySummary & USER_ACTIVITY_SCREEN_BRIGHT) != 0);
+                proto.write(PowerManagerServiceDumpProto.UserActivityProto.IS_SCREEN_DIM,
+                        (userActivitySummary & USER_ACTIVITY_SCREEN_DIM) != 0);
+                proto.write(PowerManagerServiceDumpProto.UserActivityProto.IS_SCREEN_DREAM,
+                        (userActivitySummary & USER_ACTIVITY_SCREEN_DREAM) != 0);
+                proto.write(
+                        PowerManagerServiceDumpProto.UserActivityProto.LAST_USER_ACTIVITY_TIME_MS,
+                        mDisplayGroupPowerStateMapper.getLastUserActivityTimeLocked(id));
+                proto.write(
+                        PowerManagerServiceDumpProto.UserActivityProto.LAST_USER_ACTIVITY_TIME_NO_CHANGE_LIGHTS_MS,
+                        mDisplayGroupPowerStateMapper.getLastUserActivityTimeNoChangeLightsLocked(
+                                id));
+                proto.end(userActivityToken);
+            }
 
             proto.write(
                     PowerManagerServiceDumpProto.IS_REQUEST_WAIT_FOR_NEGATIVE_PROXIMITY,
@@ -4295,10 +4428,6 @@
 
             proto.write(PowerManagerServiceDumpProto.LAST_WAKE_TIME_MS, mLastWakeTime);
             proto.write(PowerManagerServiceDumpProto.LAST_SLEEP_TIME_MS, mLastSleepTime);
-            proto.write(PowerManagerServiceDumpProto.LAST_USER_ACTIVITY_TIME_MS, mLastUserActivityTime);
-            proto.write(
-                    PowerManagerServiceDumpProto.LAST_USER_ACTIVITY_TIME_NO_CHANGE_LIGHTS_MS,
-                    mLastUserActivityTimeNoChangeLights);
             proto.write(
                     PowerManagerServiceDumpProto.LAST_INTERACTIVE_POWER_HINT_TIME_MS,
                     mLastInteractivePowerHintTime);
@@ -4663,6 +4792,7 @@
      */
     /* package */ final class WakeLock implements IBinder.DeathRecipient {
         public final IBinder mLock;
+        public final int mDisplayId;
         public int mFlags;
         public String mTag;
         public final String mPackageName;
@@ -4676,10 +4806,11 @@
         public boolean mNotifiedLong;
         public boolean mDisabled;
 
-        public WakeLock(IBinder lock, int flags, String tag, String packageName,
+        public WakeLock(IBinder lock, int displayId, int flags, String tag, String packageName,
                 WorkSource workSource, String historyTag, int ownerUid, int ownerPid,
                 UidState uidState) {
             mLock = lock;
+            mDisplayId = displayId;
             mFlags = flags;
             mTag = tag;
             mPackageName = packageName;
@@ -4732,6 +4863,15 @@
             mWorkSource = copyWorkSource(workSource);
         }
 
+        public int getDisplayGroupId() {
+            if (!mSystemReady || mDisplayId == Display.INVALID_DISPLAY) {
+                return Display.INVALID_DISPLAY_GROUP;
+            }
+
+            final DisplayInfo displayInfo = mDisplayManagerInternal.getDisplayInfo(mDisplayId);
+            return displayInfo == null ? Display.INVALID_DISPLAY_GROUP : displayInfo.displayGroupId;
+        }
+
         @Override
         public String toString() {
             StringBuilder sb = new StringBuilder();
@@ -4921,11 +5061,11 @@
 
         @Override // Binder call
         public void acquireWakeLockWithUid(IBinder lock, int flags, String tag,
-                String packageName, int uid) {
+                String packageName, int uid, int displayId) {
             if (uid < 0) {
                 uid = Binder.getCallingUid();
             }
-            acquireWakeLock(lock, flags, tag, packageName, new WorkSource(uid), null);
+            acquireWakeLock(lock, flags, tag, packageName, new WorkSource(uid), null, displayId);
         }
 
         @Override // Binder call
@@ -4960,7 +5100,7 @@
 
         @Override // Binder call
         public void acquireWakeLock(IBinder lock, int flags, String tag, String packageName,
-                WorkSource ws, String historyTag) {
+                WorkSource ws, String historyTag, int displayId) {
             if (lock == null) {
                 throw new IllegalArgumentException("lock must not be null");
             }
@@ -4985,7 +5125,8 @@
             final int pid = Binder.getCallingPid();
             final long ident = Binder.clearCallingIdentity();
             try {
-                acquireWakeLockInternal(lock, flags, tag, packageName, ws, historyTag, uid, pid);
+                acquireWakeLockInternal(lock, displayId, flags, tag, packageName, ws, historyTag,
+                        uid, pid);
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
@@ -4994,7 +5135,7 @@
         @Override // Binder call
         public void acquireWakeLockAsync(IBinder lock, int flags, String tag, String packageName,
                 WorkSource ws, String historyTag) {
-            acquireWakeLock(lock, flags, tag, packageName, ws, historyTag);
+            acquireWakeLock(lock, flags, tag, packageName, ws, historyTag, Display.INVALID_DISPLAY);
         }
 
         @Override // Binder call
@@ -5102,7 +5243,7 @@
             final int uid = Binder.getCallingUid();
             final long ident = Binder.clearCallingIdentity();
             try {
-                userActivityInternal(eventTime, event, flags, uid);
+                userActivityInternal(displayId, eventTime, event, flags, uid);
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
diff --git a/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java
index beebb31..fe21201 100644
--- a/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java
+++ b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java
@@ -21,11 +21,13 @@
 import android.annotation.IntDef;
 import android.content.Context;
 import android.content.IntentSender;
+import android.content.SharedPreferences;
 import android.content.pm.PackageManager;
 import android.hardware.boot.V1_0.IBootControl;
 import android.net.LocalSocket;
 import android.net.LocalSocketAddress;
 import android.os.Binder;
+import android.os.Environment;
 import android.os.IRecoverySystem;
 import android.os.IRecoverySystemProgressListener;
 import android.os.PowerManager;
@@ -52,6 +54,7 @@
 
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
+import java.io.File;
 import java.io.FileDescriptor;
 import java.io.FileWriter;
 import java.io.IOException;
@@ -87,6 +90,12 @@
 
     private static final int SOCKET_CONNECTION_MAX_RETRY = 30;
 
+    static final String REQUEST_LSKF_TIMESTAMP_PREF_SUFFIX = "_request_lskf_timestamp";
+    static final String REQUEST_LSKF_COUNT_PREF_SUFFIX = "_request_lskf_count";
+
+    static final String LSKF_CAPTURED_TIMESTAMP_PREF = "lskf_captured_timestamp";
+    static final String LSKF_CAPTURED_COUNT_PREF = "lskf_captured_count";
+
     private final Injector mInjector;
     private final Context mContext;
 
@@ -127,7 +136,7 @@
      */
     @IntDef({ ROR_NEED_PREPARATION,
             ROR_SKIP_PREPARATION_AND_NOTIFY,
-            ROR_SKIP_PREPARATION_NOT_NOTIFY })
+            ROR_SKIP_PREPARATION_NOT_NOTIFY})
     private @interface ResumeOnRebootActionsOnRequest {}
 
     /**
@@ -139,7 +148,7 @@
     private @interface ResumeOnRebootActionsOnClear {}
 
     /**
-     * The error code for reboots initiated by resume on reboot clients.
+     * The error codes for reboots initiated by resume on reboot clients.
      */
     private static final int REBOOT_ERROR_NONE = 0;
     private static final int REBOOT_ERROR_UNKNOWN = 1;
@@ -156,11 +165,64 @@
             REBOOT_ERROR_ARM_REBOOT_ESCROW_FAILURE})
     private @interface ResumeOnRebootRebootErrorCode {}
 
+    /**
+     * Manages shared preference, i.e. the storage used for metrics reporting.
+     */
+    public static class PreferencesManager {
+        private static final String METRICS_DIR = "recovery_system";
+        private static final String METRICS_PREFS_FILE = "RecoverySystemMetricsPrefs.xml";
+
+        protected final SharedPreferences mSharedPreferences;
+        private final File mMetricsPrefsFile;
+
+        PreferencesManager(Context context) {
+            File prefsDir = new File(Environment.getDataSystemCeDirectory(USER_SYSTEM),
+                    METRICS_DIR);
+            mMetricsPrefsFile = new File(prefsDir, METRICS_PREFS_FILE);
+            mSharedPreferences = context.getSharedPreferences(mMetricsPrefsFile, 0);
+        }
+
+        /** Reads the value of a given key with type long. **/
+        public long getLong(String key, long defaultValue) {
+            return mSharedPreferences.getLong(key, defaultValue);
+        }
+
+        /** Reads the value of a given key with type int. **/
+        public int getInt(String key, int defaultValue) {
+            return mSharedPreferences.getInt(key, defaultValue);
+        }
+
+        /** Stores the value of a given key with type long. **/
+        public void putLong(String key, long value) {
+            mSharedPreferences.edit().putLong(key, value).commit();
+        }
+
+        /** Stores the value of a given key with type int. **/
+        public void putInt(String key, int value) {
+            mSharedPreferences.edit().putInt(key, value).commit();
+        }
+
+        /** Increments the value of a given key with type int. **/
+        public synchronized void incrementIntKey(String key, int defaultInitialValue) {
+            int oldValue = getInt(key, defaultInitialValue);
+            putInt(key, oldValue + 1);
+        }
+
+        /** Delete the preference file and cleanup all metrics storage. **/
+        public void deletePrefsFile() {
+            if (!mMetricsPrefsFile.delete()) {
+                Slog.w(TAG, "Failed to delete metrics prefs");
+            }
+        }
+    }
+
     static class Injector {
         protected final Context mContext;
+        protected final PreferencesManager mPrefs;
 
         Injector(Context context) {
             mContext = context;
+            mPrefs = new PreferencesManager(context);
         }
 
         public Context getContext() {
@@ -236,6 +298,14 @@
             return -1;
         }
 
+        public PreferencesManager getMetricsPrefs() {
+            return mPrefs;
+        }
+
+        public long getCurrentTimeMillis() {
+            return System.currentTimeMillis();
+        }
+
         public void reportRebootEscrowPreparationMetrics(int uid,
                 @ResumeOnRebootActionsOnRequest int requestResult, int requestedClientCount) {
             FrameworkStatsLog.write(FrameworkStatsLog.REBOOT_ESCROW_PREPARATION_REPORTED, uid,
@@ -414,7 +484,7 @@
         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.RECOVERY)
                 != PackageManager.PERMISSION_GRANTED
                 && mContext.checkCallingOrSelfPermission(android.Manifest.permission.REBOOT)
-                        != PackageManager.PERMISSION_GRANTED) {
+                    != PackageManager.PERMISSION_GRANTED) {
             throw new SecurityException("Caller must have " + android.Manifest.permission.RECOVERY
                     + " or " + android.Manifest.permission.REBOOT + " for resume on reboot.");
         }
@@ -427,6 +497,12 @@
             pendingRequestCount = mCallerPendingRequest.size();
         }
 
+        // Save the timestamp and request count for new ror request
+        PreferencesManager prefs = mInjector.getMetricsPrefs();
+        prefs.putLong(packageName + REQUEST_LSKF_TIMESTAMP_PREF_SUFFIX,
+                mInjector.getCurrentTimeMillis());
+        prefs.incrementIntKey(packageName + REQUEST_LSKF_COUNT_PREF_SUFFIX, 0);
+
         mInjector.reportRebootEscrowPreparationMetrics(uid, requestResult, pendingRequestCount);
     }
 
@@ -486,15 +562,31 @@
     }
 
     private void reportMetricsOnPreparedForReboot() {
+        long currentTimestamp = mInjector.getCurrentTimeMillis();
+
         List<String> preparedClients;
         synchronized (this) {
             preparedClients = new ArrayList<>(mCallerPreparedForReboot);
         }
 
+        // Save the timestamp & lskf capture count for lskf capture
+        PreferencesManager prefs = mInjector.getMetricsPrefs();
+        prefs.putLong(LSKF_CAPTURED_TIMESTAMP_PREF, currentTimestamp);
+        prefs.incrementIntKey(LSKF_CAPTURED_COUNT_PREF, 0);
+
         for (String packageName : preparedClients) {
             int uid = mInjector.getUidFromPackageName(packageName);
+
+            int durationSeconds = -1;
+            long requestLskfTimestamp = prefs.getLong(
+                    packageName + REQUEST_LSKF_TIMESTAMP_PREF_SUFFIX, -1);
+            if (requestLskfTimestamp != -1 && currentTimestamp > requestLskfTimestamp) {
+                durationSeconds = (int) (currentTimestamp - requestLskfTimestamp) / 1000;
+            }
+            Slog.i(TAG, String.format("Reporting lskf captured, lskf capture takes %d seconds for"
+                    + " package %s", durationSeconds, packageName));
             mInjector.reportRebootEscrowLskfCapturedMetrics(uid, preparedClients.size(),
-                    -1 /* duration */);
+                    durationSeconds);
         }
     }
 
@@ -541,6 +633,7 @@
             Slog.w(TAG, "Missing packageName when clearing lskf.");
             return false;
         }
+        // TODO(179105110) Clear the RoR metrics for the given packageName.
 
         @ResumeOnRebootActionsOnClear int action = updateRoRPreparationStateOnClear(packageName);
         switch (action) {
@@ -641,7 +734,15 @@
             return REBOOT_ERROR_SLOT_MISMATCH;
         }
 
-        if (!mInjector.getLockSettingsService().armRebootEscrow()) {
+        final long origId = Binder.clearCallingIdentity();
+        boolean result;
+        try {
+            result = mInjector.getLockSettingsService().armRebootEscrow();
+        } finally {
+            Binder.restoreCallingIdentity(origId);
+        }
+
+        if (!result) {
             Slog.w(TAG, "Failure to escrow key for reboot");
             return REBOOT_ERROR_ARM_REBOOT_ESCROW_FAILURE;
         }
@@ -649,20 +750,42 @@
         return REBOOT_ERROR_NONE;
     }
 
+    private boolean useServerBasedRoR() {
+        final long origId = Binder.clearCallingIdentity();
+        try {
+            return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_OTA,
+                    "server_based_ror_enabled", false);
+        } finally {
+            Binder.restoreCallingIdentity(origId);
+        }
+    }
+
     private void reportMetricsOnRebootWithLskf(String packageName, boolean slotSwitch,
             @ResumeOnRebootRebootErrorCode int errorCode) {
         int uid = mInjector.getUidFromPackageName(packageName);
-        boolean serverBased = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_OTA,
-                "server_based_ror_enabled", false);
+        boolean serverBased = useServerBasedRoR();
         int preparedClientCount;
         synchronized (this) {
             preparedClientCount = mCallerPreparedForReboot.size();
         }
 
-        // TODO(b/179105110) report the true value of duration and counts
+        long currentTimestamp = mInjector.getCurrentTimeMillis();
+        int durationSeconds = -1;
+        PreferencesManager prefs = mInjector.getMetricsPrefs();
+        long lskfCapturedTimestamp = prefs.getLong(LSKF_CAPTURED_TIMESTAMP_PREF, -1);
+        if (lskfCapturedTimestamp != -1 && currentTimestamp > lskfCapturedTimestamp) {
+            durationSeconds = (int) (currentTimestamp - lskfCapturedTimestamp) / 1000;
+        }
+
+        int requestCount = prefs.getInt(packageName + REQUEST_LSKF_COUNT_PREF_SUFFIX, -1);
+        int lskfCapturedCount = prefs.getInt(LSKF_CAPTURED_COUNT_PREF, -1);
+
+        Slog.i(TAG, String.format("Reporting reboot with lskf, package name %s, client count %d,"
+                        + " request count %d, lskf captured count %d, duration since lskf captured"
+                        + " %d seconds.", packageName, preparedClientCount, requestCount,
+                lskfCapturedCount, durationSeconds));
         mInjector.reportRebootEscrowRebootMetrics(errorCode, uid, preparedClientCount,
-                1 /* request count */, slotSwitch, serverBased,
-                -1 /* duration */, 1 /* lskf capture count */);
+                requestCount, slotSwitch, serverBased, durationSeconds, lskfCapturedCount);
     }
 
     private boolean rebootWithLskfImpl(String packageName, String reason, boolean slotSwitch) {
@@ -673,6 +796,9 @@
             return false;
         }
 
+        // Clear the metrics prefs after a successful RoR reboot.
+        mInjector.getMetricsPrefs().deletePrefsFile();
+
         PowerManager pm = mInjector.getPowerManager();
         pm.reboot(reason);
         return true;
diff --git a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
index a4459d0..4adcfb6 100644
--- a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
+++ b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
@@ -615,7 +615,7 @@
                 if (session == null || session.isStagedSessionFailed()) {
                     iter.remove();
                     deleteRollback(rollback,
-                            "Session " + session.getSessionId() + " not existed or failed");
+                            "Session " + rollback.getStagedSessionId() + " not existed or failed");
                     continue;
                 }
 
diff --git a/services/core/java/com/android/server/rotationresolver/RotationResolverManagerService.java b/services/core/java/com/android/server/rotationresolver/RotationResolverManagerService.java
index a7f3cdb..c029bf5 100644
--- a/services/core/java/com/android/server/rotationresolver/RotationResolverManagerService.java
+++ b/services/core/java/com/android/server/rotationresolver/RotationResolverManagerService.java
@@ -28,6 +28,7 @@
 import android.annotation.NonNull;
 import android.annotation.UserIdInt;
 import android.content.Context;
+import android.hardware.SensorPrivacyManager;
 import android.os.Binder;
 import android.os.CancellationSignal;
 import android.os.ResultReceiver;
@@ -79,6 +80,7 @@
             FrameworkStatsLog.AUTO_ROTATE_REPORTED__PROPOSED_ORIENTATION__FAILURE;
 
     private final Context mContext;
+    private final SensorPrivacyManager mPrivacyManager;
     boolean mIsServiceEnabled;
 
     public RotationResolverManagerService(Context context) {
@@ -89,6 +91,7 @@
                 PACKAGE_UPDATE_POLICY_REFRESH_EAGER
                         | /*To avoid high rotation latency*/ PACKAGE_RESTART_POLICY_REFRESH_EAGER);
         mContext = context;
+        mPrivacyManager = SensorPrivacyManager.getInstance(context);
     }
 
     @Override
@@ -156,15 +159,22 @@
             Objects.requireNonNull(callbackInternal);
             Objects.requireNonNull(cancellationSignalInternal);
             synchronized (mLock) {
-                if (mIsServiceEnabled) {
-                    final RotationResolverManagerPerUserService service = getServiceForUserLocked(
-                            UserHandle.getCallingUserId());
+                final boolean isCameraAvailable = !mPrivacyManager.isSensorPrivacyEnabled(
+                        SensorPrivacyManager.Sensors.CAMERA);
+                if (mIsServiceEnabled && isCameraAvailable) {
+                    final RotationResolverManagerPerUserService service =
+                            getServiceForUserLocked(
+                                    UserHandle.getCallingUserId());
                     final RotationResolutionRequest request = new RotationResolutionRequest("",
                             currentRotation, proposedRotation, true, timeout);
                     service.resolveRotationLocked(callbackInternal, request,
                             cancellationSignalInternal);
                 } else {
-                    Slog.w(TAG, "Rotation Resolver service is disabled.");
+                    if (isCameraAvailable) {
+                        Slog.w(TAG, "Rotation Resolver service is disabled.");
+                    } else {
+                        Slog.w(TAG, "Camera is locked by a toggle.");
+                    }
                     callbackInternal.onFailure(ROTATION_RESULT_FAILURE_CANCELLED);
                     logRotationStats(proposedRotation, currentRotation, RESOLUTION_DISABLED);
                 }
diff --git a/services/core/java/com/android/server/servicewatcher/CurrentUserServiceSupplier.java b/services/core/java/com/android/server/servicewatcher/CurrentUserServiceSupplier.java
new file mode 100644
index 0000000..3ca8a5a
--- /dev/null
+++ b/services/core/java/com/android/server/servicewatcher/CurrentUserServiceSupplier.java
@@ -0,0 +1,302 @@
+/*
+ * 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.servicewatcher;
+
+import static android.content.pm.PackageManager.GET_META_DATA;
+import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AUTO;
+import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
+import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
+import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.os.UserHandle.USER_SYSTEM;
+
+import android.annotation.BoolRes;
+import android.annotation.Nullable;
+import android.annotation.StringRes;
+import android.app.ActivityManagerInternal;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.os.UserHandle;
+import android.permission.PermissionManager;
+import android.util.Log;
+
+import com.android.internal.util.Preconditions;
+import com.android.server.FgThread;
+import com.android.server.LocalServices;
+import com.android.server.servicewatcher.ServiceWatcher.ServiceChangedListener;
+import com.android.server.servicewatcher.ServiceWatcher.ServiceSupplier;
+
+import java.util.Comparator;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Supplies services based on the current active user and version as defined in the service
+ * manifest. This implementation uses {@link android.content.pm.PackageManager#MATCH_SYSTEM_ONLY} to
+ * ensure only system (ie, privileged) services are matched. It also handles services that are not
+ * direct boot aware, and will automatically pick the best service as the user's direct boot state
+ * changes.
+ *
+ * <p>Optionally, two permissions may be specified: (1) a caller permission - any service that does
+ * not require callers to hold this permission is rejected (2) a service permission - any service
+ * whose package does not hold this permission is rejected.
+ */
+public class CurrentUserServiceSupplier extends BroadcastReceiver implements
+        ServiceSupplier<CurrentUserServiceSupplier.BoundServiceInfo> {
+
+    private static final String TAG = "CurrentUserServiceSupplier";
+
+    private static final String EXTRA_SERVICE_VERSION = "serviceVersion";
+    private static final String EXTRA_SERVICE_IS_MULTIUSER = "serviceIsMultiuser";
+
+    private static final Comparator<BoundServiceInfo> sBoundServiceInfoComparator = (o1, o2) -> {
+        if (o1 == o2) {
+            return 0;
+        } else if (o1 == null) {
+            return -1;
+        } else if (o2 == null) {
+            return 1;
+        }
+
+        // ServiceInfos with higher version numbers always win. if version numbers are equal
+        // then we prefer components that work for all users vs components that only work for a
+        // single user at a time. otherwise everything's equal.
+        int ret = Integer.compare(o1.getVersion(), o2.getVersion());
+        if (ret == 0) {
+            if (o1.getUserId() != USER_SYSTEM && o2.getUserId() == USER_SYSTEM) {
+                ret = -1;
+            } else if (o1.getUserId() == USER_SYSTEM && o2.getUserId() != USER_SYSTEM) {
+                ret = 1;
+            }
+        }
+        return ret;
+    };
+
+    /** Bound service information with version information. */
+    public static class BoundServiceInfo extends ServiceWatcher.BoundServiceInfo {
+
+        private static int parseUid(ResolveInfo resolveInfo) {
+            int uid = resolveInfo.serviceInfo.applicationInfo.uid;
+            Bundle metadata = resolveInfo.serviceInfo.metaData;
+            if (metadata != null && metadata.getBoolean(EXTRA_SERVICE_IS_MULTIUSER, false)) {
+                // reconstruct a uid for the same app but with the system user - hope this exists
+                uid = UserHandle.getUid(USER_SYSTEM, UserHandle.getAppId(uid));
+            }
+            return uid;
+        }
+
+        private static int parseVersion(ResolveInfo resolveInfo) {
+            int version = Integer.MIN_VALUE;
+            if (resolveInfo.serviceInfo.metaData != null) {
+                version = resolveInfo.serviceInfo.metaData.getInt(EXTRA_SERVICE_VERSION, version);
+            }
+            return version;
+        }
+
+        private final int mVersion;
+        private final @Nullable Bundle mMetadata;
+
+        protected BoundServiceInfo(String action, ResolveInfo resolveInfo) {
+            this(action, parseUid(resolveInfo), resolveInfo.serviceInfo.getComponentName(),
+                    parseVersion(resolveInfo), resolveInfo.serviceInfo.metaData);
+        }
+
+        protected BoundServiceInfo(String action, int uid, ComponentName componentName, int version,
+                @Nullable Bundle metadata) {
+            super(action, uid, componentName);
+
+            mVersion = version;
+            mMetadata = metadata;
+        }
+
+        public int getVersion() {
+            return mVersion;
+        }
+
+        public @Nullable Bundle getMetadata() {
+            return mMetadata;
+        }
+
+        @Override
+        public String toString() {
+            return super.toString() + "@" + mVersion;
+        }
+    }
+
+    private static @Nullable String retrieveExplicitPackage(Context context,
+            @BoolRes int enableOverlayResId, @StringRes int nonOverlayPackageResId) {
+        Resources resources = context.getResources();
+        boolean enableOverlay = resources.getBoolean(enableOverlayResId);
+        if (!enableOverlay) {
+            return resources.getString(nonOverlayPackageResId);
+        } else {
+            return null;
+        }
+    }
+
+    private final Context mContext;
+    private final ActivityManagerInternal mActivityManager;
+    private final Intent mIntent;
+    // a permission that the service forces callers (ie ServiceWatcher/system server) to hold
+    private final @Nullable String mCallerPermission;
+    // a permission that the service package should hold
+    private final @Nullable String mServicePermission;
+
+    private volatile ServiceChangedListener mListener;
+
+    public CurrentUserServiceSupplier(Context context, String action) {
+        this(context, action, null, null, null);
+    }
+
+    public CurrentUserServiceSupplier(Context context, String action,
+            @BoolRes int enableOverlayResId, @StringRes int nonOverlayPackageResId) {
+        this(context, action,
+                retrieveExplicitPackage(context, enableOverlayResId, nonOverlayPackageResId), null,
+                null);
+    }
+
+    public CurrentUserServiceSupplier(Context context, String action,
+            @BoolRes int enableOverlayResId, @StringRes int nonOverlayPackageResId,
+            @Nullable String callerPermission, @Nullable String servicePermission) {
+        this(context, action,
+                retrieveExplicitPackage(context, enableOverlayResId, nonOverlayPackageResId),
+                callerPermission, servicePermission);
+    }
+
+    public CurrentUserServiceSupplier(Context context, String action,
+            @Nullable String explicitPackage, @Nullable String callerPermission,
+            @Nullable String servicePermission) {
+        mContext = context;
+        mActivityManager = Objects.requireNonNull(
+                LocalServices.getService(ActivityManagerInternal.class));
+        mIntent = new Intent(action);
+
+        if (explicitPackage != null) {
+            mIntent.setPackage(explicitPackage);
+        }
+
+        mCallerPermission = callerPermission;
+        mServicePermission = servicePermission;
+    }
+
+    @Override
+    public boolean hasMatchingService() {
+        List<ResolveInfo> resolveInfos = mContext.getPackageManager()
+                .queryIntentServicesAsUser(mIntent,
+                        MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE | MATCH_SYSTEM_ONLY,
+                        UserHandle.USER_SYSTEM);
+        return !resolveInfos.isEmpty();
+    }
+
+    @Override
+    public void register(ServiceChangedListener listener) {
+        Preconditions.checkState(mListener == null);
+
+        mListener = listener;
+
+        IntentFilter intentFilter = new IntentFilter();
+        intentFilter.addAction(Intent.ACTION_USER_SWITCHED);
+        intentFilter.addAction(Intent.ACTION_USER_UNLOCKED);
+        mContext.registerReceiverAsUser(this, UserHandle.ALL, intentFilter, null,
+                FgThread.getHandler());
+    }
+
+    @Override
+    public void unregister() {
+        Preconditions.checkArgument(mListener != null);
+
+        mListener = null;
+        mContext.unregisterReceiver(this);
+    }
+
+    @Override
+    public BoundServiceInfo getServiceInfo() {
+        BoundServiceInfo bestServiceInfo = null;
+
+        // only allow privileged services in the correct direct boot state to match
+        int currentUserId = mActivityManager.getCurrentUserId();
+        List<ResolveInfo> resolveInfos = mContext.getPackageManager().queryIntentServicesAsUser(
+                mIntent,
+                GET_META_DATA | MATCH_DIRECT_BOOT_AUTO | MATCH_SYSTEM_ONLY,
+                currentUserId);
+        for (ResolveInfo resolveInfo : resolveInfos) {
+            ServiceInfo service = Objects.requireNonNull(resolveInfo.serviceInfo);
+
+            if (mCallerPermission != null) {
+                if (!mCallerPermission.equals(service.permission)) {
+                    Log.d(TAG, service.getComponentName().flattenToShortString()
+                            + " disqualified due to not requiring " + mCallerPermission);
+                    continue;
+                }
+            }
+
+            BoundServiceInfo serviceInfo = new BoundServiceInfo(mIntent.getAction(), resolveInfo);
+
+            if (mServicePermission != null) {
+                if (PermissionManager.checkPackageNamePermission(mServicePermission,
+                        service.packageName, serviceInfo.getUserId()) != PERMISSION_GRANTED) {
+                    Log.d(TAG, serviceInfo.getComponentName().flattenToShortString()
+                            + " disqualified due to not holding " + mCallerPermission);
+                    continue;
+                }
+            }
+
+            if (sBoundServiceInfoComparator.compare(serviceInfo, bestServiceInfo) > 0) {
+                bestServiceInfo = serviceInfo;
+            }
+        }
+
+        return bestServiceInfo;
+    }
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        String action = intent.getAction();
+        if (action == null) {
+            return;
+        }
+        int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
+        if (userId == UserHandle.USER_NULL) {
+            return;
+        }
+        ServiceChangedListener listener = mListener;
+        if (listener == null) {
+            return;
+        }
+
+        switch (action) {
+            case Intent.ACTION_USER_SWITCHED:
+                listener.onServiceChanged();
+                break;
+            case Intent.ACTION_USER_UNLOCKED:
+                // user unlocked implies direct boot mode may have changed
+                if (userId == mActivityManager.getCurrentUserId()) {
+                    listener.onServiceChanged();
+                }
+                break;
+            default:
+                break;
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/servicewatcher/ServiceWatcher.java b/services/core/java/com/android/server/servicewatcher/ServiceWatcher.java
index 5d49663..030bbd2 100644
--- a/services/core/java/com/android/server/servicewatcher/ServiceWatcher.java
+++ b/services/core/java/com/android/server/servicewatcher/ServiceWatcher.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 The Android Open Source Project
+ * 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.
@@ -16,516 +16,244 @@
 
 package com.android.server.servicewatcher;
 
-import static android.content.Context.BIND_AUTO_CREATE;
-import static android.content.Context.BIND_NOT_FOREGROUND;
-import static android.content.Context.BIND_NOT_VISIBLE;
-import static android.content.pm.PackageManager.GET_META_DATA;
-import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AUTO;
-import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
-import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
-import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
-
-import android.annotation.BoolRes;
-import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.annotation.StringRes;
 import android.annotation.UserIdInt;
-import android.app.ActivityManager;
-import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.ServiceConnection;
 import android.content.pm.ResolveInfo;
-import android.content.res.Resources;
-import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
-import android.os.Looper;
 import android.os.RemoteException;
 import android.os.UserHandle;
-import android.util.ArrayMap;
-import android.util.Log;
 
-import com.android.internal.annotations.Immutable;
-import com.android.internal.content.PackageMonitor;
-import com.android.internal.util.Preconditions;
-import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.server.FgThread;
 
-import java.io.FileDescriptor;
 import java.io.PrintWriter;
-import java.util.List;
-import java.util.Map;
 import java.util.Objects;
-import java.util.function.Predicate;
 
 /**
- * Maintains a binding to the best service that matches the given intent information. Bind and
- * unbind callbacks, as well as all binder operations, will all be run on a single thread.
+ * A ServiceWatcher is responsible for continuously maintaining an active binding to a service
+ * selected by it's {@link ServiceSupplier}. The {@link ServiceSupplier} may change the service it
+ * selects over time, and the currently bound service may crash, restart, have a user change, have
+ * changes made to its package, and so on and so forth. The ServiceWatcher is responsible for
+ * maintaining the binding across all these changes.
+ *
+ * <p>Clients may invoke {@link BinderOperation}s on the ServiceWatcher, and it will make a best
+ * effort to run these on the currently bound service, but individual operations may fail (if there
+ * is no service currently bound for instance). In order to help clients maintain the correct state,
+ * clients may supply a {@link ServiceListener}, which is informed when the ServiceWatcher connects
+ * and disconnects from a service. This allows clients to bring a bound service back into a known
+ * state on connection, and then run binder operations from there. In order to help clients
+ * accomplish this, ServiceWatcher guarantees that {@link BinderOperation}s and the
+ * {@link ServiceListener} will always be run on the same thread, so that strong ordering guarantees
+ * can be established between them.
+ *
+ * There is never any guarantee of whether a ServiceWatcher is currently connected to a service, and
+ * whether any particular {@link BinderOperation} will succeed. Clients must ensure they do not rely
+ * on this, and instead use {@link ServiceListener} notifications as necessary to recover from
+ * failures.
  */
-public class ServiceWatcher implements ServiceConnection {
+public interface ServiceWatcher {
 
-    private static final String TAG = "ServiceWatcher";
-    private static final boolean D = Log.isLoggable(TAG, Log.DEBUG);
-
-    private static final String EXTRA_SERVICE_VERSION = "serviceVersion";
-    private static final String EXTRA_SERVICE_IS_MULTIUSER = "serviceIsMultiuser";
-
-    private static final long RETRY_DELAY_MS = 15 * 1000;
-
-    private static final Predicate<ResolveInfo> DEFAULT_SERVICE_CHECK_PREDICATE = x -> true;
-
-    /** Function to run on binder interface. */
-    public interface BinderRunner {
-        /** Called to run client code with the binder. */
+    /**
+     * Operation to run on a binder interface. All operations will be run on the thread used by the
+     * ServiceWatcher this is run with.
+     */
+    interface BinderOperation {
+        /** Invoked to run the operation. Run on the ServiceWatcher thread. */
         void run(IBinder binder) throws RemoteException;
+
         /**
-         * Called if an error occurred and the function could not be run. This callback is only
-         * intended for resource deallocation and cleanup in response to a single binder operation,
-         * it should not be used to propagate errors further.
+         * Invoked if {@link #run(IBinder)} could not be invoked because there was no current
+         * binding, or if {@link #run(IBinder)} threw an exception ({@link RemoteException} or
+         * {@link RuntimeException}). This callback is only intended for resource deallocation and
+         * cleanup in response to a single binder operation, it should not be used to propagate
+         * errors further. Run on the ServiceWatcher thread.
          */
         default void onError() {}
     }
 
-    /** Function to run on binder interface when first bound. */
-    public interface OnBindRunner {
-        /** Called to run client code with the binder. */
-        void run(IBinder binder, BoundService service) throws RemoteException;
+    /**
+     * Listener for bind and unbind events. All operations will be run on the thread used by the
+     * ServiceWatcher this is run with.
+     *
+     * @param <TBoundServiceInfo> type of bound service
+     */
+    interface ServiceListener<TBoundServiceInfo extends BoundServiceInfo> {
+        /** Invoked when a service is bound. Run on the ServiceWatcher thread. */
+        void onBind(IBinder binder, TBoundServiceInfo service) throws RemoteException;
+
+        /** Invoked when a service is unbound. Run on the ServiceWatcher thread. */
+        void onUnbind();
     }
 
     /**
-     * Information on the service ServiceWatcher has selected as the best option for binding.
+     * A listener for when a {@link ServiceSupplier} decides that the current service has changed.
      */
-    @Immutable
-    public static final class BoundService implements Comparable<BoundService> {
+    interface ServiceChangedListener {
+        /**
+         * Should be invoked when the current service may have changed.
+         */
+        void onServiceChanged();
+    }
 
-        public static final BoundService NONE = new BoundService(Integer.MIN_VALUE, null,
-                false, null, -1);
+    /**
+     * This supplier encapsulates the logic of deciding what service a {@link ServiceWatcher} should
+     * be bound to at any given moment.
+     *
+     * @param <TBoundServiceInfo> type of bound service
+     */
+    interface ServiceSupplier<TBoundServiceInfo extends BoundServiceInfo> {
+        /**
+         * Should return true if there exists at least one service capable of meeting the criteria
+         * of this supplier. This does not imply that {@link #getServiceInfo()} will always return a
+         * non-null result, as any service may be disqualified for various reasons at any point in
+         * time. May be invoked at any time from any thread and thus should generally not have any
+         * dependency on the other methods in this interface.
+         */
+        boolean hasMatchingService();
 
-        public final int version;
-        @Nullable
-        public final ComponentName component;
-        public final boolean serviceIsMultiuser;
-        public final int uid;
-        @Nullable
-        public final Bundle metadata;
+        /**
+         * Invoked when the supplier should start monitoring for any changes that could result in a
+         * different service selection, and should invoke
+         * {@link ServiceChangedListener#onServiceChanged()} in that case. {@link #getServiceInfo()}
+         * may be invoked after this method is called.
+         */
+        void register(ServiceChangedListener listener);
 
-        BoundService(ResolveInfo resolveInfo) {
-            Preconditions.checkArgument(resolveInfo.serviceInfo.getComponentName() != null);
+        /**
+         * Invoked when the supplier should stop monitoring for any changes that could result in a
+         * different service selection, should no longer invoke
+         * {@link ServiceChangedListener#onServiceChanged()}. {@link #getServiceInfo()} will not be
+         * invoked after this method is called.
+         */
+        void unregister();
 
-            metadata = resolveInfo.serviceInfo.metaData;
-            if (metadata != null) {
-                version = metadata.getInt(EXTRA_SERVICE_VERSION, Integer.MIN_VALUE);
-                serviceIsMultiuser = metadata.getBoolean(EXTRA_SERVICE_IS_MULTIUSER, false);
-            } else {
-                version = Integer.MIN_VALUE;
-                serviceIsMultiuser = false;
-            }
+        /**
+         * Must be implemented to return the current service selected by this supplier. May return
+         * null if no service currently meets the criteria. Only invoked while registered.
+         */
+        @Nullable TBoundServiceInfo getServiceInfo();
+    }
 
-            component = resolveInfo.serviceInfo.getComponentName();
-            uid = resolveInfo.serviceInfo.applicationInfo.uid;
+    /**
+     * Information on the service selected as the best option for binding.
+     */
+    class BoundServiceInfo {
+
+        protected final @Nullable String mAction;
+        protected final int mUid;
+        protected final ComponentName mComponentName;
+
+        protected BoundServiceInfo(String action, ResolveInfo resolveInfo) {
+            this(action, resolveInfo.serviceInfo.applicationInfo.uid,
+                    resolveInfo.serviceInfo.getComponentName());
         }
 
-        private BoundService(int version, @Nullable ComponentName component,
-                boolean serviceIsMultiuser, @Nullable Bundle metadata, int uid) {
-            Preconditions.checkArgument(component != null || version == Integer.MIN_VALUE);
-            this.version = version;
-            this.component = component;
-            this.serviceIsMultiuser = serviceIsMultiuser;
-            this.metadata = metadata;
-            this.uid = uid;
+        protected BoundServiceInfo(String action, int uid, ComponentName componentName) {
+            mAction = action;
+            mUid = uid;
+            mComponentName = Objects.requireNonNull(componentName);
         }
 
-        public @Nullable String getPackageName() {
-            return component != null ? component.getPackageName() : null;
+        /** Returns the action associated with this bound service. */
+        public @Nullable String getAction() {
+            return mAction;
+        }
+
+        /** Returns the component of this bound service. */
+        public ComponentName getComponentName() {
+            return mComponentName;
+        }
+
+        /** Returns the user id for this bound service. */
+        public @UserIdInt int getUserId() {
+            return UserHandle.getUserId(mUid);
         }
 
         @Override
-        public boolean equals(Object o) {
+        public final boolean equals(Object o) {
             if (this == o) {
                 return true;
             }
-            if (!(o instanceof BoundService)) {
+            if (!(o instanceof BoundServiceInfo)) {
                 return false;
             }
-            BoundService that = (BoundService) o;
-            return version == that.version && uid == that.uid
-                    && Objects.equals(component, that.component);
+
+            BoundServiceInfo that = (BoundServiceInfo) o;
+            return mUid == that.mUid
+                    && Objects.equals(mAction, that.mAction)
+                    && mComponentName.equals(that.mComponentName);
         }
 
         @Override
-        public int hashCode() {
-            return Objects.hash(version, component, uid);
-        }
-
-        @Override
-        public int compareTo(BoundService that) {
-            // ServiceInfos with higher version numbers always win (having a version number >
-            // MIN_VALUE implies having a non-null component). if version numbers are equal, a
-            // non-null component wins over a null component. if the version numbers are equal and
-            // both components exist then we prefer components that work for all users vs components
-            // that only work for a single user at a time. otherwise everything's equal.
-            int ret = Integer.compare(version, that.version);
-            if (ret == 0) {
-                if (component == null && that.component != null) {
-                    ret = -1;
-                } else if (component != null && that.component == null) {
-                    ret = 1;
-                } else {
-                    if (UserHandle.getUserId(uid) != UserHandle.USER_SYSTEM
-                            && UserHandle.getUserId(that.uid) == UserHandle.USER_SYSTEM) {
-                        ret = -1;
-                    } else if (UserHandle.getUserId(uid) == UserHandle.USER_SYSTEM
-                            && UserHandle.getUserId(that.uid) != UserHandle.USER_SYSTEM) {
-                        ret = 1;
-                    }
-                }
-            }
-            return ret;
+        public final int hashCode() {
+            return Objects.hash(mAction, mUid, mComponentName);
         }
 
         @Override
         public String toString() {
-            if (component == null) {
+            if (mComponentName == null) {
                 return "none";
             } else {
-                return component.toShortString() + "@" + version + "[u"
-                        + UserHandle.getUserId(uid) + "]";
+                return mUid + "/" + mComponentName.flattenToShortString();
             }
         }
     }
 
-    private final Context mContext;
-    private final Handler mHandler;
-    private final Intent mIntent;
-    private final Predicate<ResolveInfo> mServiceCheckPredicate;
-
-    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
-        @Override
-        public boolean onPackageChanged(String packageName, int uid, String[] components) {
-            return true;
-        }
-
-        @Override
-        public void onSomePackagesChanged() {
-            onBestServiceChanged(false);
-        }
-    };
-    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            String action = intent.getAction();
-            if (action == null) {
-                return;
-            }
-            int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
-            if (userId == UserHandle.USER_NULL) {
-                return;
-            }
-
-            switch (action) {
-                case Intent.ACTION_USER_SWITCHED:
-                    onUserSwitched(userId);
-                    break;
-                case Intent.ACTION_USER_UNLOCKED:
-                    onUserUnlocked(userId);
-                    break;
-                default:
-                    break;
-            }
-
-        }
-    };
-
-    // read/write from handler thread only
-    private final Map<ComponentName, BoundService> mPendingBinds = new ArrayMap<>();
-
-    @Nullable
-    private final OnBindRunner mOnBind;
-
-    @Nullable
-    private final Runnable mOnUnbind;
-
-    // read/write from handler thread only
-    private boolean mRegistered;
-
-    // read/write from handler thread only
-    private int mCurrentUserId;
-
-    // write from handler thread only, read anywhere
-    private volatile BoundService mTargetService;
-    private volatile IBinder mBinder;
-
-    public ServiceWatcher(Context context, String action,
-            @Nullable OnBindRunner onBind, @Nullable Runnable onUnbind,
-            @BoolRes int enableOverlayResId, @StringRes int nonOverlayPackageResId) {
-        this(context, FgThread.getHandler(), action, onBind, onUnbind, enableOverlayResId,
-                nonOverlayPackageResId, DEFAULT_SERVICE_CHECK_PREDICATE);
-    }
-
-    public ServiceWatcher(Context context, Handler handler, String action,
-            @Nullable OnBindRunner onBind, @Nullable Runnable onUnbind,
-            @BoolRes int enableOverlayResId, @StringRes int nonOverlayPackageResId) {
-        this(context, handler, action, onBind, onUnbind, enableOverlayResId, nonOverlayPackageResId,
-                DEFAULT_SERVICE_CHECK_PREDICATE);
-    }
-
-    public ServiceWatcher(Context context, Handler handler, String action,
-            @Nullable OnBindRunner onBind, @Nullable Runnable onUnbind,
-            @BoolRes int enableOverlayResId, @StringRes int nonOverlayPackageResId,
-            @NonNull Predicate<ResolveInfo> serviceCheckPredicate) {
-        mContext = context;
-        mHandler = handler;
-        mIntent = new Intent(Objects.requireNonNull(action));
-        mServiceCheckPredicate = Objects.requireNonNull(serviceCheckPredicate);
-
-        Resources resources = context.getResources();
-        boolean enableOverlay = resources.getBoolean(enableOverlayResId);
-        if (!enableOverlay) {
-            mIntent.setPackage(resources.getString(nonOverlayPackageResId));
-        }
-
-        mOnBind = onBind;
-        mOnUnbind = onUnbind;
-
-        mCurrentUserId = UserHandle.USER_NULL;
-
-        mTargetService = BoundService.NONE;
-        mBinder = null;
-    }
-
-    /**
-     * Returns true if there is at least one component that could satisfy the ServiceWatcher's
-     * constraints.
-     */
-    public boolean checkServiceResolves() {
-        List<ResolveInfo> resolveInfos = mContext.getPackageManager()
-                .queryIntentServicesAsUser(mIntent,
-                        MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE | MATCH_SYSTEM_ONLY,
-                        UserHandle.USER_SYSTEM);
-        for (ResolveInfo resolveInfo : resolveInfos) {
-            if (mServiceCheckPredicate.test(resolveInfo)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Starts the process of determining the best matching service and maintaining a binding to it.
-     */
-    public void register() {
-        mHandler.sendMessage(PooledLambda.obtainMessage(ServiceWatcher::registerInternal,
-                ServiceWatcher.this));
-    }
-
-    private void registerInternal() {
-        Preconditions.checkState(!mRegistered);
-
-        mPackageMonitor.register(mContext, UserHandle.ALL, true, mHandler);
-
-        IntentFilter intentFilter = new IntentFilter();
-        intentFilter.addAction(Intent.ACTION_USER_SWITCHED);
-        intentFilter.addAction(Intent.ACTION_USER_UNLOCKED);
-        mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, intentFilter, null,
-                mHandler);
-
-        // TODO: This makes the behavior of the class unpredictable as the caller needs
-        // to know the internal impl detail that calling register would pick the current user.
-        mCurrentUserId = ActivityManager.getCurrentUser();
-
-        mRegistered = true;
-
-        mHandler.post(() -> onBestServiceChanged(false));
-    }
-
-    /**
-     * Stops the process of determining the best matching service and releases any binding.
-     */
-    public void unregister() {
-        mHandler.sendMessage(PooledLambda.obtainMessage(ServiceWatcher::unregisterInternal,
-                ServiceWatcher.this));
-    }
-
-    private void unregisterInternal() {
-        Preconditions.checkState(mRegistered);
-
-        mRegistered = false;
-
-        mPackageMonitor.unregister();
-        mContext.unregisterReceiver(mBroadcastReceiver);
-
-        mHandler.post(() -> onBestServiceChanged(false));
-    }
-
-    private void onBestServiceChanged(boolean forceRebind) {
-        Preconditions.checkState(Looper.myLooper() == mHandler.getLooper());
-
-        BoundService bestServiceInfo = BoundService.NONE;
-
-        if (mRegistered) {
-            List<ResolveInfo> resolveInfos = mContext.getPackageManager().queryIntentServicesAsUser(
-                    mIntent,
-                    GET_META_DATA | MATCH_DIRECT_BOOT_AUTO | MATCH_SYSTEM_ONLY,
-                    mCurrentUserId);
-            for (ResolveInfo resolveInfo : resolveInfos) {
-                if (!mServiceCheckPredicate.test(resolveInfo)) {
-                    continue;
-                }
-                BoundService serviceInfo = new BoundService(resolveInfo);
-                if (serviceInfo.compareTo(bestServiceInfo) > 0) {
-                    bestServiceInfo = serviceInfo;
-                }
-            }
-        }
-
-        if (forceRebind || !bestServiceInfo.equals(mTargetService)) {
-            rebind(bestServiceInfo);
-        }
-    }
-
-    private void rebind(BoundService newServiceInfo) {
-        Preconditions.checkState(Looper.myLooper() == mHandler.getLooper());
-
-        if (!mTargetService.equals(BoundService.NONE)) {
-            if (D) {
-                Log.d(TAG, "[" + mIntent.getAction() + "] unbinding from " + mTargetService);
-            }
-
-            mContext.unbindService(this);
-            onServiceDisconnected(mTargetService.component);
-            mPendingBinds.remove(mTargetService.component);
-            mTargetService = BoundService.NONE;
-        }
-
-        mTargetService = newServiceInfo;
-        if (mTargetService.equals(BoundService.NONE)) {
-            return;
-        }
-
-        Preconditions.checkState(mTargetService.component != null);
-
-        Log.i(TAG, getLogPrefix() + " binding to " + mTargetService);
-
-        Intent bindIntent = new Intent(mIntent).setComponent(mTargetService.component);
-        if (!mContext.bindServiceAsUser(bindIntent, this,
-                BIND_AUTO_CREATE | BIND_NOT_FOREGROUND | BIND_NOT_VISIBLE,
-                mHandler, UserHandle.of(UserHandle.getUserId(mTargetService.uid)))) {
-            mTargetService = BoundService.NONE;
-            Log.e(TAG, getLogPrefix() + " unexpected bind failure - retrying later");
-            mHandler.postDelayed(() -> onBestServiceChanged(false), RETRY_DELAY_MS);
-        } else {
-            mPendingBinds.put(mTargetService.component, mTargetService);
-        }
-    }
-
-    @Override
-    public final void onServiceConnected(ComponentName component, IBinder binder) {
-        Preconditions.checkState(Looper.myLooper() == mHandler.getLooper());
-        Preconditions.checkState(mBinder == null);
-
-        if (D) {
-            Log.d(TAG, getLogPrefix() + " connected to " + component.toShortString());
-        }
-
-        final BoundService boundService = mPendingBinds.remove(component);
-        if (boundService == null) {
-            return;
-        }
-
-        mBinder = binder;
-        if (mOnBind != null) {
-            try {
-                mOnBind.run(binder, boundService);
-            } catch (RuntimeException | RemoteException e) {
-                // binders may propagate some specific non-RemoteExceptions from the other side
-                // through the binder as well - we cannot allow those to crash the system server
-                Log.e(TAG, getLogPrefix() + " exception running on " + component, e);
-            }
-        }
-    }
-
-    @Override
-    public final void onServiceDisconnected(ComponentName component) {
-        Preconditions.checkState(Looper.myLooper() == mHandler.getLooper());
-
-        if (mBinder == null) {
-            return;
-        }
-
-        if (D) {
-            Log.d(TAG, getLogPrefix() + " disconnected from " + component.toShortString());
-        }
-
-        mBinder = null;
-        if (mOnUnbind != null) {
-            mOnUnbind.run();
-        }
-    }
-
-    @Override
-    public final void onBindingDied(ComponentName component) {
-        Preconditions.checkState(Looper.myLooper() == mHandler.getLooper());
-
-        Log.i(TAG, getLogPrefix() + " " + component.toShortString() + " died");
-
-        onBestServiceChanged(true);
-    }
-
-    @Override
-    public final void onNullBinding(ComponentName component) {
-        Log.e(TAG, getLogPrefix() + " " + component.toShortString() + " has null binding");
-    }
-
-    void onUserSwitched(@UserIdInt int userId) {
-        mCurrentUserId = userId;
-        onBestServiceChanged(false);
-    }
-
-    void onUserUnlocked(@UserIdInt int userId) {
-        if (userId == mCurrentUserId) {
-            onBestServiceChanged(false);
-        }
-    }
-
     /**
-     * Runs the given function asynchronously if and only if currently connected. Suppresses any
-     * RemoteException thrown during execution.
+     * Creates a new ServiceWatcher instance.
      */
-    public final void runOnBinder(BinderRunner runner) {
-        mHandler.post(() -> {
-            if (mBinder == null) {
-                runner.onError();
-                return;
-            }
-
-            try {
-                runner.run(mBinder);
-            } catch (RuntimeException | RemoteException e) {
-                // binders may propagate some specific non-RemoteExceptions from the other side
-                // through the binder as well - we cannot allow those to crash the system server
-                Log.e(TAG, getLogPrefix() + " exception running on " + mTargetService, e);
-                runner.onError();
-            }
-        });
-    }
-
-    private String getLogPrefix() {
-        return "[" + mIntent.getAction() + "]";
-    }
-
-    @Override
-    public String toString() {
-        return mTargetService.toString();
+    static <TBoundServiceInfo extends BoundServiceInfo> ServiceWatcher create(
+            Context context,
+            String tag,
+            ServiceSupplier<TBoundServiceInfo> serviceSupplier,
+            @Nullable ServiceListener<? super TBoundServiceInfo> serviceListener) {
+        return create(context, FgThread.getHandler(), tag, serviceSupplier, serviceListener);
     }
 
     /**
-     * Dump for debugging.
+     * Creates a new ServiceWatcher instance that runs on the given handler.
      */
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println("target service=" + mTargetService);
-        pw.println("connected=" + (mBinder != null));
+    static <TBoundServiceInfo extends BoundServiceInfo> ServiceWatcher create(
+            Context context,
+            Handler handler,
+            String tag,
+            ServiceSupplier<TBoundServiceInfo> serviceSupplier,
+            @Nullable ServiceListener<? super TBoundServiceInfo> serviceListener) {
+        return new ServiceWatcherImpl<>(context, handler, tag, serviceSupplier, serviceListener);
     }
-}
+
+    /**
+     * Returns true if there is at least one service that the ServiceWatcher could hypothetically
+     * bind to, as selected by the {@link ServiceSupplier}.
+     */
+    boolean checkServiceResolves();
+
+    /**
+     * Registers the ServiceWatcher, so that it will begin maintaining an active binding to the
+     * service selected by {@link ServiceSupplier}, until {@link #unregister()} is called.
+     */
+    void register();
+
+    /**
+     * Unregisters the ServiceWatcher, so that it will release any active bindings. If the
+     * ServiceWatcher is currently bound, this will result in one final
+     * {@link ServiceListener#onUnbind()} invocation, which may happen after this method completes
+     * (but which is guaranteed to occur before any further
+     * {@link ServiceListener#onBind(IBinder, BoundServiceInfo)} invocation in response to a later
+     * call to {@link #register()}).
+     */
+    void unregister();
+
+    /**
+     * Runs the given binder operation on the currently bound service (if available). The operation
+     * will always fail if the ServiceWatcher is not currently registered.
+     */
+    void runOnBinder(BinderOperation operation);
+
+    /**
+     * Dumps ServiceWatcher information.
+     */
+    void dump(PrintWriter pw);
+}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/servicewatcher/ServiceWatcherImpl.java b/services/core/java/com/android/server/servicewatcher/ServiceWatcherImpl.java
new file mode 100644
index 0000000..e718ba3
--- /dev/null
+++ b/services/core/java/com/android/server/servicewatcher/ServiceWatcherImpl.java
@@ -0,0 +1,307 @@
+/*
+ * 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.servicewatcher;
+
+import static android.content.Context.BIND_AUTO_CREATE;
+import static android.content.Context.BIND_NOT_FOREGROUND;
+import static android.content.Context.BIND_NOT_VISIBLE;
+
+import android.annotation.Nullable;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.util.Log;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.content.PackageMonitor;
+import com.android.internal.util.Preconditions;
+import com.android.server.servicewatcher.ServiceWatcher.BoundServiceInfo;
+import com.android.server.servicewatcher.ServiceWatcher.ServiceChangedListener;
+
+import java.io.PrintWriter;
+import java.util.Objects;
+
+/**
+ * Implementation of ServiceWatcher. Keeping the implementation separate from the interface allows
+ * us to store the generic relationship between the service supplier and the service listener, while
+ * hiding the generics from clients, simplifying the API.
+ */
+class ServiceWatcherImpl<TBoundServiceInfo extends BoundServiceInfo> implements ServiceWatcher,
+        ServiceChangedListener {
+
+    static final String TAG = "ServiceWatcher";
+    static final boolean D = Log.isLoggable(TAG, Log.DEBUG);
+
+    static final long RETRY_DELAY_MS = 15 * 1000;
+
+    final Context mContext;
+    final Handler mHandler;
+    final String mTag;
+    final ServiceSupplier<TBoundServiceInfo> mServiceSupplier;
+    final @Nullable ServiceListener<? super TBoundServiceInfo> mServiceListener;
+
+    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
+        @Override
+        public boolean onPackageChanged(String packageName, int uid, String[] components) {
+            return true;
+        }
+
+        @Override
+        public void onSomePackagesChanged() {
+            onServiceChanged(false);
+        }
+    };
+
+    @GuardedBy("this")
+    private boolean mRegistered = false;
+    @GuardedBy("this")
+    private MyServiceConnection mServiceConnection = new MyServiceConnection(null);
+
+    ServiceWatcherImpl(Context context, Handler handler, String tag,
+            ServiceSupplier<TBoundServiceInfo> serviceSupplier,
+            ServiceListener<? super TBoundServiceInfo> serviceListener) {
+        mContext = context;
+        mHandler = handler;
+        mTag = tag;
+        mServiceSupplier = serviceSupplier;
+        mServiceListener = serviceListener;
+    }
+
+    @Override
+    public boolean checkServiceResolves() {
+        return mServiceSupplier.hasMatchingService();
+    }
+
+    @Override
+    public synchronized void register() {
+        Preconditions.checkState(!mRegistered);
+
+        mRegistered = true;
+        mPackageMonitor.register(mContext, UserHandle.ALL, /*externalStorage=*/ true, mHandler);
+        mServiceSupplier.register(this);
+
+        onServiceChanged(false);
+    }
+
+    @Override
+    public synchronized void unregister() {
+        Preconditions.checkState(mRegistered);
+
+        mServiceSupplier.unregister();
+        mPackageMonitor.unregister();
+        mRegistered = false;
+
+        onServiceChanged(false);
+    }
+
+    @Override
+    public synchronized void onServiceChanged() {
+        onServiceChanged(false);
+    }
+
+    @Override
+    public synchronized void runOnBinder(BinderOperation operation) {
+        MyServiceConnection serviceConnection = mServiceConnection;
+        mHandler.post(() -> serviceConnection.runOnBinder(operation));
+    }
+
+    synchronized void onServiceChanged(boolean forceRebind) {
+        TBoundServiceInfo newBoundServiceInfo;
+        if (mRegistered) {
+            newBoundServiceInfo = mServiceSupplier.getServiceInfo();
+        } else {
+            newBoundServiceInfo = null;
+        }
+
+        if (forceRebind || !Objects.equals(mServiceConnection.getBoundServiceInfo(),
+                newBoundServiceInfo)) {
+            MyServiceConnection oldServiceConnection = mServiceConnection;
+            MyServiceConnection newServiceConnection = new MyServiceConnection(newBoundServiceInfo);
+            mServiceConnection = newServiceConnection;
+            mHandler.post(() -> {
+                oldServiceConnection.unbind();
+                newServiceConnection.bind();
+            });
+        }
+    }
+
+    @Override
+    public String toString() {
+        MyServiceConnection serviceConnection;
+        synchronized (this) {
+            serviceConnection = mServiceConnection;
+        }
+
+        return serviceConnection.getBoundServiceInfo().toString();
+    }
+
+    @Override
+    public void dump(PrintWriter pw) {
+        MyServiceConnection serviceConnection;
+        synchronized (this) {
+            serviceConnection = mServiceConnection;
+        }
+
+        pw.println("target service=" + serviceConnection.getBoundServiceInfo());
+        pw.println("connected=" + serviceConnection.isConnected());
+    }
+
+    // runs on the handler thread, and expects most of it's methods to be called from that thread
+    private class MyServiceConnection implements ServiceConnection {
+
+        private final @Nullable TBoundServiceInfo mBoundServiceInfo;
+
+        // volatile so that isConnected can be called from any thread easily
+        private volatile @Nullable IBinder mBinder;
+        private @Nullable Runnable mRebinder;
+
+        MyServiceConnection(@Nullable TBoundServiceInfo boundServiceInfo) {
+            mBoundServiceInfo = boundServiceInfo;
+        }
+
+        // may be called from any thread
+        @Nullable TBoundServiceInfo getBoundServiceInfo() {
+            return mBoundServiceInfo;
+        }
+
+        // may be called from any thread
+        boolean isConnected() {
+            return mBinder != null;
+        }
+
+        void bind() {
+            Preconditions.checkState(Looper.myLooper() == mHandler.getLooper());
+
+            if (mBoundServiceInfo == null) {
+                return;
+            }
+
+            Log.i(TAG, "[" + mTag + "] binding to " + mBoundServiceInfo);
+
+            Intent bindIntent = new Intent(mBoundServiceInfo.getAction()).setComponent(
+                    mBoundServiceInfo.getComponentName());
+            if (!mContext.bindServiceAsUser(bindIntent, this,
+                    BIND_AUTO_CREATE | BIND_NOT_FOREGROUND | BIND_NOT_VISIBLE,
+                    mHandler, UserHandle.of(mBoundServiceInfo.getUserId()))) {
+                Log.e(TAG, "[" + mTag + "] unexpected bind failure - retrying later");
+                mRebinder = this::bind;
+                mHandler.postDelayed(mRebinder, RETRY_DELAY_MS);
+            } else {
+                mRebinder = null;
+            }
+        }
+
+        void unbind() {
+            Preconditions.checkState(Looper.myLooper() == mHandler.getLooper());
+
+            if (mBoundServiceInfo == null) {
+                return;
+            }
+
+            if (D) {
+                Log.d(TAG, "[" + mTag + "] unbinding from " + mBoundServiceInfo);
+            }
+
+            if (mRebinder != null) {
+                mHandler.removeCallbacks(mRebinder);
+                mRebinder = null;
+            } else {
+                mContext.unbindService(this);
+            }
+
+            onServiceDisconnected(mBoundServiceInfo.getComponentName());
+        }
+
+        void runOnBinder(BinderOperation operation) {
+            Preconditions.checkState(Looper.myLooper() == mHandler.getLooper());
+
+            if (mBinder == null) {
+                operation.onError();
+                return;
+            }
+
+            try {
+                operation.run(mBinder);
+            } catch (RuntimeException | RemoteException e) {
+                // binders may propagate some specific non-RemoteExceptions from the other side
+                // through the binder as well - we cannot allow those to crash the system server
+                Log.e(TAG, "[" + mTag + "] error running operation on " + mBoundServiceInfo, e);
+                operation.onError();
+            }
+        }
+
+        @Override
+        public final void onServiceConnected(ComponentName component, IBinder binder) {
+            Preconditions.checkState(Looper.myLooper() == mHandler.getLooper());
+            Preconditions.checkState(mBinder == null);
+
+            if (D) {
+                Log.d(TAG, "[" + mTag + "] connected to " + component.toShortString());
+            }
+
+            mBinder = binder;
+
+            if (mServiceListener != null) {
+                try {
+                    mServiceListener.onBind(binder, mBoundServiceInfo);
+                } catch (RuntimeException | RemoteException e) {
+                    // binders may propagate some specific non-RemoteExceptions from the other side
+                    // through the binder as well - we cannot allow those to crash the system server
+                    Log.e(TAG, "[" + mTag + "] error running operation on " + mBoundServiceInfo, e);
+                }
+            }
+        }
+
+        @Override
+        public final void onServiceDisconnected(ComponentName component) {
+            Preconditions.checkState(Looper.myLooper() == mHandler.getLooper());
+
+            if (mBinder == null) {
+                return;
+            }
+
+            if (D) {
+                Log.d(TAG, "[" + mTag + "] disconnected from " + mBoundServiceInfo);
+            }
+
+            mBinder = null;
+            if (mServiceListener != null) {
+                mServiceListener.onUnbind();
+            }
+        }
+
+        @Override
+        public final void onBindingDied(ComponentName component) {
+            Preconditions.checkState(Looper.myLooper() == mHandler.getLooper());
+
+            Log.i(TAG, "[" + mTag + "] " + mBoundServiceInfo + " died");
+
+            onServiceChanged(true);
+        }
+
+        @Override
+        public final void onNullBinding(ComponentName component) {
+            Log.e(TAG, "[" + mTag + "] " + mBoundServiceInfo + " has null binding");
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/speech/RemoteSpeechRecognitionService.java b/services/core/java/com/android/server/speech/RemoteSpeechRecognitionService.java
index 3f20302..9c8ff68 100644
--- a/services/core/java/com/android/server/speech/RemoteSpeechRecognitionService.java
+++ b/services/core/java/com/android/server/speech/RemoteSpeechRecognitionService.java
@@ -18,12 +18,12 @@
 
 import static com.android.internal.infra.AbstractRemoteService.PERMANENT_BOUND_TIMEOUT_MS;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.app.AppOpsManager;
+import android.content.AttributionSource;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
-import android.os.Binder;
 import android.os.Bundle;
 import android.os.RemoteException;
 import android.speech.IRecognitionListener;
@@ -40,10 +40,6 @@
     private static final String TAG = RemoteSpeechRecognitionService.class.getSimpleName();
     private static final boolean DEBUG = false;
 
-    private static final String APP_OP_MESSAGE = "Recording audio for speech recognition";
-    private static final String RECORD_AUDIO_APP_OP =
-            AppOpsManager.permissionToOp(android.Manifest.permission.RECORD_AUDIO);
-
     private final Object mLock = new Object();
 
     private boolean mConnected = false;
@@ -53,14 +49,6 @@
 
     @Nullable
     @GuardedBy("mLock")
-    private String mPackageName;
-
-    @Nullable
-    @GuardedBy("mLock")
-    private String mFeatureId;
-
-    @Nullable
-    @GuardedBy("mLock")
     private DelegatingListener mDelegatingListener;
 
     // Makes sure we can block startListening() if session is still in progress.
@@ -72,7 +60,6 @@
     private boolean mRecordingInProgress = false;
 
     private final int mCallingUid;
-    private final AppOpsManager mAppOpsManager;
     private final ComponentName mComponentName;
 
     RemoteSpeechRecognitionService(
@@ -87,7 +74,6 @@
                 IRecognitionService.Stub::asInterface);
 
         mCallingUid = callingUid;
-        mAppOpsManager = mContext.getSystemService(AppOpsManager.class);
         mComponentName = serviceName;
 
         if (DEBUG) {
@@ -99,11 +85,12 @@
         return mComponentName;
     }
 
-    void startListening(Intent recognizerIntent, IRecognitionListener listener, String packageName,
-            String featureId) {
+    void startListening(Intent recognizerIntent, IRecognitionListener listener,
+            @NonNull AttributionSource attributionSource) {
         if (DEBUG) {
             Slog.i(TAG, String.format("#startListening for package: %s, feature=%s, callingUid=%d",
-                    packageName, featureId, mCallingUid));
+                    attributionSource.getPackageName(), attributionSource.getAttributionTag(),
+                    mCallingUid));
         }
 
         if (listener == null) {
@@ -123,10 +110,6 @@
                 return;
             }
 
-            if (startProxyOp(packageName, featureId) != AppOpsManager.MODE_ALLOWED) {
-                tryRespondWithError(listener, SpeechRecognizer.ERROR_INSUFFICIENT_PERMISSIONS);
-                return;
-            }
             mSessionInProgress = true;
             mRecordingInProgress = true;
 
@@ -141,23 +124,18 @@
                     resetStateLocked();
                 }
             });
-            mPackageName = packageName;
-            mFeatureId = featureId;
 
             run(service ->
                     service.startListening(
                             recognizerIntent,
                             mDelegatingListener,
-                            packageName,
-                            featureId,
-                            mCallingUid));
+                            attributionSource));
         }
     }
 
-    void stopListening(
-            IRecognitionListener listener, String packageName, String featureId) {
+    void stopListening(IRecognitionListener listener) {
         if (DEBUG) {
-            Slog.i(TAG, "#stopListening for package: " + packageName + ", feature=" + featureId);
+            Slog.i(TAG, "#stopListening");
         }
 
         if (!mConnected) {
@@ -184,19 +162,13 @@
             }
             mRecordingInProgress = false;
 
-            finishProxyOp(packageName, featureId);
-
-            run(service -> service.stopListening(mDelegatingListener, packageName, featureId));
+            run(service -> service.stopListening(mDelegatingListener));
         }
     }
 
-    void cancel(
-            IRecognitionListener listener,
-            String packageName,
-            String featureId,
-            boolean isShutdown) {
+    void cancel(IRecognitionListener listener, boolean isShutdown) {
         if (DEBUG) {
-            Slog.i(TAG, "#cancel for package: " + packageName + ", feature=" + featureId);
+            Slog.i(TAG, "#cancel");
         }
 
         if (!mConnected) {
@@ -220,11 +192,8 @@
             // Temporary reference to allow for resetting the hard link mDelegatingListener to null.
             IRecognitionListener delegatingListener = mDelegatingListener;
 
-            run(service -> service.cancel(delegatingListener, packageName, featureId, isShutdown));
+            run(service -> service.cancel(delegatingListener, isShutdown));
 
-            if (mRecordingInProgress) {
-                finishProxyOp(packageName, featureId);
-            }
             mRecordingInProgress = false;
             mSessionInProgress = false;
 
@@ -249,7 +218,7 @@
             }
         }
 
-        cancel(mListener, mPackageName, mFeatureId, true /* isShutdown */);
+        cancel(mListener, true /* isShutdown */);
     }
 
     @Override // from ServiceConnector.Impl
@@ -286,40 +255,12 @@
     }
 
     private void resetStateLocked() {
-        if (mRecordingInProgress && mPackageName != null) {
-            finishProxyOp(mPackageName, mFeatureId);
-        }
-
         mListener = null;
         mDelegatingListener = null;
         mSessionInProgress = false;
         mRecordingInProgress = false;
     }
 
-    private int startProxyOp(String packageName, String featureId) {
-        final long identity = Binder.clearCallingIdentity();
-        try {
-            return mAppOpsManager.startProxyOp(
-                    RECORD_AUDIO_APP_OP,
-                    mCallingUid,
-                    packageName,
-                    featureId,
-                    APP_OP_MESSAGE);
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-    }
-
-    private void finishProxyOp(String packageName, String featureId) {
-        final long identity = Binder.clearCallingIdentity();
-        try {
-            mAppOpsManager.finishProxyOp(
-                    RECORD_AUDIO_APP_OP, mCallingUid, packageName, featureId);
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-    }
-
     private static void tryRespondWithError(IRecognitionListener listener, int errorCode) {
         if (DEBUG) {
             Slog.i(TAG, "Responding with error " + errorCode);
diff --git a/services/core/java/com/android/server/speech/SpeechRecognitionManagerService.java b/services/core/java/com/android/server/speech/SpeechRecognitionManagerService.java
index 52c1467b..22eeb34 100644
--- a/services/core/java/com/android/server/speech/SpeechRecognitionManagerService.java
+++ b/services/core/java/com/android/server/speech/SpeechRecognitionManagerService.java
@@ -75,7 +75,7 @@
     @Override
     protected SpeechRecognitionManagerServiceImpl newServiceLocked(
             @UserIdInt int resolvedUserId, boolean disabled) {
-        return new SpeechRecognitionManagerServiceImpl(this, mLock, resolvedUserId, disabled);
+        return new SpeechRecognitionManagerServiceImpl(this, mLock, resolvedUserId);
     }
 
     final class SpeechRecognitionManagerServiceStub extends IRecognitionServiceManager.Stub {
diff --git a/services/core/java/com/android/server/speech/SpeechRecognitionManagerServiceImpl.java b/services/core/java/com/android/server/speech/SpeechRecognitionManagerServiceImpl.java
index 769e049..eee08c2 100644
--- a/services/core/java/com/android/server/speech/SpeechRecognitionManagerServiceImpl.java
+++ b/services/core/java/com/android/server/speech/SpeechRecognitionManagerServiceImpl.java
@@ -20,6 +20,7 @@
 import android.annotation.Nullable;
 import android.annotation.UserIdInt;
 import android.app.AppGlobals;
+import android.content.AttributionSource;
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.pm.PackageManager;
@@ -36,8 +37,6 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.server.infra.AbstractPerUserSystemService;
 
-import com.google.android.collect.Sets;
-
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
@@ -60,7 +59,7 @@
 
     SpeechRecognitionManagerServiceImpl(
             @NonNull SpeechRecognitionManagerService master,
-            @NonNull Object lock, @UserIdInt int userId, boolean disabled) {
+            @NonNull Object lock, @UserIdInt int userId) {
         super(master, lock, userId);
     }
 
@@ -108,10 +107,6 @@
         }
 
         final int creatorCallingUid = Binder.getCallingUid();
-        Set<String> creatorPackageNames =
-                Sets.newArraySet(
-                        getContext().getPackageManager().getPackagesForUid(creatorCallingUid));
-
         RemoteSpeechRecognitionService service = createService(creatorCallingUid, serviceComponent);
 
         if (service == null) {
@@ -127,6 +122,7 @@
         } catch (RemoteException e) {
             // RemoteException == binder already died, schedule disconnect anyway.
             handleClientDeath(creatorCallingUid, service, true /* invoke #cancel */);
+            return;
         }
 
         service.connect().thenAccept(binderService -> {
@@ -137,41 +133,24 @@
                         public void startListening(
                                 Intent recognizerIntent,
                                 IRecognitionListener listener,
-                                String packageName,
-                                String featureId,
-                                int callingUid) throws RemoteException {
-                            verifyCallerIdentity(
-                                    creatorCallingUid, packageName, creatorPackageNames, listener);
-                            if (callingUid != creatorCallingUid) {
-                                listener.onError(SpeechRecognizer.ERROR_INSUFFICIENT_PERMISSIONS);
-                                return;
-                            }
-
-                            service.startListening(
-                                    recognizerIntent, listener, packageName, featureId);
+                                @NonNull AttributionSource attributionSource)
+                                        throws RemoteException {
+                            attributionSource.enforceCallingUid();
+                            service.startListening(recognizerIntent, listener, attributionSource);
                         }
 
                         @Override
                         public void stopListening(
-                                IRecognitionListener listener,
-                                String packageName,
-                                String featureId) throws RemoteException {
-                            verifyCallerIdentity(
-                                    creatorCallingUid, packageName, creatorPackageNames, listener);
-
-                            service.stopListening(listener, packageName, featureId);
+                                IRecognitionListener listener) throws RemoteException {
+                            service.stopListening(listener);
                         }
 
                         @Override
                         public void cancel(
                                 IRecognitionListener listener,
-                                String packageName,
-                                String featureId,
                                 boolean isShutdown) throws RemoteException {
-                            verifyCallerIdentity(
-                                    creatorCallingUid, packageName, creatorPackageNames, listener);
 
-                            service.cancel(listener, packageName, featureId, isShutdown);
+                            service.cancel(listener, isShutdown);
 
                             if (isShutdown) {
                                 handleClientDeath(
@@ -192,17 +171,6 @@
         });
     }
 
-    private void verifyCallerIdentity(
-            int creatorCallingUid,
-            String packageName,
-            Set<String> creatorPackageNames,
-            IRecognitionListener listener) throws RemoteException {
-        if (creatorCallingUid != Binder.getCallingUid()
-                || !creatorPackageNames.contains(packageName)) {
-            listener.onError(SpeechRecognizer.ERROR_INSUFFICIENT_PERMISSIONS);
-        }
-    }
-
     private void handleClientDeath(
             int callingUid,
             RemoteSpeechRecognitionService service, boolean invokeCancel) {
diff --git a/services/core/java/com/android/server/stats/StatsHelper.java b/services/core/java/com/android/server/stats/StatsHelper.java
new file mode 100644
index 0000000..9b9f6b50
--- /dev/null
+++ b/services/core/java/com/android/server/stats/StatsHelper.java
@@ -0,0 +1,45 @@
+/*
+ * 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.stats;
+
+import static android.app.StatsManager.ACTION_STATSD_STARTED;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.content.Context;
+import android.content.Intent;
+import android.os.UserHandle;
+
+/**
+ * Provides helper methods for the Statsd APEX
+ *
+ * @hide
+ **/
+@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
+public final class StatsHelper {
+    private StatsHelper() {}
+
+    /**
+     * Send statsd ready broadcast
+     *
+     **/
+    public static void sendStatsdReadyBroadcast(@NonNull final Context context) {
+        context.sendBroadcastAsUser(
+                new Intent(ACTION_STATSD_STARTED).addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND),
+                UserHandle.SYSTEM, android.Manifest.permission.DUMP);
+    }
+}
diff --git a/services/core/java/com/android/server/storage/StorageSessionController.java b/services/core/java/com/android/server/storage/StorageSessionController.java
index dedb3ac..ff6c2f5 100644
--- a/services/core/java/com/android/server/storage/StorageSessionController.java
+++ b/services/core/java/com/android/server/storage/StorageSessionController.java
@@ -27,11 +27,13 @@
 import android.content.pm.ProviderInfo;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
+import android.content.pm.UserInfo;
 import android.os.IVold;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
 import android.os.ServiceSpecificException;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.os.storage.StorageManager;
 import android.os.storage.StorageVolume;
 import android.os.storage.VolumeInfo;
@@ -53,6 +55,7 @@
 
     private final Object mLock = new Object();
     private final Context mContext;
+    private final UserManager mUserManager;
     @GuardedBy("mLock")
     private final SparseArray<StorageUserConnection> mConnections = new SparseArray<>();
 
@@ -63,6 +66,30 @@
 
     public StorageSessionController(Context context) {
         mContext = Objects.requireNonNull(context);
+        mUserManager = mContext.getSystemService(UserManager.class);
+    }
+
+    /**
+     * Returns userId for the volume to be used in the StorageUserConnection.
+     * If the user is a clone profile, it will use the same connection
+     * as the parent user, and hence this method returns the parent's userId. Else, it returns the
+     * volume's mountUserId
+     * @param vol for which the storage session has to be started
+     * @return userId for connection for this volume
+     */
+    public int getConnectionUserIdForVolume(VolumeInfo vol) {
+        final Context volumeUserContext = mContext.createContextAsUser(
+                UserHandle.of(vol.mountUserId), 0);
+        boolean sharesMediaWithParent = volumeUserContext.getSystemService(
+                UserManager.class).sharesMediaWithParent();
+
+        UserInfo userInfo = mUserManager.getUserInfo(vol.mountUserId);
+        if (userInfo != null && sharesMediaWithParent) {
+            // Clones use the same connection as their parent
+            return userInfo.profileGroupId;
+        } else {
+            return vol.mountUserId;
+        }
     }
 
     /**
@@ -88,7 +115,7 @@
         Slog.i(TAG, "On volume mount " + vol);
 
         String sessionId = vol.getId();
-        int userId = vol.getMountUserId();
+        int userId = getConnectionUserIdForVolume(vol);
 
         StorageUserConnection connection = null;
         synchronized (mLock) {
@@ -120,7 +147,7 @@
             return;
         }
         String sessionId = vol.getId();
-        int userId = vol.getMountUserId();
+        int userId = getConnectionUserIdForVolume(vol);
 
         StorageUserConnection connection = null;
         synchronized (mLock) {
@@ -191,7 +218,7 @@
 
         Slog.i(TAG, "On volume remove " + vol);
         String sessionId = vol.getId();
-        int userId = vol.getMountUserId();
+        int userId = getConnectionUserIdForVolume(vol);
 
         synchronized (mLock) {
             StorageUserConnection connection = mConnections.get(userId);
diff --git a/services/core/java/com/android/server/storage/StorageUserConnection.java b/services/core/java/com/android/server/storage/StorageUserConnection.java
index a0e2286..0b11b0b 100644
--- a/services/core/java/com/android/server/storage/StorageUserConnection.java
+++ b/services/core/java/com/android/server/storage/StorageUserConnection.java
@@ -265,6 +265,10 @@
         synchronized (mSessionsLock) {
             int ioBlockedCounter = mUidsBlockedOnIo.get(uid, 0);
             if (ioBlockedCounter == 0) {
+                Slog.w(TAG, "Unexpected app IO resumption for uid: " + uid);
+            }
+
+            if (ioBlockedCounter <= 1) {
                 mUidsBlockedOnIo.remove(uid);
             } else {
                 mUidsBlockedOnIo.put(uid, --ioBlockedCounter);
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorService.java b/services/core/java/com/android/server/timedetector/TimeDetectorService.java
index eefa045a..27e2ee5 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorService.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorService.java
@@ -228,7 +228,7 @@
     private void enforceSuggestExternalTimePermission() {
         // We don't expect a call from system server, so simply enforce calling permission.
         mContext.enforceCallingPermission(
-                android.Manifest.permission.SET_TIME,
+                android.Manifest.permission.SUGGEST_EXTERNAL_TIME,
                 "suggest time from external source");
     }
 
diff --git a/services/core/java/com/android/server/timezone/TimeZoneUpdateIdler.java b/services/core/java/com/android/server/timezone/TimeZoneUpdateIdler.java
index a7767a4..23e3eba 100644
--- a/services/core/java/com/android/server/timezone/TimeZoneUpdateIdler.java
+++ b/services/core/java/com/android/server/timezone/TimeZoneUpdateIdler.java
@@ -16,8 +16,6 @@
 
 package com.android.server.timezone;
 
-import com.android.server.LocalServices;
-
 import android.app.job.JobInfo;
 import android.app.job.JobParameters;
 import android.app.job.JobScheduler;
@@ -26,6 +24,8 @@
 import android.content.Context;
 import android.util.Slog;
 
+import com.android.server.LocalServices;
+
 /**
  * A JobService used to trigger time zone rules update work when a device falls idle.
  */
@@ -55,7 +55,7 @@
     @Override
     public boolean onStopJob(JobParameters params) {
         // Reschedule if stopped unless it was cancelled due to unschedule().
-        boolean reschedule = params.getStopReason() != JobParameters.REASON_CANCELED;
+        boolean reschedule = params.getStopReason() != JobParameters.STOP_REASON_CANCELLED_BY_APP;
         Slog.d(TAG, "onStopJob() called: Reschedule=" + reschedule);
         return reschedule;
     }
diff --git a/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessor.java b/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessor.java
index 2452c8d..222e852 100644
--- a/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessor.java
+++ b/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessor.java
@@ -18,8 +18,8 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.content.res.Resources;
-import android.net.ConnectivityManager;
 import android.os.SystemProperties;
 import android.util.ArraySet;
 
@@ -124,9 +124,7 @@
      * device.
      */
     public boolean isTelephonyTimeZoneDetectionFeatureSupported() {
-        // TODO b/150583524 Avoid the use of a deprecated API.
-        return mContext.getSystemService(ConnectivityManager.class)
-                .isNetworkSupported(ConnectivityManager.TYPE_MOBILE);
+        return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
     }
 
     /**
diff --git a/services/core/java/com/android/server/timezonedetector/location/BinderLocationTimeZoneProvider.java b/services/core/java/com/android/server/timezonedetector/location/BinderLocationTimeZoneProvider.java
index 4fa920e..f054c57 100644
--- a/services/core/java/com/android/server/timezonedetector/location/BinderLocationTimeZoneProvider.java
+++ b/services/core/java/com/android/server/timezonedetector/location/BinderLocationTimeZoneProvider.java
@@ -47,7 +47,7 @@
             @NonNull String providerName,
             @NonNull LocationTimeZoneProviderProxy proxy) {
         super(providerMetricsLogger, threadingDomain, providerName,
-                new ZoneInfoDbTimeZoneIdValidator());
+                new ZoneInfoDbTimeZoneProviderEventPreProcessor());
         mProxy = Objects.requireNonNull(proxy);
     }
 
diff --git a/services/core/java/com/android/server/timezonedetector/location/LocationTimeZoneProvider.java b/services/core/java/com/android/server/timezonedetector/location/LocationTimeZoneProvider.java
index cc815dc6..e116a87 100644
--- a/services/core/java/com/android/server/timezonedetector/location/LocationTimeZoneProvider.java
+++ b/services/core/java/com/android/server/timezonedetector/location/LocationTimeZoneProvider.java
@@ -20,7 +20,6 @@
 import static android.service.timezone.TimeZoneProviderService.TEST_COMMAND_RESULT_SUCCESS_KEY;
 
 import static com.android.server.timezonedetector.location.LocationTimeZoneManagerService.debugLog;
-import static com.android.server.timezonedetector.location.LocationTimeZoneManagerService.infoLog;
 import static com.android.server.timezonedetector.location.LocationTimeZoneManagerService.warnLog;
 import static com.android.server.timezonedetector.location.LocationTimeZoneProvider.ProviderState.PROVIDER_STATE_DESTROYED;
 import static com.android.server.timezonedetector.location.LocationTimeZoneProvider.ProviderState.PROVIDER_STATE_PERM_FAILED;
@@ -86,18 +85,6 @@
     }
 
     /**
-     * Used by {@link LocationTimeZoneProvider} to check if time zone IDs are understood
-     * by the platform.
-     */
-    interface TimeZoneIdValidator {
-
-        /**
-         * Returns whether {@code timeZoneId} is supported by the platform or not.
-         */
-        boolean isValid(@NonNull String timeZoneId);
-    }
-
-    /**
      * Listener interface used to log provider events for metrics.
      */
     interface ProviderMetricsLogger {
@@ -386,19 +373,20 @@
     // Non-null and effectively final after initialize() is called.
     ProviderListener mProviderListener;
 
-    @NonNull private TimeZoneIdValidator mTimeZoneIdValidator;
+    @NonNull private final TimeZoneProviderEventPreProcessor mTimeZoneProviderEventPreProcessor;
 
     /** Creates the instance. */
     LocationTimeZoneProvider(@NonNull ProviderMetricsLogger providerMetricsLogger,
             @NonNull ThreadingDomain threadingDomain,
             @NonNull String providerName,
-            @NonNull TimeZoneIdValidator timeZoneIdValidator) {
+            @NonNull TimeZoneProviderEventPreProcessor timeZoneProviderEventPreProcessor) {
         mThreadingDomain = Objects.requireNonNull(threadingDomain);
         mProviderMetricsLogger = Objects.requireNonNull(providerMetricsLogger);
         mInitializationTimeoutQueue = threadingDomain.createSingleRunnableQueue();
         mSharedLock = threadingDomain.getLockObject();
         mProviderName = Objects.requireNonNull(providerName);
-        mTimeZoneIdValidator = Objects.requireNonNull(timeZoneIdValidator);
+        mTimeZoneProviderEventPreProcessor =
+                Objects.requireNonNull(timeZoneProviderEventPreProcessor);
     }
 
     /**
@@ -639,24 +627,8 @@
         mThreadingDomain.assertCurrentThread();
         Objects.requireNonNull(timeZoneProviderEvent);
 
-        // If the provider has made a suggestion with unknown time zone IDs it cannot be used to set
-        // the device's time zone. This logic prevents bad time zone IDs entering the time zone
-        // detection logic from third party code.
-        //
-        // An event containing an unknown time zone ID could occur if the provider is using a
-        // different TZDB version than the device. Provider developers are expected to take steps to
-        // avoid version skew problem, e.g. by ensuring atomic updates with the platform time zone
-        // rules, or providing IDs based on the device's TZDB version, so this is not considered a
-        // common case.
-        //
-        // Treating a suggestion containing unknown time zone IDs as "uncertain" in the primary
-        // enables immediate failover to a secondary provider, one that might provide valid IDs for
-        // the same location, which should provide better behavior than just ignoring the event.
-        if (hasInvalidTimeZones(timeZoneProviderEvent)) {
-            infoLog("event=" + timeZoneProviderEvent + " has unsupported time zones. "
-                    + "Replacing it with uncertain event.");
-            timeZoneProviderEvent = TimeZoneProviderEvent.createUncertainEvent();
-        }
+        timeZoneProviderEvent =
+                mTimeZoneProviderEventPreProcessor.preProcess(timeZoneProviderEvent);
 
         synchronized (mSharedLock) {
             debugLog("handleTimeZoneProviderEvent: mProviderName=" + mProviderName
@@ -755,20 +727,6 @@
         }
     }
 
-    private boolean hasInvalidTimeZones(@NonNull TimeZoneProviderEvent event) {
-        if (event.getSuggestion() == null) {
-            return false;
-        }
-
-        for (String timeZone : event.getSuggestion().getTimeZoneIds()) {
-            if (!mTimeZoneIdValidator.isValid(timeZone)) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
     @GuardedBy("mSharedLock")
     private void assertIsStarted() {
         ProviderState currentState = mCurrentState.get();
diff --git a/services/core/java/com/android/server/timezonedetector/location/RealLocationTimeZoneProviderProxy.java b/services/core/java/com/android/server/timezonedetector/location/RealLocationTimeZoneProviderProxy.java
index 0b51488..6c3f016 100644
--- a/services/core/java/com/android/server/timezonedetector/location/RealLocationTimeZoneProviderProxy.java
+++ b/services/core/java/com/android/server/timezonedetector/location/RealLocationTimeZoneProviderProxy.java
@@ -16,19 +16,14 @@
 
 package com.android.server.timezonedetector.location;
 
-import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.Manifest.permission.BIND_TIME_ZONE_PROVIDER_SERVICE;
+import static android.Manifest.permission.INSTALL_LOCATION_TIME_ZONE_PROVIDER_SERVICE;
 import static android.service.timezone.TimeZoneProviderService.TEST_COMMAND_RESULT_ERROR_KEY;
 import static android.service.timezone.TimeZoneProviderService.TEST_COMMAND_RESULT_SUCCESS_KEY;
 
-import static com.android.server.timezonedetector.location.LocationTimeZoneManagerService.warnLog;
-
-import android.Manifest;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Context;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.content.pm.ServiceInfo;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
@@ -39,11 +34,12 @@
 import android.util.IndentingPrintWriter;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.server.servicewatcher.CurrentUserServiceSupplier;
+import com.android.server.servicewatcher.CurrentUserServiceSupplier.BoundServiceInfo;
 import com.android.server.servicewatcher.ServiceWatcher;
-import com.android.server.servicewatcher.ServiceWatcher.BoundService;
+import com.android.server.servicewatcher.ServiceWatcher.ServiceListener;
 
 import java.util.Objects;
-import java.util.function.Predicate;
 
 /**
  * System server-side proxy for ITimeZoneProvider implementations, i.e. this provides the
@@ -52,7 +48,8 @@
  * different process. As "remote" providers are bound / unbound this proxy will rebind to the "best"
  * available remote process.
  */
-class RealLocationTimeZoneProviderProxy extends LocationTimeZoneProviderProxy {
+class RealLocationTimeZoneProviderProxy extends LocationTimeZoneProviderProxy implements
+        ServiceListener<BoundServiceInfo> {
 
     @NonNull private final ServiceWatcher mServiceWatcher;
 
@@ -69,38 +66,13 @@
         super(context, threadingDomain);
         mManagerProxy = null;
         mRequest = TimeZoneProviderRequest.createStopUpdatesRequest();
-
-        // A predicate that is used to confirm that an intent service can be used as a
-        // location-based TimeZoneProvider. The service must:
-        // 1) Declare android:permission="android.permission.BIND_TIME_ZONE_PROVIDER_SERVICE" - this
-        //    ensures that the provider will only communicate with the system server.
-        // 2) Be in an application that has been granted the
-        //    android.permission.INSTALL_LOCATION_TIME_ZONE_PROVIDER_SERVICE permission. This
-        //    ensures only trusted time zone providers will be discovered.
-        final String requiredClientPermission = Manifest.permission.BIND_TIME_ZONE_PROVIDER_SERVICE;
-        final String requiredPermission =
-                Manifest.permission.INSTALL_LOCATION_TIME_ZONE_PROVIDER_SERVICE;
-        Predicate<ResolveInfo> intentServiceCheckPredicate = resolveInfo -> {
-            ServiceInfo serviceInfo = resolveInfo.serviceInfo;
-
-            boolean hasClientPermissionRequirement =
-                    requiredClientPermission.equals(serviceInfo.permission);
-
-            String packageName = serviceInfo.packageName;
-            PackageManager packageManager = context.getPackageManager();
-            int checkResult = packageManager.checkPermission(requiredPermission, packageName);
-            boolean hasRequiredPermission = checkResult == PERMISSION_GRANTED;
-
-            boolean result = hasClientPermissionRequirement && hasRequiredPermission;
-            if (!result) {
-                warnLog("resolveInfo=" + resolveInfo + " does not meet requirements:"
-                        + " hasClientPermissionRequirement=" + hasClientPermissionRequirement
-                        + ", hasRequiredPermission=" + hasRequiredPermission);
-            }
-            return result;
-        };
-        mServiceWatcher = new ServiceWatcher(context, handler, action, this::onBind, this::onUnbind,
-                enableOverlayResId, nonOverlayPackageResId, intentServiceCheckPredicate);
+        mServiceWatcher = ServiceWatcher.create(context,
+                handler,
+                "RealLocationTimeZoneProviderProxy",
+                new CurrentUserServiceSupplier(context, action, enableOverlayResId,
+                        nonOverlayPackageResId, BIND_TIME_ZONE_PROVIDER_SERVICE,
+                        INSTALL_LOCATION_TIME_ZONE_PROVIDER_SERVICE),
+                this);
     }
 
     @Override
@@ -123,7 +95,8 @@
         return resolves;
     }
 
-    private void onBind(IBinder binder, BoundService boundService) {
+    @Override
+    public void onBind(IBinder binder, BoundServiceInfo boundService) {
         mThreadingDomain.assertCurrentThread();
 
         synchronized (mSharedLock) {
@@ -138,7 +111,8 @@
         }
     }
 
-    private void onUnbind() {
+    @Override
+    public void onUnbind() {
         mThreadingDomain.assertCurrentThread();
 
         synchronized (mSharedLock) {
@@ -199,7 +173,7 @@
         synchronized (mSharedLock) {
             ipw.println("{RealLocationTimeZoneProviderProxy}");
             ipw.println("mRequest=" + mRequest);
-            mServiceWatcher.dump(null, ipw, args);
+            mServiceWatcher.dump(ipw);
         }
     }
 
diff --git a/services/core/java/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneIdValidator.java b/services/core/java/com/android/server/timezonedetector/location/TimeZoneProviderEventPreProcessor.java
similarity index 64%
rename from services/core/java/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneIdValidator.java
rename to services/core/java/com/android/server/timezonedetector/location/TimeZoneProviderEventPreProcessor.java
index cab5ad2..951e9d0 100644
--- a/services/core/java/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneIdValidator.java
+++ b/services/core/java/com/android/server/timezonedetector/location/TimeZoneProviderEventPreProcessor.java
@@ -18,13 +18,16 @@
 
 import android.annotation.NonNull;
 
-import com.android.i18n.timezone.ZoneInfoDb;
+/**
+ * Used by {@link LocationTimeZoneProvider} to ensure that all time zone IDs are understood by the
+ * platform.
+ */
+public interface TimeZoneProviderEventPreProcessor {
 
-class ZoneInfoDbTimeZoneIdValidator implements
-        LocationTimeZoneProvider.TimeZoneIdValidator {
+    /**
+     * May return uncertain event if {@code timeZoneProviderEvent} is ill-formed or drop/rewrite
+     * time zone IDs.
+     */
+    TimeZoneProviderEvent preProcess(@NonNull TimeZoneProviderEvent timeZoneProviderEvent);
 
-    @Override
-    public boolean isValid(@NonNull String timeZoneId) {
-        return ZoneInfoDb.getInstance().hasTimeZone(timeZoneId);
-    }
 }
diff --git a/services/core/java/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneProviderEventPreProcessor.java b/services/core/java/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneProviderEventPreProcessor.java
new file mode 100644
index 0000000..0f4367d
--- /dev/null
+++ b/services/core/java/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneProviderEventPreProcessor.java
@@ -0,0 +1,72 @@
+/*
+ * 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.timezonedetector.location;
+
+import static com.android.server.timezonedetector.location.LocationTimeZoneManagerService.infoLog;
+
+import android.annotation.NonNull;
+
+import com.android.i18n.timezone.ZoneInfoDb;
+
+/**
+ * {@link TimeZoneProviderEventPreProcessor} implementation which makes validations against
+ * {@link ZoneInfoDb}.
+ */
+public class ZoneInfoDbTimeZoneProviderEventPreProcessor
+        implements TimeZoneProviderEventPreProcessor {
+
+    /**
+     * Returns uncertain event if {@code event} has at least one unsupported time zone ID.
+     */
+    @Override
+    public TimeZoneProviderEvent preProcess(@NonNull TimeZoneProviderEvent event) {
+        if (event.getSuggestion() == null || event.getSuggestion().getTimeZoneIds().isEmpty()) {
+            return event;
+        }
+
+        // If the provider has made a suggestion with unknown time zone IDs it cannot be used to set
+        // the device's time zone. This logic prevents bad time zone IDs entering the time zone
+        // detection logic from third party code.
+        //
+        // An event containing an unknown time zone ID could occur if the provider is using a
+        // different TZDB version than the device. Provider developers are expected to take steps to
+        // avoid version skew problem, e.g. by ensuring atomic updates with the platform time zone
+        // rules, or providing IDs based on the device's TZDB version, so this is not considered a
+        // common case.
+        //
+        // Treating a suggestion containing unknown time zone IDs as "uncertain" in the primary
+        // enables immediate failover to a secondary provider, one that might provide valid IDs for
+        // the same location, which should provide better behavior than just ignoring the event.
+        if (hasInvalidZones(event)) {
+            return TimeZoneProviderEvent.createUncertainEvent();
+        }
+
+        return event;
+    }
+
+    private static boolean hasInvalidZones(TimeZoneProviderEvent event) {
+        for (String timeZone : event.getSuggestion().getTimeZoneIds()) {
+            if (!ZoneInfoDb.getInstance().hasTimeZone(timeZone)) {
+                infoLog("event=" + event + " has unsupported zone(" + timeZone + ")");
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+}
diff --git a/services/core/java/com/android/server/vcn/Vcn.java b/services/core/java/com/android/server/vcn/Vcn.java
index 3f74938..89ed956 100644
--- a/services/core/java/com/android/server/vcn/Vcn.java
+++ b/services/core/java/com/android/server/vcn/Vcn.java
@@ -41,6 +41,7 @@
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.Objects;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicBoolean;
@@ -110,6 +111,24 @@
     @NonNull private final VcnNetworkRequestListener mRequestListener;
     @NonNull private final VcnCallback mVcnCallback;
 
+    /**
+     * Map containing all VcnGatewayConnections and their VcnGatewayConnectionConfigs.
+     *
+     * <p>Due to potential for race conditions, VcnGatewayConnections MUST only be created and added
+     * to this map in {@link #handleNetworkRequested(NetworkRequest, int, int)}, when a VCN receives
+     * a NetworkRequest that matches a VcnGatewayConnectionConfig for this VCN's VcnConfig.
+     *
+     * <p>A VcnGatewayConnection instance MUST NEVER overwrite an existing instance - otherwise
+     * there is potential for a orphaned VcnGatewayConnection instance that does not get properly
+     * shut down.
+     *
+     * <p>Due to potential for race conditions, VcnGatewayConnections MUST only be removed from this
+     * map once they have finished tearing down, which is reported to this VCN via {@link
+     * VcnGatewayStatusCallback#onQuit()}. Once this is done, all NetworkRequests are retrieved from
+     * the NetworkProvider so that another VcnGatewayConnectionConfig can match the
+     * previously-matched request.
+     */
+    // TODO(b/182533200): remove the invariant on VcnGatewayConnection lifecycles
     @NonNull
     private final Map<VcnGatewayConnectionConfig, VcnGatewayConnection> mVcnGatewayConnections =
             new HashMap<>();
@@ -191,6 +210,19 @@
         return Collections.unmodifiableSet(new HashSet<>(mVcnGatewayConnections.values()));
     }
 
+    /** Get current Configs and Gateways for testing purposes */
+    @VisibleForTesting(visibility = Visibility.PRIVATE)
+    public Map<VcnGatewayConnectionConfig, VcnGatewayConnection>
+            getVcnGatewayConnectionConfigMap() {
+        return Collections.unmodifiableMap(new HashMap<>(mVcnGatewayConnections));
+    }
+
+    /** Set whether this Vcn is active for testing purposes */
+    @VisibleForTesting(visibility = Visibility.PRIVATE)
+    public void setIsActive(boolean isActive) {
+        mIsActive.set(isActive);
+    }
+
     private class VcnNetworkRequestListener implements VcnNetworkProvider.NetworkRequestListener {
         @Override
         public void onNetworkRequested(@NonNull NetworkRequest request, int score, int providerId) {
@@ -202,11 +234,6 @@
 
     @Override
     public void handleMessage(@NonNull Message msg) {
-        // Ignore if this Vcn is not active and we're not receiving new configs
-        if (!isActive() && msg.what != MSG_EVENT_CONFIG_UPDATED) {
-            return;
-        }
-
         switch (msg.what) {
             case MSG_EVENT_CONFIG_UPDATED:
                 handleConfigUpdated((VcnConfig) msg.obj);
@@ -237,9 +264,31 @@
 
         mConfig = config;
 
-        // TODO(b/181815405): Reevaluate active VcnGatewayConnection(s)
+        if (mIsActive.getAndSet(true)) {
+            // VCN is already active - teardown any GatewayConnections whose configs have been
+            // removed and get all current requests
+            for (final Entry<VcnGatewayConnectionConfig, VcnGatewayConnection> entry :
+                    mVcnGatewayConnections.entrySet()) {
+                final VcnGatewayConnectionConfig gatewayConnectionConfig = entry.getKey();
+                final VcnGatewayConnection gatewayConnection = entry.getValue();
 
-        if (!mIsActive.getAndSet(true)) {
+                // GatewayConnectionConfigs must match exactly (otherwise authentication or
+                // connection details may have changed).
+                if (!mConfig.getGatewayConnectionConfigs().contains(gatewayConnectionConfig)) {
+                    if (gatewayConnection == null) {
+                        Slog.wtf(
+                                getLogTag(),
+                                "Found gatewayConnectionConfig without GatewayConnection");
+                    } else {
+                        gatewayConnection.teardownAsynchronously();
+                    }
+                }
+            }
+
+            // Trigger a re-evaluation of all NetworkRequests (to make sure any that can be
+            // satisfied start a new GatewayConnection)
+            mVcnContext.getVcnNetworkProvider().resendAllRequests(mRequestListener);
+        } else {
             // If this VCN was not previously active, it is exiting Safe Mode. Re-register the
             // request listener to get NetworkRequests again (and all cached requests).
             mVcnContext.getVcnNetworkProvider().registerListener(mRequestListener);
@@ -259,13 +308,16 @@
     private void handleEnterSafeMode() {
         handleTeardown();
 
-        mVcnGatewayConnections.clear();
-
         mVcnCallback.onEnteredSafeMode();
     }
 
     private void handleNetworkRequested(
             @NonNull NetworkRequest request, int score, int providerId) {
+        if (!isActive()) {
+            Slog.v(getLogTag(), "Received NetworkRequest while inactive. Ignore for now");
+            return;
+        }
+
         if (score > getNetworkScore()) {
             if (VDBG) {
                 Slog.v(
@@ -318,8 +370,10 @@
         mVcnGatewayConnections.remove(config);
 
         // Trigger a re-evaluation of all NetworkRequests (to make sure any that can be satisfied
-        // start a new GatewayConnection)
-        mVcnContext.getVcnNetworkProvider().resendAllRequests(mRequestListener);
+        // start a new GatewayConnection), but only if the Vcn is still active
+        if (isActive()) {
+            mVcnContext.getVcnNetworkProvider().resendAllRequests(mRequestListener);
+        }
     }
 
     private void handleSubscriptionsChanged(@NonNull TelephonySubscriptionSnapshot snapshot) {
diff --git a/services/core/java/com/android/server/vibrator/DeviceVibrationEffectAdapter.java b/services/core/java/com/android/server/vibrator/DeviceVibrationEffectAdapter.java
new file mode 100644
index 0000000..7f2b07b
--- /dev/null
+++ b/services/core/java/com/android/server/vibrator/DeviceVibrationEffectAdapter.java
@@ -0,0 +1,174 @@
+/*
+ * 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.vibrator;
+
+import android.hardware.vibrator.IVibrator;
+import android.os.VibrationEffect;
+import android.os.VibratorInfo;
+import android.os.vibrator.RampSegment;
+import android.os.vibrator.StepSegment;
+import android.os.vibrator.VibrationEffectSegment;
+import android.util.MathUtils;
+import android.util.Range;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/** Adapts a {@link VibrationEffect} to a specific device, taking into account its capabilities. */
+final class DeviceVibrationEffectAdapter implements VibrationEffectModifier<VibratorInfo> {
+
+    /** Adapts a sequence of {@link VibrationEffectSegment} to device's capabilities. */
+    interface SegmentsAdapter {
+
+        /**
+         * Modifies the given segments list by adding/removing segments to it based on the
+         * device capabilities specified by given {@link VibratorInfo}.
+         *
+         * @param segments    List of {@link VibrationEffectSegment} to be adapter to the device.
+         * @param repeatIndex Repeat index on the current segment list.
+         * @param info        The device vibrator info that the segments must be adapted to.
+         * @return The new repeat index on the modifies list.
+         */
+        int apply(List<VibrationEffectSegment> segments, int repeatIndex, VibratorInfo info);
+    }
+
+    private final SegmentsAdapter mAmplitudeFrequencyAdapter;
+    private final SegmentsAdapter mStepToRampAdapter;
+
+    DeviceVibrationEffectAdapter() {
+        this(new ClippingAmplitudeFrequencyAdapter());
+    }
+
+    DeviceVibrationEffectAdapter(SegmentsAdapter amplitudeFrequencyAdapter) {
+        mAmplitudeFrequencyAdapter = amplitudeFrequencyAdapter;
+        mStepToRampAdapter = new StepToRampAdapter();
+    }
+
+    @Override
+    public VibrationEffect apply(VibrationEffect effect, VibratorInfo info) {
+        if (!(effect instanceof VibrationEffect.Composed)) {
+            return effect;
+        }
+
+        VibrationEffect.Composed composed = (VibrationEffect.Composed) effect;
+        List<VibrationEffectSegment> newSegments = new ArrayList<>(composed.getSegments());
+        int newRepeatIndex = composed.getRepeatIndex();
+
+        // Maps steps that should be handled by PWLE to ramps.
+        // This should be done before frequency is converted from relative to absolute values.
+        newRepeatIndex = mStepToRampAdapter.apply(newSegments, newRepeatIndex, info);
+
+        // Adapt amplitude and frequency values to device supported ones, converting frequency
+        // to absolute values in Hertz.
+        newRepeatIndex = mAmplitudeFrequencyAdapter.apply(newSegments, newRepeatIndex, info);
+
+        // TODO(b/167947076): add ramp to step adapter
+        // TODO(b/167947076): add filter that removes unsupported primitives
+        // TODO(b/167947076): add filter that replaces unsupported prebaked with fallback
+
+        return new VibrationEffect.Composed(newSegments, newRepeatIndex);
+    }
+
+    /**
+     * Adapter that converts step segments that should be handled as PWLEs to ramp segments.
+     *
+     * <p>This leves the list unchanged if the device do not have compose PWLE capability.
+     */
+    private static final class StepToRampAdapter implements SegmentsAdapter {
+        @Override
+        public int apply(List<VibrationEffectSegment> segments, int repeatIndex,
+                VibratorInfo info) {
+            if (!info.hasCapability(IVibrator.CAP_COMPOSE_PWLE_EFFECTS)) {
+                // The vibrator do not have PWLE capability, so keep the segments unchanged.
+                return repeatIndex;
+            }
+            int segmentCount = segments.size();
+            // Convert steps that require frequency control to ramps.
+            for (int i = 0; i < segmentCount; i++) {
+                VibrationEffectSegment segment = segments.get(i);
+                if ((segment instanceof StepSegment)
+                        && ((StepSegment) segment).getFrequency() != 0) {
+                    segments.set(i, apply((StepSegment) segment));
+                }
+            }
+            // Convert steps that are next to ramps to also become ramps, so they can be composed
+            // together in the same PWLE waveform.
+            for (int i = 1; i < segmentCount; i++) {
+                if (segments.get(i) instanceof RampSegment) {
+                    for (int j = i - 1; j >= 0 && (segments.get(j) instanceof StepSegment); j--) {
+                        segments.set(j, apply((StepSegment) segments.get(j)));
+                    }
+                }
+            }
+            return repeatIndex;
+        }
+
+        private RampSegment apply(StepSegment segment) {
+            return new RampSegment(segment.getAmplitude(), segment.getAmplitude(),
+                    segment.getFrequency(), segment.getFrequency(), (int) segment.getDuration());
+        }
+    }
+
+    /**
+     * Adapter that clips frequency values to {@link VibratorInfo#getFrequencyRange()} and
+     * amplitude values to respective {@link VibratorInfo#getMaxAmplitude}.
+     *
+     * <p>Devices with no frequency control will collapse all frequencies to zero and leave
+     * amplitudes unchanged.
+     *
+     * <p>The frequency value returned in segments will be absolute, conveted with
+     * {@link VibratorInfo#getAbsoluteFrequency(float)}.
+     */
+    private static final class ClippingAmplitudeFrequencyAdapter implements SegmentsAdapter {
+        @Override
+        public int apply(List<VibrationEffectSegment> segments, int repeatIndex,
+                VibratorInfo info) {
+            int segmentCount = segments.size();
+            for (int i = 0; i < segmentCount; i++) {
+                VibrationEffectSegment segment = segments.get(i);
+                if (segment instanceof StepSegment) {
+                    segments.set(i, apply((StepSegment) segment, info));
+                } else if (segment instanceof RampSegment) {
+                    segments.set(i, apply((RampSegment) segment, info));
+                }
+            }
+            return repeatIndex;
+        }
+
+        private StepSegment apply(StepSegment segment, VibratorInfo info) {
+            float clampedFrequency = info.getFrequencyRange().clamp(segment.getFrequency());
+            return new StepSegment(
+                    MathUtils.min(segment.getAmplitude(), info.getMaxAmplitude(clampedFrequency)),
+                    info.getAbsoluteFrequency(clampedFrequency),
+                    (int) segment.getDuration());
+        }
+
+        private RampSegment apply(RampSegment segment, VibratorInfo info) {
+            Range<Float> frequencyRange = info.getFrequencyRange();
+            float clampedStartFrequency = frequencyRange.clamp(segment.getStartFrequency());
+            float clampedEndFrequency = frequencyRange.clamp(segment.getEndFrequency());
+            return new RampSegment(
+                    MathUtils.min(segment.getStartAmplitude(),
+                            info.getMaxAmplitude(clampedStartFrequency)),
+                    MathUtils.min(segment.getEndAmplitude(),
+                            info.getMaxAmplitude(clampedEndFrequency)),
+                    info.getAbsoluteFrequency(clampedStartFrequency),
+                    info.getAbsoluteFrequency(clampedEndFrequency),
+                    (int) segment.getDuration());
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/vibrator/Vibration.java b/services/core/java/com/android/server/vibrator/Vibration.java
index e84ee672..cd84058 100644
--- a/services/core/java/com/android/server/vibrator/Vibration.java
+++ b/services/core/java/com/android/server/vibrator/Vibration.java
@@ -16,17 +16,24 @@
 
 package com.android.server.vibrator;
 
-import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.os.CombinedVibrationEffect;
 import android.os.IBinder;
 import android.os.SystemClock;
 import android.os.VibrationAttributes;
 import android.os.VibrationEffect;
+import android.os.vibrator.PrebakedSegment;
+import android.os.vibrator.PrimitiveSegment;
+import android.os.vibrator.RampSegment;
+import android.os.vibrator.StepSegment;
+import android.os.vibrator.VibrationEffectSegment;
+import android.util.SparseArray;
 import android.util.proto.ProtoOutputStream;
 
 import java.text.SimpleDateFormat;
 import java.util.Date;
+import java.util.List;
+import java.util.function.Function;
 
 /** Represents a vibration request to the vibrator service. */
 final class Vibration {
@@ -61,6 +68,7 @@
     public final String opPkg;
     public final String reason;
     public final IBinder token;
+    public final SparseArray<VibrationEffect> mFallbacks = new SparseArray<>();
 
     /** The actual effect to be played. */
     @Nullable
@@ -113,17 +121,70 @@
     }
 
     /**
-     * Replace this vibration effect if given {@code scaledEffect} is different, preserving the
-     * original one for debug purposes.
+     * Return the effect to be played when given prebaked effect id is not supported by the
+     * vibrator.
      */
-    public void updateEffect(@NonNull CombinedVibrationEffect newEffect) {
-        if (newEffect.equals(mEffect)) {
-            return;
+    @Nullable
+    public VibrationEffect getFallback(int effectId) {
+        return mFallbacks.get(effectId);
+    }
+
+    /**
+     * Add a fallback {@link VibrationEffect} to be played when given effect id is not supported,
+     * which might be necessary for replacement in realtime.
+     */
+    public void addFallback(int effectId, VibrationEffect effect) {
+        mFallbacks.put(effectId, effect);
+    }
+
+    /**
+     * Applied update function to the current effect held by this vibration, and to each fallback
+     * effect added.
+     */
+    public void updateEffects(Function<VibrationEffect, VibrationEffect> updateFn) {
+        CombinedVibrationEffect newEffect = transformCombinedEffect(mEffect, updateFn);
+        if (!newEffect.equals(mEffect)) {
+            if (mOriginalEffect == null) {
+                mOriginalEffect = mEffect;
+            }
+            mEffect = newEffect;
         }
-        if (mOriginalEffect == null) {
-            mOriginalEffect = mEffect;
+        for (int i = 0; i < mFallbacks.size(); i++) {
+            mFallbacks.setValueAt(i, updateFn.apply(mFallbacks.valueAt(i)));
         }
-        mEffect = newEffect;
+    }
+
+    /**
+     * Creates a new {@link CombinedVibrationEffect} by applying the given transformation function
+     * to each {@link VibrationEffect}.
+     */
+    private static CombinedVibrationEffect transformCombinedEffect(
+            CombinedVibrationEffect combinedEffect, Function<VibrationEffect, VibrationEffect> fn) {
+        if (combinedEffect instanceof CombinedVibrationEffect.Mono) {
+            VibrationEffect effect = ((CombinedVibrationEffect.Mono) combinedEffect).getEffect();
+            return CombinedVibrationEffect.createSynced(fn.apply(effect));
+        } else if (combinedEffect instanceof CombinedVibrationEffect.Stereo) {
+            SparseArray<VibrationEffect> effects =
+                    ((CombinedVibrationEffect.Stereo) combinedEffect).getEffects();
+            CombinedVibrationEffect.SyncedCombination combination =
+                    CombinedVibrationEffect.startSynced();
+            for (int i = 0; i < effects.size(); i++) {
+                combination.addVibrator(effects.keyAt(i), fn.apply(effects.valueAt(i)));
+            }
+            return combination.combine();
+        } else if (combinedEffect instanceof CombinedVibrationEffect.Sequential) {
+            List<CombinedVibrationEffect> effects =
+                    ((CombinedVibrationEffect.Sequential) combinedEffect).getEffects();
+            CombinedVibrationEffect.SequentialCombination combination =
+                    CombinedVibrationEffect.startSequential();
+            for (CombinedVibrationEffect effect : effects) {
+                combination.addNext(transformCombinedEffect(effect, fn));
+            }
+            return combination.combine();
+        } else {
+            // Unknown combination, return same effect.
+            return combinedEffect;
+        }
     }
 
     /** Return true is current status is different from {@link Status#RUNNING}. */
@@ -272,57 +333,62 @@
         private void dumpEffect(
                 ProtoOutputStream proto, long fieldId, VibrationEffect effect) {
             final long token = proto.start(fieldId);
-            if (effect instanceof VibrationEffect.OneShot) {
-                dumpEffect(proto, VibrationEffectProto.ONESHOT, (VibrationEffect.OneShot) effect);
-            } else if (effect instanceof VibrationEffect.Waveform) {
-                dumpEffect(proto, VibrationEffectProto.WAVEFORM, (VibrationEffect.Waveform) effect);
-            } else if (effect instanceof VibrationEffect.Prebaked) {
-                dumpEffect(proto, VibrationEffectProto.PREBAKED, (VibrationEffect.Prebaked) effect);
-            } else if (effect instanceof VibrationEffect.Composed) {
-                dumpEffect(proto, VibrationEffectProto.COMPOSED, (VibrationEffect.Composed) effect);
+            VibrationEffect.Composed composed = (VibrationEffect.Composed) effect;
+            for (VibrationEffectSegment segment : composed.getSegments()) {
+                dumpEffect(proto, VibrationEffectProto.SEGMENTS, segment);
             }
+            proto.write(VibrationEffectProto.REPEAT, composed.getRepeatIndex());
             proto.end(token);
         }
 
         private void dumpEffect(ProtoOutputStream proto, long fieldId,
-                VibrationEffect.OneShot effect) {
+                VibrationEffectSegment segment) {
             final long token = proto.start(fieldId);
-            proto.write(OneShotProto.DURATION, (int) effect.getDuration());
-            proto.write(OneShotProto.AMPLITUDE, effect.getAmplitude());
+            if (segment instanceof StepSegment) {
+                dumpEffect(proto, SegmentProto.STEP, (StepSegment) segment);
+            } else if (segment instanceof RampSegment) {
+                dumpEffect(proto, SegmentProto.RAMP, (RampSegment) segment);
+            } else if (segment instanceof PrebakedSegment) {
+                dumpEffect(proto, SegmentProto.PREBAKED, (PrebakedSegment) segment);
+            } else if (segment instanceof PrimitiveSegment) {
+                dumpEffect(proto, SegmentProto.PRIMITIVE, (PrimitiveSegment) segment);
+            }
+            proto.end(token);
+        }
+
+        private void dumpEffect(ProtoOutputStream proto, long fieldId, StepSegment segment) {
+            final long token = proto.start(fieldId);
+            proto.write(StepSegmentProto.DURATION, segment.getDuration());
+            proto.write(StepSegmentProto.AMPLITUDE, segment.getAmplitude());
+            proto.write(StepSegmentProto.FREQUENCY, segment.getFrequency());
+            proto.end(token);
+        }
+
+        private void dumpEffect(ProtoOutputStream proto, long fieldId, RampSegment segment) {
+            final long token = proto.start(fieldId);
+            proto.write(RampSegmentProto.DURATION, segment.getDuration());
+            proto.write(RampSegmentProto.START_AMPLITUDE, segment.getStartAmplitude());
+            proto.write(RampSegmentProto.END_AMPLITUDE, segment.getEndAmplitude());
+            proto.write(RampSegmentProto.START_FREQUENCY, segment.getStartFrequency());
+            proto.write(RampSegmentProto.END_FREQUENCY, segment.getEndFrequency());
             proto.end(token);
         }
 
         private void dumpEffect(ProtoOutputStream proto, long fieldId,
-                VibrationEffect.Waveform effect) {
+                PrebakedSegment segment) {
             final long token = proto.start(fieldId);
-            for (long timing : effect.getTimings()) {
-                proto.write(WaveformProto.TIMINGS, (int) timing);
-            }
-            for (int amplitude : effect.getAmplitudes()) {
-                proto.write(WaveformProto.AMPLITUDES, amplitude);
-            }
-            proto.write(WaveformProto.REPEAT, effect.getRepeatIndex() >= 0);
+            proto.write(PrebakedSegmentProto.EFFECT_ID, segment.getEffectId());
+            proto.write(PrebakedSegmentProto.EFFECT_STRENGTH, segment.getEffectStrength());
+            proto.write(PrebakedSegmentProto.FALLBACK, segment.shouldFallback());
             proto.end(token);
         }
 
         private void dumpEffect(ProtoOutputStream proto, long fieldId,
-                VibrationEffect.Prebaked effect) {
+                PrimitiveSegment segment) {
             final long token = proto.start(fieldId);
-            proto.write(PrebakedProto.EFFECT_ID, effect.getId());
-            proto.write(PrebakedProto.EFFECT_STRENGTH, effect.getEffectStrength());
-            proto.write(PrebakedProto.FALLBACK, effect.shouldFallback());
-            proto.end(token);
-        }
-
-        private void dumpEffect(ProtoOutputStream proto, long fieldId,
-                VibrationEffect.Composed effect) {
-            final long token = proto.start(fieldId);
-            for (VibrationEffect.Composition.PrimitiveEffect primitive :
-                    effect.getPrimitiveEffects()) {
-                proto.write(ComposedProto.EFFECT_IDS, primitive.id);
-                proto.write(ComposedProto.EFFECT_SCALES, primitive.scale);
-                proto.write(ComposedProto.DELAYS, primitive.delay);
-            }
+            proto.write(PrimitiveSegmentProto.PRIMITIVE_ID, segment.getPrimitiveId());
+            proto.write(PrimitiveSegmentProto.SCALE, segment.getScale());
+            proto.write(PrimitiveSegmentProto.DELAY, segment.getDelay());
             proto.end(token);
         }
     }
diff --git a/services/core/java/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneIdValidator.java b/services/core/java/com/android/server/vibrator/VibrationEffectModifier.java
similarity index 61%
copy from services/core/java/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneIdValidator.java
copy to services/core/java/com/android/server/vibrator/VibrationEffectModifier.java
index cab5ad2..d287c8f 100644
--- a/services/core/java/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneIdValidator.java
+++ b/services/core/java/com/android/server/vibrator/VibrationEffectModifier.java
@@ -14,17 +14,13 @@
  * limitations under the License.
  */
 
-package com.android.server.timezonedetector.location;
+package com.android.server.vibrator;
 
-import android.annotation.NonNull;
+import android.os.VibrationEffect;
 
-import com.android.i18n.timezone.ZoneInfoDb;
+/** Function that applies a generic modifier to a {@link VibrationEffect}. */
+interface VibrationEffectModifier<T> {
 
-class ZoneInfoDbTimeZoneIdValidator implements
-        LocationTimeZoneProvider.TimeZoneIdValidator {
-
-    @Override
-    public boolean isValid(@NonNull String timeZoneId) {
-        return ZoneInfoDb.getInstance().hasTimeZone(timeZoneId);
-    }
+    /** Applies the modifier to given {@link VibrationEffect}. */
+    VibrationEffect apply(VibrationEffect effect, T modifier);
 }
diff --git a/services/core/java/com/android/server/vibrator/VibrationScaler.java b/services/core/java/com/android/server/vibrator/VibrationScaler.java
index 10393f6..f481772 100644
--- a/services/core/java/com/android/server/vibrator/VibrationScaler.java
+++ b/services/core/java/com/android/server/vibrator/VibrationScaler.java
@@ -18,16 +18,13 @@
 
 import android.content.Context;
 import android.hardware.vibrator.V1_0.EffectStrength;
-import android.os.CombinedVibrationEffect;
 import android.os.IExternalVibratorService;
 import android.os.VibrationEffect;
 import android.os.Vibrator;
+import android.os.vibrator.PrebakedSegment;
 import android.util.Slog;
 import android.util.SparseArray;
 
-import java.util.List;
-import java.util.Objects;
-
 /** Controls vibration scaling. */
 final class VibrationScaler {
     private static final String TAG = "VibrationScaler";
@@ -90,43 +87,6 @@
     }
 
     /**
-     * Scale a {@link CombinedVibrationEffect} based on the given usage hint for this vibration.
-     *
-     * @param combinedEffect the effect to be scaled
-     * @param usageHint      one of VibrationAttributes.USAGE_*
-     * @return The same given effect, if no changes were made, or a new
-     * {@link CombinedVibrationEffect} with resolved and scaled amplitude
-     */
-    public <T extends CombinedVibrationEffect> T scale(CombinedVibrationEffect combinedEffect,
-            int usageHint) {
-        if (combinedEffect instanceof CombinedVibrationEffect.Mono) {
-            VibrationEffect effect = ((CombinedVibrationEffect.Mono) combinedEffect).getEffect();
-            return (T) CombinedVibrationEffect.createSynced(scale(effect, usageHint));
-        } else if (combinedEffect instanceof CombinedVibrationEffect.Stereo) {
-            SparseArray<VibrationEffect> effects =
-                    ((CombinedVibrationEffect.Stereo) combinedEffect).getEffects();
-            CombinedVibrationEffect.SyncedCombination combination =
-                    CombinedVibrationEffect.startSynced();
-            for (int i = 0; i < effects.size(); i++) {
-                combination.addVibrator(effects.keyAt(i), scale(effects.valueAt(i), usageHint));
-            }
-            return (T) combination.combine();
-        } else if (combinedEffect instanceof CombinedVibrationEffect.Sequential) {
-            List<CombinedVibrationEffect> effects =
-                    ((CombinedVibrationEffect.Sequential) combinedEffect).getEffects();
-            CombinedVibrationEffect.SequentialCombination combination =
-                    CombinedVibrationEffect.startSequential();
-            for (CombinedVibrationEffect effect : effects) {
-                combination.addNext(scale(effect, usageHint));
-            }
-            return (T) combination.combine();
-        } else {
-            // Unknown combination, return same effect.
-            return (T) combinedEffect;
-        }
-    }
-
-    /**
      * Scale a {@link VibrationEffect} based on the given usage hint for this vibration.
      *
      * @param effect    the effect to be scaled
@@ -135,33 +95,10 @@
      * resolved and scaled amplitude
      */
     public <T extends VibrationEffect> T scale(VibrationEffect effect, int usageHint) {
-        if (effect instanceof VibrationEffect.Prebaked) {
-            // Prebaked effects are always just a direct translation to EffectStrength.
-            int intensity = mSettingsController.getCurrentIntensity(usageHint);
-            int newStrength = intensityToEffectStrength(intensity);
-            VibrationEffect.Prebaked prebaked = (VibrationEffect.Prebaked) effect;
-            int strength = prebaked.getEffectStrength();
-            VibrationEffect fallback = prebaked.getFallbackEffect();
-
-            if (fallback != null) {
-                VibrationEffect scaledFallback = scale(fallback, usageHint);
-                if (strength == newStrength && Objects.equals(fallback, scaledFallback)) {
-                    return (T) prebaked;
-                }
-
-                return (T) new VibrationEffect.Prebaked(prebaked.getId(), newStrength,
-                        scaledFallback);
-            } else if (strength == newStrength) {
-                return (T) prebaked;
-            } else {
-                return (T) new VibrationEffect.Prebaked(prebaked.getId(), prebaked.shouldFallback(),
-                        newStrength);
-            }
-        }
-
-        effect = effect.resolve(mDefaultVibrationAmplitude);
         int defaultIntensity = mSettingsController.getDefaultIntensity(usageHint);
         int currentIntensity = mSettingsController.getCurrentIntensity(usageHint);
+        int newEffectStrength = intensityToEffectStrength(currentIntensity);
+        effect = effect.applyEffectStrength(newEffectStrength).resolve(mDefaultVibrationAmplitude);
         ScaleLevel scale = mScaleLevels.get(currentIntensity - defaultIntensity);
 
         if (scale == null) {
@@ -171,7 +108,21 @@
             return (T) effect;
         }
 
-        return effect.scale(scale.factor);
+        return (T) effect.scale(scale.factor);
+    }
+
+    /**
+     * Scale a {@link PrebakedSegment} based on the given usage hint for this vibration.
+     *
+     * @param prebaked  the prebaked segment to be scaled
+     * @param usageHint one of VibrationAttributes.USAGE_*
+     * @return The same segment if no changes were made, or a new {@link PrebakedSegment} with
+     * updated effect strength
+     */
+    public PrebakedSegment scale(PrebakedSegment prebaked, int usageHint) {
+        int currentIntensity = mSettingsController.getCurrentIntensity(usageHint);
+        int newEffectStrength = intensityToEffectStrength(currentIntensity);
+        return prebaked.applyEffectStrength(newEffectStrength);
     }
 
     /** Mapping of Vibrator.VIBRATION_INTENSITY_* values to {@link EffectStrength}. */
diff --git a/services/core/java/com/android/server/vibrator/VibrationThread.java b/services/core/java/com/android/server/vibrator/VibrationThread.java
index b90408f..df85e26 100644
--- a/services/core/java/com/android/server/vibrator/VibrationThread.java
+++ b/services/core/java/com/android/server/vibrator/VibrationThread.java
@@ -27,7 +27,13 @@
 import android.os.SystemClock;
 import android.os.Trace;
 import android.os.VibrationEffect;
+import android.os.VibratorInfo;
 import android.os.WorkSource;
+import android.os.vibrator.PrebakedSegment;
+import android.os.vibrator.PrimitiveSegment;
+import android.os.vibrator.RampSegment;
+import android.os.vibrator.StepSegment;
+import android.os.vibrator.VibrationEffectSegment;
 import android.util.Slog;
 import android.util.SparseArray;
 
@@ -87,6 +93,8 @@
     private final WorkSource mWorkSource = new WorkSource();
     private final PowerManager.WakeLock mWakeLock;
     private final IBatteryStats mBatteryStatsService;
+    private final VibrationEffectModifier<VibratorInfo> mDeviceEffectAdapter =
+            new DeviceVibrationEffectAdapter();
     private final Vibration mVibration;
     private final VibrationCallbacks mCallbacks;
     private final SparseArray<VibratorController> mVibrators = new SparseArray<>();
@@ -244,32 +252,38 @@
         }
     }
 
-    /**
-     * Get the duration the vibrator will be on for given {@code waveform}, starting at {@code
-     * startIndex} until the next time it's vibrating amplitude is zero.
-     */
-    private static long getVibratorOnDuration(VibrationEffect.Waveform waveform, int startIndex) {
-        long[] timings = waveform.getTimings();
-        int[] amplitudes = waveform.getAmplitudes();
-        int repeatIndex = waveform.getRepeatIndex();
-        int i = startIndex;
-        long timing = 0;
-        while (timings[i] == 0 || amplitudes[i] != 0) {
-            timing += timings[i++];
-            if (i >= timings.length) {
-                if (repeatIndex >= 0) {
-                    i = repeatIndex;
-                    // prevent infinite loop
-                    repeatIndex = -1;
-                } else {
-                    break;
-                }
-            }
-            if (i == startIndex) {
-                return 1000;
+    @Nullable
+    private SingleVibratorStep nextVibrateStep(long startTime, VibratorController controller,
+            VibrationEffect.Composed effect, int segmentIndex, long vibratorOffTimeout) {
+        // Some steps should only start after the vibrator has finished the previous vibration, so
+        // make sure we take the latest between both timings.
+        long latestStartTime = Math.max(startTime, vibratorOffTimeout);
+        if (segmentIndex >= effect.getSegments().size()) {
+            segmentIndex = effect.getRepeatIndex();
+        }
+        if (segmentIndex < 0) {
+            if (vibratorOffTimeout > SystemClock.uptimeMillis()) {
+                // No more segments to play, last step is to wait for the vibrator to complete
+                return new OffStep(vibratorOffTimeout, controller);
+            } else {
+                return null;
             }
         }
-        return timing;
+
+        VibrationEffectSegment segment = effect.getSegments().get(segmentIndex);
+        if (segment instanceof PrebakedSegment) {
+            return new PerformStep(latestStartTime, controller, effect, segmentIndex,
+                    vibratorOffTimeout);
+        }
+        if (segment instanceof PrimitiveSegment) {
+            return new ComposePrimitivesStep(latestStartTime, controller, effect, segmentIndex,
+                    vibratorOffTimeout);
+        }
+        if (segment instanceof RampSegment) {
+            return new ComposePwleStep(latestStartTime, controller, effect, segmentIndex,
+                    vibratorOffTimeout);
+        }
+        return new AmplitudeStep(startTime, controller, effect, segmentIndex, vibratorOffTimeout);
     }
 
     private static CombinedVibrationEffect.Sequential toSequential(CombinedVibrationEffect effect) {
@@ -437,8 +451,13 @@
                 duration = startVibrating(effectMapping, nextSteps);
                 noteVibratorOn(duration);
             } finally {
-                // If this step triggered any vibrator then add a finish step to wait for all
+                if (duration < 0) {
+                    // Something failed while playing this step so stop playing this sequence.
+                    return EMPTY_STEP_LIST;
+                }
+                // It least one vibrator was started then add a finish step to wait for all
                 // active vibrators to finish their individual steps before going to the next.
+                // Otherwise this step was ignored so just go to the next one.
                 Step nextStep = duration > 0 ? new FinishVibrateStep(this) : nextStep();
                 if (nextStep != null) {
                     nextSteps.add(nextStep);
@@ -494,11 +513,13 @@
                 return 0;
             }
 
-            VibratorOnStep[] steps = new VibratorOnStep[vibratorCount];
+            SingleVibratorStep[] steps = new SingleVibratorStep[vibratorCount];
             long vibrationStartTime = SystemClock.uptimeMillis();
             for (int i = 0; i < vibratorCount; i++) {
-                steps[i] = new VibratorOnStep(vibrationStartTime,
-                        mVibrators.get(effectMapping.vibratorIdAt(i)), effectMapping.effectAt(i));
+                steps[i] = nextVibrateStep(vibrationStartTime,
+                        mVibrators.get(effectMapping.vibratorIdAt(i)),
+                        effectMapping.effectAt(i),
+                        /* segmentIndex= */ 0, /* vibratorOffTimeout= */ 0);
             }
 
             if (steps.length == 1) {
@@ -512,35 +533,52 @@
             synchronized (mLock) {
                 boolean hasPrepared = false;
                 boolean hasTriggered = false;
+                long maxDuration = 0;
                 try {
                     hasPrepared = mCallbacks.prepareSyncedVibration(
                             effectMapping.getRequiredSyncCapabilities(),
                             effectMapping.getVibratorIds());
 
-                    long duration = 0;
-                    for (VibratorOnStep step : steps) {
-                        duration = Math.max(duration, startVibrating(step, nextSteps));
+                    for (SingleVibratorStep step : steps) {
+                        long duration = startVibrating(step, nextSteps);
+                        if (duration < 0) {
+                            // One vibrator has failed, fail this entire sync attempt.
+                            return maxDuration = -1;
+                        }
+                        maxDuration = Math.max(maxDuration, duration);
                     }
 
                     // Check if sync was prepared and if any step was accepted by a vibrator,
                     // otherwise there is nothing to trigger here.
-                    if (hasPrepared && duration > 0) {
+                    if (hasPrepared && maxDuration > 0) {
                         hasTriggered = mCallbacks.triggerSyncedVibration(mVibration.id);
                     }
-                    return duration;
+                    return maxDuration;
                 } finally {
                     if (hasPrepared && !hasTriggered) {
                         // Trigger has failed or all steps were ignored by the vibrators.
                         mCallbacks.cancelSyncedVibration();
-                        return 0;
+                        nextSteps.clear();
+                    } else if (maxDuration < 0) {
+                        // Some vibrator failed without being prepared so other vibrators might be
+                        // active. Cancel and remove every pending step from output list.
+                        for (int i = nextSteps.size() - 1; i >= 0; i--) {
+                            nextSteps.remove(i).cancel();
+                        }
                     }
                 }
             }
         }
 
-        private long startVibrating(VibratorOnStep step, List<Step> nextSteps) {
+        private long startVibrating(SingleVibratorStep step, List<Step> nextSteps) {
             nextSteps.addAll(step.play());
-            return step.getDuration();
+            long stepDuration = step.getOnResult();
+            if (stepDuration < 0) {
+                // Step failed, so return negative duration to propagate failure.
+                return stepDuration;
+            }
+            // Return the longest estimation for the entire effect.
+            return Math.max(stepDuration, step.effect.getDuration());
         }
     }
 
@@ -580,90 +618,274 @@
     }
 
     /**
-     * Represent a step turn the vibrator on.
-     *
-     * <p>No other calls to the vibrator is made from this step, so this can be played in between
-     * calls to 'prepare' and 'trigger' for synchronized vibrations.
+     * Represent a step on a single vibrator that plays one or more segments from a
+     * {@link VibrationEffect.Composed} effect.
      */
-    private final class VibratorOnStep extends Step {
+    private abstract class SingleVibratorStep extends Step {
         public final VibratorController controller;
-        public final VibrationEffect effect;
-        private long mDuration;
+        public final VibrationEffect.Composed effect;
+        public final int segmentIndex;
+        public final long vibratorOffTimeout;
 
-        VibratorOnStep(long startTime, VibratorController controller, VibrationEffect effect) {
+        long mVibratorOnResult;
+
+        /**
+         * @param startTime          The time to schedule this step in the {@link StepQueue}.
+         * @param controller         The vibrator that is playing the effect.
+         * @param effect             The effect being played in this step.
+         * @param index              The index of the next segment to be played by this step
+         * @param vibratorOffTimeout The time the vibrator is expected to complete any previous
+         *                           vibration and turn off. This is used to allow this step to be
+         *                           anticipated when the completion callback is triggered, and can
+         *                           be used play effects back-to-back.
+         */
+        SingleVibratorStep(long startTime, VibratorController controller,
+                VibrationEffect.Composed effect, int index, long vibratorOffTimeout) {
             super(startTime);
             this.controller = controller;
             this.effect = effect;
+            this.segmentIndex = index;
+            this.vibratorOffTimeout = vibratorOffTimeout;
         }
 
         /**
-         * Return the duration, in millis, of this effect. Repeating waveforms return {@link
-         * Long#MAX_VALUE}. Zero or negative values indicate the vibrator has ignored this effect.
+         * Return the result a call to {@link VibratorController#on} method triggered by
+         * {@link #play()}.
+         *
+         * @return A positive duration that the vibrator was turned on for by this step;
+         * Zero if the segment is not supported or vibrator was never turned on;
+         * A negative value if the vibrator call has failed.
          */
-        public long getDuration() {
-            return mDuration;
+        public long getOnResult() {
+            return mVibratorOnResult;
+        }
+
+        @Override
+        public boolean shouldPlayWhenVibratorComplete(int vibratorId) {
+            // Only anticipate this step if a timeout was set to wait for the vibration to complete,
+            // otherwise we are waiting for the correct time to play the next step.
+            return (controller.getVibratorInfo().getId() == vibratorId)
+                    && (vibratorOffTimeout > SystemClock.uptimeMillis());
+        }
+
+        @Override
+        public void cancel() {
+            if (vibratorOffTimeout > SystemClock.uptimeMillis()) {
+                // Vibrator might be running from previous steps, so turn it off while canceling.
+                stopVibrating();
+            }
+        }
+
+        void stopVibrating() {
+            if (DEBUG) {
+                Slog.d(TAG, "Turning off vibrator " + controller.getVibratorInfo().getId());
+            }
+            controller.off();
+        }
+
+        /** Return the {@link #nextVibrateStep} with same timings, only jumping the segments. */
+        public List<Step> skipToNextSteps(int segmentsSkipped) {
+            return nextSteps(startTime, vibratorOffTimeout, segmentsSkipped);
+        }
+
+        /**
+         * Return the {@link #nextVibrateStep} with same start and off timings calculated from
+         * {@link #getOnResult()}, jumping all played segments.
+         *
+         * <p>This method has same behavior as {@link #skipToNextSteps(int)} when the vibrator
+         * result is non-positive, meaning the vibrator has either ignored or failed to turn on.
+         */
+        public List<Step> nextSteps(int segmentsPlayed) {
+            if (mVibratorOnResult <= 0) {
+                // Vibration was not started, so just skip the played segments and keep timings.
+                return skipToNextSteps(segmentsPlayed);
+            }
+            long nextVibratorOffTimeout =
+                    SystemClock.uptimeMillis() + mVibratorOnResult + CALLBACKS_EXTRA_TIMEOUT;
+            return nextSteps(nextVibratorOffTimeout, nextVibratorOffTimeout, segmentsPlayed);
+        }
+
+        /**
+         * Return the {@link #nextVibrateStep} with given start and off timings, which might be
+         * calculated independently, jumping all played segments.
+         *
+         * <p>This should be used when the vibrator on/off state is not responsible for the steps
+         * execution timings, e.g. while playing the vibrator amplitudes.
+         */
+        public List<Step> nextSteps(long nextStartTime, long vibratorOffTimeout,
+                int segmentsPlayed) {
+            Step nextStep = nextVibrateStep(nextStartTime, controller, effect,
+                    segmentIndex + segmentsPlayed, vibratorOffTimeout);
+            return nextStep == null ? EMPTY_STEP_LIST : Arrays.asList(nextStep);
+        }
+    }
+
+    /**
+     * Represent a step turn the vibrator on with a single prebaked effect.
+     *
+     * <p>This step automatically falls back by replacing the prebaked segment with
+     * {@link VibrationSettings#getFallbackEffect(int)}, if available.
+     */
+    private final class PerformStep extends SingleVibratorStep {
+
+        PerformStep(long startTime, VibratorController controller,
+                VibrationEffect.Composed effect, int index, long vibratorOffTimeout) {
+            super(startTime, controller, effect, index, vibratorOffTimeout);
         }
 
         @Override
         public List<Step> play() {
-            Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "VibratorOnStep");
+            Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "PerformStep");
             try {
-                if (DEBUG) {
-                    Slog.d(TAG, "Turning on vibrator " + controller.getVibratorInfo().getId());
+                VibrationEffectSegment segment = effect.getSegments().get(segmentIndex);
+                if (!(segment instanceof PrebakedSegment)) {
+                    Slog.w(TAG, "Ignoring wrong segment for a PerformStep: " + segment);
+                    return skipToNextSteps(/* segmentsSkipped= */ 1);
                 }
-                List<Step> nextSteps = new ArrayList<>();
-                mDuration = startVibrating(effect, nextSteps);
-                return nextSteps;
+
+                PrebakedSegment prebaked = (PrebakedSegment) segment;
+                if (DEBUG) {
+                    Slog.d(TAG, "Perform " + VibrationEffect.effectIdToString(
+                            prebaked.getEffectId()) + " on vibrator "
+                            + controller.getVibratorInfo().getId());
+                }
+
+                VibrationEffect fallback = mVibration.getFallback(prebaked.getEffectId());
+                mVibratorOnResult = controller.on(prebaked, mVibration.id);
+
+                if (mVibratorOnResult == 0 && prebaked.shouldFallback()
+                        && (fallback instanceof VibrationEffect.Composed)) {
+                    if (DEBUG) {
+                        Slog.d(TAG, "Playing fallback for effect "
+                                + VibrationEffect.effectIdToString(prebaked.getEffectId()));
+                    }
+                    SingleVibratorStep fallbackStep = nextVibrateStep(startTime, controller,
+                            replaceCurrentSegment((VibrationEffect.Composed) fallback),
+                            segmentIndex, vibratorOffTimeout);
+                    List<Step> fallbackResult = fallbackStep.play();
+                    // Update the result with the fallback result so this step is seamlessly
+                    // replaced by the fallback to any outer application of this.
+                    mVibratorOnResult = fallbackStep.getOnResult();
+                    return fallbackResult;
+                }
+
+                return nextSteps(/* segmentsPlayed= */ 1);
             } finally {
                 Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
             }
         }
 
-        private long startVibrating(VibrationEffect effect, List<Step> nextSteps) {
-            final long duration;
-            final long now = SystemClock.uptimeMillis();
-            if (effect instanceof VibrationEffect.OneShot) {
-                VibrationEffect.OneShot oneShot = (VibrationEffect.OneShot) effect;
-                duration = oneShot.getDuration();
-                // Do NOT set amplitude here. This might be called between prepareSynced and
-                // triggerSynced, so the vibrator is not actually turned on here.
-                // The next steps will handle the amplitude after the vibrator has turned on.
-                controller.on(duration, mVibration.id);
-                nextSteps.add(new VibratorAmplitudeStep(now, controller, oneShot,
-                        now + duration + CALLBACKS_EXTRA_TIMEOUT));
-            } else if (effect instanceof VibrationEffect.Waveform) {
-                VibrationEffect.Waveform waveform = (VibrationEffect.Waveform) effect;
-                // Return the full duration of this waveform effect.
-                duration = waveform.getDuration();
-                long onDuration = getVibratorOnDuration(waveform, 0);
-                if (onDuration > 0) {
-                    // Do NOT set amplitude here. This might be called between prepareSynced and
-                    // triggerSynced, so the vibrator is not actually turned on here.
-                    // The next steps will handle the amplitudes after the vibrator has turned on.
-                    controller.on(onDuration, mVibration.id);
-                }
-                long offTime = onDuration > 0 ? now + onDuration + CALLBACKS_EXTRA_TIMEOUT : now;
-                nextSteps.add(new VibratorAmplitudeStep(now, controller, waveform, offTime));
-            } else if (effect instanceof VibrationEffect.Prebaked) {
-                VibrationEffect.Prebaked prebaked = (VibrationEffect.Prebaked) effect;
-                duration = controller.on(prebaked, mVibration.id);
-                if (duration > 0) {
-                    nextSteps.add(new VibratorOffStep(now + duration + CALLBACKS_EXTRA_TIMEOUT,
-                            controller));
-                } else if (prebaked.getFallbackEffect() != null) {
-                    return startVibrating(prebaked.getFallbackEffect(), nextSteps);
-                }
-            } else if (effect instanceof VibrationEffect.Composed) {
-                VibrationEffect.Composed composed = (VibrationEffect.Composed) effect;
-                duration = controller.on(composed, mVibration.id);
-                if (duration > 0) {
-                    nextSteps.add(new VibratorOffStep(now + duration + CALLBACKS_EXTRA_TIMEOUT,
-                            controller));
-                }
-            } else {
-                duration = 0;
+        /**
+         * Replace segment at {@link #segmentIndex} in {@link #effect} with given fallback segments.
+         *
+         * @return a copy of {@link #effect} with replaced segment.
+         */
+        private VibrationEffect.Composed replaceCurrentSegment(VibrationEffect.Composed fallback) {
+            List<VibrationEffectSegment> newSegments = new ArrayList<>(effect.getSegments());
+            int newRepeatIndex = effect.getRepeatIndex();
+            newSegments.remove(segmentIndex);
+            newSegments.addAll(segmentIndex, fallback.getSegments());
+            if (segmentIndex < effect.getRepeatIndex()) {
+                newRepeatIndex += fallback.getSegments().size();
             }
-            return duration;
+            return new VibrationEffect.Composed(newSegments, newRepeatIndex);
+        }
+    }
+
+    /**
+     * Represent a step turn the vibrator on using a composition of primitives.
+     *
+     * <p>This step will use the maximum supported number of consecutive segments of type
+     * {@link PrimitiveSegment} starting at the current index.
+     */
+    private final class ComposePrimitivesStep extends SingleVibratorStep {
+
+        ComposePrimitivesStep(long startTime, VibratorController controller,
+                VibrationEffect.Composed effect, int index, long vibratorOffTimeout) {
+            super(startTime, controller, effect, index, vibratorOffTimeout);
+        }
+
+        @Override
+        public List<Step> play() {
+            Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "ComposePrimitivesStep");
+            try {
+                int segmentCount = effect.getSegments().size();
+                List<PrimitiveSegment> primitives = new ArrayList<>();
+                for (int i = segmentIndex; i < segmentCount; i++) {
+                    VibrationEffectSegment segment = effect.getSegments().get(i);
+                    if (segment instanceof PrimitiveSegment) {
+                        primitives.add((PrimitiveSegment) segment);
+                    } else {
+                        break;
+                    }
+                }
+
+                if (primitives.isEmpty()) {
+                    Slog.w(TAG, "Ignoring wrong segment for a ComposePrimitivesStep: "
+                            + effect.getSegments().get(segmentIndex));
+                    return skipToNextSteps(/* segmentsSkipped= */ 1);
+                }
+
+                if (DEBUG) {
+                    Slog.d(TAG, "Compose " + primitives + " primitives on vibrator "
+                            + controller.getVibratorInfo().getId());
+                }
+                mVibratorOnResult = controller.on(
+                        primitives.toArray(new PrimitiveSegment[primitives.size()]),
+                        mVibration.id);
+
+                return nextSteps(/* segmentsPlayed= */ primitives.size());
+            } finally {
+                Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
+            }
+        }
+    }
+
+    /**
+     * Represent a step turn the vibrator on using a composition of PWLE segments.
+     *
+     * <p>This step will use the maximum supported number of consecutive segments of type
+     * {@link StepSegment} or {@link RampSegment} starting at the current index.
+     */
+    private final class ComposePwleStep extends SingleVibratorStep {
+
+        ComposePwleStep(long startTime, VibratorController controller,
+                VibrationEffect.Composed effect, int index, long vibratorOffTimeout) {
+            super(startTime, controller, effect, index, vibratorOffTimeout);
+        }
+
+        @Override
+        public List<Step> play() {
+            Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "ComposePwleStep");
+            try {
+                int segmentCount = effect.getSegments().size();
+                List<RampSegment> pwles = new ArrayList<>();
+                for (int i = segmentIndex; i < segmentCount; i++) {
+                    VibrationEffectSegment segment = effect.getSegments().get(i);
+                    if (segment instanceof RampSegment) {
+                        pwles.add((RampSegment) segment);
+                    } else {
+                        break;
+                    }
+                }
+
+                if (pwles.isEmpty()) {
+                    Slog.w(TAG, "Ignoring wrong segment for a ComposePwleStep: "
+                            + effect.getSegments().get(segmentIndex));
+                    return skipToNextSteps(/* segmentsSkipped= */ 1);
+                }
+
+                if (DEBUG) {
+                    Slog.d(TAG, "Compose " + pwles + " PWLEs on vibrator "
+                            + controller.getVibratorInfo().getId());
+                }
+                mVibratorOnResult = controller.on(pwles.toArray(new RampSegment[pwles.size()]),
+                        mVibration.id);
+
+                return nextSteps(/* segmentsPlayed= */ pwles.size());
+            } finally {
+                Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
+            }
         }
     }
 
@@ -673,22 +895,15 @@
      * <p>This runs after a timeout on the expected time the vibrator should have finished playing,
      * and can anticipated by vibrator complete callbacks.
      */
-    private final class VibratorOffStep extends Step {
-        public final VibratorController controller;
+    private final class OffStep extends SingleVibratorStep {
 
-        VibratorOffStep(long startTime, VibratorController controller) {
-            super(startTime);
-            this.controller = controller;
-        }
-
-        @Override
-        public boolean shouldPlayWhenVibratorComplete(int vibratorId) {
-            return controller.getVibratorInfo().getId() == vibratorId;
+        OffStep(long startTime, VibratorController controller) {
+            super(startTime, controller, /* effect= */ null, /* index= */ -1, startTime);
         }
 
         @Override
         public List<Step> play() {
-            Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "VibratorOffStep");
+            Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "OffStep");
             try {
                 stopVibrating();
                 return EMPTY_STEP_LIST;
@@ -696,117 +911,91 @@
                 Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
             }
         }
-
-        @Override
-        public void cancel() {
-            stopVibrating();
-        }
-
-        private void stopVibrating() {
-            if (DEBUG) {
-                Slog.d(TAG, "Turning off vibrator " + controller.getVibratorInfo().getId());
-            }
-            controller.off();
-        }
     }
 
-    /** Represents a step to change the amplitude of the vibrator. */
-    private final class VibratorAmplitudeStep extends Step {
-        public final VibratorController controller;
-        public final VibrationEffect.Waveform waveform;
-        public final int currentIndex;
-        public final long expectedVibratorStopTime;
+    /**
+     * Represents a step to turn the vibrator on and change its amplitude.
+     *
+     * <p>This step ignores vibration completion callbacks and control the vibrator on/off state
+     * and amplitude to simulate waveforms represented by a sequence of {@link StepSegment}.
+     */
+    private final class AmplitudeStep extends SingleVibratorStep {
+        private long mNextOffTime;
 
-        private long mNextVibratorStopTime;
-
-        VibratorAmplitudeStep(long startTime, VibratorController controller,
-                VibrationEffect.OneShot oneShot, long expectedVibratorStopTime) {
-            this(startTime, controller,
-                    (VibrationEffect.Waveform) VibrationEffect.createWaveform(
-                            new long[]{oneShot.getDuration()}, new int[]{oneShot.getAmplitude()},
-                            /* repeat= */ -1),
-                    expectedVibratorStopTime);
-        }
-
-        VibratorAmplitudeStep(long startTime, VibratorController controller,
-                VibrationEffect.Waveform waveform, long expectedVibratorStopTime) {
-            this(startTime, controller, waveform, /* index= */ 0, expectedVibratorStopTime);
-        }
-
-        VibratorAmplitudeStep(long startTime, VibratorController controller,
-                VibrationEffect.Waveform waveform, int index, long expectedVibratorStopTime) {
-            super(startTime);
-            this.controller = controller;
-            this.waveform = waveform;
-            this.currentIndex = index;
-            this.expectedVibratorStopTime = expectedVibratorStopTime;
-            mNextVibratorStopTime = expectedVibratorStopTime;
+        AmplitudeStep(long startTime, VibratorController controller,
+                VibrationEffect.Composed effect, int index, long vibratorOffTimeout) {
+            super(startTime, controller, effect, index, vibratorOffTimeout);
+            mNextOffTime = vibratorOffTimeout;
         }
 
         @Override
         public boolean shouldPlayWhenVibratorComplete(int vibratorId) {
             if (controller.getVibratorInfo().getId() == vibratorId) {
-                mNextVibratorStopTime = SystemClock.uptimeMillis();
+                mNextOffTime = SystemClock.uptimeMillis();
             }
+            // Timings are tightly controlled here, so never anticipate when vibrator is complete.
             return false;
         }
 
         @Override
         public List<Step> play() {
-            Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "VibratorAmplitudeStep");
+            Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "AmplitudeStep");
             try {
                 if (DEBUG) {
                     long latency = SystemClock.uptimeMillis() - startTime;
                     Slog.d(TAG, "Running amplitude step with " + latency + "ms latency.");
                 }
-                if (waveform.getTimings()[currentIndex] == 0) {
+
+                VibrationEffectSegment segment = effect.getSegments().get(segmentIndex);
+                if (!(segment instanceof StepSegment)) {
+                    Slog.w(TAG, "Ignoring wrong segment for a AmplitudeStep: " + segment);
+                    return skipToNextSteps(/* segmentsSkipped= */ 1);
+                }
+
+                StepSegment stepSegment = (StepSegment) segment;
+                if (stepSegment.getDuration() == 0) {
                     // Skip waveform entries with zero timing.
-                    return nextSteps();
+                    return skipToNextSteps(/* segmentsSkipped= */ 1);
                 }
-                int amplitude = waveform.getAmplitudes()[currentIndex];
+
+                long now = SystemClock.uptimeMillis();
+                float amplitude = stepSegment.getAmplitude();
                 if (amplitude == 0) {
-                    stopVibrating();
-                    return nextSteps();
-                }
-                if (startTime >= mNextVibratorStopTime) {
-                    // Vibrator has stopped. Turn vibrator back on for the duration of another
-                    // cycle before setting the amplitude.
-                    long onDuration = getVibratorOnDuration(waveform, currentIndex);
-                    if (onDuration > 0) {
-                        startVibrating(onDuration);
-                        mNextVibratorStopTime =
-                                SystemClock.uptimeMillis() + onDuration + CALLBACKS_EXTRA_TIMEOUT;
+                    if (mNextOffTime > now) {
+                        // Amplitude cannot be set to zero, so stop the vibrator.
+                        stopVibrating();
+                        mNextOffTime = now;
                     }
+                } else {
+                    if (startTime >= mNextOffTime) {
+                        // Vibrator has stopped. Turn vibrator back on for the duration of another
+                        // cycle before setting the amplitude.
+                        long onDuration = getVibratorOnDuration(effect, segmentIndex);
+                        if (onDuration > 0) {
+                            mVibratorOnResult = startVibrating(onDuration);
+                            mNextOffTime = now + onDuration + CALLBACKS_EXTRA_TIMEOUT;
+                        }
+                    }
+                    changeAmplitude(amplitude);
                 }
-                changeAmplitude(amplitude);
-                return nextSteps();
+
+                // Use original startTime to avoid propagating latencies to the waveform.
+                long nextStartTime = startTime + segment.getDuration();
+                return nextSteps(nextStartTime, mNextOffTime, /* segmentsPlayed= */ 1);
             } finally {
                 Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
             }
         }
 
-        @Override
-        public void cancel() {
-            stopVibrating();
-        }
-
-        private void stopVibrating() {
-            if (DEBUG) {
-                Slog.d(TAG, "Turning off vibrator " + controller.getVibratorInfo().getId());
-            }
-            controller.off();
-            mNextVibratorStopTime = SystemClock.uptimeMillis();
-        }
-
-        private void startVibrating(long duration) {
+        private long startVibrating(long duration) {
             if (DEBUG) {
                 Slog.d(TAG, "Turning on vibrator " + controller.getVibratorInfo().getId() + " for "
                         + duration + "ms");
             }
-            controller.on(duration, mVibration.id);
+            return controller.on(duration, mVibration.id);
         }
 
-        private void changeAmplitude(int amplitude) {
+        private void changeAmplitude(float amplitude) {
             if (DEBUG) {
                 Slog.d(TAG, "Amplitude changed on vibrator " + controller.getVibratorInfo().getId()
                         + " to " + amplitude);
@@ -814,18 +1003,35 @@
             controller.setAmplitude(amplitude);
         }
 
-        @NonNull
-        private List<Step> nextSteps() {
-            long nextStartTime = startTime + waveform.getTimings()[currentIndex];
-            int nextIndex = currentIndex + 1;
-            if (nextIndex >= waveform.getTimings().length) {
-                nextIndex = waveform.getRepeatIndex();
+        /**
+         * Get the duration the vibrator will be on for a waveform, starting at {@code startIndex}
+         * until the next time it's vibrating amplitude is zero or a different type of segment is
+         * found.
+         */
+        private long getVibratorOnDuration(VibrationEffect.Composed effect, int startIndex) {
+            List<VibrationEffectSegment> segments = effect.getSegments();
+            int segmentCount = segments.size();
+            int repeatIndex = effect.getRepeatIndex();
+            int i = startIndex;
+            long timing = 0;
+            while (i < segmentCount) {
+                VibrationEffectSegment segment = segments.get(i);
+                if (!(segment instanceof StepSegment)
+                        || ((StepSegment) segment).getAmplitude() == 0) {
+                    break;
+                }
+                timing += segment.getDuration();
+                i++;
+                if (i == segmentCount && repeatIndex >= 0) {
+                    i = repeatIndex;
+                    // prevent infinite loop
+                    repeatIndex = -1;
+                }
+                if (i == startIndex) {
+                    return 1000;
+                }
             }
-            if (nextIndex < 0) {
-                return Arrays.asList(new VibratorOffStep(nextStartTime, controller));
-            }
-            return Arrays.asList(new VibratorAmplitudeStep(nextStartTime, controller, waveform,
-                    nextIndex, mNextVibratorStopTime));
+            return timing;
         }
     }
 
@@ -836,7 +1042,7 @@
      * play all of the effects in sync.
      */
     private final class DeviceEffectMap {
-        private final SparseArray<VibrationEffect> mVibratorEffects;
+        private final SparseArray<VibrationEffect.Composed> mVibratorEffects;
         private final int[] mVibratorIds;
         private final long mRequiredSyncCapabilities;
 
@@ -845,8 +1051,12 @@
             mVibratorIds = new int[mVibrators.size()];
             for (int i = 0; i < mVibrators.size(); i++) {
                 int vibratorId = mVibrators.keyAt(i);
-                mVibratorEffects.put(vibratorId, mono.getEffect());
-                mVibratorIds[i] = vibratorId;
+                VibratorInfo vibratorInfo = mVibrators.valueAt(i).getVibratorInfo();
+                VibrationEffect effect = mDeviceEffectAdapter.apply(mono.getEffect(), vibratorInfo);
+                if (effect instanceof VibrationEffect.Composed) {
+                    mVibratorEffects.put(vibratorId, (VibrationEffect.Composed) effect);
+                    mVibratorIds[i] = vibratorId;
+                }
             }
             mRequiredSyncCapabilities = calculateRequiredSyncCapabilities(mVibratorEffects);
         }
@@ -857,7 +1067,12 @@
             for (int i = 0; i < stereoEffects.size(); i++) {
                 int vibratorId = stereoEffects.keyAt(i);
                 if (mVibrators.contains(vibratorId)) {
-                    mVibratorEffects.put(vibratorId, stereoEffects.valueAt(i));
+                    VibratorInfo vibratorInfo = mVibrators.valueAt(i).getVibratorInfo();
+                    VibrationEffect effect = mDeviceEffectAdapter.apply(
+                            stereoEffects.valueAt(i), vibratorInfo);
+                    if (effect instanceof VibrationEffect.Composed) {
+                        mVibratorEffects.put(vibratorId, (VibrationEffect.Composed) effect);
+                    }
                 }
             }
             mVibratorIds = new int[mVibratorEffects.size()];
@@ -895,7 +1110,7 @@
         }
 
         /** Return the {@link VibrationEffect} at given index. */
-        public VibrationEffect effectAt(int index) {
+        public VibrationEffect.Composed effectAt(int index) {
             return mVibratorEffects.valueAt(index);
         }
 
@@ -906,16 +1121,16 @@
          * @return {@link IVibratorManager#CAP_SYNC} together with all required
          * IVibratorManager.CAP_PREPARE_* and IVibratorManager.CAP_MIXED_TRIGGER_* capabilities.
          */
-        private long calculateRequiredSyncCapabilities(SparseArray<VibrationEffect> effects) {
+        private long calculateRequiredSyncCapabilities(
+                SparseArray<VibrationEffect.Composed> effects) {
             long prepareCap = 0;
             for (int i = 0; i < effects.size(); i++) {
-                VibrationEffect effect = effects.valueAt(i);
-                if (effect instanceof VibrationEffect.OneShot
-                        || effect instanceof VibrationEffect.Waveform) {
+                VibrationEffectSegment firstSegment = effects.valueAt(i).getSegments().get(0);
+                if (firstSegment instanceof StepSegment) {
                     prepareCap |= IVibratorManager.CAP_PREPARE_ON;
-                } else if (effect instanceof VibrationEffect.Prebaked) {
+                } else if (firstSegment instanceof PrebakedSegment) {
                     prepareCap |= IVibratorManager.CAP_PREPARE_PERFORM;
-                } else if (effect instanceof VibrationEffect.Composed) {
+                } else if (firstSegment instanceof PrimitiveSegment) {
                     prepareCap |= IVibratorManager.CAP_PREPARE_COMPOSE;
                 }
             }
diff --git a/services/core/java/com/android/server/vibrator/VibratorController.java b/services/core/java/com/android/server/vibrator/VibratorController.java
index e3dc70b..a09bfc5 100644
--- a/services/core/java/com/android/server/vibrator/VibratorController.java
+++ b/services/core/java/com/android/server/vibrator/VibratorController.java
@@ -22,12 +22,15 @@
 import android.os.IVibratorStateListener;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
-import android.os.VibrationEffect;
 import android.os.VibratorInfo;
+import android.os.vibrator.PrebakedSegment;
+import android.os.vibrator.PrimitiveSegment;
+import android.os.vibrator.RampSegment;
 import android.util.Slog;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.Preconditions;
 
 import libcore.util.NativeAllocationRegistry;
 
@@ -63,10 +66,10 @@
             NativeWrapper nativeWrapper) {
         mNativeWrapper = nativeWrapper;
         mNativeWrapper.init(vibratorId, listener);
-
-        mVibratorInfo = new VibratorInfo(vibratorId, nativeWrapper.getCapabilities(),
-                nativeWrapper.getSupportedEffects(), nativeWrapper.getSupportedPrimitives(),
-                nativeWrapper.getResonantFrequency(), nativeWrapper.getQFactor());
+        // TODO(b/167947076): load suggested range from config
+        mVibratorInfo = mNativeWrapper.getInfo(/* suggestedFrequencyRange= */ 100);
+        Preconditions.checkNotNull(mVibratorInfo, "Failed to retrieve data for vibrator %d",
+                vibratorId);
     }
 
     /** Register state listener for this vibrator. */
@@ -156,21 +159,22 @@
      * Update the predefined vibration effect saved with given id. This will remove the saved effect
      * if given {@code effect} is {@code null}.
      */
-    public void updateAlwaysOn(int id, @Nullable VibrationEffect.Prebaked effect) {
+    public void updateAlwaysOn(int id, @Nullable PrebakedSegment prebaked) {
         if (!mVibratorInfo.hasCapability(IVibrator.CAP_ALWAYS_ON_CONTROL)) {
             return;
         }
         synchronized (mLock) {
-            if (effect == null) {
+            if (prebaked == null) {
                 mNativeWrapper.alwaysOnDisable(id);
             } else {
-                mNativeWrapper.alwaysOnEnable(id, effect.getId(), effect.getEffectStrength());
+                mNativeWrapper.alwaysOnEnable(id, prebaked.getEffectId(),
+                        prebaked.getEffectStrength());
             }
         }
     }
 
     /** Set the vibration amplitude. This will NOT affect the state of {@link #isVibrating()}. */
-    public void setAmplitude(int amplitude) {
+    public void setAmplitude(float amplitude) {
         synchronized (mLock) {
             if (mVibratorInfo.hasCapability(IVibrator.CAP_AMPLITUDE_CONTROL)) {
                 mNativeWrapper.setAmplitude(amplitude);
@@ -183,11 +187,17 @@
      * callback to {@link OnVibrationCompleteListener}.
      *
      * <p>This will affect the state of {@link #isVibrating()}.
+     *
+     * @return The positive duration of the vibration started, if successful, zero if the vibrator
+     * do not support the input or a negative number if the operation failed.
      */
-    public void on(long milliseconds, long vibrationId) {
+    public long on(long milliseconds, long vibrationId) {
         synchronized (mLock) {
-            mNativeWrapper.on(milliseconds, vibrationId);
-            notifyVibratorOnLocked();
+            long duration = mNativeWrapper.on(milliseconds, vibrationId);
+            if (duration > 0) {
+                notifyVibratorOnLocked();
+            }
+            return duration;
         }
     }
 
@@ -197,12 +207,13 @@
      *
      * <p>This will affect the state of {@link #isVibrating()}.
      *
-     * @return The duration of the effect playing, or 0 if unsupported.
+     * @return The positive duration of the vibration started, if successful, zero if the vibrator
+     * do not support the input or a negative number if the operation failed.
      */
-    public long on(VibrationEffect.Prebaked effect, long vibrationId) {
+    public long on(PrebakedSegment prebaked, long vibrationId) {
         synchronized (mLock) {
-            long duration = mNativeWrapper.perform(effect.getId(), effect.getEffectStrength(),
-                    vibrationId);
+            long duration = mNativeWrapper.perform(prebaked.getEffectId(),
+                    prebaked.getEffectStrength(), vibrationId);
             if (duration > 0) {
                 notifyVibratorOnLocked();
             }
@@ -211,22 +222,42 @@
     }
 
     /**
-     * Plays composited vibration effect, using {@code vibrationId} or completion callback to
-     * {@link OnVibrationCompleteListener}.
+     * Plays a composition of vibration primitives, using {@code vibrationId} or completion callback
+     * to {@link OnVibrationCompleteListener}.
+     *
+     * <p>This will affect the state of {@link #isVibrating()}.
+     *
+     * @return The positive duration of the vibration started, if successful, zero if the vibrator
+     * do not support the input or a negative number if the operation failed.
+     */
+    public long on(PrimitiveSegment[] primitives, long vibrationId) {
+        if (!mVibratorInfo.hasCapability(IVibrator.CAP_COMPOSE_EFFECTS)) {
+            return 0;
+        }
+        synchronized (mLock) {
+            long duration = mNativeWrapper.compose(primitives, vibrationId);
+            if (duration > 0) {
+                notifyVibratorOnLocked();
+            }
+            return duration;
+        }
+    }
+
+    /**
+     * Plays a composition of pwle primitives, using {@code vibrationId} or completion callback
+     * to {@link OnVibrationCompleteListener}.
      *
      * <p>This will affect the state of {@link #isVibrating()}.
      *
      * @return The duration of the effect playing, or 0 if unsupported.
      */
-    public long on(VibrationEffect.Composed effect, long vibrationId) {
-        if (!mVibratorInfo.hasCapability(IVibrator.CAP_COMPOSE_EFFECTS)) {
+    public long on(RampSegment[] primitives, long vibrationId) {
+        if (!mVibratorInfo.hasCapability(IVibrator.CAP_COMPOSE_PWLE_EFFECTS)) {
             return 0;
         }
         synchronized (mLock) {
-            VibrationEffect.Composition.PrimitiveEffect[] primitives =
-                    effect.getPrimitiveEffects().toArray(
-                            new VibrationEffect.Composition.PrimitiveEffect[0]);
-            long duration = mNativeWrapper.compose(primitives, vibrationId);
+            int braking = mVibratorInfo.getDefaultBraking();
+            long duration = mNativeWrapper.composePwle(primitives, braking, vibrationId);
             if (duration > 0) {
                 notifyVibratorOnLocked();
             }
@@ -311,22 +342,26 @@
          */
         private static native long getNativeFinalizer();
         private static native boolean isAvailable(long nativePtr);
-        private static native void on(long nativePtr, long milliseconds, long vibrationId);
+        private static native long on(long nativePtr, long milliseconds, long vibrationId);
         private static native void off(long nativePtr);
-        private static native void setAmplitude(long nativePtr, int amplitude);
-        private static native int[] getSupportedEffects(long nativePtr);
-        private static native int[] getSupportedPrimitives(long nativePtr);
-        private static native long performEffect(
-                long nativePtr, long effect, long strength, long vibrationId);
-        private static native long performComposedEffect(long nativePtr,
-                VibrationEffect.Composition.PrimitiveEffect[] effect, long vibrationId);
+        private static native void setAmplitude(long nativePtr, float amplitude);
+        private static native long performEffect(long nativePtr, long effect, long strength,
+                long vibrationId);
+
+        private static native long performComposedEffect(long nativePtr, PrimitiveSegment[] effect,
+                long vibrationId);
+
+        private static native long performPwleEffect(long nativePtr, RampSegment[] effect,
+                int braking, long vibrationId);
+
         private static native void setExternalControl(long nativePtr, boolean enabled);
-        private static native long getCapabilities(long nativePtr);
+
         private static native void alwaysOnEnable(long nativePtr, long id, long effect,
                 long strength);
+
         private static native void alwaysOnDisable(long nativePtr, long id);
-        private static native float getResonantFrequency(long nativePtr);
-        private static native float getQFactor(long nativePtr);
+
+        private static native VibratorInfo getInfo(long nativePtr, float suggestedFrequencyRange);
 
         private long mNativePtr = 0;
 
@@ -349,8 +384,8 @@
         }
 
         /** Turns vibrator on for given time. */
-        public void on(long milliseconds, long vibrationId) {
-            on(mNativePtr, milliseconds, vibrationId);
+        public long on(long milliseconds, long vibrationId) {
+            return on(mNativePtr, milliseconds, vibrationId);
         }
 
         /** Turns vibrator off. */
@@ -359,29 +394,23 @@
         }
 
         /** Sets the amplitude for the vibrator to run. */
-        public void setAmplitude(int amplitude) {
+        public void setAmplitude(float amplitude) {
             setAmplitude(mNativePtr, amplitude);
         }
 
-        /** Returns all predefined effects supported by the device vibrator. */
-        public int[] getSupportedEffects() {
-            return getSupportedEffects(mNativePtr);
-        }
-
-        /** Returns all compose primitives supported by the device vibrator. */
-        public int[] getSupportedPrimitives() {
-            return getSupportedPrimitives(mNativePtr);
-        }
-
         /** Turns vibrator on to perform one of the supported effects. */
         public long perform(long effect, long strength, long vibrationId) {
             return performEffect(mNativePtr, effect, strength, vibrationId);
         }
 
-        /** Turns vibrator on to perform one of the supported composed effects. */
-        public long compose(
-                VibrationEffect.Composition.PrimitiveEffect[] effect, long vibrationId) {
-            return performComposedEffect(mNativePtr, effect, vibrationId);
+        /** Turns vibrator on to perform effect composed of give primitives effect. */
+        public long compose(PrimitiveSegment[] primitives, long vibrationId) {
+            return performComposedEffect(mNativePtr, primitives, vibrationId);
+        }
+
+        /** Turns vibrator on to perform PWLE effect composed of given primitives. */
+        public long composePwle(RampSegment[] primitives, int braking, long vibrationId) {
+            return performPwleEffect(mNativePtr, primitives, braking, vibrationId);
         }
 
         /** Enabled the device vibrator to be controlled by another service. */
@@ -389,11 +418,6 @@
             setExternalControl(mNativePtr, enabled);
         }
 
-        /** Returns all capabilities of the device vibrator. */
-        public long getCapabilities() {
-            return getCapabilities(mNativePtr);
-        }
-
         /** Enable always-on vibration with given id and effect. */
         public void alwaysOnEnable(long id, long effect, long strength) {
             alwaysOnEnable(mNativePtr, id, effect, strength);
@@ -404,14 +428,9 @@
             alwaysOnDisable(mNativePtr, id);
         }
 
-        /** Gets the vibrator's resonant frequency (F0) */
-        public float getResonantFrequency() {
-            return getResonantFrequency(mNativePtr);
-        }
-
-        /** Gets the vibrator's Q factor */
-        public float getQFactor() {
-            return getQFactor(mNativePtr);
+        /** Return device vibrator metadata. */
+        public VibratorInfo getInfo(float suggestedFrequencyRange) {
+            return getInfo(mNativePtr, suggestedFrequencyRange);
         }
     }
 }
diff --git a/services/core/java/com/android/server/vibrator/VibratorManagerService.java b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
index c9751bb..b1d6050 100644
--- a/services/core/java/com/android/server/vibrator/VibratorManagerService.java
+++ b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
@@ -48,6 +48,8 @@
 import android.os.VibrationEffect;
 import android.os.Vibrator;
 import android.os.VibratorInfo;
+import android.os.vibrator.PrebakedSegment;
+import android.os.vibrator.VibrationEffectSegment;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.proto.ProtoOutputStream;
@@ -312,7 +314,7 @@
             }
             attrs = fixupVibrationAttributes(attrs);
             synchronized (mLock) {
-                SparseArray<VibrationEffect.Prebaked> effects = fixupAlwaysOnEffectsLocked(effect);
+                SparseArray<PrebakedSegment> effects = fixupAlwaysOnEffectsLocked(effect);
                 if (effects == null) {
                     // Invalid effects set in CombinedVibrationEffect, or always-on capability is
                     // missing on individual vibrators.
@@ -347,8 +349,7 @@
             attrs = fixupVibrationAttributes(attrs);
             Vibration vib = new Vibration(token, mNextVibrationId.getAndIncrement(), effect, attrs,
                     uid, opPkg, reason);
-            // Update with fixed up effect to keep the original effect in Vibration for debugging.
-            vib.updateEffect(fixupVibrationEffect(effect));
+            fillVibrationFallbacks(vib, effect);
 
             synchronized (mLock) {
                 Vibration.Status ignoreStatus = shouldIgnoreVibrationLocked(vib);
@@ -476,7 +477,7 @@
     private void updateAlwaysOnLocked(AlwaysOnVibration vib) {
         for (int i = 0; i < vib.effects.size(); i++) {
             VibratorController vibrator = mVibrators.get(vib.effects.keyAt(i));
-            VibrationEffect.Prebaked effect = vib.effects.valueAt(i);
+            PrebakedSegment effect = vib.effects.valueAt(i);
             if (vibrator == null) {
                 continue;
             }
@@ -496,7 +497,7 @@
     private Vibration.Status startVibrationLocked(Vibration vib) {
         Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "startVibrationLocked");
         try {
-            vib.updateEffect(mVibrationScaler.scale(vib.getEffect(), vib.attrs.getUsage()));
+            vib.updateEffects(effect -> mVibrationScaler.scale(effect, vib.attrs.getUsage()));
             boolean inputDevicesAvailable = mInputDeviceDelegate.vibrateIfAvailable(
                     vib.uid, vib.opPkg, vib.getEffect(), vib.reason, vib.attrs);
             if (inputDevicesAvailable) {
@@ -757,43 +758,38 @@
      * Sets fallback effects to all prebaked ones in given combination of effects, based on {@link
      * VibrationSettings#getFallbackEffect}.
      */
-    private CombinedVibrationEffect fixupVibrationEffect(CombinedVibrationEffect effect) {
+    private void fillVibrationFallbacks(Vibration vib, CombinedVibrationEffect effect) {
         if (effect instanceof CombinedVibrationEffect.Mono) {
-            return CombinedVibrationEffect.createSynced(
-                    fixupVibrationEffect(((CombinedVibrationEffect.Mono) effect).getEffect()));
+            fillVibrationFallbacks(vib, ((CombinedVibrationEffect.Mono) effect).getEffect());
         } else if (effect instanceof CombinedVibrationEffect.Stereo) {
-            CombinedVibrationEffect.SyncedCombination combination =
-                    CombinedVibrationEffect.startSynced();
             SparseArray<VibrationEffect> effects =
                     ((CombinedVibrationEffect.Stereo) effect).getEffects();
             for (int i = 0; i < effects.size(); i++) {
-                combination.addVibrator(effects.keyAt(i), fixupVibrationEffect(effects.valueAt(i)));
+                fillVibrationFallbacks(vib, effects.valueAt(i));
             }
-            return combination.combine();
         } else if (effect instanceof CombinedVibrationEffect.Sequential) {
-            CombinedVibrationEffect.SequentialCombination combination =
-                    CombinedVibrationEffect.startSequential();
             List<CombinedVibrationEffect> effects =
                     ((CombinedVibrationEffect.Sequential) effect).getEffects();
-            for (CombinedVibrationEffect e : effects) {
-                combination.addNext(fixupVibrationEffect(e));
+            for (int i = 0; i < effects.size(); i++) {
+                fillVibrationFallbacks(vib, effects.get(i));
             }
-            return combination.combine();
         }
-        return effect;
     }
 
-    private VibrationEffect fixupVibrationEffect(VibrationEffect effect) {
-        if (effect instanceof VibrationEffect.Prebaked
-                && ((VibrationEffect.Prebaked) effect).shouldFallback()) {
-            VibrationEffect.Prebaked prebaked = (VibrationEffect.Prebaked) effect;
-            VibrationEffect fallback = mVibrationSettings.getFallbackEffect(prebaked.getId());
-            if (fallback != null) {
-                return new VibrationEffect.Prebaked(prebaked.getId(), prebaked.getEffectStrength(),
-                        fallback);
+    private void fillVibrationFallbacks(Vibration vib, VibrationEffect effect) {
+        VibrationEffect.Composed composed = (VibrationEffect.Composed) effect;
+        int segmentCount = composed.getSegments().size();
+        for (int i = 0; i < segmentCount; i++) {
+            VibrationEffectSegment segment = composed.getSegments().get(i);
+            if (segment instanceof PrebakedSegment) {
+                PrebakedSegment prebaked = (PrebakedSegment) segment;
+                VibrationEffect fallback = mVibrationSettings.getFallbackEffect(
+                        prebaked.getEffectId());
+                if (prebaked.shouldFallback() && fallback != null) {
+                    vib.addFallback(prebaked.getEffectId(), fallback);
+                }
             }
         }
-        return effect;
     }
 
     /**
@@ -819,7 +815,7 @@
 
     @GuardedBy("mLock")
     @Nullable
-    private SparseArray<VibrationEffect.Prebaked> fixupAlwaysOnEffectsLocked(
+    private SparseArray<PrebakedSegment> fixupAlwaysOnEffectsLocked(
             CombinedVibrationEffect effect) {
         Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "fixupAlwaysOnEffectsLocked");
         try {
@@ -833,17 +829,17 @@
                 // Only synced combinations can be used for always-on effects.
                 return null;
             }
-            SparseArray<VibrationEffect.Prebaked> result = new SparseArray<>();
+            SparseArray<PrebakedSegment> result = new SparseArray<>();
             for (int i = 0; i < effects.size(); i++) {
-                VibrationEffect prebaked = effects.valueAt(i);
-                if (!(prebaked instanceof VibrationEffect.Prebaked)) {
+                PrebakedSegment prebaked = extractPrebakedSegment(effects.valueAt(i));
+                if (prebaked == null) {
                     Slog.e(TAG, "Only prebaked effects supported for always-on.");
                     return null;
                 }
                 int vibratorId = effects.keyAt(i);
                 VibratorController vibrator = mVibrators.get(vibratorId);
                 if (vibrator != null && vibrator.hasCapability(IVibrator.CAP_ALWAYS_ON_CONTROL)) {
-                    result.put(vibratorId, (VibrationEffect.Prebaked) prebaked);
+                    result.put(vibratorId, prebaked);
                 }
             }
             if (result.size() == 0) {
@@ -855,6 +851,20 @@
         }
     }
 
+    @Nullable
+    private static PrebakedSegment extractPrebakedSegment(VibrationEffect effect) {
+        if (effect instanceof VibrationEffect.Composed) {
+            VibrationEffect.Composed composed = (VibrationEffect.Composed) effect;
+            if (composed.getSegments().size() == 1) {
+                VibrationEffectSegment segment = composed.getSegments().get(0);
+                if (segment instanceof PrebakedSegment) {
+                    return (PrebakedSegment) segment;
+                }
+            }
+        }
+        return null;
+    }
+
     /**
      * Check given mode, one of the AppOpsManager.MODE_*, against {@link VibrationAttributes} to
      * allow bypassing {@link AppOpsManager} checks.
@@ -1008,10 +1018,10 @@
         public final int uid;
         public final String opPkg;
         public final VibrationAttributes attrs;
-        public final SparseArray<VibrationEffect.Prebaked> effects;
+        public final SparseArray<PrebakedSegment> effects;
 
         AlwaysOnVibration(int alwaysOnId, int uid, String opPkg, VibrationAttributes attrs,
-                SparseArray<VibrationEffect.Prebaked> effects) {
+                SparseArray<PrebakedSegment> effects) {
             this.alwaysOnId = alwaysOnId;
             this.uid = uid;
             this.opPkg = opPkg;
@@ -1384,15 +1394,15 @@
                 while ((nextArg = peekNextArg()) != null) {
                     switch (nextArg) {
                         case "-f":
-                            getNextArgRequired(); // consume the -f argument;
+                            getNextArgRequired(); // consume "-f"
                             force = true;
                             break;
                         case "-d":
-                            getNextArgRequired(); // consume the -d argument;
+                            getNextArgRequired(); // consume "-d"
                             description = getNextArgRequired();
                             break;
                         default:
-                            // Not a common option, finish reading.
+                            // nextArg is not a common option, finish reading.
                             return;
                     }
                 }
@@ -1446,14 +1456,9 @@
 
         private int runMono() {
             CommonOptions commonOptions = new CommonOptions();
-            VibrationEffect effect = nextEffect();
-            if (effect == null) {
-                return 0;
-            }
-
-            CombinedVibrationEffect combinedEffect = CombinedVibrationEffect.createSynced(effect);
+            CombinedVibrationEffect effect = CombinedVibrationEffect.createSynced(nextEffect());
             VibrationAttributes attrs = createVibrationAttributes(commonOptions);
-            vibrate(Binder.getCallingUid(), SHELL_PACKAGE_NAME, combinedEffect, attrs,
+            vibrate(Binder.getCallingUid(), SHELL_PACKAGE_NAME, effect, attrs,
                     commonOptions.description, mToken);
             return 0;
         }
@@ -1464,10 +1469,7 @@
                     CombinedVibrationEffect.startSynced();
             while ("-v".equals(getNextOption())) {
                 int vibratorId = Integer.parseInt(getNextArgRequired());
-                VibrationEffect effect = nextEffect();
-                if (effect != null) {
-                    combination.addVibrator(vibratorId, effect);
-                }
+                combination.addVibrator(vibratorId, nextEffect());
             }
             VibrationAttributes attrs = createVibrationAttributes(commonOptions);
             vibrate(Binder.getCallingUid(), SHELL_PACKAGE_NAME, combination.combine(), attrs,
@@ -1477,19 +1479,11 @@
 
         private int runSequential() {
             CommonOptions commonOptions = new CommonOptions();
-
             CombinedVibrationEffect.SequentialCombination combination =
                     CombinedVibrationEffect.startSequential();
             while ("-v".equals(getNextOption())) {
                 int vibratorId = Integer.parseInt(getNextArgRequired());
-                int delay = 0;
-                if ("-w".equals(getNextOption())) {
-                    delay = Integer.parseInt(getNextArgRequired());
-                }
-                VibrationEffect effect = nextEffect();
-                if (effect != null) {
-                    combination.addNext(vibratorId, effect, delay);
-                }
+                combination.addNext(vibratorId, nextEffect());
             }
             VibrationAttributes attrs = createVibrationAttributes(commonOptions);
             vibrate(Binder.getCallingUid(), SHELL_PACKAGE_NAME, combination.combine(), attrs,
@@ -1502,87 +1496,145 @@
             return 0;
         }
 
-        @Nullable
         private VibrationEffect nextEffect() {
-            String effectType = getNextArgRequired();
-            if ("oneshot".equals(effectType)) {
-                return nextOneShot();
+            VibrationEffect.Composition composition = VibrationEffect.startComposition();
+            String nextArg;
+
+            while ((nextArg = peekNextArg()) != null) {
+                if ("oneshot".equals(nextArg)) {
+                    addOneShotToComposition(composition);
+                } else if ("waveform".equals(nextArg)) {
+                    addWaveformToComposition(composition);
+                } else if ("prebaked".equals(nextArg)) {
+                    addPrebakedToComposition(composition);
+                } else if ("primitives".equals(nextArg)) {
+                    addPrimitivesToComposition(composition);
+                } else {
+                    // nextArg is not an effect, finish reading.
+                    break;
+                }
             }
-            if ("waveform".equals(effectType)) {
-                return nextWaveform();
-            }
-            if ("prebaked".equals(effectType)) {
-                return nextPrebaked();
-            }
-            if ("composed".equals(effectType)) {
-                return nextComposed();
-            }
-            return null;
+
+            return composition.compose();
         }
 
-        private VibrationEffect nextOneShot() {
-            boolean hasAmplitude = "-a".equals(getNextOption());
+        private void addOneShotToComposition(VibrationEffect.Composition composition) {
+            boolean hasAmplitude = false;
+            int delay = 0;
+
+            getNextArgRequired(); // consume "oneshot"
+            String nextOption;
+            while ((nextOption = getNextOption()) != null) {
+                if ("-a".equals(nextOption)) {
+                    hasAmplitude = true;
+                } else if ("-w".equals(nextOption)) {
+                    delay = Integer.parseInt(getNextArgRequired());
+                }
+            }
+
             long duration = Long.parseLong(getNextArgRequired());
             int amplitude = hasAmplitude ? Integer.parseInt(getNextArgRequired())
                     : VibrationEffect.DEFAULT_AMPLITUDE;
-            return VibrationEffect.createOneShot(duration, amplitude);
+            composition.addEffect(VibrationEffect.createOneShot(duration, amplitude), delay);
         }
 
-        private VibrationEffect nextWaveform() {
+        private void addWaveformToComposition(VibrationEffect.Composition composition) {
             boolean hasAmplitudes = false;
+            boolean hasFrequencies = false;
+            boolean isContinuous = false;
             int repeat = -1;
+            int delay = 0;
 
-            String nextOption = getNextOption();
-            while (nextOption != null) {
+            getNextArgRequired(); // consume "waveform"
+            String nextOption;
+            while ((nextOption = getNextOption()) != null) {
                 if ("-a".equals(nextOption)) {
                     hasAmplitudes = true;
                 } else if ("-r".equals(nextOption)) {
                     repeat = Integer.parseInt(getNextArgRequired());
+                } else if ("-w".equals(nextOption)) {
+                    delay = Integer.parseInt(getNextArgRequired());
+                } else if ("-f".equals(nextOption)) {
+                    hasFrequencies = true;
+                } else if ("-c".equals(nextOption)) {
+                    isContinuous = true;
                 }
-                nextOption = getNextOption();
             }
-            List<Long> durations = new ArrayList<>();
-            List<Integer> amplitudes = new ArrayList<>();
+            List<Integer> durations = new ArrayList<>();
+            List<Float> amplitudes = new ArrayList<>();
+            List<Float> frequencies = new ArrayList<>();
 
+            float nextAmplitude = 0;
             String nextArg;
-            while ((nextArg = peekNextArg()) != null && !"-v".equals(nextArg)) {
-                durations.add(Long.parseLong(getNextArgRequired()));
+            while ((nextArg = peekNextArg()) != null) {
+                try {
+                    durations.add(Integer.parseInt(nextArg));
+                    getNextArgRequired(); // consume the duration
+                } catch (NumberFormatException e) {
+                    // nextArg is not a duration, finish reading.
+                    break;
+                }
                 if (hasAmplitudes) {
-                    amplitudes.add(Integer.parseInt(getNextArgRequired()));
+                    amplitudes.add(
+                            Float.parseFloat(getNextArgRequired()) / VibrationEffect.MAX_AMPLITUDE);
+                } else {
+                    amplitudes.add(nextAmplitude);
+                    nextAmplitude = 1 - nextAmplitude;
+                }
+                if (hasFrequencies) {
+                    frequencies.add(Float.parseFloat(getNextArgRequired()));
+                } else {
+                    frequencies.add(0f);
                 }
             }
 
-            long[] durationArray = durations.stream().mapToLong(Long::longValue).toArray();
-            if (!hasAmplitudes) {
-                return VibrationEffect.createWaveform(durationArray, repeat);
+            VibrationEffect.WaveformBuilder waveform = VibrationEffect.startWaveform();
+            for (int i = 0; i < durations.size(); i++) {
+                if (isContinuous) {
+                    waveform.addRamp(amplitudes.get(i), frequencies.get(i), durations.get(i));
+                } else {
+                    waveform.addStep(amplitudes.get(i), frequencies.get(i), durations.get(i));
+                }
+            }
+            composition.addEffect(waveform.build(repeat), delay);
+        }
+
+        private void addPrebakedToComposition(VibrationEffect.Composition composition) {
+            boolean shouldFallback = false;
+            int delay = 0;
+
+            getNextArgRequired(); // consume "prebaked"
+            String nextOption;
+            while ((nextOption = getNextOption()) != null) {
+                if ("-b".equals(nextOption)) {
+                    shouldFallback = true;
+                } else if ("-w".equals(nextOption)) {
+                    delay = Integer.parseInt(getNextArgRequired());
+                }
             }
 
-            int[] amplitudeArray = amplitudes.stream().mapToInt(Integer::intValue).toArray();
-            return VibrationEffect.createWaveform(durationArray, amplitudeArray, repeat);
-        }
-
-        private VibrationEffect nextPrebaked() {
-            boolean shouldFallback = "-b".equals(getNextOption());
             int effectId = Integer.parseInt(getNextArgRequired());
-            return VibrationEffect.get(effectId, shouldFallback);
+            composition.addEffect(VibrationEffect.get(effectId, shouldFallback), delay);
         }
 
-        private VibrationEffect nextComposed() {
-            VibrationEffect.Composition composition = VibrationEffect.startComposition();
+        private void addPrimitivesToComposition(VibrationEffect.Composition composition) {
+            getNextArgRequired(); // consume "primitives"
             String nextArg;
             while ((nextArg = peekNextArg()) != null) {
                 int delay = 0;
                 if ("-w".equals(nextArg)) {
-                    getNextArgRequired(); // consume the -w option
+                    getNextArgRequired(); // consume "-w"
                     delay = Integer.parseInt(getNextArgRequired());
-                } else if ("-v".equals(nextArg)) {
-                    // Starting next vibrator, this composed effect if finished.
+                    nextArg = peekNextArg();
+                }
+                try {
+                    composition.addPrimitive(Integer.parseInt(nextArg), /* scale= */ 1, delay);
+                    getNextArgRequired(); // consume the primitive id
+                } catch (NumberFormatException | NullPointerException e) {
+                    // nextArg is not describing a primitive, leave it to be consumed by outer loops
                     break;
                 }
-                int primitiveId = Integer.parseInt(getNextArgRequired());
-                composition.addPrimitive(primitiveId, /* scale= */ 1f, delay);
             }
-            return composition.compose();
         }
 
         private VibrationAttributes createVibrationAttributes(CommonOptions commonOptions) {
@@ -1605,38 +1657,51 @@
                 pw.println("  list");
                 pw.println("    Prints the id of device vibrators. This does not include any ");
                 pw.println("    connected input device.");
-                pw.println("  synced [options] <effect>");
+                pw.println("  synced [options] <effect>...");
                 pw.println("    Vibrates effect on all vibrators in sync.");
-                pw.println("  combined [options] (-v <vibrator-id> <effect>)...");
+                pw.println("  combined [options] (-v <vibrator-id> <effect>...)...");
                 pw.println("    Vibrates different effects on each vibrator in sync.");
-                pw.println("  sequential [options] (-v <vibrator-id> [-w <delay>] <effect>)...");
+                pw.println("  sequential [options] (-v <vibrator-id> <effect>...)...");
                 pw.println("    Vibrates different effects on each vibrator in sequence.");
                 pw.println("  cancel");
                 pw.println("    Cancels any active vibration");
                 pw.println("");
                 pw.println("Effect commands:");
-                pw.println("  oneshot [-a] <duration> [<amplitude>]");
+                pw.println("  oneshot [-w delay] [-a] <duration> [<amplitude>]");
                 pw.println("    Vibrates for duration milliseconds; ignored when device is on ");
                 pw.println("    DND (Do Not Disturb) mode; touch feedback strength user setting ");
                 pw.println("    will be used to scale amplitude.");
+                pw.println("    If -w is provided, the effect will be played after the specified");
+                pw.println("    wait time in milliseconds.");
                 pw.println("    If -a is provided, the command accepts a second argument for ");
                 pw.println("    amplitude, in a scale of 1-255.");
-                pw.println("  waveform [-r <index>] [-a] (<duration> [<amplitude>])...");
+                pw.print("    waveform [-w delay] [-r index] [-a] [-f] [-c] ");
+                pw.println("(<duration> [<amplitude>] [<frequency>])...");
                 pw.println("    Vibrates for durations and amplitudes in list; ignored when ");
                 pw.println("    device is on DND (Do Not Disturb) mode; touch feedback strength ");
                 pw.println("    user setting will be used to scale amplitude.");
+                pw.println("    If -w is provided, the effect will be played after the specified");
+                pw.println("    wait time in milliseconds.");
                 pw.println("    If -r is provided, the waveform loops back to the specified");
                 pw.println("    index (e.g. 0 loops from the beginning)");
-                pw.println("    If -a is provided, the command accepts duration-amplitude pairs;");
-                pw.println("    otherwise, it accepts durations only and alternates off/on");
-                pw.println("    Duration is in milliseconds; amplitude is a scale of 1-255.");
-                pw.println("  prebaked [-b] <effect-id>");
+                pw.println("    If -a is provided, the command expects amplitude to follow each");
+                pw.println("    duration; otherwise, it accepts durations only and alternates");
+                pw.println("    off/on");
+                pw.println("    If -f is provided, the command expects frequency to follow each");
+                pw.println("    amplitude or duration; otherwise, it uses resonant frequency");
+                pw.println("    If -c is provided, the waveform is continuous and will ramp");
+                pw.println("    between values; otherwise each entry is a fixed step.");
+                pw.println("    Duration is in milliseconds; amplitude is a scale of 1-255;");
+                pw.println("    frequency is a relative value around resonant frequency 0;");
+                pw.println("  prebaked [-w delay] [-b] <effect-id>");
                 pw.println("    Vibrates with prebaked effect; ignored when device is on DND ");
                 pw.println("    (Do Not Disturb) mode; touch feedback strength user setting ");
                 pw.println("    will be used to scale amplitude.");
+                pw.println("    If -w is provided, the effect will be played after the specified");
+                pw.println("    wait time in milliseconds.");
                 pw.println("    If -b is provided, the prebaked fallback effect will be played if");
                 pw.println("    the device doesn't support the given effect-id.");
-                pw.println("  composed [-w <delay>] <primitive-id>...");
+                pw.println("  primitives ([-w delay] <primitive-id>)...");
                 pw.println("    Vibrates with a composed effect; ignored when device is on DND ");
                 pw.println("    (Do Not Disturb) mode; touch feedback strength user setting ");
                 pw.println("    will be used to scale primitive intensities.");
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index e6d37b6..16692e1 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -514,6 +514,18 @@
         }
     }
 
+    void onImeSurfaceShownChanged(WindowState windowState, boolean shown) {
+        if (mAccessibilityTracing.isEnabled()) {
+            mAccessibilityTracing.logState(TAG + ".onImeSurfaceShownChanged",
+                    "windowState=" + windowState + "; shown=" + shown);
+        }
+        final int displayId = windowState.getDisplayId();
+        final DisplayMagnifier displayMagnifier = mDisplayMagnifiers.get(displayId);
+        if (displayMagnifier != null) {
+            displayMagnifier.onImeSurfaceShownChanged(shown);
+        }
+    }
+
     private static void populateTransformationMatrix(WindowState windowState,
             Matrix outMatrix) {
         windowState.getTransformationMatrix(sTempFloats, outMatrix);
@@ -766,6 +778,15 @@
             }
         }
 
+        void onImeSurfaceShownChanged(boolean shown) {
+            if (mAccessibilityTracing.isEnabled()) {
+                mAccessibilityTracing.logState(
+                        LOG_TAG + ".onImeSurfaceShownChanged", "shown=" + shown);
+            }
+            mHandler.obtainMessage(MyHandler.MESSAGE_NOTIFY_IME_WINDOW_VISIBILITY_CHANGED,
+                    shown ? 1 : 0, 0).sendToTarget();
+        }
+
         MagnificationSpec getMagnificationSpecForWindow(WindowState windowState) {
             if (mAccessibilityTracing.isEnabled()) {
                 mAccessibilityTracing.logState(LOG_TAG + ".getMagnificationSpecForWindow",
@@ -1337,6 +1358,7 @@
             public static final int MESSAGE_NOTIFY_USER_CONTEXT_CHANGED = 3;
             public static final int MESSAGE_NOTIFY_ROTATION_CHANGED = 4;
             public static final int MESSAGE_SHOW_MAGNIFIED_REGION_BOUNDS_IF_NEEDED = 5;
+            public static final int MESSAGE_NOTIFY_IME_WINDOW_VISIBILITY_CHANGED = 6;
 
             MyHandler(Looper looper) {
                 super(looper);
@@ -1380,6 +1402,11 @@
                             }
                         }
                     } break;
+
+                    case MESSAGE_NOTIFY_IME_WINDOW_VISIBILITY_CHANGED: {
+                        final boolean shown = message.arg1 == 1;
+                        mCallbacks.onImeWindowVisibilityChanged(shown);
+                    } break;
                 }
             }
         }
@@ -1511,10 +1538,15 @@
             IBinder topFocusedWindowToken = null;
 
             synchronized (mService.mGlobalLock) {
-                // Do not send the windows if there is no top focus as
-                // the window manager is still looking for where to put it.
-                // We will do the work when we get a focus change callback.
-                final WindowState topFocusedWindowState = getTopFocusWindow();
+                // If there is a recents animation running, then use the animation target as the
+                // top window state. Otherwise,do not send the windows if there is no top focus as
+                // the window manager is still looking for where to put it. We will do the work when
+                // we get a focus change callback.
+                final RecentsAnimationController controller =
+                        mService.getRecentsAnimationController();
+                final WindowState topFocusedWindowState = controller != null
+                        ? controller.getTargetAppMainWindow()
+                        : getTopFocusWindow();
                 if (topFocusedWindowState == null) {
                     if (DEBUG) {
                         Slog.d(LOG_TAG, "top focused window is null, compute it again later");
@@ -2118,5 +2150,4 @@
             }
         }
     }
-
 }
diff --git a/services/core/java/com/android/server/wm/ActivityAssistInfo.java b/services/core/java/com/android/server/wm/ActivityAssistInfo.java
new file mode 100644
index 0000000..054044b
--- /dev/null
+++ b/services/core/java/com/android/server/wm/ActivityAssistInfo.java
@@ -0,0 +1,52 @@
+/*
+ * 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 android.os.IBinder;
+
+/**
+ * Class needed to expose some {@link ActivityRecord} fields in order to provide
+ * {@link android.service.voice.VoiceInteractionSession#onHandleAssist(AssistState)}
+ *
+ * @hide
+ */
+public class ActivityAssistInfo {
+    private final IBinder mActivityToken;
+    private final IBinder mAssistToken;
+    private final int mTaskId;
+
+    public ActivityAssistInfo(ActivityRecord activityRecord) {
+        this.mActivityToken = activityRecord.appToken;
+        this.mAssistToken = activityRecord.assistToken;
+        this.mTaskId = activityRecord.getTask().mTaskId;
+    }
+
+    /** @hide */
+    public IBinder getActivityToken() {
+        return mActivityToken;
+    }
+
+    /** @hide */
+    public IBinder getAssistToken() {
+        return mAssistToken;
+    }
+
+    /** @hide */
+    public int getTaskId() {
+        return mTaskId;
+    }
+}
diff --git a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
index 3a0eb39..dc69175 100644
--- a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
@@ -287,6 +287,11 @@
             if (mLastLaunchedActivity == r) {
                 return;
             }
+            if (mLastLaunchedActivity != null) {
+                // Transfer the launch cookie because it is a consecutive launch event.
+                r.mLaunchCookie = mLastLaunchedActivity.mLaunchCookie;
+                mLastLaunchedActivity.mLaunchCookie = null;
+            }
             mLastLaunchedActivity = r;
             if (!r.noDisplay && !r.isReportedDrawn()) {
                 if (DEBUG_METRICS) Slog.i(TAG, "Add pending draw " + r);
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 4517ef5..eadfbe2 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -6790,7 +6790,12 @@
             // The app bounds hasn't been computed yet.
             return false;
         }
-        final Configuration parentConfig = getParent().getConfiguration();
+        final WindowContainer parent = getParent();
+        if (parent == null) {
+            // The parent of detached Activity can be null.
+            return false;
+        }
+        final Configuration parentConfig = parent.getConfiguration();
         // Although colorMode, screenLayout, smallestScreenWidthDp are also fixed, generally these
         // fields should be changed with density and bounds, so here only compares the most
         // significant field.
@@ -6954,18 +6959,27 @@
         mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
         getResolvedOverrideConfiguration().seq = mConfigurationSeq;
 
-        // Sandbox max bounds by setting it to the app bounds, if activity is letterboxed or in
-        // size compat mode.
+        // Sandbox max bounds by setting it to the activity bounds, if activity is letterboxed, or
+        // has or will have mCompatDisplayInsets for size compat.
         if (providesMaxBounds()) {
-            if (DEBUG_CONFIGURATION) {
-                ProtoLog.d(WM_DEBUG_CONFIGURATION, "Sandbox max bounds for uid %s to bounds %s "
-                        + "due to letterboxing from mismatch with parent bounds? %s size compat "
-                        + "mode %s", getUid(),
-                        resolvedConfig.windowConfiguration.getBounds(), !matchParentBounds(),
-                        inSizeCompatMode());
+            mTmpBounds.set(resolvedConfig.windowConfiguration.getBounds());
+            if (mTmpBounds.isEmpty()) {
+                // When there is no override bounds, the activity will inherit the bounds from
+                // parent.
+                mTmpBounds.set(newParentConfiguration.windowConfiguration.getBounds());
             }
-            resolvedConfig.windowConfiguration
-                    .setMaxBounds(resolvedConfig.windowConfiguration.getBounds());
+            if (DEBUG_CONFIGURATION) {
+                ProtoLog.d(WM_DEBUG_CONFIGURATION, "Sandbox max bounds for uid %s to bounds %s. "
+                                + "letterboxing from mismatch with parent bounds = %s, "
+                                + "has mCompatDisplayInsets = %s, "
+                                + "should create compatDisplayInsets = %s",
+                        getUid(),
+                        mTmpBounds,
+                        !matchParentBounds(),
+                        mCompatDisplayInsets != null,
+                        shouldCreateCompatDisplayInsets());
+            }
+            resolvedConfig.windowConfiguration.setMaxBounds(mTmpBounds);
         }
     }
 
@@ -7318,8 +7332,21 @@
             return false;
         }
         // Max bounds should be sandboxed where an activity is letterboxed (activity bounds will be
-        // smaller than task bounds) or put in size compat mode.
-        return !matchParentBounds() || inSizeCompatMode();
+        // smaller than task bounds).
+        if (!matchParentBounds()) {
+            return true;
+        }
+
+        // Max bounds should be sandboxed when an activity should have compatDisplayInsets, and it
+        // will keep the same bounds and screen configuration when it was first launched regardless
+        // how its parent window changes, so that the sandbox API will provide a consistent result.
+        if (mCompatDisplayInsets != null || shouldCreateCompatDisplayInsets()) {
+            return true;
+        }
+
+        // No need to sandbox for resizable apps in multi-window because resizableActivity=true
+        // indicates that they support multi-window.
+        return false;
     }
 
     @VisibleForTesting
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
index 060323c..c09136e 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
@@ -32,7 +32,6 @@
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.service.voice.IVoiceInteractionSession;
-import android.util.Pair;
 import android.util.proto.ProtoOutputStream;
 import android.window.TaskSnapshot;
 
@@ -166,7 +165,7 @@
      * Returns the top activity from each of the currently visible root tasks, and the related task
      * id. The first entry will be the focused activity.
      */
-    public abstract List<Pair<IBinder, Integer>> getTopVisibleActivities();
+    public abstract List<ActivityAssistInfo> getTopVisibleActivities();
 
     /**
      * Returns whether {@code uid} has any resumed activity.
@@ -607,4 +606,10 @@
          */
         void commit() throws RemoteException;
     }
+
+    /**
+     * A utility method to check AppOps and PackageManager for SYSTEM_ALERT_WINDOW permission.
+     */
+    public abstract boolean hasSystemAlertWindowPermission(int callingUid, int callingPid,
+            String callingPackage);
 }
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 09f5c93..c8fa50c 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -215,7 +215,6 @@
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.Log;
-import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.TimeUtils;
@@ -251,6 +250,7 @@
 import com.android.server.am.ActivityManagerService;
 import com.android.server.am.ActivityManagerServiceDumpProcessesProto;
 import com.android.server.am.AppTimeTracker;
+import com.android.server.am.AssistDataRequester;
 import com.android.server.am.BaseErrorDialog;
 import com.android.server.am.PendingIntentController;
 import com.android.server.am.PendingIntentRecord;
@@ -933,7 +933,8 @@
         return getUserManager().hasUserRestriction(restriction, userId);
     }
 
-    boolean hasSystemAlertWindowPermission(int callingUid, int callingPid, String callingPackage) {
+    boolean hasSystemAlertWindowPermission(int callingUid, int callingPid,
+            String callingPackage) {
         final int mode = getAppOpsManager().noteOpNoThrow(AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
                 callingUid, callingPackage, /* featureId */ null, "");
         if (mode == AppOpsManager.MODE_DEFAULT) {
@@ -2827,10 +2828,45 @@
 
     @Override
     public boolean requestAssistContextExtras(int requestType, IAssistDataReceiver receiver,
-            Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
+            Bundle receiverExtras, IBinder activityToken, boolean checkActivityIsTop,
+            boolean newSessionId) {
         return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
-                activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
-                PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
+                activityToken, checkActivityIsTop, newSessionId, UserHandle.getCallingUserId(),
+                null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
+    }
+
+    @Override
+    public boolean requestAssistDataForTask(IAssistDataReceiver receiver, int taskId,
+            String callingPackageName) {
+        mAmInternal.enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
+                "requestAssistDataForTask()");
+        final long callingId = Binder.clearCallingIdentity();
+        LocalService.ActivityTokens tokens = null;
+        try {
+            tokens = mInternal.getTopActivityForTask(taskId);
+        } finally {
+            Binder.restoreCallingIdentity(callingId);
+        }
+        if (tokens == null) {
+            Log.e(TAG, "Could not find activity for task " + taskId);
+            return false;
+        }
+
+        final AssistDataReceiverProxy proxy =
+                new AssistDataReceiverProxy(receiver, callingPackageName);
+        Object lock = new Object();
+        AssistDataRequester requester = new AssistDataRequester(mContext, mWindowManager,
+                getAppOpsManager(), proxy, lock, AppOpsManager.OP_ASSIST_STRUCTURE,
+                AppOpsManager.OP_NONE);
+
+        List<IBinder> topActivityToken = new ArrayList<>();
+        topActivityToken.add(tokens.getActivityToken());
+        requester.requestAssistData(topActivityToken, true /* fetchData */,
+                false /* fetchScreenshot */, true /* allowFetchData */,
+                false /* allowFetchScreenshot*/, true /* ignoreFocusCheck */,
+                Binder.getCallingUid(), callingPackageName);
+
+        return true;
     }
 
     @Override
@@ -2844,7 +2880,7 @@
     @Override
     public Bundle getAssistContextExtras(int requestType) {
         PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
-                null, null, true /* focused */, true /* newSessionId */,
+                null, null, true /* checkActivityIsTop */, true /* newSessionId */,
                 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
         if (pae == null) {
             return null;
@@ -3047,8 +3083,8 @@
 
     private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
             IAssistDataReceiver receiver, Bundle receiverExtras, IBinder activityToken,
-            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
-            int flags) {
+            boolean checkActivityIsTop, boolean newSessionId, int userHandle, Bundle args,
+            long timeout, int flags) {
         mAmInternal.enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
                 "enqueueAssistContext()");
 
@@ -3064,7 +3100,7 @@
                 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
                 return null;
             }
-            if (focused) {
+            if (checkActivityIsTop) {
                 if (activityToken != null) {
                     ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
                     if (activity != caller) {
@@ -5075,7 +5111,7 @@
         }
 
         @Override
-        public List<Pair<IBinder, Integer>> getTopVisibleActivities() {
+        public List<ActivityAssistInfo> getTopVisibleActivities() {
             synchronized (mGlobalLock) {
                 return mRootWindowContainer.getTopVisibleActivities();
             }
@@ -6370,6 +6406,13 @@
                 return new PackageConfigurationUpdaterImpl(Binder.getCallingPid());
             }
         }
+
+        @Override
+        public boolean hasSystemAlertWindowPermission(int callingUid, int callingPid,
+                String callingPackage) {
+            return ActivityTaskManagerService.this.hasSystemAlertWindowPermission(callingUid,
+                    callingPid, callingPackage);
+        }
     }
 
     final class PackageConfigurationUpdaterImpl implements
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 6d24105..a9d33dc 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -516,7 +516,7 @@
 
     /** The delay to avoid toggling the animation quickly. */
     private static final long FIXED_ROTATION_HIDE_ANIMATION_DEBOUNCE_DELAY_MS = 250;
-    private FixedRotationAnimationController mFixedRotationAnimationController;
+    private FadeRotationAnimationController mFadeRotationAnimationController;
 
     final FixedRotationTransitionListener mFixedRotationTransitionListener =
             new FixedRotationTransitionListener();
@@ -1590,8 +1590,8 @@
     }
 
     @VisibleForTesting
-    @Nullable FixedRotationAnimationController getFixedRotationAnimationController() {
-        return mFixedRotationAnimationController;
+    @Nullable FadeRotationAnimationController getFadeRotationAnimationController() {
+        return mFadeRotationAnimationController;
     }
 
     void setFixedRotationLaunchingAppUnchecked(@Nullable ActivityRecord r) {
@@ -1601,13 +1601,13 @@
     void setFixedRotationLaunchingAppUnchecked(@Nullable ActivityRecord r, int rotation) {
         if (mFixedRotationLaunchingApp == null && r != null) {
             mWmService.mDisplayNotificationController.dispatchFixedRotationStarted(this, rotation);
-            startFixedRotationAnimation(
+            startFadeRotationAnimation(
                     // Delay the hide animation to avoid blinking by clicking navigation bar that
                     // may toggle fixed rotation in a short time.
                     r == mFixedRotationTransitionListener.mAnimatingRecents /* shouldDebounce */);
         } else if (mFixedRotationLaunchingApp != null && r == null) {
             mWmService.mDisplayNotificationController.dispatchFixedRotationFinished(this);
-            finishFixedRotationAnimationIfPossible();
+            finishFadeRotationAnimationIfPossible();
         }
         mFixedRotationLaunchingApp = r;
     }
@@ -1714,12 +1714,12 @@
      *
      * @return {@code true} if the animation is executed right now.
      */
-    private boolean startFixedRotationAnimation(boolean shouldDebounce) {
+    private boolean startFadeRotationAnimation(boolean shouldDebounce) {
         if (shouldDebounce) {
             mWmService.mH.postDelayed(() -> {
                 synchronized (mWmService.mGlobalLock) {
                     if (mFixedRotationLaunchingApp != null
-                            && startFixedRotationAnimation(false /* shouldDebounce */)) {
+                            && startFadeRotationAnimation(false /* shouldDebounce */)) {
                         // Apply the transaction so the animation leash can take effect immediately.
                         getPendingTransaction().apply();
                     }
@@ -1727,23 +1727,41 @@
             }, FIXED_ROTATION_HIDE_ANIMATION_DEBOUNCE_DELAY_MS);
             return false;
         }
-        if (mFixedRotationAnimationController == null) {
-            mFixedRotationAnimationController = new FixedRotationAnimationController(this);
-            mFixedRotationAnimationController.hide();
+        if (mFadeRotationAnimationController == null) {
+            mFadeRotationAnimationController = new FadeRotationAnimationController(this);
+            mFadeRotationAnimationController.hide();
             return true;
         }
         return false;
     }
 
     /** Re-show the previously hidden windows if all seamless rotated windows are done. */
-    void finishFixedRotationAnimationIfPossible() {
-        final FixedRotationAnimationController controller = mFixedRotationAnimationController;
+    void finishFadeRotationAnimationIfPossible() {
+        final FadeRotationAnimationController controller = mFadeRotationAnimationController;
         if (controller != null && !mDisplayRotation.hasSeamlessRotatingWindow()) {
             controller.show();
-            mFixedRotationAnimationController = null;
+            mFadeRotationAnimationController = null;
         }
     }
 
+    /** Shows the given window which may be hidden for screen frozen. */
+    void finishFadeRotationAnimation(WindowState w) {
+        final FadeRotationAnimationController controller = mFadeRotationAnimationController;
+        if (controller != null && controller.show(w.mToken)) {
+            mFadeRotationAnimationController = null;
+        }
+    }
+
+    /** Returns {@code true} if the display should wait for the given window to stop freezing. */
+    boolean waitForUnfreeze(WindowState w) {
+        if (w.mForceSeamlesslyRotate) {
+            // The window should look no different before and after rotation.
+            return false;
+        }
+        final FadeRotationAnimationController controller = mFadeRotationAnimationController;
+        return controller == null || !controller.isTargetToken(w.mToken);
+    }
+
     void notifyInsetsChanged(Consumer<WindowState> dispatchInsetsChanged) {
         if (mFixedRotationLaunchingApp != null) {
             // The insets state of fixed rotation app is a rotated copy. Make sure the visibilities
@@ -2964,6 +2982,13 @@
             mScreenRotationAnimation.kill();
         }
         mScreenRotationAnimation = screenRotationAnimation;
+
+        // Hide the windows which are not significant in rotation animation. So that the windows
+        // don't need to block the unfreeze time.
+        if (screenRotationAnimation != null && screenRotationAnimation.hasScreenshot()
+                && mFadeRotationAnimationController == null) {
+            startFadeRotationAnimation(false /* shouldDebounce */);
+        }
     }
 
     public ScreenRotationAnimation getRotationAnimation() {
@@ -3699,10 +3724,15 @@
         // config. (Only happens when the target window is in a different root DA)
         if (target != null) {
             RootDisplayArea targetRoot = target.getRootDisplayArea();
-            if (targetRoot != null) {
+            if (targetRoot != null && targetRoot != mImeWindowsContainer.getRootDisplayArea()) {
                 // Reposition the IME container to the target root to get the correct bounds and
                 // config.
                 targetRoot.placeImeContainer(mImeWindowsContainer);
+                // Directly hide the IME window so it doesn't flash immediately after reparenting.
+                // InsetsController will make IME visible again before animating it.
+                if (mInputMethodWindow != null) {
+                    mInputMethodWindow.hide(false /* doAnimation */, false /* requestAnim */);
+                }
             }
         }
         // 2. Assign window layers based on the IME surface parent to make sure it is on top of the
diff --git a/services/core/java/com/android/server/wm/DisplayHashController.java b/services/core/java/com/android/server/wm/DisplayHashController.java
index 1262dee..5a8af45 100644
--- a/services/core/java/com/android/server/wm/DisplayHashController.java
+++ b/services/core/java/com/android/server/wm/DisplayHashController.java
@@ -17,7 +17,9 @@
 package com.android.server.wm;
 
 import static android.service.displayhash.DisplayHasherService.EXTRA_VERIFIED_DISPLAY_HASH;
+import static android.service.displayhash.DisplayHasherService.SERVICE_META_DATA;
 import static android.view.displayhash.DisplayHashResultCallback.DISPLAY_HASH_ERROR_INVALID_HASH_ALGORITHM;
+import static android.view.displayhash.DisplayHashResultCallback.DISPLAY_HASH_ERROR_TOO_MANY_REQUESTS;
 import static android.view.displayhash.DisplayHashResultCallback.DISPLAY_HASH_ERROR_UNKNOWN;
 import static android.view.displayhash.DisplayHashResultCallback.EXTRA_DISPLAY_HASH_ERROR_CODE;
 
@@ -34,6 +36,9 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
 import android.graphics.Matrix;
 import android.graphics.Rect;
 import android.graphics.RectF;
@@ -49,15 +54,22 @@
 import android.service.displayhash.DisplayHashParams;
 import android.service.displayhash.DisplayHasherService;
 import android.service.displayhash.IDisplayHasherService;
+import android.util.AttributeSet;
 import android.util.Size;
 import android.util.Slog;
+import android.util.Xml;
 import android.view.MagnificationSpec;
 import android.view.SurfaceControl;
 import android.view.displayhash.DisplayHash;
 import android.view.displayhash.VerifiedDisplayHash;
 
+import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
 
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Map;
@@ -102,6 +114,41 @@
     private final Matrix mTmpMatrix = new Matrix();
     private final RectF mTmpRectF = new RectF();
 
+    /**
+     * Lock used when retrieving xml metadata. Lock when retrieving the xml data the first time
+     * since it will be cached after that. Check if {@link #mParsedXml} is set to determine if the
+     * metadata needs to retrieved.
+     */
+    private final Object mParseXmlLock = new Object();
+
+    /**
+     * Flag whether the xml metadata has been retrieved and parsed. Once this is set to true,
+     * there's no need to request metadata again.
+     */
+    @GuardedBy("mParseXmlLock")
+    private boolean mParsedXml;
+
+    /**
+     * Specified throttle time in milliseconds. Don't allow an app to generate a display hash more
+     * than once per throttleTime
+     */
+    private int mThrottleDurationMillis = 0;
+
+    /**
+     * The last time an app requested to generate a display hash in System time.
+     */
+    private long mLastRequestTimeMs;
+
+    /**
+     * The last uid that requested to generate a hash.
+     */
+    private int mLastRequestUid;
+
+    /**
+     * Only used for testing. Throttling should always be enabled unless running tests
+     */
+    private boolean mDisplayHashThrottlingEnabled = true;
+
     private interface Command {
         void run(IDisplayHasherService service) throws RemoteException;
     }
@@ -131,6 +178,10 @@
         return results.getParcelable(EXTRA_VERIFIED_DISPLAY_HASH);
     }
 
+    void setDisplayHashThrottlingEnabled(boolean enable) {
+        mDisplayHashThrottlingEnabled = enable;
+    }
+
     private void generateDisplayHash(HardwareBuffer buffer, Rect bounds,
             String hashAlgorithm, RemoteCallback callback) {
         connectAndRun(
@@ -138,8 +189,36 @@
                         callback));
     }
 
+    private boolean allowedToGenerateHash(int uid) {
+        if (!mDisplayHashThrottlingEnabled) {
+            // Always allow to generate the hash. This is used to allow tests to run without
+            // waiting on the designated threshold.
+            return true;
+        }
+
+        long currentTime = System.currentTimeMillis();
+        if (mLastRequestUid != uid) {
+            mLastRequestUid = uid;
+            mLastRequestTimeMs = currentTime;
+            return true;
+        }
+
+        int throttleDurationMs = getThrottleDurationMillis();
+        if (currentTime - mLastRequestTimeMs < throttleDurationMs) {
+            return false;
+        }
+
+        mLastRequestTimeMs = currentTime;
+        return true;
+    }
+
     void generateDisplayHash(SurfaceControl.LayerCaptureArgs.Builder args,
-            Rect boundsInWindow, String hashAlgorithm, RemoteCallback callback) {
+            Rect boundsInWindow, String hashAlgorithm, int uid, RemoteCallback callback) {
+        if (!allowedToGenerateHash(uid)) {
+            sendDisplayHashError(callback, DISPLAY_HASH_ERROR_TOO_MANY_REQUESTS);
+            return;
+        }
+
         final Map<String, DisplayHashParams> displayHashAlgorithmsMap = getDisplayHashAlgorithms();
         DisplayHashParams displayHashParams = displayHashAlgorithmsMap.get(hashAlgorithm);
         if (displayHashParams == null) {
@@ -277,6 +356,64 @@
         }
     }
 
+    private int getThrottleDurationMillis() {
+        if (!parseXmlProperties()) {
+            return 0;
+        }
+        return mThrottleDurationMillis;
+    }
+
+    private boolean parseXmlProperties() {
+        // We have a separate lock for the xml parsing since it doesn't need to make the
+        // request through the service connection. Instead, we have a lock to ensure we can
+        // properly cache the xml metadata so we don't need to call into the  ExtServices
+        // process for each request.
+        synchronized (mParseXmlLock) {
+            if (mParsedXml) {
+                return true;
+            }
+
+            final ServiceInfo serviceInfo = getServiceInfo();
+            if (serviceInfo == null) return false;
+
+            final PackageManager pm = mContext.getPackageManager();
+
+            XmlResourceParser parser;
+            parser = serviceInfo.loadXmlMetaData(pm, SERVICE_META_DATA);
+            if (parser == null) {
+                return false;
+            }
+
+            Resources res;
+            try {
+                res = pm.getResourcesForApplication(serviceInfo.applicationInfo);
+            } catch (PackageManager.NameNotFoundException e) {
+                return false;
+            }
+
+            AttributeSet attrs = Xml.asAttributeSet(parser);
+
+            int type;
+            while (true) {
+                try {
+                    if (!((type = parser.next()) != XmlPullParser.END_DOCUMENT
+                            && type != XmlPullParser.START_TAG)) {
+                        break;
+                    }
+                } catch (XmlPullParserException | IOException e) {
+                    return false;
+                }
+            }
+
+            TypedArray sa = res.obtainAttributes(attrs, R.styleable.DisplayHasherService);
+            mThrottleDurationMillis = sa.getInt(
+                    R.styleable.DisplayHasherService_throttleDurationMillis, 0);
+            sa.recycle();
+            mParsedXml = true;
+            return true;
+        }
+    }
+
     /**
      * Run a command, starting the service connection if necessary.
      */
diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java
index d0e4c40..9ff701c 100644
--- a/services/core/java/com/android/server/wm/DisplayRotation.java
+++ b/services/core/java/com/android/server/wm/DisplayRotation.java
@@ -626,7 +626,7 @@
         }, true /* traverseTopToBottom */);
         mSeamlessRotationCount = 0;
         mRotatingSeamlessly = false;
-        mDisplayContent.finishFixedRotationAnimationIfPossible();
+        mDisplayContent.finishFadeRotationAnimationIfPossible();
     }
 
     private void prepareSeamlessRotation() {
@@ -717,7 +717,7 @@
                     "Performing post-rotate rotation after seamless rotation");
             // Finish seamless rotation.
             mRotatingSeamlessly = false;
-            mDisplayContent.finishFixedRotationAnimationIfPossible();
+            mDisplayContent.finishFadeRotationAnimationIfPossible();
 
             updateRotationAndSendNewConfigIfChanged();
         }
@@ -1539,20 +1539,6 @@
             }
         }
 
-        @Override
-        public boolean canUseRotationResolver() {
-            if (mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED) return false;
-
-            switch (mCurrentAppOrientation) {
-                case ActivityInfo.SCREEN_ORIENTATION_FULL_USER:
-                case ActivityInfo.SCREEN_ORIENTATION_USER:
-                case ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED:
-                case ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE:
-                case ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT:
-                    return true;
-            }
-            return false;
-        }
 
         @Override
         public void onProposedRotationChanged(int rotation) {
diff --git a/services/core/java/com/android/server/wm/FadeRotationAnimationController.java b/services/core/java/com/android/server/wm/FadeRotationAnimationController.java
new file mode 100644
index 0000000..5ee6928
--- /dev/null
+++ b/services/core/java/com/android/server/wm/FadeRotationAnimationController.java
@@ -0,0 +1,135 @@
+/*
+ * 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;
+
+import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_FIXED_TRANSFORM;
+
+import android.view.animation.AlphaAnimation;
+import android.view.animation.Animation;
+import android.view.animation.AnimationUtils;
+
+import com.android.internal.R;
+
+import java.util.ArrayList;
+
+/**
+ * Controller to fade out and in windows when the display is changing rotation. It can be used for
+ * both fixed rotation and normal rotation to hide some non-activity windows. The caller should show
+ * the windows until they are drawn with the new rotation.
+ */
+public class FadeRotationAnimationController extends FadeAnimationController {
+
+    private final ArrayList<WindowToken> mTargetWindowTokens = new ArrayList<>();
+    private final WindowManagerService mService;
+    /** If non-null, it usually indicates that there will be a screen rotation animation. */
+    private final Runnable mFrozenTimeoutRunnable;
+    private final WindowToken mNavBarToken;
+
+    public FadeRotationAnimationController(DisplayContent displayContent) {
+        super(displayContent);
+        mService = displayContent.mWmService;
+        mFrozenTimeoutRunnable = mService.mDisplayFrozen ? () -> {
+            synchronized (mService.mGlobalLock) {
+                displayContent.finishFadeRotationAnimationIfPossible();
+                mService.mWindowPlacerLocked.performSurfacePlacement();
+            }
+        } : null;
+        final DisplayPolicy displayPolicy = displayContent.getDisplayPolicy();
+        final WindowState navigationBar = displayPolicy.getNavigationBar();
+        if (navigationBar != null) {
+            mNavBarToken = navigationBar.mToken;
+            final RecentsAnimationController controller = mService.getRecentsAnimationController();
+            final boolean navBarControlledByRecents =
+                    controller != null && controller.isNavigationBarAttachedToApp();
+            // Do not animate movable navigation bar (e.g. non-gesture mode) or when the navigation
+            // bar is currently controlled by recents animation.
+            if (!displayPolicy.navigationBarCanMove() && !navBarControlledByRecents) {
+                mTargetWindowTokens.add(mNavBarToken);
+            }
+        } else {
+            mNavBarToken = null;
+        }
+        displayContent.forAllWindows(w -> {
+            if (w.mActivityRecord == null && w.mHasSurface && !w.mForceSeamlesslyRotate
+                    && !w.mIsWallpaper && !w.mIsImWindow && w != navigationBar) {
+                mTargetWindowTokens.add(w.mToken);
+            }
+        }, true /* traverseTopToBottom */);
+    }
+
+    /** Applies show animation on the previously hidden window tokens. */
+    void show() {
+        for (int i = mTargetWindowTokens.size() - 1; i >= 0; i--) {
+            final WindowToken windowToken = mTargetWindowTokens.get(i);
+            fadeWindowToken(true /* show */, windowToken, ANIMATION_TYPE_FIXED_TRANSFORM);
+        }
+        mTargetWindowTokens.clear();
+        if (mFrozenTimeoutRunnable != null) {
+            mService.mH.removeCallbacks(mFrozenTimeoutRunnable);
+        }
+    }
+
+    /**
+     * Returns {@code true} if all target windows are shown. It only takes effects if this
+     * controller is created for normal rotation.
+     */
+    boolean show(WindowToken token) {
+        if (mFrozenTimeoutRunnable != null && mTargetWindowTokens.remove(token)) {
+            fadeWindowToken(true /* show */, token, ANIMATION_TYPE_FIXED_TRANSFORM);
+            if (mTargetWindowTokens.isEmpty()) {
+                mService.mH.removeCallbacks(mFrozenTimeoutRunnable);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /** Applies hide animation on the window tokens which may be seamlessly rotated later. */
+    void hide() {
+        for (int i = mTargetWindowTokens.size() - 1; i >= 0; i--) {
+            final WindowToken windowToken = mTargetWindowTokens.get(i);
+            fadeWindowToken(false /* show */, windowToken, ANIMATION_TYPE_FIXED_TRANSFORM);
+        }
+        if (mFrozenTimeoutRunnable != null) {
+            mService.mH.postDelayed(mFrozenTimeoutRunnable,
+                    WindowManagerService.WINDOW_FREEZE_TIMEOUT_DURATION);
+        }
+    }
+
+    /** Returns {@code true} if the window is handled by this controller. */
+    boolean isTargetToken(WindowToken token) {
+        return token == mNavBarToken || mTargetWindowTokens.contains(token);
+    }
+
+    @Override
+    public Animation getFadeInAnimation() {
+        if (mFrozenTimeoutRunnable != null) {
+            // Use a shorter animation so it is easier to align with screen rotation animation.
+            return AnimationUtils.loadAnimation(mContext, R.anim.screen_rotate_0_enter);
+        }
+        return super.getFadeInAnimation();
+    }
+
+    @Override
+    public Animation getFadeOutAnimation() {
+        if (mFrozenTimeoutRunnable != null) {
+            // Hide the window immediately because screen should have been covered by screenshot.
+            return new AlphaAnimation(0 /* fromAlpha */, 0 /* toAlpha */);
+        }
+        return super.getFadeOutAnimation();
+    }
+}
diff --git a/services/core/java/com/android/server/wm/FixedRotationAnimationController.java b/services/core/java/com/android/server/wm/FixedRotationAnimationController.java
deleted file mode 100644
index aa73170..0000000
--- a/services/core/java/com/android/server/wm/FixedRotationAnimationController.java
+++ /dev/null
@@ -1,76 +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.server.wm;
-
-import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_FIXED_TRANSFORM;
-
-import java.util.ArrayList;
-
-/**
- * Controller to fade out and in system ui when applying a fixed rotation transform to a window
- * token.
- *
- * The system bars will be fade out when the fixed rotation transform starts and will be fade in
- * once all surfaces have been rotated.
- */
-public class FixedRotationAnimationController extends FadeAnimationController {
-
-    private final WindowState mStatusBar;
-    private final WindowState mNavigationBar;
-    private final ArrayList<WindowToken> mAnimatedWindowToken = new ArrayList<>(2);
-
-    public FixedRotationAnimationController(DisplayContent displayContent) {
-        super(displayContent);
-        final DisplayPolicy displayPolicy = displayContent.getDisplayPolicy();
-        mStatusBar = displayPolicy.getStatusBar();
-
-        final RecentsAnimationController controller =
-                displayContent.mWmService.getRecentsAnimationController();
-        final boolean navBarControlledByRecents =
-                controller != null && controller.isNavigationBarAttachedToApp();
-        // Do not animate movable navigation bar (e.g. non-gesture mode) or when the navigation bar
-        // is currently controlled by recents animation.
-        mNavigationBar = !displayPolicy.navigationBarCanMove()
-                && !navBarControlledByRecents ? displayPolicy.getNavigationBar() : null;
-    }
-
-    /** Applies show animation on the previously hidden window tokens. */
-    void show() {
-        for (int i = mAnimatedWindowToken.size() - 1; i >= 0; i--) {
-            final WindowToken windowToken = mAnimatedWindowToken.get(i);
-            fadeWindowToken(true /* show */, windowToken, ANIMATION_TYPE_FIXED_TRANSFORM);
-        }
-    }
-
-    /** Applies hide animation on the window tokens which may be seamlessly rotated later. */
-    void hide() {
-        if (mNavigationBar != null) {
-            fadeWindowToken(false /* show */, mNavigationBar.mToken,
-                    ANIMATION_TYPE_FIXED_TRANSFORM);
-        }
-        if (mStatusBar != null) {
-            fadeWindowToken(false /* show */, mStatusBar.mToken,
-                    ANIMATION_TYPE_FIXED_TRANSFORM);
-        }
-    }
-
-    @Override
-    public void fadeWindowToken(boolean show, WindowToken windowToken, int animationType) {
-        super.fadeWindowToken(show, windowToken, animationType);
-        mAnimatedWindowToken.add(windowToken);
-    }
-}
diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java
index 465042d..cda3fda 100644
--- a/services/core/java/com/android/server/wm/InsetsPolicy.java
+++ b/services/core/java/com/android/server/wm/InsetsPolicy.java
@@ -25,6 +25,7 @@
 import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
 import static android.view.InsetsState.ITYPE_STATUS_BAR;
 import static android.view.SyncRtSurfaceTransactionApplier.applyParams;
+import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION;
 
@@ -458,10 +459,8 @@
         InsetsPolicyAnimationControlCallbacks mControlCallbacks;
 
         InsetsPolicyAnimationControlListener(boolean show, Runnable finishCallback, int types) {
-
-            super(show, false /* hasCallbacks */, types, false /* disable */,
-                    (int) (mDisplayContent.getDisplayMetrics().density * FLOATING_IME_BOTTOM_INSET
-                            + 0.5f));
+            super(show, false /* hasCallbacks */, types, BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE,
+                    false /* disable */, 0 /* floatingImeBottomInsets */);
             mFinishCallback = finishCallback;
             mControlCallbacks = new InsetsPolicyAnimationControlCallbacks(this);
         }
@@ -497,7 +496,7 @@
                 // the controlled types should be animated regardless of the frame.
                 mAnimationControl = new InsetsAnimationControlImpl(controls,
                         null /* frame */, state, mListener, typesReady, this,
-                        mListener.getDurationMs(), InsetsController.SYSTEM_BARS_INTERPOLATOR,
+                        mListener.getDurationMs(), getInsetsInterpolator(),
                         show ? ANIMATION_TYPE_SHOW : ANIMATION_TYPE_HIDE, null /* translator */);
                 SurfaceAnimationThread.getHandler().post(
                         () -> mListener.onReady(mAnimationControl, typesReady));
diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
index 38ad4f0..7b0fb01 100644
--- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
@@ -30,7 +30,6 @@
 import static com.android.server.wm.InsetsSourceProviderProto.CONTROL_TARGET;
 import static com.android.server.wm.InsetsSourceProviderProto.FAKE_CONTROL;
 import static com.android.server.wm.InsetsSourceProviderProto.FAKE_CONTROL_TARGET;
-import static com.android.server.wm.InsetsSourceProviderProto.FINISH_SEAMLESS_ROTATE_FRAME_NUMBER;
 import static com.android.server.wm.InsetsSourceProviderProto.FRAME;
 import static com.android.server.wm.InsetsSourceProviderProto.IME_OVERRIDDEN_FRAME;
 import static com.android.server.wm.InsetsSourceProviderProto.IS_LEASH_READY_FOR_DISPATCHING;
@@ -60,6 +59,7 @@
 import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
 
 import java.io.PrintWriter;
+import java.util.function.Consumer;
 
 /**
  * Controller for a specific inset source on the server. It's called provider as it provides the
@@ -85,6 +85,16 @@
     private final Rect mImeOverrideFrame = new Rect();
     private boolean mIsLeashReadyForDispatching;
 
+    private final Consumer<Transaction> mSetLeashPositionConsumer = t -> {
+        if (mControl != null) {
+            final SurfaceControl leash = mControl.getLeash();
+            if (leash != null) {
+                final Point position = mControl.getSurfacePosition();
+                t.setPosition(leash, position.x, position.y);
+            }
+        }
+    };
+
     /** The visibility override from the current controlling window. */
     private boolean mClientVisible;
 
@@ -151,7 +161,6 @@
             // TODO: Ideally, we should wait for the animation to finish so previous window can
             // animate-out as new one animates-in.
             mWin.cancelAnimation();
-            mWin.mPendingPositionChanged = null;
             mWin.mProvidedInsetsSources.remove(mSource.getType());
         }
         ProtoLog.d(WM_DEBUG_IME, "InsetsSource setWin %s", win);
@@ -252,12 +261,11 @@
             final Point position = getWindowFrameSurfacePosition();
             if (mControl.setSurfacePosition(position.x, position.y) && mControlTarget != null) {
                 changed = true;
-                if (!mWin.getWindowFrames().didFrameSizeChange()) {
-                    updateLeashPosition(-1 /* frameNumber */);
-                } else if (mWin.mInRelayout) {
-                    updateLeashPosition(mWin.getFrameNumber());
+                if (mWin.getWindowFrames().didFrameSizeChange() && mWin.mWinAnimator.getShown()
+                        && mWin.okToDisplay()) {
+                    mWin.applyWithNextDraw(mSetLeashPositionConsumer);
                 } else {
-                    mWin.mPendingPositionChanged = this;
+                    mSetLeashPositionConsumer.accept(mWin.getPendingTransaction());
                 }
             }
             final Insets insetsHint = mSource.calculateInsets(
@@ -272,19 +280,6 @@
         }
     }
 
-    void updateLeashPosition(long frameNumber) {
-        if (mControl == null) {
-            return;
-        }
-        final SurfaceControl leash = mControl.getLeash();
-        if (leash != null) {
-            final Transaction t = mDisplayContent.getPendingTransaction();
-            final Point position = mControl.getSurfacePosition();
-            t.setPosition(leash, position.x, position.y);
-            deferTransactionUntil(t, leash, frameNumber);
-        }
-    }
-
     private Point getWindowFrameSurfacePosition() {
         final Rect frame = mWin.getFrame();
         final Point position = new Point();
@@ -292,14 +287,6 @@
         return position;
     }
 
-    private void deferTransactionUntil(Transaction t, SurfaceControl leash, long frameNumber) {
-        if (frameNumber >= 0) {
-            final SurfaceControl barrier = mWin.getClientViewRootSurface();
-            t.deferTransactionUntil(mWin.getSurfaceControl(), barrier, frameNumber);
-            t.deferTransactionUntil(leash, barrier, frameNumber);
-        }
-    }
-
     /**
      * @see InsetsStateController#onControlFakeTargetChanged(int, InsetsControlTarget)
      */
diff --git a/services/core/java/com/android/server/wm/KeyguardController.java b/services/core/java/com/android/server/wm/KeyguardController.java
index b31c2e4..20216c3 100644
--- a/services/core/java/com/android/server/wm/KeyguardController.java
+++ b/services/core/java/com/android/server/wm/KeyguardController.java
@@ -167,6 +167,11 @@
         if (aodChanged) {
             // Ensure the new state takes effect.
             mWindowManager.mWindowPlacerLocked.performSurfacePlacement();
+            // If the device can enter AOD and keyguard at the same time, the screen will not be
+            // turned off, so the snapshot needs to be refreshed when these states are changed.
+            if (aodShowing && keyguardShowing && keyguardChanged) {
+                mWindowManager.mTaskSnapshotController.snapshotForSleeping(DEFAULT_DISPLAY);
+            }
         }
 
         if (keyguardChanged) {
diff --git a/services/core/java/com/android/server/wm/NonAppWindowAnimationAdapter.java b/services/core/java/com/android/server/wm/NonAppWindowAnimationAdapter.java
index 4ab5cd6..b1e12b6 100644
--- a/services/core/java/com/android/server/wm/NonAppWindowAnimationAdapter.java
+++ b/services/core/java/com/android/server/wm/NonAppWindowAnimationAdapter.java
@@ -77,7 +77,7 @@
             final boolean shouldAttachNavBarToApp =
                     displayContent.getDisplayPolicy().shouldAttachNavBarToAppDuringTransition()
                             && service.getRecentsAnimationController() == null
-                            && displayContent.getFixedRotationAnimationController() == null;
+                            && displayContent.getFadeRotationAnimationController() == null;
             if (shouldAttachNavBarToApp) {
                 startNavigationBarWindowAnimation(
                         displayContent, durationHint, statusBarTransitionDelay, targets,
diff --git a/services/core/java/com/android/server/wm/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java
index d81181d..20c0d41 100644
--- a/services/core/java/com/android/server/wm/RecentTasks.java
+++ b/services/core/java/com/android/server/wm/RecentTasks.java
@@ -1573,6 +1573,10 @@
                 } else if (document || trIsDocument) {
                     // Only one of these is a document. Not the droid we're looking for.
                     continue;
+                } else if (multiTasksAllowed) {
+                    // Neither is a document, but the new task supports multiple tasks so keep the
+                    // existing task
+                    continue;
                 }
             }
             return i;
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index 64ff108..bd84854 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -568,8 +568,9 @@
                             ? mMinimizedHomeBounds
                             : null;
             final Rect contentInsets;
-            if (mTargetActivityRecord != null && mTargetActivityRecord.findMainWindow() != null) {
-                contentInsets = mTargetActivityRecord.findMainWindow()
+            final WindowState targetAppMainWindow = getTargetAppMainWindow();
+            if (targetAppMainWindow != null) {
+                contentInsets = targetAppMainWindow
                         .getInsetsStateWithVisibilityOverride()
                         .calculateInsets(mTargetActivityRecord.getBounds(), Type.systemBars(),
                                 false /* ignoreVisibility */);
@@ -607,8 +608,8 @@
 
     private void attachNavigationBarToApp() {
         if (!mShouldAttachNavBarToAppDuringTransition
-                // Skip the case where the nav bar is controlled by fixed rotation.
-                || mDisplayContent.getFixedRotationAnimationController() != null) {
+                // Skip the case where the nav bar is controlled by fade rotation.
+                || mDisplayContent.getFadeRotationAnimationController() != null) {
             return;
         }
         ActivityRecord topActivity = null;
@@ -1004,9 +1005,7 @@
 
     boolean updateInputConsumerForApp(InputWindowHandle inputWindowHandle) {
         // Update the input consumer touchable region to match the target app main window
-        final WindowState targetAppMainWindow = mTargetActivityRecord != null
-                ? mTargetActivityRecord.findMainWindow()
-                : null;
+        final WindowState targetAppMainWindow = getTargetAppMainWindow();
         if (targetAppMainWindow != null) {
             targetAppMainWindow.getBounds(mTmpRect);
             inputWindowHandle.touchableRegion.set(mTmpRect);
@@ -1026,6 +1025,13 @@
         return mTargetActivityRecord.windowsCanBeWallpaperTarget();
     }
 
+    WindowState getTargetAppMainWindow() {
+        if (mTargetActivityRecord == null) {
+            return null;
+        }
+        return mTargetActivityRecord.findMainWindow();
+    }
+
     boolean isAnimatingTask(Task task) {
         for (int i = mPendingAnimations.size() - 1; i >= 0; i--) {
             if (task == mPendingAnimations.get(i).mTask) {
diff --git a/services/core/java/com/android/server/wm/RootDisplayArea.java b/services/core/java/com/android/server/wm/RootDisplayArea.java
index 505af05..cd20c82 100644
--- a/services/core/java/com/android/server/wm/RootDisplayArea.java
+++ b/services/core/java/com/android/server/wm/RootDisplayArea.java
@@ -79,10 +79,6 @@
      */
     void placeImeContainer(DisplayArea.Tokens imeContainer) {
         final RootDisplayArea previousRoot = imeContainer.getRootDisplayArea();
-        if (previousRoot == this) {
-            // No need to reparent if IME container is below the same root.
-            return;
-        }
 
         List<Feature> features = mFeatures;
         for (int i = 0; i < features.size(); i++) {
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 857217f..7261048 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -1817,8 +1817,8 @@
      * @return a list of pairs, containing activities and their task id which are the top ones in
      * each visible root task. The first entry will be the focused activity.
      */
-    List<Pair<IBinder, Integer>> getTopVisibleActivities() {
-        final ArrayList<Pair<IBinder, Integer>> topVisibleActivities = new ArrayList<>();
+    List<ActivityAssistInfo> getTopVisibleActivities() {
+        final ArrayList<ActivityAssistInfo> topVisibleActivities = new ArrayList<>();
         final Task topFocusedRootTask = getTopDisplayFocusedRootTask();
         // Traverse all displays.
         forAllRootTasks(rootTask -> {
@@ -1826,8 +1826,7 @@
             if (rootTask.shouldBeVisible(null /* starting */)) {
                 final ActivityRecord top = rootTask.getTopNonFinishingActivity();
                 if (top != null) {
-                    Pair<IBinder, Integer> visibleActivity = new Pair<>(top.appToken,
-                            top.getTask().mTaskId);
+                    ActivityAssistInfo visibleActivity = new ActivityAssistInfo(top);
                     if (rootTask == topFocusedRootTask) {
                         topVisibleActivities.add(0, visibleActivity);
                     } else {
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java
index 8915eba..5af44317 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotController.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java
@@ -635,20 +635,7 @@
         mHandler.post(() -> {
             try {
                 synchronized (mService.mGlobalLock) {
-                    mTmpTasks.clear();
-                    mService.mRoot.getDisplayContent(displayId).forAllTasks(task -> {
-                        // 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()) {
-                            mTmpTasks.add(task);
-                        }
-                    });
-                    // Allow taking snapshot of home when turning screen off to reduce the delay of
-                    // waking from secure lock to home.
-                    final boolean allowSnapshotHome = displayId == Display.DEFAULT_DISPLAY &&
-                            mService.mPolicy.isKeyguardSecure(mService.mCurrentUserId);
-                    snapshotTasks(mTmpTasks, allowSnapshotHome);
+                    snapshotForSleeping(displayId);
                 }
             } finally {
                 listener.onScreenOff();
@@ -656,6 +643,27 @@
         });
     }
 
+    /** Called when the device is going to sleep (e.g. screen off, AOD without screen off). */
+    void snapshotForSleeping(int displayId) {
+        if (shouldDisableSnapshots()) {
+            return;
+        }
+        mTmpTasks.clear();
+        mService.mRoot.getDisplayContent(displayId).forAllTasks(task -> {
+            // 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()) {
+                mTmpTasks.add(task);
+            }
+        });
+        // Allow taking snapshot of home when turning screen off to reduce the delay of waking from
+        // secure lock to home.
+        final boolean allowSnapshotHome = displayId == Display.DEFAULT_DISPLAY
+                && mService.mPolicy.isKeyguardSecure(mService.mCurrentUserId);
+        snapshotTasks(mTmpTasks, allowSnapshotHome);
+    }
+
     /**
      * @return The {@link Appearance} flags for the top fullscreen opaque window in the given
      *         {@param task}.
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index 7c5afa8..7644cf2 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -43,7 +43,6 @@
 import android.util.ArraySet;
 import android.util.MathUtils;
 import android.util.Slog;
-import android.view.DisplayInfo;
 import android.view.SurfaceControl;
 import android.view.WindowManager;
 import android.view.animation.Animation;
@@ -296,9 +295,9 @@
     }
 
     boolean updateWallpaperOffset(WindowState wallpaperWin, boolean sync) {
-        final DisplayInfo displayInfo = wallpaperWin.getDisplayInfo();
-        final int dw = displayInfo.logicalWidth;
-        final int dh = displayInfo.logicalHeight;
+        final Rect parentFrame = wallpaperWin.getParentFrame();
+        final int dw = parentFrame.width();
+        final int dh = parentFrame.height();
 
         int xOffset = 0;
         int yOffset = 0;
diff --git a/services/core/java/com/android/server/wm/WindowContextListenerController.java b/services/core/java/com/android/server/wm/WindowContextListenerController.java
index a65adbb..8b08314 100644
--- a/services/core/java/com/android/server/wm/WindowContextListenerController.java
+++ b/services/core/java/com/android/server/wm/WindowContextListenerController.java
@@ -33,6 +33,7 @@
 import android.util.ArrayMap;
 import android.view.View;
 import android.view.WindowManager.LayoutParams.WindowType;
+import android.window.WindowContext;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.protolog.common.ProtoLog;
@@ -40,22 +41,21 @@
 import java.util.Objects;
 
 /**
- * A controller to register/unregister {@link WindowContainerListener} for
- * {@link android.app.WindowContext}.
+ * A controller to register/unregister {@link WindowContainerListener} for {@link WindowContext}.
  *
  * <ul>
- *   <li>When a {@link android.app.WindowContext} is created, it registers the listener via
+ *   <li>When a {@link WindowContext} is created, it registers the listener via
  *     {@link WindowManagerService#registerWindowContextListener(IBinder, int, int, Bundle)}
  *     automatically.</li>
- *   <li>When the {@link android.app.WindowContext} adds the first window to the screen via
+ *   <li>When the {@link WindowContext} adds the first window to the screen via
  *     {@link android.view.WindowManager#addView(View, android.view.ViewGroup.LayoutParams)},
  *     {@link WindowManagerService} then updates the {@link WindowContextListenerImpl} to listen
  *     to corresponding {@link WindowToken} via this controller.</li>
- *   <li>When the {@link android.app.WindowContext} is GCed, it unregisters the previously
+ *   <li>When the {@link WindowContext} is GCed, it unregisters the previously
  *     registered listener via
  *     {@link WindowManagerService#unregisterWindowContextListener(IBinder)}.
  *     {@link WindowManagerService} is also responsible for removing the
- *     {@link android.app.WindowContext} created {@link WindowToken}.</li>
+ *     {@link WindowContext} created {@link WindowToken}.</li>
  * </ul>
  * <p>Note that the listener may be removed earlier than the
  * {@link #unregisterWindowContainerListener(IBinder)} if the listened {@link WindowContainer} was
diff --git a/services/core/java/com/android/server/wm/WindowFrames.java b/services/core/java/com/android/server/wm/WindowFrames.java
index 9245f8c..ffd6d21 100644
--- a/services/core/java/com/android/server/wm/WindowFrames.java
+++ b/services/core/java/com/android/server/wm/WindowFrames.java
@@ -113,7 +113,7 @@
     }
 
     /**
-     * @return true if the width or height has changed since last reported to the client.
+     * @return true if the width or height has changed since last updating resizing window.
      */
     boolean didFrameSizeChange() {
         return (mLastFrame.width() != mFrame.width()) || (mLastFrame.height() != mFrame.height());
@@ -135,6 +135,13 @@
     }
 
     /**
+     * @return true if the width or height has changed since last reported to the client.
+     */
+    boolean isFrameSizeChangeReported() {
+        return mFrameSizeChanged || didFrameSizeChange();
+    }
+
+    /**
      * Resets the size changed flags so they're all set to false again. This should be called
      * after the frames are reported to client.
      */
diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java
index 8148f15..ab515d4 100644
--- a/services/core/java/com/android/server/wm/WindowManagerInternal.java
+++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java
@@ -113,7 +113,7 @@
          *
          * @param magnificationRegion the current magnification region
          */
-        public void onMagnificationRegionChanged(Region magnificationRegion);
+        void onMagnificationRegionChanged(Region magnificationRegion);
 
         /**
          * Called when an application requests a rectangle on the screen to allow
@@ -124,20 +124,27 @@
          * @param right The rectangle right.
          * @param bottom The rectangle bottom.
          */
-        public void onRectangleOnScreenRequested(int left, int top, int right, int bottom);
+        void onRectangleOnScreenRequested(int left, int top, int right, int bottom);
 
         /**
          * Notifies that the rotation changed.
          *
          * @param rotation The current rotation.
          */
-        public void onRotationChanged(int rotation);
+        void onRotationChanged(int rotation);
 
         /**
          * Notifies that the context of the user changed. For example, an application
          * was started.
          */
-        public void onUserContextChanged();
+        void onUserContextChanged();
+
+        /**
+         * Notifies that the IME window visibility changed.
+         * @param shown {@code true} means the IME window shows on the screen. Otherwise it's
+         *                           hidden.
+         */
+        void onImeWindowVisibilityChanged(boolean shown);
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 57394d6..a670b39 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -433,11 +433,6 @@
     public static boolean sEnableRemoteKeyguardAnimation =
             SystemProperties.getBoolean(ENABLE_REMOTE_KEYGUARD_ANIMATION_PROPERTY, false);
 
-    private static final String DISABLE_TRIPLE_BUFFERING_PROPERTY =
-            "ro.sf.disable_triple_buffer";
-
-    static boolean sEnableTripleBuffering = !SystemProperties.getBoolean(
-            DISABLE_TRIPLE_BUFFERING_PROPERTY, false);
 
     /**
      * Allows a fullscreen windowing mode activity to launch in its desired orientation directly
@@ -1747,9 +1742,6 @@
             if (mUseBLAST) {
                 res |= WindowManagerGlobal.ADD_FLAG_USE_BLAST;
             }
-            if (sEnableTripleBuffering) {
-                res |= WindowManagerGlobal.ADD_FLAG_USE_TRIPLE_BUFFERING;
-            }
 
             if (displayContent.mCurrentFocus == null) {
                 displayContent.mWinAddedSinceNullFocus.add(win);
@@ -2236,18 +2228,6 @@
 
             win.setFrameNumber(frameNumber);
 
-            final DisplayContent dc = win.getDisplayContent();
-
-            if (win.mPendingPositionChanged != null) {
-                win.mPendingPositionChanged.updateLeashPosition(frameNumber);
-                win.mPendingPositionChanged = null;
-            }
-
-            if (mUseBLASTSync && win.useBLASTSync() && viewVisibility != View.GONE) {
-                win.prepareDrawHandlers();
-                result |= RELAYOUT_RES_BLAST_SYNC;
-            }
-
             int attrChanges = 0;
             int flagChanges = 0;
             int privateFlagChanges = 0;
@@ -2520,6 +2500,12 @@
             }
             win.mInRelayout = false;
 
+            if (mUseBLASTSync && win.useBLASTSync() && viewVisibility != View.GONE) {
+                win.prepareDrawHandlers();
+                win.markRedrawForSyncReported();
+                result |= RELAYOUT_RES_BLAST_SYNC;
+            }
+
             if (configChanged) {
                 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER,
                         "relayoutWindow: postNewConfigurationToHandler");
@@ -2715,7 +2701,7 @@
     }
 
     /**
-     * Registers a listener for a {@link android.app.WindowContext} to subscribe to configuration
+     * Registers a listener for a {@link android.window.WindowContext} to subscribe to configuration
      * changes of a {@link DisplayArea}.
      *
      * @param clientToken the window context's token
@@ -8640,6 +8626,14 @@
         return mDisplayHashController.verifyDisplayHash(displayHash);
     }
 
+    @Override
+    public void setDisplayHashThrottlingEnabled(boolean enable) {
+        if (!checkCallingPermission(READ_FRAME_BUFFER, "setDisplayHashThrottle()")) {
+            throw new SecurityException("Requires READ_FRAME_BUFFER permission");
+        }
+        mDisplayHashController.setDisplayHashThrottlingEnabled(enable);
+    }
+
     void generateDisplayHash(Session session, IWindow window, Rect boundsInWindow,
             String hashAlgorithm, RemoteCallback callback) {
         final SurfaceControl displaySurfaceControl;
@@ -8653,6 +8647,13 @@
                 return;
             }
 
+            if (win.mActivityRecord == null || !win.mActivityRecord.isState(
+                    Task.ActivityState.RESUMED)) {
+                mDisplayHashController.sendDisplayHashError(callback,
+                        DISPLAY_HASH_ERROR_MISSING_WINDOW);
+                return;
+            }
+
             DisplayContent displayContent = win.getDisplayContent();
             if (displayContent == null) {
                 Slog.w(TAG, "Failed to generate DisplayHash. Window is not on a display");
@@ -8683,8 +8684,8 @@
                         .setUid(uid)
                         .setSourceCrop(boundsInDisplay);
 
-        mDisplayHashController.generateDisplayHash(args, boundsInWindow,
-                hashAlgorithm, callback);
+        mDisplayHashController.generateDisplayHash(args, boundsInWindow, hashAlgorithm, uid,
+                callback);
     }
 
     boolean shouldRestoreImeVisibility(IBinder imeTargetWindowToken) {
diff --git a/services/core/java/com/android/server/wm/WindowOrientationListener.java b/services/core/java/com/android/server/wm/WindowOrientationListener.java
index 5ef9420..b971cab 100644
--- a/services/core/java/com/android/server/wm/WindowOrientationListener.java
+++ b/services/core/java/com/android/server/wm/WindowOrientationListener.java
@@ -275,19 +275,6 @@
         }
     }
 
-    /**
-     * Returns true if the current status of the phone is suitable for using rotation resolver
-     * service.
-     *
-     * To reduce the power consumption of rotation resolver service, rotation query should run less
-     * frequently than other low power orientation sensors. This method is used to check whether
-     * the current status of the phone is necessary to request a suggested screen rotation from the
-     * rotation resolver service. Note that it always returns {@code false} in the base class. It
-     * should be overridden in the derived classes.
-     */
-    public boolean canUseRotationResolver() {
-        return false;
-    }
 
     /**
      * Returns true if the rotation resolver feature is enabled by setting. It means {@link
@@ -1150,11 +1137,12 @@
                     FrameworkStatsLog.write(
                             FrameworkStatsLog.DEVICE_ROTATED,
                             event.timestamp,
-                            rotationToLogEnum(reportedRotation));
+                            rotationToLogEnum(reportedRotation),
+                            FrameworkStatsLog.DEVICE_ROTATED__ROTATION_EVENT_TYPE__ACTUAL_EVENT);
                 }
             }
 
-            if (isRotationResolverEnabled() && canUseRotationResolver()) {
+            if (isRotationResolverEnabled()) {
                 if (mRotationResolverService == null) {
                     mRotationResolverService = LocalServices.getService(
                             RotationResolverInternal.class);
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 6d88387..92c9522 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -726,8 +726,6 @@
      */
     private InsetsState mFrozenInsetsState;
 
-    @Nullable InsetsSourceProvider mPendingPositionChanged;
-
     private static final float DEFAULT_DIM_AMOUNT_DEAD_WINDOW = 0.5f;
     private KeyInterceptionInfo mKeyInterceptionInfo;
 
@@ -763,6 +761,56 @@
      * into mReadyDrawHandlers. Finally once we get to finishDrawing we know everything in
      * mReadyDrawHandlers corresponds to state which was observed by the client and we can
      * invoke the consumers.
+     *
+     * To see in more detail that this works, we can look at it like this:
+     *
+     * The client is in one of these states:
+     *
+     * 1. Asleep
+     * 2. Traversal scheduled
+     * 3. Starting traversal
+     * 4. In relayout
+     * 5. Already drawing
+     *
+     * The property we want to implement with the draw handlers is:
+     *   If WM code makes a change to client observable state (e.g. configuration),
+     *   and registers a draw handler (without releasing the WM lock in between),
+     *   the FIRST frame reflecting that change, will be in the Transaction passed
+     *   to the draw handler.
+     *
+     * We describe the expected sequencing in each of the possible client states.
+     * We aim to "prove" that the WM can call applyWithNextDraw() with the client
+     * starting in any state, and achieve the desired result.
+     *
+     * 1. Asleep: The client will wake up in response to MSG_RESIZED, call relayout,
+     * observe the changes. Relayout will return BLAST_SYNC, and the client will
+     * send the transaction to finishDrawing. Since the client was asleep. This
+     * will be the first finishDrawing reflecting the change.
+     * 2, 3: traversal scheduled/starting traversal: These two states can be considered
+     *    together. Each has two sub-states:
+     *       a) Traversal will call relayout. In this case we proceed like the starting
+     *          from asleep case.
+     *       b) Traversal will not call relayout. In this case, the client produced
+     *       frame will not include the change. Because there is no call to relayout
+     *       there is no call to prepareDrawHandlers() and even if the client calls
+     *       finish drawing the draw handler will not be invoked. We have to wait
+     *       on the client to receive MSG_RESIZED, and will sync on the next frame
+     * 4. In relayout. In this case we are careful to prepare draw handlers and check
+     *    whether to return the BLAST flag at the end of relayoutWindow. This means if you
+     *    add a draw handler while the client is in relayout, BLAST_SYNC will be
+     *    immediately returned, and the client will submit the frame corresponding
+     *    to what returns from layout. When we prepare the draw handlers we clear the
+     *    flag which would later cause us to report draw for sync. Since we reported
+     *    sync through relayout (by luck the client was calling relayout perhaps)
+     *    there is no need for a MSG_RESIZED.
+     * 5. Already drawing. This works much like cases 2 and 3. If there is no call to
+     *    finishDrawing then of course the draw handlers will not be invoked and we just
+     *    wait on the next frame for sync. If there is a call to finishDrawing,
+     *    the draw handler will not have been prepared (since we did not call relayout)
+     *    and we will have to wait on the next frame.
+     *
+     * By this logic we can see no matter which of the client states we are in when the
+     * draw handler is added, it will always execute on the expected frame.
      */
     private final List<Consumer<SurfaceControl.Transaction>> mPendingDrawHandlers
         = new ArrayList<>();
@@ -774,6 +822,12 @@
         updateSurfacePosition(t);
     };
 
+    private final Consumer<SurfaceControl.Transaction> mSetSurfacePositionConsumer = t -> {
+        if (mSurfaceControl != null && mSurfaceControl.isValid()) {
+            t.setPosition(mSurfaceControl, mSurfacePosition.x, mSurfacePosition.y);
+        }
+    };
+
     /**
      * @see #setSurfaceTranslationY(int)
      */
@@ -1514,11 +1568,20 @@
     }
 
     void setOrientationChanging(boolean changing) {
-        mOrientationChanging = changing;
         mOrientationChangeTimedOut = false;
+        if (mOrientationChanging == changing) {
+            return;
+        }
+        mOrientationChanging = changing;
         if (changing) {
             mLastFreezeDuration = 0;
-            mWmService.mRoot.mOrientationChangeComplete = false;
+            if (mWmService.mRoot.mOrientationChangeComplete
+                    && mDisplayContent.waitForUnfreeze(this)) {
+                mWmService.mRoot.mOrientationChangeComplete = false;
+            }
+        } else {
+            // The orientation change is completed. If it was hidden by the animation, reshow it.
+            mDisplayContent.finishFadeRotationAnimation(this);
         }
     }
 
@@ -2121,18 +2184,7 @@
         final int left = mWindowFrames.mFrame.left;
         final int top = mWindowFrames.mFrame.top;
 
-        // During the transition from pip to fullscreen, the activity windowing mode is set to
-        // fullscreen at the beginning while the task is kept in pinned mode. Skip the move
-        // animation in such case since the transition is handled in SysUI.
-        final boolean hasMovementAnimation = getTask() == null
-                ? getWindowConfiguration().hasMovementAnimations()
-                : getTask().getWindowConfiguration().hasMovementAnimations();
-        if (mToken.okToAnimate()
-                && (mAttrs.privateFlags & PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0
-                && !isDragResizing()
-                && hasMovementAnimation
-                && !mWinAnimator.mLastHidden
-                && !mSeamlesslyRotated) {
+        if (canPlayMoveAnimation()) {
             startMoveAnimation(left, top);
         }
 
@@ -2148,6 +2200,22 @@
         mMovedByResize = false;
     }
 
+    private boolean canPlayMoveAnimation() {
+
+        // During the transition from pip to fullscreen, the activity windowing mode is set to
+        // fullscreen at the beginning while the task is kept in pinned mode. Skip the move
+        // animation in such case since the transition is handled in SysUI.
+        final boolean hasMovementAnimation = getTask() == null
+                ? getWindowConfiguration().hasMovementAnimations()
+                : getTask().getWindowConfiguration().hasMovementAnimations();
+        return mToken.okToAnimate()
+                && (mAttrs.privateFlags & PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0
+                && !isDragResizing()
+                && hasMovementAnimation
+                && !mWinAnimator.mLastHidden
+                && !mSeamlesslyRotated;
+    }
+
     /**
      * Return whether this window has moved. (Only makes
      * sense to call from performLayoutAndPlaceSurfacesLockedInner().)
@@ -3394,6 +3462,9 @@
         if (mAttrs.type >= FIRST_SYSTEM_WINDOW && mAttrs.type != TYPE_TOAST) {
             mWmService.mAtmService.mActiveUids.onNonAppSurfaceVisibilityChanged(mOwnerUid, shown);
         }
+        if (mIsImWindow && mWmService.mAccessibilityController != null) {
+            mWmService.mAccessibilityController.onImeSurfaceShownChanged(this, shown);
+        }
     }
 
     private void logExclusionRestrictions(int side) {
@@ -3697,7 +3768,7 @@
         final int displayId = getDisplayId();
         fillClientWindowFrames(mClientWindowFrames);
 
-        mRedrawForSyncReported = true;
+        markRedrawForSyncReported();
 
         try {
             mClient.resized(mClientWindowFrames, reportDraw, mergedConfiguration, forceRelayout,
@@ -5318,13 +5389,18 @@
         // prior to the rotation.
         if (!mSurfaceAnimator.hasLeash() && mPendingSeamlessRotate == null
                 && !mLastSurfacePosition.equals(mSurfacePosition)) {
-            t.setPosition(mSurfaceControl, mSurfacePosition.x, mSurfacePosition.y);
+            final boolean frameSizeChanged = mWindowFrames.isFrameSizeChangeReported();
+            final boolean surfaceInsetsChanged = surfaceInsetsChanging();
+            final boolean surfaceSizeChanged = frameSizeChanged || surfaceInsetsChanged;
             mLastSurfacePosition.set(mSurfacePosition.x, mSurfacePosition.y);
-            if (surfaceInsetsChanging() && mWinAnimator.hasSurface()) {
+            if (surfaceInsetsChanged) {
                 mLastSurfaceInsets.set(mAttrs.surfaceInsets);
-                t.deferTransactionUntil(mSurfaceControl,
-                        mWinAnimator.mSurfaceController.mSurfaceControl,
-                        getFrameNumber());
+            }
+            if (surfaceSizeChanged && mWinAnimator.getShown() && !canPlayMoveAnimation()
+                    && okToDisplay()) {
+                applyWithNextDraw(mSetSurfacePositionConsumer);
+            } else {
+                mSetSurfacePositionConsumer.accept(t);
             }
         }
     }
@@ -5841,7 +5917,7 @@
      * "in relayout", the results may be undefined but at all other times the function
      * should sort of transparently work like this:
      *    1. Make changes to WM hierarchy (say change app configuration)
-     *    2. Call apply with next draw.
+     *    2. Call applyWithNextDraw
      *    3. After finishDrawing, our consumer will be passed the Transaction
      *    containing the buffer, and we can merge in additional operations.
      * See {@link WindowState#mPendingDrawHandlers}
@@ -5870,16 +5946,26 @@
      * See {@link WindowState#mPendingDrawHandlers}
      */
     boolean executeDrawHandlers(SurfaceControl.Transaction t) {
-        if (t == null) t = mTmpTransaction;
         boolean hadHandlers = false;
+        boolean applyHere = false;
+        if (t == null) {
+            t = mTmpTransaction;
+            applyHere = true;
+        }
+
         for (int i = 0; i < mReadyDrawHandlers.size(); i++) {
             mReadyDrawHandlers.get(i).accept(t);
             hadHandlers = true;
         }
-        mReadyDrawHandlers.clear();
-        mWmService.mH.removeMessages(WINDOW_STATE_BLAST_SYNC_TIMEOUT, this);
 
-        t.apply();
+        if (hadHandlers) {
+            mReadyDrawHandlers.clear();
+            mWmService.mH.removeMessages(WINDOW_STATE_BLAST_SYNC_TIMEOUT, this);
+        }
+
+        if (applyHere) {
+            t.apply();
+        }
 
         return hadHandlers;
     }
@@ -5897,4 +5983,8 @@
     @WindowManager.LayoutParams.WindowType int getWindowType() {
         return mAttrs.type;
     }
+
+    void markRedrawForSyncReported() {
+       mRedrawForSyncReported = true;
+    }
 }
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index ebbebbb..3ef7ccd 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -272,14 +272,15 @@
             }
             mDrawState = COMMIT_DRAW_PENDING;
             layoutNeeded = true;
+        }
 
-            if (postDrawTransaction != null) {
+        if (postDrawTransaction != null) {
+            if (mLastHidden) {
                 mPostDrawTransaction.merge(postDrawTransaction);
+                layoutNeeded = true;
+            } else {
+                postDrawTransaction.apply();
             }
-        } else if (postDrawTransaction != null) {
-            // If draw state is not pending we may delay applying this transaction from the client,
-            // so apply it now.
-            postDrawTransaction.apply();
         }
 
         return layoutNeeded;
@@ -656,8 +657,10 @@
 
         if (w.getOrientationChanging()) {
             if (!w.isDrawn()) {
-                w.mWmService.mRoot.mOrientationChangeComplete = false;
-                mAnimator.mLastWindowFreezeSource = w;
+                if (w.mDisplayContent.waitForUnfreeze(w)) {
+                    w.mWmService.mRoot.mOrientationChangeComplete = false;
+                    mAnimator.mLastWindowFreezeSource = w;
+                }
                 ProtoLog.v(WM_DEBUG_ORIENTATION,
                         "Orientation continue waiting for draw in %s", w);
             } else {
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index 5276d9c8..d54cf5f 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -54,6 +54,7 @@
 import android.view.InsetsState;
 import android.view.SurfaceControl;
 import android.view.WindowManager;
+import android.window.WindowContext;
 
 import com.android.internal.protolog.common.ProtoLog;
 import com.android.server.policy.WindowManagerPolicy;
@@ -109,7 +110,7 @@
     private FixedRotationTransformState mFixedRotationTransformState;
 
     /**
-     * When set to {@code true}, this window token is created from {@link android.app.WindowContext}
+     * When set to {@code true}, this window token is created from {@link WindowContext}
      */
     private final boolean mFromClientToken;
 
@@ -758,11 +759,15 @@
 
     /** @see WindowState#freezeInsetsState() */
     void setInsetsFrozen(boolean freeze) {
-        if (freeze) {
-            forAllWindows(WindowState::freezeInsetsState, true /* traverseTopToBottom */);
-        } else {
-            forAllWindows(WindowState::clearFrozenInsetsState, true /* traverseTopToBottom */);
-        }
+        forAllWindows(w -> {
+            if (w.mToken == this) {
+                if (freeze) {
+                    w.freezeInsetsState();
+                } else {
+                    w.clearFrozenInsetsState();
+                }
+            }
+        },  true /* traverseTopToBottom */);
     }
 
     @Override
diff --git a/services/core/jni/com_android_server_vibrator_VibratorController.cpp b/services/core/jni/com_android_server_vibrator_VibratorController.cpp
index f60b354..cf64a68 100644
--- a/services/core/jni/com_android_server_vibrator_VibratorController.cpp
+++ b/services/core/jni/com_android_server_vibrator_VibratorController.cpp
@@ -39,11 +39,22 @@
 
 static JavaVM* sJvm = nullptr;
 static jmethodID sMethodIdOnComplete;
+static jclass sFrequencyMappingClass;
+static jmethodID sFrequencyMappingCtor;
+static jclass sVibratorInfoClass;
+static jmethodID sVibratorInfoCtor;
 static struct {
     jfieldID id;
     jfieldID scale;
     jfieldID delay;
 } sPrimitiveClassInfo;
+static struct {
+    jfieldID startAmplitude;
+    jfieldID endAmplitude;
+    jfieldID startFrequency;
+    jfieldID endFrequency;
+    jfieldID duration;
+} sRampClassInfo;
 
 static_assert(static_cast<uint8_t>(V1_0::EffectStrength::LIGHT) ==
               static_cast<uint8_t>(aidl::EffectStrength::LIGHT));
@@ -97,7 +108,17 @@
         jniEnv->DeleteGlobalRef(mCallbackListener);
     }
 
-    vibrator::HalController* hal() const { return mHal.get(); }
+    int32_t getVibratorId() const { return mVibratorId; }
+
+    vibrator::Info getVibratorInfo() { return mHal->getInfo(); }
+
+    void initHal() { mHal->init(); }
+
+    template <typename T>
+    vibrator::HalResult<T> halCall(const vibrator::HalFunction<vibrator::HalResult<T>>& fn,
+                                   const char* functionName) {
+        return mHal->doWithRetry(fn, functionName);
+    }
 
     std::function<void()> createCallback(jlong vibrationId) {
         return [vibrationId, this]() {
@@ -113,6 +134,37 @@
     const jobject mCallbackListener;
 };
 
+static aidl::BrakingPwle brakingPwle(aidl::Braking braking, int32_t duration) {
+    aidl::BrakingPwle pwle;
+    pwle.braking = braking;
+    pwle.duration = duration;
+    return pwle;
+}
+
+static aidl::ActivePwle activePwleFromJavaPrimitive(JNIEnv* env, jobject ramp) {
+    aidl::ActivePwle pwle;
+    pwle.startAmplitude =
+            static_cast<float>(env->GetFloatField(ramp, sRampClassInfo.startAmplitude));
+    pwle.endAmplitude = static_cast<float>(env->GetFloatField(ramp, sRampClassInfo.endAmplitude));
+    pwle.startFrequency =
+            static_cast<float>(env->GetFloatField(ramp, sRampClassInfo.startFrequency));
+    pwle.endFrequency = static_cast<float>(env->GetFloatField(ramp, sRampClassInfo.endFrequency));
+    pwle.duration = static_cast<int32_t>(env->GetIntField(ramp, sRampClassInfo.duration));
+    return pwle;
+}
+
+/* Return true if braking is not NONE and the active PWLE starts and ends with zero amplitude. */
+static bool shouldBeReplacedWithBraking(aidl::ActivePwle activePwle, aidl::Braking braking) {
+    return (braking != aidl::Braking::NONE) && (activePwle.startAmplitude == 0) &&
+            (activePwle.endAmplitude == 0);
+}
+
+/* Return true if braking is not NONE and the active PWLE only ends with zero amplitude. */
+static bool shouldAddLastBraking(aidl::ActivePwle lastActivePwle, aidl::Braking braking) {
+    return (braking != aidl::Braking::NONE) && (lastActivePwle.startAmplitude > 0) &&
+            (lastActivePwle.endAmplitude == 0);
+}
+
 static aidl::CompositeEffect effectFromJavaPrimitive(JNIEnv* env, jobject primitive) {
     aidl::CompositeEffect effect;
     effect.primitive = static_cast<aidl::CompositePrimitive>(
@@ -133,7 +185,7 @@
                                 jobject callbackListener) {
     std::unique_ptr<VibratorControllerWrapper> wrapper =
             std::make_unique<VibratorControllerWrapper>(env, vibratorId, callbackListener);
-    wrapper->hal()->init();
+    wrapper->initHal();
     return reinterpret_cast<jlong>(wrapper.release());
 }
 
@@ -147,18 +199,23 @@
         ALOGE("vibratorIsAvailable failed because native wrapper was not initialized");
         return JNI_FALSE;
     }
-    return wrapper->hal()->ping().isOk() ? JNI_TRUE : JNI_FALSE;
+    auto pingFn = [](std::shared_ptr<vibrator::HalWrapper> hal) { return hal->ping(); };
+    return wrapper->halCall<void>(pingFn, "ping").isOk() ? JNI_TRUE : JNI_FALSE;
 }
 
-static void vibratorOn(JNIEnv* env, jclass /* clazz */, jlong ptr, jlong timeoutMs,
-                       jlong vibrationId) {
+static jlong vibratorOn(JNIEnv* env, jclass /* clazz */, jlong ptr, jlong timeoutMs,
+                        jlong vibrationId) {
     VibratorControllerWrapper* wrapper = reinterpret_cast<VibratorControllerWrapper*>(ptr);
     if (wrapper == nullptr) {
         ALOGE("vibratorOn failed because native wrapper was not initialized");
-        return;
+        return -1;
     }
     auto callback = wrapper->createCallback(vibrationId);
-    wrapper->hal()->on(std::chrono::milliseconds(timeoutMs), callback);
+    auto onFn = [&](std::shared_ptr<vibrator::HalWrapper> hal) {
+        return hal->on(std::chrono::milliseconds(timeoutMs), callback);
+    };
+    auto result = wrapper->halCall<void>(onFn, "on");
+    return result.isOk() ? timeoutMs : (result.isUnsupported() ? 0 : -1);
 }
 
 static void vibratorOff(JNIEnv* env, jclass /* clazz */, jlong ptr) {
@@ -167,16 +224,20 @@
         ALOGE("vibratorOff failed because native wrapper was not initialized");
         return;
     }
-    wrapper->hal()->off();
+    auto offFn = [](std::shared_ptr<vibrator::HalWrapper> hal) { return hal->off(); };
+    wrapper->halCall<void>(offFn, "off");
 }
 
-static void vibratorSetAmplitude(JNIEnv* env, jclass /* clazz */, jlong ptr, jint amplitude) {
+static void vibratorSetAmplitude(JNIEnv* env, jclass /* clazz */, jlong ptr, jfloat amplitude) {
     VibratorControllerWrapper* wrapper = reinterpret_cast<VibratorControllerWrapper*>(ptr);
     if (wrapper == nullptr) {
         ALOGE("vibratorSetAmplitude failed because native wrapper was not initialized");
         return;
     }
-    wrapper->hal()->setAmplitude(static_cast<int32_t>(amplitude));
+    auto setAmplitudeFn = [&](std::shared_ptr<vibrator::HalWrapper> hal) {
+        return hal->setAmplitude(static_cast<float>(amplitude));
+    };
+    wrapper->halCall<void>(setAmplitudeFn, "setAmplitude");
 }
 
 static void vibratorSetExternalControl(JNIEnv* env, jclass /* clazz */, jlong ptr,
@@ -186,41 +247,10 @@
         ALOGE("vibratorSetExternalControl failed because native wrapper was not initialized");
         return;
     }
-    wrapper->hal()->setExternalControl(enabled);
-}
-
-static jintArray vibratorGetSupportedEffects(JNIEnv* env, jclass /* clazz */, jlong ptr) {
-    VibratorControllerWrapper* wrapper = reinterpret_cast<VibratorControllerWrapper*>(ptr);
-    if (wrapper == nullptr) {
-        ALOGE("vibratorGetSupportedEffects failed because native wrapper was not initialized");
-        return nullptr;
-    }
-    auto result = wrapper->hal()->getSupportedEffects();
-    if (!result.isOk()) {
-        return nullptr;
-    }
-    std::vector<aidl::Effect> supportedEffects = result.value();
-    jintArray effects = env->NewIntArray(supportedEffects.size());
-    env->SetIntArrayRegion(effects, 0, supportedEffects.size(),
-                           reinterpret_cast<jint*>(supportedEffects.data()));
-    return effects;
-}
-
-static jintArray vibratorGetSupportedPrimitives(JNIEnv* env, jclass /* clazz */, jlong ptr) {
-    VibratorControllerWrapper* wrapper = reinterpret_cast<VibratorControllerWrapper*>(ptr);
-    if (wrapper == nullptr) {
-        ALOGE("vibratorGetSupportedPrimitives failed because native wrapper was not initialized");
-        return nullptr;
-    }
-    auto result = wrapper->hal()->getSupportedPrimitives();
-    if (!result.isOk()) {
-        return nullptr;
-    }
-    std::vector<aidl::CompositePrimitive> supportedPrimitives = result.value();
-    jintArray primitives = env->NewIntArray(supportedPrimitives.size());
-    env->SetIntArrayRegion(primitives, 0, supportedPrimitives.size(),
-                           reinterpret_cast<jint*>(supportedPrimitives.data()));
-    return primitives;
+    auto setExternalControlFn = [&](std::shared_ptr<vibrator::HalWrapper> hal) {
+        return hal->setExternalControl(enabled);
+    };
+    wrapper->halCall<void>(setExternalControlFn, "setExternalControl");
 }
 
 static jlong vibratorPerformEffect(JNIEnv* env, jclass /* clazz */, jlong ptr, jlong effect,
@@ -233,8 +263,11 @@
     aidl::Effect effectType = static_cast<aidl::Effect>(effect);
     aidl::EffectStrength effectStrength = static_cast<aidl::EffectStrength>(strength);
     auto callback = wrapper->createCallback(vibrationId);
-    auto result = wrapper->hal()->performEffect(effectType, effectStrength, callback);
-    return result.isOk() ? result.value().count() : -1;
+    auto performEffectFn = [&](std::shared_ptr<vibrator::HalWrapper> hal) {
+        return hal->performEffect(effectType, effectStrength, callback);
+    };
+    auto result = wrapper->halCall<std::chrono::milliseconds>(performEffectFn, "performEffect");
+    return result.isOk() ? result.value().count() : (result.isUnsupported() ? 0 : -1);
 }
 
 static jlong vibratorPerformComposedEffect(JNIEnv* env, jclass /* clazz */, jlong ptr,
@@ -251,18 +284,46 @@
         effects.push_back(effectFromJavaPrimitive(env, element));
     }
     auto callback = wrapper->createCallback(vibrationId);
-    auto result = wrapper->hal()->performComposedEffect(effects, callback);
-    return result.isOk() ? result.value().count() : -1;
+    auto performComposedEffectFn = [&](std::shared_ptr<vibrator::HalWrapper> hal) {
+        return hal->performComposedEffect(effects, callback);
+    };
+    auto result = wrapper->halCall<std::chrono::milliseconds>(performComposedEffectFn,
+                                                              "performComposedEffect");
+    return result.isOk() ? result.value().count() : (result.isUnsupported() ? 0 : -1);
 }
 
-static jlong vibratorGetCapabilities(JNIEnv* env, jclass /* clazz */, jlong ptr) {
+static jlong vibratorPerformPwleEffect(JNIEnv* env, jclass /* clazz */, jlong ptr,
+                                       jobjectArray waveform, jint brakingId, jlong vibrationId) {
     VibratorControllerWrapper* wrapper = reinterpret_cast<VibratorControllerWrapper*>(ptr);
     if (wrapper == nullptr) {
-        ALOGE("vibratorGetCapabilities failed because native wrapper was not initialized");
-        return 0;
+        ALOGE("vibratorPerformPwleEffect failed because native wrapper was not initialized");
+        return -1;
     }
-    auto result = wrapper->hal()->getCapabilities();
-    return result.isOk() ? static_cast<jlong>(result.value()) : 0;
+    aidl::Braking braking = static_cast<aidl::Braking>(brakingId);
+    size_t size = env->GetArrayLength(waveform);
+    std::vector<aidl::PrimitivePwle> primitives;
+    std::chrono::milliseconds totalDuration(0);
+    for (size_t i = 0; i < size; i++) {
+        jobject element = env->GetObjectArrayElement(waveform, i);
+        aidl::ActivePwle activePwle = activePwleFromJavaPrimitive(env, element);
+        if ((i > 0) && shouldBeReplacedWithBraking(activePwle, braking)) {
+            primitives.push_back(brakingPwle(braking, activePwle.duration));
+        } else {
+            primitives.push_back(activePwle);
+        }
+        totalDuration += std::chrono::milliseconds(activePwle.duration);
+
+        if ((i == (size - 1)) && shouldAddLastBraking(activePwle, braking)) {
+            primitives.push_back(brakingPwle(braking, 0 /* duration */));
+        }
+    }
+
+    auto callback = wrapper->createCallback(vibrationId);
+    auto performPwleEffectFn = [&](std::shared_ptr<vibrator::HalWrapper> hal) {
+        return hal->performPwleEffect(primitives, callback);
+    };
+    auto result = wrapper->halCall<void>(performPwleEffectFn, "performPwleEffect");
+    return result.isOk() ? totalDuration.count() : (result.isUnsupported() ? 0 : -1);
 }
 
 static void vibratorAlwaysOnEnable(JNIEnv* env, jclass /* clazz */, jlong ptr, jlong id,
@@ -272,8 +333,11 @@
         ALOGE("vibratorAlwaysOnEnable failed because native wrapper was not initialized");
         return;
     }
-    wrapper->hal()->alwaysOnEnable(static_cast<int32_t>(id), static_cast<aidl::Effect>(effect),
+    auto alwaysOnEnableFn = [&](std::shared_ptr<vibrator::HalWrapper> hal) {
+        return hal->alwaysOnEnable(static_cast<int32_t>(id), static_cast<aidl::Effect>(effect),
                                    static_cast<aidl::EffectStrength>(strength));
+    };
+    wrapper->halCall<void>(alwaysOnEnableFn, "alwaysOnEnable");
 }
 
 static void vibratorAlwaysOnDisable(JNIEnv* env, jclass /* clazz */, jlong ptr, jlong id) {
@@ -282,27 +346,64 @@
         ALOGE("vibratorAlwaysOnDisable failed because native wrapper was not initialized");
         return;
     }
-    wrapper->hal()->alwaysOnDisable(static_cast<int32_t>(id));
+    auto alwaysOnDisableFn = [&](std::shared_ptr<vibrator::HalWrapper> hal) {
+        return hal->alwaysOnDisable(static_cast<int32_t>(id));
+    };
+    wrapper->halCall<void>(alwaysOnDisableFn, "alwaysOnDisable");
 }
 
-static float vibratorGetResonantFrequency(JNIEnv* env, jclass /* clazz */, jlong ptr) {
+static jobject vibratorGetInfo(JNIEnv* env, jclass /* clazz */, jlong ptr,
+                               jfloat suggestedSafeRange) {
     VibratorControllerWrapper* wrapper = reinterpret_cast<VibratorControllerWrapper*>(ptr);
     if (wrapper == nullptr) {
-        ALOGE("vibratorGetResonantFrequency failed because native wrapper was not initialized");
-        return NAN;
+        ALOGE("vibratorGetInfo failed because native wrapper was not initialized");
+        return nullptr;
     }
-    auto result = wrapper->hal()->getResonantFrequency();
-    return result.isOk() ? static_cast<jfloat>(result.value()) : NAN;
-}
+    vibrator::Info info = wrapper->getVibratorInfo();
 
-static float vibratorGetQFactor(JNIEnv* env, jclass /* clazz */, jlong ptr) {
-    VibratorControllerWrapper* wrapper = reinterpret_cast<VibratorControllerWrapper*>(ptr);
-    if (wrapper == nullptr) {
-        ALOGE("vibratorGetQFactor failed because native wrapper was not initialized");
-        return NAN;
+    jlong capabilities =
+            static_cast<jlong>(info.capabilities.valueOr(vibrator::Capabilities::NONE));
+    jfloat minFrequency = static_cast<jfloat>(info.minFrequency.valueOr(NAN));
+    jfloat resonantFrequency = static_cast<jfloat>(info.resonantFrequency.valueOr(NAN));
+    jfloat frequencyResolution = static_cast<jfloat>(info.frequencyResolution.valueOr(NAN));
+    jfloat qFactor = static_cast<jfloat>(info.qFactor.valueOr(NAN));
+    jintArray supportedEffects = nullptr;
+    jintArray supportedBraking = nullptr;
+    jintArray supportedPrimitives = nullptr;
+    jfloatArray maxAmplitudes = nullptr;
+
+    if (info.supportedEffects.isOk()) {
+        std::vector<aidl::Effect> effects = info.supportedEffects.value();
+        supportedEffects = env->NewIntArray(effects.size());
+        env->SetIntArrayRegion(supportedEffects, 0, effects.size(),
+                               reinterpret_cast<jint*>(effects.data()));
     }
-    auto result = wrapper->hal()->getQFactor();
-    return result.isOk() ? static_cast<jfloat>(result.value()) : NAN;
+    if (info.supportedBraking.isOk()) {
+        std::vector<aidl::Braking> braking = info.supportedBraking.value();
+        supportedBraking = env->NewIntArray(braking.size());
+        env->SetIntArrayRegion(supportedBraking, 0, braking.size(),
+                               reinterpret_cast<jint*>(braking.data()));
+    }
+    if (info.supportedPrimitives.isOk()) {
+        std::vector<aidl::CompositePrimitive> primitives = info.supportedPrimitives.value();
+        supportedPrimitives = env->NewIntArray(primitives.size());
+        env->SetIntArrayRegion(supportedPrimitives, 0, primitives.size(),
+                               reinterpret_cast<jint*>(primitives.data()));
+    }
+    if (info.maxAmplitudes.isOk()) {
+        std::vector<float> amplitudes = info.maxAmplitudes.value();
+        maxAmplitudes = env->NewFloatArray(amplitudes.size());
+        env->SetFloatArrayRegion(maxAmplitudes, 0, amplitudes.size(),
+                                 reinterpret_cast<jfloat*>(amplitudes.data()));
+    }
+
+    jobject frequencyMapping = env->NewObject(sFrequencyMappingClass, sFrequencyMappingCtor,
+                                              minFrequency, resonantFrequency, frequencyResolution,
+                                              suggestedSafeRange, maxAmplitudes);
+
+    return env->NewObject(sVibratorInfoClass, sVibratorInfoCtor, wrapper->getVibratorId(),
+                          capabilities, supportedEffects, supportedBraking, supportedPrimitives,
+                          qFactor, frequencyMapping);
 }
 
 static const JNINativeMethod method_table[] = {
@@ -311,20 +412,18 @@
          (void*)vibratorNativeInit},
         {"getNativeFinalizer", "()J", (void*)vibratorGetNativeFinalizer},
         {"isAvailable", "(J)Z", (void*)vibratorIsAvailable},
-        {"on", "(JJJ)V", (void*)vibratorOn},
+        {"on", "(JJJ)J", (void*)vibratorOn},
         {"off", "(J)V", (void*)vibratorOff},
-        {"setAmplitude", "(JI)V", (void*)vibratorSetAmplitude},
+        {"setAmplitude", "(JF)V", (void*)vibratorSetAmplitude},
         {"performEffect", "(JJJJ)J", (void*)vibratorPerformEffect},
-        {"performComposedEffect", "(J[Landroid/os/VibrationEffect$Composition$PrimitiveEffect;J)J",
+        {"performComposedEffect", "(J[Landroid/os/vibrator/PrimitiveSegment;J)J",
          (void*)vibratorPerformComposedEffect},
-        {"getSupportedEffects", "(J)[I", (void*)vibratorGetSupportedEffects},
-        {"getSupportedPrimitives", "(J)[I", (void*)vibratorGetSupportedPrimitives},
+        {"performPwleEffect", "(J[Landroid/os/vibrator/RampSegment;IJ)J",
+         (void*)vibratorPerformPwleEffect},
         {"setExternalControl", "(JZ)V", (void*)vibratorSetExternalControl},
-        {"getCapabilities", "(J)J", (void*)vibratorGetCapabilities},
         {"alwaysOnEnable", "(JJJJ)V", (void*)vibratorAlwaysOnEnable},
         {"alwaysOnDisable", "(JJ)V", (void*)vibratorAlwaysOnDisable},
-        {"getResonantFrequency", "(J)F", (void*)vibratorGetResonantFrequency},
-        {"getQFactor", "(J)F", (void*)vibratorGetQFactor},
+        {"getInfo", "(JF)Landroid/os/VibratorInfo;", (void*)vibratorGetInfo},
 };
 
 int register_android_server_vibrator_VibratorController(JavaVM* jvm, JNIEnv* env) {
@@ -334,11 +433,26 @@
     jclass listenerClass = FindClassOrDie(env, listenerClassName);
     sMethodIdOnComplete = GetMethodIDOrDie(env, listenerClass, "onComplete", "(IJ)V");
 
-    jclass primitiveClass =
-            FindClassOrDie(env, "android/os/VibrationEffect$Composition$PrimitiveEffect");
-    sPrimitiveClassInfo.id = GetFieldIDOrDie(env, primitiveClass, "id", "I");
-    sPrimitiveClassInfo.scale = GetFieldIDOrDie(env, primitiveClass, "scale", "F");
-    sPrimitiveClassInfo.delay = GetFieldIDOrDie(env, primitiveClass, "delay", "I");
+    jclass primitiveClass = FindClassOrDie(env, "android/os/vibrator/PrimitiveSegment");
+    sPrimitiveClassInfo.id = GetFieldIDOrDie(env, primitiveClass, "mPrimitiveId", "I");
+    sPrimitiveClassInfo.scale = GetFieldIDOrDie(env, primitiveClass, "mScale", "F");
+    sPrimitiveClassInfo.delay = GetFieldIDOrDie(env, primitiveClass, "mDelay", "I");
+
+    jclass rampClass = FindClassOrDie(env, "android/os/vibrator/RampSegment");
+    sRampClassInfo.startAmplitude = GetFieldIDOrDie(env, rampClass, "mStartAmplitude", "F");
+    sRampClassInfo.endAmplitude = GetFieldIDOrDie(env, rampClass, "mEndAmplitude", "F");
+    sRampClassInfo.startFrequency = GetFieldIDOrDie(env, rampClass, "mStartFrequency", "F");
+    sRampClassInfo.endFrequency = GetFieldIDOrDie(env, rampClass, "mEndFrequency", "F");
+    sRampClassInfo.duration = GetFieldIDOrDie(env, rampClass, "mDuration", "I");
+
+    jclass frequencyMappingClass = FindClassOrDie(env, "android/os/VibratorInfo$FrequencyMapping");
+    sFrequencyMappingClass = (jclass)env->NewGlobalRef(frequencyMappingClass);
+    sFrequencyMappingCtor = GetMethodIDOrDie(env, sFrequencyMappingClass, "<init>", "(FFFF[F)V");
+
+    jclass vibratorInfoClass = FindClassOrDie(env, "android/os/VibratorInfo");
+    sVibratorInfoClass = (jclass)env->NewGlobalRef(vibratorInfoClass);
+    sVibratorInfoCtor = GetMethodIDOrDie(env, sVibratorInfoClass, "<init>",
+                                         "(IJ[I[I[IFLandroid/os/VibratorInfo$FrequencyMapping;)V");
 
     return jniRegisterNativeMethods(env,
                                     "com/android/server/vibrator/VibratorController$NativeWrapper",
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java b/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java
index aed13b2..a419bf8 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java
@@ -16,6 +16,7 @@
 
 package com.android.server.devicepolicy;
 
+import static android.app.admin.DevicePolicyManager.NEARBY_STREAMING_DISABLED;
 import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_NONE;
 import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
 
@@ -69,6 +70,10 @@
             "disable-bt-contacts-sharing";
     private static final String TAG_DISABLE_SCREEN_CAPTURE = "disable-screen-capture";
     private static final String TAG_DISABLE_ACCOUNT_MANAGEMENT = "disable-account-management";
+    private static final String TAG_NEARBY_NOTIFICATION_STREAMING_POLICY =
+            "nearby-notification-streaming-policy";
+    private static final String TAG_NEARBY_APP_STREAMING_POLICY =
+            "nearby-app-streaming-policy";
     private static final String TAG_REQUIRE_AUTO_TIME = "require_auto_time";
     private static final String TAG_FORCE_EPHEMERAL_USERS = "force_ephemeral_users";
     private static final String TAG_IS_NETWORK_LOGGING_ENABLED = "is_network_logging_enabled";
@@ -139,12 +144,13 @@
     private static final String TAG_ENROLLMENT_SPECIFIC_ID = "enrollment-specific-id";
     private static final String TAG_ADMIN_CAN_GRANT_SENSORS_PERMISSIONS =
             "admin-can-grant-sensors-permissions";
-    private static final String TAG_NETWORK_SLICING_ENABLED = "network-slicing-enabled";
+    private static final String TAG_ENTERPRISE_NETWORK_PREFERENCE_ENABLED =
+            "enterprise-network-preference-enabled";
     private static final String TAG_USB_DATA_SIGNALING = "usb-data-signaling";
     private static final String ATTR_VALUE = "value";
     private static final String ATTR_LAST_NETWORK_LOGGING_NOTIFICATION = "last-notification";
     private static final String ATTR_NUM_NETWORK_LOGGING_NOTIFICATIONS = "num-notifications";
-    private static final boolean NETWORK_SLICING_ENABLED_DEFAULT = true;
+    private static final boolean ENTERPRISE_NETWORK_PREFERENCE_ENABLED_DEFAULT = true;
 
     DeviceAdminInfo info;
 
@@ -158,6 +164,12 @@
     @DevicePolicyManager.PasswordComplexity
     int mPasswordComplexity = PASSWORD_COMPLEXITY_NONE;
 
+    @DevicePolicyManager.NearbyStreamingPolicy
+    int mNearbyNotificationStreamingPolicy = NEARBY_STREAMING_DISABLED;
+
+    @DevicePolicyManager.NearbyStreamingPolicy
+    int mNearbyAppStreamingPolicy = NEARBY_STREAMING_DISABLED;
+
     @Nullable
     FactoryResetProtectionPolicy mFactoryResetProtectionPolicy = null;
 
@@ -284,7 +296,8 @@
     public String mOrganizationId;
     public String mEnrollmentSpecificId;
     public boolean mAdminCanGrantSensorsPermissions;
-    public boolean mNetworkSlicingEnabled = NETWORK_SLICING_ENABLED_DEFAULT;
+    public boolean mEnterpriseNetworkPreferenceEnabled =
+            ENTERPRISE_NETWORK_PREFERENCE_ENABLED_DEFAULT;
 
     private static final boolean USB_DATA_SIGNALING_ENABLED_DEFAULT = true;
     boolean mUsbDataSignalingEnabled = USB_DATA_SIGNALING_ENABLED_DEFAULT;
@@ -547,6 +560,14 @@
         if (mPasswordComplexity != PASSWORD_COMPLEXITY_NONE) {
             writeAttributeValueToXml(out, TAG_PASSWORD_COMPLEXITY, mPasswordComplexity);
         }
+        if (mNearbyNotificationStreamingPolicy != NEARBY_STREAMING_DISABLED) {
+            writeAttributeValueToXml(out, TAG_NEARBY_NOTIFICATION_STREAMING_POLICY,
+                    mNearbyNotificationStreamingPolicy);
+        }
+        if (mNearbyAppStreamingPolicy != NEARBY_STREAMING_DISABLED) {
+            writeAttributeValueToXml(out, TAG_NEARBY_APP_STREAMING_POLICY,
+                    mNearbyAppStreamingPolicy);
+        }
         if (!TextUtils.isEmpty(mOrganizationId)) {
             writeTextToXml(out, TAG_ORGANIZATION_ID, mOrganizationId);
         }
@@ -555,8 +576,9 @@
         }
         writeAttributeValueToXml(out, TAG_ADMIN_CAN_GRANT_SENSORS_PERMISSIONS,
                 mAdminCanGrantSensorsPermissions);
-        if (mNetworkSlicingEnabled != NETWORK_SLICING_ENABLED_DEFAULT) {
-            writeAttributeValueToXml(out, TAG_NETWORK_SLICING_ENABLED, mNetworkSlicingEnabled);
+        if (mEnterpriseNetworkPreferenceEnabled != ENTERPRISE_NETWORK_PREFERENCE_ENABLED_DEFAULT) {
+            writeAttributeValueToXml(out, TAG_ENTERPRISE_NETWORK_PREFERENCE_ENABLED,
+                    mEnterpriseNetworkPreferenceEnabled);
         }
         if (mUsbDataSignalingEnabled != USB_DATA_SIGNALING_ENABLED_DEFAULT) {
             writeAttributeValueToXml(out, TAG_USB_DATA_SIGNALING, mUsbDataSignalingEnabled);
@@ -784,13 +806,17 @@
                 mAlwaysOnVpnPackage = parser.getAttributeValue(null, ATTR_VALUE);
             } else if (TAG_ALWAYS_ON_VPN_LOCKDOWN.equals(tag)) {
                 mAlwaysOnVpnLockdown = parser.getAttributeBoolean(null, ATTR_VALUE, false);
-            } else if (TAG_NETWORK_SLICING_ENABLED.equals(tag)) {
-                mNetworkSlicingEnabled = parser.getAttributeBoolean(
-                        null, ATTR_VALUE, NETWORK_SLICING_ENABLED_DEFAULT);
+            } else if (TAG_ENTERPRISE_NETWORK_PREFERENCE_ENABLED.equals(tag)) {
+                mEnterpriseNetworkPreferenceEnabled = parser.getAttributeBoolean(
+                        null, ATTR_VALUE, ENTERPRISE_NETWORK_PREFERENCE_ENABLED_DEFAULT);
             } else if (TAG_COMMON_CRITERIA_MODE.equals(tag)) {
                 mCommonCriteriaMode = parser.getAttributeBoolean(null, ATTR_VALUE, false);
             } else if (TAG_PASSWORD_COMPLEXITY.equals(tag)) {
                 mPasswordComplexity = parser.getAttributeInt(null, ATTR_VALUE);
+            } else if (TAG_NEARBY_NOTIFICATION_STREAMING_POLICY.equals(tag)) {
+                mNearbyNotificationStreamingPolicy = parser.getAttributeInt(null, ATTR_VALUE);
+            } else if (TAG_NEARBY_APP_STREAMING_POLICY.equals(tag)) {
+                mNearbyAppStreamingPolicy = parser.getAttributeInt(null, ATTR_VALUE);
             } else if (TAG_ORGANIZATION_ID.equals(tag)) {
                 type = parser.next();
                 if (type == TypedXmlPullParser.TEXT) {
@@ -1142,8 +1168,8 @@
         pw.print("mAlwaysOnVpnLockdown=");
         pw.println(mAlwaysOnVpnLockdown);
 
-        pw.print("mNetworkSlicingEnabled=");
-        pw.println(mNetworkSlicingEnabled);
+        pw.print("mEnterpriseNetworkPreferenceEnabled=");
+        pw.println(mEnterpriseNetworkPreferenceEnabled);
 
         pw.print("mCommonCriteriaMode=");
         pw.println(mCommonCriteriaMode);
@@ -1151,6 +1177,12 @@
         pw.print("mPasswordComplexity=");
         pw.println(mPasswordComplexity);
 
+        pw.print("mNearbyNotificationStreamingPolicy=");
+        pw.println(mNearbyNotificationStreamingPolicy);
+
+        pw.print("mNearbyAppStreamingPolicy=");
+        pw.println(mNearbyAppStreamingPolicy);
+
         if (!TextUtils.isEmpty(mOrganizationId)) {
             pw.print("mOrganizationId=");
             pw.println(mOrganizationId);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java b/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
index cdd5a92b..55ab8c3 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
@@ -109,6 +109,14 @@
         return 0;
     }
 
+    @Override
+    public void acknowledgeDeviceCompliant() {}
+
+    @Override
+    public boolean isComplianceAcknowledgementRequired() {
+        return false;
+    }
+
     public boolean canProfileOwnerResetPasswordWhenLocked(int userId) {
         return false;
     }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 283895b..1858712 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -22,6 +22,7 @@
 import static android.accessibilityservice.AccessibilityServiceInfo.FEEDBACK_ALL_MASK;
 import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
 import static android.app.AppOpsManager.MODE_ALLOWED;
+import static android.app.admin.DeviceAdminReceiver.ACTION_COMPLIANCE_ACKNOWLEDGEMENT_REQUIRED;
 import static android.app.admin.DeviceAdminReceiver.EXTRA_TRANSFER_OWNERSHIP_ADMIN_EXTRAS_BUNDLE;
 import static android.app.admin.DevicePolicyManager.ACTION_CHECK_POLICY_COMPLIANCE;
 import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE;
@@ -62,6 +63,7 @@
 import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_HOME;
 import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_NOTIFICATIONS;
 import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_OVERVIEW;
+import static android.app.admin.DevicePolicyManager.NEARBY_STREAMING_DISABLED;
 import static android.app.admin.DevicePolicyManager.NON_ORG_OWNED_PROFILE_KEYGUARD_FEATURES_AFFECT_OWNER;
 import static android.app.admin.DevicePolicyManager.OPERATION_SAFETY_REASON_NONE;
 import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_HIGH;
@@ -102,8 +104,8 @@
 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
-// TODO (b/178655595) import static android.net.ConnectivityManager.USER_PREFERENCE_ENTERPRISE;
-// TODO (b/178655595) import static android.net.ConnectivityManager.USER_PREFERENCE_SYSTEM_DEFAULT;
+import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_DEFAULT;
+import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE;
 import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
 import static android.provider.Settings.Global.PRIVATE_DNS_MODE;
 import static android.provider.Settings.Global.PRIVATE_DNS_SPECIFIER;
@@ -687,12 +689,19 @@
 
     private static final boolean ENABLE_LOCK_GUARD = true;
 
-    /** Profile off deadline is not set or more than MANAGED_PROFILE_OFF_WARNING_PERIOD away. */
-    private static final int PROFILE_OFF_DEADLINE_DEFAULT = 0;
-    /** Profile off deadline is closer than MANAGED_PROFILE_OFF_WARNING_PERIOD. */
-    private static final int PROFILE_OFF_DEADLINE_WARNING = 1;
-    /** Profile off deadline reached, notify the user that personal apps blocked. */
-    private static final int PROFILE_OFF_DEADLINE_REACHED = 2;
+    /**
+     * Profile off deadline is not set or more than MANAGED_PROFILE_OFF_WARNING_PERIOD away, or the
+     * user is running unlocked, no need for notification.
+     */
+    private static final int PROFILE_OFF_NOTIFICATION_NONE = 0;
+    /**
+     * Profile off deadline is closer than MANAGED_PROFILE_OFF_WARNING_PERIOD.
+     */
+    private static final int PROFILE_OFF_NOTIFICATION_WARNING = 1;
+    /**
+     * Profile off deadline reached, notify the user that personal apps blocked.
+     */
+    private static final int PROFILE_OFF_NOTIFICATION_SUSPENDED = 2;
 
     interface Stats {
         int LOCK_GUARD_GUARD = 0;
@@ -889,10 +898,9 @@
                 }
                 if (isManagedProfile(userHandle)) {
                     Slog.d(LOG_TAG, "Managed profile became unlocked");
-                    if (updatePersonalAppsSuspension(userHandle, true /* unlocked */)
-                            == PERSONAL_APPS_SUSPENDED_PROFILE_TIMEOUT) {
-                        triggerPolicyComplianceCheck(userHandle);
-                    }
+                    final boolean suspended =
+                            updatePersonalAppsSuspension(userHandle, true /* unlocked */);
+                    triggerPolicyComplianceCheckIfNeeded(userHandle, suspended);
                 }
             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) {
                 handlePackagesChanged(null /* check all admins */, userHandle);
@@ -3089,12 +3097,13 @@
         updatePermissionPolicyCache(userId);
         updateAdminCanGrantSensorsPermissionCache(userId);
 
-        boolean enableEnterpriseNetworkSlice = true;
+        boolean enableEnterpriseNetworkPreferenceEnabled = true;
         synchronized (getLockObject()) {
             ActiveAdmin owner = getDeviceOrProfileOwnerAdminLocked(userId);
-            enableEnterpriseNetworkSlice = owner != null ? owner.mNetworkSlicingEnabled : true;
+            enableEnterpriseNetworkPreferenceEnabled = owner != null
+                    ? owner.mEnterpriseNetworkPreferenceEnabled : true;
         }
-        updateNetworkPreferenceForUser(userId, enableEnterpriseNetworkSlice);
+        updateNetworkPreferenceForUser(userId, enableEnterpriseNetworkPreferenceEnabled);
 
         startOwnerService(userId, "start-user");
     }
@@ -7464,6 +7473,78 @@
         });
     }
 
+    @Override
+    public void setNearbyNotificationStreamingPolicy(int policy) {
+        if (!mHasFeature) {
+            return;
+        }
+
+        final CallerIdentity caller = getCallerIdentity();
+        Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller));
+
+        synchronized (getLockObject()) {
+            final ActiveAdmin admin = getProfileOwnerOrDeviceOwnerLocked(caller);
+            if (admin.mNearbyNotificationStreamingPolicy != policy) {
+                admin.mNearbyNotificationStreamingPolicy = policy;
+                saveSettingsLocked(caller.getUserId());
+            }
+        }
+    }
+
+    @Override
+    public int getNearbyNotificationStreamingPolicy() {
+        if (!mHasFeature) {
+            return NEARBY_STREAMING_DISABLED;
+        }
+
+        final CallerIdentity caller = getCallerIdentity();
+        Preconditions.checkCallAuthorization(
+                isDeviceOwner(caller)
+                    || isProfileOwner(caller)
+                    || hasCallingOrSelfPermission(permission.READ_NEARBY_STREAMING_POLICY));
+
+        synchronized (getLockObject()) {
+            final ActiveAdmin admin = getProfileOwnerOrDeviceOwnerLocked(caller);
+            return admin.mNearbyNotificationStreamingPolicy;
+        }
+    }
+
+    @Override
+    public void setNearbyAppStreamingPolicy(int policy) {
+        if (!mHasFeature) {
+            return;
+        }
+
+        final CallerIdentity caller = getCallerIdentity();
+        Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller));
+
+        synchronized (getLockObject()) {
+            final ActiveAdmin admin = getProfileOwnerOrDeviceOwnerLocked(caller);
+            if (admin.mNearbyAppStreamingPolicy != policy) {
+                admin.mNearbyAppStreamingPolicy = policy;
+                saveSettingsLocked(caller.getUserId());
+            }
+        }
+    }
+
+    @Override
+    public int getNearbyAppStreamingPolicy() {
+        if (!mHasFeature) {
+            return NEARBY_STREAMING_DISABLED;
+        }
+
+        final CallerIdentity caller = getCallerIdentity();
+        Preconditions.checkCallAuthorization(
+                isDeviceOwner(caller)
+                    || isProfileOwner(caller)
+                    || hasCallingOrSelfPermission(permission.READ_NEARBY_STREAMING_POLICY));
+
+        synchronized (getLockObject()) {
+            final ActiveAdmin admin = getProfileOwnerOrDeviceOwnerLocked(caller);
+            return admin.mNearbyAppStreamingPolicy;
+        }
+    }
+
     /**
      * Set whether auto time is required by the specified admin (must be device or profile owner).
      */
@@ -10598,21 +10679,58 @@
         });
     }
 
+    /**
+     * Returns the apps that are non-exempt from some policies (such as suspension), and populates
+     * the given set with the apps that are exempt.
+     *
+     * @param packageNames apps to check
+     * @param outputExemptApps will be populate with subset of {@code packageNames} that is exempt
+     * from some policy restrictions
+     *
+     * @return subset of {@code packageNames} that is affected by some policy restrictions.
+     */
+    private String[] populateNonExemptAndExemptFromPolicyApps(String[] packageNames,
+            Set<String> outputExemptApps) {
+        Preconditions.checkArgument(outputExemptApps.isEmpty(), "outputExemptApps is not empty");
+        List<String> exemptApps = listPolicyExemptAppsUnchecked();
+        if (exemptApps.isEmpty()) {
+            return packageNames;
+        }
+        List<String> nonExemptApps = new ArrayList<>(packageNames.length);
+        for (int i = 0; i < packageNames.length; i++) {
+            String app = packageNames[i];
+            if (exemptApps.contains(app)) {
+                outputExemptApps.add(app);
+            } else {
+                nonExemptApps.add(app);
+            }
+        }
+        String[] result = new String[nonExemptApps.size()];
+        nonExemptApps.toArray(result);
+        return result;
+    }
+
     @Override
     public String[] setPackagesSuspended(ComponentName who, String callerPackage,
             String[] packageNames, boolean suspended) {
+        Objects.requireNonNull(packageNames, "array of packages cannot be null");
         final CallerIdentity caller = getCallerIdentity(who, callerPackage);
         Preconditions.checkCallAuthorization((caller.hasAdminComponent()
                 && (isProfileOwner(caller) || isDeviceOwner(caller)))
                 || (caller.hasPackage() && isCallerDelegate(caller, DELEGATION_PACKAGE_ACCESS)));
         checkCanExecuteOrThrowUnsafe(DevicePolicyManager.OPERATION_SET_PACKAGES_SUSPENDED);
 
-        String[] result = null;
+        // Must remove the exempt apps from the input before calling PM, then add them back to
+        // the array returned to the caller
+        Set<String> exemptApps = new HashSet<>();
+        packageNames = populateNonExemptAndExemptFromPolicyApps(packageNames, exemptApps);
+
+        String[] nonSuspendedPackages = null;
         synchronized (getLockObject()) {
             long id = mInjector.binderClearCallingIdentity();
             try {
-                result = mIPackageManager.setPackagesSuspendedAsUser(packageNames, suspended, null,
-                        null, null, PLATFORM_PACKAGE_NAME, caller.getUserId());
+                nonSuspendedPackages = mIPackageManager.setPackagesSuspendedAsUser(packageNames,
+                        suspended, null, null, null, PLATFORM_PACKAGE_NAME, caller.getUserId());
             } catch (RemoteException re) {
                 // Shouldn't happen.
                 Slog.e(LOG_TAG, "Failed talking to the package manager", re);
@@ -10626,10 +10744,35 @@
                 .setBoolean(/* isDelegate */ who == null)
                 .setStrings(packageNames)
                 .write();
-        if (result != null) {
-            return result;
+
+        if (nonSuspendedPackages == null) {
+            Slog.w(LOG_TAG, "PM failed to suspend packages (%s)", Arrays.toString(packageNames));
+            return packageNames;
         }
-        return packageNames;
+        if (exemptApps.isEmpty()) {
+            return nonSuspendedPackages;
+        }
+
+        String[] result = buildNonSuspendedPackagesUnionArray(nonSuspendedPackages, exemptApps);
+        if (VERBOSE_LOG) Slog.v(LOG_TAG, "Returning %s", Arrays.toString(result));
+        return result;
+    }
+
+    /**
+     * Returns an array containing the union of the given non-suspended packages and
+     * exempt apps. Assumes both parameters are non-null and non-empty.
+     */
+    private String[] buildNonSuspendedPackagesUnionArray(String[] nonSuspendedPackages,
+            Set<String> exemptApps) {
+        String[] result = new String[nonSuspendedPackages.length + exemptApps.size()];
+        int index = 0;
+        for (String app : nonSuspendedPackages) {
+            result[index++] = app;
+        }
+        for (String app : exemptApps) {
+            result[index++] = app;
+        }
+        return result;
     }
 
     @Override
@@ -10655,9 +10798,15 @@
 
     @Override
     public List<String> listPolicyExemptApps() {
+        CallerIdentity caller = getCallerIdentity();
         Preconditions.checkCallAuthorization(
-                hasCallingOrSelfPermission(permission.MANAGE_DEVICE_ADMINS));
+                hasCallingOrSelfPermission(permission.MANAGE_DEVICE_ADMINS) || isDeviceOwner(caller)
+                        || isProfileOwner(caller));
 
+        return listPolicyExemptAppsUnchecked();
+    }
+
+    private List<String> listPolicyExemptAppsUnchecked() {
         // TODO(b/181238156): decide whether it should only list the apps set by the resources,
         // or also the "critical" apps defined by PersonalAppsSuspensionHelper (like SMS app).
         // If it's the latter, refactor PersonalAppsSuspensionHelper so it (or a superclass) takes
@@ -11423,30 +11572,32 @@
     }
 
     @Override
-    public void setNetworkSlicingEnabled(boolean enabled) {
+    public void setEnterpriseNetworkPreferenceEnabled(boolean enabled) {
         if (!mHasFeature) {
             return;
         }
         final CallerIdentity caller = getCallerIdentity();
         Preconditions.checkCallAuthorization(isProfileOwner(caller),
-                "Caller is not profile owner; only profile owner may control the network slicing");
+                "Caller is not profile owner;"
+                        + " only profile owner may control the enterprise network preference");
         synchronized (getLockObject()) {
             final ActiveAdmin requiredAdmin = getProfileOwnerAdminLocked(
                     caller.getUserId());
-            if (requiredAdmin != null && requiredAdmin.mNetworkSlicingEnabled != enabled) {
-                requiredAdmin.mNetworkSlicingEnabled = enabled;
+            if (requiredAdmin != null
+                    && requiredAdmin.mEnterpriseNetworkPreferenceEnabled != enabled) {
+                requiredAdmin.mEnterpriseNetworkPreferenceEnabled = enabled;
                 saveSettingsLocked(caller.getUserId());
             }
         }
         updateNetworkPreferenceForUser(caller.getUserId(), enabled);
         DevicePolicyEventLogger
-                .createEvent(DevicePolicyEnums.SET_NETWORK_SLICING_ENABLED)
+                .createEvent(DevicePolicyEnums.SET_ENTERPRISE_NETWORK_PREFERENCE_ENABLED)
                 .setBoolean(enabled)
                 .write();
     }
 
     @Override
-    public boolean isNetworkSlicingEnabled(int userHandle) {
+    public boolean isEnterpriseNetworkPreferenceEnabled(int userHandle) {
         if (!mHasFeature) {
             return false;
         }
@@ -11457,7 +11608,7 @@
         synchronized (getLockObject()) {
             final ActiveAdmin requiredAdmin = getProfileOwnerAdminLocked(userHandle);
             if (requiredAdmin != null) {
-                return requiredAdmin.mNetworkSlicingEnabled;
+                return requiredAdmin.mEnterpriseNetworkPreferenceEnabled;
             } else {
                 return false;
             }
@@ -16040,7 +16191,6 @@
         Objects.requireNonNull(who, "ComponentName is null");
 
         final CallerIdentity caller = getCallerIdentity(who);
-        // DO shouldn't be able to use this method.
         Preconditions.checkCallAuthorization(isProfileOwnerOfOrganizationOwnedDevice(caller));
         Preconditions.checkState(canHandleCheckPolicyComplianceIntent(caller));
 
@@ -16071,18 +16221,26 @@
                 .write();
     }
 
-    /** Starts an activity to check policy compliance in the DPC. */
-    private void triggerPolicyComplianceCheck(int profileUserId) {
-        final Intent intent = new Intent(ACTION_CHECK_POLICY_COMPLIANCE);
+    /** Starts an activity to check policy compliance or request compliance acknowledgement. */
+    private void triggerPolicyComplianceCheckIfNeeded(int profileUserId, boolean suspended) {
         synchronized (getLockObject()) {
             final ActiveAdmin profileOwner = getProfileOwnerAdminLocked(profileUserId);
             if (profileOwner == null) {
                 Slog.wtf(LOG_TAG, "Profile owner not found for compliance check");
                 return;
             }
-            intent.setPackage(profileOwner.info.getPackageName());
+            if (suspended) {
+                // If suspended, DPC will need to show an activity.
+                final Intent intent = new Intent(ACTION_CHECK_POLICY_COMPLIANCE);
+                intent.setPackage(profileOwner.info.getPackageName());
+                mContext.startActivityAsUser(intent, UserHandle.of(profileUserId));
+            } else if (profileOwner.mProfileOffDeadline > 0) {
+                // If not suspended, but deadline set, DPC needs to acknowledge compliance so that
+                // the deadline can be reset.
+                sendAdminCommandLocked(profileOwner, ACTION_COMPLIANCE_ACKNOWLEDGEMENT_REQUIRED,
+                        /* adminExtras= */ null, /* receiver= */ null, /* inForeground = */ true);
+            }
         }
-        mContext.startActivityAsUser(intent, UserHandle.of(profileUserId));
     }
 
     /**
@@ -16091,39 +16249,35 @@
      *
      * @param unlocked whether the profile is currently running unlocked.
      */
-    private @PersonalAppsSuspensionReason int updatePersonalAppsSuspension(
-            int profileUserId, boolean unlocked) {
-        final boolean suspendedExplicitly;
-        final boolean suspendedByTimeout;
+    private boolean updatePersonalAppsSuspension(int profileUserId, boolean unlocked) {
+        final boolean shouldSuspend;
         synchronized (getLockObject()) {
             final ActiveAdmin profileOwner = getProfileOwnerAdminLocked(profileUserId);
             if (profileOwner != null) {
-                final int deadlineState =
-                        updateProfileOffDeadlineLocked(profileUserId, profileOwner, unlocked);
-                suspendedExplicitly = profileOwner.mSuspendPersonalApps;
-                suspendedByTimeout = deadlineState == PROFILE_OFF_DEADLINE_REACHED;
-                Slog.d(LOG_TAG, "Personal apps suspended explicitly: %b, deadline state: %d",
-                        suspendedExplicitly, deadlineState);
                 final int notificationState =
-                        unlocked ? PROFILE_OFF_DEADLINE_DEFAULT : deadlineState;
+                        updateProfileOffDeadlineLocked(profileUserId, profileOwner, unlocked);
+                final boolean suspendedExplicitly = profileOwner.mSuspendPersonalApps;
+                final boolean suspendedByTimeout = profileOwner.mProfileOffDeadline == -1;
+                Slog.d(LOG_TAG,
+                        "Personal apps suspended explicitly: %b, by timeout: %b, notification: %d",
+                        suspendedExplicitly, suspendedByTimeout, notificationState);
                 updateProfileOffDeadlineNotificationLocked(
                         profileUserId, profileOwner, notificationState);
+                shouldSuspend = suspendedExplicitly || suspendedByTimeout;
             } else {
-                suspendedExplicitly = false;
-                suspendedByTimeout = false;
+                shouldSuspend = false;
             }
         }
 
         final int parentUserId = getProfileParentId(profileUserId);
-        suspendPersonalAppsInternal(parentUserId, suspendedExplicitly || suspendedByTimeout);
-
-        return makeSuspensionReasons(suspendedExplicitly, suspendedByTimeout);
+        suspendPersonalAppsInternal(parentUserId, shouldSuspend);
+        return shouldSuspend;
     }
 
     /**
      * Checks work profile time off policy, scheduling personal apps suspension via alarm if
      * necessary.
-     * @return profile deadline state
+     * @return notification state
      */
     private int updateProfileOffDeadlineLocked(
             int profileUserId, ActiveAdmin profileOwner, boolean unlocked) {
@@ -16135,7 +16289,7 @@
                 profileOwner.mProfileOffDeadline = -1;
                 saveSettingsLocked(profileUserId);
             }
-            return PROFILE_OFF_DEADLINE_REACHED;
+            return unlocked ? PROFILE_OFF_NOTIFICATION_NONE : PROFILE_OFF_NOTIFICATION_SUSPENDED;
         }
         boolean shouldSaveSettings = false;
         if (profileOwner.mSuspendPersonalApps) {
@@ -16145,8 +16299,8 @@
                 shouldSaveSettings = true;
             }
         } else if (profileOwner.mProfileOffDeadline != 0
-                && (profileOwner.mProfileMaximumTimeOffMillis == 0 || unlocked)) {
-            // There is a deadline but either there is no policy or the profile is unlocked -> clear
+                && (profileOwner.mProfileMaximumTimeOffMillis == 0)) {
+            // There is a deadline but either there is no policy -> clear
             // the deadline.
             Slog.i(LOG_TAG, "Profile off deadline is reset to zero");
             profileOwner.mProfileOffDeadline = 0;
@@ -16165,19 +16319,19 @@
         }
 
         final long alarmTime;
-        final int deadlineState;
-        if (profileOwner.mProfileOffDeadline == 0) {
+        final int notificationState;
+        if (unlocked || profileOwner.mProfileOffDeadline == 0) {
             alarmTime = 0;
-            deadlineState = PROFILE_OFF_DEADLINE_DEFAULT;
+            notificationState = PROFILE_OFF_NOTIFICATION_NONE;
         } else if (profileOwner.mProfileOffDeadline - now < MANAGED_PROFILE_OFF_WARNING_PERIOD) {
             // The deadline is close, upon the alarm personal apps should be suspended.
             alarmTime = profileOwner.mProfileOffDeadline;
-            deadlineState = PROFILE_OFF_DEADLINE_WARNING;
+            notificationState = PROFILE_OFF_NOTIFICATION_WARNING;
         } else {
             // The deadline is quite far, upon the alarm we should warn the user first, so the
             // alarm is scheduled earlier than the actual deadline.
             alarmTime = profileOwner.mProfileOffDeadline - MANAGED_PROFILE_OFF_WARNING_PERIOD;
-            deadlineState = PROFILE_OFF_DEADLINE_DEFAULT;
+            notificationState = PROFILE_OFF_NOTIFICATION_NONE;
         }
 
         final AlarmManager am = mInjector.getAlarmManager();
@@ -16197,7 +16351,7 @@
             am.set(AlarmManager.RTC, alarmTime, pi);
         }
 
-        return deadlineState;
+        return notificationState;
     }
 
     private void suspendPersonalAppsInternal(int userId, boolean suspended) {
@@ -16239,7 +16393,7 @@
     @GuardedBy("getLockObject()")
     private void updateProfileOffDeadlineNotificationLocked(
             int profileUserId, ActiveAdmin profileOwner, int notificationState) {
-        if (notificationState == PROFILE_OFF_DEADLINE_DEFAULT) {
+        if (notificationState == PROFILE_OFF_NOTIFICATION_NONE) {
             mInjector.getNotificationManager().cancel(SystemMessage.NOTE_PERSONAL_APPS_SUSPENDED);
             return;
         }
@@ -16260,7 +16414,7 @@
 
         final String text;
         final boolean ongoing;
-        if (notificationState == PROFILE_OFF_DEADLINE_WARNING) {
+        if (notificationState == PROFILE_OFF_NOTIFICATION_WARNING) {
             // Round to the closest integer number of days.
             final int maxDays = (int)
                     ((profileOwner.mProfileMaximumTimeOffMillis + MS_PER_DAY / 2) / MS_PER_DAY);
@@ -16351,7 +16505,6 @@
         Objects.requireNonNull(who, "ComponentName is null");
 
         final CallerIdentity caller = getCallerIdentity(who);
-        // DO shouldn't be able to use this method.
         Preconditions.checkCallAuthorization(isProfileOwnerOfOrganizationOwnedDevice(caller));
 
         synchronized (getLockObject()) {
@@ -16361,6 +16514,33 @@
     }
 
     @Override
+    public void acknowledgeDeviceCompliant() {
+        final CallerIdentity caller = getCallerIdentity();
+        Preconditions.checkCallAuthorization(isProfileOwnerOfOrganizationOwnedDevice(caller));
+        enforceUserUnlocked(caller.getUserId());
+
+        synchronized (getLockObject()) {
+            final ActiveAdmin admin = getProfileOwnerLocked(caller);
+            if (admin.mProfileOffDeadline > 0) {
+                admin.mProfileOffDeadline = 0;
+                saveSettingsLocked(caller.getUserId());
+            }
+        }
+    }
+
+    @Override
+    public boolean isComplianceAcknowledgementRequired() {
+        final CallerIdentity caller = getCallerIdentity();
+        Preconditions.checkCallAuthorization(isProfileOwnerOfOrganizationOwnedDevice(caller));
+        enforceUserUnlocked(caller.getUserId());
+
+        synchronized (getLockObject()) {
+            final ActiveAdmin admin = getProfileOwnerLocked(caller);
+            return admin.mProfileOffDeadline != 0;
+        }
+    }
+
+    @Override
     public boolean canProfileOwnerResetPasswordWhenLocked(int userId) {
         enforceSystemCaller("call canProfileOwnerResetPasswordWhenLocked");
         synchronized (getLockObject()) {
@@ -17006,18 +17186,18 @@
         }
     }
 
-    private void updateNetworkPreferenceForUser(int userId, boolean enableEnterprise) {
+    private void updateNetworkPreferenceForUser(int userId,
+            boolean enableEnterpriseNetworkPreferenceEnabled) {
         if (!isManagedProfile(userId)) {
             return;
         }
-        // TODO(b/178655595)
-        // int networkPreference = enable ? ConnectivityManager.USER_PREFERENCE_ENTERPRISE :
-        //        ConnectivityManager.USER_PREFERENCE_SYSTEM_DEFAULT;
-        // mInjector.binderWithCleanCallingIdentity(() ->
-        //         mInjector.getConnectivityManager().setNetworkPreferenceForUser(
-        //                 UserHandle.of(userId),
-        //                 networkPreference,
-        //                 null /* executor */, null /* listener */));
+        int networkPreference = enableEnterpriseNetworkPreferenceEnabled
+                ? PROFILE_NETWORK_PREFERENCE_ENTERPRISE : PROFILE_NETWORK_PREFERENCE_DEFAULT;
+        mInjector.binderWithCleanCallingIdentity(() ->
+                mInjector.getConnectivityManager().setProfileNetworkPreference(
+                        UserHandle.of(userId),
+                        networkPreference,
+                        null /* executor */, null /* listener */));
     }
 
     @Override
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/RemoteBugreportManager.java b/services/devicepolicy/java/com/android/server/devicepolicy/RemoteBugreportManager.java
index fa6ef00..5f35a26 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/RemoteBugreportManager.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/RemoteBugreportManager.java
@@ -149,7 +149,8 @@
                         .setLocalOnly(true)
                         .setContentIntent(pendingDialogIntent)
                         .setColor(mContext.getColor(
-                                com.android.internal.R.color.system_notification_accent_color));
+                                com.android.internal.R.color.system_notification_accent_color))
+                        .extend(new Notification.TvExtender());
 
         if (type == NOTIFICATION_BUGREPORT_ACCEPTED_NOT_FINISHED) {
             builder.setContentTitle(mContext.getString(
diff --git a/services/incremental/IncrementalService.cpp b/services/incremental/IncrementalService.cpp
index a88f2b4..6695ba8 100644
--- a/services/incremental/IncrementalService.cpp
+++ b/services/incremental/IncrementalService.cpp
@@ -81,8 +81,8 @@
 
     static constexpr auto bindingTimeout = 1min;
 
-    // 10s, 100s (~2min), 1000s (~15min), 10000s (~3hrs)
-    static constexpr auto minBindDelay = 10s;
+    // 1s, 10s, 100s (~2min), 1000s (~15min), 10000s (~3hrs)
+    static constexpr auto minBindDelay = 1s;
     static constexpr auto maxBindDelay = 10000s;
     static constexpr auto bindDelayMultiplier = 10;
     static constexpr auto bindDelayJitterDivider = 10;
@@ -100,6 +100,21 @@
     return (s & (Constants::blockSize - 1)) == 0;
 }
 
+static bool getEnforceReadLogsMaxIntervalForSystemDataLoaders() {
+    return android::base::GetBoolProperty("debug.incremental.enforce_readlogs_max_interval_for_"
+                                          "system_dataloaders",
+                                          false);
+}
+
+static Seconds getReadLogsMaxInterval() {
+    constexpr int limit = duration_cast<Seconds>(Constants::readLogsMaxInterval).count();
+    int readlogs_max_interval_secs =
+            std::min(limit,
+                     android::base::GetIntProperty<
+                             int>("debug.incremental.readlogs_max_interval_sec", limit));
+    return Seconds{readlogs_max_interval_secs};
+}
+
 template <base::LogSeverity level = base::ERROR>
 bool mkdirOrLog(std::string_view name, int mode = 0770, bool allowExisting = true) {
     auto cstr = path::c_str(name);
@@ -308,6 +323,14 @@
     }
 }
 
+void IncrementalService::IncFsMount::setReadLogsRequested(bool value) {
+    if (value) {
+        flags |= StorageFlags::ReadLogsRequested;
+    } else {
+        flags &= ~StorageFlags::ReadLogsRequested;
+    }
+}
+
 IncrementalService::IncrementalService(ServiceManagerWrapper&& sm, std::string_view rootDir)
       : mVold(sm.getVoldService()),
         mDataLoaderManager(sm.getDataLoaderManager()),
@@ -377,6 +400,7 @@
 
     dprintf(fd, "Mounts (%d): {\n", int(mMounts.size()));
     for (auto&& [id, ifs] : mMounts) {
+        std::unique_lock ll(ifs->lock);
         const IncFsMount& mnt = *ifs;
         dprintf(fd, "  [%d]: {\n", id);
         if (id != mnt.mountId) {
@@ -422,6 +446,9 @@
 }
 
 bool IncrementalService::needStartDataLoaderLocked(IncFsMount& ifs) {
+    if (!ifs.dataLoaderStub) {
+        return false;
+    }
     if (ifs.dataLoaderStub->isSystemDataLoader()) {
         return true;
     }
@@ -439,6 +466,8 @@
         std::lock_guard l(mLock);
         mounts.reserve(mMounts.size());
         for (auto&& [id, ifs] : mMounts) {
+            std::unique_lock ll(ifs->lock);
+
             if (ifs->mountId != id) {
                 continue;
             }
@@ -456,7 +485,10 @@
     std::thread([this, mounts = std::move(mounts)]() {
         mJni->initializeForCurrentThread();
         for (auto&& ifs : mounts) {
-            ifs->dataLoaderStub->requestStart();
+            std::unique_lock l(ifs->lock);
+            if (ifs->dataLoaderStub) {
+                ifs->dataLoaderStub->requestStart();
+            }
         }
     }).detach();
 }
@@ -671,25 +703,39 @@
         setUidReadTimeouts(storageId, std::move(perUidReadTimeouts));
     }
 
+    IfsMountPtr ifs;
+    DataLoaderStubPtr dataLoaderStub;
+
     // Re-initialize DataLoader.
-    std::unique_lock l(mLock);
-    const auto ifs = getIfsLocked(storageId);
-    if (!ifs) {
-        return false;
-    }
-    if (ifs->dataLoaderStub) {
-        ifs->dataLoaderStub->cleanupResources();
-        ifs->dataLoaderStub = {};
-    }
-    l.unlock();
+    {
+        ifs = getIfs(storageId);
+        if (!ifs) {
+            return false;
+        }
 
-    // DataLoader.
-    auto dataLoaderStub =
-            prepareDataLoader(*ifs, std::move(dataLoaderParams), std::move(statusListener),
-                              healthCheckParams, std::move(healthListener));
-    CHECK(dataLoaderStub);
+        std::unique_lock l(ifs->lock);
+        dataLoaderStub = std::exchange(ifs->dataLoaderStub, nullptr);
+    }
 
-    if (dataLoaderStub->isSystemDataLoader()) {
+    if (dataLoaderStub) {
+        dataLoaderStub->cleanupResources();
+        dataLoaderStub = {};
+    }
+
+    {
+        std::unique_lock l(ifs->lock);
+        if (ifs->dataLoaderStub) {
+            LOG(INFO) << "Skipped data loader stub creation because it already exists";
+            return false;
+        }
+        prepareDataLoaderLocked(*ifs, std::move(dataLoaderParams), std::move(statusListener),
+                                healthCheckParams, std::move(healthListener));
+        CHECK(ifs->dataLoaderStub);
+        dataLoaderStub = ifs->dataLoaderStub;
+    }
+
+    if (dataLoaderStub->isSystemDataLoader() &&
+        !getEnforceReadLogsMaxIntervalForSystemDataLoaders()) {
         // Readlogs from system dataloader (adb) can always be collected.
         ifs->startLoadingTs = TimePoint::max();
     } else {
@@ -697,7 +743,7 @@
         const auto startLoadingTs = mClock->now();
         ifs->startLoadingTs = startLoadingTs;
         // Setup a callback to disable the readlogs after max interval.
-        addTimedJob(*mTimedQueue, storageId, Constants::readLogsMaxInterval,
+        addTimedJob(*mTimedQueue, storageId, getReadLogsMaxInterval(),
                     [this, storageId, startLoadingTs]() {
                         const auto ifs = getIfs(storageId);
                         if (!ifs) {
@@ -705,13 +751,14 @@
                                          << storageId;
                             return;
                         }
+                        std::unique_lock l(ifs->lock);
                         if (ifs->startLoadingTs != startLoadingTs) {
                             LOG(INFO) << "Can't disable the readlogs, timestamp mismatch (new "
                                          "installation?): "
                                       << storageId;
                             return;
                         }
-                        setStorageParams(*ifs, storageId, /*enableReadLogs=*/false);
+                        disableReadLogsLocked(*ifs);
                     });
     }
 
@@ -733,17 +780,17 @@
 }
 
 void IncrementalService::disallowReadLogs(StorageId storageId) {
-    std::unique_lock l(mLock);
-    const auto ifs = getIfsLocked(storageId);
+    const auto ifs = getIfs(storageId);
     if (!ifs) {
         LOG(ERROR) << "disallowReadLogs failed, invalid storageId: " << storageId;
         return;
     }
+
+    std::unique_lock l(ifs->lock);
     if (!ifs->readLogsAllowed()) {
         return;
     }
     ifs->disallowReadLogs();
-    l.unlock();
 
     const auto metadata = constants().readLogsDisabledMarkerName;
     if (auto err = mIncFs->makeFile(ifs->control,
@@ -755,7 +802,7 @@
         return;
     }
 
-    setStorageParams(storageId, /*enableReadLogs=*/false);
+    disableReadLogsLocked(*ifs);
 }
 
 int IncrementalService::setStorageParams(StorageId storageId, bool enableReadLogs) {
@@ -764,61 +811,79 @@
         LOG(ERROR) << "setStorageParams failed, invalid storageId: " << storageId;
         return -EINVAL;
     }
-    return setStorageParams(*ifs, storageId, enableReadLogs);
-}
 
-int IncrementalService::setStorageParams(IncFsMount& ifs, StorageId storageId,
-                                         bool enableReadLogs) {
-    const auto& params = ifs.dataLoaderStub->params();
-    if (enableReadLogs) {
-        if (!ifs.readLogsAllowed()) {
-            LOG(ERROR) << "setStorageParams failed, readlogs disallowed for storageId: "
-                       << storageId;
+    std::string packageName;
+
+    {
+        std::unique_lock l(ifs->lock);
+        if (!enableReadLogs) {
+            return disableReadLogsLocked(*ifs);
+        }
+
+        if (!ifs->readLogsAllowed()) {
+            LOG(ERROR) << "enableReadLogs failed, readlogs disallowed for storageId: " << storageId;
             return -EPERM;
         }
 
-        // Check loader usage stats permission and apop.
-        if (auto status = mAppOpsManager->checkPermission(kLoaderUsageStats, kOpUsage,
-                                                          params.packageName.c_str());
-            !status.isOk()) {
-            LOG(ERROR) << " Permission: " << kLoaderUsageStats
-                       << " check failed: " << status.toString8();
-            return fromBinderStatus(status);
-        }
-
-        // Check multiuser permission.
-        if (auto status = mAppOpsManager->checkPermission(kInteractAcrossUsers, nullptr,
-                                                          params.packageName.c_str());
-            !status.isOk()) {
-            LOG(ERROR) << " Permission: " << kInteractAcrossUsers
-                       << " check failed: " << status.toString8();
-            return fromBinderStatus(status);
+        if (!ifs->dataLoaderStub) {
+            // This should never happen - only DL can call enableReadLogs.
+            LOG(ERROR) << "enableReadLogs failed: invalid state";
+            return -EPERM;
         }
 
         // Check installation time.
         const auto now = mClock->now();
-        const auto startLoadingTs = ifs.startLoadingTs;
-        if (startLoadingTs <= now && now - startLoadingTs > Constants::readLogsMaxInterval) {
-            LOG(ERROR) << "setStorageParams failed, readlogs can't be enabled at this time, "
-                          "storageId: "
-                       << storageId;
+        const auto startLoadingTs = ifs->startLoadingTs;
+        if (startLoadingTs <= now && now - startLoadingTs > getReadLogsMaxInterval()) {
+            LOG(ERROR)
+                    << "enableReadLogs failed, readlogs can't be enabled at this time, storageId: "
+                    << storageId;
             return -EPERM;
         }
+
+        packageName = ifs->dataLoaderStub->params().packageName;
+        ifs->setReadLogsRequested(true);
     }
 
-    if (auto status = applyStorageParams(ifs, enableReadLogs); !status.isOk()) {
-        LOG(ERROR) << "applyStorageParams failed: " << status.toString8();
+    // Check loader usage stats permission and apop.
+    if (auto status =
+                mAppOpsManager->checkPermission(kLoaderUsageStats, kOpUsage, packageName.c_str());
+        !status.isOk()) {
+        LOG(ERROR) << " Permission: " << kLoaderUsageStats
+                   << " check failed: " << status.toString8();
         return fromBinderStatus(status);
     }
 
-    if (enableReadLogs) {
-        registerAppOpsCallback(params.packageName);
+    // Check multiuser permission.
+    if (auto status =
+                mAppOpsManager->checkPermission(kInteractAcrossUsers, nullptr, packageName.c_str());
+        !status.isOk()) {
+        LOG(ERROR) << " Permission: " << kInteractAcrossUsers
+                   << " check failed: " << status.toString8();
+        return fromBinderStatus(status);
     }
 
+    {
+        std::unique_lock l(ifs->lock);
+        if (!ifs->readLogsRequested()) {
+            return 0;
+        }
+        if (auto status = applyStorageParamsLocked(*ifs, /*enableReadLogs=*/true); status != 0) {
+            return status;
+        }
+    }
+
+    registerAppOpsCallback(packageName);
+
     return 0;
 }
 
-binder::Status IncrementalService::applyStorageParams(IncFsMount& ifs, bool enableReadLogs) {
+int IncrementalService::disableReadLogsLocked(IncFsMount& ifs) {
+    ifs.setReadLogsRequested(false);
+    return applyStorageParamsLocked(ifs, /*enableReadLogs=*/false);
+}
+
+int IncrementalService::applyStorageParamsLocked(IncFsMount& ifs, bool enableReadLogs) {
     os::incremental::IncrementalFileSystemControlParcel control;
     control.cmd.reset(dup(ifs.control.cmd()));
     control.pendingReads.reset(dup(ifs.control.pendingReads()));
@@ -832,8 +897,10 @@
     if (status.isOk()) {
         // Store enabled state.
         ifs.setReadLogsEnabled(enableReadLogs);
+    } else {
+        LOG(ERROR) << "applyStorageParams failed: " << status.toString8();
     }
-    return status;
+    return status.isOk() ? 0 : fromBinderStatus(status);
 }
 
 void IncrementalService::deleteStorage(StorageId storageId) {
@@ -1019,17 +1086,14 @@
         return err;
     }
     if (params.size > 0) {
-        // Only v2+ incfs supports automatically trimming file over-reserved sizes
-        if (mIncFs->features() & incfs::Features::v2) {
-            if (auto err = mIncFs->reserveSpace(ifs->control, normPath, params.size)) {
-                if (err != -EOPNOTSUPP) {
-                    LOG(ERROR) << "Failed to reserve space for a new file: " << err;
-                    (void)mIncFs->unlink(ifs->control, normPath);
-                    return err;
-                } else {
-                    LOG(WARNING) << "Reserving space for backing file isn't supported, "
-                                    "may run out of disk later";
-                }
+        if (auto err = mIncFs->reserveSpace(ifs->control, id, params.size)) {
+            if (err != -EOPNOTSUPP) {
+                LOG(ERROR) << "Failed to reserve space for a new file: " << err;
+                (void)mIncFs->unlink(ifs->control, normPath);
+                return err;
+            } else {
+                LOG(WARNING) << "Reserving space for backing file isn't supported, "
+                                "may run out of disk later";
             }
         }
         if (!data.empty()) {
@@ -1224,9 +1288,14 @@
         return;
     }
 
-    const auto timeout = std::chrono::duration_cast<milliseconds>(maxPendingTimeUs) -
-            Constants::perUidTimeoutOffset;
-    updateUidReadTimeouts(storage, Clock::now() + timeout);
+    const auto timeout = Clock::now() + maxPendingTimeUs - Constants::perUidTimeoutOffset;
+    addIfsStateCallback(storage, [this, timeout](StorageId storageId, IfsState state) -> bool {
+        if (checkUidReadTimeouts(storageId, state, timeout)) {
+            return true;
+        }
+        clearUidReadTimeouts(storageId);
+        return false;
+    });
 }
 
 void IncrementalService::clearUidReadTimeouts(StorageId storage) {
@@ -1234,39 +1303,32 @@
     if (!ifs) {
         return;
     }
-
     mIncFs->setUidReadTimeouts(ifs->control, {});
 }
 
-void IncrementalService::updateUidReadTimeouts(StorageId storage, Clock::time_point timeLimit) {
-    // Reached maximum timeout.
+bool IncrementalService::checkUidReadTimeouts(StorageId storage, IfsState state,
+                                              Clock::time_point timeLimit) {
     if (Clock::now() >= timeLimit) {
-        return clearUidReadTimeouts(storage);
+        // Reached maximum timeout.
+        return false;
+    }
+    if (state.error) {
+        // Something is wrong, abort.
+        return false;
     }
 
     // Still loading?
-    const auto state = isMountFullyLoaded(storage);
-    if (int(state) < 0) {
-        // Something is wrong, abort.
-        return clearUidReadTimeouts(storage);
-    }
-
-    if (state == incfs::LoadingState::Full) {
-        // Fully loaded, check readLogs collection.
-        const auto ifs = getIfs(storage);
-        if (!ifs->readLogsEnabled()) {
-            return clearUidReadTimeouts(storage);
-        }
+    if (state.fullyLoaded && !state.readLogsEnabled) {
+        return false;
     }
 
     const auto timeLeft = timeLimit - Clock::now();
     if (timeLeft < Constants::progressUpdateInterval) {
         // Don't bother.
-        return clearUidReadTimeouts(storage);
+        return false;
     }
 
-    addTimedJob(*mTimedQueue, storage, Constants::progressUpdateInterval,
-                [this, storage, timeLimit]() { updateUidReadTimeouts(storage, timeLimit); });
+    return true;
 }
 
 std::unordered_set<std::string_view> IncrementalService::adoptMountedInstances() {
@@ -1533,7 +1595,7 @@
         dataLoaderParams.arguments = loader.arguments();
     }
 
-    prepareDataLoader(*ifs, std::move(dataLoaderParams));
+    prepareDataLoaderLocked(*ifs, std::move(dataLoaderParams));
     CHECK(ifs->dataLoaderStub);
 
     std::vector<std::pair<std::string, metadata::BindPoint>> bindPoints;
@@ -1615,24 +1677,19 @@
     }
 }
 
-IncrementalService::DataLoaderStubPtr IncrementalService::prepareDataLoader(
-        IncFsMount& ifs, DataLoaderParamsParcel&& params, DataLoaderStatusListener&& statusListener,
-        const StorageHealthCheckParams& healthCheckParams, StorageHealthListener&& healthListener) {
-    std::unique_lock l(ifs.lock);
-    prepareDataLoaderLocked(ifs, std::move(params), std::move(statusListener), healthCheckParams,
-                            std::move(healthListener));
-    return ifs.dataLoaderStub;
+void IncrementalService::trimReservedSpaceV1(const IncFsMount& ifs) {
+    mIncFs->forEachFile(ifs.control, [this](auto&& control, auto&& fileId) {
+        if (mIncFs->isFileFullyLoaded(control, fileId) == incfs::LoadingState::Full) {
+            mIncFs->reserveSpace(control, fileId, -1);
+        }
+        return true;
+    });
 }
 
 void IncrementalService::prepareDataLoaderLocked(IncFsMount& ifs, DataLoaderParamsParcel&& params,
                                                  DataLoaderStatusListener&& statusListener,
                                                  const StorageHealthCheckParams& healthCheckParams,
                                                  StorageHealthListener&& healthListener) {
-    if (ifs.dataLoaderStub) {
-        LOG(INFO) << "Skipped data loader preparation because it already exists";
-        return;
-    }
-
     FileSystemControlParcel fsControlParcel;
     fsControlParcel.incremental = std::make_optional<IncrementalFileSystemControlParcel>();
     fsControlParcel.incremental->cmd.reset(dup(ifs.control.cmd()));
@@ -1647,6 +1704,45 @@
             new DataLoaderStub(*this, ifs.mountId, std::move(params), std::move(fsControlParcel),
                                std::move(statusListener), healthCheckParams,
                                std::move(healthListener), path::join(ifs.root, constants().mount));
+
+    // pre-v2 IncFS doesn't do automatic reserved space trimming - need to run it manually
+    if (!(mIncFs->features() & incfs::Features::v2)) {
+        addIfsStateCallback(ifs.mountId, [this](StorageId storageId, IfsState state) -> bool {
+            if (!state.fullyLoaded) {
+                return true;
+            }
+
+            const auto ifs = getIfs(storageId);
+            if (!ifs) {
+                return false;
+            }
+            trimReservedSpaceV1(*ifs);
+            return false;
+        });
+    }
+
+    addIfsStateCallback(ifs.mountId, [this](StorageId storageId, IfsState state) -> bool {
+        if (!state.fullyLoaded || state.readLogsEnabled) {
+            return true;
+        }
+
+        DataLoaderStubPtr dataLoaderStub;
+        {
+            const auto ifs = getIfs(storageId);
+            if (!ifs) {
+                return false;
+            }
+
+            std::unique_lock l(ifs->lock);
+            dataLoaderStub = std::exchange(ifs->dataLoaderStub, nullptr);
+        }
+
+        if (dataLoaderStub) {
+            dataLoaderStub->cleanupResources();
+        }
+
+        return false;
+    });
 }
 
 template <class Duration>
@@ -2070,11 +2166,11 @@
         StorageHealthListener healthListener) {
     DataLoaderStubPtr dataLoaderStub;
     {
-        std::unique_lock l(mLock);
-        const auto& ifs = getIfsLocked(storage);
+        const auto& ifs = getIfs(storage);
         if (!ifs) {
             return false;
         }
+        std::unique_lock l(ifs->lock);
         dataLoaderStub = ifs->dataLoaderStub;
         if (!dataLoaderStub) {
             return false;
@@ -2160,13 +2256,16 @@
         std::lock_guard l(mLock);
         affected.reserve(mMounts.size());
         for (auto&& [id, ifs] : mMounts) {
-            if (ifs->mountId == id && ifs->dataLoaderStub->params().packageName == packageName) {
+            std::unique_lock ll(ifs->lock);
+            if (ifs->mountId == id && ifs->dataLoaderStub &&
+                ifs->dataLoaderStub->params().packageName == packageName) {
                 affected.push_back(ifs);
             }
         }
     }
     for (auto&& ifs : affected) {
-        applyStorageParams(*ifs, false);
+        std::unique_lock ll(ifs->lock);
+        disableReadLogsLocked(*ifs);
     }
 }
 
@@ -2187,6 +2286,108 @@
     return true;
 }
 
+void IncrementalService::addIfsStateCallback(StorageId storageId, IfsStateCallback callback) {
+    bool wasEmpty;
+    {
+        std::lock_guard l(mIfsStateCallbacksLock);
+        wasEmpty = mIfsStateCallbacks.empty();
+        mIfsStateCallbacks[storageId].emplace_back(std::move(callback));
+    }
+    if (wasEmpty) {
+        addTimedJob(*mTimedQueue, kAllStoragesId, Constants::progressUpdateInterval,
+                    [this]() { processIfsStateCallbacks(); });
+    }
+}
+
+void IncrementalService::processIfsStateCallbacks() {
+    StorageId storageId = kInvalidStorageId;
+    std::vector<IfsStateCallback> local;
+    while (true) {
+        {
+            std::lock_guard l(mIfsStateCallbacksLock);
+            if (mIfsStateCallbacks.empty()) {
+                return;
+            }
+            IfsStateCallbacks::iterator it;
+            if (storageId == kInvalidStorageId) {
+                // First entry, initialize the |it|.
+                it = mIfsStateCallbacks.begin();
+            } else {
+                // Subsequent entries, update the |storageId|, and shift to the new one (not that
+                // it guarantees much about updated items, but at least the loop will finish).
+                it = mIfsStateCallbacks.lower_bound(storageId);
+                if (it == mIfsStateCallbacks.end()) {
+                    // Nothing else left, too bad.
+                    break;
+                }
+                if (it->first != storageId) {
+                    local.clear(); // Was removed during processing, forget the old callbacks.
+                } else {
+                    // Put the 'surviving' callbacks back into the map and advance the position.
+                    auto& callbacks = it->second;
+                    if (callbacks.empty()) {
+                        std::swap(callbacks, local);
+                    } else {
+                        callbacks.insert(callbacks.end(), std::move_iterator(local.begin()),
+                                         std::move_iterator(local.end()));
+                        local.clear();
+                    }
+                    if (callbacks.empty()) {
+                        it = mIfsStateCallbacks.erase(it);
+                        if (mIfsStateCallbacks.empty()) {
+                            return;
+                        }
+                    } else {
+                        ++it;
+                    }
+                }
+            }
+
+            if (it == mIfsStateCallbacks.end()) {
+                break;
+            }
+
+            storageId = it->first;
+            auto& callbacks = it->second;
+            if (callbacks.empty()) {
+                // Invalid case, one extra lookup should be ok.
+                continue;
+            }
+            std::swap(callbacks, local);
+        }
+
+        processIfsStateCallbacks(storageId, local);
+    }
+
+    addTimedJob(*mTimedQueue, kAllStoragesId, Constants::progressUpdateInterval,
+                [this]() { processIfsStateCallbacks(); });
+}
+
+void IncrementalService::processIfsStateCallbacks(StorageId storageId,
+                                                  std::vector<IfsStateCallback>& callbacks) {
+    const auto state = isMountFullyLoaded(storageId);
+    IfsState storageState = {};
+    storageState.error = int(state) < 0;
+    storageState.fullyLoaded = state == incfs::LoadingState::Full;
+    if (storageState.fullyLoaded) {
+        const auto ifs = getIfs(storageId);
+        storageState.readLogsEnabled = ifs && ifs->readLogsEnabled();
+    }
+
+    for (auto cur = callbacks.begin(); cur != callbacks.end();) {
+        if ((*cur)(storageId, storageState)) {
+            ++cur;
+        } else {
+            cur = callbacks.erase(cur);
+        }
+    }
+}
+
+void IncrementalService::removeIfsStateCallbacks(StorageId storageId) {
+    std::lock_guard l(mIfsStateCallbacksLock);
+    mIfsStateCallbacks.erase(storageId);
+}
+
 void IncrementalService::getMetrics(StorageId storageId, android::os::PersistableBundle* result) {
     const auto duration = getMillsSinceOldestPendingRead(storageId);
     if (duration >= 0) {
@@ -2197,12 +2398,12 @@
 }
 
 long IncrementalService::getMillsSinceOldestPendingRead(StorageId storageId) {
-    std::unique_lock l(mLock);
-    const auto ifs = getIfsLocked(storageId);
+    const auto ifs = getIfs(storageId);
     if (!ifs) {
         LOG(ERROR) << "getMillsSinceOldestPendingRead failed, invalid storageId: " << storageId;
         return -EINVAL;
     }
+    std::unique_lock l(ifs->lock);
     if (!ifs->dataLoaderStub) {
         LOG(ERROR) << "getMillsSinceOldestPendingRead failed, no data loader: " << storageId;
         return -EINVAL;
@@ -2248,6 +2449,7 @@
         resetHealthControl();
         mService.removeTimedJobs(*mService.mTimedQueue, mId);
     }
+    mService.removeIfsStateCallbacks(mId);
 
     requestDestroy();
 
@@ -2321,7 +2523,8 @@
         now - mCurrentStatusTs <= Constants::bindingTimeout) {
         LOG(INFO) << "Binding still in progress. "
                   << (healthy ? "The DL is healthy/freshly bound, ok to retry for a few times."
-                              : "Already unhealthy, don't do anything.");
+                              : "Already unhealthy, don't do anything.")
+                  << " for storage " << mId;
         // Binding still in progress.
         if (!healthy) {
             // Already unhealthy, don't do anything.
@@ -2344,7 +2547,8 @@
     const auto previousBindTs = mPreviousBindTs;
     mPreviousBindTs = now;
 
-    const auto nonCrashingInterval = std::max(castToMs(now - previousBindTs), 100ms);
+    const auto nonCrashingInterval =
+            std::max(castToMs(now - previousBindTs - mPreviousBindDelay), 100ms);
     if (previousBindTs.time_since_epoch() == Clock::duration::zero() ||
         nonCrashingInterval > Constants::healthyDataLoaderUptime) {
         mPreviousBindDelay = 0ms;
@@ -2373,7 +2577,8 @@
     const auto bindDelay = *maybeBindDelay;
     if (bindDelay > 1s) {
         LOG(INFO) << "Delaying bind to " << mParams.packageName << " by "
-                  << bindDelay.count() / 1000 << "s";
+                  << bindDelay.count() / 1000 << "s"
+                  << " for storage " << mId;
     }
 
     bool result = false;
@@ -2758,7 +2963,7 @@
     mService.mLooper->addFd(
             pendingReadsFd, android::Looper::POLL_CALLBACK, android::Looper::EVENT_INPUT,
             [](int, int, void* data) -> int {
-                auto&& self = (DataLoaderStub*)data;
+                auto self = (DataLoaderStub*)data;
                 self->updateHealthStatus(/*baseline=*/true);
                 return 0;
             },
diff --git a/services/incremental/IncrementalService.h b/services/incremental/IncrementalService.h
index 4a5db06..fb6f56c 100644
--- a/services/incremental/IncrementalService.h
+++ b/services/incremental/IncrementalService.h
@@ -74,6 +74,17 @@
 
 using PerUidReadTimeouts = ::android::os::incremental::PerUidReadTimeouts;
 
+struct IfsState {
+    // If mount is fully loaded.
+    bool fullyLoaded = false;
+    // If read logs are enabled on this mount. Populated only if fullyLoaded == true.
+    bool readLogsEnabled = false;
+    // If there was an error fetching any of the above.
+    bool error = false;
+};
+// Returns true if wants to be called again.
+using IfsStateCallback = std::function<bool(StorageId, IfsState)>;
+
 class IncrementalService final {
 public:
     explicit IncrementalService(ServiceManagerWrapper&& sm, std::string_view rootDir);
@@ -84,7 +95,8 @@
 #pragma GCC diagnostic pop
 
     static constexpr StorageId kInvalidStorageId = -1;
-    static constexpr StorageId kMaxStorageId = std::numeric_limits<int>::max();
+    static constexpr StorageId kMaxStorageId = std::numeric_limits<int>::max() - 1;
+    static constexpr StorageId kAllStoragesId = kMaxStorageId + 1;
 
     static constexpr BootClockTsUs kMaxBootClockTsUs = std::numeric_limits<BootClockTsUs>::max();
 
@@ -105,6 +117,7 @@
     enum StorageFlags {
         ReadLogsAllowed = 1 << 0,
         ReadLogsEnabled = 1 << 1,
+        ReadLogsRequested = 1 << 2,
     };
 
     struct LoadingProgress {
@@ -354,6 +367,9 @@
         void setReadLogsEnabled(bool value);
         int32_t readLogsEnabled() const { return (flags & StorageFlags::ReadLogsEnabled); }
 
+        void setReadLogsRequested(bool value);
+        int32_t readLogsRequested() const { return (flags & StorageFlags::ReadLogsRequested); }
+
         static void cleanupFilesystem(std::string_view root);
     };
 
@@ -366,7 +382,7 @@
     void setUidReadTimeouts(StorageId storage,
                             std::vector<PerUidReadTimeouts>&& perUidReadTimeouts);
     void clearUidReadTimeouts(StorageId storage);
-    void updateUidReadTimeouts(StorageId storage, Clock::time_point timeLimit);
+    bool checkUidReadTimeouts(StorageId storage, IfsState state, Clock::time_point timeLimit);
 
     std::unordered_set<std::string_view> adoptMountedInstances();
     void mountExistingImages(const std::unordered_set<std::string_view>& mountedRootNames);
@@ -387,11 +403,6 @@
 
     bool needStartDataLoaderLocked(IncFsMount& ifs);
 
-    DataLoaderStubPtr prepareDataLoader(IncFsMount& ifs,
-                                        content::pm::DataLoaderParamsParcel&& params,
-                                        DataLoaderStatusListener&& statusListener = {},
-                                        const StorageHealthCheckParams& healthCheckParams = {},
-                                        StorageHealthListener&& healthListener = {});
     void prepareDataLoaderLocked(IncFsMount& ifs, content::pm::DataLoaderParamsParcel&& params,
                                  DataLoaderStatusListener&& statusListener = {},
                                  const StorageHealthCheckParams& healthCheckParams = {},
@@ -410,8 +421,8 @@
                                              std::string_view path) const;
     int makeDirs(const IncFsMount& ifs, StorageId storageId, std::string_view path, int mode);
 
-    int setStorageParams(IncFsMount& ifs, StorageId storageId, bool enableReadLogs);
-    binder::Status applyStorageParams(IncFsMount& ifs, bool enableReadLogs);
+    int disableReadLogsLocked(IncFsMount& ifs);
+    int applyStorageParamsLocked(IncFsMount& ifs, bool enableReadLogs);
 
     LoadingProgress getLoadingProgressFromPath(const IncFsMount& ifs, std::string_view path) const;
 
@@ -431,10 +442,18 @@
 
     bool addTimedJob(TimedQueueWrapper& timedQueue, MountId id, Milliseconds after, Job what);
     bool removeTimedJobs(TimedQueueWrapper& timedQueue, MountId id);
+
+    void addIfsStateCallback(StorageId storageId, IfsStateCallback callback);
+    void removeIfsStateCallbacks(StorageId storageId);
+    void processIfsStateCallbacks();
+    void processIfsStateCallbacks(StorageId storageId, std::vector<IfsStateCallback>& callbacks);
+
     bool updateLoadingProgress(int32_t storageId,
                                StorageLoadingProgressListener&& progressListener);
     long getMillsSinceOldestPendingRead(StorageId storage);
 
+    void trimReservedSpaceV1(const IncFsMount& ifs);
+
 private:
     const std::unique_ptr<VoldServiceWrapper> mVold;
     const std::unique_ptr<DataLoaderManagerWrapper> mDataLoaderManager;
@@ -456,6 +475,10 @@
     std::mutex mCallbacksLock;
     std::unordered_map<std::string, sp<AppOpsListener>> mCallbackRegistered;
 
+    using IfsStateCallbacks = std::map<StorageId, std::vector<IfsStateCallback>>;
+    std::mutex mIfsStateCallbacksLock;
+    IfsStateCallbacks mIfsStateCallbacks;
+
     std::atomic_bool mSystemReady = false;
     StorageId mNextId = 0;
 
diff --git a/services/incremental/ServiceWrappers.cpp b/services/incremental/ServiceWrappers.cpp
index 7e85f9d..8e416f3 100644
--- a/services/incremental/ServiceWrappers.cpp
+++ b/services/incremental/ServiceWrappers.cpp
@@ -212,6 +212,9 @@
                                           std::string_view path) const final {
         return incfs::isFullyLoaded(control, path);
     }
+    incfs::LoadingState isFileFullyLoaded(const Control& control, FileId id) const final {
+        return incfs::isFullyLoaded(control, id);
+    }
     incfs::LoadingState isEverythingFullyLoaded(const Control& control) const final {
         return incfs::isEverythingFullyLoaded(control);
     }
@@ -227,9 +230,8 @@
     ErrorCode writeBlocks(std::span<const incfs::DataBlock> blocks) const final {
         return incfs::writeBlocks({blocks.data(), size_t(blocks.size())});
     }
-    ErrorCode reserveSpace(const Control& control, std::string_view path,
-                           IncFsSize size) const final {
-        return incfs::reserveSpace(control, path, size);
+    ErrorCode reserveSpace(const Control& control, FileId id, IncFsSize size) const final {
+        return incfs::reserveSpace(control, id, size);
     }
     WaitResult waitForPendingReads(const Control& control, std::chrono::milliseconds timeout,
                                    std::vector<incfs::ReadInfo>* pendingReadsBuffer) const final {
@@ -238,24 +240,31 @@
     ErrorCode setUidReadTimeouts(const Control& control,
                                  const std::vector<android::os::incremental::PerUidReadTimeouts>&
                                          perUidReadTimeouts) const final {
-        std::vector<incfs::UidReadTimeouts> timeouts;
-        timeouts.resize(perUidReadTimeouts.size());
+        std::vector<incfs::UidReadTimeouts> timeouts(perUidReadTimeouts.size());
         for (int i = 0, size = perUidReadTimeouts.size(); i < size; ++i) {
-            auto&& timeout = timeouts[i];
+            auto& timeout = timeouts[i];
             const auto& perUidTimeout = perUidReadTimeouts[i];
             timeout.uid = perUidTimeout.uid;
             timeout.minTimeUs = perUidTimeout.minTimeUs;
             timeout.minPendingTimeUs = perUidTimeout.minPendingTimeUs;
             timeout.maxPendingTimeUs = perUidTimeout.maxPendingTimeUs;
         }
-
         return incfs::setUidReadTimeouts(control, timeouts);
     }
+    ErrorCode forEachFile(const Control& control, FileCallback cb) const final {
+        return incfs::forEachFile(control,
+                                  [&](auto& control, FileId id) { return cb(control, id); });
+    }
+    ErrorCode forEachIncompleteFile(const Control& control, FileCallback cb) const final {
+        return incfs::forEachIncompleteFile(control, [&](auto& control, FileId id) {
+            return cb(control, id);
+        });
+    }
 };
 
 static JNIEnv* getOrAttachJniEnv(JavaVM* jvm);
 
-class RealTimedQueueWrapper : public TimedQueueWrapper {
+class RealTimedQueueWrapper final : public TimedQueueWrapper {
 public:
     RealTimedQueueWrapper(JavaVM* jvm) {
         mThread = std::thread([this, jvm]() {
@@ -268,11 +277,11 @@
         CHECK(!mThread.joinable()) << "call stop first";
     }
 
-    void addJob(MountId id, Milliseconds after, Job what) final {
+    void addJob(MountId id, Milliseconds timeout, Job what) final {
         const auto now = Clock::now();
         {
             std::unique_lock lock(mMutex);
-            mJobs.insert(TimedJob{id, now + after, std::move(what)});
+            mJobs.insert(TimedJob{id, now + timeout, std::move(what)});
         }
         mCondition.notify_all();
     }
@@ -293,29 +302,28 @@
 private:
     void runTimers() {
         static constexpr TimePoint kInfinityTs{Clock::duration::max()};
-        TimePoint nextJobTs = kInfinityTs;
         std::unique_lock lock(mMutex);
         for (;;) {
-            mCondition.wait_until(lock, nextJobTs, [this, nextJobTs]() {
+            const TimePoint nextJobTs = mJobs.empty() ? kInfinityTs : mJobs.begin()->when;
+            mCondition.wait_until(lock, nextJobTs, [this, oldNextJobTs = nextJobTs]() {
                 const auto now = Clock::now();
-                const auto firstJobTs = !mJobs.empty() ? mJobs.begin()->when : kInfinityTs;
-                return !mRunning || firstJobTs <= now || firstJobTs < nextJobTs;
+                const auto newFirstJobTs = !mJobs.empty() ? mJobs.begin()->when : kInfinityTs;
+                return newFirstJobTs <= now || newFirstJobTs < oldNextJobTs || !mRunning;
             });
             if (!mRunning) {
                 return;
             }
 
             const auto now = Clock::now();
-            auto it = mJobs.begin();
-            // Always acquire begin(). We can't use it after unlock as mTimedJobs can change.
-            for (; it != mJobs.end() && it->when <= now; it = mJobs.begin()) {
+            // Always re-acquire begin(). We can't use it after unlock as mTimedJobs can change.
+            for (auto it = mJobs.begin(); it != mJobs.end() && it->when <= now;
+                 it = mJobs.begin()) {
                 auto jobNode = mJobs.extract(it);
 
                 lock.unlock();
                 jobNode.value().what();
                 lock.lock();
             }
-            nextJobTs = it != mJobs.end() ? it->when : kInfinityTs;
         }
     }
 
@@ -328,7 +336,7 @@
         }
     };
     bool mRunning = true;
-    std::set<TimedJob> mJobs;
+    std::multiset<TimedJob> mJobs;
     std::condition_variable mCondition;
     std::mutex mMutex;
     std::thread mThread;
diff --git a/services/incremental/ServiceWrappers.h b/services/incremental/ServiceWrappers.h
index a787db5..d4cdcbe 100644
--- a/services/incremental/ServiceWrappers.h
+++ b/services/incremental/ServiceWrappers.h
@@ -84,6 +84,8 @@
             void(std::string_view root, std::string_view backingDir,
                  std::span<std::pair<std::string_view, std::string_view>> binds)>;
 
+    using FileCallback = android::base::function_ref<bool(const Control& control, FileId fileId)>;
+
     static std::string toString(FileId fileId);
 
     virtual ~IncFsWrapper() = default;
@@ -105,14 +107,14 @@
             const Control& control, std::string_view path) const = 0;
     virtual incfs::LoadingState isFileFullyLoaded(const Control& control,
                                                   std::string_view path) const = 0;
+    virtual incfs::LoadingState isFileFullyLoaded(const Control& control, FileId id) const = 0;
     virtual incfs::LoadingState isEverythingFullyLoaded(const Control& control) const = 0;
     virtual ErrorCode link(const Control& control, std::string_view from,
                            std::string_view to) const = 0;
     virtual ErrorCode unlink(const Control& control, std::string_view path) const = 0;
     virtual UniqueFd openForSpecialOps(const Control& control, FileId id) const = 0;
     virtual ErrorCode writeBlocks(std::span<const incfs::DataBlock> blocks) const = 0;
-    virtual ErrorCode reserveSpace(const Control& control, std::string_view path,
-                                   IncFsSize size) const = 0;
+    virtual ErrorCode reserveSpace(const Control& control, FileId id, IncFsSize size) const = 0;
     virtual WaitResult waitForPendingReads(
             const Control& control, std::chrono::milliseconds timeout,
             std::vector<incfs::ReadInfo>* pendingReadsBuffer) const = 0;
@@ -120,6 +122,8 @@
             const Control& control,
             const std::vector<::android::os::incremental::PerUidReadTimeouts>& perUidReadTimeouts)
             const = 0;
+    virtual ErrorCode forEachFile(const Control& control, FileCallback cb) const = 0;
+    virtual ErrorCode forEachIncompleteFile(const Control& control, FileCallback cb) const = 0;
 };
 
 class AppOpsManagerWrapper {
diff --git a/services/incremental/path.cpp b/services/incremental/path.cpp
index 338659d..bf4e9616 100644
--- a/services/incremental/path.cpp
+++ b/services/incremental/path.cpp
@@ -44,19 +44,20 @@
                                         PathCharsLess());
 }
 
-static void preparePathComponent(std::string_view& path, bool trimFront) {
-    if (trimFront) {
-        while (!path.empty() && path.front() == '/') {
-            path.remove_prefix(1);
-        }
+static void preparePathComponent(std::string_view& path, bool trimAll) {
+    // need to check for double front slash as a single one has a separate meaning in front
+    while (!path.empty() && path.front() == '/' &&
+           (trimAll || (path.size() > 1 && path[1] == '/'))) {
+        path.remove_prefix(1);
     }
-    while (!path.empty() && path.back() == '/') {
+    // for the back we don't care about double-vs-single slash difference
+    while (path.size() > !trimAll && path.back() == '/') {
         path.remove_suffix(1);
     }
 }
 
 void details::append_next_path(std::string& target, std::string_view path) {
-    preparePathComponent(path, true);
+    preparePathComponent(path, !target.empty());
     if (path.empty()) {
         return;
     }
diff --git a/services/incremental/path.h b/services/incremental/path.h
index 3e5fd21..e12e1d0 100644
--- a/services/incremental/path.h
+++ b/services/incremental/path.h
@@ -89,15 +89,25 @@
 bool startsWith(std::string_view path, std::string_view prefix);
 
 template <class... Paths>
-std::string join(std::string_view first, std::string_view second, Paths&&... paths) {
-    std::string result;
+std::string join(std::string&& first, std::string_view second, Paths&&... paths) {
+    std::string& result = first;
     {
         using std::size;
         result.reserve(first.size() + second.size() + 1 + (sizeof...(paths) + ... + size(paths)));
     }
-    result.assign(first);
-    (details::append_next_path(result, second), ..., details::append_next_path(result, paths));
-    return result;
+    (details::append_next_path(result, second), ...,
+     details::append_next_path(result, std::forward<Paths>(paths)));
+    return std::move(result);
+}
+
+template <class... Paths>
+std::string join(std::string_view first, std::string_view second, Paths&&... paths) {
+    return path::join(std::string(), first, second, std::forward<Paths>(paths)...);
+}
+
+template <class... Paths>
+std::string join(const char* first, std::string_view second, Paths&&... paths) {
+    return path::join(std::string_view(first), second, std::forward<Paths>(paths)...);
 }
 
 } // namespace android::incremental::path
diff --git a/services/incremental/test/IncrementalServiceTest.cpp b/services/incremental/test/IncrementalServiceTest.cpp
index 54bc95d..1ec446d 100644
--- a/services/incremental/test/IncrementalServiceTest.cpp
+++ b/services/incremental/test/IncrementalServiceTest.cpp
@@ -140,9 +140,7 @@
                             const content::pm::FileSystemControlParcel& control,
                             const sp<content::pm::IDataLoaderStatusListener>& listener) {
         createOkNoStatus(id, params, control, listener);
-        if (mListener) {
-            mListener->onStatusChanged(id, IDataLoaderStatusListener::DATA_LOADER_CREATED);
-        }
+        reportStatus(id);
         return binder::Status::ok();
     }
     binder::Status createOkNoStatus(int32_t id, const content::pm::DataLoaderParamsParcel& params,
@@ -150,33 +148,26 @@
                                     const sp<content::pm::IDataLoaderStatusListener>& listener) {
         mServiceConnector = control.service;
         mListener = listener;
+        mStatus = IDataLoaderStatusListener::DATA_LOADER_CREATED;
         return binder::Status::ok();
     }
     binder::Status startOk(int32_t id) {
-        if (mListener) {
-            mListener->onStatusChanged(id, IDataLoaderStatusListener::DATA_LOADER_STARTED);
-        }
+        setAndReportStatus(id, IDataLoaderStatusListener::DATA_LOADER_STARTED);
         return binder::Status::ok();
     }
     binder::Status stopOk(int32_t id) {
-        if (mListener) {
-            mListener->onStatusChanged(id, IDataLoaderStatusListener::DATA_LOADER_STOPPED);
-        }
+        setAndReportStatus(id, IDataLoaderStatusListener::DATA_LOADER_STOPPED);
         return binder::Status::ok();
     }
     binder::Status destroyOk(int32_t id) {
-        if (mListener) {
-            mListener->onStatusChanged(id, IDataLoaderStatusListener::DATA_LOADER_DESTROYED);
-        }
+        setAndReportStatus(id, IDataLoaderStatusListener::DATA_LOADER_DESTROYED);
         mListener = nullptr;
         return binder::Status::ok();
     }
     binder::Status prepareImageOk(int32_t id,
                                   const ::std::vector<content::pm::InstallationFileParcel>&,
                                   const ::std::vector<::std::string>&) {
-        if (mListener) {
-            mListener->onStatusChanged(id, IDataLoaderStatusListener::DATA_LOADER_IMAGE_READY);
-        }
+        setAndReportStatus(id, IDataLoaderStatusListener::DATA_LOADER_IMAGE_READY);
         return binder::Status::ok();
     }
     binder::Status storageError(int32_t id) {
@@ -197,10 +188,22 @@
         EXPECT_TRUE(mServiceConnector->setStorageParams(enableReadLogs, &result).isOk());
         return result;
     }
+    int status() const { return mStatus; }
 
 private:
+    void setAndReportStatus(int id, int status) {
+        mStatus = status;
+        reportStatus(id);
+    }
+    void reportStatus(int id) {
+        if (mListener) {
+            mListener->onStatusChanged(id, mStatus);
+        }
+    }
+
     sp<IIncrementalServiceConnector> mServiceConnector;
     sp<IDataLoaderStatusListener> mListener;
+    int mStatus = IDataLoaderStatusListener::DATA_LOADER_DESTROYED;
 };
 
 class MockDataLoaderManager : public DataLoaderManagerWrapper {
@@ -242,6 +245,7 @@
         mId = mountId;
         mListener = listener;
         mDataLoader = mDataLoaderHolder;
+        mBindDelayMs = bindDelayMs;
         *_aidl_return = true;
         if (mListener) {
             mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_BOUND);
@@ -269,12 +273,20 @@
         }
         return binder::Status::ok();
     }
+    binder::Status bindToDataLoaderOkWith1sDelay(int32_t mountId,
+                                                 const DataLoaderParamsParcel& params,
+                                                 int bindDelayMs,
+                                                 const sp<IDataLoaderStatusListener>& listener,
+                                                 bool* _aidl_return) {
+        CHECK(100 * 9 <= bindDelayMs && bindDelayMs <= 100 * 11) << bindDelayMs;
+        return bindToDataLoaderOk(mountId, params, bindDelayMs, listener, _aidl_return);
+    }
     binder::Status bindToDataLoaderOkWith10sDelay(int32_t mountId,
                                                   const DataLoaderParamsParcel& params,
                                                   int bindDelayMs,
                                                   const sp<IDataLoaderStatusListener>& listener,
                                                   bool* _aidl_return) {
-        CHECK(1000 * 9 <= bindDelayMs && bindDelayMs <= 1000 * 11) << bindDelayMs;
+        CHECK(100 * 9 * 9 <= bindDelayMs && bindDelayMs <= 100 * 11 * 11) << bindDelayMs;
         return bindToDataLoaderOk(mountId, params, bindDelayMs, listener, _aidl_return);
     }
     binder::Status bindToDataLoaderOkWith100sDelay(int32_t mountId,
@@ -282,7 +294,7 @@
                                                    int bindDelayMs,
                                                    const sp<IDataLoaderStatusListener>& listener,
                                                    bool* _aidl_return) {
-        CHECK(1000 * 9 * 9 < bindDelayMs && bindDelayMs < 1000 * 11 * 11) << bindDelayMs;
+        CHECK(100 * 9 * 9 * 9 < bindDelayMs && bindDelayMs < 100 * 11 * 11 * 11) << bindDelayMs;
         return bindToDataLoaderOk(mountId, params, bindDelayMs, listener, _aidl_return);
     }
     binder::Status bindToDataLoaderOkWith1000sDelay(int32_t mountId,
@@ -290,7 +302,8 @@
                                                     int bindDelayMs,
                                                     const sp<IDataLoaderStatusListener>& listener,
                                                     bool* _aidl_return) {
-        CHECK(1000 * 9 * 9 * 9 < bindDelayMs && bindDelayMs < 1000 * 11 * 11 * 11) << bindDelayMs;
+        CHECK(100 * 9 * 9 * 9 * 9 < bindDelayMs && bindDelayMs < 100 * 11 * 11 * 11 * 11)
+                << bindDelayMs;
         return bindToDataLoaderOk(mountId, params, bindDelayMs, listener, _aidl_return);
     }
     binder::Status bindToDataLoaderOkWith10000sDelay(int32_t mountId,
@@ -298,7 +311,7 @@
                                                      int bindDelayMs,
                                                      const sp<IDataLoaderStatusListener>& listener,
                                                      bool* _aidl_return) {
-        CHECK(1000 * 9 * 9 * 9 * 9 < bindDelayMs && bindDelayMs < 1000 * 11 * 11 * 11 * 11)
+        CHECK(100 * 9 * 9 * 9 * 9 * 9 < bindDelayMs && bindDelayMs < 100 * 11 * 11 * 11 * 11 * 11)
                 << bindDelayMs;
         return bindToDataLoaderOk(mountId, params, bindDelayMs, listener, _aidl_return);
     }
@@ -329,14 +342,18 @@
             }
             mDataLoader = nullptr;
         }
+        mBindDelayMs = -1;
         if (mListener) {
             mListener->onStatusChanged(id, IDataLoaderStatusListener::DATA_LOADER_DESTROYED);
         }
         return binder::Status::ok();
     }
 
+    int bindDelayMs() const { return mBindDelayMs; }
+
 private:
-    int mId;
+    int mId = -1;
+    int mBindDelayMs = -1;
     sp<IDataLoaderStatusListener> mListener;
     sp<IDataLoader> mDataLoader;
     sp<IDataLoader> mDataLoaderHolder;
@@ -367,6 +384,7 @@
                                                                    std::string_view path));
     MOCK_CONST_METHOD2(isFileFullyLoaded,
                        incfs::LoadingState(const Control& control, std::string_view path));
+    MOCK_CONST_METHOD2(isFileFullyLoaded, incfs::LoadingState(const Control& control, FileId id));
     MOCK_CONST_METHOD1(isEverythingFullyLoaded, incfs::LoadingState(const Control& control));
     MOCK_CONST_METHOD3(link,
                        ErrorCode(const Control& control, std::string_view from,
@@ -374,14 +392,15 @@
     MOCK_CONST_METHOD2(unlink, ErrorCode(const Control& control, std::string_view path));
     MOCK_CONST_METHOD2(openForSpecialOps, UniqueFd(const Control& control, FileId id));
     MOCK_CONST_METHOD1(writeBlocks, ErrorCode(std::span<const DataBlock> blocks));
-    MOCK_CONST_METHOD3(reserveSpace,
-                       ErrorCode(const Control& control, std::string_view path, IncFsSize size));
+    MOCK_CONST_METHOD3(reserveSpace, ErrorCode(const Control& control, FileId id, IncFsSize size));
     MOCK_CONST_METHOD3(waitForPendingReads,
                        WaitResult(const Control& control, std::chrono::milliseconds timeout,
                                   std::vector<incfs::ReadInfo>* pendingReadsBuffer));
     MOCK_CONST_METHOD2(setUidReadTimeouts,
                        ErrorCode(const Control& control,
                                  const std::vector<PerUidReadTimeouts>& perUidReadTimeouts));
+    MOCK_CONST_METHOD2(forEachFile, ErrorCode(const Control& control, FileCallback cb));
+    MOCK_CONST_METHOD2(forEachIncompleteFile, ErrorCode(const Control& control, FileCallback cb));
 
     MockIncFs() {
         ON_CALL(*this, listExistingMounts(_)).WillByDefault(Return());
@@ -590,11 +609,14 @@
     MOCK_CONST_METHOD0(now, TimePoint());
 
     void start() { ON_CALL(*this, now()).WillByDefault(Invoke(this, &MockClockWrapper::getClock)); }
+
     template <class Delta>
     void advance(Delta delta) {
         mClock += delta;
     }
 
+    void advanceMs(int deltaMs) { mClock += std::chrono::milliseconds(deltaMs); }
+
     TimePoint getClock() const { return mClock; }
 
     TimePoint mClock = Clock::now();
@@ -862,10 +884,10 @@
 }
 
 TEST_F(IncrementalServiceTest, testDataLoaderDestroyedAndDelayed) {
-    EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(6);
+    EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(7);
     EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
-    EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(6);
-    EXPECT_CALL(*mDataLoader, start(_)).Times(6);
+    EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(7);
+    EXPECT_CALL(*mDataLoader, start(_)).Times(7);
     EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
     EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
     TemporaryDir tempDir;
@@ -879,27 +901,39 @@
 
     ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
             .WillByDefault(Invoke(mDataLoaderManager,
+                                  &MockDataLoaderManager::bindToDataLoaderOkWith1sDelay));
+    mClock->advanceMs(mDataLoaderManager->bindDelayMs());
+    mDataLoaderManager->setDataLoaderStatusDestroyed();
+
+    ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
+            .WillByDefault(Invoke(mDataLoaderManager,
                                   &MockDataLoaderManager::bindToDataLoaderOkWith10sDelay));
+    mClock->advanceMs(mDataLoaderManager->bindDelayMs());
     mDataLoaderManager->setDataLoaderStatusDestroyed();
 
     ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
             .WillByDefault(Invoke(mDataLoaderManager,
                                   &MockDataLoaderManager::bindToDataLoaderOkWith100sDelay));
+    mClock->advanceMs(mDataLoaderManager->bindDelayMs());
     mDataLoaderManager->setDataLoaderStatusDestroyed();
 
     ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
             .WillByDefault(Invoke(mDataLoaderManager,
                                   &MockDataLoaderManager::bindToDataLoaderOkWith1000sDelay));
+    mClock->advanceMs(mDataLoaderManager->bindDelayMs());
     mDataLoaderManager->setDataLoaderStatusDestroyed();
 
     ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
             .WillByDefault(Invoke(mDataLoaderManager,
                                   &MockDataLoaderManager::bindToDataLoaderOkWith10000sDelay));
+    // Try the reduced delay, just in case.
+    mClock->advanceMs(mDataLoaderManager->bindDelayMs() / 2);
     mDataLoaderManager->setDataLoaderStatusDestroyed();
 
     ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
             .WillByDefault(Invoke(mDataLoaderManager,
                                   &MockDataLoaderManager::bindToDataLoaderOkWith10000sDelay));
+    mClock->advanceMs(mDataLoaderManager->bindDelayMs());
     mDataLoaderManager->setDataLoaderStatusDestroyed();
 }
 
@@ -909,13 +943,13 @@
 
     constexpr auto bindRetryInterval = 5s;
 
-    EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(10);
+    EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(11);
     EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
-    EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(6);
-    EXPECT_CALL(*mDataLoader, start(_)).Times(6);
+    EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(7);
+    EXPECT_CALL(*mDataLoader, start(_)).Times(7);
     EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
     EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
-    EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(3);
+    EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(4);
     TemporaryDir tempDir;
     int storageId =
             mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
@@ -992,27 +1026,38 @@
     // Simulated crash/other connection breakage.
     ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
             .WillByDefault(Invoke(mDataLoaderManager,
+                                  &MockDataLoaderManager::bindToDataLoaderOkWith1sDelay));
+    mClock->advanceMs(mDataLoaderManager->bindDelayMs());
+    mDataLoaderManager->setDataLoaderStatusDestroyed();
+
+    ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
+            .WillByDefault(Invoke(mDataLoaderManager,
                                   &MockDataLoaderManager::bindToDataLoaderOkWith10sDelay));
+    mClock->advanceMs(mDataLoaderManager->bindDelayMs());
     mDataLoaderManager->setDataLoaderStatusDestroyed();
 
     ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
             .WillByDefault(Invoke(mDataLoaderManager,
                                   &MockDataLoaderManager::bindToDataLoaderOkWith100sDelay));
+    mClock->advanceMs(mDataLoaderManager->bindDelayMs());
     mDataLoaderManager->setDataLoaderStatusDestroyed();
 
     ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
             .WillByDefault(Invoke(mDataLoaderManager,
                                   &MockDataLoaderManager::bindToDataLoaderOkWith1000sDelay));
+    mClock->advanceMs(mDataLoaderManager->bindDelayMs());
     mDataLoaderManager->setDataLoaderStatusDestroyed();
 
     ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
             .WillByDefault(Invoke(mDataLoaderManager,
                                   &MockDataLoaderManager::bindToDataLoaderOkWith10000sDelay));
+    mClock->advanceMs(mDataLoaderManager->bindDelayMs());
     mDataLoaderManager->setDataLoaderStatusDestroyed();
 
     ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
             .WillByDefault(Invoke(mDataLoaderManager,
                                   &MockDataLoaderManager::bindToDataLoaderOkWith10000sDelay));
+    mClock->advanceMs(mDataLoaderManager->bindDelayMs());
     mDataLoaderManager->setDataLoaderStatusDestroyed();
 }
 
@@ -1126,7 +1171,7 @@
     EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
     EXPECT_CALL(*mLooper, addFd(MockIncFs::kPendingReadsFd, _, _, _, _)).Times(2);
     EXPECT_CALL(*mLooper, removeFd(MockIncFs::kPendingReadsFd)).Times(2);
-    EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(5);
+    EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(6);
 
     sp<NiceMock<MockStorageHealthListener>> listener{new NiceMock<MockStorageHealthListener>};
     NiceMock<MockStorageHealthListener>* listenerMock = listener.get();
@@ -1314,7 +1359,7 @@
     EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
     // Not expecting callback removal.
     EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
-    EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(1);
+    EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(2);
     TemporaryDir tempDir;
     int storageId =
             mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
@@ -1355,7 +1400,7 @@
     EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
     // Not expecting callback removal.
     EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
-    EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(0);
+    EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(2);
     // System data loader.
     mDataLoaderParcel.packageName = "android";
     TemporaryDir tempDir;
@@ -1366,9 +1411,9 @@
     ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
                                                   {}, {}));
 
-    // No readlogs callback.
-    ASSERT_EQ(mTimedQueue->mAfter, 0ms);
-    ASSERT_EQ(mTimedQueue->mWhat, nullptr);
+    // IfsState callback.
+    auto callback = mTimedQueue->mWhat;
+    mTimedQueue->clearJob(storageId);
 
     ASSERT_GE(mDataLoader->setStorageParams(true), 0);
     // Now advance clock for 1hr.
@@ -1376,6 +1421,8 @@
     ASSERT_GE(mDataLoader->setStorageParams(true), 0);
     // Now advance clock for 2hrs.
     mClock->advance(readLogsMaxInterval);
+    // IfsStorage callback should not affect anything.
+    callback();
     ASSERT_EQ(mDataLoader->setStorageParams(true), 0);
 }
 
@@ -1394,7 +1441,7 @@
     EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
     // Not expecting callback removal.
     EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
-    EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(2);
+    EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(4);
     TemporaryDir tempDir;
     int storageId =
             mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
@@ -1570,7 +1617,7 @@
     int storageId =
             mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
                                                IncrementalService::CreateOptions::CreateNew);
-    EXPECT_CALL(*mIncFs, isFileFullyLoaded(_, _))
+    EXPECT_CALL(*mIncFs, isFileFullyLoaded(_, An<std::string_view>()))
             .Times(1)
             .WillOnce(Return(incfs::LoadingState::MissingBlocks));
     ASSERT_GT((int)mIncrementalService->isFileFullyLoaded(storageId, "base.apk"), 0);
@@ -1581,7 +1628,7 @@
     int storageId =
             mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
                                                IncrementalService::CreateOptions::CreateNew);
-    EXPECT_CALL(*mIncFs, isFileFullyLoaded(_, _))
+    EXPECT_CALL(*mIncFs, isFileFullyLoaded(_, An<std::string_view>()))
             .Times(1)
             .WillOnce(Return(incfs::LoadingState(-1)));
     ASSERT_LT((int)mIncrementalService->isFileFullyLoaded(storageId, "base.apk"), 0);
@@ -1592,7 +1639,7 @@
     int storageId =
             mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
                                                IncrementalService::CreateOptions::CreateNew);
-    EXPECT_CALL(*mIncFs, isFileFullyLoaded(_, _))
+    EXPECT_CALL(*mIncFs, isFileFullyLoaded(_, An<std::string_view>()))
             .Times(1)
             .WillOnce(Return(incfs::LoadingState::Full));
     ASSERT_EQ(0, (int)mIncrementalService->isFileFullyLoaded(storageId, "base.apk"));
@@ -1685,6 +1732,144 @@
     mIncrementalService->registerLoadingProgressListener(storageId, listener);
 }
 
+TEST_F(IncrementalServiceTest, testStartDataLoaderUnbindOnAllDone) {
+    mFs->hasFiles();
+
+    const auto stateUpdateInterval = 1s;
+
+    EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(1);
+    // No unbinding just yet.
+    EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0);
+    EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
+    EXPECT_CALL(*mDataLoader, start(_)).Times(1);
+    EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
+    EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
+    // System data loader to get rid of readlog timeout callback.
+    mDataLoaderParcel.packageName = "android";
+    TemporaryDir tempDir;
+    int storageId =
+            mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
+                                               IncrementalService::CreateOptions::CreateNew);
+    ASSERT_GE(storageId, 0);
+    ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
+                                                  {}, {}));
+
+    // Started.
+    ASSERT_EQ(mDataLoader->status(), IDataLoaderStatusListener::DATA_LOADER_STARTED);
+
+    // IfsState callback present.
+    ASSERT_EQ(IncrementalService::kAllStoragesId, mTimedQueue->mId);
+    ASSERT_EQ(mTimedQueue->mAfter, stateUpdateInterval);
+    auto callback = mTimedQueue->mWhat;
+    mTimedQueue->clearJob(IncrementalService::kAllStoragesId);
+
+    // Not loaded yet.
+    EXPECT_CALL(*mIncFs, isEverythingFullyLoaded(_))
+            .WillOnce(Return(incfs::LoadingState::MissingBlocks));
+
+    // Send the callback, should not do anything.
+    callback();
+
+    // Still started.
+    ASSERT_EQ(mDataLoader->status(), IDataLoaderStatusListener::DATA_LOADER_STARTED);
+
+    // Still present.
+    ASSERT_EQ(IncrementalService::kAllStoragesId, mTimedQueue->mId);
+    ASSERT_EQ(mTimedQueue->mAfter, stateUpdateInterval);
+    callback = mTimedQueue->mWhat;
+    mTimedQueue->clearJob(IncrementalService::kAllStoragesId);
+
+    // Fully loaded.
+    EXPECT_CALL(*mIncFs, isEverythingFullyLoaded(_)).WillOnce(Return(incfs::LoadingState::Full));
+    // Expect the unbind.
+    EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
+
+    callback();
+
+    // Destroyed.
+    ASSERT_EQ(mDataLoader->status(), IDataLoaderStatusListener::DATA_LOADER_DESTROYED);
+}
+
+TEST_F(IncrementalServiceTest, testStartDataLoaderUnbindOnAllDoneWithReadlogs) {
+    mFs->hasFiles();
+
+    // Readlogs.
+    mVold->setIncFsMountOptionsSuccess();
+    mAppOpsManager->checkPermissionSuccess();
+
+    const auto stateUpdateInterval = 1s;
+
+    EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(1);
+    // No unbinding just yet.
+    EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0);
+    EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
+    EXPECT_CALL(*mDataLoader, start(_)).Times(1);
+    EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
+    EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
+    // System data loader to get rid of readlog timeout callback.
+    mDataLoaderParcel.packageName = "android";
+    TemporaryDir tempDir;
+    int storageId =
+            mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
+                                               IncrementalService::CreateOptions::CreateNew);
+    ASSERT_GE(storageId, 0);
+    ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
+                                                  {}, {}));
+
+    // Started.
+    ASSERT_EQ(mDataLoader->status(), IDataLoaderStatusListener::DATA_LOADER_STARTED);
+
+    // IfsState callback present.
+    ASSERT_EQ(IncrementalService::kAllStoragesId, mTimedQueue->mId);
+    ASSERT_EQ(mTimedQueue->mAfter, stateUpdateInterval);
+    auto callback = mTimedQueue->mWhat;
+    mTimedQueue->clearJob(IncrementalService::kAllStoragesId);
+
+    // Not loaded yet.
+    EXPECT_CALL(*mIncFs, isEverythingFullyLoaded(_))
+            .WillOnce(Return(incfs::LoadingState::MissingBlocks));
+
+    // Send the callback, should not do anything.
+    callback();
+
+    // Still started.
+    ASSERT_EQ(mDataLoader->status(), IDataLoaderStatusListener::DATA_LOADER_STARTED);
+
+    // Still present.
+    ASSERT_EQ(IncrementalService::kAllStoragesId, mTimedQueue->mId);
+    ASSERT_EQ(mTimedQueue->mAfter, stateUpdateInterval);
+    callback = mTimedQueue->mWhat;
+    mTimedQueue->clearJob(IncrementalService::kAllStoragesId);
+
+    // Fully loaded.
+    EXPECT_CALL(*mIncFs, isEverythingFullyLoaded(_))
+            .WillOnce(Return(incfs::LoadingState::Full))
+            .WillOnce(Return(incfs::LoadingState::Full));
+    // But with readlogs.
+    ASSERT_GE(mDataLoader->setStorageParams(true), 0);
+
+    // Send the callback, still nothing.
+    callback();
+
+    // Still started.
+    ASSERT_EQ(mDataLoader->status(), IDataLoaderStatusListener::DATA_LOADER_STARTED);
+
+    // Still present.
+    ASSERT_EQ(IncrementalService::kAllStoragesId, mTimedQueue->mId);
+    ASSERT_EQ(mTimedQueue->mAfter, stateUpdateInterval);
+    callback = mTimedQueue->mWhat;
+    mTimedQueue->clearJob(IncrementalService::kAllStoragesId);
+
+    // Disable readlogs and expect the unbind.
+    EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
+    ASSERT_GE(mDataLoader->setStorageParams(false), 0);
+
+    callback();
+
+    // Destroyed.
+    ASSERT_EQ(mDataLoader->status(), IDataLoaderStatusListener::DATA_LOADER_DESTROYED);
+}
+
 TEST_F(IncrementalServiceTest, testRegisterStorageHealthListenerSuccess) {
     mIncFs->openMountSuccess();
     sp<NiceMock<MockStorageHealthListener>> listener{new NiceMock<MockStorageHealthListener>};
@@ -1801,7 +1986,7 @@
     EXPECT_CALL(*mDataLoader, start(_)).Times(1);
     EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
     EXPECT_CALL(*mIncFs, setUidReadTimeouts(_, _)).Times(0);
-    EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(1);
+    EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(2);
     EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
     TemporaryDir tempDir;
     int storageId =
@@ -1829,7 +2014,6 @@
     EXPECT_CALL(*mIncFs, isEverythingFullyLoaded(_))
             .WillOnce(Return(incfs::LoadingState::MissingBlocks))
             .WillOnce(Return(incfs::LoadingState::MissingBlocks))
-            .WillOnce(Return(incfs::LoadingState::Full))
             .WillOnce(Return(incfs::LoadingState::Full));
 
     // Mark DataLoader as 'system' so that readlogs don't pollute the timed queue.
@@ -1846,10 +2030,10 @@
 
     {
         // Timed callback present -> 0 progress.
-        ASSERT_EQ(storageId, mTimedQueue->mId);
+        ASSERT_EQ(IncrementalService::kAllStoragesId, mTimedQueue->mId);
         ASSERT_GE(mTimedQueue->mAfter, std::chrono::seconds(1));
         const auto timedCallback = mTimedQueue->mWhat;
-        mTimedQueue->clearJob(storageId);
+        mTimedQueue->clearJob(IncrementalService::kAllStoragesId);
 
         // Call it again.
         timedCallback();
@@ -1857,10 +2041,10 @@
 
     {
         // Still present -> some progress.
-        ASSERT_EQ(storageId, mTimedQueue->mId);
+        ASSERT_EQ(IncrementalService::kAllStoragesId, mTimedQueue->mId);
         ASSERT_GE(mTimedQueue->mAfter, std::chrono::seconds(1));
         const auto timedCallback = mTimedQueue->mWhat;
-        mTimedQueue->clearJob(storageId);
+        mTimedQueue->clearJob(IncrementalService::kAllStoragesId);
 
         // Fully loaded but readlogs collection enabled.
         ASSERT_GE(mDataLoader->setStorageParams(true), 0);
@@ -1871,10 +2055,10 @@
 
     {
         // Still present -> fully loaded + readlogs.
-        ASSERT_EQ(storageId, mTimedQueue->mId);
+        ASSERT_EQ(IncrementalService::kAllStoragesId, mTimedQueue->mId);
         ASSERT_GE(mTimedQueue->mAfter, std::chrono::seconds(1));
         const auto timedCallback = mTimedQueue->mWhat;
-        mTimedQueue->clearJob(storageId);
+        mTimedQueue->clearJob(IncrementalService::kAllStoragesId);
 
         // Now disable readlogs.
         ASSERT_GE(mDataLoader->setStorageParams(false), 0);
diff --git a/services/incremental/test/path_test.cpp b/services/incremental/test/path_test.cpp
index cbe479e1..4a8ae5b 100644
--- a/services/incremental/test/path_test.cpp
+++ b/services/incremental/test/path_test.cpp
@@ -40,4 +40,24 @@
     EXPECT_TRUE(!PathLess()("/a/b", "/a"));
 }
 
+TEST(Path, Join) {
+    EXPECT_STREQ("", path::join("", "").c_str());
+
+    EXPECT_STREQ("/", path::join("", "/").c_str());
+    EXPECT_STREQ("/", path::join("/", "").c_str());
+    EXPECT_STREQ("/", path::join("/", "/").c_str());
+    EXPECT_STREQ("/", path::join("/"s, "/").c_str());
+    EXPECT_STREQ("/", path::join("/"sv, "/").c_str());
+    EXPECT_STREQ("/", path::join("/", "/", "/", "/", "/", "/", "/", "/", "/", "/").c_str());
+
+    EXPECT_STREQ("/a/b/c/d", path::join("/a/b/"s, "c", "d").c_str());
+    EXPECT_STREQ("/a/b/c/d", path::join("/a/b/", "c", "d").c_str());
+    EXPECT_STREQ("/a/b/c/d", path::join("/", "a/b/", "c", "d").c_str());
+    EXPECT_STREQ("/a/b/c/d", path::join("/", "a/b", "c", "d").c_str());
+    EXPECT_STREQ("/a/b/c/d", path::join("/", "//a/b//", "c", "d").c_str());
+    EXPECT_STREQ("/a/b/c/d", path::join("", "", "/", "//a/b//", "c", "d").c_str());
+    EXPECT_STREQ("/a/b/c/d", path::join(""s, "", "/", "//a/b//", "c", "d").c_str());
+    EXPECT_STREQ("/a/b/c/d", path::join("/a/b", "", "", "/", "", "/", "/", "/c", "d").c_str());
+}
+
 } // namespace android::incremental::path
diff --git a/services/net/Android.bp b/services/net/Android.bp
index b01e425..800f7ad 100644
--- a/services/net/Android.bp
+++ b/services/net/Android.bp
@@ -83,3 +83,15 @@
         "//packages/modules/Connectivity/Tethering"
     ],
 }
+
+filegroup {
+    name: "services-connectivity-shared-srcs",
+    srcs: [
+        // TODO: move to networkstack-client
+        "java/android/net/IpMemoryStore.java",
+        "java/android/net/NetworkMonitorManager.java",
+        // TODO: move to libs/net
+        "java/android/net/util/KeepalivePacketDataUtil.java",
+        "java/android/net/util/NetworkConstants.java",
+    ],
+}
diff --git a/services/people/java/com/android/server/people/PeopleService.java b/services/people/java/com/android/server/people/PeopleService.java
index e7d0121..eab3b77 100644
--- a/services/people/java/com/android/server/people/PeopleService.java
+++ b/services/people/java/com/android/server/people/PeopleService.java
@@ -388,9 +388,11 @@
         private Map<AppPredictionSessionId, SessionInfo> mSessions = new ArrayMap<>();
 
         @Override
-        public void onCreatePredictionSession(AppPredictionContext context,
+        public void onCreatePredictionSession(AppPredictionContext appPredictionContext,
                 AppPredictionSessionId sessionId) {
-            mSessions.put(sessionId, new SessionInfo(context, mDataManager, sessionId.getUserId()));
+            mSessions.put(sessionId,
+                    new SessionInfo(appPredictionContext, mDataManager, sessionId.getUserId(),
+                            getContext()));
         }
 
         @Override
diff --git a/services/people/java/com/android/server/people/SessionInfo.java b/services/people/java/com/android/server/people/SessionInfo.java
index 28612f1..d256d9c 100644
--- a/services/people/java/com/android/server/people/SessionInfo.java
+++ b/services/people/java/com/android/server/people/SessionInfo.java
@@ -20,6 +20,7 @@
 import android.app.prediction.AppPredictionContext;
 import android.app.prediction.AppTarget;
 import android.app.prediction.IPredictionCallback;
+import android.content.Context;
 import android.content.pm.ParceledListSlice;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
@@ -40,9 +41,9 @@
             new RemoteCallbackList<>();
 
     SessionInfo(AppPredictionContext predictionContext, DataManager dataManager,
-            @UserIdInt int callingUserId) {
+            @UserIdInt int callingUserId, Context context) {
         mAppTargetPredictor = AppTargetPredictor.create(predictionContext,
-                this::updatePredictions, dataManager, callingUserId);
+                this::updatePredictions, dataManager, callingUserId, context);
     }
 
     void addCallback(IPredictionCallback callback) {
diff --git a/services/people/java/com/android/server/people/prediction/AppTargetPredictor.java b/services/people/java/com/android/server/people/prediction/AppTargetPredictor.java
index c89dadc..e191081 100644
--- a/services/people/java/com/android/server/people/prediction/AppTargetPredictor.java
+++ b/services/people/java/com/android/server/people/prediction/AppTargetPredictor.java
@@ -24,6 +24,7 @@
 import android.app.prediction.AppTarget;
 import android.app.prediction.AppTargetEvent;
 import android.app.prediction.AppTargetId;
+import android.content.Context;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.server.people.data.DataManager;
@@ -43,10 +44,10 @@
     /** Creates a {@link AppTargetPredictor} instance based on the prediction context. */
     public static AppTargetPredictor create(@NonNull AppPredictionContext predictionContext,
             @NonNull Consumer<List<AppTarget>> updatePredictionsMethod,
-            @NonNull DataManager dataManager, @UserIdInt int callingUserId) {
+            @NonNull DataManager dataManager, @UserIdInt int callingUserId, Context context) {
         if (UI_SURFACE_SHARE.equals(predictionContext.getUiSurface())) {
-            return new ShareTargetPredictor(
-                    predictionContext, updatePredictionsMethod, dataManager, callingUserId);
+            return new ShareTargetPredictor(predictionContext, updatePredictionsMethod, dataManager,
+                    callingUserId, context);
         }
         return new AppTargetPredictor(
                 predictionContext, updatePredictionsMethod, dataManager, callingUserId);
@@ -124,6 +125,11 @@
         callback.accept(targets);
     }
 
+    /** To be overridden by the subclass to recycle resources. */
+    @WorkerThread
+    void destroy() {
+    }
+
     AppPredictionContext getPredictionContext() {
         return mPredictionContext;
     }
diff --git a/services/people/java/com/android/server/people/prediction/ShareTargetPredictor.java b/services/people/java/com/android/server/people/prediction/ShareTargetPredictor.java
index 236ac84..368b737 100644
--- a/services/people/java/com/android/server/people/prediction/ShareTargetPredictor.java
+++ b/services/people/java/com/android/server/people/prediction/ShareTargetPredictor.java
@@ -16,6 +16,8 @@
 
 package com.android.server.people.prediction;
 
+import static android.provider.DeviceConfig.NAMESPACE_SYSTEMUI;
+
 import static java.util.Collections.reverseOrder;
 
 import android.annotation.NonNull;
@@ -23,17 +25,23 @@
 import android.annotation.UserIdInt;
 import android.annotation.WorkerThread;
 import android.app.prediction.AppPredictionContext;
+import android.app.prediction.AppPredictionManager;
+import android.app.prediction.AppPredictor;
 import android.app.prediction.AppTarget;
 import android.app.prediction.AppTargetEvent;
 import android.app.prediction.AppTargetId;
+import android.content.Context;
 import android.content.IntentFilter;
 import android.content.pm.ShortcutInfo;
 import android.content.pm.ShortcutManager.ShareShortcutInfo;
+import android.os.UserHandle;
+import android.provider.DeviceConfig;
 import android.util.Log;
 import android.util.Slog;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.app.ChooserActivity;
+import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
 import com.android.server.people.data.ConversationInfo;
 import com.android.server.people.data.DataManager;
 import com.android.server.people.data.EventHistory;
@@ -52,14 +60,27 @@
 
     private static final String TAG = "ShareTargetPredictor";
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+    private static final String REMOTE_APP_PREDICTOR_KEY = "remote_app_predictor";
     private final IntentFilter mIntentFilter;
+    private final AppPredictor mRemoteAppPredictor;
 
     ShareTargetPredictor(@NonNull AppPredictionContext predictionContext,
             @NonNull Consumer<List<AppTarget>> updatePredictionsMethod,
-            @NonNull DataManager dataManager, @UserIdInt int callingUserId) {
+            @NonNull DataManager dataManager,
+            @UserIdInt int callingUserId, @NonNull Context context) {
         super(predictionContext, updatePredictionsMethod, dataManager, callingUserId);
         mIntentFilter = predictionContext.getExtras().getParcelable(
                 ChooserActivity.APP_PREDICTION_INTENT_FILTER_KEY);
+        if (DeviceConfig.getBoolean(NAMESPACE_SYSTEMUI,
+                SystemUiDeviceConfigFlags.DARK_LAUNCH_REMOTE_PREDICTION_SERVICE_ENABLED,
+                false)) {
+            predictionContext.getExtras().putBoolean(REMOTE_APP_PREDICTOR_KEY, true);
+            mRemoteAppPredictor = context.createContextAsUser(UserHandle.of(callingUserId), 0)
+                    .getSystemService(AppPredictionManager.class)
+                    .createAppPredictionSession(predictionContext);
+        } else {
+            mRemoteAppPredictor = null;
+        }
     }
 
     /** Reports chosen history of direct/app share targets. */
@@ -72,6 +93,9 @@
         if (mIntentFilter != null) {
             getDataManager().reportShareTargetEvent(event, mIntentFilter);
         }
+        if (mRemoteAppPredictor != null) {
+            mRemoteAppPredictor.notifyAppTargetEvent(event);
+        }
     }
 
     /** Provides prediction on direct share targets */
@@ -129,6 +153,15 @@
         callback.accept(appTargetList);
     }
 
+    /** Recycles resources. */
+    @WorkerThread
+    @Override
+    void destroy() {
+        if (mRemoteAppPredictor != null) {
+            mRemoteAppPredictor.destroy();
+        }
+    }
+
     private List<ShareTarget> getDirectShareTargets() {
         List<ShareTarget> shareTargets = new ArrayList<>();
         List<ShareShortcutInfo> shareShortcuts =
diff --git a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
index a262939..1208ecc 100644
--- a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
+++ b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
@@ -30,6 +30,8 @@
 import android.os.ServiceManager;
 import android.os.UpdateEngine;
 import android.os.UpdateEngineCallback;
+import android.os.UserHandle;
+import android.os.UserManager;
 import android.provider.DeviceConfig;
 import android.util.Log;
 
@@ -295,10 +297,56 @@
             return;
         }
 
-        try {
-            mIProfcollect.report();
-        } catch (RemoteException e) {
-            Log.e(LOG_TAG, e.getMessage());
+        final boolean uploadReport =
+                DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_PROFCOLLECT_NATIVE_BOOT,
+                                        "upload_report", false);
+
+        new Thread(() -> {
+            try {
+                String reportUuid = mIProfcollect.report();
+
+                if (!uploadReport) {
+                    return;
+                }
+
+                final int profileId = getBBProfileId();
+                mIProfcollect.copy_report_to_bb(profileId, reportUuid);
+                String reportPath =
+                        "/data/user/" + profileId
+                        + "/com.google.android.apps.internal.betterbug/cache/"
+                        + reportUuid + ".zip";
+                Intent uploadIntent =
+                        new Intent("com.google.android.apps.betterbug.intent.action.UPLOAD_PROFILE")
+                        .setPackage("com.google.android.apps.internal.betterbug")
+                        .putExtra("EXTRA_DESTINATION", "PROFCOLLECT")
+                        .putExtra("EXTRA_PACKAGE_NAME", getContext().getPackageName())
+                        .putExtra("EXTRA_PROFILE_PATH", reportPath)
+                        .addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+                Context context = getContext();
+                if (context.getPackageManager().queryBroadcastReceivers(uploadIntent, 0) != null) {
+                    context.sendBroadcast(uploadIntent);
+                }
+                mIProfcollect.delete_report(reportUuid);
+            } catch (RemoteException e) {
+                Log.e(LOG_TAG, e.getMessage());
+            }
+        }).start();
+    }
+
+    /**
+     * Get BetterBug's profile ID. It is the work profile ID, if it exists. Otherwise the system
+     * user ID.
+     *
+     * @return BetterBug's profile ID.
+     */
+    private int getBBProfileId() {
+        UserManager userManager = UserManager.get(getContext());
+        int[] profiles = userManager.getProfileIds(UserHandle.USER_SYSTEM, false);
+        for (int p : profiles) {
+            if (userManager.getUserInfo(p).isManagedProfile()) {
+                return p;
+            }
         }
+        return UserHandle.USER_SYSTEM;
     }
 }
diff --git a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationCollectorTest.kt b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationCollectorTest.kt
index d5eda20..dce853a 100644
--- a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationCollectorTest.kt
+++ b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationCollectorTest.kt
@@ -41,7 +41,12 @@
     }
 
     private val platformCompat: PlatformCompat = mockThrowOnUnmocked {
-        whenever(isChangeEnabled(eq(DomainVerificationCollector.RESTRICT_DOMAINS), any())) {
+        whenever(
+            isChangeEnabledInternalNoLogging(
+                eq(DomainVerificationCollector.RESTRICT_DOMAINS),
+                any()
+            )
+        ) {
             (arguments[1] as ApplicationInfo).targetSdkVersion >= Build.VERSION_CODES.S
         }
     }
diff --git a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationEnforcerTest.kt b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationEnforcerTest.kt
index 7e25901..537a49e 100644
--- a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationEnforcerTest.kt
+++ b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationEnforcerTest.kt
@@ -114,12 +114,7 @@
                     it,
                     mockThrowOnUnmocked { whenever(linkedApps) { ArraySet<String>() } },
                     mockThrowOnUnmocked {
-                        whenever(
-                            isChangeEnabled(
-                                anyLong(),
-                                any()
-                            )
-                        ) { true }
+                        whenever(isChangeEnabledInternalNoLogging(anyLong(), any())) { true }
                     }).apply {
                     setConnection(connection)
                 }
@@ -422,7 +417,7 @@
 
         allowQueryAll.set(true)
 
-        runMethod(target, NON_VERIFIER_UID)
+        assertFails { runMethod(target, NON_VERIFIER_UID) }
     }
 
     private fun approvedVerifier() {
@@ -821,7 +816,7 @@
         // System/shell only
         INTERNAL,
 
-        // INTERNAL || domain verification agent || user setting permission holder
+        // INTERNAL || non-legacy domain verification agent
         QUERENT,
 
         // INTERNAL || domain verification agent
diff --git a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationJavaUtil.java b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationJavaUtil.java
index 8ae4c5a..14c02d5 100644
--- a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationJavaUtil.java
+++ b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationJavaUtil.java
@@ -20,6 +20,7 @@
 import android.annotation.Nullable;
 import android.annotation.UserIdInt;
 import android.content.pm.PackageManager;
+import android.content.pm.verify.domain.DomainVerificationManager;
 
 import com.android.server.pm.verify.domain.DomainVerificationService;
 
@@ -45,4 +46,16 @@
             throws PackageManager.NameNotFoundException {
         return service.setDomainVerificationUserSelection(domainSetId, domains, enabled, userId);
     }
+
+    static int setStatusForceNullable(@NonNull DomainVerificationManager manager,
+            @Nullable UUID domainSetId, @Nullable Set<String> domains, int state)
+            throws PackageManager.NameNotFoundException {
+        return manager.setDomainVerificationStatus(domainSetId, domains, state);
+    }
+
+    static int setUserSelectionForceNullable(@NonNull DomainVerificationManager manager,
+            @Nullable UUID domainSetId, @Nullable Set<String> domains, boolean enabled)
+            throws PackageManager.NameNotFoundException {
+        return manager.setDomainVerificationUserSelection(domainSetId, domains, enabled);
+    }
 }
diff --git a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationManagerApiTest.kt b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationManagerApiTest.kt
index 0e74b65..881604f 100644
--- a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationManagerApiTest.kt
+++ b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationManagerApiTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.server.pm.test.verify.domain
 
+import android.content.Context
 import android.content.Intent
 import android.content.pm.PackageManager
 import android.content.pm.parsing.component.ParsedActivity
@@ -23,6 +24,7 @@
 import android.content.pm.verify.domain.DomainVerificationInfo
 import android.content.pm.verify.domain.DomainVerificationManager
 import android.content.pm.verify.domain.DomainVerificationUserState
+import android.content.pm.verify.domain.IDomainVerificationManager
 import android.os.Build
 import android.os.PatternMatcher
 import android.os.Process
@@ -127,15 +129,17 @@
         assertThat(service.setStatus(UUID_INVALID, setOf(DOMAIN_1), 1100))
                 .isEqualTo(DomainVerificationManager.ERROR_DOMAIN_SET_ID_INVALID)
 
-        assertThat(DomainVerificationJavaUtil.setStatusForceNullable(service, null,
-                setOf(DOMAIN_1), 1100))
-                .isEqualTo(DomainVerificationManager.ERROR_DOMAIN_SET_ID_NULL)
+        assertFailsWith(IllegalArgumentException::class) {
+            DomainVerificationJavaUtil.setStatusForceNullable(service, null, setOf(DOMAIN_1), 1100)
+        }
 
-        assertThat(DomainVerificationJavaUtil.setStatusForceNullable(service, UUID_ONE, null,
-                1100)).isEqualTo(DomainVerificationManager.ERROR_DOMAIN_SET_NULL_OR_EMPTY)
+        assertFailsWith(IllegalArgumentException::class) {
+            DomainVerificationJavaUtil.setStatusForceNullable(service, UUID_ONE, null, 1100)
+        }
 
-        assertThat(service.setStatus(UUID_ONE, emptySet(), 1100))
-                .isEqualTo(DomainVerificationManager.ERROR_DOMAIN_SET_NULL_OR_EMPTY)
+        assertFailsWith(IllegalArgumentException::class) {
+            service.setStatus(UUID_ONE, emptySet(), 1100)
+        }
 
         assertThat(service.setStatus(UUID_ONE, setOf(DOMAIN_3), 1100))
                 .isEqualTo(DomainVerificationManager.ERROR_UNKNOWN_DOMAIN)
@@ -143,8 +147,9 @@
         assertThat(service.setStatus(UUID_ONE, setOf(DOMAIN_1, DOMAIN_2, DOMAIN_3), 1100))
                 .isEqualTo(DomainVerificationManager.ERROR_UNKNOWN_DOMAIN)
 
-        assertThat(service.setStatus(UUID_ONE, setOf(DOMAIN_1), 15))
-                .isEqualTo(DomainVerificationManager.ERROR_INVALID_STATE_CODE)
+        assertFailsWith(IllegalArgumentException::class) {
+            service.setStatus(UUID_ONE, setOf(DOMAIN_1), 15)
+        }
 
         map.clear()
         assertFailsWith(PackageManager.NameNotFoundException::class){
@@ -198,15 +203,19 @@
         assertThat(service.setUserSelection(UUID_INVALID, setOf(DOMAIN_1), true, 0))
                 .isEqualTo(DomainVerificationManager.ERROR_DOMAIN_SET_ID_INVALID)
 
-        assertThat(DomainVerificationJavaUtil.setUserSelectionForceNullable(service, null,
-                setOf(DOMAIN_1), true, 0))
-                .isEqualTo(DomainVerificationManager.ERROR_DOMAIN_SET_ID_NULL)
+        assertFailsWith(IllegalArgumentException::class) {
+            DomainVerificationJavaUtil.setUserSelectionForceNullable(service, null,
+                setOf(DOMAIN_1), true, 0)
+        }
 
-        assertThat(DomainVerificationJavaUtil.setUserSelectionForceNullable(service, UUID_ONE, null,
-                true, 0)).isEqualTo(DomainVerificationManager.ERROR_DOMAIN_SET_NULL_OR_EMPTY)
+        assertFailsWith(IllegalArgumentException::class) {
+            DomainVerificationJavaUtil.setUserSelectionForceNullable(service, UUID_ONE, null,
+                true, 0)
+        }
 
-        assertThat(service.setUserSelection(UUID_ONE, emptySet(), true, 0))
-                .isEqualTo(DomainVerificationManager.ERROR_DOMAIN_SET_NULL_OR_EMPTY)
+        assertFailsWith(IllegalArgumentException::class) {
+            service.setUserSelection(UUID_ONE, emptySet(), true, 0)
+        }
 
         assertThat(service.setUserSelection(UUID_ONE, setOf(DOMAIN_3), true, 0))
                 .isEqualTo(DomainVerificationManager.ERROR_UNKNOWN_DOMAIN)
@@ -297,6 +306,48 @@
         assertThat(service.getOwnersForDomain(DOMAIN_2, 1)).isEmpty()
     }
 
+    @Test
+    fun appProcessManager() {
+        // The app side DomainVerificationManager also has to do some argument enforcement since
+        // the input values are transformed before they are sent across Binder. Verify that here.
+
+        // Mock nothing to ensure no calls are made before failing
+        val context = mockThrowOnUnmocked<Context>()
+        val binderInterface = mockThrowOnUnmocked<IDomainVerificationManager>()
+
+        val manager = DomainVerificationManager(context, binderInterface)
+
+        assertFailsWith(IllegalArgumentException::class) {
+            DomainVerificationJavaUtil.setStatusForceNullable(manager, null, setOf(DOMAIN_1), 1100)
+        }
+
+        assertFailsWith(IllegalArgumentException::class) {
+            DomainVerificationJavaUtil.setStatusForceNullable(manager, UUID_ONE, null, 1100)
+        }
+
+        assertFailsWith(IllegalArgumentException::class) {
+            manager.setDomainVerificationStatus(UUID_ONE, emptySet(), 1100)
+        }
+
+        assertFailsWith(IllegalArgumentException::class) {
+            DomainVerificationJavaUtil.setUserSelectionForceNullable(
+                manager, null,
+                setOf(DOMAIN_1), true
+            )
+        }
+
+        assertFailsWith(IllegalArgumentException::class) {
+            DomainVerificationJavaUtil.setUserSelectionForceNullable(
+                manager, UUID_ONE,
+                null, true
+            )
+        }
+
+        assertFailsWith(IllegalArgumentException::class) {
+            manager.setDomainVerificationUserSelection(UUID_ONE, emptySet(), true)
+        }
+    }
+
     private fun makeService(vararg pkgSettings: PackageSetting) =
             makeService { pkgName -> pkgSettings.find { pkgName == it.getName() } }
 
@@ -310,7 +361,7 @@
             }, mockThrowOnUnmocked {
                 whenever(linkedApps) { ArraySet<String>() }
             }, mockThrowOnUnmocked {
-                whenever(isChangeEnabled(anyLong(), any())) { true }
+                whenever(isChangeEnabledInternalNoLogging(anyLong(), any())) { true }
             }).apply {
                 setConnection(mockThrowOnUnmocked {
                     whenever(filterAppAccess(anyString(), anyInt(), anyInt())) { false }
diff --git a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationPackageTest.kt b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationPackageTest.kt
index fe3672d..0ce16e6 100644
--- a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationPackageTest.kt
+++ b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationPackageTest.kt
@@ -43,6 +43,7 @@
 import org.mockito.ArgumentMatchers
 import org.mockito.ArgumentMatchers.any
 import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.ArgumentMatchers.anyLong
 import org.mockito.ArgumentMatchers.anyString
 import java.util.UUID
 
@@ -366,7 +367,7 @@
             }, mockThrowOnUnmocked {
                 whenever(linkedApps) { ArraySet<String>() }
             }, mockThrowOnUnmocked {
-                whenever(isChangeEnabled(ArgumentMatchers.anyLong(), any())) { true }
+                whenever(isChangeEnabledInternalNoLogging(anyLong(), any())) { true }
             }).apply {
                 setConnection(mockThrowOnUnmocked {
                     whenever(filterAppAccess(anyString(), anyInt(), anyInt())) { false }
diff --git a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationSettingsMutationTest.kt b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationSettingsMutationTest.kt
index 377bae1..b7c6922 100644
--- a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationSettingsMutationTest.kt
+++ b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationSettingsMutationTest.kt
@@ -98,7 +98,7 @@
                         context,
                         mockThrowOnUnmocked { whenever(linkedApps) { ArraySet<String>() } },
                         mockThrowOnUnmocked {
-                            whenever(isChangeEnabled(anyLong(),any())) { true }
+                            whenever(isChangeEnabledInternalNoLogging(anyLong(), any())) { true }
                         }).apply {
                         setConnection(connection)
                     }
diff --git a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationUserSelectionOverrideTest.kt b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationUserSelectionOverrideTest.kt
index 44c1b8f..54648ab 100644
--- a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationUserSelectionOverrideTest.kt
+++ b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationUserSelectionOverrideTest.kt
@@ -71,7 +71,7 @@
         }, mockThrowOnUnmocked {
             whenever(linkedApps) { ArraySet<String>() }
         }, mockThrowOnUnmocked {
-            whenever(isChangeEnabled(anyLong(), any())) { true }
+            whenever(isChangeEnabledInternalNoLogging(anyLong(), any())) { true }
         }).apply {
             setConnection(mockThrowOnUnmocked {
                 whenever(filterAppAccess(anyString(), anyInt(), anyInt())) { false }
diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
index 28940b3..8481961 100644
--- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
@@ -21,6 +21,7 @@
 import static android.app.AlarmManager.FLAG_ALLOW_WHILE_IDLE_COMPAT;
 import static android.app.AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED;
 import static android.app.AlarmManager.FLAG_IDLE_UNTIL;
+import static android.app.AlarmManager.FLAG_PRIORITIZE;
 import static android.app.AlarmManager.FLAG_STANDALONE;
 import static android.app.AlarmManager.FLAG_WAKE_FROM_IDLE;
 import static android.app.AlarmManager.RTC;
@@ -62,6 +63,7 @@
 import static com.android.server.alarm.AlarmManagerService.Constants.KEY_MIN_FUTURITY;
 import static com.android.server.alarm.AlarmManagerService.Constants.KEY_MIN_INTERVAL;
 import static com.android.server.alarm.AlarmManagerService.Constants.KEY_MIN_WINDOW;
+import static com.android.server.alarm.AlarmManagerService.Constants.KEY_PRIORITY_ALARM_DELAY;
 import static com.android.server.alarm.AlarmManagerService.FREQUENT_INDEX;
 import static com.android.server.alarm.AlarmManagerService.INDEFINITE_DELAY;
 import static com.android.server.alarm.AlarmManagerService.IS_WAKEUP_MASK;
@@ -443,6 +445,12 @@
                 TEST_CALLING_UID);
     }
 
+    private void setPrioritizedAlarm(int type, long triggerTime, IAlarmListener listener) {
+        mService.setImpl(type, triggerTime, WINDOW_EXACT, 0, null, listener, "test",
+                FLAG_STANDALONE | FLAG_PRIORITIZE, null, null, TEST_CALLING_UID,
+                TEST_CALLING_PACKAGE, null);
+    }
+
     private void setAllowWhileIdleAlarm(int type, long triggerTime, PendingIntent pi,
             boolean unrestricted) {
         final int flags = unrestricted ? FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED : FLAG_ALLOW_WHILE_IDLE;
@@ -579,6 +587,7 @@
         setDeviceConfigLong(KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION, 40);
         setDeviceConfigLong(KEY_LISTENER_TIMEOUT, 45);
         setDeviceConfigLong(KEY_MIN_WINDOW, 50);
+        setDeviceConfigLong(KEY_PRIORITY_ALARM_DELAY, 55);
         assertEquals(5, mService.mConstants.MIN_FUTURITY);
         assertEquals(10, mService.mConstants.MIN_INTERVAL);
         assertEquals(15, mService.mConstants.MAX_INTERVAL);
@@ -589,6 +598,7 @@
         assertEquals(40, mService.mConstants.ALLOW_WHILE_IDLE_WHITELIST_DURATION);
         assertEquals(45, mService.mConstants.LISTENER_TIMEOUT);
         assertEquals(50, mService.mConstants.MIN_WINDOW);
+        assertEquals(55, mService.mConstants.PRIORITY_ALARM_DELAY);
     }
 
     @Test
@@ -1586,6 +1596,89 @@
     }
 
     @Test
+    public void prioritizedAlarmsInBatterySaver() throws Exception {
+        when(mAppStateTracker.areAlarmsRestrictedByBatterySaver(TEST_CALLING_UID,
+                TEST_CALLING_PACKAGE)).thenReturn(true);
+        when(mAppStateTracker.isForceAllAppsStandbyEnabled()).thenReturn(true);
+        final long minDelay = 5;
+        setDeviceConfigLong(KEY_PRIORITY_ALARM_DELAY, minDelay);
+
+        final long firstTrigger = mNowElapsedTest + 4;
+        final AtomicInteger alarmsFired = new AtomicInteger(0);
+        final int numAlarms = 10;
+        for (int i = 0; i < numAlarms; i++) {
+            setPrioritizedAlarm(ELAPSED_REALTIME_WAKEUP, firstTrigger + i,
+                    new IAlarmListener.Stub() {
+                        @Override
+                        public void doAlarm(IAlarmCompleteListener callback)
+                                throws RemoteException {
+                            alarmsFired.incrementAndGet();
+                        }
+                    });
+        }
+        assertEquals(firstTrigger, mTestTimer.getElapsed());
+        mNowElapsedTest = firstTrigger;
+        mTestTimer.expire();
+        while (alarmsFired.get() < numAlarms) {
+            assertEquals(mNowElapsedTest + minDelay, mTestTimer.getElapsed());
+            mNowElapsedTest = mTestTimer.getElapsed();
+            mTestTimer.expire();
+        }
+        assertEquals(numAlarms, alarmsFired.get());
+    }
+
+    @Test
+    public void prioritizedAlarmsInDeviceIdle() throws Exception {
+        doReturn(0).when(mService).fuzzForDuration(anyLong());
+
+        final long minDelay = 5;
+        setDeviceConfigLong(KEY_PRIORITY_ALARM_DELAY, minDelay);
+
+        final long idleUntil = mNowElapsedTest + 1000;
+        setIdleUntilAlarm(ELAPSED_REALTIME_WAKEUP, idleUntil, getNewMockPendingIntent());
+        assertNotNull(mService.mPendingIdleUntil);
+
+        final long firstTrigger = mNowElapsedTest + 4;
+        final AtomicInteger alarmsFired = new AtomicInteger(0);
+        final int numAlarms = 10;
+        for (int i = 0; i < numAlarms; i++) {
+            setPrioritizedAlarm(ELAPSED_REALTIME_WAKEUP, firstTrigger + i,
+                    new IAlarmListener.Stub() {
+                        @Override
+                        public void doAlarm(IAlarmCompleteListener callback)
+                                throws RemoteException {
+                            alarmsFired.incrementAndGet();
+                        }
+                    });
+        }
+        assertEquals(firstTrigger, mTestTimer.getElapsed());
+        mNowElapsedTest = firstTrigger;
+        mTestTimer.expire();
+        while (alarmsFired.get() < numAlarms) {
+            assertEquals(mNowElapsedTest + minDelay, mTestTimer.getElapsed());
+            mNowElapsedTest = mTestTimer.getElapsed();
+            mTestTimer.expire();
+        }
+        assertEquals(numAlarms, alarmsFired.get());
+
+        setPrioritizedAlarm(ELAPSED_REALTIME_WAKEUP, idleUntil - 3, new IAlarmListener.Stub() {
+            @Override
+            public void doAlarm(IAlarmCompleteListener callback) throws RemoteException {
+            }
+        });
+        setPrioritizedAlarm(ELAPSED_REALTIME_WAKEUP, idleUntil - 2, new IAlarmListener.Stub() {
+            @Override
+            public void doAlarm(IAlarmCompleteListener callback) throws RemoteException {
+            }
+        });
+        assertEquals(idleUntil - 3, mTestTimer.getElapsed());
+        mNowElapsedTest = mTestTimer.getElapsed();
+        mTestTimer.expire();
+
+        assertEquals(idleUntil, mTestTimer.getElapsed());
+    }
+
+    @Test
     public void dispatchOrder() throws Exception {
         doReturn(0).when(mService).fuzzForDuration(anyLong());
 
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 22b2f7e..d220444 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/ApplicationExitInfoTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/ApplicationExitInfoTest.java
@@ -1015,7 +1015,7 @@
         assertNotNull(info);
 
         if (timestamp != null) {
-            final long tolerance = 1000; // ms
+            final long tolerance = 10000; // ms
             assertTrue(timestamp - tolerance <= info.getTimestamp());
             assertTrue(timestamp + tolerance >= info.getTimestamp());
         }
diff --git a/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java
index 7a3a950..647ea13 100644
--- a/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java
@@ -16,8 +16,6 @@
 package com.android.server.appop;
 
 import static android.app.ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
-import static android.app.AppOpsManager.FILTER_BY_PACKAGE_NAME;
-import static android.app.AppOpsManager.FILTER_BY_UID;
 import static android.app.AppOpsManager.MODE_ALLOWED;
 import static android.app.AppOpsManager.MODE_ERRORED;
 import static android.app.AppOpsManager.MODE_FOREGROUND;
@@ -44,7 +42,6 @@
 import static org.mockito.ArgumentMatchers.nullable;
 
 import android.app.ActivityManager;
-import android.app.AppOpsManager;
 import android.app.AppOpsManager.OpEntry;
 import android.app.AppOpsManager.PackageOps;
 import android.content.ContentResolver;
@@ -53,7 +50,6 @@
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Process;
-import android.os.RemoteCallback;
 import android.provider.Settings;
 
 import androidx.test.InstrumentationRegistry;
@@ -66,6 +62,7 @@
 
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.quality.Strictness;
@@ -73,9 +70,6 @@
 import java.io.File;
 import java.util.Collections;
 import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicReference;
 
 /**
  * Unit tests for AppOpsService. Covers functionality that is difficult to test using CTS tests
@@ -229,6 +223,7 @@
 
     // Tests that ops are persisted during shutdown.
     @Test
+    @Ignore("b/183523911")
     public void testShutdown() {
         mAppOpsService.setMode(OP_READ_SMS, mMyUid, sMyPackageName, MODE_ALLOWED);
         mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, sMyPackageName, null, false, null, false);
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java
index 3870b02..1b8f9c7 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java
@@ -19,6 +19,7 @@
 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
@@ -41,10 +42,11 @@
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.app.job.JobInfo;
 import android.content.ComponentName;
 import android.content.Context;
@@ -53,8 +55,6 @@
 import android.net.ConnectivityManager.NetworkCallback;
 import android.net.Network;
 import android.net.NetworkCapabilities;
-import android.net.NetworkInfo;
-import android.net.NetworkInfo.DetailedState;
 import android.net.NetworkPolicyManager;
 import android.os.Build;
 import android.os.Looper;
@@ -136,7 +136,7 @@
     }
 
     @Test
-    public void testInsane() throws Exception {
+    public void testUsable() throws Exception {
         final Network net = new Network(101);
         final JobInfo.Builder job = createJob()
                 .setEstimatedNetworkBytes(DataUnit.MEBIBYTES.toBytes(1),
@@ -192,6 +192,30 @@
     }
 
     @Test
+    public void testInsane() throws Exception {
+        final Network net = new Network(101);
+        final JobInfo.Builder job = createJob()
+                .setEstimatedNetworkBytes(DataUnit.MEBIBYTES.toBytes(1),
+                        DataUnit.MEBIBYTES.toBytes(1))
+                .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);
+
+        final ConnectivityController controller = new ConnectivityController(mService);
+        when(mService.getMaxJobExecutionTimeMs(any())).thenReturn(10 * 60_000L);
+
+
+        // Suspended networks aren't usable.
+        assertFalse(controller.isSatisfied(createJobStatus(job), net,
+                createCapabilities().removeCapability(NET_CAPABILITY_NOT_SUSPENDED)
+                        .setLinkUpstreamBandwidthKbps(1024).setLinkDownstreamBandwidthKbps(1024),
+                mConstants));
+
+        // Not suspended networks are usable.
+        assertTrue(controller.isSatisfied(createJobStatus(job), net,
+                createCapabilities().setLinkUpstreamBandwidthKbps(1024)
+                        .setLinkDownstreamBandwidthKbps(1024), mConstants));
+    }
+
+    @Test
     public void testCongestion() throws Exception {
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
         final JobInfo.Builder job = createJob()
@@ -263,9 +287,17 @@
 
     @Test
     public void testUpdates() throws Exception {
-        final ArgumentCaptor<NetworkCallback> callback = ArgumentCaptor
-                .forClass(NetworkCallback.class);
-        doNothing().when(mConnManager).registerNetworkCallback(any(), callback.capture());
+        final ArgumentCaptor<NetworkCallback> callbackCaptor =
+                ArgumentCaptor.forClass(NetworkCallback.class);
+        doNothing().when(mConnManager).registerNetworkCallback(any(), callbackCaptor.capture());
+        final ArgumentCaptor<NetworkCallback> redCallbackCaptor =
+                ArgumentCaptor.forClass(NetworkCallback.class);
+        doNothing().when(mConnManager).registerDefaultNetworkCallbackAsUid(
+                eq(UID_RED), redCallbackCaptor.capture(), any());
+        final ArgumentCaptor<NetworkCallback> blueCallbackCaptor =
+                ArgumentCaptor.forClass(NetworkCallback.class);
+        doNothing().when(mConnManager).registerDefaultNetworkCallbackAsUid(
+                eq(UID_BLUE), blueCallbackCaptor.capture(), any());
 
         final ConnectivityController controller = new ConnectivityController(mService);
 
@@ -281,15 +313,16 @@
         final JobStatus blue = createJobStatus(createJob()
                 .setEstimatedNetworkBytes(DataUnit.MEBIBYTES.toBytes(1), 0)
                 .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY), UID_BLUE);
+        controller.maybeStartTrackingJobLocked(red, null);
+        controller.maybeStartTrackingJobLocked(blue, null);
+        final NetworkCallback generalCallback = callbackCaptor.getValue();
+        final NetworkCallback redCallback = redCallbackCaptor.getValue();
+        final NetworkCallback blueCallback = blueCallbackCaptor.getValue();
 
         // Pretend we're offline when job is added
         {
-            reset(mConnManager);
-            answerNetwork(UID_RED, null, null);
-            answerNetwork(UID_BLUE, null, null);
-
-            controller.maybeStartTrackingJobLocked(red, null);
-            controller.maybeStartTrackingJobLocked(blue, null);
+            answerNetwork(generalCallback, redCallback, null, null, null);
+            answerNetwork(generalCallback, blueCallback, null, null, null);
 
             assertFalse(red.isConstraintSatisfied(JobStatus.CONSTRAINT_CONNECTIVITY));
             assertFalse(blue.isConstraintSatisfied(JobStatus.CONSTRAINT_CONNECTIVITY));
@@ -297,11 +330,10 @@
 
         // Metered network
         {
-            reset(mConnManager);
-            answerNetwork(UID_RED, meteredNet, meteredCaps);
-            answerNetwork(UID_BLUE, meteredNet, meteredCaps);
+            answerNetwork(generalCallback, redCallback, null, meteredNet, meteredCaps);
+            answerNetwork(generalCallback, blueCallback, null, meteredNet, meteredCaps);
 
-            callback.getValue().onCapabilitiesChanged(meteredNet, meteredCaps);
+            generalCallback.onCapabilitiesChanged(meteredNet, meteredCaps);
 
             assertFalse(red.isConstraintSatisfied(JobStatus.CONSTRAINT_CONNECTIVITY));
             assertTrue(blue.isConstraintSatisfied(JobStatus.CONSTRAINT_CONNECTIVITY));
@@ -309,11 +341,10 @@
 
         // Unmetered network background
         {
-            reset(mConnManager);
-            answerNetwork(UID_RED, meteredNet, meteredCaps);
-            answerNetwork(UID_BLUE, meteredNet, meteredCaps);
+            answerNetwork(generalCallback, redCallback, meteredNet, meteredNet, meteredCaps);
+            answerNetwork(generalCallback, blueCallback, meteredNet, meteredNet, meteredCaps);
 
-            callback.getValue().onCapabilitiesChanged(unmeteredNet, unmeteredCaps);
+            generalCallback.onCapabilitiesChanged(unmeteredNet, unmeteredCaps);
 
             assertFalse(red.isConstraintSatisfied(JobStatus.CONSTRAINT_CONNECTIVITY));
             assertTrue(blue.isConstraintSatisfied(JobStatus.CONSTRAINT_CONNECTIVITY));
@@ -321,11 +352,10 @@
 
         // Lost metered network
         {
-            reset(mConnManager);
-            answerNetwork(UID_RED, unmeteredNet, unmeteredCaps);
-            answerNetwork(UID_BLUE, unmeteredNet, unmeteredCaps);
+            answerNetwork(generalCallback, redCallback, meteredNet, unmeteredNet, unmeteredCaps);
+            answerNetwork(generalCallback, blueCallback, meteredNet, unmeteredNet, unmeteredCaps);
 
-            callback.getValue().onLost(meteredNet);
+            generalCallback.onLost(meteredNet);
 
             assertTrue(red.isConstraintSatisfied(JobStatus.CONSTRAINT_CONNECTIVITY));
             assertTrue(blue.isConstraintSatisfied(JobStatus.CONSTRAINT_CONNECTIVITY));
@@ -333,11 +363,10 @@
 
         // Specific UID was blocked
         {
-            reset(mConnManager);
-            answerNetwork(UID_RED, null, null);
-            answerNetwork(UID_BLUE, unmeteredNet, unmeteredCaps);
+            answerNetwork(generalCallback, redCallback, unmeteredNet, null, null);
+            answerNetwork(generalCallback, blueCallback, unmeteredNet, unmeteredNet, unmeteredCaps);
 
-            callback.getValue().onCapabilitiesChanged(unmeteredNet, unmeteredCaps);
+            generalCallback.onCapabilitiesChanged(unmeteredNet, unmeteredCaps);
 
             assertFalse(red.isConstraintSatisfied(JobStatus.CONSTRAINT_CONNECTIVITY));
             assertTrue(blue.isConstraintSatisfied(JobStatus.CONSTRAINT_CONNECTIVITY));
@@ -404,6 +433,8 @@
         final JobStatus blue = createJobStatus(createJob()
                 .setEstimatedNetworkBytes(DataUnit.MEBIBYTES.toBytes(1), 0)
                 .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY), UID_BLUE);
+        controller.maybeStartTrackingJobLocked(red, null);
+        controller.maybeStartTrackingJobLocked(blue, null);
 
         InOrder inOrder = inOrder(mNetPolicyManagerInternal);
 
@@ -560,6 +591,18 @@
 
     @Test
     public void testRestrictedJobTracking() {
+        final ArgumentCaptor<NetworkCallback> callback =
+                ArgumentCaptor.forClass(NetworkCallback.class);
+        doNothing().when(mConnManager).registerNetworkCallback(any(), callback.capture());
+        final ArgumentCaptor<NetworkCallback> redCallback =
+                ArgumentCaptor.forClass(NetworkCallback.class);
+        doNothing().when(mConnManager).registerDefaultNetworkCallbackAsUid(
+                eq(UID_RED), redCallback.capture(), any());
+        final ArgumentCaptor<NetworkCallback> blueCallback =
+                ArgumentCaptor.forClass(NetworkCallback.class);
+        doNothing().when(mConnManager).registerDefaultNetworkCallbackAsUid(
+                eq(UID_BLUE), blueCallback.capture(), any());
+
         final JobStatus networked = createJobStatus(createJob()
                 .setEstimatedNetworkBytes(DataUnit.MEBIBYTES.toBytes(1), 0)
                 .setRequiredNetworkType(JobInfo.NETWORK_TYPE_CELLULAR), UID_RED);
@@ -570,13 +613,11 @@
         final Network cellularNet = new Network(101);
         final NetworkCapabilities cellularCaps =
                 createCapabilities().addTransportType(TRANSPORT_CELLULAR);
-        reset(mConnManager);
-        answerNetwork(UID_RED, cellularNet, cellularCaps);
-        answerNetwork(UID_BLUE, cellularNet, cellularCaps);
 
         final ConnectivityController controller = new ConnectivityController(mService);
         controller.maybeStartTrackingJobLocked(networked, null);
         controller.maybeStartTrackingJobLocked(unnetworked, null);
+        answerNetwork(callback.getValue(), redCallback.getValue(), null, cellularNet, cellularCaps);
 
         assertTrue(networked.isConstraintSatisfied(JobStatus.CONSTRAINT_CONNECTIVITY));
         assertFalse(unnetworked.isConstraintSatisfied(JobStatus.CONSTRAINT_CONNECTIVITY));
@@ -600,18 +641,28 @@
         assertFalse(unnetworked.isConstraintSatisfied(JobStatus.CONSTRAINT_CONNECTIVITY));
     }
 
-    private void answerNetwork(int uid, Network net, NetworkCapabilities caps) {
-        when(mConnManager.getActiveNetworkForUid(eq(uid), anyBoolean())).thenReturn(net);
-        when(mConnManager.getNetworkCapabilities(eq(net))).thenReturn(caps);
-        if (net != null) {
-            final NetworkInfo ni = new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0, null, null);
-            ni.setDetailedState(DetailedState.CONNECTED, null, null);
-            when(mConnManager.getNetworkInfoForUid(eq(net), eq(uid), anyBoolean())).thenReturn(ni);
+    private void answerNetwork(@NonNull NetworkCallback generalCallback,
+            @Nullable NetworkCallback uidCallback, @Nullable Network lastNetwork,
+            @Nullable Network net, @Nullable NetworkCapabilities caps) {
+        if (net == null) {
+            generalCallback.onLost(lastNetwork);
+            if (uidCallback != null) {
+                uidCallback.onLost(lastNetwork);
+            }
+        } else {
+            generalCallback.onAvailable(net);
+            generalCallback.onCapabilitiesChanged(net, caps);
+            if (uidCallback != null) {
+                uidCallback.onAvailable(net);
+                uidCallback.onBlockedStatusChanged(net, false);
+                uidCallback.onCapabilitiesChanged(net, caps);
+            }
         }
     }
 
     private static NetworkCapabilities createCapabilities() {
         return new NetworkCapabilities().addCapability(NET_CAPABILITY_INTERNET)
+                .addCapability(NET_CAPABILITY_NOT_SUSPENDED)
                 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
                 .addCapability(NET_CAPABILITY_VALIDATED);
     }
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/JobStatusTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/JobStatusTest.java
index 7925b69..0fcda81 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/JobStatusTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/JobStatusTest.java
@@ -660,15 +660,19 @@
                 new JobInfo.Builder(101, new ComponentName("foo", "bar")).build());
 
         markImplicitConstraintsSatisfied(job, false);
-        job.setBackgroundNotRestrictedConstraintSatisfied(sElapsedRealtimeClock.millis(), false);
+        job.setBackgroundNotRestrictedConstraintSatisfied(
+                sElapsedRealtimeClock.millis(), false, false);
         assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_BACKGROUND_NOT_RESTRICTED));
-        job.setBackgroundNotRestrictedConstraintSatisfied(sElapsedRealtimeClock.millis(), true);
+        job.setBackgroundNotRestrictedConstraintSatisfied(
+                sElapsedRealtimeClock.millis(), true, false);
         assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_BACKGROUND_NOT_RESTRICTED));
 
         markImplicitConstraintsSatisfied(job, true);
-        job.setBackgroundNotRestrictedConstraintSatisfied(sElapsedRealtimeClock.millis(), false);
+        job.setBackgroundNotRestrictedConstraintSatisfied(
+                sElapsedRealtimeClock.millis(), false, false);
         assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_BACKGROUND_NOT_RESTRICTED));
-        job.setBackgroundNotRestrictedConstraintSatisfied(sElapsedRealtimeClock.millis(), true);
+        job.setBackgroundNotRestrictedConstraintSatisfied(
+                sElapsedRealtimeClock.millis(), true, false);
         assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_BACKGROUND_NOT_RESTRICTED));
     }
 
@@ -677,7 +681,7 @@
         job.setDeviceNotDozingConstraintSatisfied(
                 sElapsedRealtimeClock.millis(), isSatisfied, false);
         job.setBackgroundNotRestrictedConstraintSatisfied(
-                sElapsedRealtimeClock.millis(), isSatisfied);
+                sElapsedRealtimeClock.millis(), isSatisfied, false);
     }
 
     private static JobStatus createJobStatus(long earliestRunTimeElapsedMillis,
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 f73af53..4bab8e5 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
@@ -384,7 +384,8 @@
         // Make sure Doze and background-not-restricted don't affect tests.
         js.setDeviceNotDozingConstraintSatisfied(/* nowElapsed */ sElapsedRealtimeClock.millis(),
                 /* state */ true, /* allowlisted */false);
-        js.setBackgroundNotRestrictedConstraintSatisfied(sElapsedRealtimeClock.millis(), true);
+        js.setBackgroundNotRestrictedConstraintSatisfied(
+                sElapsedRealtimeClock.millis(), true, false);
         return js;
     }
 
@@ -5415,9 +5416,8 @@
         inOrder.verify(mJobSchedulerService,
                 timeout(remainingTimeMs / 2 + 2 * SECOND_IN_MILLIS).times(1))
                 .onControllerStateChanged();
-        // Top and bg EJs should still be allowed to run since they started before the app ran
-        // out of quota.
-        assertTrue(jobBg.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_EXPEDITED_QUOTA));
+        // Top should still be "in quota" since it started before the app ran on top out of quota.
+        assertFalse(jobBg.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_EXPEDITED_QUOTA));
         assertTrue(jobTop.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_EXPEDITED_QUOTA));
         assertFalse(
                 jobUnstarted.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_EXPEDITED_QUOTA));
@@ -5466,7 +5466,7 @@
         // wasn't started. Top should remain in quota since it started when the app was in TOP.
         assertTrue(jobTop2.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_EXPEDITED_QUOTA));
         assertFalse(jobFg.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_EXPEDITED_QUOTA));
-        assertTrue(jobBg.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_EXPEDITED_QUOTA));
+        assertFalse(jobBg.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_EXPEDITED_QUOTA));
         trackJobs(jobBg2);
         assertFalse(jobBg2.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_EXPEDITED_QUOTA));
         assertFalse(
diff --git a/services/tests/mockingservicestests/src/com/android/server/location/injector/FakeLocationPowerSaveModeHelper.java b/services/tests/mockingservicestests/src/com/android/server/location/injector/FakeLocationPowerSaveModeHelper.java
index 0597443..ef48646 100644
--- a/services/tests/mockingservicestests/src/com/android/server/location/injector/FakeLocationPowerSaveModeHelper.java
+++ b/services/tests/mockingservicestests/src/com/android/server/location/injector/FakeLocationPowerSaveModeHelper.java
@@ -19,8 +19,6 @@
 import android.os.IPowerManager;
 import android.os.PowerManager.LocationPowerSaveMode;
 
-import com.android.server.location.eventlog.LocationEventLog;
-
 /**
  * Version of LocationPowerSaveModeHelper for testing. Power save mode is initialized as "no
  * change".
@@ -30,8 +28,7 @@
     @LocationPowerSaveMode
     private int mLocationPowerSaveMode;
 
-    public FakeLocationPowerSaveModeHelper(LocationEventLog locationEventLog) {
-        super(locationEventLog);
+    public FakeLocationPowerSaveModeHelper() {
         mLocationPowerSaveMode = IPowerManager.LOCATION_MODE_NO_CHANGE;
     }
 
diff --git a/services/tests/mockingservicestests/src/com/android/server/location/injector/SystemLocationPowerSaveModeHelperTest.java b/services/tests/mockingservicestests/src/com/android/server/location/injector/SystemLocationPowerSaveModeHelperTest.java
index 6156ba9..28da027 100644
--- a/services/tests/mockingservicestests/src/com/android/server/location/injector/SystemLocationPowerSaveModeHelperTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/location/injector/SystemLocationPowerSaveModeHelperTest.java
@@ -43,7 +43,6 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.server.LocalServices;
-import com.android.server.location.eventlog.LocationEventLog;
 import com.android.server.location.injector.LocationPowerSaveModeHelper.LocationPowerSaveModeChangedListener;
 
 import org.junit.After;
@@ -85,7 +84,7 @@
         Context context = mock(Context.class);
         doReturn(powerManager).when(context).getSystemService(PowerManager.class);
 
-        mHelper = new SystemLocationPowerSaveModeHelper(context, new LocationEventLog());
+        mHelper = new SystemLocationPowerSaveModeHelper(context);
         mHelper.onSystemReady();
     }
 
diff --git a/services/tests/mockingservicestests/src/com/android/server/location/injector/TestInjector.java b/services/tests/mockingservicestests/src/com/android/server/location/injector/TestInjector.java
index 1f102ac..ae70dad 100644
--- a/services/tests/mockingservicestests/src/com/android/server/location/injector/TestInjector.java
+++ b/services/tests/mockingservicestests/src/com/android/server/location/injector/TestInjector.java
@@ -16,8 +16,6 @@
 
 package com.android.server.location.injector;
 
-import com.android.server.location.eventlog.LocationEventLog;
-
 public class TestInjector implements Injector {
 
     private final FakeUserInfoHelper mUserInfoHelper;
@@ -35,17 +33,13 @@
     private final LocationUsageLogger mLocationUsageLogger;
 
     public TestInjector() {
-        this(new LocationEventLog());
-    }
-
-    public TestInjector(LocationEventLog eventLog) {
         mUserInfoHelper = new FakeUserInfoHelper();
         mAlarmHelper = new FakeAlarmHelper();
         mAppOpsHelper = new FakeAppOpsHelper();
         mLocationPermissionsHelper = new FakeLocationPermissionsHelper(mAppOpsHelper);
         mSettingsHelper = new FakeSettingsHelper();
         mAppForegroundHelper = new FakeAppForegroundHelper();
-        mLocationPowerSaveModeHelper = new FakeLocationPowerSaveModeHelper(eventLog);
+        mLocationPowerSaveModeHelper = new FakeLocationPowerSaveModeHelper();
         mScreenInteractiveHelper = new FakeScreenInteractiveHelper();
         mDeviceStationaryHelper = new FakeDeviceStationaryHelper();
         mDeviceIdleHelper = new FakeDeviceIdleHelper();
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 1b58e92..24b85f0 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
@@ -83,7 +83,6 @@
 
 import com.android.server.FgThread;
 import com.android.server.LocalServices;
-import com.android.server.location.eventlog.LocationEventLog;
 import com.android.server.location.injector.FakeUserInfoHelper;
 import com.android.server.location.injector.TestInjector;
 
@@ -161,19 +160,17 @@
         doReturn(mPowerManager).when(mContext).getSystemService(PowerManager.class);
         doReturn(mWakeLock).when(mPowerManager).newWakeLock(anyInt(), anyString());
 
-        LocationEventLog eventLog = new LocationEventLog();
-
-        mInjector = new TestInjector(eventLog);
+        mInjector = new TestInjector();
         mInjector.getUserInfoHelper().startUser(OTHER_USER);
 
-        mPassive = new PassiveLocationProviderManager(mContext, mInjector, eventLog);
+        mPassive = new PassiveLocationProviderManager(mContext, mInjector);
         mPassive.startManager();
         mPassive.setRealProvider(new PassiveLocationProvider(mContext));
 
         mProvider = new TestProvider(PROPERTIES, PROVIDER_IDENTITY);
         mProvider.setProviderAllowed(true);
 
-        mManager = new LocationProviderManager(mContext, mInjector, eventLog, NAME, mPassive);
+        mManager = new LocationProviderManager(mContext, mInjector, NAME, mPassive);
         mManager.startManager();
         mManager.setRealProvider(mProvider);
     }
diff --git a/services/tests/mockingservicestests/src/com/android/server/location/provider/StationaryThrottlingLocationProviderTest.java b/services/tests/mockingservicestests/src/com/android/server/location/provider/StationaryThrottlingLocationProviderTest.java
index c3cca64..04e0151 100644
--- a/services/tests/mockingservicestests/src/com/android/server/location/provider/StationaryThrottlingLocationProviderTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/location/provider/StationaryThrottlingLocationProviderTest.java
@@ -36,7 +36,6 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
-import com.android.server.location.eventlog.LocationEventLog;
 import com.android.server.location.injector.TestInjector;
 import com.android.server.location.test.FakeProvider;
 
@@ -77,7 +76,7 @@
         mDelegateProvider = new FakeProvider(mDelegate);
 
         mProvider = new StationaryThrottlingLocationProvider("test_provider", mInjector,
-                mDelegateProvider, new LocationEventLog());
+                mDelegateProvider);
         mProvider.getController().setListener(mListener);
         mProvider.getController().start();
     }
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 17c6b6f..db0c3ae 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt
@@ -36,6 +36,7 @@
 import android.os.UserHandle
 import android.os.UserManager
 import android.os.incremental.IncrementalManager
+import android.provider.DeviceConfig
 import android.util.ArrayMap
 import android.util.DisplayMetrics
 import android.util.EventLog
@@ -131,6 +132,7 @@
                 .mockStatic(LockGuard::class.java)
                 .mockStatic(EventLog::class.java)
                 .mockStatic(LocalServices::class.java)
+                .mockStatic(DeviceConfig::class.java)
                 .apply(withSession)
         session = apply.startMocking()
         whenever(mocks.settings.insertPackageSettingLPw(
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 a0e208f..46487ea2 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/PackageManagerServiceHibernationTests.kt
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/PackageManagerServiceHibernationTests.kt
@@ -17,8 +17,13 @@
 package com.android.server.pm
 
 import android.os.Build
+import android.provider.DeviceConfig
+import android.provider.DeviceConfig.NAMESPACE_APP_HIBERNATION
 import com.android.server.apphibernation.AppHibernationManagerInternal
+import com.android.server.extendedtestutils.wheneverStatic
 import com.android.server.testutils.whenever
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertTrue
 import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
@@ -33,7 +38,10 @@
 
     companion object {
         val TEST_PACKAGE_NAME = "test.package"
+        val TEST_PACKAGE_2_NAME = "test.package2"
         val TEST_USER_ID = 0
+
+        val KEY_APP_HIBERNATION_ENABLED = "app_hibernation_enabled"
     }
 
     @Rule
@@ -47,6 +55,8 @@
     @Throws(Exception::class)
     fun setup() {
         MockitoAnnotations.initMocks(this)
+        wheneverStatic { DeviceConfig.getBoolean(
+            NAMESPACE_APP_HIBERNATION, KEY_APP_HIBERNATION_ENABLED, false) }.thenReturn(true)
         rule.system().stageNominalSystemState()
         whenever(rule.mocks().injector.getLocalService(AppHibernationManagerInternal::class.java))
             .thenReturn(appHibernationManager)
@@ -68,6 +78,28 @@
         verify(appHibernationManager).setHibernatingGlobally(TEST_PACKAGE_NAME, false)
     }
 
+    @Test
+    fun testGetOptimizablePackages_ExcludesGloballyHibernatingPackages() {
+        rule.system().stageScanExistingPackage(
+            TEST_PACKAGE_NAME,
+            1L,
+            rule.system().dataAppDirectory,
+            withPackage = { it.apply { isHasCode = true } })
+        rule.system().stageScanExistingPackage(
+            TEST_PACKAGE_2_NAME,
+            1L,
+            rule.system().dataAppDirectory,
+            withPackage = { it.apply { isHasCode = true } })
+        val pm = createPackageManagerService()
+        rule.system().validateFinalState()
+        whenever(appHibernationManager.isHibernatingGlobally(TEST_PACKAGE_2_NAME)).thenReturn(true)
+
+        val optimizablePkgs = pm.optimizablePackages
+
+        assertTrue(optimizablePkgs.contains(TEST_PACKAGE_NAME))
+        assertFalse(optimizablePkgs.contains(TEST_PACKAGE_2_NAME))
+    }
+
     private fun createPackageManagerService(): PackageManagerService {
         return PackageManagerService(rule.mocks().injector,
             false /*coreOnly*/,
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/SuspendPackagesBroadcastTest.kt b/services/tests/mockingservicestests/src/com/android/server/pm/SuspendPackagesBroadcastTest.kt
new file mode 100644
index 0000000..7a6110b
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/SuspendPackagesBroadcastTest.kt
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.pm
+
+import android.content.Intent
+import android.os.Build
+import android.os.Bundle
+import android.util.SparseArray
+import com.android.server.testutils.any
+import com.android.server.testutils.eq
+import com.android.server.testutils.nullable
+import com.android.server.testutils.whenever
+import com.android.server.utils.WatchedArrayMap
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import org.mockito.ArgumentCaptor
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.Captor
+import org.mockito.Mockito.spy
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@RunWith(JUnit4::class)
+class SuspendPackagesBroadcastTest {
+
+    companion object {
+        const val TEST_PACKAGE_1 = "com.android.test.package1"
+        const val TEST_PACKAGE_2 = "com.android.test.package2"
+        const val TEST_USER_ID = 0
+    }
+
+    lateinit var pms: PackageManagerService
+    lateinit var packageSetting1: PackageSetting
+    lateinit var packageSetting2: PackageSetting
+    lateinit var packagesToSuspend: Array<String>
+    lateinit var uidsToSuspend: IntArray
+
+    @Captor
+    lateinit var bundleCaptor: ArgumentCaptor<Bundle>
+
+    @Rule
+    @JvmField
+    val rule = MockSystemRule()
+
+    @Before
+    @Throws(Exception::class)
+    fun setup() {
+        MockitoAnnotations.initMocks(this)
+        rule.system().stageNominalSystemState()
+        pms = spy(createPackageManagerService(TEST_PACKAGE_1, TEST_PACKAGE_2))
+        packageSetting1 = pms.getPackageSetting(TEST_PACKAGE_1)!!
+        packageSetting2 = pms.getPackageSetting(TEST_PACKAGE_2)!!
+        packagesToSuspend = arrayOf(TEST_PACKAGE_1, TEST_PACKAGE_2)
+        uidsToSuspend = intArrayOf(packageSetting1.appId, packageSetting2.appId)
+    }
+
+    @Test
+    @Throws(Exception::class)
+    fun sendPackagesSuspendedForUser_withSameVisibilityAllowList() {
+        mockAllowList(packageSetting1, allowList(10001, 10002, 10003))
+        mockAllowList(packageSetting2, allowList(10001, 10002, 10003))
+
+        pms.sendPackagesSuspendedForUser(
+                packagesToSuspend, uidsToSuspend, TEST_USER_ID, /* suspended = */ true)
+        verify(pms).sendPackageBroadcast(any(), nullable(), bundleCaptor.capture(),
+                anyInt(), nullable(), nullable(), any(), nullable(), any(), nullable())
+
+        var changedPackages = bundleCaptor.value.getStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST)
+        var changedUids = bundleCaptor.value.getIntArray(Intent.EXTRA_CHANGED_UID_LIST)
+        assertThat(changedPackages).asList().containsExactly(TEST_PACKAGE_1, TEST_PACKAGE_2)
+        assertThat(changedUids).asList().containsExactly(
+                packageSetting1.appId, packageSetting2.appId)
+    }
+
+    @Test
+    @Throws(Exception::class)
+    fun sendPackagesSuspendedForUser_withDifferentVisibilityAllowList() {
+        mockAllowList(packageSetting1, allowList(10001, 10002, 10003))
+        mockAllowList(packageSetting2, allowList(10001, 10002, 10007))
+
+        pms.sendPackagesSuspendedForUser(
+                packagesToSuspend, uidsToSuspend, TEST_USER_ID, /* suspended = */ true)
+        verify(pms, times(2)).sendPackageBroadcast(any(), nullable(), bundleCaptor.capture(),
+                anyInt(), nullable(), nullable(), any(), nullable(), any(), nullable())
+
+        bundleCaptor.allValues.forEach {
+            var changedPackages = it.getStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST)
+            var changedUids = it.getIntArray(Intent.EXTRA_CHANGED_UID_LIST)
+            assertThat(changedPackages?.size).isEqualTo(1)
+            assertThat(changedUids?.size).isEqualTo(1)
+            assertThat(changedPackages?.get(0)).isAnyOf(TEST_PACKAGE_1, TEST_PACKAGE_2)
+            assertThat(changedUids?.get(0)).isAnyOf(packageSetting1.appId, packageSetting2.appId)
+        }
+    }
+
+    @Test
+    @Throws(Exception::class)
+    fun sendPackagesSuspendedForUser_withNullVisibilityAllowList() {
+        mockAllowList(packageSetting1, allowList(10001, 10002, 10003))
+        mockAllowList(packageSetting2, null)
+
+        pms.sendPackagesSuspendedForUser(
+                packagesToSuspend, uidsToSuspend, TEST_USER_ID, /* suspended = */ true)
+        verify(pms, times(2)).sendPackageBroadcast(any(), nullable(), bundleCaptor.capture(),
+                anyInt(), nullable(), nullable(), any(), nullable(), nullable(), nullable())
+
+        bundleCaptor.allValues.forEach {
+            var changedPackages = it.getStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST)
+            var changedUids = it.getIntArray(Intent.EXTRA_CHANGED_UID_LIST)
+            assertThat(changedPackages?.size).isEqualTo(1)
+            assertThat(changedUids?.size).isEqualTo(1)
+            assertThat(changedPackages?.get(0)).isAnyOf(TEST_PACKAGE_1, TEST_PACKAGE_2)
+            assertThat(changedUids?.get(0)).isAnyOf(packageSetting1.appId, packageSetting2.appId)
+        }
+    }
+
+    private fun allowList(vararg uids: Int) = SparseArray<IntArray>().apply {
+        this.put(TEST_USER_ID, uids)
+    }
+
+    private fun mockAllowList(pkgSetting: PackageSetting, list: SparseArray<IntArray>?) {
+        whenever(rule.mocks().injector.appsFilter.getVisibilityAllowList(eq(pkgSetting),
+                any(IntArray::class.java), any() as WatchedArrayMap<String, PackageSetting>))
+                .thenReturn(list)
+    }
+
+    private fun createPackageManagerService(vararg stageExistingPackages: String):
+            PackageManagerService {
+        stageExistingPackages.forEach {
+            rule.system().stageScanExistingPackage(it, 1L,
+                    rule.system().dataAppDirectory)
+        }
+        var pms = PackageManagerService(rule.mocks().injector,
+                false /*coreOnly*/,
+                false /*factoryTest*/,
+                MockSystem.DEFAULT_VERSION_INFO.fingerprint,
+                false /*isEngBuild*/,
+                false /*isUserDebugBuild*/,
+                Build.VERSION_CODES.CUR_DEVELOPMENT,
+                Build.VERSION.INCREMENTAL)
+        rule.system().validateFinalState()
+        return pms
+    }
+}
diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml
index b9aa554..9513c6e 100644
--- a/services/tests/servicestests/AndroidManifest.xml
+++ b/services/tests/servicestests/AndroidManifest.xml
@@ -70,10 +70,14 @@
     <uses-permission android:name="android.permission.CONTROL_KEYGUARD"/>
     <uses-permission android:name="android.permission.MANAGE_BIND_INSTANT_SERVICE"/>
     <uses-permission android:name="android.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS"/>
+    <uses-permission android:name="android.permission.CONTROL_DISPLAY_BRIGHTNESS"/>
     <uses-permission android:name="android.permission.READ_DEVICE_CONFIG"/>
     <uses-permission android:name="android.permission.WRITE_DEVICE_CONFIG"/>
     <uses-permission android:name="android.permission.HARDWARE_TEST"/>
     <uses-permission android:name="android.permission.BLUETOOTH"/>
+    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
+    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>
+    <uses-permission android:name="android.permission.BLUETOOTH_SCAN"/>
     <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/>
     <uses-permission android:name="android.permission.DUMP"/>
     <uses-permission android:name="android.permission.READ_DREAM_STATE"/>
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 29691fb..502f64a 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
@@ -16,7 +16,7 @@
 
 package com.android.server.accessibility.magnification;
 
-import static com.android.server.accessibility.magnification.FullScreenMagnificationController.MagnificationRequestObserver;
+import static com.android.server.accessibility.magnification.FullScreenMagnificationController.MagnificationInfoChangedCallback;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -96,8 +96,8 @@
     final WindowManagerInternal mMockWindowManager = mock(WindowManagerInternal.class);
     private final MagnificationAnimationCallback mAnimationCallback = mock(
             MagnificationAnimationCallback.class);
-    private final MagnificationRequestObserver mRequestObserver = mock(
-            MagnificationRequestObserver.class);
+    private final MagnificationInfoChangedCallback mRequestObserver = mock(
+            MagnificationInfoChangedCallback.class);
     final MessageCapturingHandler mMessageCapturingHandler = new MessageCapturingHandler(null);
 
     ValueAnimator mMockValueAnimator;
@@ -1145,6 +1145,15 @@
         verify(mRequestObserver).onFullScreenMagnificationActivationState(eq(false));
     }
 
+    @Test
+    public void testImeWindowIsShown_serviceNotified() {
+        register(DISPLAY_0);
+        MagnificationCallbacks callbacks = getMagnificationCallbacks(DISPLAY_0);
+        callbacks.onImeWindowVisibilityChanged(true);
+        mMessageCapturingHandler.sendAllMessages();
+        verify(mRequestObserver).onImeWindowVisibilityChanged(eq(true));
+    }
+
     private void setScaleToMagnifying() {
         register(DISPLAY_0);
         float scale = 2.0f;
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java
index 28a6ff7..f881f04 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java
@@ -53,7 +53,7 @@
 
 import com.android.server.accessibility.AccessibilityManagerService;
 import com.android.server.accessibility.EventStreamTransformation;
-import com.android.server.accessibility.magnification.FullScreenMagnificationController.MagnificationRequestObserver;
+import com.android.server.accessibility.magnification.FullScreenMagnificationController.MagnificationInfoChangedCallback;
 import com.android.server.testutils.OffsettableClock;
 import com.android.server.testutils.TestHandler;
 import com.android.server.wm.WindowManagerInternal;
@@ -126,7 +126,7 @@
     @Mock
     MagnificationGestureHandler.Callback mMockCallback;
     @Mock
-    MagnificationRequestObserver mMagnificationRequestObserver;
+    MagnificationInfoChangedCallback mMagnificationInfoChangedCallback;
     @Mock
     WindowMagnificationPromptController mWindowMagnificationPromptController;
 
@@ -151,7 +151,7 @@
         when(mockController.getAnimationDuration()).thenReturn(1000L);
         when(mockWindowManager.setMagnificationCallbacks(eq(DISPLAY_0), any())).thenReturn(true);
         mFullScreenMagnificationController = new FullScreenMagnificationController(mockController,
-                new Object(), mMagnificationRequestObserver) {
+                new Object(), mMagnificationInfoChangedCallback) {
             @Override
             public boolean magnificationRegionContains(int displayId, float x, float y) {
                 return true;
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 cf23197..3dff36e 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
@@ -486,6 +486,47 @@
                 eq(MODE_WINDOW));
     }
 
+    @Test
+    public void imeWindowStateShown_windowMagnifying_logWindowMode() {
+        mMagnificationController.onWindowMagnificationActivationState(true);
+
+        mMagnificationController.onImeWindowVisibilityChanged(true);
+
+        verify(mMagnificationController).logMagnificationModeWithIme(
+                eq(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW));
+    }
+
+    @Test
+    public void imeWindowStateShown_fullScreenMagnifying_logFullScreenMode() {
+        mMagnificationController.onFullScreenMagnificationActivationState(true);
+
+        mMagnificationController.onImeWindowVisibilityChanged(true);
+
+        verify(mMagnificationController).logMagnificationModeWithIme(
+                eq(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN));
+    }
+
+    @Test
+    public void imeWindowStateShown_noMagnifying_noLogAnyMode() {
+        mMagnificationController.onImeWindowVisibilityChanged(true);
+
+        verify(mMagnificationController, never()).logMagnificationModeWithIme(anyInt());
+    }
+
+    @Test
+    public void imeWindowStateHidden_windowMagnifying_noLogAnyMode() {
+        mMagnificationController.onFullScreenMagnificationActivationState(true);
+
+        verify(mMagnificationController, never()).logMagnificationModeWithIme(anyInt());
+    }
+
+    @Test
+    public void imeWindowStateHidden_fullScreenMagnifying_noLogAnyMode() {
+        mMagnificationController.onWindowMagnificationActivationState(true);
+
+        verify(mMagnificationController, never()).logMagnificationModeWithIme(anyInt());
+    }
+
     private void setMagnificationEnabled(int mode) throws RemoteException {
 
         setMagnificationEnabled(mode, MAGNIFIED_CENTER_X, MAGNIFIED_CENTER_Y);
diff --git a/services/tests/servicestests/src/com/android/server/am/BatteryExternalStatsWorkerTest.java b/services/tests/servicestests/src/com/android/server/am/BatteryExternalStatsWorkerTest.java
index 73a2feb..4a67ec7 100644
--- a/services/tests/servicestests/src/com/android/server/am/BatteryExternalStatsWorkerTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/BatteryExternalStatsWorkerTest.java
@@ -20,6 +20,7 @@
 import static com.android.internal.os.BatteryStatsImpl.ExternalStatsSync.UPDATE_BT;
 import static com.android.internal.os.BatteryStatsImpl.ExternalStatsSync.UPDATE_CPU;
 import static com.android.internal.os.BatteryStatsImpl.ExternalStatsSync.UPDATE_DISPLAY;
+import static com.android.internal.os.BatteryStatsImpl.ExternalStatsSync.UPDATE_RADIO;
 import static com.android.internal.os.BatteryStatsImpl.ExternalStatsSync.UPDATE_WIFI;
 
 import static org.junit.Assert.assertArrayEquals;
@@ -93,6 +94,16 @@
         tempAllIds.add(btId);
         mPowerStatsInternal.incrementEnergyConsumption(btId, 34567);
 
+        final int gnssId = mPowerStatsInternal.addEnergyConsumer(EnergyConsumerType.GNSS, 0,
+                "gnss");
+        tempAllIds.add(gnssId);
+        mPowerStatsInternal.incrementEnergyConsumption(gnssId, 787878);
+
+        final int mobileRadioId = mPowerStatsInternal.addEnergyConsumer(
+                EnergyConsumerType.MOBILE_RADIO, 0, "mobile_radio");
+        tempAllIds.add(mobileRadioId);
+        mPowerStatsInternal.incrementEnergyConsumption(mobileRadioId, 62626);
+
         final int[] cpuClusterIds = new int[numCpuClusters];
         for (int i = 0; i < numCpuClusters; i++) {
             cpuClusterIds[i] = mPowerStatsInternal.addEnergyConsumer(
@@ -135,6 +146,12 @@
         assertEquals(1, bluetoothResults.length);
         assertEquals(btId, bluetoothResults[0].id);
 
+        final EnergyConsumerResult[] mobileRadioResults =
+                mBatteryExternalStatsWorker.getMeasuredEnergyLocked(UPDATE_RADIO).getNow(null);
+        // Results should only have the mobile radio energy consumer
+        assertEquals(1, mobileRadioResults.length);
+        assertEquals(mobileRadioId, mobileRadioResults[0].id);
+
         final EnergyConsumerResult[] cpuResults =
                 mBatteryExternalStatsWorker.getMeasuredEnergyLocked(UPDATE_CPU).getNow(null);
         // Results should only have the cpu cluster energy consumers
diff --git a/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java b/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
index 9ffb5017..5c8a7d2 100644
--- a/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
@@ -80,6 +80,7 @@
 
 import androidx.test.filters.SmallTest;
 
+import com.android.internal.widget.LockPatternUtils;
 import com.android.server.FgThread;
 import com.android.server.am.UserState.KeyEvictedCallback;
 import com.android.server.pm.UserManagerInternal;
@@ -123,6 +124,7 @@
     private static final long HANDLER_WAIT_TIME_MS = 100;
 
     private UserController mUserController;
+    private LockPatternUtils mLockPatternUtils;
     private TestInjector mInjector;
     private final HashMap<Integer, UserState> mUserStates = new HashMap<>();
 
@@ -161,6 +163,13 @@
             doNothing().when(mInjector).activityManagerOnUserStopped(anyInt());
             doNothing().when(mInjector).clearBroadcastQueueForUser(anyInt());
             doNothing().when(mInjector).taskSupervisorRemoveUser(anyInt());
+
+            // Make it appear that calling unlockUserKey() is needed.
+            doReturn(true).when(mInjector).isFileEncryptedNativeOnly();
+            mLockPatternUtils = mock(LockPatternUtils.class);
+            when(mLockPatternUtils.isSecure(anyInt())).thenReturn(false);
+            doReturn(mLockPatternUtils).when(mInjector).getLockPatternUtils();
+
             // All UserController params are set to default.
             mUserController = new UserController(mInjector);
             setUpUser(TEST_USER_ID, NO_USERINFO_FLAGS);
@@ -552,6 +561,20 @@
                 /* keyEvictedCallback= */ mKeyEvictedCallback, /* expectLocking= */ true);
     }
 
+    /**
+     * Test that if a user has a lock screen credential set, then UserController
+     * doesn't bother trying to unlock their storage key without a credential
+     * token, as it will never work.
+     */
+    @Test
+    public void testSecureUserUnlockNotAttempted() throws Exception {
+        when(mLockPatternUtils.isSecure(eq(TEST_USER_ID1))).thenReturn(true);
+        setUpUser(TEST_USER_ID1, 0);
+        mUserController.startUser(TEST_USER_ID1, /* foreground= */ false);
+        verify(mInjector.mStorageManagerMock, times(0))
+                .unlockUserKey(eq(TEST_USER_ID1), anyInt(), any(), any());
+    }
+
     @Test
     public void testStartProfile_fullUserFails() {
         setUpUser(TEST_USER_ID1, 0);
diff --git a/services/tests/servicestests/src/com/android/server/app/GameManagerServiceTests.java b/services/tests/servicestests/src/com/android/server/app/GameManagerServiceTests.java
index 3d0895d..24a8b61 100644
--- a/services/tests/servicestests/src/com/android/server/app/GameManagerServiceTests.java
+++ b/services/tests/servicestests/src/com/android/server/app/GameManagerServiceTests.java
@@ -49,14 +49,18 @@
     private static final int USER_ID_2 = 1002;
 
     // Stolen from ConnectivityServiceTest.MockContext
-    class MockContext extends ContextWrapper {
+    static class MockContext extends ContextWrapper {
         private static final String TAG = "MockContext";
 
         // Map of permission name -> PermissionManager.Permission_{GRANTED|DENIED} constant
         private final HashMap<String, Integer> mMockedPermissions = new HashMap<>();
 
+        @Mock
+        private final MockPackageManager mMockPackageManager;
+
         MockContext(Context base) {
             super(base);
+            mMockPackageManager = new MockPackageManager();
         }
 
         /**
@@ -101,6 +105,11 @@
                 throw new SecurityException("[Test] permission denied: " + permission);
             }
         }
+
+        @Override
+        public PackageManager getPackageManager() {
+            return mMockPackageManager;
+        }
     }
 
     @Mock
diff --git a/services/tests/servicestests/src/com/android/server/app/MockPackageManager.java b/services/tests/servicestests/src/com/android/server/app/MockPackageManager.java
new file mode 100644
index 0000000..5edbc16
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/app/MockPackageManager.java
@@ -0,0 +1,1133 @@
+/*
+ * 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.app;
+
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.IntentSender;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.ChangedPackages;
+import android.content.pm.FeatureInfo;
+import android.content.pm.IPackageDataObserver;
+import android.content.pm.IPackageDeleteObserver;
+import android.content.pm.IPackageStatsObserver;
+import android.content.pm.InstantAppInfo;
+import android.content.pm.InstrumentationInfo;
+import android.content.pm.IntentFilterVerificationInfo;
+import android.content.pm.KeySet;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageInstaller;
+import android.content.pm.PackageItemInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PermissionGroupInfo;
+import android.content.pm.PermissionInfo;
+import android.content.pm.ProviderInfo;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.content.pm.SharedLibraryInfo;
+import android.content.pm.VerifierDeviceIdentity;
+import android.content.pm.VersionedPackage;
+import android.content.res.Resources;
+import android.content.res.XmlResourceParser;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.os.Handler;
+import android.os.UserHandle;
+import android.os.storage.VolumeInfo;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import java.util.List;
+
+public class MockPackageManager extends PackageManager {
+    private static final String TAG = "MockPackageManager";
+
+    private final ApplicationInfo mApplicationInfo = new ApplicationInfo();
+
+    public MockPackageManager() {
+        // Mock the ApplicationInfo, so we can treat the test as a "game".
+        mApplicationInfo.category = ApplicationInfo.CATEGORY_GAME;
+    }
+
+    @Override
+    public PackageInfo getPackageInfo(@NonNull String packageName, int flags)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public PackageInfo getPackageInfo(@NonNull VersionedPackage versionedPackage, int flags)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public PackageInfo getPackageInfoAsUser(@NonNull String packageName, int flags, int userId)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public String[] currentToCanonicalPackageNames(@NonNull String[] packageNames) {
+        return new String[0];
+    }
+
+    @Override
+    public String[] canonicalToCurrentPackageNames(@NonNull String[] packageNames) {
+        return new String[0];
+    }
+
+    @Nullable
+    @Override
+    public Intent getLaunchIntentForPackage(@NonNull String packageName) {
+        return null;
+    }
+
+    @Nullable
+    @Override
+    public Intent getLeanbackLaunchIntentForPackage(@NonNull String packageName) {
+        return null;
+    }
+
+    @Nullable
+    @Override
+    public Intent getCarLaunchIntentForPackage(@NonNull String packageName) {
+        return null;
+    }
+
+    @Override
+    public int[] getPackageGids(@NonNull String packageName) throws NameNotFoundException {
+        return new int[0];
+    }
+
+    @Override
+    public int[] getPackageGids(@NonNull String packageName, int flags)
+            throws NameNotFoundException {
+        return new int[0];
+    }
+
+    @Override
+    public int getPackageUid(@NonNull String packageName, int flags)
+            throws NameNotFoundException {
+        return 0;
+    }
+
+    @Override
+    public int getPackageUidAsUser(@NonNull String packageName, int userId)
+            throws NameNotFoundException {
+        return 0;
+    }
+
+    @Override
+    public int getPackageUidAsUser(@NonNull String packageName, int flags, int userId)
+            throws NameNotFoundException {
+        return 0;
+    }
+
+    @Override
+    public PermissionInfo getPermissionInfo(@NonNull String permName, int flags)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @NonNull
+    @Override
+    public List<PermissionInfo> queryPermissionsByGroup(@NonNull String permissionGroup,
+            int flags) throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public boolean arePermissionsIndividuallyControlled() {
+        return false;
+    }
+
+    @Override
+    public boolean isWirelessConsentModeEnabled() {
+        return false;
+    }
+
+    @NonNull
+    @Override
+    public PermissionGroupInfo getPermissionGroupInfo(@NonNull String groupName, int flags)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @NonNull
+    @Override
+    public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
+        return null;
+    }
+
+    @NonNull
+    @Override
+    public ApplicationInfo getApplicationInfo(@NonNull String packageName, int flags)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @NonNull
+    @Override
+    public ApplicationInfo getApplicationInfoAsUser(@NonNull String packageName, int flags,
+            int userId) throws NameNotFoundException {
+        return mApplicationInfo;
+    }
+
+    @NonNull
+    @Override
+    public ActivityInfo getActivityInfo(@NonNull ComponentName component, int flags)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @NonNull
+    @Override
+    public ActivityInfo getReceiverInfo(@NonNull ComponentName component, int flags)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @NonNull
+    @Override
+    public ServiceInfo getServiceInfo(@NonNull ComponentName component, int flags)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @NonNull
+    @Override
+    public ProviderInfo getProviderInfo(@NonNull ComponentName component, int flags)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @NonNull
+    @Override
+    public List<PackageInfo> getInstalledPackages(int flags) {
+        return null;
+    }
+
+    @NonNull
+    @Override
+    public List<PackageInfo> getPackagesHoldingPermissions(@NonNull String[] permissions,
+            int flags) {
+        return null;
+    }
+
+    @NonNull
+    @Override
+    public List<PackageInfo> getInstalledPackagesAsUser(int flags, int userId) {
+        return null;
+    }
+
+    @Override
+    public int checkPermission(@NonNull String permName, @NonNull String packageName) {
+        return 0;
+    }
+
+    @Override
+    public boolean isPermissionRevokedByPolicy(@NonNull String permName,
+            @NonNull String packageName) {
+        return false;
+    }
+
+    @Override
+    public boolean addPermission(@NonNull PermissionInfo info) {
+        return false;
+    }
+
+    @Override
+    public boolean addPermissionAsync(@NonNull PermissionInfo info) {
+        return false;
+    }
+
+    @Override
+    public void removePermission(@NonNull String permName) {
+
+    }
+
+    @Override
+    public void grantRuntimePermission(@NonNull String packageName, @NonNull String permName,
+            @NonNull UserHandle user) {
+
+    }
+
+    @Override
+    public void revokeRuntimePermission(@NonNull String packageName, @NonNull String permName,
+            @NonNull UserHandle user) {
+
+    }
+
+    @Override
+    public int getPermissionFlags(@NonNull String permName, @NonNull String packageName,
+            @NonNull UserHandle user) {
+        return 0;
+    }
+
+    @Override
+    public void updatePermissionFlags(@NonNull String permName, @NonNull String packageName,
+            int flagMask, int flagValues, @NonNull UserHandle user) {
+
+    }
+
+    @Override
+    public boolean shouldShowRequestPermissionRationale(@NonNull String permName) {
+        return false;
+    }
+
+    @Override
+    public int checkSignatures(@NonNull String packageName1, @NonNull String packageName2) {
+        return 0;
+    }
+
+    @Override
+    public int checkSignatures(int uid1, int uid2) {
+        return 0;
+    }
+
+    @Nullable
+    @Override
+    public String[] getPackagesForUid(int uid) {
+        return new String[0];
+    }
+
+    @Nullable
+    @Override
+    public String getNameForUid(int uid) {
+        return null;
+    }
+
+    @Nullable
+    @Override
+    public String[] getNamesForUids(int[] uids) {
+        return new String[0];
+    }
+
+    @Override
+    public int getUidForSharedUser(@NonNull String sharedUserName)
+            throws NameNotFoundException {
+        return 0;
+    }
+
+    @NonNull
+    @Override
+    public List<ApplicationInfo> getInstalledApplications(int flags) {
+        return null;
+    }
+
+    @NonNull
+    @Override
+    public List<ApplicationInfo> getInstalledApplicationsAsUser(int flags, int userId) {
+        return null;
+    }
+
+    @NonNull
+    @Override
+    public List<InstantAppInfo> getInstantApps() {
+        return null;
+    }
+
+    @Nullable
+    @Override
+    public Drawable getInstantAppIcon(String packageName) {
+        return null;
+    }
+
+    @Override
+    public boolean isInstantApp() {
+        return false;
+    }
+
+    @Override
+    public boolean isInstantApp(@NonNull String packageName) {
+        return false;
+    }
+
+    @Override
+    public int getInstantAppCookieMaxBytes() {
+        return 0;
+    }
+
+    @Override
+    public int getInstantAppCookieMaxSize() {
+        return 0;
+    }
+
+    @NonNull
+    @Override
+    public byte[] getInstantAppCookie() {
+        return new byte[0];
+    }
+
+    @Override
+    public void clearInstantAppCookie() {
+
+    }
+
+    @Override
+    public void updateInstantAppCookie(@Nullable byte[] cookie) {
+
+    }
+
+    @Override
+    public boolean setInstantAppCookie(@Nullable byte[] cookie) {
+        return false;
+    }
+
+    @Nullable
+    @Override
+    public String[] getSystemSharedLibraryNames() {
+        return new String[0];
+    }
+
+    @NonNull
+    @Override
+    public List<SharedLibraryInfo> getSharedLibraries(int flags) {
+        return null;
+    }
+
+    @NonNull
+    @Override
+    public List<SharedLibraryInfo> getSharedLibrariesAsUser(int flags, int userId) {
+        return null;
+    }
+
+    @NonNull
+    @Override
+    public String getServicesSystemSharedLibraryPackageName() {
+        return null;
+    }
+
+    @NonNull
+    @Override
+    public String getSharedSystemSharedLibraryPackageName() {
+        return null;
+    }
+
+    @Nullable
+    @Override
+    public ChangedPackages getChangedPackages(int sequenceNumber) {
+        return null;
+    }
+
+    @NonNull
+    @Override
+    public FeatureInfo[] getSystemAvailableFeatures() {
+        return new FeatureInfo[0];
+    }
+
+    @Override
+    public boolean hasSystemFeature(@NonNull String featureName) {
+        return false;
+    }
+
+    @Override
+    public boolean hasSystemFeature(@NonNull String featureName, int version) {
+        return false;
+    }
+
+    @Nullable
+    @Override
+    public ResolveInfo resolveActivity(@NonNull Intent intent, int flags) {
+        return null;
+    }
+
+    @Nullable
+    @Override
+    public ResolveInfo resolveActivityAsUser(@NonNull Intent intent, int flags, int userId) {
+        return null;
+    }
+
+    @NonNull
+    @Override
+    public List<ResolveInfo> queryIntentActivities(@NonNull Intent intent, int flags) {
+        return null;
+    }
+
+    @NonNull
+    @Override
+    public List<ResolveInfo> queryIntentActivitiesAsUser(@NonNull Intent intent, int flags,
+            int userId) {
+        return null;
+    }
+
+    @NonNull
+    @Override
+    public List<ResolveInfo> queryIntentActivityOptions(@Nullable ComponentName caller,
+            @Nullable Intent[] specifics, @NonNull Intent intent, int flags) {
+        return null;
+    }
+
+    @NonNull
+    @Override
+    public List<ResolveInfo> queryBroadcastReceivers(@NonNull Intent intent, int flags) {
+        return null;
+    }
+
+    @NonNull
+    @Override
+    public List<ResolveInfo> queryBroadcastReceiversAsUser(@NonNull Intent intent, int flags,
+            int userId) {
+        return null;
+    }
+
+    @Nullable
+    @Override
+    public ResolveInfo resolveService(@NonNull Intent intent, int flags) {
+        return null;
+    }
+
+    @Nullable
+    @Override
+    public ResolveInfo resolveServiceAsUser(@NonNull Intent intent, int flags, int userId) {
+        return null;
+    }
+
+    @NonNull
+    @Override
+    public List<ResolveInfo> queryIntentServices(@NonNull Intent intent, int flags) {
+        return null;
+    }
+
+    @NonNull
+    @Override
+    public List<ResolveInfo> queryIntentServicesAsUser(@NonNull Intent intent, int flags,
+            int userId) {
+        return null;
+    }
+
+    @NonNull
+    @Override
+    public List<ResolveInfo> queryIntentContentProvidersAsUser(@NonNull Intent intent,
+            int flags, int userId) {
+        return null;
+    }
+
+    @NonNull
+    @Override
+    public List<ResolveInfo> queryIntentContentProviders(@NonNull Intent intent, int flags) {
+        return null;
+    }
+
+    @Nullable
+    @Override
+    public ProviderInfo resolveContentProvider(@NonNull String authority, int flags) {
+        return null;
+    }
+
+    @Nullable
+    @Override
+    public ProviderInfo resolveContentProviderAsUser(@NonNull String providerName, int flags,
+            int userId) {
+        return null;
+    }
+
+    @NonNull
+    @Override
+    public List<ProviderInfo> queryContentProviders(@Nullable String processName, int uid,
+            int flags) {
+        return null;
+    }
+
+    @NonNull
+    @Override
+    public InstrumentationInfo getInstrumentationInfo(@NonNull ComponentName className,
+            int flags) throws NameNotFoundException {
+        return null;
+    }
+
+    @NonNull
+    @Override
+    public List<InstrumentationInfo> queryInstrumentation(@NonNull String targetPackage,
+            int flags) {
+        return null;
+    }
+
+    @Nullable
+    @Override
+    public Drawable getDrawable(@NonNull String packageName, int resid,
+            @Nullable ApplicationInfo appInfo) {
+        return null;
+    }
+
+    @NonNull
+    @Override
+    public Drawable getActivityIcon(@NonNull ComponentName activityName)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @NonNull
+    @Override
+    public Drawable getActivityIcon(@NonNull Intent intent) throws NameNotFoundException {
+        return null;
+    }
+
+    @Nullable
+    @Override
+    public Drawable getActivityBanner(@NonNull ComponentName activityName)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Nullable
+    @Override
+    public Drawable getActivityBanner(@NonNull Intent intent) throws NameNotFoundException {
+        return null;
+    }
+
+    @NonNull
+    @Override
+    public Drawable getDefaultActivityIcon() {
+        return null;
+    }
+
+    @NonNull
+    @Override
+    public Drawable getApplicationIcon(@NonNull ApplicationInfo info) {
+        return null;
+    }
+
+    @NonNull
+    @Override
+    public Drawable getApplicationIcon(@NonNull String packageName)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Nullable
+    @Override
+    public Drawable getApplicationBanner(@NonNull ApplicationInfo info) {
+        return null;
+    }
+
+    @Nullable
+    @Override
+    public Drawable getApplicationBanner(@NonNull String packageName)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Nullable
+    @Override
+    public Drawable getActivityLogo(@NonNull ComponentName activityName)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Nullable
+    @Override
+    public Drawable getActivityLogo(@NonNull Intent intent) throws NameNotFoundException {
+        return null;
+    }
+
+    @Nullable
+    @Override
+    public Drawable getApplicationLogo(@NonNull ApplicationInfo info) {
+        return null;
+    }
+
+    @Nullable
+    @Override
+    public Drawable getApplicationLogo(@NonNull String packageName)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @NonNull
+    @Override
+    public Drawable getUserBadgedIcon(@NonNull Drawable drawable, @NonNull UserHandle user) {
+        return null;
+    }
+
+    @NonNull
+    @Override
+    public Drawable getUserBadgedDrawableForDensity(@NonNull Drawable drawable,
+            @NonNull UserHandle user, @Nullable Rect badgeLocation, int badgeDensity) {
+        return null;
+    }
+
+    @Nullable
+    @Override
+    public Drawable getUserBadgeForDensity(@NonNull UserHandle user, int density) {
+        return null;
+    }
+
+    @Nullable
+    @Override
+    public Drawable getUserBadgeForDensityNoBackground(@NonNull UserHandle user, int density) {
+        return null;
+    }
+
+    @NonNull
+    @Override
+    public CharSequence getUserBadgedLabel(@NonNull CharSequence label,
+            @NonNull UserHandle user) {
+        return null;
+    }
+
+    @Nullable
+    @Override
+    public CharSequence getText(@NonNull String packageName, int resid,
+            @Nullable ApplicationInfo appInfo) {
+        return null;
+    }
+
+    @Nullable
+    @Override
+    public XmlResourceParser getXml(@NonNull String packageName, int resid,
+            @Nullable ApplicationInfo appInfo) {
+        return null;
+    }
+
+    @NonNull
+    @Override
+    public CharSequence getApplicationLabel(@NonNull ApplicationInfo info) {
+        return null;
+    }
+
+    @NonNull
+    @Override
+    public Resources getResourcesForActivity(@NonNull ComponentName activityName)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @NonNull
+    @Override
+    public Resources getResourcesForApplication(@NonNull ApplicationInfo app)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @NonNull
+    @Override
+    public Resources getResourcesForApplication(@NonNull String packageName)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @NonNull
+    @Override
+    public Resources getResourcesForApplicationAsUser(@NonNull String packageName, int userId)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public int installExistingPackage(@NonNull String packageName)
+            throws NameNotFoundException {
+        return 0;
+    }
+
+    @Override
+    public int installExistingPackage(@NonNull String packageName, int installReason)
+            throws NameNotFoundException {
+        return 0;
+    }
+
+    @Override
+    public int installExistingPackageAsUser(@NonNull String packageName, int userId)
+            throws NameNotFoundException {
+        return 0;
+    }
+
+    @Override
+    public void verifyPendingInstall(int id, int verificationCode) {
+
+    }
+
+    @Override
+    public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
+            long millisecondsToDelay) {
+
+    }
+
+    @Override
+    public void verifyIntentFilter(int verificationId, int verificationCode,
+            @NonNull List<String> failedDomains) {
+
+    }
+
+    @Override
+    public int getIntentVerificationStatusAsUser(@NonNull String packageName, int userId) {
+        return 0;
+    }
+
+    @Override
+    public boolean updateIntentVerificationStatusAsUser(@NonNull String packageName, int status,
+            int userId) {
+        return false;
+    }
+
+    @NonNull
+    @Override
+    public List<IntentFilterVerificationInfo> getIntentFilterVerifications(
+            @NonNull String packageName) {
+        return null;
+    }
+
+    @NonNull
+    @Override
+    public List<IntentFilter> getAllIntentFilters(@NonNull String packageName) {
+        return null;
+    }
+
+    @Nullable
+    @Override
+    public String getDefaultBrowserPackageNameAsUser(int userId) {
+        return null;
+    }
+
+    @Override
+    public boolean setDefaultBrowserPackageNameAsUser(@Nullable String packageName,
+            int userId) {
+        return false;
+    }
+
+    @Override
+    public void setInstallerPackageName(@NonNull String targetPackage,
+            @Nullable String installerPackageName) {
+
+    }
+
+    @Override
+    public void setUpdateAvailable(@NonNull String packageName, boolean updateAvaialble) {
+
+    }
+
+    @Override
+    public void deletePackage(@NonNull String packageName,
+            @Nullable IPackageDeleteObserver observer, int flags) {
+
+    }
+
+    @Override
+    public void deletePackageAsUser(@NonNull String packageName,
+            @Nullable IPackageDeleteObserver observer, int flags, int userId) {
+
+    }
+
+    @Nullable
+    @Override
+    public String getInstallerPackageName(@NonNull String packageName) {
+        return null;
+    }
+
+    @Override
+    public void clearApplicationUserData(@NonNull String packageName,
+            @Nullable IPackageDataObserver observer) {
+
+    }
+
+    @Override
+    public void deleteApplicationCacheFiles(@NonNull String packageName,
+            @Nullable IPackageDataObserver observer) {
+
+    }
+
+    @Override
+    public void deleteApplicationCacheFilesAsUser(@NonNull String packageName, int userId,
+            @Nullable IPackageDataObserver observer) {
+
+    }
+
+    @Override
+    public void freeStorageAndNotify(@Nullable String volumeUuid, long freeStorageSize,
+            @Nullable IPackageDataObserver observer) {
+
+    }
+
+    @Override
+    public void freeStorage(@Nullable String volumeUuid, long freeStorageSize,
+            @Nullable IntentSender pi) {
+
+    }
+
+    @Override
+    public void getPackageSizeInfoAsUser(@NonNull String packageName, int userId,
+            @Nullable IPackageStatsObserver observer) {
+
+    }
+
+    @Override
+    public void addPackageToPreferred(@NonNull String packageName) {
+
+    }
+
+    @Override
+    public void removePackageFromPreferred(@NonNull String packageName) {
+
+    }
+
+    @NonNull
+    @Override
+    public List<PackageInfo> getPreferredPackages(int flags) {
+        return null;
+    }
+
+    @Override
+    public void addPreferredActivity(@NonNull IntentFilter filter, int match,
+            @Nullable ComponentName[] set, @NonNull ComponentName activity) {
+
+    }
+
+    @Override
+    public void replacePreferredActivity(@NonNull IntentFilter filter, int match,
+            @Nullable ComponentName[] set, @NonNull ComponentName activity) {
+
+    }
+
+    @Override
+    public void clearPackagePreferredActivities(@NonNull String packageName) {
+
+    }
+
+    @Override
+    public int getPreferredActivities(@NonNull List<IntentFilter> outFilters,
+            @NonNull List<ComponentName> outActivities, @Nullable String packageName) {
+        return 0;
+    }
+
+    @Nullable
+    @Override
+    public ComponentName getHomeActivities(@NonNull List<ResolveInfo> outActivities) {
+        return null;
+    }
+
+    @Override
+    public void setComponentEnabledSetting(@NonNull ComponentName componentName, int newState,
+            int flags) {
+
+    }
+
+    @Override
+    public int getComponentEnabledSetting(@NonNull ComponentName componentName) {
+        return 0;
+    }
+
+    @Override
+    public void setApplicationEnabledSetting(@NonNull String packageName, int newState,
+            int flags) {
+
+    }
+
+    @Override
+    public int getApplicationEnabledSetting(@NonNull String packageName) {
+        return 0;
+    }
+
+    @Override
+    public void flushPackageRestrictionsAsUser(int userId) {
+
+    }
+
+    @Override
+    public boolean setApplicationHiddenSettingAsUser(@NonNull String packageName,
+            boolean hidden, @NonNull UserHandle userHandle) {
+        return false;
+    }
+
+    @Override
+    public boolean getApplicationHiddenSettingAsUser(@NonNull String packageName,
+            @NonNull UserHandle userHandle) {
+        return false;
+    }
+
+    @Override
+    public boolean isSafeMode() {
+        return false;
+    }
+
+    @Override
+    public void addOnPermissionsChangeListener(@NonNull OnPermissionsChangedListener listener) {
+
+    }
+
+    @Override
+    public void removeOnPermissionsChangeListener(
+            @NonNull OnPermissionsChangedListener listener) {
+
+    }
+
+    @NonNull
+    @Override
+    public KeySet getKeySetByAlias(@NonNull String packageName, @NonNull String alias) {
+        return null;
+    }
+
+    @NonNull
+    @Override
+    public KeySet getSigningKeySet(@NonNull String packageName) {
+        return null;
+    }
+
+    @Override
+    public boolean isSignedBy(@NonNull String packageName, @NonNull KeySet ks) {
+        return false;
+    }
+
+    @Override
+    public boolean isSignedByExactly(@NonNull String packageName, @NonNull KeySet ks) {
+        return false;
+    }
+
+    @Override
+    public boolean isPackageSuspendedForUser(@NonNull String packageName, int userId) {
+        return false;
+    }
+
+    @Override
+    public void setApplicationCategoryHint(@NonNull String packageName, int categoryHint) {
+
+    }
+
+    @Override
+    public int getMoveStatus(int moveId) {
+        return 0;
+    }
+
+    @Override
+    public void registerMoveCallback(@NonNull MoveCallback callback, @NonNull Handler handler) {
+
+    }
+
+    @Override
+    public void unregisterMoveCallback(@NonNull MoveCallback callback) {
+
+    }
+
+    @Override
+    public int movePackage(@NonNull String packageName, @NonNull VolumeInfo vol) {
+        return 0;
+    }
+
+    @Nullable
+    @Override
+    public VolumeInfo getPackageCurrentVolume(@NonNull ApplicationInfo app) {
+        return null;
+    }
+
+    @NonNull
+    @Override
+    public List<VolumeInfo> getPackageCandidateVolumes(@NonNull ApplicationInfo app) {
+        return null;
+    }
+
+    @Override
+    public int movePrimaryStorage(@NonNull VolumeInfo vol) {
+        return 0;
+    }
+
+    @Nullable
+    @Override
+    public VolumeInfo getPrimaryStorageCurrentVolume() {
+        return null;
+    }
+
+    @NonNull
+    @Override
+    public List<VolumeInfo> getPrimaryStorageCandidateVolumes() {
+        return null;
+    }
+
+    @NonNull
+    @Override
+    public VerifierDeviceIdentity getVerifierDeviceIdentity() {
+        return null;
+    }
+
+    @Override
+    public boolean isUpgrade() {
+        return false;
+    }
+
+    @NonNull
+    @Override
+    public PackageInstaller getPackageInstaller() {
+        return null;
+    }
+
+    @Override
+    public void addCrossProfileIntentFilter(@NonNull IntentFilter filter, int sourceUserId,
+            int targetUserId, int flags) {
+
+    }
+
+    @Override
+    public void clearCrossProfileIntentFilters(int sourceUserId) {
+
+    }
+
+    @NonNull
+    @Override
+    public Drawable loadItemIcon(@NonNull PackageItemInfo itemInfo,
+            @Nullable ApplicationInfo appInfo) {
+        return null;
+    }
+
+    @NonNull
+    @Override
+    public Drawable loadUnbadgedItemIcon(@NonNull PackageItemInfo itemInfo,
+            @Nullable ApplicationInfo appInfo) {
+        return null;
+    }
+
+    @Override
+    public boolean isPackageAvailable(@NonNull String packageName) {
+        return false;
+    }
+
+    @Override
+    public int getInstallReason(@NonNull String packageName, @NonNull UserHandle user) {
+        return 0;
+    }
+
+    @Override
+    public boolean canRequestPackageInstalls() {
+        return false;
+    }
+
+    @Nullable
+    @Override
+    public ComponentName getInstantAppResolverSettingsComponent() {
+        return null;
+    }
+
+    @Nullable
+    @Override
+    public ComponentName getInstantAppInstallerComponent() {
+        return null;
+    }
+
+    @Nullable
+    @Override
+    public String getInstantAppAndroidId(@NonNull String packageName,
+            @NonNull UserHandle user) {
+        return null;
+    }
+
+    @Override
+    public void registerDexModule(@NonNull String dexModulePath,
+            @Nullable DexModuleRegisterCallback callback) {
+
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/apphibernation/AppHibernationServiceTest.java b/services/tests/servicestests/src/com/android/server/apphibernation/AppHibernationServiceTest.java
index 1c96838..0dbf3fe 100644
--- a/services/tests/servicestests/src/com/android/server/apphibernation/AppHibernationServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/apphibernation/AppHibernationServiceTest.java
@@ -18,6 +18,7 @@
 
 import static android.content.pm.PackageManager.MATCH_ANY_USER;
 
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.AdditionalAnswers.returnsArgAt;
 import static org.mockito.ArgumentMatchers.any;
@@ -27,6 +28,7 @@
 import static org.mockito.ArgumentMatchers.intThat;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 
 import android.app.IActivityManager;
@@ -35,6 +37,7 @@
 import android.content.Intent;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageInfo;
+import android.content.pm.PackageManagerInternal;
 import android.content.pm.ParceledListSlice;
 import android.content.pm.UserInfo;
 import android.net.Uri;
@@ -52,11 +55,11 @@
 import org.mockito.ArgumentCaptor;
 import org.mockito.Captor;
 import org.mockito.Mock;
-import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.concurrent.Executor;
 
 /**
  * Tests for {@link com.android.server.apphibernation.AppHibernationService}
@@ -67,6 +70,7 @@
     private static final String PACKAGE_SCHEME = "package";
     private static final String PACKAGE_NAME_1 = "package1";
     private static final String PACKAGE_NAME_2 = "package2";
+    private static final String PACKAGE_NAME_3 = "package3";
     private static final int USER_ID_1 = 1;
     private static final int USER_ID_2 = 2;
 
@@ -79,6 +83,8 @@
     @Mock
     private IPackageManager mIPackageManager;
     @Mock
+    private PackageManagerInternal mPackageManagerInternal;
+    @Mock
     private IActivityManager mIActivityManager;
     @Mock
     private UserManager mUserManager;
@@ -107,13 +113,15 @@
 
         List<PackageInfo> packages = new ArrayList<>();
         packages.add(makePackageInfo(PACKAGE_NAME_1));
+        packages.add(makePackageInfo(PACKAGE_NAME_2));
+        packages.add(makePackageInfo(PACKAGE_NAME_3));
         doReturn(new ParceledListSlice<>(packages)).when(mIPackageManager).getInstalledPackages(
                 intThat(arg -> (arg & MATCH_ANY_USER) != 0), anyInt());
         mAppHibernationService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
 
         UserInfo userInfo = addUser(USER_ID_1);
-        mAppHibernationService.onUserUnlocking(new SystemService.TargetUser(userInfo));
         doReturn(true).when(mUserManager).isUserUnlockingOrUnlocked(USER_ID_1);
+        mAppHibernationService.onUserUnlocking(new SystemService.TargetUser(userInfo));
 
         mAppHibernationService.mIsServiceEnabled = true;
     }
@@ -146,8 +154,8 @@
             throws RemoteException {
         // WHEN a new user is added and a package from the user is hibernated
         UserInfo user2 = addUser(USER_ID_2);
-        mAppHibernationService.onUserUnlocking(new SystemService.TargetUser(user2));
         doReturn(true).when(mUserManager).isUserUnlockingOrUnlocked(USER_ID_2);
+        mAppHibernationService.onUserUnlocking(new SystemService.TargetUser(user2));
         mAppHibernationService.setHibernatingForUser(PACKAGE_NAME_1, USER_ID_2, true);
 
         // THEN the new user's package is hibernated
@@ -179,6 +187,26 @@
         assertTrue(mAppHibernationService.isHibernatingGlobally(PACKAGE_NAME_1));
     }
 
+    @Test
+    public void testGetHibernatingPackagesForUser_returnsCorrectPackages() throws RemoteException {
+        // GIVEN an unlocked user with all packages installed
+        UserInfo userInfo =
+                addUser(USER_ID_2, new String[]{PACKAGE_NAME_1, PACKAGE_NAME_2, PACKAGE_NAME_3});
+        doReturn(true).when(mUserManager).isUserUnlockingOrUnlocked(USER_ID_2);
+        mAppHibernationService.onUserUnlocking(new SystemService.TargetUser(userInfo));
+
+        // WHEN packages are hibernated for the user
+        mAppHibernationService.setHibernatingForUser(PACKAGE_NAME_1, USER_ID_2, true);
+        mAppHibernationService.setHibernatingForUser(PACKAGE_NAME_2, USER_ID_2, true);
+
+        // THEN the hibernating packages returned matches
+        List<String> hibernatingPackages =
+                mAppHibernationService.getHibernatingPackagesForUser(USER_ID_2);
+        assertEquals(2, hibernatingPackages.size());
+        assertTrue(hibernatingPackages.contains(PACKAGE_NAME_1));
+        assertTrue(hibernatingPackages.contains(PACKAGE_NAME_2));
+    }
+
     /**
      * Add a mock user with one package.
      */
@@ -230,18 +258,29 @@
         }
 
         @Override
+        public PackageManagerInternal getPackageManagerInternal() {
+            return mPackageManagerInternal;
+        }
+
+        @Override
         public UserManager getUserManager() {
             return mUserManager;
         }
 
         @Override
+        public Executor getBackgroundExecutor() {
+            // Just execute immediately in tests.
+            return r -> r.run();
+        }
+
+        @Override
         public HibernationStateDiskStore<GlobalLevelState> getGlobalLevelDiskStore() {
-            return Mockito.mock(HibernationStateDiskStore.class);
+            return mock(HibernationStateDiskStore.class);
         }
 
         @Override
         public HibernationStateDiskStore<UserLevelState> getUserLevelDiskStore(int userId) {
-            return Mockito.mock(HibernationStateDiskStore.class);
+            return mock(HibernationStateDiskStore.class);
         }
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/AppSearchImplPlatformTest.java b/services/tests/servicestests/src/com/android/server/appsearch/AppSearchImplPlatformTest.java
index ad22cba..4240581 100644
--- a/services/tests/servicestests/src/com/android/server/appsearch/AppSearchImplPlatformTest.java
+++ b/services/tests/servicestests/src/com/android/server/appsearch/AppSearchImplPlatformTest.java
@@ -87,7 +87,8 @@
                 schema1,
                 /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
                 /*schemasPackageAccessible=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false);
+                /*forceOverride=*/ false,
+                /*schemaVersion=*/ 0);
 
         // Insert package2 schema
         List<AppSearchSchema> schema2 =
@@ -98,16 +99,17 @@
                 schema2,
                 /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
                 /*schemasPackageAccessible=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false);
+                /*forceOverride=*/ false,
+                /*schemaVersion=*/ 0);
 
         // Insert package1 document
         GenericDocument document1 =
-                new GenericDocument.Builder<>("uri", "schema1").setNamespace("namespace").build();
+                new GenericDocument.Builder<>("namespace", "uri", "schema1").build();
         mAppSearchImpl.putDocument("package1", "database1", document1, /*logger=*/ null);
 
         // Insert package2 document
         GenericDocument document2 =
-                new GenericDocument.Builder<>("uri", "schema2").setNamespace("namespace").build();
+                new GenericDocument.Builder<>("namespace", "uri", "schema2").build();
         mAppSearchImpl.putDocument("package2", "database2", document2, /*logger=*/ null);
 
         // No query filters specified, global query can retrieve all documents.
@@ -120,8 +122,8 @@
 
         // Document2 will be first since it got indexed later and has a "better", aka more recent
         // score.
-        assertThat(searchResultPage.getResults().get(0).getDocument()).isEqualTo(document2);
-        assertThat(searchResultPage.getResults().get(1).getDocument()).isEqualTo(document1);
+        assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document2);
+        assertThat(searchResultPage.getResults().get(1).getGenericDocument()).isEqualTo(document1);
     }
 
     /**
@@ -139,7 +141,8 @@
                 schema1,
                 /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
                 /*schemasPackageAccessible=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false);
+                /*forceOverride=*/ false,
+                /*schemaVersion=*/ 0);
 
         // Insert package2 schema
         List<AppSearchSchema> schema2 =
@@ -150,16 +153,17 @@
                 schema2,
                 /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
                 /*schemasPackageAccessible=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false);
+                /*forceOverride=*/ false,
+                /*schemaVersion=*/ 0);
 
         // Insert package1 document
         GenericDocument document1 =
-                new GenericDocument.Builder<>("uri", "schema1").setNamespace("namespace").build();
+                new GenericDocument.Builder<>("namespace", "uri", "schema1").build();
         mAppSearchImpl.putDocument("package1", "database1", document1, /*logger=*/ null);
 
         // Insert package2 document
         GenericDocument document2 =
-                new GenericDocument.Builder<>("uri", "schema2").setNamespace("namespace").build();
+                new GenericDocument.Builder<>("namespace", "uri", "schema2").build();
         mAppSearchImpl.putDocument("package2", "database2", document2, /*logger=*/ null);
 
         // "package1" filter specified
@@ -172,7 +176,7 @@
                 mAppSearchImpl.globalQuery(
                         "", searchSpec, mContext.getPackageName(), mGlobalQuerierUid);
         assertThat(searchResultPage.getResults()).hasSize(1);
-        assertThat(searchResultPage.getResults().get(0).getDocument()).isEqualTo(document1);
+        assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document1);
 
         // "package2" filter specified
         searchSpec =
@@ -184,7 +188,7 @@
                 mAppSearchImpl.globalQuery(
                         "", searchSpec, mContext.getPackageName(), mGlobalQuerierUid);
         assertThat(searchResultPage.getResults()).hasSize(1);
-        assertThat(searchResultPage.getResults().get(0).getDocument()).isEqualTo(document2);
+        assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document2);
     }
 
     @Test
@@ -208,7 +212,8 @@
                 /*schemasPackageAccessible=*/ ImmutableMap.of(
                         "schema1",
                         ImmutableList.of(new PackageIdentifier(packageNameFoo, sha256CertFoo))),
-                /*forceOverride=*/ false);
+                /*forceOverride=*/ false,
+                /*schemaVersion=*/ 0);
 
         // "schema1" is platform hidden now and package visible to package1
         assertThat(
@@ -234,7 +239,8 @@
                 /*schemasPackageAccessible=*/ ImmutableMap.of(
                         "schema1",
                         ImmutableList.of(new PackageIdentifier(packageNameFoo, sha256CertFoo))),
-                /*forceOverride=*/ false);
+                /*forceOverride=*/ false,
+                /*schemaVersion=*/ 0);
 
         // Check that "schema1" still has the same visibility settings
         assertThat(
@@ -283,7 +289,8 @@
                 /*schemasPackageAccessible=*/ ImmutableMap.of(
                         "schema1",
                         ImmutableList.of(new PackageIdentifier(packageNameFoo, sha256CertFoo))),
-                /*forceOverride=*/ false);
+                /*forceOverride=*/ false,
+                /*schemaVersion=*/ 0);
 
         // "schema1" is platform hidden now and package accessible
         assertThat(
@@ -305,7 +312,8 @@
                 /*schemas=*/ Collections.emptyList(),
                 /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
                 /*schemasPackageAccessible=*/ Collections.emptyMap(),
-                /*forceOverride=*/ true);
+                /*forceOverride=*/ true,
+                /*schemaVersion=*/ 0);
 
         // Check that "schema1" is no longer considered platform hidden or package accessible
         assertThat(
@@ -328,7 +336,8 @@
                 Collections.singletonList(new AppSearchSchema.Builder("schema1").build()),
                 /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
                 /*schemasPackageAccessible=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false);
+                /*forceOverride=*/ false,
+                /*schemaVersion=*/ 0);
         assertThat(
                         mAppSearchImpl
                                 .getVisibilityStoreLocked()
@@ -351,7 +360,8 @@
                 Collections.singletonList(new AppSearchSchema.Builder("Schema").build()),
                 /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
                 /*schemasPackageAccessible=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false);
+                /*forceOverride=*/ false,
+                /*schemaVersion=*/ 0);
         assertThat(
                         mAppSearchImpl
                                 .getVisibilityStoreLocked()
@@ -369,7 +379,8 @@
                 Collections.singletonList(new AppSearchSchema.Builder("Schema").build()),
                 /*schemasNotPlatformSurfaceable=*/ Collections.singletonList("Schema"),
                 /*schemasPackageAccessible=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false);
+                /*forceOverride=*/ false,
+                /*schemaVersion=*/ 0);
         assertThat(
                         mAppSearchImpl
                                 .getVisibilityStoreLocked()
@@ -387,7 +398,8 @@
                 Collections.singletonList(new AppSearchSchema.Builder("Schema").build()),
                 /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
                 /*schemasPackageAccessible=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false);
+                /*forceOverride=*/ false,
+                /*schemaVersion=*/ 0);
         assertThat(
                         mAppSearchImpl
                                 .getVisibilityStoreLocked()
@@ -416,7 +428,8 @@
                 /*schemasPackageAccessible=*/ ImmutableMap.of(
                         "Schema",
                         ImmutableList.of(new PackageIdentifier(packageNameFoo, sha256CertFoo))),
-                /*forceOverride=*/ false);
+                /*forceOverride=*/ false,
+                /*schemaVersion=*/ 0);
         assertThat(
                         mAppSearchImpl
                                 .getVisibilityStoreLocked()
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchImplTest.java b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchImplTest.java
index e0cdedd..c34c00d 100644
--- a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchImplTest.java
@@ -26,6 +26,7 @@
 import android.app.appsearch.SearchResultPage;
 import android.app.appsearch.SearchSpec;
 import android.app.appsearch.SetSchemaResponse;
+import android.app.appsearch.StorageInfo;
 import android.app.appsearch.exceptions.AppSearchException;
 import android.content.Context;
 import android.util.ArrayMap;
@@ -406,7 +407,8 @@
                 schemas,
                 /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
                 /*schemasPackageAccessible=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false);
+                /*forceOverride=*/ false,
+                /*version=*/ 0);
 
         // Insert enough documents.
         for (int i = 0;
@@ -471,7 +473,8 @@
                 schemas,
                 /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
                 /*schemasPackageAccessible=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false);
+                /*forceOverride=*/ false,
+                /*version=*/ 0);
 
         // Insert document
         GenericDocument document =
@@ -504,14 +507,16 @@
                 schemas,
                 /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
                 /*schemasPackageAccessible=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false);
+                /*forceOverride=*/ false,
+                /*version=*/ 0);
         mAppSearchImpl.setSchema(
                 "package",
                 "database2",
                 schemas,
                 /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
                 /*schemasPackageAccessible=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false);
+                /*forceOverride=*/ false,
+                /*version=*/ 0);
 
         // Insert documents
         GenericDocument document1 =
@@ -555,7 +560,8 @@
                 schemas,
                 /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
                 /*schemasPackageAccessible=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false);
+                /*forceOverride=*/ false,
+                /*version=*/ 0);
 
         // Insert document
         GenericDocument document =
@@ -597,7 +603,8 @@
                 schema1,
                 /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
                 /*schemasPackageAccessible=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false);
+                /*forceOverride=*/ false,
+                /*version=*/ 0);
 
         // Insert package2 schema
         List<AppSearchSchema> schema2 =
@@ -608,7 +615,8 @@
                 schema2,
                 /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
                 /*schemasPackageAccessible=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false);
+                /*forceOverride=*/ false,
+                /*version=*/ 0);
 
         // Insert package1 document
         GenericDocument document =
@@ -647,7 +655,8 @@
                 schema1,
                 /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
                 /*schemasPackageAccessible=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false);
+                /*forceOverride=*/ false,
+                /*version=*/ 0);
 
         // Insert package2 schema
         List<AppSearchSchema> schema2 =
@@ -658,7 +667,8 @@
                 schema2,
                 /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
                 /*schemasPackageAccessible=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false);
+                /*forceOverride=*/ false,
+                /*version=*/ 0);
 
         // Insert package1 document
         GenericDocument document =
@@ -735,7 +745,8 @@
                 schemas,
                 /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
                 /*schemasPackageAccessible=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false);
+                /*forceOverride=*/ false,
+                /*version=*/ 0);
 
         // Create expected schemaType proto.
         SchemaProto expectedProto =
@@ -781,7 +792,8 @@
                 oldSchemas,
                 /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
                 /*schemasPackageAccessible=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false);
+                /*forceOverride=*/ false,
+                /*version=*/ 0);
 
         // Create incompatible schema
         List<AppSearchSchema> newSchemas =
@@ -795,7 +807,8 @@
                         newSchemas,
                         /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
                         /*schemasPackageAccessible=*/ Collections.emptyMap(),
-                        /*forceOverride=*/ true);
+                        /*forceOverride=*/ true,
+                        /*version=*/ 0);
         assertThat(setSchemaResponse.getDeletedTypes()).containsExactly("Text");
         assertThat(setSchemaResponse.getIncompatibleTypes()).containsExactly("Email");
     }
@@ -816,7 +829,8 @@
                 schemas,
                 /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
                 /*schemasPackageAccessible=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false);
+                /*forceOverride=*/ false,
+                /*version=*/ 0);
 
         // Create expected schemaType proto.
         SchemaProto expectedProto =
@@ -847,7 +861,8 @@
                         finalSchemas,
                         /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
                         /*schemasPackageAccessible=*/ Collections.emptyMap(),
-                        /*forceOverride=*/ false);
+                        /*forceOverride=*/ false,
+                        /*version=*/ 0);
 
         // Check the Document type has been deleted.
         assertThat(setSchemaResponse.getDeletedTypes()).containsExactly("Document");
@@ -859,7 +874,8 @@
                 finalSchemas,
                 /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
                 /*schemasPackageAccessible=*/ Collections.emptyMap(),
-                /*forceOverride=*/ true);
+                /*forceOverride=*/ true,
+                /*version=*/ 0);
 
         // Check Document schema is removed.
         expectedProto =
@@ -895,14 +911,16 @@
                 schemas,
                 /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
                 /*schemasPackageAccessible=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false);
+                /*forceOverride=*/ false,
+                /*version=*/ 0);
         mAppSearchImpl.setSchema(
                 "package",
                 "database2",
                 schemas,
                 /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
                 /*schemasPackageAccessible=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false);
+                /*forceOverride=*/ false,
+                /*version=*/ 0);
 
         // Create expected schemaType proto.
         SchemaProto expectedProto =
@@ -940,7 +958,8 @@
                 schemas,
                 /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
                 /*schemasPackageAccessible=*/ Collections.emptyMap(),
-                /*forceOverride=*/ true);
+                /*forceOverride=*/ true,
+                /*version=*/ 0);
 
         // Create expected schemaType list, database 1 should only contain Email but database 2
         // remains in same.
@@ -982,7 +1001,8 @@
                 Collections.singletonList(new AppSearchSchema.Builder("schema").build()),
                 /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
                 /*schemasPackageAccessible=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false);
+                /*forceOverride=*/ false,
+                /*version=*/ 0);
         assertThat(mAppSearchImpl.getPackageToDatabases())
                 .containsExactlyEntriesIn(expectedMapping);
 
@@ -994,7 +1014,8 @@
                 Collections.singletonList(new AppSearchSchema.Builder("schema").build()),
                 /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
                 /*schemasPackageAccessible=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false);
+                /*forceOverride=*/ false,
+                /*version=*/ 0);
         assertThat(mAppSearchImpl.getPackageToDatabases())
                 .containsExactlyEntriesIn(expectedMapping);
 
@@ -1006,7 +1027,8 @@
                 Collections.singletonList(new AppSearchSchema.Builder("schema").build()),
                 /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
                 /*schemasPackageAccessible=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false);
+                /*forceOverride=*/ false,
+                /*version=*/ 0);
         assertThat(mAppSearchImpl.getPackageToDatabases())
                 .containsExactlyEntriesIn(expectedMapping);
     }
@@ -1024,7 +1046,8 @@
                 Collections.singletonList(new AppSearchSchema.Builder("schema").build()),
                 /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
                 /*schemasPackageAccessible=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false);
+                /*forceOverride=*/ false,
+                /*version=*/ 0);
         assertThat(mAppSearchImpl.getPrefixesLocked()).containsExactlyElementsIn(expectedPrefixes);
 
         // Has both databases
@@ -1035,7 +1058,8 @@
                 Collections.singletonList(new AppSearchSchema.Builder("schema").build()),
                 /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
                 /*schemasPackageAccessible=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false);
+                /*forceOverride=*/ false,
+                /*version=*/ 0);
         assertThat(mAppSearchImpl.getPrefixesLocked()).containsExactlyElementsIn(expectedPrefixes);
     }
 
@@ -1077,6 +1101,330 @@
     }
 
     @Test
+    public void testReportUsage() throws Exception {
+        // Insert schema
+        List<AppSearchSchema> schemas =
+                Collections.singletonList(new AppSearchSchema.Builder("type").build());
+        mAppSearchImpl.setSchema(
+                "package",
+                "database",
+                schemas,
+                /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
+                /*schemasPackageAccessible=*/ Collections.emptyMap(),
+                /*forceOverride=*/ false,
+                /*version=*/ 0);
+
+        // Insert two docs
+        GenericDocument document1 =
+                new GenericDocument.Builder<>("namespace", "uri1", "type").build();
+        GenericDocument document2 =
+                new GenericDocument.Builder<>("namespace", "uri2", "type").build();
+        mAppSearchImpl.putDocument("package", "database", document1, /*logger=*/ null);
+        mAppSearchImpl.putDocument("package", "database", document2, /*logger=*/ null);
+
+        // Report some usages. uri1 has 2 app and 1 system usage, uri2 has 1 app and 2 system usage.
+        mAppSearchImpl.reportUsage(
+                "package",
+                "database",
+                "namespace",
+                "uri1",
+                /*usageTimestampMillis=*/ 10,
+                /*systemUsage=*/ false);
+        mAppSearchImpl.reportUsage(
+                "package",
+                "database",
+                "namespace",
+                "uri1",
+                /*usageTimestampMillis=*/ 20,
+                /*systemUsage=*/ false);
+        mAppSearchImpl.reportUsage(
+                "package",
+                "database",
+                "namespace",
+                "uri1",
+                /*usageTimestampMillis=*/ 1000,
+                /*systemUsage=*/ true);
+
+        mAppSearchImpl.reportUsage(
+                "package",
+                "database",
+                "namespace",
+                "uri2",
+                /*usageTimestampMillis=*/ 100,
+                /*systemUsage=*/ false);
+        mAppSearchImpl.reportUsage(
+                "package",
+                "database",
+                "namespace",
+                "uri2",
+                /*usageTimestampMillis=*/ 200,
+                /*systemUsage=*/ true);
+        mAppSearchImpl.reportUsage(
+                "package",
+                "database",
+                "namespace",
+                "uri2",
+                /*usageTimestampMillis=*/ 150,
+                /*systemUsage=*/ true);
+
+        // Sort by app usage count: uri1 should win
+        List<SearchResult> page =
+                mAppSearchImpl
+                        .query(
+                                "package",
+                                "database",
+                                "",
+                                new SearchSpec.Builder()
+                                        .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
+                                        .setRankingStrategy(SearchSpec.RANKING_STRATEGY_USAGE_COUNT)
+                                        .build())
+                        .getResults();
+        assertThat(page).hasSize(2);
+        assertThat(page.get(0).getGenericDocument().getUri()).isEqualTo("uri1");
+        assertThat(page.get(1).getGenericDocument().getUri()).isEqualTo("uri2");
+
+        // Sort by app usage timestamp: uri2 should win
+        page =
+                mAppSearchImpl
+                        .query(
+                                "package",
+                                "database",
+                                "",
+                                new SearchSpec.Builder()
+                                        .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
+                                        .setRankingStrategy(
+                                                SearchSpec
+                                                        .RANKING_STRATEGY_USAGE_LAST_USED_TIMESTAMP)
+                                        .build())
+                        .getResults();
+        assertThat(page).hasSize(2);
+        assertThat(page.get(0).getGenericDocument().getUri()).isEqualTo("uri2");
+        assertThat(page.get(1).getGenericDocument().getUri()).isEqualTo("uri1");
+
+        // Sort by system usage count: uri2 should win
+        page =
+                mAppSearchImpl
+                        .query(
+                                "package",
+                                "database",
+                                "",
+                                new SearchSpec.Builder()
+                                        .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
+                                        .setRankingStrategy(
+                                                SearchSpec.RANKING_STRATEGY_SYSTEM_USAGE_COUNT)
+                                        .build())
+                        .getResults();
+        assertThat(page).hasSize(2);
+        assertThat(page.get(0).getGenericDocument().getUri()).isEqualTo("uri2");
+        assertThat(page.get(1).getGenericDocument().getUri()).isEqualTo("uri1");
+
+        // Sort by system usage timestamp: uri1 should win
+        page =
+                mAppSearchImpl
+                        .query(
+                                "package",
+                                "database",
+                                "",
+                                new SearchSpec.Builder()
+                                        .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
+                                        .setRankingStrategy(
+                                                SearchSpec
+                                                        .RANKING_STRATEGY_SYSTEM_USAGE_LAST_USED_TIMESTAMP)
+                                        .build())
+                        .getResults();
+        assertThat(page).hasSize(2);
+        assertThat(page.get(0).getGenericDocument().getUri()).isEqualTo("uri1");
+        assertThat(page.get(1).getGenericDocument().getUri()).isEqualTo("uri2");
+    }
+
+    @Test
+    public void testGetStorageInfoForPackage_nonexistentPackage() throws Exception {
+        // "package2" doesn't exist yet, so it shouldn't have any storage size
+        StorageInfo storageInfo = mAppSearchImpl.getStorageInfoForPackage("nonexistent.package");
+        assertThat(storageInfo.getSizeBytes()).isEqualTo(0);
+        assertThat(storageInfo.getAliveDocumentsCount()).isEqualTo(0);
+        assertThat(storageInfo.getAliveNamespacesCount()).isEqualTo(0);
+    }
+
+    @Test
+    public void testGetStorageInfoForPackage_withoutDocument() throws Exception {
+        // Insert schema for "package1"
+        List<AppSearchSchema> schemas =
+                Collections.singletonList(new AppSearchSchema.Builder("type").build());
+        mAppSearchImpl.setSchema(
+                "package1",
+                "database",
+                schemas,
+                /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
+                /*schemasPackageAccessible=*/ Collections.emptyMap(),
+                /*forceOverride=*/ false,
+                /*version=*/ 0);
+
+        // Since "package1" doesn't have a document, it get any space attributed to it.
+        StorageInfo storageInfo = mAppSearchImpl.getStorageInfoForPackage("package1");
+        assertThat(storageInfo.getSizeBytes()).isEqualTo(0);
+        assertThat(storageInfo.getAliveDocumentsCount()).isEqualTo(0);
+        assertThat(storageInfo.getAliveNamespacesCount()).isEqualTo(0);
+    }
+
+    @Test
+    public void testGetStorageInfoForPackage_proportionalToDocuments() throws Exception {
+        List<AppSearchSchema> schemas =
+                Collections.singletonList(new AppSearchSchema.Builder("type").build());
+
+        // Insert schema for "package1"
+        mAppSearchImpl.setSchema(
+                "package1",
+                "database",
+                schemas,
+                /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
+                /*schemasPackageAccessible=*/ Collections.emptyMap(),
+                /*forceOverride=*/ false,
+                /*version=*/ 0);
+
+        // Insert document for "package1"
+        GenericDocument document =
+                new GenericDocument.Builder<>("namespace", "uri1", "type").build();
+        mAppSearchImpl.putDocument("package1", "database", document, /*logger=*/ null);
+
+        // Insert schema for "package2"
+        mAppSearchImpl.setSchema(
+                "package2",
+                "database",
+                schemas,
+                /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
+                /*schemasPackageAccessible=*/ Collections.emptyMap(),
+                /*forceOverride=*/ false,
+                /*version=*/ 0);
+
+        // Insert two documents for "package2"
+        document = new GenericDocument.Builder<>("namespace", "uri1", "type").build();
+        mAppSearchImpl.putDocument("package2", "database", document, /*logger=*/ null);
+        document = new GenericDocument.Builder<>("namespace", "uri2", "type").build();
+        mAppSearchImpl.putDocument("package2", "database", document, /*logger=*/ null);
+
+        StorageInfo storageInfo = mAppSearchImpl.getStorageInfoForPackage("package1");
+        long size1 = storageInfo.getSizeBytes();
+        assertThat(size1).isGreaterThan(0);
+        assertThat(storageInfo.getAliveDocumentsCount()).isEqualTo(1);
+        assertThat(storageInfo.getAliveNamespacesCount()).isEqualTo(1);
+
+        storageInfo = mAppSearchImpl.getStorageInfoForPackage("package2");
+        long size2 = storageInfo.getSizeBytes();
+        assertThat(size2).isGreaterThan(0);
+        assertThat(storageInfo.getAliveDocumentsCount()).isEqualTo(2);
+        assertThat(storageInfo.getAliveNamespacesCount()).isEqualTo(1);
+
+        // Size is proportional to number of documents. Since "package2" has twice as many
+        // documents as "package1", its size is twice as much too.
+        assertThat(size2).isAtLeast(2 * size1);
+    }
+
+    @Test
+    public void testGetStorageInfoForDatabase_nonexistentPackage() throws Exception {
+        // "package2" doesn't exist yet, so it shouldn't have any storage size
+        StorageInfo storageInfo =
+                mAppSearchImpl.getStorageInfoForDatabase(
+                        "nonexistent.package", "nonexistentDatabase");
+        assertThat(storageInfo.getSizeBytes()).isEqualTo(0);
+        assertThat(storageInfo.getAliveDocumentsCount()).isEqualTo(0);
+        assertThat(storageInfo.getAliveNamespacesCount()).isEqualTo(0);
+    }
+
+    @Test
+    public void testGetStorageInfoForDatabase_nonexistentDatabase() throws Exception {
+        // Insert schema for "package1"
+        List<AppSearchSchema> schemas =
+                Collections.singletonList(new AppSearchSchema.Builder("type").build());
+        mAppSearchImpl.setSchema(
+                "package1",
+                "database",
+                schemas,
+                /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
+                /*schemasPackageAccessible=*/ Collections.emptyMap(),
+                /*forceOverride=*/ false,
+                /*version=*/ 0);
+
+        // "package2" doesn't exist yet, so it shouldn't have any storage size
+        StorageInfo storageInfo =
+                mAppSearchImpl.getStorageInfoForDatabase("package1", "nonexistentDatabase");
+        assertThat(storageInfo.getSizeBytes()).isEqualTo(0);
+        assertThat(storageInfo.getAliveDocumentsCount()).isEqualTo(0);
+        assertThat(storageInfo.getAliveNamespacesCount()).isEqualTo(0);
+    }
+
+    @Test
+    public void testGetStorageInfoForDatabase_withoutDocument() throws Exception {
+        // Insert schema for "package1"
+        List<AppSearchSchema> schemas =
+                Collections.singletonList(new AppSearchSchema.Builder("type").build());
+        mAppSearchImpl.setSchema(
+                "package1",
+                "database1",
+                schemas,
+                /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
+                /*schemasPackageAccessible=*/ Collections.emptyMap(),
+                /*forceOverride=*/ false,
+                /*version=*/ 0);
+
+        // Since "package1", "database1" doesn't have a document, it get any space attributed to it.
+        StorageInfo storageInfo = mAppSearchImpl.getStorageInfoForDatabase("package1", "database1");
+        assertThat(storageInfo.getSizeBytes()).isEqualTo(0);
+        assertThat(storageInfo.getAliveDocumentsCount()).isEqualTo(0);
+        assertThat(storageInfo.getAliveNamespacesCount()).isEqualTo(0);
+    }
+
+    @Test
+    public void testGetStorageInfoForDatabase_proportionalToDocuments() throws Exception {
+        // Insert schema for "package1", "database1" and "database2"
+        List<AppSearchSchema> schemas =
+                Collections.singletonList(new AppSearchSchema.Builder("type").build());
+        mAppSearchImpl.setSchema(
+                "package1",
+                "database1",
+                schemas,
+                /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
+                /*schemasPackageAccessible=*/ Collections.emptyMap(),
+                /*forceOverride=*/ false,
+                /*version=*/ 0);
+        mAppSearchImpl.setSchema(
+                "package1",
+                "database2",
+                schemas,
+                /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
+                /*schemasPackageAccessible=*/ Collections.emptyMap(),
+                /*forceOverride=*/ false,
+                /*version=*/ 0);
+
+        // Add a document for "package1", "database1"
+        GenericDocument document =
+                new GenericDocument.Builder<>("namespace1", "uri1", "type").build();
+        mAppSearchImpl.putDocument("package1", "database1", document, /*logger=*/ null);
+
+        // Add two documents for "package1", "database2"
+        document = new GenericDocument.Builder<>("namespace1", "uri1", "type").build();
+        mAppSearchImpl.putDocument("package1", "database2", document, /*logger=*/ null);
+        document = new GenericDocument.Builder<>("namespace1", "uri2", "type").build();
+        mAppSearchImpl.putDocument("package1", "database2", document, /*logger=*/ null);
+
+        StorageInfo storageInfo = mAppSearchImpl.getStorageInfoForDatabase("package1", "database1");
+        long size1 = storageInfo.getSizeBytes();
+        assertThat(size1).isGreaterThan(0);
+        assertThat(storageInfo.getAliveDocumentsCount()).isEqualTo(1);
+        assertThat(storageInfo.getAliveNamespacesCount()).isEqualTo(1);
+
+        storageInfo = mAppSearchImpl.getStorageInfoForDatabase("package1", "database2");
+        long size2 = storageInfo.getSizeBytes();
+        assertThat(size2).isGreaterThan(0);
+        assertThat(storageInfo.getAliveDocumentsCount()).isEqualTo(2);
+        assertThat(storageInfo.getAliveNamespacesCount()).isEqualTo(1);
+
+        // Size is proportional to number of documents. Since "database2" has twice as many
+        // documents as "database1", its size is twice as much too.
+        assertThat(size2).isAtLeast(2 * size1);
+    }
+
+    @Test
     public void testThrowsExceptionIfClosed() throws Exception {
         Context context = ApplicationProvider.getApplicationContext();
         AppSearchImpl appSearchImpl =
@@ -1095,7 +1443,8 @@
                 schemas,
                 /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
                 /*schemasPackageAccessible=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false);
+                /*forceOverride=*/ false,
+                /*version=*/ 0);
 
         appSearchImpl.close();
 
@@ -1109,7 +1458,8 @@
                             schemas,
                             /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
                             /*schemasPackageAccessible=*/ Collections.emptyMap(),
-                            /*forceOverride=*/ false);
+                            /*forceOverride=*/ false,
+                            /*version=*/ 0);
                 });
 
         expectThrows(
@@ -1179,7 +1529,8 @@
                             "database",
                             "namespace",
                             "uri",
-                            /*usageTimestampMillis=*/ 1000L);
+                            /*usageTimestampMillis=*/ 1000L,
+                            /*systemUsage=*/ false);
                 });
 
         expectThrows(
@@ -1203,6 +1554,18 @@
         expectThrows(
                 IllegalStateException.class,
                 () -> {
+                    appSearchImpl.getStorageInfoForPackage("package");
+                });
+
+        expectThrows(
+                IllegalStateException.class,
+                () -> {
+                    appSearchImpl.getStorageInfoForDatabase("package", "database");
+                });
+
+        expectThrows(
+                IllegalStateException.class,
+                () -> {
                     appSearchImpl.persistToDisk();
                 });
     }
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchLoggerTest.java b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchLoggerTest.java
index 467ede4..673b7ee 100644
--- a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchLoggerTest.java
+++ b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchLoggerTest.java
@@ -127,7 +127,8 @@
                 schemas,
                 /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
                 /*schemasPackageAccessible=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false);
+                /*forceOverride=*/ false,
+                /*version=*/ 0);
         GenericDocument document =
                 new GenericDocument.Builder<>("namespace", "uri", "type").build();
 
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverterTest.java b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverterTest.java
index dc225f1..0fe3903 100644
--- a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverterTest.java
+++ b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverterTest.java
@@ -32,7 +32,6 @@
     public void testGetProto_Email() {
         AppSearchSchema emailSchema =
                 new AppSearchSchema.Builder("Email")
-                        .setVersion(12345)
                         .addProperty(
                                 new AppSearchSchema.StringPropertyConfig.Builder("subject")
                                         .setCardinality(
@@ -89,7 +88,7 @@
                                                                 TermMatchType.Code.PREFIX)))
                         .build();
 
-        assertThat(SchemaToProtoConverter.toSchemaTypeConfigProto(emailSchema))
+        assertThat(SchemaToProtoConverter.toSchemaTypeConfigProto(emailSchema, /*version=*/ 12345))
                 .isEqualTo(expectedEmailProto);
         assertThat(SchemaToProtoConverter.toAppSearchSchema(expectedEmailProto))
                 .isEqualTo(emailSchema);
@@ -142,7 +141,9 @@
                                                 PropertyConfigProto.Cardinality.Code.OPTIONAL))
                         .build();
 
-        assertThat(SchemaToProtoConverter.toSchemaTypeConfigProto(musicRecordingSchema))
+        assertThat(
+                        SchemaToProtoConverter.toSchemaTypeConfigProto(
+                                musicRecordingSchema, /*version=*/ 0))
                 .isEqualTo(expectedMusicRecordingProto);
         assertThat(SchemaToProtoConverter.toAppSearchSchema(expectedMusicRecordingProto))
                 .isEqualTo(musicRecordingSchema);
diff --git a/services/tests/servicestests/src/com/android/server/backup/utils/BackupEligibilityRulesTest.java b/services/tests/servicestests/src/com/android/server/backup/utils/BackupEligibilityRulesTest.java
index 738527e..7323096 100644
--- a/services/tests/servicestests/src/com/android/server/backup/utils/BackupEligibilityRulesTest.java
+++ b/services/tests/servicestests/src/com/android/server/backup/utils/BackupEligibilityRulesTest.java
@@ -219,6 +219,7 @@
     }
 
     @Test
+    @EnableCompatChanges({BackupEligibilityRules.IGNORE_ALLOW_BACKUP_IN_D2D})
     public void appIsEligibleForBackup_backupNotAllowedAndInMigration_returnsTrue()
             throws Exception {
         ApplicationInfo applicationInfo = getApplicationInfo(Process.FIRST_APPLICATION_UID,
@@ -235,7 +236,7 @@
     public void appIsEligibleForBackup_backupNotAllowedForSystemAppAndInMigration_returnsFalse()
             throws Exception {
         ApplicationInfo applicationInfo = getApplicationInfo(Process.SYSTEM_UID,
-                /* flags */ 0, CUSTOM_BACKUP_AGENT_NAME);
+                ApplicationInfo.FLAG_SYSTEM, CUSTOM_BACKUP_AGENT_NAME);
         BackupEligibilityRules eligibilityRules = getBackupEligibilityRules(
                 OperationType.MIGRATION);
         boolean isEligible = eligibilityRules.appIsEligibleForBackup(applicationInfo);
@@ -478,34 +479,6 @@
     }
 
     @Test
-    public void appGetsFullBackup_withCustomBackupAgentAndWithoutFullBackupOnlyFlagAndInMigration_returnsTrue()
-            throws Exception {
-        PackageInfo packageInfo = new PackageInfo();
-        packageInfo.applicationInfo = getApplicationInfo(Process.FIRST_APPLICATION_UID,
-                ~ApplicationInfo.FLAG_FULL_BACKUP_ONLY, CUSTOM_BACKUP_AGENT_NAME);
-
-        BackupEligibilityRules eligibilityRules = getBackupEligibilityRules(
-                OperationType.MIGRATION);
-        boolean result = eligibilityRules.appGetsFullBackup(packageInfo);
-
-        assertThat(result).isTrue();
-    }
-
-    @Test
-    public void appGetsFullBackup_systemAppWithCustomBackupAgentAndWithoutFullBackupOnlyFlagAndInMigration_returnsFalse()
-            throws Exception {
-        PackageInfo packageInfo = new PackageInfo();
-        packageInfo.applicationInfo = getApplicationInfo(Process.SYSTEM_UID,
-                ~ApplicationInfo.FLAG_FULL_BACKUP_ONLY, CUSTOM_BACKUP_AGENT_NAME);
-
-        BackupEligibilityRules eligibilityRules = getBackupEligibilityRules(
-                OperationType.MIGRATION);
-        boolean result = eligibilityRules.appGetsFullBackup(packageInfo);
-
-        assertThat(result).isFalse();
-    }
-
-    @Test
     public void appIsKeyValueOnly_noCustomBackupAgent_returnsTrue() throws Exception {
         PackageInfo packageInfo = new PackageInfo();
         packageInfo.applicationInfo = new ApplicationInfo();
@@ -543,52 +516,6 @@
     }
 
     @Test
-    public void appIgnoresIncludeExcludeRules_systemAppAndInMigration_returnsFalse() {
-        ApplicationInfo applicationInfo = new ApplicationInfo();
-        applicationInfo.uid = Process.SYSTEM_UID;
-
-        BackupEligibilityRules eligibilityRules = getBackupEligibilityRules(
-                OperationType.MIGRATION);
-        boolean result = eligibilityRules.appIgnoresIncludeExcludeRules(applicationInfo);
-
-        assertThat(result).isFalse();
-    }
-
-    @Test
-    public void appIgnoresIncludeExcludeRules_systemAppInBackup_returnsFalse() {
-        ApplicationInfo applicationInfo = new ApplicationInfo();
-        applicationInfo.uid = Process.SYSTEM_UID;
-
-        BackupEligibilityRules eligibilityRules = getBackupEligibilityRules(
-                OperationType.MIGRATION);
-        boolean result = eligibilityRules.appIgnoresIncludeExcludeRules(applicationInfo);
-
-        assertThat(result).isFalse();
-    }
-
-    @Test
-    public void appIgnoresIncludeExcludeRules_nonSystemAppInMigration_returnsTrue() {
-        ApplicationInfo applicationInfo = new ApplicationInfo();
-        applicationInfo.uid = Process.FIRST_APPLICATION_UID;
-
-        BackupEligibilityRules eligibilityRules = getBackupEligibilityRules(
-                OperationType.MIGRATION);
-        boolean result = eligibilityRules.appIgnoresIncludeExcludeRules(applicationInfo);
-
-        assertThat(result).isTrue();
-    }
-
-    @Test
-    public void appIgnoresIncludeExcludeRules_nonSystemInBackup_returnsFalse() {
-        ApplicationInfo applicationInfo = new ApplicationInfo();
-        applicationInfo.uid = Process.FIRST_APPLICATION_UID;
-
-        boolean result = mBackupEligibilityRules.appIgnoresIncludeExcludeRules(applicationInfo);
-
-        assertThat(result).isFalse();
-    }
-
-    @Test
     public void signaturesMatch_targetIsNull_returnsFalse() throws Exception {
         boolean result = mBackupEligibilityRules.signaturesMatch(new Signature[] {SIGNATURE_1}, null);
 
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/UserAwareBiometricSchedulerTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/UserAwareBiometricSchedulerTest.java
new file mode 100644
index 0000000..557c14a
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/UserAwareBiometricSchedulerTest.java
@@ -0,0 +1,219 @@
+/*
+ * 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.biometrics.sensors;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+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.content.Context;
+import android.hardware.biometrics.IBiometricService;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.UserHandle;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@Presubmit
+@SmallTest
+public class UserAwareBiometricSchedulerTest {
+
+    private static final String TAG = "BiometricSchedulerTest";
+    private static final int TEST_SENSOR_ID = 0;
+
+    private UserAwareBiometricScheduler mScheduler;
+    private IBinder mToken;
+
+    @Mock
+    private Context mContext;
+    @Mock
+    private IBiometricService mBiometricService;
+
+    private TestUserStartedCallback mUserStartedCallback;
+    private TestUserStoppedCallback mUserStoppedCallback;
+    private int mCurrentUserId = UserHandle.USER_NULL;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        mToken = new Binder();
+        mUserStartedCallback = new TestUserStartedCallback();
+        mUserStoppedCallback = new TestUserStoppedCallback();
+
+        mScheduler = new UserAwareBiometricScheduler(TAG,
+                null /* gestureAvailabilityDispatcher */,
+                mBiometricService,
+                () -> mCurrentUserId,
+                new UserAwareBiometricScheduler.UserSwitchCallback() {
+                    @NonNull
+                    @Override
+                    public StopUserClient<?> getStopUserClient(int userId) {
+                        return new TestStopUserClient(mContext, Object::new, mToken, userId,
+                                TEST_SENSOR_ID, mUserStoppedCallback);
+                    }
+
+                    @NonNull
+                    @Override
+                    public StartUserClient<?, ?> getStartUserClient(int newUserId) {
+                        return new TestStartUserClient(mContext, Object::new, mToken, newUserId,
+                                TEST_SENSOR_ID, mUserStartedCallback);
+                    }
+                });
+    }
+
+    @Test
+    public void testScheduleOperation_whenNoUser() {
+        mCurrentUserId = UserHandle.USER_NULL;
+
+        final int nextUserId = 0;
+
+        BaseClientMonitor nextClient = mock(BaseClientMonitor.class);
+        when(nextClient.getTargetUserId()).thenReturn(nextUserId);
+
+        mScheduler.scheduleClientMonitor(nextClient);
+        verify(nextClient, never()).start(any());
+        assertEquals(0, mUserStoppedCallback.numInvocations);
+        assertEquals(1, mUserStartedCallback.numInvocations);
+
+        waitForIdle();
+        verify(nextClient).start(any());
+    }
+
+    @Test
+    public void testScheduleOperation_whenSameUser() {
+        mCurrentUserId = 10;
+
+        BaseClientMonitor nextClient = mock(BaseClientMonitor.class);
+        when(nextClient.getTargetUserId()).thenReturn(mCurrentUserId);
+
+        mScheduler.scheduleClientMonitor(nextClient);
+
+        waitForIdle();
+
+        verify(nextClient).start(any());
+        assertEquals(0, mUserStoppedCallback.numInvocations);
+        assertEquals(0, mUserStartedCallback.numInvocations);
+    }
+
+    @Test
+    public void testScheduleOperation_whenDifferentUser() {
+        mCurrentUserId = 10;
+
+        final int nextUserId = 11;
+        BaseClientMonitor nextClient = mock(BaseClientMonitor.class);
+        when(nextClient.getTargetUserId()).thenReturn(nextUserId);
+
+        mScheduler.scheduleClientMonitor(nextClient);
+
+        waitForIdle();
+        assertEquals(1, mUserStoppedCallback.numInvocations);
+
+        waitForIdle();
+        assertEquals(1, mUserStartedCallback.numInvocations);
+
+        waitForIdle();
+        verify(nextClient).start(any());
+    }
+
+    private static void waitForIdle() {
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+    }
+
+    private class TestUserStoppedCallback implements StopUserClient.UserStoppedCallback {
+
+        int numInvocations;
+
+        @Override
+        public void onUserStopped() {
+            numInvocations++;
+            mCurrentUserId = UserHandle.USER_NULL;
+        }
+    }
+
+    private class TestUserStartedCallback implements StartUserClient.UserStartedCallback<Object> {
+
+        int numInvocations;
+
+        @Override
+        public void onUserStarted(int newUserId, Object newObject) {
+            numInvocations++;
+            mCurrentUserId = newUserId;
+        }
+    }
+
+    private static class TestStopUserClient extends StopUserClient<Object> {
+        public TestStopUserClient(@NonNull Context context,
+                @NonNull LazyDaemon<Object> lazyDaemon, @Nullable IBinder token, int userId,
+                int sensorId, @NonNull UserStoppedCallback callback) {
+            super(context, lazyDaemon, token, userId, sensorId, callback);
+        }
+
+        @Override
+        protected void startHalOperation() {
+
+        }
+
+        @Override
+        public void start(@NonNull Callback callback) {
+            super.start(callback);
+            onUserStopped();
+        }
+
+        @Override
+        public void unableToStart() {
+
+        }
+    }
+
+    private static class TestStartUserClient extends StartUserClient<Object, Object> {
+        public TestStartUserClient(@NonNull Context context,
+                @NonNull LazyDaemon<Object> lazyDaemon, @Nullable IBinder token, int userId,
+                int sensorId, @NonNull UserStartedCallback<Object> callback) {
+            super(context, lazyDaemon, token, userId, sensorId, callback);
+        }
+
+        @Override
+        protected void startHalOperation() {
+
+        }
+
+        @Override
+        public void start(@NonNull Callback callback) {
+            super.start(callback);
+            mUserStartedCallback.onUserStarted(getTargetUserId(), new Object());
+            callback.onClientFinished(this, true /* success */);
+        }
+
+        @Override
+        public void unableToStart() {
+
+        }
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceProviderTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceProviderTest.java
index 04a7122..0cd6d86 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceProviderTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceProviderTest.java
@@ -24,10 +24,12 @@
 
 import android.content.Context;
 import android.hardware.biometrics.common.CommonProps;
+import android.hardware.biometrics.face.IFace;
 import android.hardware.biometrics.face.SensorProps;
 import android.os.UserManager;
 import android.platform.test.annotations.Presubmit;
 
+import androidx.annotation.NonNull;
 import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.SmallTest;
 
@@ -56,7 +58,7 @@
 
     private SensorProps[] mSensorProps;
     private LockoutResetDispatcher mLockoutResetDispatcher;
-    private FaceProvider mFaceProvider;
+    private TestableFaceProvider mFaceProvider;
 
     private static void waitForIdle() {
         InstrumentationRegistry.getInstrumentation().waitForIdleSync();
@@ -80,7 +82,7 @@
 
         mLockoutResetDispatcher = new LockoutResetDispatcher(mContext);
 
-        mFaceProvider = new FaceProvider(mContext, mSensorProps, TAG,
+        mFaceProvider = new TestableFaceProvider(mContext, mSensorProps, TAG,
                 mLockoutResetDispatcher);
     }
 
@@ -123,4 +125,19 @@
             assertEquals(0, scheduler.getCurrentPendingCount());
         }
     }
+
+    private static class TestableFaceProvider extends FaceProvider {
+        public TestableFaceProvider(@NonNull Context context,
+                @NonNull SensorProps[] props,
+                @NonNull String halInstanceName,
+                @NonNull LockoutResetDispatcher lockoutResetDispatcher) {
+            super(context, props, halInstanceName, lockoutResetDispatcher);
+        }
+
+        @Override
+        synchronized IFace getHalInstance() {
+            return mock(IFace.class);
+        }
+    }
+
 }
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProviderTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProviderTest.java
index d149880..94cc666 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProviderTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProviderTest.java
@@ -24,10 +24,12 @@
 
 import android.content.Context;
 import android.hardware.biometrics.common.CommonProps;
+import android.hardware.biometrics.fingerprint.IFingerprint;
 import android.hardware.biometrics.fingerprint.SensorProps;
 import android.os.UserManager;
 import android.platform.test.annotations.Presubmit;
 
+import androidx.annotation.NonNull;
 import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.SmallTest;
 
@@ -59,7 +61,7 @@
 
     private SensorProps[] mSensorProps;
     private LockoutResetDispatcher mLockoutResetDispatcher;
-    private FingerprintProvider mFingerprintProvider;
+    private TestableFingerprintProvider mFingerprintProvider;
 
     private static void waitForIdle() {
         InstrumentationRegistry.getInstrumentation().waitForIdleSync();
@@ -83,7 +85,7 @@
 
         mLockoutResetDispatcher = new LockoutResetDispatcher(mContext);
 
-        mFingerprintProvider = new FingerprintProvider(mContext, mSensorProps, TAG,
+        mFingerprintProvider = new TestableFingerprintProvider(mContext, mSensorProps, TAG,
                 mLockoutResetDispatcher, mGestureAvailabilityDispatcher);
     }
 
@@ -126,4 +128,20 @@
             assertEquals(0, scheduler.getCurrentPendingCount());
         }
     }
+
+    private static class TestableFingerprintProvider extends FingerprintProvider {
+        public TestableFingerprintProvider(@NonNull Context context,
+                @NonNull SensorProps[] props,
+                @NonNull String halInstanceName,
+                @NonNull LockoutResetDispatcher lockoutResetDispatcher,
+                @NonNull GestureAvailabilityDispatcher gestureAvailabilityDispatcher) {
+            super(context, props, halInstanceName, lockoutResetDispatcher,
+                    gestureAvailabilityDispatcher);
+        }
+
+        @Override
+        synchronized IFingerprint getHalInstance() {
+            return mock(IFingerprint.class);
+        }
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/compat/CompatConfigBuilder.java b/services/tests/servicestests/src/com/android/server/compat/CompatConfigBuilder.java
index fcd6b84..7bdc87e 100644
--- a/services/tests/servicestests/src/com/android/server/compat/CompatConfigBuilder.java
+++ b/services/tests/servicestests/src/com/android/server/compat/CompatConfigBuilder.java
@@ -116,7 +116,7 @@
     }
 
     CompatConfigBuilder addOverridableChangeWithId(long id) {
-        mChanges.add(new CompatChange(id, "", -1, -1, false, true, "", true));
+        mChanges.add(new CompatChange(id, "", -1, -1, true, false, "", true));
         return this;
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java b/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java
index bd77405..a866363 100644
--- a/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java
+++ b/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java
@@ -260,6 +260,36 @@
     }
 
     @Test
+    public void testInstallerCanSetOverrides() throws Exception {
+        final long changeId = 1234L;
+        final int installerUid = 23;
+        CompatConfig compatConfig = CompatConfigBuilder.create(mBuildClassifier, mContext)
+                .addOverridableChangeWithId(1234L)
+                .build();
+        ApplicationInfo applicationInfo = ApplicationInfoBuilder.create()
+                .withPackageName("com.some.package")
+                .build();
+        PackageManager packageManager = mock(PackageManager.class);
+        when(mContext.getPackageManager()).thenReturn(packageManager);
+        when(packageManager.getApplicationInfo(eq("com.some.package"), anyInt()))
+                .thenReturn(applicationInfo);
+
+        // Force the validator to prevent overriding the change by using a user build.
+        when(mBuildClassifier.isDebuggableBuild()).thenReturn(false);
+        when(mBuildClassifier.isFinalBuild()).thenReturn(true);
+
+        CompatibilityOverrideConfig config = new CompatibilityOverrideConfig(
+                Collections.singletonMap(1234L,
+                        new PackageOverride.Builder()
+                                .setMaxVersionCode(99L)
+                                .setEnabled(true)
+                                .build()));
+
+        compatConfig.addOverrides(config, "com.some.package");
+        assertThat(compatConfig.isChangeEnabled(1234L, applicationInfo)).isTrue();
+    }
+
+    @Test
     public void testApplyDeferredOverridesAfterInstallingApp() throws Exception {
         ApplicationInfo applicationInfo = ApplicationInfoBuilder.create()
                 .withPackageName("com.notinstalled.foo")
@@ -639,9 +669,18 @@
                         .build());
         when(mPackageManager.getApplicationInfo(eq("bar.baz"), anyInt()))
                 .thenThrow(new NameNotFoundException());
-
-        compatConfig.addOverride(1L, "foo.bar", true);
-        compatConfig.addOverride(2L, "bar.baz", false);
+        compatConfig.addOverrides(
+                new CompatibilityOverrideConfig(
+                        Collections.singletonMap(
+                                1L,
+                                new PackageOverride.Builder().setEnabled(true).build())),
+                "foo.bar");
+        compatConfig.addOverrides(
+                new CompatibilityOverrideConfig(
+                        Collections.singletonMap(
+                                2L,
+                                new PackageOverride.Builder().setEnabled(false).build())),
+                "bar.baz");
 
         assertThat(readFile(overridesFile)).isEqualTo("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
                 + "<overrides>\n"
diff --git a/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java b/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java
index 3fc6e99..a2664e5 100644
--- a/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java
+++ b/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java
@@ -113,7 +113,7 @@
                 new CompatibilityChangeInfo(
                         6L, "", Build.VERSION_CODES.R, -1, false, false, "", false),
                 new CompatibilityChangeInfo(7L, "", -1, -1, false, true, "", false),
-                new CompatibilityChangeInfo(8L, "", -1, -1, false, true, "", true));
+                new CompatibilityChangeInfo(8L, "", -1, -1, true, false, "", true));
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/content/OWNERS b/services/tests/servicestests/src/com/android/server/content/OWNERS
new file mode 100644
index 0000000..6264a142
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/content/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/content/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/content/SyncManagerTest.java b/services/tests/servicestests/src/com/android/server/content/SyncManagerTest.java
index d093e79..c2a81d9 100644
--- a/services/tests/servicestests/src/com/android/server/content/SyncManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/content/SyncManagerTest.java
@@ -16,6 +16,7 @@
 
 package com.android.server.content;
 
+import android.content.ContentResolver;
 import android.os.Bundle;
 import android.test.suitebuilder.annotation.SmallTest;
 
@@ -57,6 +58,23 @@
                 SyncManager.syncExtrasEquals(b1, b2, false /* don't care about system extras */));
     }
 
+    public void testSyncExtrasEqualsFails_WithNull() throws Exception {
+        Bundle b1 = new Bundle();
+        b1.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
+        b1.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
+
+        Bundle b2 = new Bundle();
+        b2.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
+        b2.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
+        b2.putString(null, "Hello NPE!");
+        b2.putString("a", "b");
+        b2.putString("c", "d");
+        b2.putString("e", "f");
+
+        assertFalse("Extras not properly compared between bundles.",
+                SyncManager.syncExtrasEquals(b1, b2, false /* don't care about system extras */));
+    }
+
     public void testSyncExtrasEqualsFails_differentValues() throws Exception {
         Bundle b1 = new Bundle();
         Bundle b2 = new Bundle();
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 576f9c2..cc206a1 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -92,6 +92,7 @@
 import android.content.pm.UserInfo;
 import android.graphics.Color;
 import android.hardware.usb.UsbManager;
+import android.net.ConnectivityManager;
 import android.net.Uri;
 import android.os.Build.VERSION_CODES;
 import android.os.Bundle;
@@ -124,9 +125,7 @@
 import org.hamcrest.Description;
 import org.hamcrest.Matcher;
 import org.junit.After;
-import org.junit.AfterClass;
 import org.junit.Before;
-import org.junit.BeforeClass;
 import org.junit.Test;
 import org.mockito.Mockito;
 import org.mockito.internal.util.collections.Sets;
@@ -221,16 +220,6 @@
     private static final String PROFILE_OFF_SUSPENSION_TEXT = "suspension_text";
     private static final String PROFILE_OFF_SUSPENSION_SOON_TEXT = "suspension_tomorrow_text";
 
-    @BeforeClass
-    public static void setUpClass() {
-        Notification.DevFlags.sForceDefaults = true;
-    }
-
-    @AfterClass
-    public static void tearDownClass() {
-        Notification.DevFlags.sForceDefaults = false;
-    }
-
     @Before
     public void setUp() throws Exception {
 
@@ -4017,53 +4006,59 @@
 
     @Test
     public void testUpdateNetworkPreferenceOnStartOnStopUser() throws Exception {
-        dpms.handleStartUser(CALLER_USER_HANDLE);
-        // TODO(b/178655595)
-        // verify(getServices().connectivityManager, times(1)).setNetworkPreferenceForUser(
-        //         any(UserHandle.class),
-        //         anyInt(),
-        //         any(Executor.class),
-        //         any(Runnable.class)
-        //);
+        final int managedProfileUserId = 15;
+        final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436);
+        addManagedProfile(admin1, managedProfileAdminUid, admin1);
+        mContext.binder.callingUid = managedProfileAdminUid;
+        mServiceContext.permissions.add(permission.INTERACT_ACROSS_USERS_FULL);
 
-        dpms.handleStopUser(CALLER_USER_HANDLE);
-        // TODO(b/178655595)
-        // verify(getServices().connectivityManager, times(1)).setNetworkPreferenceForUser(
-        //         any(UserHandle.class),
-        //         eq(ConnectivityManager.USER_PREFERENCE_SYSTEM_DEFAULT),
-        //         any(Executor.class),
-        //         any(Runnable.class)
-        //);
+        dpms.handleStartUser(managedProfileUserId);
+        verify(getServices().connectivityManager, times(1)).setProfileNetworkPreference(
+                eq(UserHandle.of(managedProfileUserId)),
+                anyInt(),
+                any(),
+                any()
+        );
+
+        dpms.handleStopUser(managedProfileUserId);
+        verify(getServices().connectivityManager, times(1)).setProfileNetworkPreference(
+                eq(UserHandle.of(managedProfileUserId)),
+                eq(ConnectivityManager.PROFILE_NETWORK_PREFERENCE_DEFAULT),
+                any(),
+                any()
+        );
     }
 
     @Test
-    public void testGetSetNetworkSlicing() throws Exception {
+    public void testGetSetEnterpriseNetworkPreference() throws Exception {
         assertExpectException(SecurityException.class, null,
-                () -> dpm.setNetworkSlicingEnabled(false));
+                () -> dpm.setEnterpriseNetworkPreferenceEnabled(false));
 
         assertExpectException(SecurityException.class, null,
-                () -> dpm.isNetworkSlicingEnabled());
+                () -> dpm.isEnterpriseNetworkPreferenceEnabled());
 
-        setupProfileOwner();
-        dpm.setNetworkSlicingEnabled(false);
-        assertThat(dpm.isNetworkSlicingEnabled()).isFalse();
-        // TODO(b/178655595)
-        // verify(getServices().connectivityManager, times(1)).setNetworkPreferenceForUser(
-        //         any(UserHandle.class),
-        //         eq(ConnectivityManager.USER_PREFERENCE_SYSTEM_DEFAULT),
-        //         any(Executor.class),
-        //         any(Runnable.class)
-        //);
+        final int managedProfileUserId = 15;
+        final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436);
+        addManagedProfile(admin1, managedProfileAdminUid, admin1);
+        mContext.binder.callingUid = managedProfileAdminUid;
 
-        dpm.setNetworkSlicingEnabled(true);
-        assertThat(dpm.isNetworkSlicingEnabled()).isTrue();
-        // TODO(b/178655595)
-        // verify(getServices().connectivityManager, times(1)).setNetworkPreferenceForUser(
-        //         any(UserHandle.class),
-        //         eq(ConnectivityManager.USER_PREFERENCE_ENTERPRISE),
-        //         any(Executor.class),
-        //         any(Runnable.class)
-        //);
+        dpm.setEnterpriseNetworkPreferenceEnabled(false);
+        assertThat(dpm.isEnterpriseNetworkPreferenceEnabled()).isFalse();
+        verify(getServices().connectivityManager, times(1)).setProfileNetworkPreference(
+                eq(UserHandle.of(managedProfileUserId)),
+                eq(ConnectivityManager.PROFILE_NETWORK_PREFERENCE_DEFAULT),
+                any(),
+                any()
+        );
+
+        dpm.setEnterpriseNetworkPreferenceEnabled(true);
+        assertThat(dpm.isEnterpriseNetworkPreferenceEnabled()).isTrue();
+        verify(getServices().connectivityManager, times(1)).setProfileNetworkPreference(
+                eq(UserHandle.of(managedProfileUserId)),
+                eq(ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE),
+                any(),
+                any()
+        );
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java
index 15ada89..c8099e2 100644
--- a/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java
@@ -464,6 +464,40 @@
     }
 
     @Test
+    public void testStaleAppRequestSize() {
+        DisplayModeDirector director =
+                new DisplayModeDirector(mContext, mHandler, mInjector);
+        Display.Mode[] modes = new Display.Mode[] {
+                new Display.Mode(1, 1280, 720, 60),
+        };
+        Display.Mode defaultMode = modes[0];
+
+        // Inject supported modes
+        SparseArray<Display.Mode[]> supportedModesByDisplay = new SparseArray<>();
+        supportedModesByDisplay.put(DISPLAY_ID, modes);
+        director.injectSupportedModesByDisplay(supportedModesByDisplay);
+
+        // Inject default mode
+        SparseArray<Display.Mode> defaultModesByDisplay = new SparseArray<>();
+        defaultModesByDisplay.put(DISPLAY_ID, defaultMode);
+        director.injectDefaultModeByDisplay(defaultModesByDisplay);
+
+        // Inject votes
+        SparseArray<Vote> votes = new SparseArray<>();
+        votes.put(Vote.PRIORITY_APP_REQUEST_SIZE, Vote.forSize(1920, 1080));
+        votes.put(Vote.PRIORITY_APP_REQUEST_REFRESH_RATE, Vote.forRefreshRates(50, 50));
+        SparseArray<SparseArray<Vote>> votesByDisplay = new SparseArray<>();
+        votesByDisplay.put(DISPLAY_ID, votes);
+        director.injectVotesByDisplay(votesByDisplay);
+
+        director.setShouldAlwaysRespectAppRequestedMode(true);
+
+        // We should return the only available mode
+        DesiredDisplayModeSpecs specs = director.getDesiredDisplayModeSpecs(DISPLAY_ID);
+        assertThat(specs.baseModeId).isEqualTo(defaultMode.getModeId());
+    }
+
+    @Test
     public void testBrightnessObserverGetsUpdatedRefreshRatesForZone() {
         DisplayModeDirector director =
                 createDirectorFromRefreshRateArray(new float[] {60.f, 90.f}, /* baseModeId= */ 0);
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 dcb2c15..bcd853c 100644
--- a/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java
@@ -186,14 +186,11 @@
         LogicalDisplay display2 = add(createDisplayDevice(Display.TYPE_INTERNAL, 600, 800, 0));
         LogicalDisplay display3 = add(createDisplayDevice(Display.TYPE_VIRTUAL, 600, 800, 0));
 
-        // Physical displays should be automatically put into the default group.
         assertEquals(Display.DEFAULT_DISPLAY_GROUP,
                 mLogicalDisplayMapper.getDisplayGroupIdFromDisplayIdLocked(id(display1)));
         assertEquals(Display.DEFAULT_DISPLAY_GROUP,
                 mLogicalDisplayMapper.getDisplayGroupIdFromDisplayIdLocked(id(display2)));
-
-        // Virtual displays should belong to no group by default.
-        assertEquals(Display.INVALID_DISPLAY_GROUP,
+        assertEquals(Display.DEFAULT_DISPLAY_GROUP,
                 mLogicalDisplayMapper.getDisplayGroupIdFromDisplayIdLocked(id(display3)));
     }
 
@@ -215,13 +212,13 @@
         assertNotEquals(Display.DEFAULT_DISPLAY_GROUP,
                 mLogicalDisplayMapper.getDisplayGroupIdFromDisplayIdLocked(id(display3)));
 
-        // Now switch it to the invalid group by removing the flag and issuing an update
+        // Now switch it back to the default group by removing the flag and issuing an update
         DisplayDeviceInfo info = device3.getSourceInfo();
         info.flags = info.flags & ~DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP;
         mDisplayDeviceRepo.onDisplayDeviceEvent(device3, DISPLAY_DEVICE_EVENT_CHANGED);
 
-        // Verify the virtual display has not been placed into a group.
-        assertEquals(Display.INVALID_DISPLAY_GROUP,
+        // Verify the new group is correct.
+        assertEquals(Display.DEFAULT_DISPLAY_GROUP,
                 mLogicalDisplayMapper.getDisplayGroupIdFromDisplayIdLocked(id(display3)));
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/graphics/fonts/UpdatableFontDirTest.java b/services/tests/servicestests/src/com/android/server/graphics/fonts/UpdatableFontDirTest.java
index dbb415c..e7ffea0 100644
--- a/services/tests/servicestests/src/com/android/server/graphics/fonts/UpdatableFontDirTest.java
+++ b/services/tests/servicestests/src/com/android/server/graphics/fonts/UpdatableFontDirTest.java
@@ -54,6 +54,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.function.Supplier;
 import java.util.stream.Collectors;
 
 @Presubmit
@@ -117,10 +118,13 @@
         }
     }
 
+    private static final long CURRENT_TIME = 1234567890L;
+
     private File mCacheDir;
     private File mUpdatableFontFilesDir;
     private File mConfigFile;
     private List<File> mPreinstalledFontDirs;
+    private Supplier<Long> mCurrentTimeSupplier = () -> CURRENT_TIME;
 
     @SuppressWarnings("ResultOfMethodCallIgnored")
     @Before
@@ -147,7 +151,7 @@
 
     @Test
     public void construct() throws Exception {
-        long expectedModifiedDate = 1234567890;
+        long expectedModifiedDate = CURRENT_TIME / 2;
         FakeFontFileParser parser = new FakeFontFileParser();
         FakeFsverityUtil fakeFsverityUtil = new FakeFsverityUtil();
         PersistentSystemFontConfig.Config config = new PersistentSystemFontConfig.Config();
@@ -155,7 +159,7 @@
         writeConfig(config, mConfigFile);
         UpdatableFontDir dirForPreparation = new UpdatableFontDir(
                 mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil,
-                mConfigFile);
+                mConfigFile, mCurrentTimeSupplier);
         dirForPreparation.loadFontFileMap();
         assertThat(dirForPreparation.getSystemFontConfig().getLastModifiedTimeMillis())
                 .isEqualTo(expectedModifiedDate);
@@ -168,6 +172,9 @@
                         + "  <font>foo.ttf</font>"
                         + "  <font>bar.ttf</font>"
                         + "</family>")));
+        // Verifies that getLastModifiedTimeMillis() returns the value of currentTimeMillis.
+        assertThat(dirForPreparation.getSystemFontConfig().getLastModifiedTimeMillis())
+                .isEqualTo(CURRENT_TIME);
         // Four font dirs are created.
         assertThat(mUpdatableFontFilesDir.list()).hasLength(4);
         assertThat(dirForPreparation.getSystemFontConfig().getLastModifiedTimeMillis())
@@ -175,7 +182,7 @@
 
         UpdatableFontDir dir = new UpdatableFontDir(
                 mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil,
-                mConfigFile);
+                mConfigFile, mCurrentTimeSupplier);
         dir.loadFontFileMap();
         assertThat(dir.getFontFileMap()).containsKey("foo.ttf");
         assertThat(parser.getRevision(dir.getFontFileMap().get("foo.ttf"))).isEqualTo(3);
@@ -199,7 +206,7 @@
         FakeFsverityUtil fakeFsverityUtil = new FakeFsverityUtil();
         UpdatableFontDir dir = new UpdatableFontDir(
                 mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil,
-                mConfigFile);
+                mConfigFile, mCurrentTimeSupplier);
         dir.loadFontFileMap();
         assertThat(dir.getFontFileMap()).isEmpty();
         assertThat(dir.getFontFamilyMap()).isEmpty();
@@ -211,7 +218,7 @@
         FakeFsverityUtil fakeFsverityUtil = new FakeFsverityUtil();
         UpdatableFontDir dirForPreparation = new UpdatableFontDir(
                 mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil,
-                mConfigFile);
+                mConfigFile, mCurrentTimeSupplier);
         dirForPreparation.loadFontFileMap();
         dirForPreparation.update(Arrays.asList(
                 newFontUpdateRequest("foo.ttf,1", GOOD_SIGNATURE),
@@ -229,7 +236,7 @@
                 dirForPreparation.getFontFileMap().get("foo.ttf").getAbsolutePath());
         UpdatableFontDir dir = new UpdatableFontDir(
                 mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil,
-                mConfigFile);
+                mConfigFile, mCurrentTimeSupplier);
         dir.loadFontFileMap();
         assertThat(dir.getFontFileMap()).isEmpty();
         // All font dirs (including dir for "bar.ttf") should be deleted.
@@ -243,7 +250,7 @@
         FakeFsverityUtil fakeFsverityUtil = new FakeFsverityUtil();
         UpdatableFontDir dirForPreparation = new UpdatableFontDir(
                 mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil,
-                mConfigFile);
+                mConfigFile, mCurrentTimeSupplier);
         dirForPreparation.loadFontFileMap();
         dirForPreparation.update(Arrays.asList(
                 newFontUpdateRequest("foo.ttf,1", GOOD_SIGNATURE),
@@ -262,7 +269,7 @@
 
         UpdatableFontDir dir = new UpdatableFontDir(
                 mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil,
-                mConfigFile);
+                mConfigFile, mCurrentTimeSupplier);
         dir.loadFontFileMap();
         assertThat(dir.getFontFileMap()).isEmpty();
         // All font dirs (including dir for "bar.ttf") should be deleted.
@@ -276,7 +283,7 @@
         FakeFsverityUtil fakeFsverityUtil = new FakeFsverityUtil();
         UpdatableFontDir dirForPreparation = new UpdatableFontDir(
                 mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil,
-                mConfigFile);
+                mConfigFile, mCurrentTimeSupplier);
         dirForPreparation.loadFontFileMap();
         dirForPreparation.update(Arrays.asList(
                 newFontUpdateRequest("foo.ttf,1", GOOD_SIGNATURE),
@@ -296,7 +303,7 @@
         FileUtils.stringToFile(new File(mPreinstalledFontDirs.get(1), "bar.ttf"), "bar,2");
         UpdatableFontDir dir = new UpdatableFontDir(
                 mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil,
-                mConfigFile);
+                mConfigFile, mCurrentTimeSupplier);
         dir.loadFontFileMap();
         // For foo.ttf, preinstalled font (revision 5) should be used.
         assertThat(dir.getFontFileMap()).doesNotContainKey("foo.ttf");
@@ -317,7 +324,7 @@
         FakeFsverityUtil fakeFsverityUtil = new FakeFsverityUtil();
         UpdatableFontDir dir = new UpdatableFontDir(
                 mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil,
-                new File("/dev/null"));
+                new File("/dev/null"), mCurrentTimeSupplier);
         dir.loadFontFileMap();
         assertThat(dir.getFontFileMap()).isEmpty();
         assertThat(dir.getFontFamilyMap()).isEmpty();
@@ -329,7 +336,7 @@
         FakeFsverityUtil fakeFsverityUtil = new FakeFsverityUtil();
         UpdatableFontDir dirForPreparation = new UpdatableFontDir(
                 mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil,
-                mConfigFile);
+                mConfigFile, mCurrentTimeSupplier);
         dirForPreparation.loadFontFileMap();
         dirForPreparation.update(Arrays.asList(
                 newFontUpdateRequest("foo.ttf,1", GOOD_SIGNATURE),
@@ -351,7 +358,7 @@
 
         UpdatableFontDir dir = new UpdatableFontDir(
                 mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil,
-                mConfigFile);
+                mConfigFile, mCurrentTimeSupplier);
         dir.loadFontFileMap();
         // The state should be rolled back as a whole if one of the update requests fail.
         assertThat(dir.getFontFileMap()).containsKey("foo.ttf");
@@ -369,7 +376,7 @@
         FakeFsverityUtil fakeFsverityUtil = new FakeFsverityUtil();
         UpdatableFontDir dir = new UpdatableFontDir(
                 mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil,
-                mConfigFile);
+                mConfigFile, mCurrentTimeSupplier);
         dir.loadFontFileMap();
 
         dir.update(Collections.singletonList(newFontUpdateRequest("test.ttf,1", GOOD_SIGNATURE)));
@@ -387,7 +394,7 @@
         FakeFsverityUtil fakeFsverityUtil = new FakeFsverityUtil();
         UpdatableFontDir dir = new UpdatableFontDir(
                 mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil,
-                mConfigFile);
+                mConfigFile, mCurrentTimeSupplier);
         dir.loadFontFileMap();
 
         dir.update(Collections.singletonList(newFontUpdateRequest("test.ttf,1", GOOD_SIGNATURE)));
@@ -406,7 +413,7 @@
         FakeFsverityUtil fakeFsverityUtil = new FakeFsverityUtil();
         UpdatableFontDir dir = new UpdatableFontDir(
                 mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil,
-                mConfigFile);
+                mConfigFile, mCurrentTimeSupplier);
         dir.loadFontFileMap();
 
         dir.update(Collections.singletonList(newFontUpdateRequest("test.ttf,2", GOOD_SIGNATURE)));
@@ -428,7 +435,7 @@
         FakeFsverityUtil fakeFsverityUtil = new FakeFsverityUtil();
         UpdatableFontDir dir = new UpdatableFontDir(
                 mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil,
-                mConfigFile);
+                mConfigFile, mCurrentTimeSupplier);
         dir.loadFontFileMap();
 
         dir.update(Collections.singletonList(newFontUpdateRequest("foo.ttf,1", GOOD_SIGNATURE)));
@@ -445,7 +452,7 @@
         FakeFsverityUtil fakeFsverityUtil = new FakeFsverityUtil();
         UpdatableFontDir dir = new UpdatableFontDir(
                 mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil,
-                mConfigFile);
+                mConfigFile, mCurrentTimeSupplier);
         dir.loadFontFileMap();
 
         dir.update(Arrays.asList(
@@ -463,7 +470,7 @@
         FakeFsverityUtil fakeFsverityUtil = new FakeFsverityUtil();
         UpdatableFontDir dir = new UpdatableFontDir(
                 mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil,
-                mConfigFile);
+                mConfigFile, mCurrentTimeSupplier);
         dir.loadFontFileMap();
 
         try {
@@ -485,7 +492,7 @@
         FileUtils.stringToFile(new File(mPreinstalledFontDirs.get(0), "test.ttf"), "test.ttf,1");
         UpdatableFontDir dir = new UpdatableFontDir(
                 mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil,
-                mConfigFile);
+                mConfigFile, mCurrentTimeSupplier);
         dir.loadFontFileMap();
 
         try {
@@ -517,7 +524,7 @@
         try {
             UpdatableFontDir dir = new UpdatableFontDir(
                     mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil,
-                    readonlyFile);
+                    readonlyFile, mCurrentTimeSupplier);
             dir.loadFontFileMap();
 
             try {
@@ -551,7 +558,7 @@
                     public long getRevision(File file) throws IOException {
                         return 0;
                     }
-                }, fakeFsverityUtil, mConfigFile);
+                }, fakeFsverityUtil, mConfigFile, mCurrentTimeSupplier);
         dir.loadFontFileMap();
 
         try {
@@ -580,7 +587,7 @@
                     public long getRevision(File file) throws IOException {
                         return 0;
                     }
-                }, fakeFsverityUtil, mConfigFile);
+                }, fakeFsverityUtil, mConfigFile, mCurrentTimeSupplier);
         dir.loadFontFileMap();
 
         try {
@@ -617,7 +624,7 @@
         FakeFontFileParser parser = new FakeFontFileParser();
         UpdatableFontDir dir = new UpdatableFontDir(
                 mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil,
-                mConfigFile);
+                mConfigFile, mCurrentTimeSupplier);
         dir.loadFontFileMap();
 
         try {
@@ -637,7 +644,7 @@
         FakeFsverityUtil fakeFsverityUtil = new FakeFsverityUtil();
         UpdatableFontDir dir = new UpdatableFontDir(
                 mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil,
-                mConfigFile);
+                mConfigFile, mCurrentTimeSupplier);
         dir.loadFontFileMap();
 
         dir.update(Collections.singletonList(newFontUpdateRequest("foo.ttf,1", GOOD_SIGNATURE)));
@@ -660,7 +667,7 @@
         FakeFsverityUtil fakeFsverityUtil = new FakeFsverityUtil();
         UpdatableFontDir dir = new UpdatableFontDir(
                 mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil,
-                mConfigFile);
+                mConfigFile, mCurrentTimeSupplier);
         dir.loadFontFileMap();
 
         dir.update(Arrays.asList(
@@ -682,7 +689,7 @@
         FakeFsverityUtil fakeFsverityUtil = new FakeFsverityUtil();
         UpdatableFontDir dir = new UpdatableFontDir(
                 mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil,
-                mConfigFile);
+                mConfigFile, mCurrentTimeSupplier);
         dir.loadFontFileMap();
 
         try {
@@ -703,7 +710,7 @@
         FakeFsverityUtil fakeFsverityUtil = new FakeFsverityUtil();
         UpdatableFontDir dir = new UpdatableFontDir(
                 mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil,
-                mConfigFile);
+                mConfigFile, mCurrentTimeSupplier);
         dir.loadFontFileMap();
 
         try {
@@ -723,7 +730,7 @@
         FakeFsverityUtil fakeFsverityUtil = new FakeFsverityUtil();
         UpdatableFontDir dir = new UpdatableFontDir(
                 mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil,
-                mConfigFile);
+                mConfigFile, mCurrentTimeSupplier);
         dir.loadFontFileMap();
         // We assume we have monospace.
         assertNamedFamilyExists(dir.getSystemFontConfig(), "monospace");
@@ -755,7 +762,7 @@
         FakeFsverityUtil fakeFsverityUtil = new FakeFsverityUtil();
         UpdatableFontDir dir = new UpdatableFontDir(
                 mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil,
-                mConfigFile);
+                mConfigFile, mCurrentTimeSupplier);
         dir.loadFontFileMap();
         assertThat(dir.getSystemFontConfig().getFontFamilies()).isNotEmpty();
         FontConfig.FontFamily firstFontFamily = dir.getSystemFontConfig().getFontFamilies().get(0);
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/ArcInitiationActionFromAvrTest.java b/services/tests/servicestests/src/com/android/server/hdmi/ArcInitiationActionFromAvrTest.java
index 50ba761..ee9de07 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/ArcInitiationActionFromAvrTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/ArcInitiationActionFromAvrTest.java
@@ -107,7 +107,7 @@
                     }
 
                     @Override
-                    Looper getServiceLooper() {
+                    protected Looper getServiceLooper() {
                         return mTestLooper.getLooper();
                     }
                 };
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java b/services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java
index aa5bc93..d5df071 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java
@@ -108,7 +108,7 @@
                     }
 
                     @Override
-                    Looper getServiceLooper() {
+                    protected Looper getServiceLooper() {
                         return mTestLooper.getLooper();
                     }
                 };
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/DetectTvSystemAudioModeSupportActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/DetectTvSystemAudioModeSupportActionTest.java
index 41f4a1e..8b23be5 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/DetectTvSystemAudioModeSupportActionTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/DetectTvSystemAudioModeSupportActionTest.java
@@ -91,7 +91,7 @@
                     }
 
                     @Override
-                    Looper getServiceLooper() {
+                    protected Looper getServiceLooper() {
                         return mTestLooper.getLooper();
                     }
                 };
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecControllerTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecControllerTest.java
index b3ee18d..ee1a857 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecControllerTest.java
@@ -19,21 +19,35 @@
 import static android.hardware.hdmi.HdmiDeviceInfo.DEVICE_PLAYBACK;
 import static android.hardware.hdmi.HdmiDeviceInfo.DEVICE_TV;
 
+import static com.android.server.hdmi.Constants.ABORT_REFUSED;
+import static com.android.server.hdmi.Constants.ABORT_UNRECOGNIZED_OPCODE;
 import static com.android.server.hdmi.Constants.ADDR_AUDIO_SYSTEM;
 import static com.android.server.hdmi.Constants.ADDR_BACKUP_1;
 import static com.android.server.hdmi.Constants.ADDR_BACKUP_2;
+import static com.android.server.hdmi.Constants.ADDR_BROADCAST;
 import static com.android.server.hdmi.Constants.ADDR_PLAYBACK_1;
 import static com.android.server.hdmi.Constants.ADDR_PLAYBACK_2;
 import static com.android.server.hdmi.Constants.ADDR_PLAYBACK_3;
 import static com.android.server.hdmi.Constants.ADDR_SPECIFIC_USE;
 import static com.android.server.hdmi.Constants.ADDR_TV;
 import static com.android.server.hdmi.Constants.ADDR_UNREGISTERED;
+import static com.android.server.hdmi.Constants.HANDLED;
+import static com.android.server.hdmi.Constants.MESSAGE_STANDBY;
+import static com.android.server.hdmi.Constants.NOT_HANDLED;
+
+import static com.google.common.truth.Truth.assertThat;
 
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertTrue;
 
-import android.content.Context;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+
 import android.hardware.hdmi.HdmiControlManager;
 import android.hardware.tv.cec.V1_0.SendMessageResult;
 import android.os.Binder;
@@ -44,6 +58,7 @@
 import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.SmallTest;
 
+import com.android.server.SystemService;
 import com.android.server.hdmi.HdmiCecController.AllocateAddressCallback;
 
 import junit.framework.TestCase;
@@ -53,6 +68,7 @@
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
 
+import java.util.ArrayList;
 import java.util.Optional;
 
 /** Tests for {@link com.android.server.hdmi.HdmiCecController} class. */
@@ -63,27 +79,7 @@
 
     private FakeNativeWrapper mNativeWrapper;
 
-    private class MyHdmiControlService extends HdmiControlService {
-
-        MyHdmiControlService(Context context) {
-            super(context);
-        }
-
-        @Override
-        Looper getIoLooper() {
-            return mMyLooper;
-        }
-
-        @Override
-        Looper getServiceLooper() {
-            return mMyLooper;
-        }
-
-        @Override
-        int getCecVersion() {
-            return mCecVersion;
-        }
-    }
+    private HdmiControlService mHdmiControlServiceSpy;
 
     private HdmiCecController mHdmiCecController;
     private int mCecVersion = HdmiControlManager.HDMI_CEC_VERSION_1_4_B;
@@ -101,12 +97,39 @@
     @Before
     public void SetUp() {
         mMyLooper = mTestLooper.getLooper();
-        mMyLooper = mTestLooper.getLooper();
-        HdmiControlService hdmiControlService = new MyHdmiControlService(
-                InstrumentationRegistry.getTargetContext());
+
+        mHdmiControlServiceSpy = spy(new HdmiControlService(
+                InstrumentationRegistry.getTargetContext()));
+        doReturn(mMyLooper).when(mHdmiControlServiceSpy).getIoLooper();
+        doReturn(mMyLooper).when(mHdmiControlServiceSpy).getServiceLooper();
+        doAnswer(__ -> mCecVersion).when(mHdmiControlServiceSpy).getCecVersion();
+        doNothing().when(mHdmiControlServiceSpy)
+                .writeStringSystemProperty(anyString(), anyString());
+
         mNativeWrapper = new FakeNativeWrapper();
         mHdmiCecController = HdmiCecController.createWithNativeWrapper(
-                hdmiControlService, mNativeWrapper, hdmiControlService.getAtomWriter());
+                mHdmiControlServiceSpy, mNativeWrapper, mHdmiControlServiceSpy.getAtomWriter());
+    }
+
+    /** Additional setup for tests for onMessage
+     *  Adds a local playback device and allocates addresses
+     */
+    public void setUpForOnMessageTest() {
+        mHdmiControlServiceSpy.setCecController(mHdmiCecController);
+
+        HdmiCecLocalDevicePlayback playbackDevice =
+                new HdmiCecLocalDevicePlayback(mHdmiControlServiceSpy);
+        playbackDevice.init();
+
+        ArrayList<HdmiCecLocalDevice> localDevices = new ArrayList<>();
+        localDevices.add(playbackDevice);
+
+        mHdmiControlServiceSpy.initService();
+        mHdmiControlServiceSpy.allocateLogicalAddress(localDevices,
+                HdmiControlService.INITIATED_BY_ENABLE_CEC);
+        mHdmiControlServiceSpy.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
+
+        mTestLooper.dispatchAll();
     }
 
     /** Tests for {@link HdmiCecController#allocateLogicalAddress} */
@@ -119,7 +142,6 @@
 
     @Test
     public void testAllocateLogicalAddress_TvDeviceNonPreferredNotOccupied() {
-
         mHdmiCecController.allocateLogicalAddress(DEVICE_TV, ADDR_UNREGISTERED, mCallback);
         mTestLooper.dispatchAll();
         assertEquals(ADDR_TV, mLogicalAddress);
@@ -308,4 +330,90 @@
         TestCase.assertEquals(Optional.of(callerUid), uidReadingRunnable.getWorkSourceUid());
         TestCase.assertEquals(runnerUid, Binder.getCallingWorkSourceUid());
     }
+
+    @Test
+    public void onMessage_broadcastMessage_doesNotSendFeatureAbort() {
+        setUpForOnMessageTest();
+
+        doReturn(ABORT_UNRECOGNIZED_OPCODE).when(mHdmiControlServiceSpy).handleCecCommand(any());
+
+        HdmiCecMessage receivedMessage = HdmiCecMessageBuilder.buildStandby(
+                ADDR_TV, ADDR_BROADCAST);
+
+        mNativeWrapper.onCecMessage(receivedMessage);
+
+        mTestLooper.dispatchAll();
+
+        assertFalse("No <Feature Abort> messages should be sent",
+                mNativeWrapper.getResultMessages().stream().anyMatch(
+                        message -> message.getOpcode() == Constants.MESSAGE_FEATURE_ABORT));
+    }
+
+    @Test
+    public void onMessage_notTheDestination_doesNotSendFeatureAbort() {
+        setUpForOnMessageTest();
+
+        doReturn(ABORT_UNRECOGNIZED_OPCODE).when(mHdmiControlServiceSpy).handleCecCommand(any());
+
+        HdmiCecMessage receivedMessage = HdmiCecMessageBuilder.buildStandby(
+                ADDR_TV, ADDR_AUDIO_SYSTEM);
+        mNativeWrapper.onCecMessage(receivedMessage);
+
+        mTestLooper.dispatchAll();
+
+        assertFalse("No <Feature Abort> messages should be sent",
+                mNativeWrapper.getResultMessages().stream().anyMatch(
+                        message -> message.getOpcode() == Constants.MESSAGE_FEATURE_ABORT));
+    }
+
+    @Test
+    public void onMessage_handledMessage_doesNotSendFeatureAbort() {
+        setUpForOnMessageTest();
+
+        doReturn(HANDLED).when(mHdmiControlServiceSpy).handleCecCommand(any());
+
+        HdmiCecMessage receivedMessage = HdmiCecMessageBuilder.buildStandby(
+                ADDR_TV, ADDR_PLAYBACK_1);
+        mNativeWrapper.onCecMessage(receivedMessage);
+
+        mTestLooper.dispatchAll();
+
+        assertFalse("No <Feature Abort> messages should be sent",
+                mNativeWrapper.getResultMessages().stream().anyMatch(
+                        message -> message.getOpcode() == Constants.MESSAGE_FEATURE_ABORT));
+    }
+
+    @Test
+    public void onMessage_unhandledMessage_sendsFeatureAbortUnrecognizedOpcode() {
+        setUpForOnMessageTest();
+
+        doReturn(NOT_HANDLED).when(mHdmiControlServiceSpy).handleCecCommand(any());
+
+        HdmiCecMessage receivedMessage = HdmiCecMessageBuilder.buildStandby(
+                ADDR_TV, ADDR_PLAYBACK_1);
+        mNativeWrapper.onCecMessage(receivedMessage);
+
+        mTestLooper.dispatchAll();
+
+        HdmiCecMessage featureAbort = HdmiCecMessageBuilder.buildFeatureAbortCommand(
+                DEVICE_PLAYBACK, DEVICE_TV, MESSAGE_STANDBY, ABORT_UNRECOGNIZED_OPCODE);
+        assertThat(mNativeWrapper.getResultMessages()).contains(featureAbort);
+    }
+
+    @Test
+    public void onMessage_sendsFeatureAbortWithRequestedOperand() {
+        setUpForOnMessageTest();
+
+        doReturn(ABORT_REFUSED).when(mHdmiControlServiceSpy).handleCecCommand(any());
+
+        HdmiCecMessage receivedMessage = HdmiCecMessageBuilder.buildStandby(
+                ADDR_TV, ADDR_PLAYBACK_1);
+        mNativeWrapper.onCecMessage(receivedMessage);
+
+        mTestLooper.dispatchAll();
+
+        HdmiCecMessage featureAbort = HdmiCecMessageBuilder.buildFeatureAbortCommand(
+                DEVICE_PLAYBACK, DEVICE_TV, MESSAGE_STANDBY, ABORT_REFUSED);
+        assertThat(mNativeWrapper.getResultMessages()).contains(featureAbort);
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java
index 6bb148d..38a44c6 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java
@@ -20,7 +20,6 @@
 import static com.android.server.hdmi.Constants.ADDR_PLAYBACK_1;
 import static com.android.server.hdmi.Constants.ADDR_TUNER_1;
 import static com.android.server.hdmi.Constants.ADDR_TV;
-import static com.android.server.hdmi.Constants.MESSAGE_GIVE_AUDIO_STATUS;
 import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC;
 import static com.android.server.hdmi.HdmiControlService.STANDBY_SCREEN_OFF;
 
@@ -248,7 +247,8 @@
                         ADDR_AUDIO_SYSTEM, ADDR_TV, scaledVolume, true);
         HdmiCecMessage messageGive =
                 HdmiCecMessageBuilder.buildGiveAudioStatus(ADDR_TV, ADDR_AUDIO_SYSTEM);
-        assertThat(mHdmiCecLocalDeviceAudioSystem.handleGiveAudioStatus(messageGive)).isTrue();
+        assertThat(mHdmiCecLocalDeviceAudioSystem.handleGiveAudioStatus(messageGive))
+            .isEqualTo(Constants.HANDLED);
         mTestLooper.dispatchAll();
         assertThat(mNativeWrapper.getOnlyResultMessage()).isEqualTo(expectedMessage);
     }
@@ -262,45 +262,25 @@
         HdmiCecMessage messageGive =
                 HdmiCecMessageBuilder.buildGiveSystemAudioModeStatus(ADDR_TV, ADDR_AUDIO_SYSTEM);
         assertThat(mHdmiCecLocalDeviceAudioSystem.handleGiveSystemAudioModeStatus(messageGive))
-            .isTrue();
+                .isEqualTo(Constants.HANDLED);
         mTestLooper.dispatchAll();
         assertThat(mNativeWrapper.getOnlyResultMessage()).isEqualTo(expectedMessage);
     }
 
     @Test
     public void handleRequestShortAudioDescriptor_featureDisabled() throws Exception {
-        HdmiCecMessage expectedMessage =
-                HdmiCecMessageBuilder.buildFeatureAbortCommand(
-                        ADDR_AUDIO_SYSTEM,
-                        ADDR_TV,
-                        Constants.MESSAGE_REQUEST_SHORT_AUDIO_DESCRIPTOR,
-                        Constants.ABORT_REFUSED);
-
         mHdmiCecLocalDeviceAudioSystem.setSystemAudioControlFeatureEnabled(false);
-        assertThat(
-            mHdmiCecLocalDeviceAudioSystem.handleRequestShortAudioDescriptor(
+        assertThat(mHdmiCecLocalDeviceAudioSystem.handleRequestShortAudioDescriptor(
                 MESSAGE_REQUEST_SAD_LCPM))
-            .isTrue();
-        mTestLooper.dispatchAll();
-        assertThat(mNativeWrapper.getOnlyResultMessage()).isEqualTo(expectedMessage);
+                .isEqualTo(Constants.ABORT_REFUSED);
     }
 
     @Test
     public void handleRequestShortAudioDescriptor_samOff() throws Exception {
-        HdmiCecMessage expectedMessage =
-                HdmiCecMessageBuilder.buildFeatureAbortCommand(
-                        ADDR_AUDIO_SYSTEM,
-                        ADDR_TV,
-                        Constants.MESSAGE_REQUEST_SHORT_AUDIO_DESCRIPTOR,
-                        Constants.ABORT_NOT_IN_CORRECT_MODE);
-
         mHdmiCecLocalDeviceAudioSystem.checkSupportAndSetSystemAudioMode(false);
-        assertThat(
-            mHdmiCecLocalDeviceAudioSystem.handleRequestShortAudioDescriptor(
+        assertThat(mHdmiCecLocalDeviceAudioSystem.handleRequestShortAudioDescriptor(
                 MESSAGE_REQUEST_SAD_LCPM))
-            .isEqualTo(true);
-        mTestLooper.dispatchAll();
-        assertThat(mNativeWrapper.getOnlyResultMessage()).isEqualTo(expectedMessage);
+                .isEqualTo(Constants.ABORT_NOT_IN_CORRECT_MODE);
     }
 
     // Testing device has sadConfig.xml
@@ -315,10 +295,9 @@
                         Constants.ABORT_UNABLE_TO_DETERMINE);
 
         mHdmiCecLocalDeviceAudioSystem.checkSupportAndSetSystemAudioMode(true);
-        assertThat(
-            mHdmiCecLocalDeviceAudioSystem.handleRequestShortAudioDescriptor(
+        assertThat(mHdmiCecLocalDeviceAudioSystem.handleRequestShortAudioDescriptor(
                 MESSAGE_REQUEST_SAD_LCPM))
-            .isEqualTo(true);
+                .isEqualTo(Constants.HANDLED);
         mTestLooper.dispatchAll();
         assertThat(mNativeWrapper.getOnlyResultMessage()).isEqualTo(expectedMessage);
     }
@@ -335,17 +314,18 @@
         HdmiCecMessage expectedMessage =
                 HdmiCecMessageBuilder.buildReportSystemAudioMode(ADDR_AUDIO_SYSTEM, ADDR_TV, false);
         assertThat(mHdmiCecLocalDeviceAudioSystem.handleGiveSystemAudioModeStatus(messageGive))
-            .isTrue();
+            .isEqualTo(Constants.HANDLED);
         mTestLooper.dispatchAll();
         assertThat(mNativeWrapper.getOnlyResultMessage()).isEqualTo(expectedMessage);
         // Check if correctly turned on
         mNativeWrapper.clearResultMessages();
         expectedMessage =
             HdmiCecMessageBuilder.buildReportSystemAudioMode(ADDR_AUDIO_SYSTEM, ADDR_TV, true);
-        assertThat(mHdmiCecLocalDeviceAudioSystem.handleSetSystemAudioMode(messageSet)).isTrue();
+        assertThat(mHdmiCecLocalDeviceAudioSystem.handleSetSystemAudioMode(messageSet))
+                .isEqualTo(Constants.HANDLED);
         mTestLooper.dispatchAll();
         assertThat(mHdmiCecLocalDeviceAudioSystem.handleGiveSystemAudioModeStatus(messageGive))
-            .isTrue();
+                .isEqualTo(Constants.HANDLED);
         mTestLooper.dispatchAll();
         assertThat(mNativeWrapper.getOnlyResultMessage()).isEqualTo(expectedMessage);
         assertThat(mMusicMute).isFalse();
@@ -365,7 +345,7 @@
                 HdmiCecMessageBuilder.buildSetSystemAudioMode(
                         ADDR_AUDIO_SYSTEM, ADDR_BROADCAST, false);
         assertThat(mHdmiCecLocalDeviceAudioSystem.handleSystemAudioModeRequest(messageRequestOff))
-            .isTrue();
+                .isEqualTo(Constants.HANDLED);
         mTestLooper.dispatchAll();
         assertThat(mNativeWrapper.getOnlyResultMessage()).isEqualTo(expectedMessage);
 
@@ -373,7 +353,7 @@
         expectedMessage =
             HdmiCecMessageBuilder.buildReportSystemAudioMode(ADDR_AUDIO_SYSTEM, ADDR_TV, false);
         assertThat(mHdmiCecLocalDeviceAudioSystem.handleGiveSystemAudioModeStatus(messageGive))
-            .isTrue();
+            .isEqualTo(Constants.HANDLED);
         mTestLooper.dispatchAll();
         assertThat(mNativeWrapper.getOnlyResultMessage()).isEqualTo(expectedMessage);
         assertThat(mMusicMute).isTrue();
@@ -441,7 +421,8 @@
     public void handleActiveSource_updateActiveSource() throws Exception {
         HdmiCecMessage message = HdmiCecMessageBuilder.buildActiveSource(ADDR_TV, 0x0000);
         ActiveSource expectedActiveSource = new ActiveSource(ADDR_TV, 0x0000);
-        assertThat(mHdmiCecLocalDeviceAudioSystem.handleActiveSource(message)).isTrue();
+        assertThat(mHdmiCecLocalDeviceAudioSystem.handleActiveSource(message))
+                .isEqualTo(Constants.HANDLED);
         mTestLooper.dispatchAll();
         assertThat(mHdmiCecLocalDeviceAudioSystem.getActiveSource().equals(expectedActiveSource))
             .isTrue();
@@ -513,17 +494,10 @@
     public void handleRequestArcInitiate_isNotDirectConnectedToTv() throws Exception {
         HdmiCecMessage message =
                 HdmiCecMessageBuilder.buildRequestArcInitiation(ADDR_TV, ADDR_AUDIO_SYSTEM);
-        HdmiCecMessage expectedMessage =
-                HdmiCecMessageBuilder.buildFeatureAbortCommand(
-                        ADDR_AUDIO_SYSTEM,
-                        ADDR_TV,
-                        Constants.MESSAGE_REQUEST_ARC_INITIATION,
-                        Constants.ABORT_NOT_IN_CORRECT_MODE);
         mNativeWrapper.setPhysicalAddress(0x1100);
 
-        assertThat(mHdmiCecLocalDeviceAudioSystem.handleRequestArcInitiate(message)).isTrue();
-        mTestLooper.dispatchAll();
-        assertThat(mNativeWrapper.getResultMessages()).contains(expectedMessage);
+        assertThat(mHdmiCecLocalDeviceAudioSystem.handleRequestArcInitiate(message))
+                .isEqualTo(Constants.ABORT_NOT_IN_CORRECT_MODE);
     }
 
     @Test
@@ -533,7 +507,8 @@
         mNativeWrapper.setPhysicalAddress(0x1000);
         mHdmiCecLocalDeviceAudioSystem.removeAction(ArcInitiationActionFromAvr.class);
 
-        assertThat(mHdmiCecLocalDeviceAudioSystem.handleRequestArcInitiate(message)).isTrue();
+        assertThat(mHdmiCecLocalDeviceAudioSystem.handleRequestArcInitiate(message))
+                .isEqualTo(Constants.HANDLED);
         mTestLooper.dispatchAll();
         assertThat(mHdmiCecLocalDeviceAudioSystem.getActions(ArcInitiationActionFromAvr.class))
             .isNotEmpty();
@@ -548,7 +523,8 @@
                 HdmiCecMessageBuilder.buildRequestArcTermination(ADDR_TV, ADDR_AUDIO_SYSTEM);
         mHdmiCecLocalDeviceAudioSystem.removeAction(ArcTerminationActionFromAvr.class);
 
-        assertThat(mHdmiCecLocalDeviceAudioSystem.handleRequestArcTermination(message)).isTrue();
+        assertThat(mHdmiCecLocalDeviceAudioSystem.handleRequestArcTermination(message))
+                .isEqualTo(Constants.HANDLED);
         mTestLooper.dispatchAll();
         assertThat(mHdmiCecLocalDeviceAudioSystem.getActions(ArcTerminationActionFromAvr.class))
             .isNotEmpty();
@@ -567,7 +543,8 @@
                         Constants.MESSAGE_REQUEST_ARC_TERMINATION,
                         Constants.ABORT_NOT_IN_CORRECT_MODE);
 
-        assertThat(mHdmiCecLocalDeviceAudioSystem.handleRequestArcTermination(message)).isTrue();
+        assertThat(mHdmiCecLocalDeviceAudioSystem.handleRequestArcTermination(message))
+                .isEqualTo(Constants.HANDLED);
         mTestLooper.dispatchAll();
         assertThat(mNativeWrapper.getResultMessages()).contains(expectedMessage);
     }
@@ -576,17 +553,10 @@
     public void handleRequestArcInit_arcIsNotSupported() throws Exception {
         HdmiCecMessage message =
                 HdmiCecMessageBuilder.buildRequestArcInitiation(ADDR_TV, ADDR_AUDIO_SYSTEM);
-        HdmiCecMessage expectedMessage =
-                HdmiCecMessageBuilder.buildFeatureAbortCommand(
-                        ADDR_AUDIO_SYSTEM,
-                        ADDR_TV,
-                        Constants.MESSAGE_REQUEST_ARC_INITIATION,
-                        Constants.ABORT_UNRECOGNIZED_OPCODE);
         mArcSupport = false;
 
-        assertThat(mHdmiCecLocalDeviceAudioSystem.handleRequestArcInitiate(message)).isTrue();
-        mTestLooper.dispatchAll();
-        assertThat(mNativeWrapper.getOnlyResultMessage()).isEqualTo(expectedMessage);
+        assertThat(mHdmiCecLocalDeviceAudioSystem.handleRequestArcInitiate(message))
+                .isEqualTo(Constants.ABORT_UNRECOGNIZED_OPCODE);
     }
 
     @Test
@@ -612,7 +582,8 @@
                         Constants.MESSAGE_SYSTEM_AUDIO_MODE_REQUEST,
                         Constants.ABORT_REFUSED);
 
-        assertThat(mHdmiCecLocalDeviceAudioSystem.handleSystemAudioModeRequest(message)).isTrue();
+        assertThat(mHdmiCecLocalDeviceAudioSystem.handleSystemAudioModeRequest(message))
+                .isEqualTo(Constants.ABORT_UNRECOGNIZED_OPCODE);
         mTestLooper.dispatchAll();
         assertThat(mNativeWrapper.getOnlyResultMessage()).isEqualTo(expectedMessage);
     }
@@ -629,7 +600,8 @@
         mHdmiCecLocalDeviceAudioSystem.setTvSystemAudioModeSupport(true);
 
 
-        assertThat(mHdmiCecLocalDeviceAudioSystem.handleSystemAudioModeRequest(message)).isTrue();
+        assertThat(mHdmiCecLocalDeviceAudioSystem.handleSystemAudioModeRequest(message))
+                .isEqualTo(Constants.HANDLED);
         mTestLooper.dispatchAll();
         assertThat(mNativeWrapper.getOnlyResultMessage()).isEqualTo(expectedMessage);
     }
@@ -642,7 +614,8 @@
 
         ActiveSource expectedActiveSource = ActiveSource.of(ADDR_TV, 0x0000);
 
-        assertThat(mHdmiCecLocalDeviceAudioSystem.handleActiveSource(message)).isTrue();
+        assertThat(mHdmiCecLocalDeviceAudioSystem.handleActiveSource(message))
+                .isEqualTo(Constants.HANDLED);
         mTestLooper.dispatchAll();
         assertThat(mHdmiCecLocalDeviceAudioSystem.getActiveSource())
             .isEqualTo(expectedActiveSource);
@@ -659,7 +632,8 @@
         ActiveSource expectedActiveSource = ActiveSource.of(ADDR_PLAYBACK_1, SELF_PHYSICAL_ADDRESS);
         int expectedLocalActivePort = Constants.CEC_SWITCH_HOME;
 
-        assertThat(mHdmiCecLocalDeviceAudioSystem.handleRoutingChange(message)).isTrue();
+        assertThat(mHdmiCecLocalDeviceAudioSystem.handleRoutingChange(message))
+                .isEqualTo(Constants.HANDLED);
         mTestLooper.dispatchAll();
         assertThat(mHdmiCecLocalDeviceAudioSystem.getActiveSource())
             .isEqualTo(expectedActiveSource);
@@ -677,7 +651,8 @@
                 HdmiCecMessageBuilder.buildRoutingInformation(
                         ADDR_AUDIO_SYSTEM, HDMI_1_PHYSICAL_ADDRESS);
 
-        assertThat(mHdmiCecLocalDeviceAudioSystem.handleRoutingInformation(message)).isTrue();
+        assertThat(mHdmiCecLocalDeviceAudioSystem.handleRoutingInformation(message))
+                .isEqualTo(Constants.HANDLED);
         mTestLooper.dispatchAll();
         assertThat(mNativeWrapper.getOnlyResultMessage()).isEqualTo(expectedMessage);
     }
@@ -691,7 +666,8 @@
         HdmiCecMessage expectedMessage =
                 HdmiCecMessageBuilder.buildActiveSource(ADDR_PLAYBACK_1, 0x2000);
 
-        assertThat(mHdmiCecLocalDeviceAudioSystem.handleRoutingChange(message)).isTrue();
+        assertThat(mHdmiCecLocalDeviceAudioSystem.handleRoutingChange(message))
+                .isEqualTo(Constants.HANDLED);
         mTestLooper.dispatchAll();
         assertThat(mNativeWrapper.getResultMessages()).contains(expectedMessage);
     }
@@ -727,18 +703,15 @@
         int scaledVolume = VolumeControlAction.scaleToCecVolume(volume, maxVolume);
         HdmiCecMessage expected = HdmiCecMessageBuilder.buildReportAudioStatus(ADDR_AUDIO_SYSTEM,
                 ADDR_TV, scaledVolume, mute);
-        HdmiCecMessage featureAbort = HdmiCecMessageBuilder.buildFeatureAbortCommand(
-                ADDR_AUDIO_SYSTEM, ADDR_TV, MESSAGE_GIVE_AUDIO_STATUS, Constants.ABORT_REFUSED);
 
         HdmiCecMessage giveAudioStatus = HdmiCecMessageBuilder.buildGiveAudioStatus(ADDR_TV,
                 ADDR_AUDIO_SYSTEM);
         mNativeWrapper.clearResultMessages();
-        boolean handled = mHdmiCecLocalDeviceAudioSystem.handleGiveAudioStatus(giveAudioStatus);
+        assertThat(mHdmiCecLocalDeviceAudioSystem.handleGiveAudioStatus(giveAudioStatus))
+                        .isEqualTo(Constants.HANDLED);
         mTestLooper.dispatchAll();
 
         assertThat(mNativeWrapper.getResultMessages()).contains(expected);
-        assertThat(mNativeWrapper.getResultMessages()).doesNotContain(featureAbort);
-        assertThat(handled).isTrue();
     }
 
     @Test
@@ -758,18 +731,15 @@
         int scaledVolume = VolumeControlAction.scaleToCecVolume(volume, maxVolume);
         HdmiCecMessage unexpected = HdmiCecMessageBuilder.buildReportAudioStatus(ADDR_AUDIO_SYSTEM,
                 ADDR_TV, scaledVolume, mute);
-        HdmiCecMessage featureAbort = HdmiCecMessageBuilder.buildFeatureAbortCommand(
-                ADDR_AUDIO_SYSTEM, ADDR_TV, MESSAGE_GIVE_AUDIO_STATUS, Constants.ABORT_REFUSED);
 
         HdmiCecMessage giveAudioStatus = HdmiCecMessageBuilder.buildGiveAudioStatus(ADDR_TV,
                 ADDR_AUDIO_SYSTEM);
         mNativeWrapper.clearResultMessages();
-        boolean handled = mHdmiCecLocalDeviceAudioSystem.handleGiveAudioStatus(giveAudioStatus);
+        assertThat(mHdmiCecLocalDeviceAudioSystem.handleGiveAudioStatus(giveAudioStatus))
+                .isEqualTo(Constants.ABORT_REFUSED);
         mTestLooper.dispatchAll();
 
-        assertThat(mNativeWrapper.getResultMessages()).contains(featureAbort);
         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(unexpected);
-        assertThat(handled).isTrue();
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
index 1a6bad8..80da696 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
@@ -113,7 +113,7 @@
                     }
 
                     @Override
-                    boolean isStandbyMessageReceived() {
+                    protected boolean isStandbyMessageReceived() {
                         return mStandby;
                     }
 
@@ -184,7 +184,8 @@
                 HdmiCecMessageBuilder.buildActiveSource(mPlaybackLogicalAddress,
                         mPlaybackPhysicalAddress);
 
-        assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message)).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message))
+                .isEqualTo(Constants.HANDLED);
         mTestLooper.dispatchAll();
         assertThat(mWokenUp).isFalse();
         assertThat(mNativeWrapper.getResultMessages().contains(expectedMessage)).isFalse();
@@ -205,7 +206,8 @@
                 HdmiCecMessageBuilder.buildActiveSource(mPlaybackLogicalAddress,
                         mPlaybackPhysicalAddress);
 
-        assertThat(mHdmiCecLocalDevicePlayback.handleRoutingInformation(message)).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.handleRoutingInformation(message))
+                .isEqualTo(Constants.HANDLED);
         mTestLooper.dispatchAll();
         assertThat(mWokenUp).isFalse();
         assertThat(mNativeWrapper.getResultMessages().contains(expectedMessage)).isFalse();
@@ -226,7 +228,8 @@
                 HdmiCecMessageBuilder.buildActiveSource(mPlaybackLogicalAddress,
                         mPlaybackPhysicalAddress);
 
-        assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message)).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message))
+                .isEqualTo(Constants.HANDLED);
         mTestLooper.dispatchAll();
         assertThat(mWokenUp).isTrue();
         assertThat(mNativeWrapper.getResultMessages().contains(expectedMessage)).isFalse();
@@ -247,7 +250,8 @@
                 HdmiCecMessageBuilder.buildActiveSource(mPlaybackLogicalAddress,
                         mPlaybackPhysicalAddress);
 
-        assertThat(mHdmiCecLocalDevicePlayback.handleRoutingInformation(message)).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.handleRoutingInformation(message))
+                .isEqualTo(Constants.HANDLED);
         mTestLooper.dispatchAll();
         assertThat(mWokenUp).isTrue();
         assertThat(mNativeWrapper.getResultMessages().contains(expectedMessage)).isFalse();
@@ -270,7 +274,8 @@
                 HdmiCecMessageBuilder.buildActiveSource(mPlaybackLogicalAddress,
                         mPlaybackPhysicalAddress);
 
-        assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message)).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message))
+                .isEqualTo(Constants.HANDLED);
         mTestLooper.dispatchAll();
         assertThat(mWokenUp).isTrue();
         assertThat(mNativeWrapper.getResultMessages()).contains(expectedMessage);
@@ -293,7 +298,8 @@
                 HdmiCecMessageBuilder.buildActiveSource(mPlaybackLogicalAddress,
                         mPlaybackPhysicalAddress);
 
-        assertThat(mHdmiCecLocalDevicePlayback.handleRoutingInformation(message)).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.handleRoutingInformation(message))
+                .isEqualTo(Constants.HANDLED);
         mTestLooper.dispatchAll();
         assertThat(mWokenUp).isTrue();
         assertThat(mNativeWrapper.getResultMessages()).contains(expectedMessage);
@@ -309,7 +315,8 @@
         mStandby = false;
         HdmiCecMessage message =
                 HdmiCecMessageBuilder.buildRoutingChange(ADDR_TV, 0x0000, 0x5000);
-        assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message)).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message))
+                .isEqualTo(Constants.HANDLED);
         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
         assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress).isEqualTo(
                 0x5000);
@@ -329,7 +336,8 @@
         HdmiCecMessage message =
                 HdmiCecMessageBuilder.buildRoutingChange(ADDR_TV, 0x0000,
                         mPlaybackPhysicalAddress);
-        assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message)).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message))
+                .isEqualTo(Constants.HANDLED);
         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isTrue();
         assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress).isEqualTo(
                 mPlaybackPhysicalAddress);
@@ -349,7 +357,8 @@
         HdmiCecMessage message =
                 HdmiCecMessageBuilder.buildRoutingChange(ADDR_TV, 0x0000,
                         mPlaybackPhysicalAddress);
-        assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message)).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message))
+                .isEqualTo(Constants.HANDLED);
         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
         assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress).isEqualTo(
                 mPlaybackPhysicalAddress);
@@ -368,7 +377,8 @@
         mStandby = false;
         HdmiCecMessage message =
                 HdmiCecMessageBuilder.buildRoutingChange(ADDR_TV, 0x0000, 0x5000);
-        assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message)).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message))
+                .isEqualTo(Constants.HANDLED);
         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
         assertThat(mStandby).isTrue();
     }
@@ -383,7 +393,8 @@
         mStandby = false;
         HdmiCecMessage message =
                 HdmiCecMessageBuilder.buildRoutingChange(ADDR_TV, 0x0000, 0x5000);
-        assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message)).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message))
+                .isEqualTo(Constants.HANDLED);
         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
         assertThat(mStandby).isFalse();
     }
@@ -399,7 +410,8 @@
         HdmiCecMessage message =
                 HdmiCecMessageBuilder.buildRoutingChange(ADDR_TV, 0x0000,
                         mPlaybackPhysicalAddress);
-        assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message)).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message))
+                .isEqualTo(Constants.HANDLED);
         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isTrue();
         assertThat(mStandby).isFalse();
     }
@@ -461,7 +473,8 @@
                 mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest");
         mStandby = false;
         HdmiCecMessage message = HdmiCecMessageBuilder.buildRoutingInformation(ADDR_TV, 0x5000);
-        assertThat(mHdmiCecLocalDevicePlayback.handleRoutingInformation(message)).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.handleRoutingInformation(message))
+                .isEqualTo(Constants.HANDLED);
         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
         assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress).isEqualTo(
                 0x5000);
@@ -481,7 +494,8 @@
         HdmiCecMessage message =
                 HdmiCecMessageBuilder.buildRoutingInformation(ADDR_TV,
                         mPlaybackPhysicalAddress);
-        assertThat(mHdmiCecLocalDevicePlayback.handleRoutingInformation(message)).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.handleRoutingInformation(message))
+                .isEqualTo(Constants.HANDLED);
         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isTrue();
         assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress).isEqualTo(
                 mPlaybackPhysicalAddress);
@@ -501,7 +515,8 @@
         HdmiCecMessage message =
                 HdmiCecMessageBuilder.buildRoutingInformation(ADDR_TV,
                         mPlaybackPhysicalAddress);
-        assertThat(mHdmiCecLocalDevicePlayback.handleRoutingInformation(message)).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.handleRoutingInformation(message))
+                .isEqualTo(Constants.HANDLED);
         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
         assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress).isEqualTo(
                 mPlaybackPhysicalAddress);
@@ -520,7 +535,8 @@
         mStandby = false;
         HdmiCecMessage message =
                 HdmiCecMessageBuilder.buildRoutingInformation(ADDR_TV, 0x5000);
-        assertThat(mHdmiCecLocalDevicePlayback.handleRoutingInformation(message)).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.handleRoutingInformation(message))
+                .isEqualTo(Constants.HANDLED);
         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
         assertThat(mStandby).isTrue();
     }
@@ -535,7 +551,8 @@
         mStandby = false;
         HdmiCecMessage message =
                 HdmiCecMessageBuilder.buildRoutingInformation(ADDR_TV, 0x5000);
-        assertThat(mHdmiCecLocalDevicePlayback.handleRoutingInformation(message)).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.handleRoutingInformation(message))
+                .isEqualTo(Constants.HANDLED);
         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
         assertThat(mStandby).isFalse();
     }
@@ -551,7 +568,8 @@
         HdmiCecMessage message =
                 HdmiCecMessageBuilder.buildRoutingInformation(ADDR_TV,
                         mPlaybackPhysicalAddress);
-        assertThat(mHdmiCecLocalDevicePlayback.handleRoutingInformation(message)).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.handleRoutingInformation(message))
+                .isEqualTo(Constants.HANDLED);
         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isTrue();
         assertThat(mStandby).isFalse();
     }
@@ -606,7 +624,8 @@
     public void handleSetStreamPath() {
         HdmiCecMessage message =
                 HdmiCecMessageBuilder.buildSetStreamPath(ADDR_TV, 0x2100);
-        assertThat(mHdmiCecLocalDevicePlayback.handleSetStreamPath(message)).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.handleSetStreamPath(message))
+                .isEqualTo(Constants.HANDLED);
     }
 
     @Test
@@ -616,7 +635,8 @@
         HdmiCecMessage message =
                 HdmiCecMessageBuilder.buildSetSystemAudioMode(
                         Constants.ADDR_AUDIO_SYSTEM, Constants.ADDR_BROADCAST, true);
-        assertThat(mHdmiCecLocalDevicePlayback.handleSetSystemAudioMode(message)).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.handleSetSystemAudioMode(message))
+                .isEqualTo(Constants.HANDLED);
         assertThat(mHdmiCecLocalDevicePlayback.mService.isSystemAudioActivated()).isTrue();
     }
 
@@ -629,7 +649,8 @@
         HdmiCecMessage message =
                 HdmiCecMessageBuilder.buildSetSystemAudioMode(
                         Constants.ADDR_AUDIO_SYSTEM, mHdmiCecLocalDevicePlayback.mAddress, false);
-        assertThat(mHdmiCecLocalDevicePlayback.handleSetSystemAudioMode(message)).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.handleSetSystemAudioMode(message))
+                .isEqualTo(Constants.HANDLED);
         assertThat(mHdmiCecLocalDevicePlayback.mService.isSystemAudioActivated()).isTrue();
     }
 
@@ -640,7 +661,8 @@
         HdmiCecMessage message =
                 HdmiCecMessageBuilder.buildReportSystemAudioMode(
                         Constants.ADDR_AUDIO_SYSTEM, mHdmiCecLocalDevicePlayback.mAddress, true);
-        assertThat(mHdmiCecLocalDevicePlayback.handleSystemAudioModeStatus(message)).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.handleSystemAudioModeStatus(message))
+                .isEqualTo(Constants.HANDLED);
         assertThat(mHdmiCecLocalDevicePlayback.mService.isSystemAudioActivated()).isTrue();
     }
 
@@ -883,7 +905,8 @@
         mStandby = false;
         HdmiCecMessage message = HdmiCecMessageBuilder.buildActiveSource(mPlaybackLogicalAddress,
                 mPlaybackPhysicalAddress);
-        assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(message)).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(message))
+                .isEqualTo(Constants.HANDLED);
         mTestLooper.dispatchAll();
         assertThat(mStandby).isFalse();
         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isTrue();
@@ -900,7 +923,8 @@
                 HdmiControlManager.POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_NONE);
         mStandby = false;
         HdmiCecMessage message = HdmiCecMessageBuilder.buildActiveSource(ADDR_TV, 0x0000);
-        assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(message)).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(message))
+                .isEqualTo(Constants.HANDLED);
         mTestLooper.dispatchAll();
         assertThat(mStandby).isFalse();
         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
@@ -918,7 +942,8 @@
         mStandby = false;
         HdmiCecMessage message = HdmiCecMessageBuilder.buildActiveSource(mPlaybackLogicalAddress,
                 mPlaybackPhysicalAddress);
-        assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(message)).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(message))
+                .isEqualTo(Constants.HANDLED);
         mTestLooper.dispatchAll();
         assertThat(mStandby).isFalse();
         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isTrue();
@@ -931,7 +956,8 @@
                 HdmiControlManager.POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_STANDBY_NOW);
         mStandby = false;
         HdmiCecMessage message = HdmiCecMessageBuilder.buildActiveSource(ADDR_TV, 0x0000);
-        assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(message)).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(message))
+                .isEqualTo(Constants.HANDLED);
         mTestLooper.dispatchAll();
         assertThat(mStandby).isTrue();
         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
@@ -996,12 +1022,14 @@
         // 1. DUT is <AS>.
         HdmiCecMessage message1 = HdmiCecMessageBuilder.buildActiveSource(
                 mHdmiCecLocalDevicePlayback.mAddress, mPlaybackPhysicalAddress);
-        assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(message1)).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(message1))
+                .isEqualTo(Constants.HANDLED);
         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isTrue();
         assertThat(mStandby).isFalse();
         // 2. DUT loses <AS> and goes to sleep.
         HdmiCecMessage message2 = HdmiCecMessageBuilder.buildActiveSource(ADDR_TV, 0x0000);
-        assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(message2)).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(message2))
+                .isEqualTo(Constants.HANDLED);
         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
         assertThat(mStandby).isTrue();
         // 3. DUT becomes <AS> again.
@@ -1271,7 +1299,8 @@
         mStandby = false;
         HdmiCecMessage message =
                 HdmiCecMessageBuilder.buildSetStreamPath(ADDR_TV, 0x5000);
-        assertThat(mHdmiCecLocalDevicePlayback.handleSetStreamPath(message)).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.handleSetStreamPath(message))
+                .isEqualTo(Constants.HANDLED);
         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
         assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress).isEqualTo(
                 0x5000);
@@ -1290,7 +1319,8 @@
         mStandby = false;
         HdmiCecMessage message =
                 HdmiCecMessageBuilder.buildSetStreamPath(ADDR_TV, 0x5000);
-        assertThat(mHdmiCecLocalDevicePlayback.handleSetStreamPath(message)).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.handleSetStreamPath(message))
+                .isEqualTo(Constants.HANDLED);
         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
         assertThat(mStandby).isTrue();
     }
@@ -1305,7 +1335,8 @@
         mStandby = false;
         HdmiCecMessage message =
                 HdmiCecMessageBuilder.buildSetStreamPath(ADDR_TV, 0x5000);
-        assertThat(mHdmiCecLocalDevicePlayback.handleSetStreamPath(message)).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.handleSetStreamPath(message))
+                .isEqualTo(Constants.HANDLED);
         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
         assertThat(mStandby).isFalse();
     }
@@ -1492,7 +1523,8 @@
         mHdmiControlService.toggleAndFollowTvPower();
         HdmiCecMessage tvPowerStatus = HdmiCecMessageBuilder.buildReportPowerStatus(ADDR_TV,
                 mPlaybackLogicalAddress, HdmiControlManager.POWER_STATUS_ON);
-        assertThat(mHdmiCecLocalDevicePlayback.dispatchMessage(tvPowerStatus)).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.dispatchMessage(tvPowerStatus))
+                .isEqualTo(Constants.HANDLED);
         mTestLooper.dispatchAll();
 
         HdmiCecMessage expectedMessage = HdmiCecMessageBuilder.buildStandby(
@@ -1510,7 +1542,8 @@
         mHdmiControlService.toggleAndFollowTvPower();
         HdmiCecMessage tvPowerStatus = HdmiCecMessageBuilder.buildReportPowerStatus(ADDR_TV,
                 mPlaybackLogicalAddress, HdmiControlManager.POWER_STATUS_ON);
-        assertThat(mHdmiCecLocalDevicePlayback.dispatchMessage(tvPowerStatus)).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.dispatchMessage(tvPowerStatus))
+                .isEqualTo(Constants.HANDLED);
         mTestLooper.dispatchAll();
 
         HdmiCecMessage expectedMessage = HdmiCecMessageBuilder.buildStandby(
@@ -1525,7 +1558,8 @@
         mHdmiControlService.toggleAndFollowTvPower();
         HdmiCecMessage tvPowerStatus = HdmiCecMessageBuilder.buildReportPowerStatus(ADDR_TV,
                 mPlaybackLogicalAddress, HdmiControlManager.POWER_STATUS_STANDBY);
-        assertThat(mHdmiCecLocalDevicePlayback.dispatchMessage(tvPowerStatus)).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.dispatchMessage(tvPowerStatus))
+                .isEqualTo(Constants.HANDLED);
         mTestLooper.dispatchAll();
 
         HdmiCecMessage textViewOn = HdmiCecMessageBuilder.buildTextViewOn(mPlaybackLogicalAddress,
@@ -1543,7 +1577,8 @@
         mHdmiControlService.toggleAndFollowTvPower();
         HdmiCecMessage tvPowerStatus = HdmiCecMessageBuilder.buildReportPowerStatus(ADDR_TV,
                 mPlaybackLogicalAddress, HdmiControlManager.POWER_STATUS_UNKNOWN);
-        assertThat(mHdmiCecLocalDevicePlayback.dispatchMessage(tvPowerStatus)).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.dispatchMessage(tvPowerStatus))
+                .isEqualTo(Constants.HANDLED);
         mTestLooper.dispatchAll();
 
         HdmiCecMessage userControlPressed = HdmiCecMessageBuilder.buildUserControlPressed(
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java
index b3f0085..6880302 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java
@@ -198,8 +198,8 @@
                         ADDR_PLAYBACK_1,
                         Constants.MESSAGE_CEC_VERSION,
                         HdmiCecMessage.EMPTY_PARAM);
-        boolean handleResult = mHdmiLocalDevice.dispatchMessage(msg);
-        assertFalse(handleResult);
+        @Constants.HandleMessageResult int handleResult = mHdmiLocalDevice.dispatchMessage(msg);
+        assertEquals(Constants.NOT_HANDLED, handleResult);
     }
 
     @Test
@@ -213,7 +213,7 @@
                     (byte) (DEVICE_TV & 0xFF)
                 };
         callbackResult = -1;
-        boolean handleResult =
+        @Constants.HandleMessageResult int handleResult =
                 mHdmiLocalDevice.handleGivePhysicalAddress(
                         (int finalResult) -> callbackResult = finalResult);
         mTestLooper.dispatchAll();
@@ -221,7 +221,7 @@
          * Test if CecMessage is sent successfully SendMessageResult#SUCCESS is defined in HAL as 0
          */
         assertEquals(0, callbackResult);
-        assertTrue(handleResult);
+        assertEquals(Constants.HANDLED, handleResult);
     }
 
     @Test
@@ -251,85 +251,85 @@
     public void handleUserControlPressed_volumeUp() {
         mHdmiControlService.setHdmiCecVolumeControlEnabledInternal(
                 HdmiControlManager.VOLUME_CONTROL_ENABLED);
-        boolean result = mHdmiLocalDevice.handleUserControlPressed(
+        @Constants.HandleMessageResult int result = mHdmiLocalDevice.handleUserControlPressed(
                 HdmiCecMessageBuilder.buildUserControlPressed(ADDR_PLAYBACK_1, ADDR_TV,
                         HdmiCecKeycode.CEC_KEYCODE_VOLUME_UP));
 
-        assertTrue(result);
+        assertEquals(Constants.HANDLED, result);
     }
 
     @Test
     public void handleUserControlPressed_volumeDown() {
         mHdmiControlService.setHdmiCecVolumeControlEnabledInternal(
                 HdmiControlManager.VOLUME_CONTROL_ENABLED);
-        boolean result = mHdmiLocalDevice.handleUserControlPressed(
+        @Constants.HandleMessageResult int result = mHdmiLocalDevice.handleUserControlPressed(
                 HdmiCecMessageBuilder.buildUserControlPressed(ADDR_PLAYBACK_1, ADDR_TV,
                         HdmiCecKeycode.CEC_KEYCODE_VOLUME_DOWN));
 
-        assertTrue(result);
+        assertEquals(Constants.HANDLED, result);
     }
 
     @Test
     public void handleUserControlPressed_volumeMute() {
         mHdmiControlService.setHdmiCecVolumeControlEnabledInternal(
                 HdmiControlManager.VOLUME_CONTROL_ENABLED);
-        boolean result = mHdmiLocalDevice.handleUserControlPressed(
+        @Constants.HandleMessageResult int result = mHdmiLocalDevice.handleUserControlPressed(
                 HdmiCecMessageBuilder.buildUserControlPressed(ADDR_PLAYBACK_1, ADDR_TV,
                         HdmiCecKeycode.CEC_KEYCODE_MUTE));
 
-        assertTrue(result);
+        assertEquals(Constants.HANDLED, result);
     }
 
     @Test
     public void handleUserControlPressed_volumeUp_disabled() {
         mHdmiControlService.setHdmiCecVolumeControlEnabledInternal(
                 HdmiControlManager.VOLUME_CONTROL_DISABLED);
-        boolean result = mHdmiLocalDevice.handleUserControlPressed(
+        @Constants.HandleMessageResult int result = mHdmiLocalDevice.handleUserControlPressed(
                 HdmiCecMessageBuilder.buildUserControlPressed(ADDR_PLAYBACK_1, ADDR_TV,
                         HdmiCecKeycode.CEC_KEYCODE_VOLUME_UP));
 
-        assertFalse(result);
+        assertThat(result).isEqualTo(Constants.ABORT_REFUSED);
     }
 
     @Test
     public void handleUserControlPressed_volumeDown_disabled() {
         mHdmiControlService.setHdmiCecVolumeControlEnabledInternal(
                 HdmiControlManager.VOLUME_CONTROL_DISABLED);
-        boolean result = mHdmiLocalDevice.handleUserControlPressed(
+        @Constants.HandleMessageResult int result = mHdmiLocalDevice.handleUserControlPressed(
                 HdmiCecMessageBuilder.buildUserControlPressed(ADDR_PLAYBACK_1, ADDR_TV,
                         HdmiCecKeycode.CEC_KEYCODE_VOLUME_DOWN));
 
-        assertFalse(result);
+        assertThat(result).isEqualTo(Constants.ABORT_REFUSED);
     }
 
     @Test
     public void handleUserControlPressed_volumeMute_disabled() {
         mHdmiControlService.setHdmiCecVolumeControlEnabledInternal(
                 HdmiControlManager.VOLUME_CONTROL_DISABLED);
-        boolean result = mHdmiLocalDevice.handleUserControlPressed(
+        @Constants.HandleMessageResult int result = mHdmiLocalDevice.handleUserControlPressed(
                 HdmiCecMessageBuilder.buildUserControlPressed(ADDR_PLAYBACK_1, ADDR_TV,
                         HdmiCecKeycode.CEC_KEYCODE_MUTE));
 
-        assertFalse(result);
+        assertThat(result).isEqualTo(Constants.ABORT_REFUSED);
     }
 
     @Test
     public void handleCecVersion_isHandled() {
-        boolean result = mHdmiLocalDevice.onMessage(
+        @Constants.HandleMessageResult int result = mHdmiLocalDevice.onMessage(
                 HdmiCecMessageBuilder.buildCecVersion(ADDR_PLAYBACK_1, mHdmiLocalDevice.mAddress,
                         HdmiControlManager.HDMI_CEC_VERSION_1_4_B));
 
-        assertThat(result).isTrue();
+        assertEquals(Constants.HANDLED, result);
     }
 
     @Test
     public void handleUserControlPressed_power_localDeviceInStandby_shouldTurnOn() {
         mPowerStatus = HdmiControlManager.POWER_STATUS_STANDBY;
-        boolean result = mHdmiLocalDevice.handleUserControlPressed(
+        @Constants.HandleMessageResult int result = mHdmiLocalDevice.handleUserControlPressed(
                 HdmiCecMessageBuilder.buildUserControlPressed(ADDR_TV, ADDR_PLAYBACK_1,
                         HdmiCecKeycode.CEC_KEYCODE_POWER));
 
-        assertThat(result).isTrue();
+        assertEquals(Constants.HANDLED, result);
         assertThat(mWakeupMessageReceived).isTrue();
         assertThat(mStandbyMessageReceived).isFalse();
     }
@@ -337,11 +337,11 @@
     @Test
     public void handleUserControlPressed_power_localDeviceOn_shouldNotChangePowerStatus() {
         mPowerStatus = HdmiControlManager.POWER_STATUS_ON;
-        boolean result = mHdmiLocalDevice.handleUserControlPressed(
+        @Constants.HandleMessageResult int result = mHdmiLocalDevice.handleUserControlPressed(
                 HdmiCecMessageBuilder.buildUserControlPressed(ADDR_TV, ADDR_PLAYBACK_1,
                         HdmiCecKeycode.CEC_KEYCODE_POWER));
 
-        assertThat(result).isTrue();
+        assertEquals(Constants.HANDLED, result);
         assertThat(mWakeupMessageReceived).isFalse();
         assertThat(mStandbyMessageReceived).isFalse();
     }
@@ -349,11 +349,11 @@
     @Test
     public void handleUserControlPressed_powerToggleFunction_localDeviceInStandby_shouldTurnOn() {
         mPowerStatus = HdmiControlManager.POWER_STATUS_STANDBY;
-        boolean result = mHdmiLocalDevice.handleUserControlPressed(
+        @Constants.HandleMessageResult int result = mHdmiLocalDevice.handleUserControlPressed(
                 HdmiCecMessageBuilder.buildUserControlPressed(ADDR_TV, ADDR_PLAYBACK_1,
                         HdmiCecKeycode.CEC_KEYCODE_POWER_TOGGLE_FUNCTION));
 
-        assertThat(result).isTrue();
+        assertEquals(Constants.HANDLED, result);
         assertThat(mWakeupMessageReceived).isTrue();
         assertThat(mStandbyMessageReceived).isFalse();
     }
@@ -361,11 +361,11 @@
     @Test
     public void handleUserControlPressed_powerToggleFunction_localDeviceOn_shouldTurnOff() {
         mPowerStatus = HdmiControlManager.POWER_STATUS_ON;
-        boolean result = mHdmiLocalDevice.handleUserControlPressed(
+        @Constants.HandleMessageResult int result = mHdmiLocalDevice.handleUserControlPressed(
                 HdmiCecMessageBuilder.buildUserControlPressed(ADDR_TV, ADDR_PLAYBACK_1,
                         HdmiCecKeycode.CEC_KEYCODE_POWER_TOGGLE_FUNCTION));
 
-        assertThat(result).isTrue();
+        assertEquals(Constants.HANDLED, result);
         assertThat(mWakeupMessageReceived).isFalse();
         assertThat(mStandbyMessageReceived).isTrue();
     }
@@ -373,11 +373,11 @@
     @Test
     public void handleUserControlPressed_powerOnFunction_localDeviceInStandby_shouldTurnOn() {
         mPowerStatus = HdmiControlManager.POWER_STATUS_STANDBY;
-        boolean result = mHdmiLocalDevice.handleUserControlPressed(
+        @Constants.HandleMessageResult int result = mHdmiLocalDevice.handleUserControlPressed(
                 HdmiCecMessageBuilder.buildUserControlPressed(ADDR_TV, ADDR_PLAYBACK_1,
                         HdmiCecKeycode.CEC_KEYCODE_POWER_ON_FUNCTION));
 
-        assertThat(result).isTrue();
+        assertEquals(Constants.HANDLED, result);
         assertThat(mWakeupMessageReceived).isTrue();
         assertThat(mStandbyMessageReceived).isFalse();
     }
@@ -385,11 +385,11 @@
     @Test
     public void handleUserControlPressed_powerOnFunction_localDeviceOn_noPowerStatusChange() {
         mPowerStatus = HdmiControlManager.POWER_STATUS_ON;
-        boolean result = mHdmiLocalDevice.handleUserControlPressed(
+        @Constants.HandleMessageResult int result = mHdmiLocalDevice.handleUserControlPressed(
                 HdmiCecMessageBuilder.buildUserControlPressed(ADDR_TV, ADDR_PLAYBACK_1,
                         HdmiCecKeycode.CEC_KEYCODE_POWER_ON_FUNCTION));
 
-        assertThat(result).isTrue();
+        assertEquals(Constants.HANDLED, result);
         assertThat(mWakeupMessageReceived).isFalse();
         assertThat(mStandbyMessageReceived).isFalse();
     }
@@ -397,11 +397,11 @@
     @Test
     public void handleUserControlPressed_powerOffFunction_localDeviceStandby_noPowerStatusChange() {
         mPowerStatus = HdmiControlManager.POWER_STATUS_STANDBY;
-        boolean result = mHdmiLocalDevice.handleUserControlPressed(
+        @Constants.HandleMessageResult int result = mHdmiLocalDevice.handleUserControlPressed(
                 HdmiCecMessageBuilder.buildUserControlPressed(ADDR_TV, ADDR_PLAYBACK_1,
                         HdmiCecKeycode.CEC_KEYCODE_POWER_OFF_FUNCTION));
 
-        assertThat(result).isTrue();
+        assertEquals(Constants.HANDLED, result);
         assertThat(mWakeupMessageReceived).isFalse();
         assertThat(mStandbyMessageReceived).isFalse();
     }
@@ -409,11 +409,11 @@
     @Test
     public void handleUserControlPressed_powerOffFunction_localDeviceOn_shouldTurnOff() {
         mPowerStatus = HdmiControlManager.POWER_STATUS_ON;
-        boolean result = mHdmiLocalDevice.handleUserControlPressed(
+        @Constants.HandleMessageResult int result = mHdmiLocalDevice.handleUserControlPressed(
                 HdmiCecMessageBuilder.buildUserControlPressed(ADDR_TV, ADDR_PLAYBACK_1,
                         HdmiCecKeycode.CEC_KEYCODE_POWER_OFF_FUNCTION));
 
-        assertThat(result).isTrue();
+        assertEquals(Constants.HANDLED, result);
         assertThat(mWakeupMessageReceived).isFalse();
         assertThat(mStandbyMessageReceived).isTrue();
     }
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 4b3ef2f..39e06a3 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
@@ -233,7 +233,7 @@
         mWokenUp = false;
         HdmiCecMessage textViewOn = HdmiCecMessageBuilder.buildTextViewOn(ADDR_PLAYBACK_1,
                 mTvLogicalAddress);
-        assertThat(mHdmiCecLocalDeviceTv.dispatchMessage(textViewOn)).isTrue();
+        assertThat(mHdmiCecLocalDeviceTv.dispatchMessage(textViewOn)).isEqualTo(Constants.HANDLED);
         mTestLooper.dispatchAll();
         assertThat(mWokenUp).isTrue();
     }
@@ -247,7 +247,7 @@
         mWokenUp = false;
         HdmiCecMessage imageViewOn = new HdmiCecMessage(ADDR_PLAYBACK_1, mTvLogicalAddress,
                 Constants.MESSAGE_IMAGE_VIEW_ON, HdmiCecMessage.EMPTY_PARAM);
-        assertThat(mHdmiCecLocalDeviceTv.dispatchMessage(imageViewOn)).isTrue();
+        assertThat(mHdmiCecLocalDeviceTv.dispatchMessage(imageViewOn)).isEqualTo(Constants.HANDLED);
         mTestLooper.dispatchAll();
         assertThat(mWokenUp).isTrue();
     }
@@ -261,7 +261,7 @@
         mWokenUp = false;
         HdmiCecMessage textViewOn = HdmiCecMessageBuilder.buildTextViewOn(ADDR_PLAYBACK_1,
                 mTvLogicalAddress);
-        assertThat(mHdmiCecLocalDeviceTv.dispatchMessage(textViewOn)).isTrue();
+        assertThat(mHdmiCecLocalDeviceTv.dispatchMessage(textViewOn)).isEqualTo(Constants.HANDLED);
         mTestLooper.dispatchAll();
         assertThat(mWokenUp).isFalse();
     }
@@ -275,7 +275,7 @@
         mWokenUp = false;
         HdmiCecMessage imageViewOn = new HdmiCecMessage(ADDR_PLAYBACK_1, mTvLogicalAddress,
                 Constants.MESSAGE_IMAGE_VIEW_ON, HdmiCecMessage.EMPTY_PARAM);
-        assertThat(mHdmiCecLocalDeviceTv.dispatchMessage(imageViewOn)).isTrue();
+        assertThat(mHdmiCecLocalDeviceTv.dispatchMessage(imageViewOn)).isEqualTo(Constants.HANDLED);
         mTestLooper.dispatchAll();
         assertThat(mWokenUp).isFalse();
     }
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceBinderAPITest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceBinderAPITest.java
deleted file mode 100644
index 70718f7..0000000
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceBinderAPITest.java
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.server.hdmi;
-
-import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static junit.framework.Assert.assertEquals;
-
-import android.content.Context;
-import android.hardware.hdmi.HdmiControlManager;
-import android.hardware.hdmi.HdmiPortInfo;
-import android.hardware.hdmi.IHdmiControlCallback;
-import android.os.Looper;
-import android.os.test.TestLooper;
-import android.provider.Settings;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Tests for {@link HdmiControlServiceBinderAPITest} class.
- */
-@SmallTest
-@RunWith(JUnit4.class)
-public class HdmiControlServiceBinderAPITest {
-
-    private Context mContext;
-
-    private class HdmiCecLocalDeviceMyDevice extends HdmiCecLocalDevice {
-
-        private boolean mCanGoToStandby;
-        private boolean mIsStandby;
-        private boolean mIsDisabled;
-
-        protected HdmiCecLocalDeviceMyDevice(HdmiControlService service, int deviceType) {
-            super(service, deviceType);
-        }
-
-        @Override
-        protected void onAddressAllocated(int logicalAddress, int reason) {
-        }
-
-        @Override
-        protected int getPreferredAddress() {
-            return 0;
-        }
-
-        @Override
-        protected void setPreferredAddress(int addr) {
-        }
-
-        @Override
-        protected boolean canGoToStandby() {
-            return mCanGoToStandby;
-        }
-
-        @Override
-        protected void disableDevice(
-            boolean initiatedByCec, final PendingActionClearedCallback originalCallback) {
-            mIsDisabled = true;
-            originalCallback.onCleared(this);
-        }
-
-        @Override
-        protected void onStandby(boolean initiatedByCec, int standbyAction) {
-            mIsStandby = true;
-        }
-
-        protected boolean isStandby() {
-            return mIsStandby;
-        }
-
-        protected boolean isDisabled() {
-            return mIsDisabled;
-        }
-
-        protected void setCanGoToStandby(boolean canGoToStandby) {
-            mCanGoToStandby = canGoToStandby;
-        }
-
-        @Override
-        protected int getRcProfile() {
-            return 0;
-        }
-
-        @Override
-        protected List<Integer> getRcFeatures() {
-            return Collections.emptyList();
-        }
-
-        @Override
-        protected List<Integer> getDeviceFeatures() {
-            return Collections.emptyList();
-        }
-    }
-
-    private static final String TAG = "HdmiControlServiceBinderAPITest";
-    private HdmiControlService mHdmiControlService;
-    private HdmiCecController mHdmiCecController;
-    private HdmiCecLocalDevicePlayback mPlaybackDevice;
-    private FakeNativeWrapper mNativeWrapper;
-    private Looper mMyLooper;
-    private TestLooper mTestLooper = new TestLooper();
-    private ArrayList<HdmiCecLocalDevice> mLocalDevices = new ArrayList<>();
-    private HdmiPortInfo[] mHdmiPortInfo;
-    private int mResult;
-    private int mPowerStatus;
-
-    @Before
-    public void SetUp() {
-        mContext = InstrumentationRegistry.getTargetContext();
-        // Some tests expect no logical addresses being allocated at the beginning of the test.
-        setHdmiControlEnabled(false);
-
-        HdmiCecConfig hdmiCecConfig = new FakeHdmiCecConfig(mContext);
-
-        mHdmiControlService =
-            new HdmiControlService(mContext) {
-                @Override
-                void sendCecCommand(HdmiCecMessage command) {
-                    switch (command.getOpcode()) {
-                        case Constants.MESSAGE_GIVE_DEVICE_POWER_STATUS:
-                            HdmiCecMessage message =
-                                HdmiCecMessageBuilder.buildReportPowerStatus(
-                                    Constants.ADDR_TV,
-                                    Constants.ADDR_PLAYBACK_1,
-                                    HdmiControlManager.POWER_STATUS_ON);
-                            handleCecCommand(message);
-                            break;
-                        default:
-                            return;
-                    }
-                }
-
-                @Override
-                boolean isPowerStandby() {
-                    return mPowerStatus == HdmiControlManager.POWER_STATUS_STANDBY;
-                }
-
-                @Override
-                protected HdmiCecConfig getHdmiCecConfig() {
-                    return hdmiCecConfig;
-                }
-            };
-        mMyLooper = mTestLooper.getLooper();
-
-        mPlaybackDevice = new HdmiCecLocalDevicePlayback(mHdmiControlService) {
-            @Override
-            protected void wakeUpIfActiveSource() {}
-
-            @Override
-            protected void setPreferredAddress(int addr) {}
-
-            @Override
-            protected int getPreferredAddress() {
-                return Constants.ADDR_PLAYBACK_1;
-            }
-        };
-        mPlaybackDevice.init();
-
-        mHdmiControlService.setIoLooper(mMyLooper);
-
-        mNativeWrapper = new FakeNativeWrapper();
-        mHdmiCecController = HdmiCecController.createWithNativeWrapper(
-                mHdmiControlService, mNativeWrapper, mHdmiControlService.getAtomWriter());
-        mHdmiControlService.setCecController(mHdmiCecController);
-        mHdmiControlService.setHdmiMhlController(HdmiMhlControllerStub.create(mHdmiControlService));
-        mHdmiControlService.setMessageValidator(new HdmiCecMessageValidator(mHdmiControlService));
-
-        mLocalDevices.add(mPlaybackDevice);
-        mHdmiPortInfo = new HdmiPortInfo[1];
-        mHdmiPortInfo[0] =
-            new HdmiPortInfo(1, HdmiPortInfo.PORT_INPUT, 0x2100, true, false, false);
-        mNativeWrapper.setPortInfo(mHdmiPortInfo);
-        mHdmiControlService.initService();
-        mResult = -1;
-        mPowerStatus = HdmiControlManager.POWER_STATUS_ON;
-
-        mTestLooper.dispatchAll();
-    }
-
-    @Test
-    public void oneTouchPlay_addressNotAllocated() {
-        assertThat(mHdmiControlService.isAddressAllocated()).isFalse();
-        mHdmiControlService.oneTouchPlay(new IHdmiControlCallback.Stub() {
-            @Override
-            public void onComplete(int result) {
-                mResult = result;
-            }
-        });
-        assertEquals(mResult, -1);
-        assertThat(mPlaybackDevice.isActiveSource()).isFalse();
-
-        setHdmiControlEnabled(true);
-        mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
-        mTestLooper.dispatchAll();
-        assertThat(mHdmiControlService.isAddressAllocated()).isTrue();
-        assertEquals(mResult, HdmiControlManager.RESULT_SUCCESS);
-        assertThat(mPlaybackDevice.isActiveSource()).isTrue();
-    }
-
-    @Test
-    public void oneTouchPlay_addressAllocated() {
-        setHdmiControlEnabled(true);
-
-        mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
-        mTestLooper.dispatchAll();
-        assertThat(mHdmiControlService.isAddressAllocated()).isTrue();
-        mHdmiControlService.oneTouchPlay(new IHdmiControlCallback.Stub() {
-            @Override
-            public void onComplete(int result) {
-                mResult = result;
-            }
-        });
-        assertEquals(mResult, HdmiControlManager.RESULT_SUCCESS);
-        assertThat(mPlaybackDevice.isActiveSource()).isTrue();
-    }
-
-    private void setHdmiControlEnabled(boolean enabled) {
-        int value = enabled ? 1 : 0;
-        Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.HDMI_CONTROL_ENABLED,
-                value);
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java
index b5336e3..68aa96a 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java
@@ -28,6 +28,9 @@
 import static junit.framework.Assert.assertTrue;
 import static junit.framework.TestCase.assertEquals;
 
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
 
@@ -68,7 +71,7 @@
 @RunWith(JUnit4.class)
 public class HdmiControlServiceTest {
 
-    private class MockPlaybackDevice extends HdmiCecLocalDevicePlayback {
+    protected static class MockPlaybackDevice extends HdmiCecLocalDevicePlayback {
 
         private boolean mCanGoToStandby;
         private boolean mIsStandby;
@@ -118,7 +121,7 @@
             mCanGoToStandby = canGoToStandby;
         }
     }
-    private class MockAudioSystemDevice extends HdmiCecLocalDeviceAudioSystem {
+    protected static class MockAudioSystemDevice extends HdmiCecLocalDeviceAudioSystem {
 
         private boolean mCanGoToStandby;
         private boolean mIsStandby;
@@ -171,15 +174,14 @@
 
     private static final String TAG = "HdmiControlServiceTest";
     private Context mContextSpy;
-    private HdmiControlService mHdmiControlService;
+    private HdmiControlService mHdmiControlServiceSpy;
     private HdmiCecController mHdmiCecController;
-    private MockAudioSystemDevice mAudioSystemDevice;
-    private MockPlaybackDevice mPlaybackDevice;
+    private MockAudioSystemDevice mAudioSystemDeviceSpy;
+    private MockPlaybackDevice mPlaybackDeviceSpy;
     private FakeNativeWrapper mNativeWrapper;
     private Looper mMyLooper;
     private TestLooper mTestLooper = new TestLooper();
     private ArrayList<HdmiCecLocalDevice> mLocalDevices = new ArrayList<>();
-    private boolean mStandbyMessageReceived;
     private HdmiPortInfo[] mHdmiPortInfo;
 
     @Mock private IPowerManager mIPowerManagerMock;
@@ -199,36 +201,32 @@
 
         HdmiCecConfig hdmiCecConfig = new FakeHdmiCecConfig(mContextSpy);
 
-        mHdmiControlService = new HdmiControlService(mContextSpy) {
-            @Override
-            boolean isStandbyMessageReceived() {
-                return mStandbyMessageReceived;
-            }
+        mHdmiControlServiceSpy = spy(new HdmiControlService(mContextSpy));
+        doNothing().when(mHdmiControlServiceSpy)
+                .writeStringSystemProperty(anyString(), anyString());
 
-            @Override
-            protected void writeStringSystemProperty(String key, String value) {
-            }
-        };
         mMyLooper = mTestLooper.getLooper();
 
-        mAudioSystemDevice = new MockAudioSystemDevice(mHdmiControlService);
-        mPlaybackDevice = new MockPlaybackDevice(mHdmiControlService);
-        mAudioSystemDevice.init();
-        mPlaybackDevice.init();
+        mAudioSystemDeviceSpy = spy(new MockAudioSystemDevice(mHdmiControlServiceSpy));
+        mPlaybackDeviceSpy = spy(new MockPlaybackDevice(mHdmiControlServiceSpy));
+        mAudioSystemDeviceSpy.init();
+        mPlaybackDeviceSpy.init();
 
-        mHdmiControlService.setIoLooper(mMyLooper);
-        mHdmiControlService.setHdmiCecConfig(hdmiCecConfig);
-        mHdmiControlService.onBootPhase(PHASE_SYSTEM_SERVICES_READY);
+        mHdmiControlServiceSpy.setIoLooper(mMyLooper);
+        mHdmiControlServiceSpy.setHdmiCecConfig(hdmiCecConfig);
+        mHdmiControlServiceSpy.onBootPhase(PHASE_SYSTEM_SERVICES_READY);
 
         mNativeWrapper = new FakeNativeWrapper();
         mHdmiCecController = HdmiCecController.createWithNativeWrapper(
-                mHdmiControlService, mNativeWrapper, mHdmiControlService.getAtomWriter());
-        mHdmiControlService.setCecController(mHdmiCecController);
-        mHdmiControlService.setHdmiMhlController(HdmiMhlControllerStub.create(mHdmiControlService));
-        mHdmiControlService.setMessageValidator(new HdmiCecMessageValidator(mHdmiControlService));
+                mHdmiControlServiceSpy, mNativeWrapper, mHdmiControlServiceSpy.getAtomWriter());
+        mHdmiControlServiceSpy.setCecController(mHdmiCecController);
+        mHdmiControlServiceSpy.setHdmiMhlController(HdmiMhlControllerStub.create(
+                mHdmiControlServiceSpy));
+        mHdmiControlServiceSpy.setMessageValidator(new HdmiCecMessageValidator(
+                mHdmiControlServiceSpy));
 
-        mLocalDevices.add(mAudioSystemDevice);
-        mLocalDevices.add(mPlaybackDevice);
+        mLocalDevices.add(mAudioSystemDeviceSpy);
+        mLocalDevices.add(mPlaybackDeviceSpy);
         mHdmiPortInfo = new HdmiPortInfo[4];
         mHdmiPortInfo[0] =
             new HdmiPortInfo(1, HdmiPortInfo.PORT_INPUT, 0x2100, true, false, false);
@@ -239,80 +237,81 @@
         mHdmiPortInfo[3] =
             new HdmiPortInfo(4, HdmiPortInfo.PORT_INPUT, 0x3000, true, false, false);
         mNativeWrapper.setPortInfo(mHdmiPortInfo);
-        mHdmiControlService.getHdmiCecConfig().setIntValue(
+        mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
                 HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED,
                 HdmiControlManager.HDMI_CEC_CONTROL_ENABLED);
-        mHdmiControlService.initService();
-        mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
+        mHdmiControlServiceSpy.initService();
+        mHdmiControlServiceSpy.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
 
         mTestLooper.dispatchAll();
     }
 
     @Test
     public void onStandby_notByCec_cannotGoToStandby() {
-        mStandbyMessageReceived = false;
-        mPlaybackDevice.setCanGoToStandby(false);
+        doReturn(false).when(mHdmiControlServiceSpy).isStandbyMessageReceived();
 
-        mHdmiControlService.onStandby(HdmiControlService.STANDBY_SCREEN_OFF);
-        assertTrue(mPlaybackDevice.isStandby());
-        assertTrue(mAudioSystemDevice.isStandby());
-        assertFalse(mPlaybackDevice.isDisabled());
-        assertFalse(mAudioSystemDevice.isDisabled());
+        mPlaybackDeviceSpy.setCanGoToStandby(false);
+
+        mHdmiControlServiceSpy.onStandby(HdmiControlService.STANDBY_SCREEN_OFF);
+        assertTrue(mPlaybackDeviceSpy.isStandby());
+        assertTrue(mAudioSystemDeviceSpy.isStandby());
+        assertFalse(mPlaybackDeviceSpy.isDisabled());
+        assertFalse(mAudioSystemDeviceSpy.isDisabled());
     }
 
     @Test
     public void onStandby_byCec() {
-        mStandbyMessageReceived = true;
+        doReturn(true).when(mHdmiControlServiceSpy).isStandbyMessageReceived();
 
-        mHdmiControlService.onStandby(HdmiControlService.STANDBY_SCREEN_OFF);
-        assertTrue(mPlaybackDevice.isStandby());
-        assertTrue(mAudioSystemDevice.isStandby());
-        assertTrue(mPlaybackDevice.isDisabled());
-        assertTrue(mAudioSystemDevice.isDisabled());
+        mHdmiControlServiceSpy.onStandby(HdmiControlService.STANDBY_SCREEN_OFF);
+        assertTrue(mPlaybackDeviceSpy.isStandby());
+        assertTrue(mAudioSystemDeviceSpy.isStandby());
+        assertTrue(mPlaybackDeviceSpy.isDisabled());
+        assertTrue(mAudioSystemDeviceSpy.isDisabled());
     }
 
     @Test
     public void initialPowerStatus_normalBoot_isTransientToStandby() {
-        assertThat(mHdmiControlService.getInitialPowerStatus()).isEqualTo(
+        assertThat(mHdmiControlServiceSpy.getInitialPowerStatus()).isEqualTo(
                 HdmiControlManager.POWER_STATUS_TRANSIENT_TO_STANDBY);
     }
 
     @Test
     public void initialPowerStatus_quiescentBoot_isTransientToStandby() throws RemoteException {
         when(mIPowerManagerMock.isInteractive()).thenReturn(false);
-        assertThat(mHdmiControlService.getInitialPowerStatus()).isEqualTo(
+        assertThat(mHdmiControlServiceSpy.getInitialPowerStatus()).isEqualTo(
                 HdmiControlManager.POWER_STATUS_TRANSIENT_TO_STANDBY);
     }
 
     @Test
     public void powerStatusAfterBootComplete_normalBoot_isOn() {
-        mHdmiControlService.setPowerStatus(HdmiControlManager.POWER_STATUS_TRANSIENT_TO_ON);
-        mHdmiControlService.onBootPhase(PHASE_BOOT_COMPLETED);
-        assertThat(mHdmiControlService.getPowerStatus()).isEqualTo(
+        mHdmiControlServiceSpy.setPowerStatus(HdmiControlManager.POWER_STATUS_TRANSIENT_TO_ON);
+        mHdmiControlServiceSpy.onBootPhase(PHASE_BOOT_COMPLETED);
+        assertThat(mHdmiControlServiceSpy.getPowerStatus()).isEqualTo(
                 HdmiControlManager.POWER_STATUS_TRANSIENT_TO_ON);
     }
 
     @Test
     public void powerStatusAfterBootComplete_quiescentBoot_isStandby() throws RemoteException {
         when(mIPowerManagerMock.isInteractive()).thenReturn(false);
-        mHdmiControlService.onBootPhase(PHASE_BOOT_COMPLETED);
-        assertThat(mHdmiControlService.getPowerStatus()).isEqualTo(
+        mHdmiControlServiceSpy.onBootPhase(PHASE_BOOT_COMPLETED);
+        assertThat(mHdmiControlServiceSpy.getPowerStatus()).isEqualTo(
                 HdmiControlManager.POWER_STATUS_STANDBY);
     }
 
     @Test
     public void initialPowerStatus_normalBoot_goToStandby_doesNotBroadcastsPowerStatus_1_4() {
-        mHdmiControlService.getHdmiCecConfig().setIntValue(
+        mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
                 HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION,
                 HdmiControlManager.HDMI_CEC_VERSION_1_4_B);
 
-        mHdmiControlService.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED);
+        mHdmiControlServiceSpy.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED);
         mNativeWrapper.clearResultMessages();
 
-        assertThat(mHdmiControlService.getInitialPowerStatus()).isEqualTo(
+        assertThat(mHdmiControlServiceSpy.getInitialPowerStatus()).isEqualTo(
                 HdmiControlManager.POWER_STATUS_TRANSIENT_TO_STANDBY);
 
-        mHdmiControlService.onStandby(HdmiControlService.STANDBY_SCREEN_OFF);
+        mHdmiControlServiceSpy.onStandby(HdmiControlService.STANDBY_SCREEN_OFF);
 
         HdmiCecMessage reportPowerStatus = HdmiCecMessageBuilder.buildReportPowerStatus(
                 Constants.ADDR_PLAYBACK_1, Constants.ADDR_BROADCAST,
@@ -322,21 +321,21 @@
 
     @Test
     public void initialPowerStatus_normalBoot_goToStandby_broadcastsPowerStatus_2_0() {
-        mHdmiControlService.getHdmiCecConfig().setIntValue(
+        mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
                 HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION,
                 HdmiControlManager.HDMI_CEC_VERSION_2_0);
         mTestLooper.dispatchAll();
 
-        mHdmiControlService.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED);
+        mHdmiControlServiceSpy.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED);
         mNativeWrapper.clearResultMessages();
 
-        mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
+        mHdmiControlServiceSpy.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
         mTestLooper.dispatchAll();
 
-        assertThat(mHdmiControlService.getInitialPowerStatus()).isEqualTo(
+        assertThat(mHdmiControlServiceSpy.getInitialPowerStatus()).isEqualTo(
                 HdmiControlManager.POWER_STATUS_TRANSIENT_TO_STANDBY);
 
-        mHdmiControlService.onStandby(HdmiControlService.STANDBY_SCREEN_OFF);
+        mHdmiControlServiceSpy.onStandby(HdmiControlService.STANDBY_SCREEN_OFF);
         mTestLooper.dispatchAll();
 
         HdmiCecMessage reportPowerStatus = HdmiCecMessageBuilder.buildReportPowerStatus(
@@ -347,53 +346,53 @@
 
     @Test
     public void setAndGetCecVolumeControlEnabled_isApi() {
-        mHdmiControlService.getHdmiCecConfig().setIntValue(
+        mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
                 HdmiControlManager.CEC_SETTING_NAME_VOLUME_CONTROL_MODE,
                 HdmiControlManager.VOLUME_CONTROL_DISABLED);
-        assertThat(mHdmiControlService.getHdmiCecConfig().getIntValue(
+        assertThat(mHdmiControlServiceSpy.getHdmiCecConfig().getIntValue(
                 HdmiControlManager.CEC_SETTING_NAME_VOLUME_CONTROL_MODE)).isEqualTo(
                 HdmiControlManager.VOLUME_CONTROL_DISABLED);
 
-        mHdmiControlService.getHdmiCecConfig().setIntValue(
+        mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
                 HdmiControlManager.CEC_SETTING_NAME_VOLUME_CONTROL_MODE,
                 HdmiControlManager.VOLUME_CONTROL_ENABLED);
-        assertThat(mHdmiControlService.getHdmiCecConfig().getIntValue(
+        assertThat(mHdmiControlServiceSpy.getHdmiCecConfig().getIntValue(
                 HdmiControlManager.CEC_SETTING_NAME_VOLUME_CONTROL_MODE)).isEqualTo(
                 HdmiControlManager.VOLUME_CONTROL_ENABLED);
     }
 
     @Test
     public void setAndGetCecVolumeControlEnabled_changesSetting() {
-        mHdmiControlService.getHdmiCecConfig().setIntValue(
+        mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
                 HdmiControlManager.CEC_SETTING_NAME_VOLUME_CONTROL_MODE,
                 HdmiControlManager.VOLUME_CONTROL_DISABLED);
-        assertThat(mHdmiControlService.readIntSetting(
+        assertThat(mHdmiControlServiceSpy.readIntSetting(
                 Settings.Global.HDMI_CONTROL_VOLUME_CONTROL_ENABLED, -1)).isEqualTo(
                 HdmiControlManager.VOLUME_CONTROL_DISABLED);
 
-        mHdmiControlService.getHdmiCecConfig().setIntValue(
+        mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
                 HdmiControlManager.CEC_SETTING_NAME_VOLUME_CONTROL_MODE,
                 HdmiControlManager.VOLUME_CONTROL_ENABLED);
-        assertThat(mHdmiControlService.readIntSetting(
+        assertThat(mHdmiControlServiceSpy.readIntSetting(
                 Settings.Global.HDMI_CONTROL_VOLUME_CONTROL_ENABLED, -1)).isEqualTo(
                 HdmiControlManager.VOLUME_CONTROL_ENABLED);
     }
 
     @Test
     public void setAndGetCecVolumeControlEnabledInternal_doesNotChangeSetting() {
-        mHdmiControlService.getHdmiCecConfig().setIntValue(
+        mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
                 HdmiControlManager.CEC_SETTING_NAME_VOLUME_CONTROL_MODE,
                 HdmiControlManager.VOLUME_CONTROL_ENABLED);
 
-        mHdmiControlService.setHdmiCecVolumeControlEnabledInternal(
+        mHdmiControlServiceSpy.setHdmiCecVolumeControlEnabledInternal(
                 HdmiControlManager.VOLUME_CONTROL_DISABLED);
-        assertThat(mHdmiControlService.getHdmiCecConfig().getIntValue(
+        assertThat(mHdmiControlServiceSpy.getHdmiCecConfig().getIntValue(
                 HdmiControlManager.CEC_SETTING_NAME_VOLUME_CONTROL_MODE)).isEqualTo(
                 HdmiControlManager.VOLUME_CONTROL_ENABLED);
 
-        mHdmiControlService.setHdmiCecVolumeControlEnabledInternal(
+        mHdmiControlServiceSpy.setHdmiCecVolumeControlEnabledInternal(
                 HdmiControlManager.VOLUME_CONTROL_ENABLED);
-        assertThat(mHdmiControlService.getHdmiCecConfig().getIntValue(
+        assertThat(mHdmiControlServiceSpy.getHdmiCecConfig().getIntValue(
                 HdmiControlManager.CEC_SETTING_NAME_VOLUME_CONTROL_MODE)).isEqualTo(
                 HdmiControlManager.VOLUME_CONTROL_ENABLED);
     }
@@ -401,60 +400,61 @@
     @Test
     public void disableAndReenableCec_volumeControlReturnsToOriginalValue_enabled() {
         int volumeControlEnabled = HdmiControlManager.VOLUME_CONTROL_ENABLED;
-        mHdmiControlService.setHdmiCecVolumeControlEnabledInternal(volumeControlEnabled);
+        mHdmiControlServiceSpy.setHdmiCecVolumeControlEnabledInternal(volumeControlEnabled);
 
-        mHdmiControlService.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_DISABLED);
-        assertThat(mHdmiControlService.getHdmiCecVolumeControl()).isEqualTo(
+        mHdmiControlServiceSpy.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_DISABLED);
+        assertThat(mHdmiControlServiceSpy.getHdmiCecVolumeControl()).isEqualTo(
                 HdmiControlManager.VOLUME_CONTROL_DISABLED);
 
-        mHdmiControlService.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED);
-        assertThat(mHdmiControlService.getHdmiCecVolumeControl()).isEqualTo(volumeControlEnabled);
+        mHdmiControlServiceSpy.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED);
+        assertThat(mHdmiControlServiceSpy.getHdmiCecVolumeControl())
+                .isEqualTo(volumeControlEnabled);
     }
 
     @Test
     public void disableAndReenableCec_volumeControlReturnsToOriginalValue_disabled() {
         int volumeControlEnabled = HdmiControlManager.VOLUME_CONTROL_DISABLED;
-        mHdmiControlService.getHdmiCecConfig().setIntValue(
+        mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
                 HdmiControlManager.CEC_SETTING_NAME_VOLUME_CONTROL_MODE, volumeControlEnabled);
 
-        mHdmiControlService.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_DISABLED);
-        assertThat(mHdmiControlService.getHdmiCecConfig().getIntValue(
+        mHdmiControlServiceSpy.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_DISABLED);
+        assertThat(mHdmiControlServiceSpy.getHdmiCecConfig().getIntValue(
                 HdmiControlManager.CEC_SETTING_NAME_VOLUME_CONTROL_MODE)).isEqualTo(
                 volumeControlEnabled);
 
-        mHdmiControlService.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED);
-        assertThat(mHdmiControlService.getHdmiCecConfig().getIntValue(
+        mHdmiControlServiceSpy.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED);
+        assertThat(mHdmiControlServiceSpy.getHdmiCecConfig().getIntValue(
                 HdmiControlManager.CEC_SETTING_NAME_VOLUME_CONTROL_MODE)).isEqualTo(
                 volumeControlEnabled);
     }
 
     @Test
     public void disableAndReenableCec_volumeControlFeatureListenersNotified() {
-        mHdmiControlService.getHdmiCecConfig().setIntValue(
+        mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
                 HdmiControlManager.CEC_SETTING_NAME_VOLUME_CONTROL_MODE,
                 HdmiControlManager.VOLUME_CONTROL_ENABLED);
 
         VolumeControlFeatureCallback callback = new VolumeControlFeatureCallback();
-        mHdmiControlService.addHdmiCecVolumeControlFeatureListener(callback);
+        mHdmiControlServiceSpy.addHdmiCecVolumeControlFeatureListener(callback);
 
-        mHdmiControlService.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_DISABLED);
+        mHdmiControlServiceSpy.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_DISABLED);
         assertThat(callback.mCallbackReceived).isTrue();
         assertThat(callback.mVolumeControlEnabled).isEqualTo(
                 HdmiControlManager.VOLUME_CONTROL_DISABLED);
 
 
-        mHdmiControlService.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED);
+        mHdmiControlServiceSpy.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED);
         assertThat(callback.mVolumeControlEnabled).isEqualTo(
                 HdmiControlManager.VOLUME_CONTROL_ENABLED);
     }
 
     @Test
     public void addHdmiCecVolumeControlFeatureListener_emitsCurrentState_enabled() {
-        mHdmiControlService.setHdmiCecVolumeControlEnabledInternal(
+        mHdmiControlServiceSpy.setHdmiCecVolumeControlEnabledInternal(
                 HdmiControlManager.VOLUME_CONTROL_ENABLED);
         VolumeControlFeatureCallback callback = new VolumeControlFeatureCallback();
 
-        mHdmiControlService.addHdmiCecVolumeControlFeatureListener(callback);
+        mHdmiControlServiceSpy.addHdmiCecVolumeControlFeatureListener(callback);
         mTestLooper.dispatchAll();
 
         assertThat(callback.mCallbackReceived).isTrue();
@@ -464,11 +464,11 @@
 
     @Test
     public void addHdmiCecVolumeControlFeatureListener_emitsCurrentState_disabled() {
-        mHdmiControlService.setHdmiCecVolumeControlEnabledInternal(
+        mHdmiControlServiceSpy.setHdmiCecVolumeControlEnabledInternal(
                 HdmiControlManager.VOLUME_CONTROL_DISABLED);
         VolumeControlFeatureCallback callback = new VolumeControlFeatureCallback();
 
-        mHdmiControlService.addHdmiCecVolumeControlFeatureListener(callback);
+        mHdmiControlServiceSpy.addHdmiCecVolumeControlFeatureListener(callback);
         mTestLooper.dispatchAll();
 
         assertThat(callback.mCallbackReceived).isTrue();
@@ -478,13 +478,13 @@
 
     @Test
     public void addHdmiCecVolumeControlFeatureListener_notifiesStateUpdate() {
-        mHdmiControlService.setHdmiCecVolumeControlEnabledInternal(
+        mHdmiControlServiceSpy.setHdmiCecVolumeControlEnabledInternal(
                 HdmiControlManager.VOLUME_CONTROL_DISABLED);
         VolumeControlFeatureCallback callback = new VolumeControlFeatureCallback();
 
-        mHdmiControlService.addHdmiCecVolumeControlFeatureListener(callback);
+        mHdmiControlServiceSpy.addHdmiCecVolumeControlFeatureListener(callback);
 
-        mHdmiControlService.setHdmiCecVolumeControlEnabledInternal(
+        mHdmiControlServiceSpy.setHdmiCecVolumeControlEnabledInternal(
                 HdmiControlManager.VOLUME_CONTROL_ENABLED);
         mTestLooper.dispatchAll();
 
@@ -495,15 +495,15 @@
 
     @Test
     public void addHdmiCecVolumeControlFeatureListener_honorsUnregistration() {
-        mHdmiControlService.setHdmiCecVolumeControlEnabledInternal(
+        mHdmiControlServiceSpy.setHdmiCecVolumeControlEnabledInternal(
                 HdmiControlManager.VOLUME_CONTROL_DISABLED);
         VolumeControlFeatureCallback callback = new VolumeControlFeatureCallback();
 
-        mHdmiControlService.addHdmiCecVolumeControlFeatureListener(callback);
+        mHdmiControlServiceSpy.addHdmiCecVolumeControlFeatureListener(callback);
         mTestLooper.dispatchAll();
 
-        mHdmiControlService.removeHdmiControlVolumeControlStatusChangeListener(callback);
-        mHdmiControlService.setHdmiCecVolumeControlEnabledInternal(
+        mHdmiControlServiceSpy.removeHdmiControlVolumeControlStatusChangeListener(callback);
+        mHdmiControlServiceSpy.setHdmiCecVolumeControlEnabledInternal(
                 HdmiControlManager.VOLUME_CONTROL_ENABLED);
         mTestLooper.dispatchAll();
 
@@ -514,16 +514,16 @@
 
     @Test
     public void addHdmiCecVolumeControlFeatureListener_notifiesStateUpdate_multiple() {
-        mHdmiControlService.setHdmiCecVolumeControlEnabledInternal(
+        mHdmiControlServiceSpy.setHdmiCecVolumeControlEnabledInternal(
                 HdmiControlManager.VOLUME_CONTROL_DISABLED);
         VolumeControlFeatureCallback callback1 = new VolumeControlFeatureCallback();
         VolumeControlFeatureCallback callback2 = new VolumeControlFeatureCallback();
 
-        mHdmiControlService.addHdmiCecVolumeControlFeatureListener(callback1);
-        mHdmiControlService.addHdmiCecVolumeControlFeatureListener(callback2);
+        mHdmiControlServiceSpy.addHdmiCecVolumeControlFeatureListener(callback1);
+        mHdmiControlServiceSpy.addHdmiCecVolumeControlFeatureListener(callback2);
 
 
-        mHdmiControlService.setHdmiCecVolumeControlEnabledInternal(
+        mHdmiControlServiceSpy.setHdmiCecVolumeControlEnabledInternal(
                 HdmiControlManager.VOLUME_CONTROL_ENABLED);
         mTestLooper.dispatchAll();
 
@@ -537,47 +537,48 @@
 
     @Test
     public void getCecVersion_1_4() {
-        mHdmiControlService.getHdmiCecConfig().setIntValue(
+        mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
                 HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION,
                 HdmiControlManager.HDMI_CEC_VERSION_1_4_B);
-        mHdmiControlService.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED);
-        assertThat(mHdmiControlService.getCecVersion()).isEqualTo(
+        mHdmiControlServiceSpy.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED);
+        assertThat(mHdmiControlServiceSpy.getCecVersion()).isEqualTo(
                 HdmiControlManager.HDMI_CEC_VERSION_1_4_B);
     }
 
     @Test
     public void getCecVersion_2_0() {
-        mHdmiControlService.getHdmiCecConfig().setIntValue(
+        mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
                 HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION,
                 HdmiControlManager.HDMI_CEC_VERSION_2_0);
-        mHdmiControlService.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED);
-        assertThat(mHdmiControlService.getCecVersion()).isEqualTo(
+        mHdmiControlServiceSpy.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED);
+        assertThat(mHdmiControlServiceSpy.getCecVersion()).isEqualTo(
                 HdmiControlManager.HDMI_CEC_VERSION_2_0);
     }
 
     @Test
     public void getCecVersion_change() {
-        mHdmiControlService.getHdmiCecConfig().setIntValue(
+        mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
                 HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION,
                 HdmiControlManager.HDMI_CEC_VERSION_1_4_B);
-        mHdmiControlService.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED);
-        assertThat(mHdmiControlService.getCecVersion()).isEqualTo(
+        mHdmiControlServiceSpy.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED);
+        assertThat(mHdmiControlServiceSpy.getCecVersion()).isEqualTo(
                 HdmiControlManager.HDMI_CEC_VERSION_1_4_B);
 
-        mHdmiControlService.getHdmiCecConfig().setIntValue(
+        mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
                 HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION,
                 HdmiControlManager.HDMI_CEC_VERSION_2_0);
-        mHdmiControlService.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED);
-        assertThat(mHdmiControlService.getCecVersion()).isEqualTo(
+        mHdmiControlServiceSpy.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED);
+        assertThat(mHdmiControlServiceSpy.getCecVersion()).isEqualTo(
                 HdmiControlManager.HDMI_CEC_VERSION_2_0);
     }
 
     @Test
     public void handleGiveFeatures_cec14_featureAbort() {
-        mHdmiControlService.getHdmiCecConfig().setIntValue(
+        mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
                 HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION,
                 HdmiControlManager.HDMI_CEC_VERSION_1_4_B);
-        mHdmiControlService.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED);
+        mHdmiControlServiceSpy.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED);
+        mHdmiControlServiceSpy.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
         mTestLooper.dispatchAll();
 
         mNativeWrapper.onCecMessage(HdmiCecMessageBuilder.buildGiveFeatures(Constants.ADDR_TV,
@@ -592,11 +593,11 @@
 
     @Test
     public void handleGiveFeatures_cec20_reportsFeatures() {
-        mHdmiControlService.getHdmiCecConfig().setIntValue(
+        mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
                 HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION,
                 HdmiControlManager.HDMI_CEC_VERSION_2_0);
-        mHdmiControlService.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED);
-        mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
+        mHdmiControlServiceSpy.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED);
+        mHdmiControlServiceSpy.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
         mTestLooper.dispatchAll();
 
         mNativeWrapper.onCecMessage(HdmiCecMessageBuilder.buildGiveFeatures(Constants.ADDR_TV,
@@ -606,43 +607,43 @@
         HdmiCecMessage reportFeatures = HdmiCecMessageBuilder.buildReportFeatures(
                 Constants.ADDR_PLAYBACK_1, HdmiControlManager.HDMI_CEC_VERSION_2_0,
                 Arrays.asList(DEVICE_PLAYBACK, DEVICE_AUDIO_SYSTEM),
-                mPlaybackDevice.getRcProfile(), mPlaybackDevice.getRcFeatures(),
-                mPlaybackDevice.getDeviceFeatures());
+                mPlaybackDeviceSpy.getRcProfile(), mPlaybackDeviceSpy.getRcFeatures(),
+                mPlaybackDeviceSpy.getDeviceFeatures());
         assertThat(mNativeWrapper.getResultMessages()).contains(reportFeatures);
     }
 
     @Test
     public void initializeCec_14_doesNotBroadcastReportFeatures() {
         mNativeWrapper.clearResultMessages();
-        mHdmiControlService.getHdmiCecConfig().setIntValue(
+        mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
                 HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION,
                 HdmiControlManager.HDMI_CEC_VERSION_1_4_B);
-        mHdmiControlService.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED);
-        mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
+        mHdmiControlServiceSpy.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED);
+        mHdmiControlServiceSpy.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
         mTestLooper.dispatchAll();
 
         HdmiCecMessage reportFeatures = HdmiCecMessageBuilder.buildReportFeatures(
                 Constants.ADDR_PLAYBACK_1, HdmiControlManager.HDMI_CEC_VERSION_2_0,
                 Arrays.asList(DEVICE_PLAYBACK, DEVICE_AUDIO_SYSTEM),
-                mPlaybackDevice.getRcProfile(), mPlaybackDevice.getRcFeatures(),
-                mPlaybackDevice.getDeviceFeatures());
+                mPlaybackDeviceSpy.getRcProfile(), mPlaybackDeviceSpy.getRcFeatures(),
+                mPlaybackDeviceSpy.getDeviceFeatures());
         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(reportFeatures);
     }
 
     @Test
     public void initializeCec_20_reportsFeaturesBroadcast() {
-        mHdmiControlService.getHdmiCecConfig().setIntValue(
+        mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
                 HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION,
                 HdmiControlManager.HDMI_CEC_VERSION_2_0);
-        mHdmiControlService.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED);
-        mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
+        mHdmiControlServiceSpy.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED);
+        mHdmiControlServiceSpy.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
         mTestLooper.dispatchAll();
 
         HdmiCecMessage reportFeatures = HdmiCecMessageBuilder.buildReportFeatures(
                 Constants.ADDR_PLAYBACK_1, HdmiControlManager.HDMI_CEC_VERSION_2_0,
                 Arrays.asList(DEVICE_PLAYBACK, DEVICE_AUDIO_SYSTEM),
-                mPlaybackDevice.getRcProfile(), mPlaybackDevice.getRcFeatures(),
-                mPlaybackDevice.getDeviceFeatures());
+                mPlaybackDeviceSpy.getRcProfile(), mPlaybackDeviceSpy.getRcFeatures(),
+                mPlaybackDeviceSpy.getDeviceFeatures());
         assertThat(mNativeWrapper.getResultMessages()).contains(reportFeatures);
     }
 
@@ -653,7 +654,7 @@
 
         Binder.setCallingWorkSourceUid(callerUid);
         WorkSourceUidReadingRunnable uidReadingRunnable = new WorkSourceUidReadingRunnable();
-        mHdmiControlService.runOnServiceThread(uidReadingRunnable);
+        mHdmiControlServiceSpy.runOnServiceThread(uidReadingRunnable);
 
         Binder.setCallingWorkSourceUid(runnerUid);
 
@@ -666,36 +667,36 @@
     @Test
     public void initCecVersion_limitToMinimumSupportedVersion() {
         mNativeWrapper.setCecVersion(HdmiControlManager.HDMI_CEC_VERSION_1_4_B);
-        mHdmiControlService.getHdmiCecConfig().setIntValue(
+        mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
                 HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION,
                 HdmiControlManager.HDMI_CEC_VERSION_2_0);
 
         mTestLooper.dispatchAll();
-        assertThat(mHdmiControlService.getCecVersion()).isEqualTo(
+        assertThat(mHdmiControlServiceSpy.getCecVersion()).isEqualTo(
                 HdmiControlManager.HDMI_CEC_VERSION_1_4_B);
     }
 
     @Test
     public void initCecVersion_limitToAtLeast1_4() {
         mNativeWrapper.setCecVersion(0x0);
-        mHdmiControlService.getHdmiCecConfig().setIntValue(
+        mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
                 HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION,
                 HdmiControlManager.HDMI_CEC_VERSION_2_0);
 
         mTestLooper.dispatchAll();
-        assertThat(mHdmiControlService.getCecVersion()).isEqualTo(
+        assertThat(mHdmiControlServiceSpy.getCecVersion()).isEqualTo(
                 HdmiControlManager.HDMI_CEC_VERSION_1_4_B);
     }
 
     @Test
     public void initCecVersion_useHighestMatchingVersion() {
         mNativeWrapper.setCecVersion(HdmiControlManager.HDMI_CEC_VERSION_2_0);
-        mHdmiControlService.getHdmiCecConfig().setIntValue(
+        mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
                 HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION,
                 HdmiControlManager.HDMI_CEC_VERSION_2_0);
 
         mTestLooper.dispatchAll();
-        assertThat(mHdmiControlService.getCecVersion()).isEqualTo(
+        assertThat(mHdmiControlServiceSpy.getCecVersion()).isEqualTo(
                 HdmiControlManager.HDMI_CEC_VERSION_2_0);
     }
 
@@ -710,4 +711,140 @@
             this.mVolumeControlEnabled = enabled;
         }
     }
+
+    @Test
+    public void handleCecCommand_errorParameter_returnsAbortInvalidOperand() {
+        // Validity ERROR_PARAMETER. Taken from HdmiCecMessageValidatorTest#isValid_menuStatus
+        HdmiCecMessage message = HdmiUtils.buildMessage("40:8D:03");
+
+        assertThat(mHdmiControlServiceSpy.handleCecCommand(message))
+                .isEqualTo(Constants.ABORT_INVALID_OPERAND);
+    }
+
+    @Test
+    public void handleCecCommand_errorSource_returnsHandled() {
+        // Validity ERROR_SOURCE. Taken from HdmiCecMessageValidatorTest#isValid_menuStatus
+        HdmiCecMessage message = HdmiUtils.buildMessage("F0:8E");
+
+        assertThat(mHdmiControlServiceSpy.handleCecCommand(message))
+                .isEqualTo(Constants.HANDLED);
+
+    }
+
+    @Test
+    public void handleCecCommand_errorDestination_returnsHandled() {
+        // Validity ERROR_DESTINATION. Taken from HdmiCecMessageValidatorTest#isValid_menuStatus
+        HdmiCecMessage message = HdmiUtils.buildMessage("0F:8E:00");
+
+        assertThat(mHdmiControlServiceSpy.handleCecCommand(message))
+                .isEqualTo(Constants.HANDLED);
+    }
+
+    @Test
+    public void handleCecCommand_errorParameterShort_returnsHandled() {
+        // Validity ERROR_PARAMETER_SHORT
+        // Taken from HdmiCecMessageValidatorTest#isValid_menuStatus
+        HdmiCecMessage message = HdmiUtils.buildMessage("40:8E");
+
+        assertThat(mHdmiControlServiceSpy.handleCecCommand(message))
+                .isEqualTo(Constants.HANDLED);
+    }
+
+    @Test
+    public void handleCecCommand_notHandledByLocalDevice_returnsNotHandled() {
+        HdmiCecMessage message = HdmiCecMessageBuilder.buildReportPowerStatus(
+                Constants.ADDR_TV,
+                Constants.ADDR_PLAYBACK_1,
+                HdmiControlManager.POWER_STATUS_ON);
+
+        doReturn(Constants.NOT_HANDLED).when(mHdmiControlServiceSpy)
+                .dispatchMessageToLocalDevice(message);
+
+        assertThat(mHdmiControlServiceSpy.handleCecCommand(message))
+                .isEqualTo(Constants.NOT_HANDLED);
+    }
+
+    @Test
+    public void handleCecCommand_handledByLocalDevice_returnsHandled() {
+        HdmiCecMessage message = HdmiCecMessageBuilder.buildReportPowerStatus(
+                Constants.ADDR_TV,
+                Constants.ADDR_PLAYBACK_1,
+                HdmiControlManager.POWER_STATUS_ON);
+
+        doReturn(Constants.HANDLED).when(mHdmiControlServiceSpy)
+                .dispatchMessageToLocalDevice(message);
+
+        assertThat(mHdmiControlServiceSpy.handleCecCommand(message))
+                .isEqualTo(Constants.HANDLED);
+    }
+
+    @Test
+    public void handleCecCommand_localDeviceReturnsFeatureAbort_returnsFeatureAbort() {
+        HdmiCecMessage message = HdmiCecMessageBuilder.buildReportPowerStatus(
+                Constants.ADDR_TV,
+                Constants.ADDR_PLAYBACK_1,
+                HdmiControlManager.POWER_STATUS_ON);
+
+        doReturn(Constants.ABORT_REFUSED).when(mHdmiControlServiceSpy)
+                .dispatchMessageToLocalDevice(message);
+
+        assertThat(mHdmiControlServiceSpy.handleCecCommand(message))
+                .isEqualTo(Constants.ABORT_REFUSED);
+    }
+
+    @Test
+    public void dispatchMessageToLocalDevice_broadcastMessage_returnsHandled() {
+        HdmiCecMessage message = HdmiCecMessageBuilder.buildStandby(
+                Constants.ADDR_TV,
+                Constants.ADDR_BROADCAST);
+
+        doReturn(Constants.ABORT_REFUSED).when(mPlaybackDeviceSpy).dispatchMessage(message);
+        doReturn(Constants.ABORT_NOT_IN_CORRECT_MODE)
+                .when(mAudioSystemDeviceSpy).dispatchMessage(message);
+
+        assertThat(mHdmiControlServiceSpy.dispatchMessageToLocalDevice(message))
+                .isEqualTo(Constants.HANDLED);
+    }
+
+    @Test
+    public void dispatchMessageToLocalDevice_localDevicesDoNotHandleMessage_returnsUnhandled() {
+        HdmiCecMessage message = HdmiCecMessageBuilder.buildStandby(
+                Constants.ADDR_TV,
+                Constants.ADDR_PLAYBACK_1);
+
+        doReturn(Constants.NOT_HANDLED).when(mPlaybackDeviceSpy).dispatchMessage(message);
+        doReturn(Constants.NOT_HANDLED)
+                .when(mAudioSystemDeviceSpy).dispatchMessage(message);
+
+        assertThat(mHdmiControlServiceSpy.dispatchMessageToLocalDevice(message))
+                .isEqualTo(Constants.NOT_HANDLED);
+    }
+
+    @Test
+    public void dispatchMessageToLocalDevice_localDeviceHandlesMessage_returnsHandled() {
+        HdmiCecMessage message = HdmiCecMessageBuilder.buildStandby(
+                Constants.ADDR_TV,
+                Constants.ADDR_PLAYBACK_1);
+
+        doReturn(Constants.NOT_HANDLED).when(mPlaybackDeviceSpy).dispatchMessage(message);
+        doReturn(Constants.HANDLED)
+                .when(mAudioSystemDeviceSpy).dispatchMessage(message);
+
+        assertThat(mHdmiControlServiceSpy.dispatchMessageToLocalDevice(message))
+                .isEqualTo(Constants.HANDLED);
+    }
+
+    @Test
+    public void dispatchMessageToLocalDevice_localDeviceReturnsFeatureAbort_returnsFeatureAbort() {
+        HdmiCecMessage message = HdmiCecMessageBuilder.buildStandby(
+                Constants.ADDR_TV,
+                Constants.ADDR_PLAYBACK_1);
+
+        doReturn(Constants.NOT_HANDLED).when(mPlaybackDeviceSpy).dispatchMessage(message);
+        doReturn(Constants.ABORT_REFUSED)
+                .when(mAudioSystemDeviceSpy).dispatchMessage(message);
+
+        assertThat(mHdmiControlServiceSpy.dispatchMessageToLocalDevice(message))
+                .isEqualTo(Constants.ABORT_REFUSED);
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/OneTouchPlayActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/OneTouchPlayActionTest.java
index c61635c..d74bff2 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/OneTouchPlayActionTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/OneTouchPlayActionTest.java
@@ -37,13 +37,13 @@
 import android.os.Looper;
 import android.os.PowerManager;
 import android.os.test.TestLooper;
+import android.provider.Settings;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.SmallTest;
 
 import com.android.server.hdmi.HdmiCecFeatureAction.ActionTimer;
 
-import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
@@ -79,12 +79,18 @@
     @Mock
     private IThermalService mIThermalServiceMock;
 
-    @Before
-    public void setUp() throws Exception {
+    /**
+     * Manually called before tests, because some tests require HDMI control to be disabled.
+     * @param hdmiControlEnabled whether to enable the global setting hdmi_control.
+     * @throws Exception
+     */
+    public void setUp(boolean hdmiControlEnabled) throws Exception {
         MockitoAnnotations.initMocks(this);
 
         mContextSpy = spy(new ContextWrapper(InstrumentationRegistry.getTargetContext()));
 
+        setHdmiControlEnabled(hdmiControlEnabled);
+
         PowerManager powerManager = new PowerManager(mContextSpy, mIPowerManagerMock,
                 mIThermalServiceMock, new Handler(mTestLooper.getLooper()));
         when(mContextSpy.getSystemService(Context.POWER_SERVICE)).thenReturn(powerManager);
@@ -146,7 +152,9 @@
     }
 
     @Test
-    public void succeedWithUnknownTvDevice() {
+    public void succeedWithUnknownTvDevice() throws Exception {
+        setUp(true);
+
         HdmiCecLocalDevicePlayback playbackDevice = new HdmiCecLocalDevicePlayback(
                 mHdmiControlService);
         playbackDevice.init();
@@ -185,7 +193,9 @@
     }
 
     @Test
-    public void succeedAfterGettingPowerStatusOn_Cec14b() {
+    public void succeedAfterGettingPowerStatusOn_Cec14b() throws Exception {
+        setUp(true);
+
         mHdmiControlService.getHdmiCecNetwork().addCecDevice(INFO_TV);
         HdmiCecLocalDevicePlayback playbackDevice = new HdmiCecLocalDevicePlayback(
                 mHdmiControlService);
@@ -225,7 +235,9 @@
     }
 
     @Test
-    public void succeedAfterGettingTransientPowerStatus_Cec14b() {
+    public void succeedAfterGettingTransientPowerStatus_Cec14b() throws Exception {
+        setUp(true);
+
         mHdmiControlService.getHdmiCecNetwork().addCecDevice(INFO_TV);
         HdmiCecLocalDevicePlayback playbackDevice = new HdmiCecLocalDevicePlayback(
                 mHdmiControlService);
@@ -275,7 +287,9 @@
     }
 
     @Test
-    public void timeOut_Cec14b() {
+    public void timeOut_Cec14b() throws Exception {
+        setUp(true);
+
         mHdmiControlService.getHdmiCecNetwork().addCecDevice(INFO_TV);
         HdmiCecLocalDevicePlayback playbackDevice = new HdmiCecLocalDevicePlayback(
                 mHdmiControlService);
@@ -316,7 +330,9 @@
     }
 
     @Test
-    public void succeedIfPowerStatusOn_Cec20() {
+    public void succeedIfPowerStatusOn_Cec20() throws Exception {
+        setUp(true);
+
         mHdmiControlService.getHdmiCecNetwork().addCecDevice(INFO_TV);
         HdmiCecLocalDevicePlayback playbackDevice = new HdmiCecLocalDevicePlayback(
                 mHdmiControlService);
@@ -348,7 +364,9 @@
     }
 
     @Test
-    public void succeedIfPowerStatusUnknown_Cec20() {
+    public void succeedIfPowerStatusUnknown_Cec20() throws Exception {
+        setUp(true);
+
         mHdmiControlService.getHdmiCecNetwork().addCecDevice(INFO_TV);
         HdmiCecLocalDevicePlayback playbackDevice = new HdmiCecLocalDevicePlayback(
                 mHdmiControlService);
@@ -390,7 +408,9 @@
     }
 
     @Test
-    public void succeedIfPowerStatusStandby_Cec20() {
+    public void succeedIfPowerStatusStandby_Cec20() throws Exception {
+        setUp(true);
+
         mHdmiControlService.getHdmiCecNetwork().addCecDevice(INFO_TV);
         HdmiCecLocalDevicePlayback playbackDevice = new HdmiCecLocalDevicePlayback(
                 mHdmiControlService);
@@ -431,6 +451,73 @@
         assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_SUCCESS);
     }
 
+    @Test
+    public void succeedWithAddressNotAllocated_Cec14b() throws Exception {
+        setUp(false);
+
+        assertThat(mHdmiControlService.isAddressAllocated()).isFalse();
+
+        HdmiCecLocalDevicePlayback playbackDevice = new HdmiCecLocalDevicePlayback(
+                mHdmiControlService);
+        playbackDevice.init();
+        mLocalDevices.add(playbackDevice);
+
+        TestCallback callback = new TestCallback();
+
+        mHdmiControlService.oneTouchPlay(callback);
+        mTestLooper.dispatchAll();
+
+        assertThat(callback.hasResult()).isFalse();
+        assertThat(playbackDevice.isActiveSource()).isFalse();
+
+        setHdmiControlEnabled(true);
+        mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
+
+        mTestLooper.dispatchAll();
+
+        HdmiCecMessage reportPowerStatusMessage = HdmiCecMessageBuilder.buildReportPowerStatus(
+                Constants.ADDR_TV,
+                playbackDevice.mAddress,
+                HdmiControlManager.POWER_STATUS_ON
+        );
+        mNativeWrapper.onCecMessage(reportPowerStatusMessage);
+
+        mTestLooper.dispatchAll();
+
+        assertThat(mHdmiControlService.isAddressAllocated()).isTrue();
+        assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_SUCCESS);
+        assertThat(playbackDevice.isActiveSource()).isTrue();
+    }
+
+    @Test
+    public void succeedWithAddressAllocated_Cec14b() throws Exception {
+        setUp(true);
+
+        HdmiCecLocalDevicePlayback playbackDevice = new HdmiCecLocalDevicePlayback(
+                mHdmiControlService);
+        playbackDevice.init();
+        mLocalDevices.add(playbackDevice);
+
+        mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
+        mTestLooper.dispatchAll();
+        assertThat(mHdmiControlService.isAddressAllocated()).isTrue();
+
+        TestCallback callback = new TestCallback();
+        mHdmiControlService.oneTouchPlay(callback);
+
+        HdmiCecMessage reportPowerStatusMessage = HdmiCecMessageBuilder.buildReportPowerStatus(
+                Constants.ADDR_TV,
+                playbackDevice.mAddress,
+                HdmiControlManager.POWER_STATUS_ON
+        );
+        mNativeWrapper.onCecMessage(reportPowerStatusMessage);
+
+        mTestLooper.dispatchAll();
+
+        assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_SUCCESS);
+        assertThat(playbackDevice.isActiveSource()).isTrue();
+    }
+
     private static class TestActionTimer implements ActionTimer {
         private int mState;
 
@@ -456,9 +543,19 @@
             mCallbackResult.add(result);
         }
 
+        private boolean hasResult() {
+            return mCallbackResult.size() != 0;
+        }
+
         private int getResult() {
             assertThat(mCallbackResult.size()).isEqualTo(1);
             return mCallbackResult.get(0);
         }
     }
+
+    private void setHdmiControlEnabled(boolean enabled) {
+        int value = enabled ? 1 : 0;
+        Settings.Global.putInt(mContextSpy.getContentResolver(),
+                Settings.Global.HDMI_CONTROL_ENABLED, value);
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodUtilsTest.java b/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodUtilsTest.java
index eebc25a..6f1268e 100644
--- a/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodUtilsTest.java
+++ b/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodUtilsTest.java
@@ -23,6 +23,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
 import android.content.Context;
@@ -34,6 +35,7 @@
 import android.os.Build;
 import android.os.LocaleList;
 import android.os.Parcel;
+import android.util.ArrayMap;
 import android.view.inputmethod.InputMethodInfo;
 import android.view.inputmethod.InputMethodSubtype;
 import android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder;
@@ -48,6 +50,7 @@
 import org.junit.runner.RunWith;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.Locale;
 import java.util.Objects;
@@ -793,6 +796,97 @@
         }
     }
 
+    @Test
+    public void testChooseSystemVoiceIme() throws Exception {
+        final InputMethodInfo systemIme = createFakeInputMethodInfo("SystemIme", "fake.voice0",
+                true /* isSystem */);
+
+        // Returns null when the config value is null.
+        {
+            final ArrayMap<String, InputMethodInfo> methodMap = new ArrayMap<>();
+            methodMap.put(systemIme.getId(), systemIme);
+            assertNull(InputMethodUtils.chooseSystemVoiceIme(methodMap, null, ""));
+        }
+
+        // Returns null when the config value is empty.
+        {
+            final ArrayMap<String, InputMethodInfo> methodMap = new ArrayMap<>();
+            methodMap.put(systemIme.getId(), systemIme);
+            assertNull(InputMethodUtils.chooseSystemVoiceIme(methodMap, "", ""));
+        }
+
+        // Returns null when the configured package doesn't have an IME.
+        {
+            assertNull(InputMethodUtils.chooseSystemVoiceIme(new ArrayMap<>(),
+                    systemIme.getPackageName(), ""));
+        }
+
+        // Returns the right one when the current default is null.
+        {
+            final ArrayMap<String, InputMethodInfo> methodMap = new ArrayMap<>();
+            methodMap.put(systemIme.getId(), systemIme);
+            assertEquals(systemIme, InputMethodUtils.chooseSystemVoiceIme(methodMap,
+                    systemIme.getPackageName(), null));
+        }
+
+        // Returns the right one when the current default is empty.
+        {
+            final ArrayMap<String, InputMethodInfo> methodMap = new ArrayMap<>();
+            methodMap.put(systemIme.getId(), systemIme);
+            assertEquals(systemIme, InputMethodUtils.chooseSystemVoiceIme(methodMap,
+                    systemIme.getPackageName(), ""));
+        }
+
+        // Returns null when the current default isn't found.
+        {
+            assertNull(InputMethodUtils.chooseSystemVoiceIme(new ArrayMap<>(),
+                    systemIme.getPackageName(), systemIme.getId()));
+        }
+
+        // Returns null when there are multiple IMEs defined by the config package.
+        {
+            final InputMethodInfo secondIme = createFakeInputMethodInfo(systemIme.getPackageName(),
+                    "fake.voice1", true /* isSystem */);
+            final ArrayMap<String, InputMethodInfo> methodMap = new ArrayMap<>();
+            methodMap.put(systemIme.getId(), systemIme);
+            methodMap.put(secondIme.getId(), secondIme);
+            assertNull(InputMethodUtils.chooseSystemVoiceIme(methodMap, systemIme.getPackageName(),
+                    ""));
+        }
+
+        // Returns the current one when the current default and config point to the same package.
+        {
+            final InputMethodInfo secondIme = createFakeInputMethodInfo("SystemIme", "fake.voice1",
+                    true /* isSystem */);
+            final ArrayMap<String, InputMethodInfo> methodMap = new ArrayMap<>();
+            methodMap.put(systemIme.getId(), systemIme);
+            methodMap.put(secondIme.getId(), secondIme);
+            assertEquals(systemIme, InputMethodUtils.chooseSystemVoiceIme(methodMap,
+                    systemIme.getPackageName(), systemIme.getId()));
+        }
+
+        // Doesn't return the current default if it isn't a system app.
+        {
+            final ArrayMap<String, InputMethodInfo> methodMap = new ArrayMap<>();
+            final InputMethodInfo nonSystemIme = createFakeInputMethodInfo("NonSystemIme",
+                    "fake.voice0", false /* isSystem */);
+            methodMap.put(nonSystemIme.getId(), nonSystemIme);
+            assertNull(InputMethodUtils.chooseSystemVoiceIme(methodMap,
+                    nonSystemIme.getPackageName(), nonSystemIme.getId()));
+        }
+
+        // Returns null if the configured one isn't a system app.
+        {
+            final ArrayMap<String, InputMethodInfo> methodMap = new ArrayMap<>();
+            final InputMethodInfo nonSystemIme = createFakeInputMethodInfo(
+                    "FakeDefaultAutoVoiceIme", "fake.voice0", false /* isSystem */);
+            methodMap.put(systemIme.getId(), systemIme);
+            methodMap.put(nonSystemIme.getId(), nonSystemIme);
+            assertNull(InputMethodUtils.chooseSystemVoiceIme(methodMap,
+                    nonSystemIme.getPackageName(), ""));
+        }
+    }
+
     private void assertDefaultEnabledImes(final ArrayList<InputMethodInfo> preinstalledImes,
             final Locale systemLocale, String... expectedImeNames) {
         final Context context = createTargetContextWithLocales(new LocaleList(systemLocale));
@@ -866,6 +960,25 @@
     }
 
     private static InputMethodInfo createFakeInputMethodInfo(String packageName, String name,
+            boolean isSystem) {
+        final ResolveInfo ri = new ResolveInfo();
+        final ServiceInfo si = new ServiceInfo();
+        final ApplicationInfo ai = new ApplicationInfo();
+        ai.packageName = packageName;
+        ai.enabled = true;
+        if (isSystem) {
+            ai.flags |= ApplicationInfo.FLAG_SYSTEM;
+        }
+        si.applicationInfo = ai;
+        si.enabled = true;
+        si.packageName = packageName;
+        si.name = name;
+        si.exported = true;
+        ri.serviceInfo = si;
+        return new InputMethodInfo(ri, false, "", Collections.emptyList(), 1, true);
+    }
+
+    private static InputMethodInfo createFakeInputMethodInfo(String packageName, String name,
             CharSequence label, boolean isAuxIme, boolean isDefault,
             List<InputMethodSubtype> subtypes) {
         final ResolveInfo ri = new ResolveInfo();
diff --git a/services/tests/servicestests/src/com/android/server/job/BackgroundRestrictionsTest.java b/services/tests/servicestests/src/com/android/server/job/BackgroundRestrictionsTest.java
index a7b32ac..68a6e60 100644
--- a/services/tests/servicestests/src/com/android/server/job/BackgroundRestrictionsTest.java
+++ b/services/tests/servicestests/src/com/android/server/job/BackgroundRestrictionsTest.java
@@ -96,7 +96,7 @@
                     case ACTION_JOB_STOPPED:
                         mTestJobStatus.running = false;
                         mTestJobStatus.jobId = params.getJobId();
-                        mTestJobStatus.stopReason = params.getStopReason();
+                        mTestJobStatus.stopReason = params.getLegacyStopReason();
                         break;
                 }
             }
diff --git a/services/tests/servicestests/src/com/android/server/job/MockPriorityJobService.java b/services/tests/servicestests/src/com/android/server/job/MockPriorityJobService.java
index 3ea86f2..87881bf 100644
--- a/services/tests/servicestests/src/com/android/server/job/MockPriorityJobService.java
+++ b/services/tests/servicestests/src/com/android/server/job/MockPriorityJobService.java
@@ -47,7 +47,7 @@
         int reason = params.getStopReason();
         int event = TestEnvironment.EVENT_STOP_JOB;
         Log.d(TAG, "stop reason: " + String.valueOf(reason));
-        if (reason == JobParameters.REASON_PREEMPT) {
+        if (reason == JobParameters.STOP_REASON_PREEMPT) {
             event = TestEnvironment.EVENT_PREEMPT_JOB;
             Log.d(TAG, "preempted " + String.valueOf(params.getJobId()));
         }
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java b/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java
index 91342ce..8c08226 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java
@@ -21,6 +21,7 @@
 import static android.content.pm.UserInfo.FLAG_PROFILE;
 import static android.os.UserHandle.USER_SYSTEM;
 
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
@@ -110,6 +111,10 @@
     public interface MockableRebootEscrowInjected {
         int getBootCount();
 
+        long getCurrentTimeMillis();
+
+        boolean forceServerBased();
+
         void reportMetric(boolean success, int errorCode, int serviceType, int attemptCount,
                 int escrowDurationInSeconds, int vbmetaDigestStatus, int durationSinceBootComplete);
     }
@@ -174,6 +179,9 @@
 
         @Override
         public boolean serverBasedResumeOnReboot() {
+            if (mInjected.forceServerBased()) {
+                return true;
+            }
             return mServerBased;
         }
 
@@ -205,9 +213,20 @@
         }
 
         @Override
+        public String getVbmetaDigest(boolean other) {
+            return other ? "" : "fake digest";
+        }
+
+        @Override
+        public long getCurrentTimeMillis() {
+            return mInjected.getCurrentTimeMillis();
+        }
+
+        @Override
         public void reportMetric(boolean success, int errorCode, int serviceType, int attemptCount,
                 int escrowDurationInSeconds, int vbmetaDigestStatus,
                 int durationSinceBootComplete) {
+
             mInjected.reportMetric(success, errorCode, serviceType, attemptCount,
                     escrowDurationInSeconds, vbmetaDigestStatus, durationSinceBootComplete);
         }
@@ -430,16 +449,21 @@
         // pretend reboot happens here
 
         when(mInjected.getBootCount()).thenReturn(1);
+        when(mInjected.getCurrentTimeMillis()).thenReturn(30000L);
+        mStorage.setLong(RebootEscrowManager.REBOOT_ESCROW_KEY_ARMED_TIMESTAMP, 10000L,
+                USER_SYSTEM);
         ArgumentCaptor<Boolean> metricsSuccessCaptor = ArgumentCaptor.forClass(Boolean.class);
         doNothing().when(mInjected).reportMetric(metricsSuccessCaptor.capture(),
                 eq(0) /* error code */, eq(1) /* HAL based */, eq(1) /* attempt count */,
-                anyInt(), anyInt(), anyInt());
+                eq(20), eq(0) /* vbmeta status */, anyInt());
         when(mRebootEscrow.retrieveKey()).thenAnswer(invocation -> keyByteCaptor.getValue());
 
         mService.loadRebootEscrowDataIfAvailable(null);
         verify(mRebootEscrow).retrieveKey();
         assertTrue(metricsSuccessCaptor.getValue());
         verify(mKeyStoreManager).clearKeyStoreEncryptionKey();
+        assertEquals(mStorage.getLong(RebootEscrowManager.REBOOT_ESCROW_KEY_ARMED_TIMESTAMP,
+                -1, USER_SYSTEM), -1);
     }
 
     @Test
@@ -468,7 +492,7 @@
         ArgumentCaptor<Boolean> metricsSuccessCaptor = ArgumentCaptor.forClass(Boolean.class);
         doNothing().when(mInjected).reportMetric(metricsSuccessCaptor.capture(),
                 eq(0) /* error code */, eq(2) /* Server based */, eq(1) /* attempt count */,
-                anyInt(), anyInt(), anyInt());
+                anyInt(), eq(0) /* vbmeta status */, anyInt());
 
         when(mServiceConnection.unwrap(any(), anyLong()))
                 .thenAnswer(invocation -> invocation.getArgument(0));
@@ -479,6 +503,84 @@
     }
 
     @Test
+    public void loadRebootEscrowDataIfAvailable_ServerBasedRemoteException_Failure()
+            throws Exception {
+        setServerBasedRebootEscrowProvider();
+
+        when(mInjected.getBootCount()).thenReturn(0);
+        RebootEscrowListener mockListener = mock(RebootEscrowListener.class);
+        mService.setRebootEscrowListener(mockListener);
+        mService.prepareRebootEscrow();
+
+        clearInvocations(mServiceConnection);
+        mService.callToRebootEscrowIfNeeded(PRIMARY_USER_ID, FAKE_SP_VERSION, FAKE_AUTH_TOKEN);
+        verify(mockListener).onPreparedForReboot(eq(true));
+        verify(mServiceConnection, never()).wrapBlob(any(), anyLong(), anyLong());
+
+        // Use x -> x for both wrap & unwrap functions.
+        when(mServiceConnection.wrapBlob(any(), anyLong(), anyLong()))
+                .thenAnswer(invocation -> invocation.getArgument(0));
+        assertTrue(mService.armRebootEscrowIfNeeded());
+        verify(mServiceConnection).wrapBlob(any(), anyLong(), anyLong());
+        assertTrue(mStorage.hasRebootEscrowServerBlob());
+
+        // pretend reboot happens here
+        when(mInjected.getBootCount()).thenReturn(1);
+        ArgumentCaptor<Boolean> metricsSuccessCaptor = ArgumentCaptor.forClass(Boolean.class);
+        ArgumentCaptor<Integer> metricsErrorCodeCaptor = ArgumentCaptor.forClass(Integer.class);
+        doNothing().when(mInjected).reportMetric(metricsSuccessCaptor.capture(),
+                metricsErrorCodeCaptor.capture(), eq(2) /* Server based */,
+                eq(1) /* attempt count */, anyInt(), eq(0) /* vbmeta status */, anyInt());
+
+        when(mServiceConnection.unwrap(any(), anyLong())).thenThrow(RemoteException.class);
+        mService.loadRebootEscrowDataIfAvailable(null);
+        verify(mServiceConnection).unwrap(any(), anyLong());
+        assertFalse(metricsSuccessCaptor.getValue());
+        assertEquals(Integer.valueOf(RebootEscrowManager.ERROR_LOAD_ESCROW_KEY),
+                metricsErrorCodeCaptor.getValue());
+    }
+
+    @Test
+    public void loadRebootEscrowDataIfAvailable_ServerBasedIoError_RetryFailure() throws Exception {
+        setServerBasedRebootEscrowProvider();
+
+        when(mInjected.getBootCount()).thenReturn(0);
+        RebootEscrowListener mockListener = mock(RebootEscrowListener.class);
+        mService.setRebootEscrowListener(mockListener);
+        mService.prepareRebootEscrow();
+
+        clearInvocations(mServiceConnection);
+        mService.callToRebootEscrowIfNeeded(PRIMARY_USER_ID, FAKE_SP_VERSION, FAKE_AUTH_TOKEN);
+        verify(mockListener).onPreparedForReboot(eq(true));
+        verify(mServiceConnection, never()).wrapBlob(any(), anyLong(), anyLong());
+
+        // Use x -> x for both wrap & unwrap functions.
+        when(mServiceConnection.wrapBlob(any(), anyLong(), anyLong()))
+                .thenAnswer(invocation -> invocation.getArgument(0));
+        assertTrue(mService.armRebootEscrowIfNeeded());
+        verify(mServiceConnection).wrapBlob(any(), anyLong(), anyLong());
+        assertTrue(mStorage.hasRebootEscrowServerBlob());
+
+        // pretend reboot happens here
+        when(mInjected.getBootCount()).thenReturn(1);
+        ArgumentCaptor<Boolean> metricsSuccessCaptor = ArgumentCaptor.forClass(Boolean.class);
+        ArgumentCaptor<Integer> metricsErrorCodeCaptor = ArgumentCaptor.forClass(Integer.class);
+        doNothing().when(mInjected).reportMetric(metricsSuccessCaptor.capture(),
+                metricsErrorCodeCaptor.capture(), eq(2) /* Server based */,
+                eq(2) /* attempt count */, anyInt(), eq(0) /* vbmeta status */, anyInt());
+        when(mServiceConnection.unwrap(any(), anyLong())).thenThrow(IOException.class);
+
+        HandlerThread thread = new HandlerThread("RebootEscrowManagerTest");
+        thread.start();
+        mService.loadRebootEscrowDataIfAvailable(new Handler(thread.getLooper()));
+        // Sleep 5s for the retry to complete
+        Thread.sleep(5 * 1000);
+        assertFalse(metricsSuccessCaptor.getValue());
+        assertEquals(Integer.valueOf(RebootEscrowManager.ERROR_RETRY_COUNT_EXHAUSTED),
+                metricsErrorCodeCaptor.getValue());
+    }
+
+    @Test
     public void loadRebootEscrowDataIfAvailable_ServerBased_RetrySuccess() throws Exception {
         setServerBasedRebootEscrowProvider();
 
@@ -607,9 +709,14 @@
         when(mInjected.getBootCount()).thenReturn(10);
         when(mRebootEscrow.retrieveKey()).thenAnswer(invocation -> keyByteCaptor.getValue());
 
+        // Trigger a vbmeta digest mismatch
+        mStorage.setString(RebootEscrowManager.REBOOT_ESCROW_KEY_VBMETA_DIGEST,
+                "non sense value", USER_SYSTEM);
         mService.loadRebootEscrowDataIfAvailable(null);
         verify(mInjected).reportMetric(eq(true), eq(0) /* error code */, eq(1) /* HAL based */,
-                eq(1) /* attempt count */, anyInt(), anyInt(), anyInt());
+                eq(1) /* attempt count */, anyInt(), eq(2) /* vbmeta status */, anyInt());
+        assertEquals(mStorage.getString(RebootEscrowManager.REBOOT_ESCROW_KEY_VBMETA_DIGEST,
+                "", USER_SYSTEM), "");
     }
 
     @Test
@@ -636,12 +743,17 @@
 
         when(mInjected.getBootCount()).thenReturn(1);
         ArgumentCaptor<Boolean> metricsSuccessCaptor = ArgumentCaptor.forClass(Boolean.class);
+        ArgumentCaptor<Integer> metricsErrorCodeCaptor = ArgumentCaptor.forClass(Integer.class);
+        // Return a null escrow key
         doNothing().when(mInjected).reportMetric(metricsSuccessCaptor.capture(),
-                anyInt() /* error code */, eq(1) /* HAL based */, eq(1) /* attempt count */,
-                anyInt(), anyInt(), anyInt());
-        when(mRebootEscrow.retrieveKey()).thenAnswer(invocation -> new byte[32]);
+                metricsErrorCodeCaptor.capture(), eq(1) /* HAL based */,
+                eq(1) /* attempt count */, anyInt(), anyInt(), anyInt());
+
+        when(mRebootEscrow.retrieveKey()).thenAnswer(invocation -> null);
         mService.loadRebootEscrowDataIfAvailable(null);
         verify(mRebootEscrow).retrieveKey();
         assertFalse(metricsSuccessCaptor.getValue());
+        assertEquals(Integer.valueOf(RebootEscrowManager.ERROR_LOAD_ESCROW_KEY),
+                metricsErrorCodeCaptor.getValue());
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
index fb01ff6..100d3ea 100644
--- a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
@@ -1773,57 +1773,75 @@
                 true);
     }
 
-    /**
-     * Test that when StatsProvider triggers limit reached, new limit will be calculated and
-     * re-armed.
-     */
-    @Test
-    public void testStatsProviderLimitReached() throws Exception {
-        final int CYCLE_DAY = 15;
-
-        final NetworkStats stats = new NetworkStats(0L, 1);
+    private void increaseMockedTotalBytes(NetworkStats stats, long rxBytes, long txBytes) {
         stats.insertEntry(TEST_IFACE, UID_A, SET_ALL, TAG_NONE,
-                2999, 1, 2000, 1, 0);
+                rxBytes, 1, txBytes, 1, 0);
         when(mStatsService.getNetworkTotalBytes(any(), anyLong(), anyLong()))
                 .thenReturn(stats.getTotalBytes());
         when(mStatsService.getNetworkUidBytes(any(), anyLong(), anyLong()))
                 .thenReturn(stats);
+    }
+
+    private void triggerOnStatsProviderWarningOrLimitReached() throws InterruptedException {
+        final NetworkPolicyManagerInternal npmi = LocalServices
+                .getService(NetworkPolicyManagerInternal.class);
+        npmi.onStatsProviderWarningOrLimitReached("TEST");
+        // Wait for processing of MSG_STATS_PROVIDER_WARNING_OR_LIMIT_REACHED.
+        postMsgAndWaitForCompletion();
+        verify(mStatsService).forceUpdate();
+        // Wait for processing of MSG_*_INTERFACE_QUOTAS.
+        postMsgAndWaitForCompletion();
+    }
+
+    /**
+     * Test that when StatsProvider triggers warning and limit reached, new quotas will be
+     * calculated and re-armed.
+     */
+    @Test
+    public void testStatsProviderWarningAndLimitReached() throws Exception {
+        final int CYCLE_DAY = 15;
+
+        final NetworkStats stats = new NetworkStats(0L, 1);
+        increaseMockedTotalBytes(stats, 2999, 2000);
 
         // Get active mobile network in place
         expectMobileDefaults();
         mService.updateNetworks();
-        verify(mStatsService).setStatsProviderLimitAsync(TEST_IFACE, Long.MAX_VALUE);
+        verify(mStatsService).setStatsProviderWarningAndLimitAsync(TEST_IFACE, Long.MAX_VALUE,
+                Long.MAX_VALUE);
 
-        // Set limit to 10KB.
+        // Set warning to 7KB and limit to 10KB.
         setNetworkPolicies(new NetworkPolicy(
-                sTemplateMobileAll, CYCLE_DAY, TIMEZONE_UTC, WARNING_DISABLED, 10000L,
-                true));
+                sTemplateMobileAll, CYCLE_DAY, TIMEZONE_UTC, 7000L, 10000L, true));
         postMsgAndWaitForCompletion();
 
-        // Verifies that remaining quota is set to providers.
-        verify(mStatsService).setStatsProviderLimitAsync(TEST_IFACE, 10000L - 4999L);
-
+        // Verifies that remaining quotas are set to providers.
+        verify(mStatsService).setStatsProviderWarningAndLimitAsync(TEST_IFACE, 2001L, 5001L);
         reset(mStatsService);
 
-        // Increase the usage.
-        stats.insertEntry(TEST_IFACE, UID_A, SET_ALL, TAG_NONE,
-                1000, 1, 999, 1, 0);
-        when(mStatsService.getNetworkTotalBytes(any(), anyLong(), anyLong()))
-                .thenReturn(stats.getTotalBytes());
-        when(mStatsService.getNetworkUidBytes(any(), anyLong(), anyLong()))
-                .thenReturn(stats);
+        // Increase the usage and simulates that limit reached fires earlier by provider,
+        // but actually the quota is not yet reached. Verifies that the limit reached leads to
+        // a force update and new quotas should be set.
+        increaseMockedTotalBytes(stats, 1000, 999);
+        triggerOnStatsProviderWarningOrLimitReached();
+        verify(mStatsService).setStatsProviderWarningAndLimitAsync(TEST_IFACE, 2L, 3002L);
+        reset(mStatsService);
 
-        // Simulates that limit reached fires earlier by provider, but actually the quota is not
-        // yet reached.
-        final NetworkPolicyManagerInternal npmi = LocalServices
-                .getService(NetworkPolicyManagerInternal.class);
-        npmi.onStatsProviderLimitReached("TEST");
+        // Increase the usage and simulate warning reached, the new warning should be unlimited
+        // since service will disable warning quota to stop lower layer from keep triggering
+        // warning reached event.
+        increaseMockedTotalBytes(stats, 1000L, 1000);
+        triggerOnStatsProviderWarningOrLimitReached();
+        verify(mStatsService).setStatsProviderWarningAndLimitAsync(
+                TEST_IFACE, Long.MAX_VALUE, 1002L);
+        reset(mStatsService);
 
-        // Verifies that the limit reached leads to a force update and new limit should be set.
-        postMsgAndWaitForCompletion();
-        verify(mStatsService).forceUpdate();
-        postMsgAndWaitForCompletion();
-        verify(mStatsService).setStatsProviderLimitAsync(TEST_IFACE, 10000L - 4999L - 1999L);
+        // Increase the usage that over the warning and limit, the new limit should set to 1 to
+        // block the network traffic.
+        increaseMockedTotalBytes(stats, 1000L, 1000);
+        triggerOnStatsProviderWarningOrLimitReached();
+        verify(mStatsService).setStatsProviderWarningAndLimitAsync(TEST_IFACE, Long.MAX_VALUE, 1L);
+        reset(mStatsService);
     }
 
     /**
diff --git a/services/tests/servicestests/src/com/android/server/people/PeopleServiceTest.java b/services/tests/servicestests/src/com/android/server/people/PeopleServiceTest.java
index ecff409..5066240 100644
--- a/services/tests/servicestests/src/com/android/server/people/PeopleServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/people/PeopleServiceTest.java
@@ -47,12 +47,14 @@
 import android.os.Bundle;
 import android.os.RemoteException;
 import android.os.test.TestLooper;
+import android.provider.DeviceConfig;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableContext;
 import android.testing.TestableLooper;
 
 import androidx.test.InstrumentationRegistry;
 
+import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
 import com.android.server.LocalServices;
 
 import org.junit.After;
@@ -126,6 +128,10 @@
                 .setPredictedTargetCount(APP_PREDICTION_TARGET_COUNT)
                 .setExtras(new Bundle())
                 .build();
+        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
+                SystemUiDeviceConfigFlags.DARK_LAUNCH_REMOTE_PREDICTION_SERVICE_ENABLED,
+                Boolean.toString(false),
+                true /* makeDefault*/);
     }
 
     @After
diff --git a/services/tests/servicestests/src/com/android/server/people/prediction/ShareTargetPredictorTest.java b/services/tests/servicestests/src/com/android/server/people/prediction/ShareTargetPredictorTest.java
index b09a3c3..fac5c1f 100644
--- a/services/tests/servicestests/src/com/android/server/people/prediction/ShareTargetPredictorTest.java
+++ b/services/tests/servicestests/src/com/android/server/people/prediction/ShareTargetPredictorTest.java
@@ -22,13 +22,17 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anySet;
+import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.app.prediction.AppPredictionContext;
+import android.app.prediction.AppPredictionManager;
 import android.app.prediction.AppTarget;
+import android.app.prediction.AppTargetEvent;
 import android.app.prediction.AppTargetId;
 import android.content.ComponentName;
 import android.content.Context;
@@ -38,9 +42,11 @@
 import android.content.pm.ShortcutManager.ShareShortcutInfo;
 import android.os.Bundle;
 import android.os.UserHandle;
+import android.provider.DeviceConfig;
 import android.util.Range;
 
 import com.android.internal.app.ChooserActivity;
+import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
 import com.android.server.people.data.ConversationInfo;
 import com.android.server.people.data.DataManager;
 import com.android.server.people.data.EventHistory;
@@ -71,6 +77,14 @@
     private static final String PACKAGE_3 = "pkg3";
     private static final String CLASS_1 = "cls1";
     private static final String CLASS_2 = "cls2";
+    private static final AppTargetEvent APP_TARGET_EVENT =
+            new AppTargetEvent.Builder(
+                    new AppTarget.Builder(
+                        new AppTargetId("cls1#pkg1"), PACKAGE_1, UserHandle.of(USER_ID)).build(),
+                        AppTargetEvent.ACTION_LAUNCH)
+                    .setLaunchLocation(ChooserActivity.LAUNCH_LOCATION_DIRECT_SHARE)
+                    .build();
+    private static final IntentFilter INTENT_FILTER = IntentFilter.create("SEND", "text/plain");
 
     @Mock private Context mContext;
     @Mock private DataManager mDataManager;
@@ -102,17 +116,33 @@
         when(mDataManager.getShareShortcuts(any(), anyInt())).thenReturn(mShareShortcuts);
         when(mDataManager.getPackage(PACKAGE_1, USER_ID)).thenReturn(mPackageData1);
         when(mDataManager.getPackage(PACKAGE_2, USER_ID)).thenReturn(mPackageData2);
+        when(mContext.createContextAsUser(any(), any())).thenReturn(mContext);
+        when(mContext.getSystemServiceName(AppPredictionManager.class)).thenReturn(
+                Context.APP_PREDICTION_SERVICE);
+        when(mContext.getSystemService(AppPredictionManager.class))
+                .thenReturn(new AppPredictionManager(mContext));
 
         Bundle bundle = new Bundle();
-        bundle.putObject(ChooserActivity.APP_PREDICTION_INTENT_FILTER_KEY,
-                IntentFilter.create("SEND", "text/plain"));
+        bundle.putObject(ChooserActivity.APP_PREDICTION_INTENT_FILTER_KEY, INTENT_FILTER);
         AppPredictionContext predictionContext = new AppPredictionContext.Builder(mContext)
                 .setUiSurface(UI_SURFACE_SHARE)
                 .setPredictedTargetCount(NUM_PREDICTED_TARGETS)
                 .setExtras(bundle)
                 .build();
+        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
+                SystemUiDeviceConfigFlags.DARK_LAUNCH_REMOTE_PREDICTION_SERVICE_ENABLED,
+                Boolean.toString(true),
+                true /* makeDefault*/);
         mPredictor = new ShareTargetPredictor(
-                predictionContext, mUpdatePredictionsMethod, mDataManager, USER_ID);
+                predictionContext, mUpdatePredictionsMethod, mDataManager, USER_ID, mContext);
+    }
+
+    @Test
+    public void testReportAppTargetEvent() {
+        mPredictor.reportAppTargetEvent(APP_TARGET_EVENT);
+
+        verify(mDataManager, times(1))
+                .reportShareTargetEvent(eq(APP_TARGET_EVENT), eq(INTENT_FILTER));
     }
 
     @Test
@@ -240,7 +270,7 @@
                 .setExtras(new Bundle())
                 .build();
         mPredictor = new ShareTargetPredictor(
-                predictionContext, mUpdatePredictionsMethod, mDataManager, USER_ID);
+                predictionContext, mUpdatePredictionsMethod, mDataManager, USER_ID, mContext);
 
         mPredictor.predictTargets();
 
@@ -349,7 +379,7 @@
                 .setExtras(new Bundle())
                 .build();
         mPredictor = new ShareTargetPredictor(
-                predictionContext, mUpdatePredictionsMethod, mDataManager, USER_ID);
+                predictionContext, mUpdatePredictionsMethod, mDataManager, USER_ID, mContext);
         AppTarget appTarget1 = new AppTarget.Builder(
                 new AppTargetId("cls1#pkg1"), PACKAGE_1, UserHandle.of(USER_ID))
                 .build();
diff --git a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
index 029e9a3..88b0651 100644
--- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
@@ -43,21 +43,26 @@
 import android.app.ActivityManager;
 import android.app.ActivityManagerInternal;
 import android.app.IUidObserver;
+import android.app.PendingIntent;
 import android.app.Person;
 import android.app.admin.DevicePolicyManager;
 import android.app.appsearch.AppSearchBatchResult;
 import android.app.appsearch.AppSearchManager;
 import android.app.appsearch.AppSearchResult;
+import android.app.appsearch.GenericDocument;
 import android.app.appsearch.IAppSearchBatchResultCallback;
 import android.app.appsearch.IAppSearchManager;
 import android.app.appsearch.IAppSearchResultCallback;
 import android.app.appsearch.PackageIdentifier;
+import android.app.appsearch.SearchResultPage;
+import android.app.appsearch.SetSchemaResponse;
 import android.app.role.OnRoleHoldersChangedListener;
 import android.app.usage.UsageStatsManagerInternal;
 import android.content.ActivityNotFoundException;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.IIntentSender;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.IntentSender;
@@ -87,6 +92,7 @@
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
+import android.os.ParcelFileDescriptor;
 import android.os.PersistableBundle;
 import android.os.Process;
 import android.os.RemoteException;
@@ -159,7 +165,7 @@
                 case Context.DEVICE_POLICY_SERVICE:
                     return mMockDevicePolicyManager;
                 case Context.APP_SEARCH_SERVICE:
-                    return new AppSearchManager(getTestContext(), mMockAppSearchManager);
+                    return new AppSearchManager(this, mMockAppSearchManager);
                 case Context.ROLE_SERVICE:
                     // RoleManager is final and cannot be mocked, so we only override the inject
                     // accessor methods in ShortcutService.
@@ -189,6 +195,19 @@
         }
 
         @Override
+        public Context createContextAsUser(UserHandle user, int flags) {
+            when(mMockPackageManager.getUserId()).thenReturn(user.getIdentifier());
+            return this;
+        }
+
+        @Override
+        public Context createPackageContextAsUser(String packageName, int flags, UserHandle user)
+                throws PackageManager.NameNotFoundException {
+            // ignore.
+            return this;
+        }
+
+        @Override
         public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
                 IntentFilter filter, String broadcastPermission, Handler scheduler) {
             // ignore.
@@ -196,12 +215,6 @@
         }
 
         @Override
-        public Context createContextAsUser(UserHandle user, int flags) {
-            when(mMockPackageManager.getUserId()).thenReturn(user.getIdentifier());
-            return this;
-        }
-
-        @Override
         public void unregisterReceiver(BroadcastReceiver receiver) {
             // ignore.
         }
@@ -238,6 +251,15 @@
         }
 
         @Override
+        public Context createContextAsUser(UserHandle user, int flags) {
+            super.createContextAsUser(user, flags);
+            final ServiceContext ctx = spy(new ServiceContext());
+            when(ctx.getUser()).thenReturn(user);
+            when(ctx.getUserId()).thenReturn(user.getIdentifier());
+            return ctx;
+        }
+
+        @Override
         public int getUserId() {
             return UserHandle.USER_SYSTEM;
         }
@@ -608,6 +630,12 @@
         boolean injectHasInteractAcrossUsersFullPermission(int callingPid, int callingUid) {
             return false;
         }
+
+        @Override
+        PendingIntent injectCreatePendingIntent(Context context, int requestCode,
+                @NonNull Intent[] intents, int flags, Bundle options, UserHandle user) {
+            return new PendingIntent(mock(IIntentSender.class));
+        }
     }
 
     protected class LauncherAppsTestable extends LauncherApps {
@@ -620,12 +648,17 @@
 
         protected Map<String, List<PackageIdentifier>> mSchemasPackageAccessible =
                 new ArrayMap<>(1);
+        private Map<String, Map<String, GenericDocument>> mDocumentMap = new ArrayMap<>(1);
+
+        private String getKey(int userId, String databaseName) {
+            return new StringBuilder().append(userId).append("@").append(databaseName).toString();
+        }
 
         @Override
         public void setSchema(String packageName, String databaseName, List<Bundle> schemaBundles,
                 List<String> schemasNotPlatformSurfaceable,
                 Map<String, List<Bundle>> schemasPackageAccessibleBundles, boolean forceOverride,
-                int userId, IAppSearchResultCallback callback) throws RemoteException {
+                int userId, int version, IAppSearchResultCallback callback) throws RemoteException {
             for (Map.Entry<String, List<Bundle>> entry :
                     schemasPackageAccessibleBundles.entrySet()) {
                 final String key = entry.getKey();
@@ -640,7 +673,8 @@
                     packageIdentifiers.add(new PackageIdentifier(entry.getValue().get(i)));
                 }
             }
-            callback.onResult(AppSearchResult.newSuccessfulResult(null));
+            final SetSchemaResponse response = new SetSchemaResponse.Builder().build();
+            callback.onResult(AppSearchResult.newSuccessfulResult(response.getBundle()));
         }
 
         @Override
@@ -650,24 +684,86 @@
         }
 
         @Override
+        public void getNamespaces(String packageName, String databaseName, int userId,
+                IAppSearchResultCallback callback) throws RemoteException {
+            ignore(callback);
+        }
+
+        @Override
         public void putDocuments(String packageName, String databaseName,
                 List<Bundle> documentBundles, int userId, IAppSearchBatchResultCallback callback)
                 throws RemoteException {
-            ignore(callback);
+            final List<GenericDocument> docs = new ArrayList<>(documentBundles.size());
+            for (Bundle bundle : documentBundles) {
+                docs.add(new GenericDocument(bundle));
+            }
+            final AppSearchBatchResult.Builder<String, Void> builder =
+                    new AppSearchBatchResult.Builder<>();
+            final String key = getKey(userId, databaseName);
+            Map<String, GenericDocument> docMap = mDocumentMap.get(key);
+            for (GenericDocument doc : docs) {
+                builder.setSuccess(doc.getUri(), null);
+                if (docMap == null) {
+                    docMap = new ArrayMap<>(1);
+                    mDocumentMap.put(key, docMap);
+                }
+                docMap.put(doc.getUri(), doc);
+            }
+            callback.onResult(builder.build());
         }
 
         @Override
         public void getDocuments(String packageName, String databaseName, String namespace,
                 List<String> uris, Map<String, List<String>> typePropertyPaths, int userId,
                 IAppSearchBatchResultCallback callback) throws RemoteException {
-            ignore(callback);
+            final AppSearchBatchResult.Builder<String, Bundle> builder =
+                    new AppSearchBatchResult.Builder<>();
+            final String key = getKey(userId, databaseName);
+            if (!mDocumentMap.containsKey(key)) {
+                for (String uri : uris) {
+                    builder.setFailure(uri, AppSearchResult.RESULT_NOT_FOUND,
+                            key + " not found when getting: " + uri);
+                }
+            } else {
+                final Map<String, GenericDocument> docs = mDocumentMap.get(key);
+                for (String uri : uris) {
+                    if (docs.containsKey(uri)) {
+                        builder.setSuccess(uri, docs.get(uri).getBundle());
+                    } else {
+                        builder.setFailure(uri, AppSearchResult.RESULT_NOT_FOUND,
+                                "shortcut not found: " + uri);
+                    }
+                }
+            }
+            callback.onResult(builder.build());
         }
 
         @Override
         public void query(String packageName, String databaseName, String queryExpression,
                 Bundle searchSpecBundle, int userId, IAppSearchResultCallback callback)
                 throws RemoteException {
-            ignore(callback);
+            final String key = getKey(userId, databaseName);
+            if (!mDocumentMap.containsKey(key)) {
+                final Bundle page = new Bundle();
+                page.putLong(SearchResultPage.NEXT_PAGE_TOKEN_FIELD, 1);
+                page.putParcelableArrayList(SearchResultPage.RESULTS_FIELD, new ArrayList<>());
+                callback.onResult(AppSearchResult.newSuccessfulResult(page));
+                return;
+            }
+            final List<GenericDocument> documents = new ArrayList<>(mDocumentMap.get(key).values());
+            final Bundle page = new Bundle();
+            page.putLong(SearchResultPage.NEXT_PAGE_TOKEN_FIELD, 0);
+            final ArrayList<Bundle> resultBundles = new ArrayList<>();
+            for (GenericDocument document : documents) {
+                final Bundle resultBundle = new Bundle();
+                resultBundle.putBundle("document", document.getBundle());
+                resultBundle.putString("packageName", packageName);
+                resultBundle.putString("databaseName", databaseName);
+                resultBundle.putParcelableArrayList("matches", new ArrayList<>());
+                resultBundles.add(resultBundle);
+            }
+            page.putParcelableArrayList(SearchResultPage.RESULTS_FIELD, resultBundles);
+            callback.onResult(AppSearchResult.newSuccessfulResult(page));
         }
 
         @Override
@@ -679,7 +775,10 @@
         @Override
         public void getNextPage(long nextPageToken, int userId, IAppSearchResultCallback callback)
                 throws RemoteException {
-            ignore(callback);
+            final Bundle page = new Bundle();
+            page.putLong(SearchResultPage.NEXT_PAGE_TOKEN_FIELD, 1);
+            page.putParcelableArrayList(SearchResultPage.RESULTS_FIELD, new ArrayList<>());
+            callback.onResult(AppSearchResult.newSuccessfulResult(page));
         }
 
         @Override
@@ -688,8 +787,24 @@
         }
 
         @Override
+        public void writeQueryResultsToFile(String packageName, String databaseName,
+                ParcelFileDescriptor fileDescriptor, String queryExpression,
+                Bundle searchSpecBundle, int userId, IAppSearchResultCallback callback)
+                throws RemoteException {
+            ignore(callback);
+        }
+
+        @Override
+        public void putDocumentsFromFile(String packageName, String databaseName,
+                ParcelFileDescriptor fileDescriptor, int userId, IAppSearchResultCallback callback)
+                throws RemoteException {
+            ignore(callback);
+        }
+
+        @Override
         public void reportUsage(String packageName, String databaseName, String namespace,
-                String uri, long usageTimeMillis, int userId, IAppSearchResultCallback callback)
+                String uri, long usageTimeMillis, boolean systemUsage, int userId,
+                IAppSearchResultCallback callback)
                 throws RemoteException {
             ignore(callback);
         }
@@ -698,13 +813,45 @@
         public void removeByUri(String packageName, String databaseName, String namespace,
                 List<String> uris, int userId, IAppSearchBatchResultCallback callback)
                 throws RemoteException {
-            ignore(callback);
+            final AppSearchBatchResult.Builder<String, Void> builder =
+                    new AppSearchBatchResult.Builder<>();
+            final String key = getKey(userId, databaseName);
+            if (!mDocumentMap.containsKey(key)) {
+                for (String uri : uris) {
+                    builder.setFailure(uri, AppSearchResult.RESULT_NOT_FOUND,
+                            "package " + key + " not found when removing " + uri);
+                }
+            } else {
+                final Map<String, GenericDocument> docs = mDocumentMap.get(key);
+                for (String uri : uris) {
+                    if (docs.containsKey(uri)) {
+                        docs.remove(uri);
+                        builder.setSuccess(uri, null);
+                    } else {
+                        builder.setFailure(uri, AppSearchResult.RESULT_NOT_FOUND,
+                                "shortcut not found when removing " + uri);
+                    }
+                }
+            }
+            callback.onResult(builder.build());
         }
 
         @Override
         public void removeByQuery(String packageName, String databaseName, String queryExpression,
                 Bundle searchSpecBundle, int userId, IAppSearchResultCallback callback)
                 throws RemoteException {
+            final String key = getKey(userId, databaseName);
+            if (!mDocumentMap.containsKey(key)) {
+                callback.onResult(AppSearchResult.newSuccessfulResult(null));
+                return;
+            }
+            mDocumentMap.get(key).clear();
+            callback.onResult(AppSearchResult.newSuccessfulResult(null));
+        }
+
+        @Override
+        public void getStorageInfo(String packageName, String databaseName, int userId,
+                IAppSearchResultCallback callback) throws RemoteException {
             ignore(callback);
         }
 
@@ -724,12 +871,12 @@
             return null;
         }
 
-        private void ignore(IAppSearchResultCallback callback) throws RemoteException {
-            callback.onResult(AppSearchResult.newSuccessfulResult(null));
+        private void removeShortcuts() {
+            mDocumentMap.clear();
         }
 
-        private void ignore(IAppSearchBatchResultCallback callback) throws RemoteException {
-            callback.onResult(new AppSearchBatchResult.Builder().build());
+        private void ignore(IAppSearchResultCallback callback) throws RemoteException {
+            callback.onResult(AppSearchResult.newSuccessfulResult(null));
         }
     }
 
@@ -1146,6 +1293,9 @@
 
         shutdownServices();
 
+        mMockAppSearchManager.removeShortcuts();
+        mMockAppSearchManager = null;
+
         super.tearDown();
     }
 
@@ -1891,6 +2041,11 @@
         return mService.getPackageShortcutForTest(packageName, shortcutId, userId);
     }
 
+    protected void updatePackageShortcut(String packageName, String shortcutId, int userId,
+            Consumer<ShortcutInfo> cb) {
+        mService.updatePackageShortcutForTest(packageName, shortcutId, userId, cb);
+    }
+
     protected void assertShortcutExists(String packageName, String shortcutId, int userId) {
         assertTrue(getPackageShortcut(packageName, shortcutId, userId) != null);
     }
@@ -2086,6 +2241,10 @@
         return getPackageShortcut(getCallingPackage(), shortcutId, getCallingUserId());
     }
 
+    protected void updateCallerShortcut(String shortcutId, Consumer<ShortcutInfo> cb) {
+        updatePackageShortcut(getCallingPackage(), shortcutId, getCallingUserId(), cb);
+    }
+
     protected List<ShortcutInfo> getLauncherShortcuts(String launcher, int userId, int queryFlags) {
         final List<ShortcutInfo>[] ret = new List[1];
         runWithCaller(launcher, userId, () -> {
@@ -2245,6 +2404,8 @@
 
         deleteAllSavedFiles();
 
+        mMockAppSearchManager.removeShortcuts();
+
         initService();
         mService.applyRestore(payload, USER_0);
 
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
index d63a467..a231169 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
@@ -287,7 +287,7 @@
 
         final SuspendDialogInfo dialogInfo1 = new SuspendDialogInfo.Builder()
                 .setIcon(0x11220001)
-                .setTitle(0x11220002)
+                .setTitle("String Title")
                 .setMessage("1st message")
                 .setNeutralButtonText(0x11220003)
                 .setNeutralButtonAction(BUTTON_ACTION_MORE_DETAILS)
@@ -296,7 +296,7 @@
                 .setIcon(0x22220001)
                 .setTitle(0x22220002)
                 .setMessage("2nd message")
-                .setNeutralButtonText(0x22220003)
+                .setNeutralButtonText("String button text")
                 .setNeutralButtonAction(BUTTON_ACTION_UNSUSPEND)
                 .build();
 
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
index 4d0beef..3f680e6 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
@@ -1385,6 +1385,7 @@
             mService.waitForBitmapSavesForTest();
             assertWith(getCallerShortcuts())
                     .forShortcutWithId("s1", si -> {
+                        Log.d("ShortcutManagerTest1", si.toString());
                         assertTrue(si.hasIconFile());
                     });
 
@@ -1702,8 +1703,8 @@
 
         // Because setDynamicShortcuts will update the timestamps when ranks are changing,
         // we explicitly set timestamps here.
-        getCallerShortcut("s1").setTimestamp(5000);
-        getCallerShortcut("s2").setTimestamp(1000);
+        updateCallerShortcut("s1", si -> si.setTimestamp(5000));
+        updateCallerShortcut("s2", si -> si.setTimestamp(1000));
 
         setCaller(CALLING_PACKAGE_2);
         final ShortcutInfo s2_2 = makeShortcut("s2");
@@ -1713,9 +1714,9 @@
                 makeComponent(ShortcutActivity.class));
         assertTrue(mManager.setDynamicShortcuts(list(s2_2, s2_3, s2_4)));
 
-        getCallerShortcut("s2").setTimestamp(1500);
-        getCallerShortcut("s3").setTimestamp(3000);
-        getCallerShortcut("s4").setTimestamp(500);
+        updateCallerShortcut("s2", si -> si.setTimestamp(1500));
+        updateCallerShortcut("s3", si -> si.setTimestamp(3000));
+        updateCallerShortcut("s4", si -> si.setTimestamp(500));
 
         setCaller(CALLING_PACKAGE_3);
         final ShortcutInfo s3_2 = makeShortcutWithLocusId("s3", makeLocusId("l2"));
@@ -1723,7 +1724,7 @@
 
         assertTrue(mManager.setDynamicShortcuts(list(s3_2)));
 
-        getCallerShortcut("s3").setTimestamp(START_TIME + 5000);
+        updateCallerShortcut("s3", si -> si.setTimestamp(START_TIME + 5000));
 
         setCaller(LAUNCHER_1);
 
@@ -7686,7 +7687,7 @@
                         assertEquals("http://www/", si.getIntent().getData().toString());
                         assertEquals("foo/bar", si.getIntent().getType());
                         assertEquals(
-                                new ComponentName("abc", ".xyz"), si.getIntent().getComponent());
+                                new ComponentName("abc", "abc.xyz"), si.getIntent().getComponent());
 
                         assertEquals(set("cat1", "cat2"), si.getIntent().getCategories());
                         assertEquals("value1", si.getIntent().getStringExtra("key1"));
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest12.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest12.java
index b17085e..fd3e7a8 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest12.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest12.java
@@ -15,8 +15,13 @@
  */
 package com.android.server.pm;
 
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.list;
+
+import android.app.PendingIntent;
 import android.app.appsearch.PackageIdentifier;
 import android.content.pm.AppSearchShortcutInfo;
+import android.os.RemoteException;
+import android.os.UserHandle;
 
 import java.util.Random;
 
@@ -41,4 +46,18 @@
                             new PackageIdentifier(CALLING_PACKAGE_2, cert)));
         });
     }
+
+    public void testGetShortcutIntents_ReturnsMutablePendingIntents() throws RemoteException {
+        setDefaultLauncher(USER_0, LAUNCHER_1);
+
+        runWithCaller(CALLING_PACKAGE_1, USER_0, () ->
+                assertTrue(mManager.setDynamicShortcuts(list(makeShortcut("s1"))))
+        );
+
+        runWithCaller(LAUNCHER_1, USER_0, () -> {
+            final PendingIntent intent = mLauncherApps.getShortcutIntent(
+                    CALLING_PACKAGE_1, "s1", null, UserHandle.SYSTEM);
+            assertNotNull(intent);
+        });
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/pm/SuspendDialogInfoTest.java b/services/tests/servicestests/src/com/android/server/pm/SuspendDialogInfoTest.java
index 322e448..826a8d4 100644
--- a/services/tests/servicestests/src/com/android/server/pm/SuspendDialogInfoTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/SuspendDialogInfoTest.java
@@ -57,7 +57,7 @@
     }
 
     @Test
-    public void equalsComparesTitle() {
+    public void equalsComparesTitleIds() {
         final SuspendDialogInfo.Builder dialogBuilder1 = createDefaultDialogBuilder();
         final SuspendDialogInfo.Builder dialogBuilder2 = createDefaultDialogBuilder();
         assertEquals(dialogBuilder1.build(), dialogBuilder2.build());
@@ -67,7 +67,39 @@
     }
 
     @Test
-    public void equalsComparesButtonText() {
+    public void equalsIgnoresTitleStringsWhenIdsSet() {
+        final SuspendDialogInfo.Builder dialogBuilder1 = new SuspendDialogInfo.Builder()
+                .setTitle(VALID_TEST_RES_ID_1)
+                .setTitle("1st title");
+        final SuspendDialogInfo.Builder dialogBuilder2 = new SuspendDialogInfo.Builder()
+                .setTitle(VALID_TEST_RES_ID_1)
+                .setTitle("2nd title");
+        // String titles different but should get be ignored when resource ids are set
+        assertEquals(dialogBuilder1.build(), dialogBuilder2.build());
+    }
+
+    @Test
+    public void equalsComparesTitleStringsWhenNoIdsSet() {
+        final SuspendDialogInfo.Builder dialogBuilder1 = new SuspendDialogInfo.Builder()
+                .setTitle("1st title");
+        final SuspendDialogInfo.Builder dialogBuilder2 = new SuspendDialogInfo.Builder()
+                .setTitle("2nd title");
+        // Both have different titles, which are not ignored as resource ids aren't set
+        assertNotEquals(dialogBuilder1.build(), dialogBuilder2.build());
+    }
+
+    @Test
+    public void titleStringClearedWhenResIdSet() {
+        final SuspendDialogInfo dialogInfo = new SuspendDialogInfo.Builder()
+                .setTitle(VALID_TEST_RES_ID_2)
+                .setTitle("Should be cleared on build")
+                .build();
+        assertNull(dialogInfo.getTitle());
+        assertEquals(VALID_TEST_RES_ID_2, dialogInfo.getTitleResId());
+    }
+
+    @Test
+    public void equalsComparesButtonTextIds() {
         final SuspendDialogInfo.Builder dialogBuilder1 = createDefaultDialogBuilder();
         final SuspendDialogInfo.Builder dialogBuilder2 = createDefaultDialogBuilder();
         assertEquals(dialogBuilder1.build(), dialogBuilder2.build());
@@ -77,6 +109,38 @@
     }
 
     @Test
+    public void equalsIgnoresButtonStringsWhenIdsSet() {
+        final SuspendDialogInfo.Builder dialogBuilder1 = new SuspendDialogInfo.Builder()
+                .setNeutralButtonText(VALID_TEST_RES_ID_1)
+                .setNeutralButtonText("1st button text");
+        final SuspendDialogInfo.Builder dialogBuilder2 = new SuspendDialogInfo.Builder()
+                .setNeutralButtonText(VALID_TEST_RES_ID_1)
+                .setNeutralButtonText("2nd button text");
+        // Button strings different but should get be ignored when resource ids are set
+        assertEquals(dialogBuilder1.build(), dialogBuilder2.build());
+    }
+
+    @Test
+    public void equalsComparesButtonStringsWhenNoIdsSet() {
+        final SuspendDialogInfo.Builder dialogBuilder1 = new SuspendDialogInfo.Builder()
+                .setNeutralButtonText("1st button text");
+        final SuspendDialogInfo.Builder dialogBuilder2 = new SuspendDialogInfo.Builder()
+                .setNeutralButtonText("2nd button text");
+        // Both have different button texts, which are not ignored as resource ids aren't set
+        assertNotEquals(dialogBuilder1.build(), dialogBuilder2.build());
+    }
+
+    @Test
+    public void buttonStringClearedWhenResIdSet() {
+        final SuspendDialogInfo dialogInfo = new SuspendDialogInfo.Builder()
+                .setNeutralButtonText(VALID_TEST_RES_ID_2)
+                .setNeutralButtonText("Should be cleared on build")
+                .build();
+        assertNull(dialogInfo.getNeutralButtonText());
+        assertEquals(VALID_TEST_RES_ID_2, dialogInfo.getNeutralButtonTextResId());
+    }
+
+    @Test
     public void equalsComparesButtonAction() {
         final SuspendDialogInfo.Builder dialogBuilder1 = createDefaultDialogBuilder();
         final SuspendDialogInfo.Builder dialogBuilder2 = createDefaultDialogBuilder();
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 395b643..fc26611 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
@@ -58,6 +58,7 @@
 import java.util.concurrent.Executors;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
 
 import javax.annotation.concurrent.GuardedBy;
 
@@ -158,6 +159,40 @@
         fail("Didn't find a guest: " + list);
     }
 
+    @Test
+    public void testCloneUser() throws Exception {
+        // Test that only one clone user can be created
+        final int primaryUserId = mUserManager.getPrimaryUser().id;
+        UserInfo userInfo = createProfileForUser("Clone user1",
+                UserManager.USER_TYPE_PROFILE_CLONE,
+                primaryUserId);
+        assertThat(userInfo).isNotNull();
+        UserInfo userInfo2 = createProfileForUser("Clone user2",
+                UserManager.USER_TYPE_PROFILE_CLONE,
+                primaryUserId);
+        assertThat(userInfo2).isNull();
+
+        final Context userContext = mContext.createPackageContextAsUser("system", 0,
+                UserHandle.of(userInfo.id));
+        assertThat(userContext.getSystemService(
+                UserManager.class).sharesMediaWithParent()).isTrue();
+
+        List<UserInfo> list = mUserManager.getUsers();
+        List<UserInfo> cloneUsers = list.stream().filter(
+                user -> (user.id == userInfo.id && user.name.equals("Clone user1")
+                        && user.isCloneProfile()))
+                .collect(Collectors.toList());
+        assertThat(cloneUsers.size()).isEqualTo(1);
+
+        // Verify clone user parent
+        assertThat(mUserManager.getProfileParent(primaryUserId)).isNull();
+        UserInfo parentProfileInfo = mUserManager.getProfileParent(userInfo.id);
+        assertThat(parentProfileInfo).isNotNull();
+        assertThat(primaryUserId).isEqualTo(parentProfileInfo.id);
+        removeUser(userInfo.id);
+        assertThat(mUserManager.getProfileParent(primaryUserId)).isNull();
+    }
+
     @MediumTest
     @Test
     public void testAdd2Users() throws Exception {
diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/ArtStatsLogUtilsTest.java b/services/tests/servicestests/src/com/android/server/pm/dex/ArtStatsLogUtilsTest.java
index 13d75a7..f014119 100644
--- a/services/tests/servicestests/src/com/android/server/pm/dex/ArtStatsLogUtilsTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/dex/ArtStatsLogUtilsTest.java
@@ -22,6 +22,7 @@
 import com.android.server.pm.dex.ArtStatsLogUtils.ArtStatsLogger;
 
 import org.junit.AfterClass;
+import org.junit.Assert;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -49,6 +50,9 @@
     private static final String COMPILER_FILTER = "space-profile";
     private static final String PROFILE_DEX_METADATA = "primary.prof";
     private static final String VDEX_DEX_METADATA = "primary.vdex";
+    private static final String INSTRUCTION_SET = "arm64";
+    private static final String BASE_APK = "base.apk";
+    private static final String SPLIT_APK = "split.apk";
     private static final byte[] DEX_CONTENT = "dexData".getBytes();
     private static final int COMPILATION_REASON = 1;
     private static final int RESULT_CODE = 222;
@@ -97,17 +101,18 @@
             ArtStatsLogUtils.writeStatsLog(
                     mockLogger,
                     SESSION_ID,
-                    apk.toString(),
                     COMPILER_FILTER,
                     UID,
                     COMPILE_TIME,
                     dexMetadataPath.toString(),
                     COMPILATION_REASON,
-                    RESULT_CODE);
+                    RESULT_CODE,
+                    ArtStatsLog.ART_DATUM_REPORTED__APK_TYPE__ART_APK_TYPE_BASE,
+                    INSTRUCTION_SET);
 
             // Assert
             verifyWrites(ArtStatsLog.
-                ART_DATUM_REPORTED__DEX_METADATA_TYPE__ART_DEX_METADATA_TYPE_PROFILE_AND_VDEX);
+                    ART_DATUM_REPORTED__DEX_METADATA_TYPE__ART_DEX_METADATA_TYPE_PROFILE_AND_VDEX);
         } finally {
             deleteSliently(dexMetadataPath);
             deleteSliently(apk);
@@ -127,17 +132,18 @@
             ArtStatsLogUtils.writeStatsLog(
                     mockLogger,
                     SESSION_ID,
-                    apk.toString(),
                     COMPILER_FILTER,
                     UID,
                     COMPILE_TIME,
                     dexMetadataPath.toString(),
                     COMPILATION_REASON,
-                    RESULT_CODE);
+                    RESULT_CODE,
+                    ArtStatsLog.ART_DATUM_REPORTED__APK_TYPE__ART_APK_TYPE_BASE,
+                    INSTRUCTION_SET);
 
             // Assert
             verifyWrites(ArtStatsLog.
-                ART_DATUM_REPORTED__DEX_METADATA_TYPE__ART_DEX_METADATA_TYPE_PROFILE);
+                    ART_DATUM_REPORTED__DEX_METADATA_TYPE__ART_DEX_METADATA_TYPE_PROFILE);
         } finally {
             deleteSliently(dexMetadataPath);
             deleteSliently(apk);
@@ -157,17 +163,18 @@
             ArtStatsLogUtils.writeStatsLog(
                     mockLogger,
                     SESSION_ID,
-                    apk.toString(),
                     COMPILER_FILTER,
                     UID,
                     COMPILE_TIME,
                     dexMetadataPath.toString(),
                     COMPILATION_REASON,
-                    RESULT_CODE);
+                    RESULT_CODE,
+                    ArtStatsLog.ART_DATUM_REPORTED__APK_TYPE__ART_APK_TYPE_BASE,
+                    INSTRUCTION_SET);
 
             // Assert
             verifyWrites(ArtStatsLog.
-                ART_DATUM_REPORTED__DEX_METADATA_TYPE__ART_DEX_METADATA_TYPE_VDEX);
+                    ART_DATUM_REPORTED__DEX_METADATA_TYPE__ART_DEX_METADATA_TYPE_VDEX);
         } finally {
             deleteSliently(dexMetadataPath);
             deleteSliently(apk);
@@ -185,17 +192,18 @@
             ArtStatsLogUtils.writeStatsLog(
                     mockLogger,
                     SESSION_ID,
-                    apk.toString(),
                     COMPILER_FILTER,
                     UID,
                     COMPILE_TIME,
                     /*dexMetadataPath=*/ null,
                     COMPILATION_REASON,
-                    RESULT_CODE);
+                    RESULT_CODE,
+                    ArtStatsLog.ART_DATUM_REPORTED__APK_TYPE__ART_APK_TYPE_BASE,
+                    INSTRUCTION_SET);
 
             // Assert
             verifyWrites(ArtStatsLog.
-                ART_DATUM_REPORTED__DEX_METADATA_TYPE__ART_DEX_METADATA_TYPE_NONE);
+                    ART_DATUM_REPORTED__DEX_METADATA_TYPE__ART_DEX_METADATA_TYPE_NONE);
         } finally {
             deleteSliently(apk);
         }
@@ -214,23 +222,35 @@
             ArtStatsLogUtils.writeStatsLog(
                     mockLogger,
                     SESSION_ID,
-                    apk.toString(),
                     COMPILER_FILTER,
                     UID,
                     COMPILE_TIME,
                     dexMetadataPath.toString(),
                     COMPILATION_REASON,
-                    RESULT_CODE);
+                    RESULT_CODE,
+                    ArtStatsLog.ART_DATUM_REPORTED__APK_TYPE__ART_APK_TYPE_BASE,
+                    INSTRUCTION_SET);
 
             // Assert
             verifyWrites(ArtStatsLog.
-                ART_DATUM_REPORTED__DEX_METADATA_TYPE__ART_DEX_METADATA_TYPE_UNKNOWN);
+                    ART_DATUM_REPORTED__DEX_METADATA_TYPE__ART_DEX_METADATA_TYPE_UNKNOWN);
         } finally {
             deleteSliently(dexMetadataPath);
             deleteSliently(apk);
         }
     }
 
+    @Test
+    public void testGetApkType() {
+        // Act
+        int result1 = ArtStatsLogUtils.getApkType(BASE_APK);
+        int result2 = ArtStatsLogUtils.getApkType(SPLIT_APK);
+
+        // Assert
+        Assert.assertEquals(result1, ArtStatsLog.ART_DATUM_REPORTED__APK_TYPE__ART_APK_TYPE_BASE);
+        Assert.assertEquals(result2, ArtStatsLog.ART_DATUM_REPORTED__APK_TYPE__ART_APK_TYPE_SPLIT);
+    }
+
     private void verifyWrites(int dexMetadataType) {
         InOrder inorder = inOrder(mockLogger);
         inorder.verify(mockLogger).write(
@@ -239,7 +259,9 @@
                 COMPILER_FILTER,
                 ArtStatsLog.ART_DATUM_REPORTED__KIND__ART_DATUM_DEX2OAT_RESULT_CODE,
                 RESULT_CODE,
-                dexMetadataType);
+                dexMetadataType,
+                ArtStatsLog.ART_DATUM_REPORTED__APK_TYPE__ART_APK_TYPE_BASE,
+                INSTRUCTION_SET);
         inorder.verify(mockLogger).write(
                 SESSION_ID,
                 UID,
@@ -247,7 +269,9 @@
                 COMPILER_FILTER,
                 ArtStatsLog.ART_DATUM_REPORTED__KIND__ART_DATUM_DEX2OAT_TOTAL_TIME,
                 COMPILE_TIME,
-                dexMetadataType);
+                dexMetadataType,
+                ArtStatsLog.ART_DATUM_REPORTED__APK_TYPE__ART_APK_TYPE_BASE,
+                INSTRUCTION_SET);
     }
 
     private Path zipFiles(String suffix, Path... files) throws IOException {
diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/DexMetadataHelperTest.java b/services/tests/servicestests/src/com/android/server/pm/dex/DexMetadataHelperTest.java
index a1b2f38..f9b8f26 100644
--- a/services/tests/servicestests/src/com/android/server/pm/dex/DexMetadataHelperTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/dex/DexMetadataHelperTest.java
@@ -55,8 +55,8 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.nio.file.Files;
 import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
 import java.util.Collection;
 import java.util.Map;
 import java.util.zip.ZipEntry;
@@ -413,7 +413,7 @@
             }
             final ApkLite baseApk = result.getResult();
             final PackageLite pkgLite = new PackageLite(null, baseApk.getPath(), baseApk, null,
-                    null, null, null, null, null);
+                    null, null, null, null, null, baseApk.getTargetSdkVersion());
             Assert.assertEquals(dm.length(), DexMetadataHelper.getPackageDexMetadataSize(pkgLite));
         }
 
diff --git a/services/tests/servicestests/src/com/android/server/pm/parsing/AndroidPackageParsingTestBase.kt b/services/tests/servicestests/src/com/android/server/pm/parsing/AndroidPackageParsingTestBase.kt
index ff0aec7..ecc40567 100644
--- a/services/tests/servicestests/src/com/android/server/pm/parsing/AndroidPackageParsingTestBase.kt
+++ b/services/tests/servicestests/src/com/android/server/pm/parsing/AndroidPackageParsingTestBase.kt
@@ -322,7 +322,8 @@
             configChanges=${this.configChanges}
             descriptionRes=${this.descriptionRes}
             directBootAware=${this.directBootAware}
-            documentLaunchMode=${this.documentLaunchMode}
+            documentLaunchMode=${this.documentLaunchMode
+            .ignored("Update for fixing b/128526493 and the testing is no longer valid")}
             enabled=${this.enabled}
             exported=${this.exported}
             flags=${Integer.toBinaryString(this.flags)}
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 6e5fbd0..874f8dc 100644
--- a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
@@ -71,6 +71,7 @@
 import android.service.dreams.DreamManagerInternal;
 import android.test.mock.MockContentResolver;
 import android.view.Display;
+import android.view.DisplayInfo;
 
 import androidx.test.InstrumentationRegistry;
 
@@ -466,21 +467,21 @@
         // First, ensure that a normal full wake lock does not cause a wakeup
         int flags = PowerManager.FULL_WAKE_LOCK;
         mService.getBinderServiceInstance().acquireWakeLock(token, flags, tag, packageName,
-                null /* workSource */, null /* historyTag */);
+                null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY);
         assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
         mService.getBinderServiceInstance().releaseWakeLock(token, 0 /* flags */);
 
         // Ensure that the flag does *NOT* work with a partial wake lock.
         flags = PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP;
         mService.getBinderServiceInstance().acquireWakeLock(token, flags, tag, packageName,
-                null /* workSource */, null /* historyTag */);
+                null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY);
         assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
         mService.getBinderServiceInstance().releaseWakeLock(token, 0 /* flags */);
 
         // Verify that flag forces a wakeup when paired to a FULL_WAKE_LOCK
         flags = PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP;
         mService.getBinderServiceInstance().acquireWakeLock(token, flags, tag, packageName,
-                null /* workSource */, null /* historyTag */);
+                null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY);
         assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
         mService.getBinderServiceInstance().releaseWakeLock(token, 0 /* flags */);
     }
@@ -594,6 +595,8 @@
     public void testWasDeviceIdleFor_true() {
         int interval = 1000;
         createService();
+        mService.systemReady(null);
+        mService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
         mService.onUserActivity();
         advanceTime(interval + 1 /* just a little more */);
         assertThat(mService.wasDeviceIdleForInternal(interval)).isTrue();
@@ -603,6 +606,8 @@
     public void testWasDeviceIdleFor_false() {
         int interval = 1000;
         createService();
+        mService.systemReady(null);
+        mService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
         mService.onUserActivity();
         assertThat(mService.wasDeviceIdleForInternal(interval)).isFalse();
     }
@@ -664,7 +669,7 @@
 
         // Create a wakelock
         mService.getBinderServiceInstance().acquireWakeLock(new Binder(), flags, tag, pkg,
-                null /* workSource */, null /* historyTag */);
+                null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY);
         assertThat(wakelockMap.get(tag)).isEqualTo(flags);  // Verify wakelock is active.
 
         // Confirm that the wakelocks have been disabled when the forceSuspend is in flight.
@@ -722,7 +727,7 @@
         // Take a nap and verify we no longer hold the blocker
         int flags = PowerManager.DOZE_WAKE_LOCK;
         mService.getBinderServiceInstance().acquireWakeLock(token, flags, tag, packageName,
-                null /* workSource */, null /* historyTag */);
+                null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY);
         when(mDreamManagerInternalMock.isDreaming()).thenReturn(true);
         mService.getBinderServiceInstance().goToSleep(mClock.now(),
                 PowerManager.GO_TO_SLEEP_REASON_APPLICATION, 0);
@@ -757,6 +762,9 @@
 
     @Test
     public void testInattentiveSleep_userActivityDismissesWarning() throws Exception {
+        final DisplayInfo info = new DisplayInfo();
+        info.displayGroupId = Display.DEFAULT_DISPLAY_GROUP;
+        when(mDisplayManagerInternalMock.getDisplayInfo(Display.DEFAULT_DISPLAY)).thenReturn(info);
         setMinimumScreenOffTimeoutConfig(5);
         setAttentiveWarningDuration(1900);
         setAttentiveTimeout(2000);
@@ -827,13 +835,94 @@
 
         mService.getBinderServiceInstance().acquireWakeLock(token,
                 PowerManager.SCREEN_BRIGHT_WAKE_LOCK, tag, pkg,
-                null /* workSource */, null /* historyTag */);
+                null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY);
 
+        assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
         advanceTime(60);
         assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
     }
 
     @Test
+    public void testWakeLock_affectsProperDisplayGroup() throws Exception {
+        final int nonDefaultDisplayGroupId = Display.DEFAULT_DISPLAY_GROUP + 1;
+        final AtomicReference<DisplayManagerInternal.DisplayGroupListener> listener =
+                new AtomicReference<>();
+        doAnswer((Answer<Void>) invocation -> {
+            listener.set(invocation.getArgument(0));
+            return null;
+        }).when(mDisplayManagerInternalMock).registerDisplayGroupListener(any());
+        final DisplayInfo info = new DisplayInfo();
+        info.displayGroupId = Display.DEFAULT_DISPLAY_GROUP;
+        when(mDisplayManagerInternalMock.getDisplayInfo(Display.DEFAULT_DISPLAY)).thenReturn(info);
+
+        final String pkg = mContextSpy.getOpPackageName();
+        final Binder token = new Binder();
+        final String tag = "testWakeLock_affectsProperDisplayGroup";
+
+        setMinimumScreenOffTimeoutConfig(5);
+        createService();
+        startSystem();
+        listener.get().onDisplayGroupAdded(nonDefaultDisplayGroupId);
+
+        mService.getBinderServiceInstance().acquireWakeLock(token,
+                PowerManager.SCREEN_BRIGHT_WAKE_LOCK, tag, pkg,
+                null /* workSource */, null /* historyTag */, Display.DEFAULT_DISPLAY);
+
+        assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+        assertThat(mService.getWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP)).isEqualTo(
+                WAKEFULNESS_AWAKE);
+        assertThat(mService.getWakefulnessLocked(nonDefaultDisplayGroupId)).isEqualTo(
+                WAKEFULNESS_AWAKE);
+
+        advanceTime(15000);
+        assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+        assertThat(mService.getWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP)).isEqualTo(
+                WAKEFULNESS_AWAKE);
+        assertThat(mService.getWakefulnessLocked(nonDefaultDisplayGroupId)).isEqualTo(
+                WAKEFULNESS_DOZING);
+    }
+
+    @Test
+    public void testInvalidDisplayGroupWakeLock_affectsAllDisplayGroups() throws Exception {
+        final int nonDefaultDisplayGroupId = Display.DEFAULT_DISPLAY_GROUP + 1;
+        final AtomicReference<DisplayManagerInternal.DisplayGroupListener> listener =
+                new AtomicReference<>();
+        doAnswer((Answer<Void>) invocation -> {
+            listener.set(invocation.getArgument(0));
+            return null;
+        }).when(mDisplayManagerInternalMock).registerDisplayGroupListener(any());
+        final DisplayInfo info = new DisplayInfo();
+        info.displayGroupId = Display.DEFAULT_DISPLAY_GROUP;
+        when(mDisplayManagerInternalMock.getDisplayInfo(Display.DEFAULT_DISPLAY)).thenReturn(info);
+
+        final String pkg = mContextSpy.getOpPackageName();
+        final Binder token = new Binder();
+        final String tag = "testInvalidDisplayGroupWakeLock_affectsAllDisplayGroups";
+
+        setMinimumScreenOffTimeoutConfig(5);
+        createService();
+        startSystem();
+        listener.get().onDisplayGroupAdded(nonDefaultDisplayGroupId);
+
+        mService.getBinderServiceInstance().acquireWakeLock(token,
+                PowerManager.SCREEN_BRIGHT_WAKE_LOCK, tag, pkg,
+                null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY);
+
+        assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+        assertThat(mService.getWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP)).isEqualTo(
+                WAKEFULNESS_AWAKE);
+        assertThat(mService.getWakefulnessLocked(nonDefaultDisplayGroupId)).isEqualTo(
+                WAKEFULNESS_AWAKE);
+
+        advanceTime(15000);
+        assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+        assertThat(mService.getWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP)).isEqualTo(
+                WAKEFULNESS_AWAKE);
+        assertThat(mService.getWakefulnessLocked(nonDefaultDisplayGroupId)).isEqualTo(
+                WAKEFULNESS_AWAKE);
+    }
+
+    @Test
     public void testBoot_ShouldBeAwake() throws Exception {
         createService();
         startSystem();
diff --git a/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTest.java b/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTest.java
index 324e592..7903a90 100644
--- a/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTest.java
@@ -22,6 +22,7 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doNothing;
@@ -72,6 +73,7 @@
     private LockSettingsInternal mLockSettingsInternal;
     private IBootControl mIBootControl;
     private RecoverySystemServiceTestable.IMetricsReporter mMetricsReporter;
+    private RecoverySystemService.PreferencesManager mSharedPreferences;
 
     private static final String FAKE_OTA_PACKAGE_NAME = "fake.ota.package";
     private static final String FAKE_OTHER_PACKAGE_NAME = "fake.other.package";
@@ -97,10 +99,11 @@
         when(mIBootControl.getActiveBootSlot()).thenReturn(1);
 
         mMetricsReporter = mock(RecoverySystemServiceTestable.IMetricsReporter.class);
+        mSharedPreferences = mock(RecoverySystemService.PreferencesManager.class);
 
         mRecoverySystemService = new RecoverySystemServiceTestable(mContext, mSystemProperties,
                 powerManager, mUncryptUpdateFileWriter, mUncryptSocket, mLockSettingsInternal,
-                mIBootControl, mMetricsReporter);
+                mIBootControl, mMetricsReporter, mSharedPreferences);
     }
 
     @Test
@@ -237,6 +240,8 @@
                 is(true));
         verify(mMetricsReporter).reportRebootEscrowPreparationMetrics(
                 eq(1000), eq(0) /* need preparation */, eq(1) /* client count */);
+        verify(mSharedPreferences).putLong(eq(FAKE_OTA_PACKAGE_NAME
+                + RecoverySystemService.REQUEST_LSKF_TIMESTAMP_PREF_SUFFIX), eq(100_000L));
     }
 
 
@@ -245,10 +250,19 @@
         IntentSender intentSender = mock(IntentSender.class);
         assertThat(mRecoverySystemService.requestLskf(FAKE_OTA_PACKAGE_NAME, intentSender),
                 is(true));
+
+        when(mSharedPreferences.getLong(eq(FAKE_OTA_PACKAGE_NAME
+                + RecoverySystemService.REQUEST_LSKF_TIMESTAMP_PREF_SUFFIX), anyLong()))
+                .thenReturn(200_000L).thenReturn(5000L);
+        mRecoverySystemService.onPreparedForReboot(true);
+        verify(mMetricsReporter).reportRebootEscrowLskfCapturedMetrics(
+                eq(1000), eq(1) /* client count */,
+                eq(-1) /* invalid duration */);
+
         mRecoverySystemService.onPreparedForReboot(true);
         verify(intentSender).sendIntent(any(), anyInt(), any(), any(), any());
         verify(mMetricsReporter).reportRebootEscrowLskfCapturedMetrics(
-                eq(1000), eq(1) /* client count */, anyInt() /* duration */);
+                eq(1000), eq(1) /* client count */, eq(95) /* duration */);
     }
 
     @Test
@@ -352,12 +366,19 @@
     public void rebootWithLskf_Success() throws Exception {
         assertThat(mRecoverySystemService.requestLskf(FAKE_OTA_PACKAGE_NAME, null), is(true));
         mRecoverySystemService.onPreparedForReboot(true);
+
+        when(mSharedPreferences.getInt(eq(FAKE_OTA_PACKAGE_NAME
+                + RecoverySystemService.REQUEST_LSKF_COUNT_PREF_SUFFIX), anyInt())).thenReturn(2);
+        when(mSharedPreferences.getInt(eq(RecoverySystemService.LSKF_CAPTURED_COUNT_PREF),
+                anyInt())).thenReturn(3);
+        when(mSharedPreferences.getLong(eq(RecoverySystemService.LSKF_CAPTURED_TIMESTAMP_PREF),
+                anyLong())).thenReturn(40_000L);
         assertThat(mRecoverySystemService.rebootWithLskf(FAKE_OTA_PACKAGE_NAME, "ab-update", true),
                 is(true));
         verify(mIPowerManager).reboot(anyBoolean(), eq("ab-update"), anyBoolean());
         verify(mMetricsReporter).reportRebootEscrowRebootMetrics(eq(0), eq(1000),
-                eq(1) /* client count */, eq(1) /* request count */, eq(true) /* slot switch */,
-                anyBoolean(), anyInt(), eq(1) /* lskf capture count */);
+                eq(1) /* client count */, eq(2) /* request count */, eq(true) /* slot switch */,
+                anyBoolean(), eq(60) /* duration */, eq(3) /* lskf capture count */);
     }
 
 
@@ -400,13 +421,19 @@
         assertThat(mRecoverySystemService.requestLskf(FAKE_OTHER_PACKAGE_NAME, null), is(true));
         mRecoverySystemService.onPreparedForReboot(true);
 
-        // Client B's clear won't affect client A's preparation.
+        when(mSharedPreferences.getInt(eq(FAKE_OTA_PACKAGE_NAME
+                + RecoverySystemService.REQUEST_LSKF_COUNT_PREF_SUFFIX), anyInt())).thenReturn(2);
+        when(mSharedPreferences.getInt(eq(RecoverySystemService.LSKF_CAPTURED_COUNT_PREF),
+                anyInt())).thenReturn(1);
+        when(mSharedPreferences.getLong(eq(RecoverySystemService.LSKF_CAPTURED_TIMESTAMP_PREF),
+                anyLong())).thenReturn(60_000L);
+
         assertThat(mRecoverySystemService.rebootWithLskf(FAKE_OTA_PACKAGE_NAME, "ab-update", true),
                 is(true));
         verify(mIPowerManager).reboot(anyBoolean(), eq("ab-update"), anyBoolean());
         verify(mMetricsReporter).reportRebootEscrowRebootMetrics(eq(0), eq(1000),
-                eq(2) /* client count */, eq(1) /* request count */, eq(true) /* slot switch */,
-                anyBoolean(), anyInt(), eq(1) /* lskf capture count */);
+                eq(2) /* client count */, eq(2) /* request count */, eq(true) /* slot switch */,
+                anyBoolean(), eq(40), eq(1) /* lskf capture count */);
     }
 
     @Test
@@ -415,22 +442,30 @@
         mRecoverySystemService.onPreparedForReboot(true);
         assertThat(mRecoverySystemService.requestLskf(FAKE_OTHER_PACKAGE_NAME, null), is(true));
 
+        when(mSharedPreferences.getInt(eq(FAKE_OTHER_PACKAGE_NAME
+                + RecoverySystemService.REQUEST_LSKF_COUNT_PREF_SUFFIX), anyInt())).thenReturn(2);
+        when(mSharedPreferences.getInt(eq(RecoverySystemService.LSKF_CAPTURED_COUNT_PREF),
+                anyInt())).thenReturn(1);
+        when(mSharedPreferences.getLong(eq(RecoverySystemService.LSKF_CAPTURED_TIMESTAMP_PREF),
+                anyLong())).thenReturn(60_000L);
+
         assertThat(mRecoverySystemService.clearLskf(FAKE_OTA_PACKAGE_NAME), is(true));
         assertThat(mRecoverySystemService.rebootWithLskf(FAKE_OTA_PACKAGE_NAME, null, true),
                 is(false));
         verifyNoMoreInteractions(mIPowerManager);
         verify(mMetricsReporter).reportRebootEscrowRebootMetrics(not(eq(0)), eq(1000),
-                eq(1) /* client count */, eq(1) /* request count */, eq(true) /* slot switch */,
-                anyBoolean(), anyInt(), eq(1) /* lskf capture count */);
+                eq(1) /* client count */, anyInt() /* request count */, eq(true) /* slot switch */,
+                anyBoolean(), eq(40), eq(1)/* lskf capture count */);
 
         assertThat(mRecoverySystemService.requestLskf(FAKE_OTHER_PACKAGE_NAME, null), is(true));
         assertThat(
                 mRecoverySystemService.rebootWithLskf(FAKE_OTHER_PACKAGE_NAME, "ab-update", true),
                 is(true));
         verify(mIPowerManager).reboot(anyBoolean(), eq("ab-update"), anyBoolean());
-        verify(mMetricsReporter).reportRebootEscrowRebootMetrics(eq(0), eq(2000),
-                eq(1) /* client count */, eq(1) /* request count */, eq(true) /* slot switch */,
-                anyBoolean(), anyInt(), eq(1) /* lskf capture count */);
+
+        verify(mMetricsReporter).reportRebootEscrowRebootMetrics((eq(0)), eq(2000),
+                eq(1) /* client count */, eq(2) /* request count */, eq(true) /* slot switch */,
+                anyBoolean(), eq(40), eq(1) /* lskf capture count */);
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTestable.java b/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTestable.java
index a894178..27e953f 100644
--- a/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTestable.java
+++ b/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTestable.java
@@ -33,11 +33,13 @@
         private final LockSettingsInternal mLockSettingsInternal;
         private final IBootControl mIBootControl;
         private final IMetricsReporter mIMetricsReporter;
+        private final RecoverySystemService.PreferencesManager mSharedPreferences;
 
         MockInjector(Context context, FakeSystemProperties systemProperties,
                 PowerManager powerManager, FileWriter uncryptPackageFileWriter,
                 UncryptSocket uncryptSocket, LockSettingsInternal lockSettingsInternal,
-                IBootControl bootControl, IMetricsReporter metricsReporter) {
+                IBootControl bootControl, IMetricsReporter metricsReporter,
+                RecoverySystemService.PreferencesManager preferences) {
             super(context);
             mSystemProperties = systemProperties;
             mPowerManager = powerManager;
@@ -46,6 +48,7 @@
             mLockSettingsInternal = lockSettingsInternal;
             mIBootControl = bootControl;
             mIMetricsReporter = metricsReporter;
+            mSharedPreferences = preferences;
         }
 
         @Override
@@ -114,12 +117,14 @@
                     requestedClientCount);
         }
 
+        @Override
         public void reportRebootEscrowLskfCapturedMetrics(int uid, int requestedClientCount,
                 int requestedToLskfCapturedDurationInSeconds) {
             mIMetricsReporter.reportRebootEscrowLskfCapturedMetrics(uid, requestedClientCount,
                     requestedToLskfCapturedDurationInSeconds);
         }
 
+        @Override
         public void reportRebootEscrowRebootMetrics(int errorCode, int uid, int preparedClientCount,
                 int requestCount, boolean slotSwitch, boolean serverBased,
                 int lskfCapturedToRebootDurationInSeconds, int lskfCapturedCounts) {
@@ -127,14 +132,25 @@
                     requestCount, slotSwitch, serverBased, lskfCapturedToRebootDurationInSeconds,
                     lskfCapturedCounts);
         }
+
+        @Override
+        public long getCurrentTimeMillis() {
+            return 100_000;
+        }
+
+        @Override
+        public RecoverySystemService.PreferencesManager getMetricsPrefs() {
+            return mSharedPreferences;
+        }
     }
 
     RecoverySystemServiceTestable(Context context, FakeSystemProperties systemProperties,
             PowerManager powerManager, FileWriter uncryptPackageFileWriter,
             UncryptSocket uncryptSocket, LockSettingsInternal lockSettingsInternal,
-            IBootControl bootControl, IMetricsReporter metricsReporter) {
+            IBootControl bootControl, IMetricsReporter metricsReporter,
+            RecoverySystemService.PreferencesManager preferences) {
         super(new MockInjector(context, systemProperties, powerManager, uncryptPackageFileWriter,
-                uncryptSocket, lockSettingsInternal, bootControl, metricsReporter));
+                uncryptSocket, lockSettingsInternal, bootControl, metricsReporter, preferences));
     }
 
     public static class FakeSystemProperties {
@@ -176,5 +192,4 @@
                 int requestCount, boolean slotSwitch, boolean serverBased,
                 int lskfCapturedToRebootDurationInSeconds, int lskfCapturedCounts);
     }
-
 }
diff --git a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java
index 1068270..742f503 100644
--- a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java
@@ -217,20 +217,20 @@
             fail();
         } finally {
             verify(mMockContext).enforceCallingPermission(
-                    eq(android.Manifest.permission.SET_TIME), anyString());
+                    eq(android.Manifest.permission.SUGGEST_EXTERNAL_TIME), anyString());
         }
     }
 
     @Test
     public void testSuggestExternalTime() throws Exception {
-        doNothing().when(mMockContext).enforceCallingOrSelfPermission(anyString(), any());
+        doNothing().when(mMockContext).enforceCallingPermission(anyString(), any());
 
         ExternalTimeSuggestion externalTimeSuggestion = createExternalTimeSuggestion();
         mTimeDetectorService.suggestExternalTime(externalTimeSuggestion);
         mTestHandler.assertTotalMessagesEnqueued(1);
 
         verify(mMockContext).enforceCallingPermission(
-                eq(android.Manifest.permission.SET_TIME), anyString());
+                eq(android.Manifest.permission.SUGGEST_EXTERNAL_TIME), anyString());
 
         mTestHandler.waitForMessagesToBeProcessed();
         mStubbedTimeDetectorStrategy.verifySuggestExternalTimeCalled(externalTimeSuggestion);
diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/location/ControllerImplTest.java b/services/tests/servicestests/src/com/android/server/timezonedetector/location/ControllerImplTest.java
index 5a100a2..a0e9d97 100644
--- a/services/tests/servicestests/src/com/android/server/timezonedetector/location/ControllerImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/location/ControllerImplTest.java
@@ -72,7 +72,6 @@
     private TestCallback mTestCallback;
     private TestLocationTimeZoneProvider mTestPrimaryLocationTimeZoneProvider;
     private TestLocationTimeZoneProvider mTestSecondaryLocationTimeZoneProvider;
-    private FakeTimeZoneIdValidator mTimeZoneAvailabilityChecker;
 
     @Before
     public void setUp() {
@@ -84,13 +83,10 @@
         };
         mTestThreadingDomain = new TestThreadingDomain();
         mTestCallback = new TestCallback(mTestThreadingDomain);
-        mTimeZoneAvailabilityChecker = new FakeTimeZoneIdValidator();
         mTestPrimaryLocationTimeZoneProvider = new TestLocationTimeZoneProvider(
-                stubbedProviderMetricsLogger, mTestThreadingDomain, "primary",
-                mTimeZoneAvailabilityChecker);
+                stubbedProviderMetricsLogger, mTestThreadingDomain, "primary");
         mTestSecondaryLocationTimeZoneProvider = new TestLocationTimeZoneProvider(
-                stubbedProviderMetricsLogger, mTestThreadingDomain, "secondary",
-                mTimeZoneAvailabilityChecker);
+                stubbedProviderMetricsLogger, mTestThreadingDomain, "secondary");
     }
 
     @Test
@@ -1185,10 +1181,9 @@
          * Creates the instance.
          */
         TestLocationTimeZoneProvider(ProviderMetricsLogger providerMetricsLogger,
-                ThreadingDomain threadingDomain, String providerName,
-                TimeZoneIdValidator timeZoneIdValidator) {
+                ThreadingDomain threadingDomain, String providerName) {
             super(providerMetricsLogger, threadingDomain, providerName,
-                    timeZoneIdValidator);
+                    new FakeTimeZoneProviderEventPreProcessor());
         }
 
         public void setFailDuringInitialization(boolean failInitialization) {
@@ -1321,14 +1316,4 @@
             mTestProviderState.commitLatest();
         }
     }
-
-    private static final class FakeTimeZoneIdValidator
-            implements LocationTimeZoneProvider.TimeZoneIdValidator {
-
-        @Override
-        public boolean isValid(@NonNull String timeZoneId) {
-            return true;
-        }
-
-    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/location/FakeTimeZoneProviderEventPreProcessor.java b/services/tests/servicestests/src/com/android/server/timezonedetector/location/FakeTimeZoneProviderEventPreProcessor.java
new file mode 100644
index 0000000..e75d05c
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/location/FakeTimeZoneProviderEventPreProcessor.java
@@ -0,0 +1,39 @@
+/*
+ * 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.timezonedetector.location;
+
+/**
+ * Fake implementation of {@link TimeZoneProviderEventPreProcessor} which assumes that all events
+ * are valid or always uncertain if {@link #enterUncertainMode()} was called.
+ */
+public final class FakeTimeZoneProviderEventPreProcessor
+        implements TimeZoneProviderEventPreProcessor {
+
+    private boolean mIsUncertain = false;
+
+    @Override
+    public TimeZoneProviderEvent preProcess(TimeZoneProviderEvent timeZoneProviderEvent) {
+        if (mIsUncertain) {
+            return TimeZoneProviderEvent.createUncertainEvent();
+        }
+        return timeZoneProviderEvent;
+    }
+
+    public void enterUncertainMode() {
+        mIsUncertain = true;
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/location/LocationTimeZoneProviderTest.java b/services/tests/servicestests/src/com/android/server/timezonedetector/location/LocationTimeZoneProviderTest.java
index d13a04e..0edb559 100644
--- a/services/tests/servicestests/src/com/android/server/timezonedetector/location/LocationTimeZoneProviderTest.java
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/location/LocationTimeZoneProviderTest.java
@@ -52,10 +52,8 @@
 
 import java.time.Duration;
 import java.util.Arrays;
-import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.Set;
 import java.util.concurrent.atomic.AtomicReference;
 
 /**
@@ -68,13 +66,13 @@
 
     private TestThreadingDomain mTestThreadingDomain;
     private TestProviderListener mProviderListener;
-    private FakeTimeZoneIdValidator mTimeZoneAvailabilityChecker;
+    private FakeTimeZoneProviderEventPreProcessor mTimeZoneProviderEventPreProcessor;
 
     @Before
     public void setUp() {
         mTestThreadingDomain = new TestThreadingDomain();
         mProviderListener = new TestProviderListener();
-        mTimeZoneAvailabilityChecker = new FakeTimeZoneIdValidator();
+        mTimeZoneProviderEventPreProcessor = new FakeTimeZoneProviderEventPreProcessor();
     }
 
     @Test
@@ -82,9 +80,10 @@
         String providerName = "arbitrary";
         RecordingProviderMetricsLogger providerMetricsLogger = new RecordingProviderMetricsLogger();
         TestLocationTimeZoneProvider provider = new TestLocationTimeZoneProvider(
-                providerMetricsLogger, mTestThreadingDomain, providerName,
-                mTimeZoneAvailabilityChecker);
-        mTimeZoneAvailabilityChecker.validIds("Europe/London");
+                providerMetricsLogger,
+                mTestThreadingDomain,
+                providerName,
+                mTimeZoneProviderEventPreProcessor);
 
         // initialize()
         provider.initialize(mProviderListener);
@@ -174,8 +173,10 @@
         String providerName = "primary";
         StubbedProviderMetricsLogger providerMetricsLogger = new StubbedProviderMetricsLogger();
         TestLocationTimeZoneProvider provider = new TestLocationTimeZoneProvider(
-                providerMetricsLogger, mTestThreadingDomain, providerName,
-                mTimeZoneAvailabilityChecker);
+                providerMetricsLogger,
+                mTestThreadingDomain,
+                providerName,
+                mTimeZoneProviderEventPreProcessor);
 
         TestCommand testCommand = TestCommand.createForTests("test", new Bundle());
         AtomicReference<Bundle> resultReference = new AtomicReference<>();
@@ -193,10 +194,11 @@
         String providerName = "primary";
         StubbedProviderMetricsLogger providerMetricsLogger = new StubbedProviderMetricsLogger();
         TestLocationTimeZoneProvider provider = new TestLocationTimeZoneProvider(
-                providerMetricsLogger, mTestThreadingDomain, providerName,
-                mTimeZoneAvailabilityChecker);
+                providerMetricsLogger,
+                mTestThreadingDomain,
+                providerName,
+                mTimeZoneProviderEventPreProcessor);
         provider.setStateChangeRecordingEnabled(true);
-        mTimeZoneAvailabilityChecker.validIds("Europe/London");
 
         // initialize()
         provider.initialize(mProviderListener);
@@ -234,14 +236,17 @@
     }
 
     @Test
-    public void considerSuggestionWithInvalidTimeZoneIdsAsUncertain() {
+    public void entersUncertainState_whenEventHasUnsupportedZones() {
         String providerName = "primary";
         StubbedProviderMetricsLogger providerMetricsLogger = new StubbedProviderMetricsLogger();
         TestLocationTimeZoneProvider provider = new TestLocationTimeZoneProvider(
-                providerMetricsLogger, mTestThreadingDomain, providerName,
-                mTimeZoneAvailabilityChecker);
+                providerMetricsLogger,
+                mTestThreadingDomain,
+                providerName,
+                mTimeZoneProviderEventPreProcessor);
         provider.setStateChangeRecordingEnabled(true);
         provider.initialize(mProviderListener);
+        mTimeZoneProviderEventPreProcessor.enterUncertainMode();
 
         ConfigurationInternal config = USER1_CONFIG_GEO_DETECTION_ENABLED;
         Duration arbitraryInitializationTimeout = Duration.ofMinutes(5);
@@ -309,8 +314,9 @@
         TestLocationTimeZoneProvider(@NonNull ProviderMetricsLogger providerMetricsLogger,
                 @NonNull ThreadingDomain threadingDomain,
                 @NonNull String providerName,
-                @NonNull TimeZoneIdValidator timeZoneIdValidator) {
-            super(providerMetricsLogger, threadingDomain, providerName, timeZoneIdValidator);
+                @NonNull TimeZoneProviderEventPreProcessor timeZoneProviderEventPreProcessor) {
+            super(providerMetricsLogger,
+                    threadingDomain, providerName, timeZoneProviderEventPreProcessor);
         }
 
         @Override
@@ -367,20 +373,6 @@
         }
     }
 
-    private static final class FakeTimeZoneIdValidator
-            implements LocationTimeZoneProvider.TimeZoneIdValidator {
-        private final Set<String> mValidTimeZoneIds = new HashSet<>();
-
-        @Override
-        public boolean isValid(@NonNull String timeZoneId) {
-            return mValidTimeZoneIds.contains(timeZoneId);
-        }
-
-        public void validIds(String... timeZoneIdss) {
-            mValidTimeZoneIds.addAll(asList(timeZoneIdss));
-        }
-    }
-
     private static class StubbedProviderMetricsLogger implements
             LocationTimeZoneProvider.ProviderMetricsLogger {
 
diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneIdValidatorTest.java b/services/tests/servicestests/src/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneIdValidatorTest.java
deleted file mode 100644
index 5561b2c..0000000
--- a/services/tests/servicestests/src/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneIdValidatorTest.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.timezonedetector.location;
-
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import android.platform.test.annotations.Presubmit;
-
-import org.junit.Test;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.TimeZone;
-
-@Presubmit
-public class ZoneInfoDbTimeZoneIdValidatorTest {
-    private final LocationTimeZoneProvider.TimeZoneIdValidator mTzChecker =
-            new ZoneInfoDbTimeZoneIdValidator();
-
-    @Test
-    public void timeZoneIdsFromZoneInfoDbAreValid() {
-        for (String timeZone : TimeZone.getAvailableIDs()) {
-            assertWithMessage("Time zone %s should be supported", timeZone)
-                    .that(mTzChecker.isValid(timeZone)).isTrue();
-        }
-    }
-
-    @Test
-    public void nonExistingZones_areNotSupported() {
-        List<String> nonExistingTimeZones = Arrays.asList(
-                "SystemV/HST10", "Atlantic/Atlantis", "EUROPE/LONDON", "Etc/GMT-5:30"
-        );
-
-        for (String timeZone : nonExistingTimeZones) {
-            assertWithMessage(timeZone + " is not a valid time zone")
-                    .that(mTzChecker.isValid(timeZone))
-                    .isFalse();
-        }
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneProviderEventPreProcessorTest.java b/services/tests/servicestests/src/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneProviderEventPreProcessorTest.java
new file mode 100644
index 0000000..173705be
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneProviderEventPreProcessorTest.java
@@ -0,0 +1,70 @@
+/*
+ * 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.timezonedetector.location;
+
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import android.platform.test.annotations.Presubmit;
+import android.service.timezone.TimeZoneProviderSuggestion;
+
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.TimeZone;
+
+/** Tests for {@link ZoneInfoDbTimeZoneProviderEventPreProcessor}. */
+@Presubmit
+public class ZoneInfoDbTimeZoneProviderEventPreProcessorTest {
+
+    private static final long ARBITRARY_TIME_MILLIS = 11223344;
+
+    private final ZoneInfoDbTimeZoneProviderEventPreProcessor mPreProcessor =
+            new ZoneInfoDbTimeZoneProviderEventPreProcessor();
+
+    @Test
+    public void timeZoneIdsFromZoneInfoDbAreValid() {
+        for (String timeZone : TimeZone.getAvailableIDs()) {
+            TimeZoneProviderEvent event = timeZoneProviderEvent(timeZone);
+            assertWithMessage("Time zone %s should be supported", timeZone)
+                    .that(mPreProcessor.preProcess(event)).isEqualTo(event);
+        }
+    }
+
+    @Test
+    public void eventWithNonExistingZones_areMappedToUncertainEvent() {
+        List<String> nonExistingTimeZones = Arrays.asList(
+                "SystemV/HST10", "Atlantic/Atlantis", "EUROPE/LONDON", "Etc/GMT-5:30");
+
+        for (String timeZone : nonExistingTimeZones) {
+            TimeZoneProviderEvent event = timeZoneProviderEvent(timeZone);
+
+            assertWithMessage(timeZone + " is not a valid time zone")
+                    .that(mPreProcessor.preProcess(event))
+                    .isEqualTo(TimeZoneProviderEvent.createUncertainEvent());
+        }
+    }
+
+    private static TimeZoneProviderEvent timeZoneProviderEvent(String... timeZoneIds) {
+        return TimeZoneProviderEvent.createSuggestionEvent(
+                new TimeZoneProviderSuggestion.Builder()
+                        .setTimeZoneIds(Arrays.asList(timeZoneIds))
+                        .setElapsedRealtimeMillis(ARBITRARY_TIME_MILLIS)
+                .build());
+    }
+
+}
diff --git a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
index 86b1620..8991e9f 100644
--- a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
@@ -940,7 +940,22 @@
                 .setLong("elapsed_threshold_restricted", -1);
         mInjector.mPropertiesChangedListener
                 .onPropertiesChanged(mInjector.getDeviceConfigProperties());
-        testTimeout();
+
+        reportEvent(mController, USER_INTERACTION, 0, PACKAGE_1);
+        mController.checkIdleStates(USER_ID);
+        assertBucket(STANDBY_BUCKET_ACTIVE);
+
+        mInjector.mElapsedRealtime = HOUR_MS;
+        mController.checkIdleStates(USER_ID);
+        assertBucket(STANDBY_BUCKET_FREQUENT);
+
+        mInjector.mElapsedRealtime = 2 * HOUR_MS;
+        mController.checkIdleStates(USER_ID);
+        assertBucket(STANDBY_BUCKET_RARE);
+
+        mInjector.mElapsedRealtime = 4 * HOUR_MS;
+        mController.checkIdleStates(USER_ID);
+        assertBucket(STANDBY_BUCKET_RESTRICTED);
     }
 
     /**
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/DeviceVibrationEffectAdapterTest.java b/services/tests/servicestests/src/com/android/server/vibrator/DeviceVibrationEffectAdapterTest.java
new file mode 100644
index 0000000..c29593f
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/vibrator/DeviceVibrationEffectAdapterTest.java
@@ -0,0 +1,188 @@
+/*
+ * 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.vibrator;
+
+import static org.junit.Assert.assertEquals;
+
+import android.hardware.vibrator.IVibrator;
+import android.os.VibrationEffect;
+import android.os.VibratorInfo;
+import android.os.vibrator.PrebakedSegment;
+import android.os.vibrator.PrimitiveSegment;
+import android.os.vibrator.RampSegment;
+import android.os.vibrator.StepSegment;
+import android.platform.test.annotations.Presubmit;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.stream.IntStream;
+
+/**
+ * Tests for {@link DeviceVibrationEffectAdapter}.
+ *
+ * Build/Install/Run:
+ * atest FrameworksServicesTests:DeviceVibrationEffectAdapterTest
+ */
+@Presubmit
+public class DeviceVibrationEffectAdapterTest {
+    private static final float TEST_MIN_FREQUENCY = 50;
+    private static final float TEST_RESONANT_FREQUENCY = 150;
+    private static final float TEST_FREQUENCY_RESOLUTION = 25;
+    private static final float[] TEST_AMPLITUDE_MAP = new float[]{
+            /* 50Hz= */ 0.1f, 0.2f, 0.4f, 0.8f, /* 150Hz= */ 1f, 0.9f, /* 200Hz= */ 0.8f};
+
+    private static final VibratorInfo.FrequencyMapping EMPTY_FREQUENCY_MAPPING =
+            new VibratorInfo.FrequencyMapping(Float.NaN, Float.NaN, Float.NaN, Float.NaN, null);
+    private static final VibratorInfo.FrequencyMapping TEST_FREQUENCY_MAPPING =
+            new VibratorInfo.FrequencyMapping(TEST_MIN_FREQUENCY,
+                    TEST_RESONANT_FREQUENCY, TEST_FREQUENCY_RESOLUTION,
+                    /* suggestedSafeRangeHz= */ 50, TEST_AMPLITUDE_MAP);
+
+    private DeviceVibrationEffectAdapter mAdapter;
+
+    @Before
+    public void setUp() throws Exception {
+        mAdapter = new DeviceVibrationEffectAdapter();
+    }
+
+    @Test
+    public void testPrebakedAndPrimitiveSegments_returnsOriginalSegment() {
+        VibrationEffect.Composed effect = new VibrationEffect.Composed(Arrays.asList(
+                new PrebakedSegment(
+                        VibrationEffect.EFFECT_CLICK, false, VibrationEffect.EFFECT_STRENGTH_LIGHT),
+                new PrimitiveSegment(VibrationEffect.Composition.PRIMITIVE_TICK, 1, 10),
+                new PrebakedSegment(
+                        VibrationEffect.EFFECT_THUD, true, VibrationEffect.EFFECT_STRENGTH_STRONG),
+                new PrimitiveSegment(VibrationEffect.Composition.PRIMITIVE_SPIN, 0.5f, 100)),
+                /* repeatIndex= */ -1);
+
+        assertEquals(effect, mAdapter.apply(effect, createVibratorInfo(EMPTY_FREQUENCY_MAPPING)));
+        assertEquals(effect, mAdapter.apply(effect, createVibratorInfo(TEST_FREQUENCY_MAPPING)));
+    }
+
+    @Test
+    public void testStepAndRampSegments_withPwleCapability_convertsStepsToRamps() {
+        VibrationEffect.Composed effect = new VibrationEffect.Composed(Arrays.asList(
+                new StepSegment(/* amplitude= */ 0, /* frequency= */ 1, /* duration= */ 10),
+                new StepSegment(/* amplitude= */ 0.5f, /* frequency= */ 0, /* duration= */ 100),
+                new RampSegment(/* startAmplitude= */ 1, /* endAmplitude= */ 1,
+                        /* startFrequency= */ -4, /* endFrequency= */ 2, /* duration= */ 50),
+                new RampSegment(/* startAmplitude= */ 0.8f, /* endAmplitude= */ 0.2f,
+                        /* startFrequency= */ 10, /* endFrequency= */ -5, /* duration= */ 20)),
+                /* repeatIndex= */ 2);
+
+        VibrationEffect.Composed expected = new VibrationEffect.Composed(Arrays.asList(
+                new RampSegment(/* startAmplitude= */ 0, /* endAmplitude*/ 0,
+                        /* startFrequency= */ 175, /* endFrequency= */ 175, /* duration= */ 10),
+                new RampSegment(/* startAmplitude= */ 0.5f, /* endAmplitude= */ 0.5f,
+                        /* startFrequency= */ 150, /* endFrequency= */ 150, /* duration= */ 100),
+                new RampSegment(/* startAmplitude= */ 0.1f, /* endAmplitude= */ 0.8f,
+                        /* startFrequency= */ 50, /* endFrequency= */ 200, /* duration= */ 50),
+                new RampSegment(/* startAmplitude= */ 0.8f, /* endAmplitude= */ 0.1f,
+                        /* startFrequency= */ 200, /* endFrequency= */ 50, /* duration= */ 20)),
+                /* repeatIndex= */ 2);
+
+        VibratorInfo info = createVibratorInfo(TEST_FREQUENCY_MAPPING,
+                IVibrator.CAP_COMPOSE_PWLE_EFFECTS);
+        assertEquals(expected, mAdapter.apply(effect, info));
+    }
+
+    @Test
+    public void testStepAndRampSegments_withPwleCapabilityAndNoFrequency_keepsOriginalSteps() {
+        VibrationEffect.Composed effect = new VibrationEffect.Composed(Arrays.asList(
+                new StepSegment(/* amplitude= */ 0, /* frequency= */ 0, /* duration= */ 10),
+                new StepSegment(/* amplitude= */ 0.5f, /* frequency= */ 0, /* duration= */ 100),
+                new PrimitiveSegment(VibrationEffect.Composition.PRIMITIVE_TICK, 1, 10),
+                new RampSegment(/* startAmplitude= */ 1, /* endAmplitude= */ 1,
+                        /* startFrequency= */ -4, /* endFrequency= */ 2, /* duration= */ 50),
+                new RampSegment(/* startAmplitude= */ 0.8f, /* endAmplitude= */ 0.2f,
+                        /* startFrequency= */ 10, /* endFrequency= */ -5, /* duration= */ 20)),
+                /* repeatIndex= */ 2);
+
+        VibrationEffect.Composed expected = new VibrationEffect.Composed(Arrays.asList(
+                new StepSegment(/* amplitude= */ 0, /* frequency= */ 150, /* duration= */ 10),
+                new StepSegment(/* amplitude= */ 0.5f, /* frequency= */ 150, /* duration= */ 100),
+                new PrimitiveSegment(VibrationEffect.Composition.PRIMITIVE_TICK, 1, 10),
+                new RampSegment(/* startAmplitude= */ 0.1f, /* endAmplitude= */ 0.8f,
+                        /* startFrequency= */ 50, /* endFrequency= */ 200, /* duration= */ 50),
+                new RampSegment(/* startAmplitude= */ 0.8f, /* endAmplitude= */ 0.1f,
+                        /* startFrequency= */ 200, /* endFrequency= */ 50, /* duration= */ 20)),
+                /* repeatIndex= */ 2);
+
+        VibratorInfo info = createVibratorInfo(TEST_FREQUENCY_MAPPING,
+                IVibrator.CAP_COMPOSE_PWLE_EFFECTS);
+        assertEquals(expected, mAdapter.apply(effect, info));
+    }
+
+    @Test
+    public void testStepAndRampSegments_emptyMapping_returnsSameAmplitudesAndFrequencyZero() {
+        VibrationEffect.Composed effect = new VibrationEffect.Composed(Arrays.asList(
+                new StepSegment(/* amplitude= */ 0, /* frequency= */ 1, /* duration= */ 10),
+                new StepSegment(/* amplitude= */ 0.5f, /* frequency= */ 0, /* duration= */ 100),
+                new RampSegment(/* startAmplitude= */ 0.8f, /* endAmplitude= */ 1,
+                        /* startFrequency= */ -1, /* endFrequency= */ 1, /* duration= */ 50),
+                new RampSegment(/* startAmplitude= */ 0.7f, /* endAmplitude= */ 0.5f,
+                        /* startFrequency= */ 10, /* endFrequency= */ -5, /* duration= */ 20)),
+                /* repeatIndex= */ 2);
+
+        VibrationEffect.Composed expected = new VibrationEffect.Composed(Arrays.asList(
+                new StepSegment(/* amplitude= */ 0, /* frequency= */ Float.NaN, /* duration= */ 10),
+                new StepSegment(/* amplitude= */ 0.5f, /* frequency= */ Float.NaN,
+                        /* duration= */ 100),
+                new RampSegment(/* startAmplitude= */ 0.8f, /* endAmplitude= */ 1,
+                        /* startFrequency= */ Float.NaN, /* endFrequency= */ Float.NaN,
+                        /* duration= */ 50),
+                new RampSegment(/* startAmplitude= */ 0.7f, /* endAmplitude= */ 0.5f,
+                        /* startFrequency= */ Float.NaN, /* endFrequency= */ Float.NaN,
+                        /* duration= */ 20)),
+                /* repeatIndex= */ 2);
+
+        assertEquals(expected, mAdapter.apply(effect, createVibratorInfo(EMPTY_FREQUENCY_MAPPING)));
+    }
+
+    @Test
+    public void testStepAndRampSegments_nonEmptyMapping_returnsClippedValues() {
+        VibrationEffect.Composed effect = new VibrationEffect.Composed(Arrays.asList(
+                new StepSegment(/* amplitude= */ 0.5f, /* frequency= */ 0, /* duration= */ 10),
+                new StepSegment(/* amplitude= */ 1, /* frequency= */ -1, /* duration= */ 100),
+                new RampSegment(/* startAmplitude= */ 1, /* endAmplitude= */ 1,
+                        /* startFrequency= */ -4, /* endFrequency= */ 2, /* duration= */ 50),
+                new RampSegment(/* startAmplitude= */ 0.8f, /* endAmplitude= */ 0.2f,
+                        /* startFrequency= */ 10, /* endFrequency= */ -5, /* duration= */ 20)),
+                /* repeatIndex= */ 2);
+
+        VibrationEffect.Composed expected = new VibrationEffect.Composed(Arrays.asList(
+                new StepSegment(/* amplitude= */ 0.5f, /* frequency= */ 150, /* duration= */ 10),
+                new StepSegment(/* amplitude= */ 0.8f, /* frequency= */ 125, /* duration= */ 100),
+                new RampSegment(/* startAmplitude= */ 0.1f, /* endAmplitude= */ 0.8f,
+                        /* startFrequency= */ 50, /* endFrequency= */ 200, /* duration= */ 50),
+                new RampSegment(/* startAmplitude= */ 0.8f, /* endAmplitude= */ 0.1f,
+                        /* startFrequency= */ 200, /* endFrequency= */ 50, /* duration= */ 20)),
+                /* repeatIndex= */ 2);
+
+        assertEquals(expected, mAdapter.apply(effect, createVibratorInfo(TEST_FREQUENCY_MAPPING)));
+    }
+
+    private static VibratorInfo createVibratorInfo(VibratorInfo.FrequencyMapping frequencyMapping,
+            int... capabilities) {
+        int cap = IntStream.of(capabilities).reduce((a, b) -> a | b).orElse(0);
+        return new VibratorInfo(/* id= */ 0, cap, null, null, null, /* qFactor= */ Float.NaN,
+                frequencyMapping);
+    }
+}
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 b54b696..1d715c8 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/FakeVibratorControllerProvider.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/FakeVibratorControllerProvider.java
@@ -20,6 +20,12 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.VibrationEffect;
+import android.os.VibratorInfo;
+import android.os.vibrator.PrebakedSegment;
+import android.os.vibrator.PrimitiveSegment;
+import android.os.vibrator.RampSegment;
+import android.os.vibrator.StepSegment;
+import android.os.vibrator.VibrationEffectSegment;
 
 import com.android.server.vibrator.VibratorController.OnVibrationCompleteListener;
 
@@ -34,12 +40,12 @@
  * interactions.
  */
 final class FakeVibratorControllerProvider {
-
     private static final int EFFECT_DURATION = 20;
 
-    private final Map<Long, VibrationEffect.Prebaked> mEnabledAlwaysOnEffects = new HashMap<>();
-    private final List<VibrationEffect> mEffects = new ArrayList<>();
-    private final List<Integer> mAmplitudes = new ArrayList<>();
+    private final Map<Long, PrebakedSegment> mEnabledAlwaysOnEffects = new HashMap<>();
+    private final List<VibrationEffectSegment> mEffectSegments = new ArrayList<>();
+    private final List<Integer> mBraking = new ArrayList<>();
+    private final List<Float> mAmplitudes = new ArrayList<>();
     private final Handler mHandler;
     private final FakeNativeWrapper mNativeWrapper;
 
@@ -48,98 +54,111 @@
 
     private int mCapabilities;
     private int[] mSupportedEffects;
+    private int[] mSupportedBraking;
     private int[] mSupportedPrimitives;
-    private float mResonantFrequency;
-    private float mQFactor;
+    private float mMinFrequency = Float.NaN;
+    private float mResonantFrequency = Float.NaN;
+    private float mFrequencyResolution = Float.NaN;
+    private float mQFactor = Float.NaN;
+    private float[] mMaxAmplitudes;
 
     private final class FakeNativeWrapper extends VibratorController.NativeWrapper {
         public int vibratorId;
         public OnVibrationCompleteListener listener;
         public boolean isInitialized;
 
+        @Override
         public void init(int vibratorId, OnVibrationCompleteListener listener) {
             isInitialized = true;
             this.vibratorId = vibratorId;
             this.listener = listener;
         }
 
+        @Override
         public boolean isAvailable() {
             return mIsAvailable;
         }
 
-        public void on(long milliseconds, long vibrationId) {
-            VibrationEffect effect = VibrationEffect.createOneShot(
-                    milliseconds, VibrationEffect.DEFAULT_AMPLITUDE);
-            mEffects.add(effect);
+        @Override
+        public long on(long milliseconds, long vibrationId) {
+            mEffectSegments.add(new StepSegment(VibrationEffect.DEFAULT_AMPLITUDE,
+                    /* frequency= */ 0, (int) milliseconds));
             applyLatency();
             scheduleListener(milliseconds, vibrationId);
+            return milliseconds;
         }
 
+        @Override
         public void off() {
         }
 
-        public void setAmplitude(int amplitude) {
+        @Override
+        public void setAmplitude(float amplitude) {
             mAmplitudes.add(amplitude);
             applyLatency();
         }
 
-        public int[] getSupportedEffects() {
-            return mSupportedEffects;
-        }
-
-        public int[] getSupportedPrimitives() {
-            return mSupportedPrimitives;
-        }
-
-        public float getResonantFrequency() {
-            return mResonantFrequency;
-        }
-
-        public float getQFactor() {
-            return mQFactor;
-        }
-
+        @Override
         public long perform(long effect, long strength, long vibrationId) {
             if (mSupportedEffects == null
                     || Arrays.binarySearch(mSupportedEffects, (int) effect) < 0) {
                 return 0;
             }
-            mEffects.add(new VibrationEffect.Prebaked((int) effect, false, (int) strength));
+            mEffectSegments.add(new PrebakedSegment((int) effect, false, (int) strength));
             applyLatency();
             scheduleListener(EFFECT_DURATION, vibrationId);
             return EFFECT_DURATION;
         }
 
-        public long compose(VibrationEffect.Composition.PrimitiveEffect[] effect,
-                long vibrationId) {
-            VibrationEffect.Composed composed = new VibrationEffect.Composed(Arrays.asList(effect));
-            mEffects.add(composed);
-            applyLatency();
+        @Override
+        public long compose(PrimitiveSegment[] effects, long vibrationId) {
             long duration = 0;
-            for (VibrationEffect.Composition.PrimitiveEffect e : effect) {
-                duration += EFFECT_DURATION + e.delay;
+            for (PrimitiveSegment primitive : effects) {
+                duration += EFFECT_DURATION + primitive.getDelay();
+                mEffectSegments.add(primitive);
             }
+            applyLatency();
             scheduleListener(duration, vibrationId);
             return duration;
         }
 
+        @Override
+        public long composePwle(RampSegment[] primitives, int braking, long vibrationId) {
+            long duration = 0;
+            for (RampSegment primitive : primitives) {
+                duration += primitive.getDuration();
+                mEffectSegments.add(primitive);
+            }
+            mBraking.add(braking);
+            applyLatency();
+            scheduleListener(duration, vibrationId);
+            return duration;
+        }
+
+        @Override
         public void setExternalControl(boolean enabled) {
         }
 
-        public long getCapabilities() {
-            return mCapabilities;
-        }
-
+        @Override
         public void alwaysOnEnable(long id, long effect, long strength) {
-            VibrationEffect.Prebaked prebaked = new VibrationEffect.Prebaked((int) effect, false,
-                    (int) strength);
+            PrebakedSegment prebaked = new PrebakedSegment((int) effect, false, (int) strength);
             mEnabledAlwaysOnEffects.put(id, prebaked);
         }
 
+        @Override
         public void alwaysOnDisable(long id) {
             mEnabledAlwaysOnEffects.remove(id);
         }
 
+        @Override
+        public VibratorInfo getInfo(float suggestedFrequencyRange) {
+            VibratorInfo.FrequencyMapping frequencyMapping = new VibratorInfo.FrequencyMapping(
+                    mMinFrequency, mResonantFrequency, mFrequencyResolution,
+                    suggestedFrequencyRange, mMaxAmplitudes);
+            return new VibratorInfo(vibratorId, mCapabilities, mSupportedEffects, mSupportedBraking,
+                    mSupportedPrimitives, mQFactor, frequencyMapping);
+        }
+
         private void applyLatency() {
             try {
                 if (mLatency > 0) {
@@ -199,6 +218,15 @@
         mSupportedEffects = effects;
     }
 
+    /** Set the effects supported by the fake vibrator hardware. */
+    public void setSupportedBraking(int... braking) {
+        if (braking != null) {
+            braking = Arrays.copyOf(braking, braking.length);
+            Arrays.sort(braking);
+        }
+        mSupportedBraking = braking;
+    }
+
     /** Set the primitives supported by the fake vibrator hardware. */
     public void setSupportedPrimitives(int... primitives) {
         if (primitives != null) {
@@ -209,8 +237,18 @@
     }
 
     /** Set the resonant frequency of the fake vibrator hardware. */
-    public void setResonantFrequency(float resonantFrequency) {
-        mResonantFrequency = resonantFrequency;
+    public void setResonantFrequency(float frequencyHz) {
+        mResonantFrequency = frequencyHz;
+    }
+
+    /** Set the minimum frequency of the fake vibrator hardware. */
+    public void setMinFrequency(float frequencyHz) {
+        mMinFrequency = frequencyHz;
+    }
+
+    /** Set the frequency resolution of the fake vibrator hardware. */
+    public void setFrequencyResolution(float frequencyHz) {
+        mFrequencyResolution = frequencyHz;
     }
 
     /** Set the Q factor of the fake vibrator hardware. */
@@ -218,25 +256,35 @@
         mQFactor = qFactor;
     }
 
+    /** Set the max amplitude supported for each frequency f the fake vibrator hardware. */
+    public void setMaxAmplitudes(float... maxAmplitudes) {
+        mMaxAmplitudes = maxAmplitudes;
+    }
+
     /**
      * Return the amplitudes set by this controller, including zeroes for each time the vibrator was
      * turned off.
      */
-    public List<Integer> getAmplitudes() {
+    public List<Float> getAmplitudes() {
         return new ArrayList<>(mAmplitudes);
     }
 
-    /** Return list of {@link VibrationEffect} played by this controller, in order. */
-    public List<VibrationEffect> getEffects() {
-        return new ArrayList<>(mEffects);
+    /** Return the braking values passed to the compose PWLE method. */
+    public List<Integer> getBraking() {
+        return mBraking;
+    }
+
+    /** Return list of {@link VibrationEffectSegment} played by this controller, in order. */
+    public List<VibrationEffectSegment> getEffectSegments() {
+        return new ArrayList<>(mEffectSegments);
     }
 
     /**
-     * Return the {@link VibrationEffect.Prebaked} effect enabled with given id, or {@code null} if
+     * Return the {@link PrebakedSegment} effect enabled with given id, or {@code null} if
      * missing or disabled.
      */
     @Nullable
-    public VibrationEffect.Prebaked getAlwaysOnEffect(int id) {
+    public PrebakedSegment getAlwaysOnEffect(int id) {
         return mEnabledAlwaysOnEffects.get((long) id);
     }
 }
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 b6c11fe..59c0b0e 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/VibrationScalerTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/VibrationScalerTest.java
@@ -26,7 +26,6 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.ContextWrapper;
-import android.os.CombinedVibrationEffect;
 import android.os.Handler;
 import android.os.IExternalVibratorService;
 import android.os.PowerManagerInternal;
@@ -35,6 +34,10 @@
 import android.os.VibrationEffect;
 import android.os.Vibrator;
 import android.os.test.TestLooper;
+import android.os.vibrator.PrebakedSegment;
+import android.os.vibrator.PrimitiveSegment;
+import android.os.vibrator.StepSegment;
+import android.os.vibrator.VibrationEffectSegment;
 import android.platform.test.annotations.Presubmit;
 import android.provider.Settings;
 
@@ -130,51 +133,13 @@
     }
 
     @Test
-    public void scale_withCombined_resolvesAndScalesRecursively() {
+    public void scale_withPrebakedSegment_setsEffectStrengthBasedOnSettings() {
         setUserSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
                 Vibrator.VIBRATION_INTENSITY_HIGH);
-        VibrationEffect prebaked = VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK);
-        VibrationEffect oneShot = VibrationEffect.createOneShot(10, 10);
+        PrebakedSegment effect = new PrebakedSegment(VibrationEffect.EFFECT_CLICK,
+                /* shouldFallback= */ false, VibrationEffect.EFFECT_STRENGTH_MEDIUM);
 
-        CombinedVibrationEffect.Mono monoScaled = mVibrationScaler.scale(
-                CombinedVibrationEffect.createSynced(prebaked),
-                VibrationAttributes.USAGE_NOTIFICATION);
-        VibrationEffect.Prebaked prebakedScaled = (VibrationEffect.Prebaked) monoScaled.getEffect();
-        assertEquals(prebakedScaled.getEffectStrength(), VibrationEffect.EFFECT_STRENGTH_STRONG);
-
-        CombinedVibrationEffect.Stereo stereoScaled = mVibrationScaler.scale(
-                CombinedVibrationEffect.startSynced()
-                        .addVibrator(1, prebaked)
-                        .addVibrator(2, oneShot)
-                        .combine(),
-                VibrationAttributes.USAGE_NOTIFICATION);
-        prebakedScaled = (VibrationEffect.Prebaked) stereoScaled.getEffects().get(1);
-        assertEquals(prebakedScaled.getEffectStrength(), VibrationEffect.EFFECT_STRENGTH_STRONG);
-        VibrationEffect.OneShot oneshotScaled =
-                (VibrationEffect.OneShot) stereoScaled.getEffects().get(2);
-        assertTrue(oneshotScaled.getAmplitude() > 0);
-
-        CombinedVibrationEffect.Sequential sequentialScaled = mVibrationScaler.scale(
-                CombinedVibrationEffect.startSequential()
-                        .addNext(CombinedVibrationEffect.createSynced(prebaked))
-                        .addNext(CombinedVibrationEffect.createSynced(oneShot))
-                        .combine(),
-                VibrationAttributes.USAGE_NOTIFICATION);
-        monoScaled = (CombinedVibrationEffect.Mono) sequentialScaled.getEffects().get(0);
-        prebakedScaled = (VibrationEffect.Prebaked) monoScaled.getEffect();
-        assertEquals(prebakedScaled.getEffectStrength(), VibrationEffect.EFFECT_STRENGTH_STRONG);
-        monoScaled = (CombinedVibrationEffect.Mono) sequentialScaled.getEffects().get(1);
-        oneshotScaled = (VibrationEffect.OneShot) monoScaled.getEffect();
-        assertTrue(oneshotScaled.getAmplitude() > 0);
-    }
-
-    @Test
-    public void scale_withPrebaked_setsEffectStrengthBasedOnSettings() {
-        setUserSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
-                Vibrator.VIBRATION_INTENSITY_HIGH);
-        VibrationEffect effect = VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK);
-
-        VibrationEffect.Prebaked scaled = mVibrationScaler.scale(
+        PrebakedSegment scaled = mVibrationScaler.scale(
                 effect, VibrationAttributes.USAGE_NOTIFICATION);
         assertEquals(scaled.getEffectStrength(), VibrationEffect.EFFECT_STRENGTH_STRONG);
 
@@ -196,25 +161,33 @@
     }
 
     @Test
-    public void scale_withPrebakedAndFallback_resolvesAndScalesRecursively() {
+    public void scale_withPrebakedEffect_setsEffectStrengthBasedOnSettings() {
         setUserSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
                 Vibrator.VIBRATION_INTENSITY_HIGH);
-        VibrationEffect.OneShot fallback2 = (VibrationEffect.OneShot) VibrationEffect.createOneShot(
-                10, VibrationEffect.DEFAULT_AMPLITUDE);
-        VibrationEffect.Prebaked fallback1 = new VibrationEffect.Prebaked(
-                VibrationEffect.EFFECT_TICK, VibrationEffect.EFFECT_STRENGTH_MEDIUM, fallback2);
-        VibrationEffect.Prebaked effect = new VibrationEffect.Prebaked(VibrationEffect.EFFECT_CLICK,
-                VibrationEffect.EFFECT_STRENGTH_MEDIUM, fallback1);
+        VibrationEffect effect = VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK);
 
-        VibrationEffect.Prebaked scaled = mVibrationScaler.scale(
-                effect, VibrationAttributes.USAGE_NOTIFICATION);
-        VibrationEffect.Prebaked scaledFallback1 =
-                (VibrationEffect.Prebaked) scaled.getFallbackEffect();
-        VibrationEffect.OneShot scaledFallback2 =
-                (VibrationEffect.OneShot) scaledFallback1.getFallbackEffect();
+        PrebakedSegment scaled = getFirstSegment(mVibrationScaler.scale(
+                effect, VibrationAttributes.USAGE_NOTIFICATION));
         assertEquals(scaled.getEffectStrength(), VibrationEffect.EFFECT_STRENGTH_STRONG);
-        assertEquals(scaledFallback1.getEffectStrength(), VibrationEffect.EFFECT_STRENGTH_STRONG);
-        assertTrue(scaledFallback2.getAmplitude() > 0);
+
+        setUserSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
+                Vibrator.VIBRATION_INTENSITY_MEDIUM);
+        scaled = getFirstSegment(mVibrationScaler.scale(
+                effect, VibrationAttributes.USAGE_NOTIFICATION));
+        assertEquals(scaled.getEffectStrength(), VibrationEffect.EFFECT_STRENGTH_MEDIUM);
+
+        setUserSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
+                Vibrator.VIBRATION_INTENSITY_LOW);
+        scaled = getFirstSegment(mVibrationScaler.scale(
+                effect, VibrationAttributes.USAGE_NOTIFICATION));
+        assertEquals(scaled.getEffectStrength(), VibrationEffect.EFFECT_STRENGTH_LIGHT);
+
+        setUserSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
+                Vibrator.VIBRATION_INTENSITY_OFF);
+        scaled = getFirstSegment(mVibrationScaler.scale(
+                effect, VibrationAttributes.USAGE_NOTIFICATION));
+        // Unexpected intensity setting will be mapped to STRONG.
+        assertEquals(scaled.getEffectStrength(), VibrationEffect.EFFECT_STRENGTH_STRONG);
     }
 
     @Test
@@ -224,20 +197,20 @@
         setUserSetting(Settings.System.RING_VIBRATION_INTENSITY,
                 Vibrator.VIBRATION_INTENSITY_LOW);
 
-        VibrationEffect.OneShot oneShot = mVibrationScaler.scale(
+        StepSegment resolved = getFirstSegment(mVibrationScaler.scale(
                 VibrationEffect.createOneShot(10, VibrationEffect.DEFAULT_AMPLITUDE),
-                VibrationAttributes.USAGE_RINGTONE);
-        assertTrue(oneShot.getAmplitude() > 0);
+                VibrationAttributes.USAGE_RINGTONE));
+        assertTrue(resolved.getAmplitude() > 0);
 
-        VibrationEffect.Waveform waveform = mVibrationScaler.scale(
+        resolved = getFirstSegment(mVibrationScaler.scale(
                 VibrationEffect.createWaveform(new long[]{10},
                         new int[]{VibrationEffect.DEFAULT_AMPLITUDE}, -1),
-                VibrationAttributes.USAGE_RINGTONE);
-        assertTrue(waveform.getAmplitudes()[0] > 0);
+                VibrationAttributes.USAGE_RINGTONE));
+        assertTrue(resolved.getAmplitude() > 0);
     }
 
     @Test
-    public void scale_withOneShotWaveform_scalesAmplitude() {
+    public void scale_withOneShotAndWaveform_scalesAmplitude() {
         mFakeVibrator.setDefaultRingVibrationIntensity(Vibrator.VIBRATION_INTENSITY_LOW);
         setUserSetting(Settings.System.RING_VIBRATION_INTENSITY,
                 Vibrator.VIBRATION_INTENSITY_HIGH);
@@ -248,21 +221,21 @@
         setUserSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY,
                 Vibrator.VIBRATION_INTENSITY_MEDIUM);
 
-        VibrationEffect.OneShot oneShot = mVibrationScaler.scale(
-                VibrationEffect.createOneShot(100, 100), VibrationAttributes.USAGE_RINGTONE);
+        StepSegment scaled = getFirstSegment(mVibrationScaler.scale(
+                VibrationEffect.createOneShot(128, 128), VibrationAttributes.USAGE_RINGTONE));
         // Ringtone scales up.
-        assertTrue(oneShot.getAmplitude() > 100);
+        assertTrue(scaled.getAmplitude() > 0.5);
 
-        VibrationEffect.Waveform waveform = mVibrationScaler.scale(
-                VibrationEffect.createWaveform(new long[]{100}, new int[]{100}, -1),
-                VibrationAttributes.USAGE_NOTIFICATION);
+        scaled = getFirstSegment(mVibrationScaler.scale(
+                VibrationEffect.createWaveform(new long[]{128}, new int[]{128}, -1),
+                VibrationAttributes.USAGE_NOTIFICATION));
         // Notification scales down.
-        assertTrue(waveform.getAmplitudes()[0] < 100);
+        assertTrue(scaled.getAmplitude() < 0.5);
 
-        oneShot = mVibrationScaler.scale(VibrationEffect.createOneShot(100, 100),
-                VibrationAttributes.USAGE_TOUCH);
+        scaled = getFirstSegment(mVibrationScaler.scale(VibrationEffect.createOneShot(128, 128),
+                VibrationAttributes.USAGE_TOUCH));
         // Haptic feedback does not scale.
-        assertEquals(100, oneShot.getAmplitude());
+        assertEquals(128f / 255, scaled.getAmplitude(), 1e-5);
     }
 
     @Test
@@ -280,18 +253,23 @@
         VibrationEffect composed = VibrationEffect.startComposition()
                 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 0.5f).compose();
 
-        VibrationEffect.Composed scaled = mVibrationScaler.scale(composed,
-                VibrationAttributes.USAGE_RINGTONE);
+        PrimitiveSegment scaled = getFirstSegment(mVibrationScaler.scale(composed,
+                VibrationAttributes.USAGE_RINGTONE));
         // Ringtone scales up.
-        assertTrue(scaled.getPrimitiveEffects().get(0).scale > 0.5f);
+        assertTrue(scaled.getScale() > 0.5f);
 
-        scaled = mVibrationScaler.scale(composed, VibrationAttributes.USAGE_NOTIFICATION);
+        scaled = getFirstSegment(mVibrationScaler.scale(composed,
+                VibrationAttributes.USAGE_NOTIFICATION));
         // Notification scales down.
-        assertTrue(scaled.getPrimitiveEffects().get(0).scale < 0.5f);
+        assertTrue(scaled.getScale() < 0.5f);
 
-        scaled = mVibrationScaler.scale(composed, VibrationAttributes.USAGE_TOUCH);
+        scaled = getFirstSegment(mVibrationScaler.scale(composed, VibrationAttributes.USAGE_TOUCH));
         // Haptic feedback does not scale.
-        assertEquals(0.5, scaled.getPrimitiveEffects().get(0).scale, 1e-5);
+        assertEquals(0.5, scaled.getScale(), 1e-5);
+    }
+
+    private <T extends VibrationEffectSegment> T getFirstSegment(VibrationEffect.Composed effect) {
+        return (T) effect.getSegments().get(0);
     }
 
     private void setUserSetting(String settingName, int value) {
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 7d5eec0..c439b9c 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java
@@ -27,9 +27,11 @@
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.inOrder;
 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.hardware.vibrator.Braking;
 import android.hardware.vibrator.IVibrator;
 import android.hardware.vibrator.IVibratorManager;
 import android.os.CombinedVibrationEffect;
@@ -40,6 +42,11 @@
 import android.os.VibrationAttributes;
 import android.os.VibrationEffect;
 import android.os.test.TestLooper;
+import android.os.vibrator.PrebakedSegment;
+import android.os.vibrator.PrimitiveSegment;
+import android.os.vibrator.RampSegment;
+import android.os.vibrator.StepSegment;
+import android.os.vibrator.VibrationEffectSegment;
 import android.platform.test.annotations.LargeTest;
 import android.platform.test.annotations.Presubmit;
 import android.util.SparseArray;
@@ -61,6 +68,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.function.Predicate;
+import java.util.stream.Collectors;
 
 /**
  * Tests for {@link VibrationThread}.
@@ -142,8 +150,8 @@
         assertFalse(thread.getVibrators().get(VIBRATOR_ID).isVibrating());
 
         assertEquals(Arrays.asList(expectedOneShot(10)),
-                mVibratorProviders.get(VIBRATOR_ID).getEffects());
-        assertEquals(Arrays.asList(100), mVibratorProviders.get(VIBRATOR_ID).getAmplitudes());
+                mVibratorProviders.get(VIBRATOR_ID).getEffectSegments());
+        assertEquals(expectedAmplitudes(100), mVibratorProviders.get(VIBRATOR_ID).getAmplitudes());
     }
 
     @Test
@@ -161,7 +169,7 @@
         assertFalse(thread.getVibrators().get(VIBRATOR_ID).isVibrating());
 
         assertEquals(Arrays.asList(expectedOneShot(10)),
-                mVibratorProviders.get(VIBRATOR_ID).getEffects());
+                mVibratorProviders.get(VIBRATOR_ID).getEffectSegments());
         assertTrue(mVibratorProviders.get(VIBRATOR_ID).getAmplitudes().isEmpty());
     }
 
@@ -183,8 +191,9 @@
         assertFalse(thread.getVibrators().get(VIBRATOR_ID).isVibrating());
 
         assertEquals(Arrays.asList(expectedOneShot(15)),
-                mVibratorProviders.get(VIBRATOR_ID).getEffects());
-        assertEquals(Arrays.asList(1, 2, 3), mVibratorProviders.get(VIBRATOR_ID).getAmplitudes());
+                mVibratorProviders.get(VIBRATOR_ID).getEffectSegments());
+        assertEquals(expectedAmplitudes(1, 2, 3),
+                mVibratorProviders.get(VIBRATOR_ID).getAmplitudes());
     }
 
     @Test
@@ -213,12 +222,12 @@
         verify(mThreadCallbacks).onVibrationEnded(eq(vibrationId), eq(Vibration.Status.CANCELLED));
         assertFalse(thread.getVibrators().get(VIBRATOR_ID).isVibrating());
 
-        List<Integer> playedAmplitudes = fakeVibrator.getAmplitudes();
-        assertFalse(fakeVibrator.getEffects().isEmpty());
+        List<Float> playedAmplitudes = fakeVibrator.getAmplitudes();
+        assertFalse(fakeVibrator.getEffectSegments().isEmpty());
         assertFalse(playedAmplitudes.isEmpty());
 
         for (int i = 0; i < playedAmplitudes.size(); i++) {
-            assertEquals(amplitudes[i % amplitudes.length], playedAmplitudes.get(i).intValue());
+            assertEquals(amplitudes[i % amplitudes.length] / 255f, playedAmplitudes.get(i), 1e-5);
         }
     }
 
@@ -292,7 +301,7 @@
         assertFalse(thread.getVibrators().get(VIBRATOR_ID).isVibrating());
 
         assertEquals(Arrays.asList(expectedPrebaked(VibrationEffect.EFFECT_THUD)),
-                mVibratorProviders.get(VIBRATOR_ID).getEffects());
+                mVibratorProviders.get(VIBRATOR_ID).getEffectSegments());
     }
 
     @Test
@@ -302,9 +311,10 @@
 
         long vibrationId = 1;
         VibrationEffect fallback = VibrationEffect.createOneShot(10, 100);
-        VibrationEffect.Prebaked effect = new VibrationEffect.Prebaked(VibrationEffect.EFFECT_CLICK,
-                VibrationEffect.EFFECT_STRENGTH_STRONG, fallback);
-        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
+        Vibration vibration = createVibration(vibrationId, CombinedVibrationEffect.createSynced(
+                VibrationEffect.get(VibrationEffect.EFFECT_CLICK)));
+        vibration.addFallback(VibrationEffect.EFFECT_CLICK, fallback);
+        VibrationThread thread = startThreadAndDispatcher(vibration);
         waitForCompletion(thread);
 
         verify(mIBatteryStatsMock).noteVibratorOn(eq(UID), eq(10L));
@@ -314,8 +324,8 @@
         assertFalse(thread.getVibrators().get(VIBRATOR_ID).isVibrating());
 
         assertEquals(Arrays.asList(expectedOneShot(10)),
-                mVibratorProviders.get(VIBRATOR_ID).getEffects());
-        assertEquals(Arrays.asList(100), mVibratorProviders.get(VIBRATOR_ID).getAmplitudes());
+                mVibratorProviders.get(VIBRATOR_ID).getEffectSegments());
+        assertEquals(expectedAmplitudes(100), mVibratorProviders.get(VIBRATOR_ID).getAmplitudes());
     }
 
     @Test
@@ -331,7 +341,7 @@
         verify(mControllerCallbacks, never()).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
         verify(mThreadCallbacks).onVibrationEnded(eq(vibrationId),
                 eq(Vibration.Status.IGNORED_UNSUPPORTED));
-        assertTrue(mVibratorProviders.get(VIBRATOR_ID).getEffects().isEmpty());
+        assertTrue(mVibratorProviders.get(VIBRATOR_ID).getEffectSegments().isEmpty());
     }
 
     @Test
@@ -351,7 +361,10 @@
         verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
         verify(mThreadCallbacks).onVibrationEnded(eq(vibrationId), eq(Vibration.Status.FINISHED));
         assertFalse(thread.getVibrators().get(VIBRATOR_ID).isVibrating());
-        assertEquals(Arrays.asList(effect), mVibratorProviders.get(VIBRATOR_ID).getEffects());
+        assertEquals(Arrays.asList(
+                expectedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1, 0),
+                expectedPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK, 0.5f, 0)),
+                mVibratorProviders.get(VIBRATOR_ID).getEffectSegments());
     }
 
     @Test
@@ -368,7 +381,79 @@
         verify(mControllerCallbacks, never()).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
         verify(mThreadCallbacks).onVibrationEnded(eq(vibrationId),
                 eq(Vibration.Status.IGNORED_UNSUPPORTED));
-        assertTrue(mVibratorProviders.get(VIBRATOR_ID).getEffects().isEmpty());
+        assertTrue(mVibratorProviders.get(VIBRATOR_ID).getEffectSegments().isEmpty());
+    }
+
+    @Test
+    public void vibrate_singleVibratorComposedEffects_runsDifferentVibrations() throws Exception {
+        mVibratorProviders.get(VIBRATOR_ID).setSupportedEffects(VibrationEffect.EFFECT_CLICK);
+        mVibratorProviders.get(VIBRATOR_ID).setSupportedPrimitives(
+                VibrationEffect.Composition.PRIMITIVE_CLICK,
+                VibrationEffect.Composition.PRIMITIVE_TICK);
+        mVibratorProviders.get(VIBRATOR_ID).setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS,
+                IVibrator.CAP_AMPLITUDE_CONTROL);
+
+        long vibrationId = 1;
+        VibrationEffect effect = VibrationEffect.startComposition()
+                .addEffect(VibrationEffect.createOneShot(10, 100))
+                .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f)
+                .addPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK, 0.5f)
+                .addEffect(VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
+                .addEffect(VibrationEffect.get(VibrationEffect.EFFECT_CLICK), 10)
+                .compose();
+        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
+        waitForCompletion(thread);
+
+        // Use first duration the vibrator is turned on since we cannot estimate the clicks.
+        verify(mIBatteryStatsMock).noteVibratorOn(eq(UID), eq(10L));
+        verify(mIBatteryStatsMock).noteVibratorOff(eq(UID));
+        verify(mControllerCallbacks, times(4)).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
+        verify(mThreadCallbacks).onVibrationEnded(eq(vibrationId), eq(Vibration.Status.FINISHED));
+        assertFalse(thread.getVibrators().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());
+        assertEquals(expectedAmplitudes(100), mVibratorProviders.get(VIBRATOR_ID).getAmplitudes());
+    }
+
+    @Test
+    public void vibrate_singleVibratorPwle_runsComposePwle() throws Exception {
+        mVibratorProviders.get(VIBRATOR_ID).setCapabilities(IVibrator.CAP_COMPOSE_PWLE_EFFECTS);
+        mVibratorProviders.get(VIBRATOR_ID).setSupportedBraking(Braking.CLAB);
+        mVibratorProviders.get(VIBRATOR_ID).setMinFrequency(100);
+        mVibratorProviders.get(VIBRATOR_ID).setResonantFrequency(150);
+        mVibratorProviders.get(VIBRATOR_ID).setFrequencyResolution(50);
+        mVibratorProviders.get(VIBRATOR_ID).setMaxAmplitudes(
+                0.5f /* 100Hz*/, 1 /* 150Hz */, 0.6f /* 200Hz */);
+
+        long vibrationId = 1;
+        VibrationEffect effect = VibrationEffect.startWaveform()
+                .addStep(1, 10)
+                .addRamp(0, 20)
+                .addStep(0.8f, 1, 30)
+                .addRamp(0.6f, -1, 40)
+                .build();
+        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
+        waitForCompletion(thread);
+
+        verify(mIBatteryStatsMock).noteVibratorOn(eq(UID), eq(100L));
+        verify(mIBatteryStatsMock).noteVibratorOff(eq(UID));
+        verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
+        verify(mThreadCallbacks).onVibrationEnded(eq(vibrationId), eq(Vibration.Status.FINISHED));
+        assertFalse(thread.getVibrators().get(VIBRATOR_ID).isVibrating());
+        assertEquals(Arrays.asList(
+                expectedRamp(/* amplitude= */ 1, /* frequency= */ 150, /* duration= */ 10),
+                expectedRamp(/* StartAmplitude= */ 1, /* endAmplitude= */ 0,
+                        /* startFrequency= */ 150, /* endFrequency= */ 150, /* duration= */ 20),
+                expectedRamp(/* amplitude= */ 0.6f, /* frequency= */ 200, /* duration= */ 30),
+                expectedRamp(/* StartAmplitude= */ 0.6f, /* endAmplitude= */ 0.5f,
+                        /* startFrequency= */ 200, /* endFrequency= */ 100, /* duration= */ 40)),
+                mVibratorProviders.get(VIBRATOR_ID).getEffectSegments());
+        assertEquals(Arrays.asList(Braking.CLAB), mVibratorProviders.get(VIBRATOR_ID).getBraking());
     }
 
     @Test
@@ -428,7 +513,7 @@
         assertFalse(thread.getVibrators().get(VIBRATOR_ID).isVibrating());
 
         assertEquals(Arrays.asList(expectedPrebaked(VibrationEffect.EFFECT_TICK)),
-                mVibratorProviders.get(VIBRATOR_ID).getEffects());
+                mVibratorProviders.get(VIBRATOR_ID).getEffectSegments());
     }
 
     @Test
@@ -454,10 +539,10 @@
         assertFalse(thread.getVibrators().get(2).isVibrating());
         assertFalse(thread.getVibrators().get(3).isVibrating());
 
-        VibrationEffect expected = expectedPrebaked(VibrationEffect.EFFECT_CLICK);
-        assertEquals(Arrays.asList(expected), mVibratorProviders.get(1).getEffects());
-        assertEquals(Arrays.asList(expected), mVibratorProviders.get(2).getEffects());
-        assertEquals(Arrays.asList(expected), mVibratorProviders.get(3).getEffects());
+        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());
     }
 
     @Test
@@ -495,12 +580,16 @@
         assertFalse(thread.getVibrators().get(4).isVibrating());
 
         assertEquals(Arrays.asList(expectedPrebaked(VibrationEffect.EFFECT_CLICK)),
-                mVibratorProviders.get(1).getEffects());
-        assertEquals(Arrays.asList(expectedOneShot(10)), mVibratorProviders.get(2).getEffects());
-        assertEquals(Arrays.asList(100), mVibratorProviders.get(2).getAmplitudes());
-        assertEquals(Arrays.asList(expectedOneShot(20)), mVibratorProviders.get(3).getEffects());
-        assertEquals(Arrays.asList(1, 2), mVibratorProviders.get(3).getAmplitudes());
-        assertEquals(Arrays.asList(composed), mVibratorProviders.get(4).getEffects());
+                mVibratorProviders.get(1).getEffectSegments());
+        assertEquals(Arrays.asList(expectedOneShot(10)),
+                mVibratorProviders.get(2).getEffectSegments());
+        assertEquals(expectedAmplitudes(100), mVibratorProviders.get(2).getAmplitudes());
+        assertEquals(Arrays.asList(expectedOneShot(20)),
+                mVibratorProviders.get(3).getEffectSegments());
+        assertEquals(expectedAmplitudes(1, 2), mVibratorProviders.get(3).getAmplitudes());
+        assertEquals(Arrays.asList(
+                expectedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1, 0)),
+                mVibratorProviders.get(4).getEffectSegments());
     }
 
     @Test
@@ -540,11 +629,14 @@
         assertFalse(thread.getVibrators().get(2).isVibrating());
         assertFalse(thread.getVibrators().get(3).isVibrating());
 
-        assertEquals(Arrays.asList(expectedOneShot(10)), mVibratorProviders.get(1).getEffects());
-        assertEquals(Arrays.asList(100), mVibratorProviders.get(1).getAmplitudes());
-        assertEquals(Arrays.asList(composed), mVibratorProviders.get(2).getEffects());
+        assertEquals(Arrays.asList(expectedOneShot(10)),
+                mVibratorProviders.get(1).getEffectSegments());
+        assertEquals(expectedAmplitudes(100), mVibratorProviders.get(1).getAmplitudes());
+        assertEquals(Arrays.asList(
+                expectedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1, 0)),
+                mVibratorProviders.get(2).getEffectSegments());
         assertEquals(Arrays.asList(expectedPrebaked(VibrationEffect.EFFECT_CLICK)),
-                mVibratorProviders.get(3).getEffects());
+                mVibratorProviders.get(3).getEffectSegments());
     }
 
     @Test
@@ -563,8 +655,9 @@
         CombinedVibrationEffect effect = CombinedVibrationEffect.createSynced(composed);
         VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
 
-        assertTrue(waitUntil(t -> !mVibratorProviders.get(1).getEffects().isEmpty()
-                && !mVibratorProviders.get(2).getEffects().isEmpty(), thread, TEST_TIMEOUT_MILLIS));
+        assertTrue(waitUntil(t -> !mVibratorProviders.get(1).getEffectSegments().isEmpty()
+                        && !mVibratorProviders.get(2).getEffectSegments().isEmpty(), thread,
+                TEST_TIMEOUT_MILLIS));
         thread.syncedVibrationComplete();
         waitForCompletion(thread);
 
@@ -574,8 +667,10 @@
         verify(mThreadCallbacks, never()).cancelSyncedVibration();
         verify(mThreadCallbacks).onVibrationEnded(eq(vibrationId), eq(Vibration.Status.FINISHED));
 
-        assertEquals(Arrays.asList(composed), mVibratorProviders.get(1).getEffects());
-        assertEquals(Arrays.asList(composed), mVibratorProviders.get(2).getEffects());
+        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());
     }
 
     @Test
@@ -634,10 +729,12 @@
         verify(mThreadCallbacks, never()).triggerSyncedVibration(eq(vibrationId));
         verify(mThreadCallbacks, never()).cancelSyncedVibration();
 
-        assertEquals(Arrays.asList(expectedOneShot(10)), mVibratorProviders.get(1).getEffects());
-        assertEquals(Arrays.asList(100), mVibratorProviders.get(1).getAmplitudes());
-        assertEquals(Arrays.asList(expectedOneShot(5)), mVibratorProviders.get(2).getEffects());
-        assertEquals(Arrays.asList(200), mVibratorProviders.get(2).getAmplitudes());
+        assertEquals(Arrays.asList(expectedOneShot(10)),
+                mVibratorProviders.get(1).getEffectSegments());
+        assertEquals(expectedAmplitudes(100), mVibratorProviders.get(1).getAmplitudes());
+        assertEquals(Arrays.asList(expectedOneShot(5)),
+                mVibratorProviders.get(2).getEffectSegments());
+        assertEquals(expectedAmplitudes(200), mVibratorProviders.get(2).getAmplitudes());
     }
 
     @Test
@@ -704,12 +801,15 @@
         assertFalse(thread.getVibrators().get(2).isVibrating());
         assertFalse(thread.getVibrators().get(3).isVibrating());
 
-        assertEquals(Arrays.asList(expectedOneShot(25)), mVibratorProviders.get(1).getEffects());
-        assertEquals(Arrays.asList(expectedOneShot(80)), mVibratorProviders.get(2).getEffects());
-        assertEquals(Arrays.asList(expectedOneShot(60)), mVibratorProviders.get(3).getEffects());
-        assertEquals(Arrays.asList(1, 2, 3), mVibratorProviders.get(1).getAmplitudes());
-        assertEquals(Arrays.asList(4, 5), mVibratorProviders.get(2).getAmplitudes());
-        assertEquals(Arrays.asList(6), mVibratorProviders.get(3).getAmplitudes());
+        assertEquals(Arrays.asList(expectedOneShot(25)),
+                mVibratorProviders.get(1).getEffectSegments());
+        assertEquals(Arrays.asList(expectedOneShot(80)),
+                mVibratorProviders.get(2).getEffectSegments());
+        assertEquals(Arrays.asList(expectedOneShot(60)),
+                mVibratorProviders.get(3).getEffectSegments());
+        assertEquals(expectedAmplitudes(1, 2, 3), mVibratorProviders.get(1).getAmplitudes());
+        assertEquals(expectedAmplitudes(4, 5), mVibratorProviders.get(2).getAmplitudes());
+        assertEquals(expectedAmplitudes(6), mVibratorProviders.get(3).getAmplitudes());
     }
 
     @LargeTest
@@ -826,7 +926,7 @@
         verify(mVibrationToken).linkToDeath(same(thread), eq(0));
         verify(mVibrationToken).unlinkToDeath(same(thread), eq(0));
         verify(mThreadCallbacks).onVibrationEnded(eq(vibrationId), eq(Vibration.Status.CANCELLED));
-        assertFalse(mVibratorProviders.get(VIBRATOR_ID).getEffects().isEmpty());
+        assertFalse(mVibratorProviders.get(VIBRATOR_ID).getEffectSegments().isEmpty());
         assertFalse(thread.getVibrators().get(VIBRATOR_ID).isVibrating());
     }
 
@@ -843,12 +943,16 @@
 
     private VibrationThread startThreadAndDispatcher(long vibrationId,
             CombinedVibrationEffect effect) {
-        VibrationThread thread = new VibrationThread(createVibration(vibrationId, effect),
-                createVibratorControllers(), mWakeLock, mIBatteryStatsMock, mThreadCallbacks);
+        return startThreadAndDispatcher(createVibration(vibrationId, effect));
+    }
+
+    private VibrationThread startThreadAndDispatcher(Vibration vib) {
+        VibrationThread thread = new VibrationThread(vib, createVibratorControllers(), mWakeLock,
+                mIBatteryStatsMock, mThreadCallbacks);
         doAnswer(answer -> {
             thread.vibratorComplete(answer.getArgument(0));
             return null;
-        }).when(mControllerCallbacks).onComplete(anyInt(), eq(vibrationId));
+        }).when(mControllerCallbacks).onComplete(anyInt(), eq(vib.id));
         mTestLooper.startAutoDispatch();
         thread.start();
         return thread;
@@ -891,12 +995,31 @@
         return array;
     }
 
-    private VibrationEffect expectedOneShot(long millis) {
-        return VibrationEffect.createOneShot(millis, VibrationEffect.DEFAULT_AMPLITUDE);
+    private VibrationEffectSegment expectedOneShot(long millis) {
+        return new StepSegment(VibrationEffect.DEFAULT_AMPLITUDE, /* frequency= */ 0, (int) millis);
     }
 
-    private VibrationEffect expectedPrebaked(int effectId) {
-        return new VibrationEffect.Prebaked(effectId, false,
-                VibrationEffect.EFFECT_STRENGTH_MEDIUM);
+    private VibrationEffectSegment expectedPrebaked(int effectId) {
+        return new PrebakedSegment(effectId, false, VibrationEffect.EFFECT_STRENGTH_MEDIUM);
+    }
+
+    private VibrationEffectSegment expectedPrimitive(int primitiveId, float scale, int delay) {
+        return new PrimitiveSegment(primitiveId, scale, delay);
+    }
+
+    private VibrationEffectSegment expectedRamp(float amplitude, float frequency, int duration) {
+        return expectedRamp(amplitude, amplitude, frequency, frequency, duration);
+    }
+
+    private VibrationEffectSegment expectedRamp(float startAmplitude, float endAmplitude,
+            float startFrequency, float endFrequency, int duration) {
+        return new RampSegment(startAmplitude, endAmplitude, startFrequency, endFrequency,
+                duration);
+    }
+
+    private List<Float> expectedAmplitudes(int... amplitudes) {
+        return Arrays.stream(amplitudes)
+                .mapToObj(amplitude -> amplitude / 255f)
+                .collect(Collectors.toList());
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/VibratorControllerTest.java b/services/tests/servicestests/src/com/android/server/vibrator/VibratorControllerTest.java
index bad3e4c..2e9aad1 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/VibratorControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/VibratorControllerTest.java
@@ -21,6 +21,7 @@
 import static org.junit.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.anyLong;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.notNull;
@@ -34,11 +35,16 @@
 
 import android.content.ContentResolver;
 import android.content.ContextWrapper;
+import android.hardware.vibrator.Braking;
 import android.hardware.vibrator.IVibrator;
 import android.os.IBinder;
 import android.os.IVibratorStateListener;
 import android.os.VibrationEffect;
+import android.os.VibratorInfo;
 import android.os.test.TestLooper;
+import android.os.vibrator.PrebakedSegment;
+import android.os.vibrator.PrimitiveSegment;
+import android.os.vibrator.RampSegment;
 import android.platform.test.annotations.Presubmit;
 
 import androidx.test.InstrumentationRegistry;
@@ -49,7 +55,6 @@
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
-import org.mockito.ArgumentCaptor;
 import org.mockito.InOrder;
 import org.mockito.Mock;
 import org.mockito.Mockito;
@@ -64,6 +69,7 @@
  */
 @Presubmit
 public class VibratorControllerTest {
+    private static final int VIBRATOR_ID = 0;
 
     @Rule public MockitoRule rule = MockitoJUnit.rule();
     @Rule public FakeSettingsProviderRule mSettingsProviderRule = FakeSettingsProvider.rule();
@@ -84,23 +90,18 @@
         ContentResolver contentResolver = mSettingsProviderRule.mockContentResolver(mContextSpy);
         when(mContextSpy.getContentResolver()).thenReturn(contentResolver);
         when(mVibratorStateListenerMock.asBinder()).thenReturn(mVibratorStateListenerBinderMock);
+        mockVibratorCapabilities(0);
     }
 
     private VibratorController createController() {
-        return new VibratorController(/* vibratorId= */ 0, mOnCompleteListenerMock,
-                mNativeWrapperMock);
-    }
-
-    private VibratorController createController(int vibratorId) {
-        return new VibratorController(vibratorId, mOnCompleteListenerMock, mNativeWrapperMock);
+        return new VibratorController(VIBRATOR_ID, mOnCompleteListenerMock, mNativeWrapperMock);
     }
 
     @Test
     public void createController_initializesNativeWrapper() {
-        int vibratorId = 13;
-        VibratorController controller = createController(vibratorId);
-        assertEquals(vibratorId, controller.getVibratorInfo().getId());
-        verify(mNativeWrapperMock).init(eq(vibratorId), notNull());
+        VibratorController controller = createController();
+        assertEquals(VIBRATOR_ID, controller.getVibratorInfo().getId());
+        verify(mNativeWrapperMock).init(eq(VIBRATOR_ID), notNull());
     }
 
     @Test
@@ -161,9 +162,9 @@
     @Test
     public void updateAlwaysOn_withCapability_enablesAlwaysOnEffect() {
         mockVibratorCapabilities(IVibrator.CAP_ALWAYS_ON_CONTROL);
-        VibrationEffect.Prebaked effect = (VibrationEffect.Prebaked)
-                VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK);
-        createController().updateAlwaysOn(1, effect);
+        PrebakedSegment prebaked = createPrebaked(VibrationEffect.EFFECT_CLICK,
+                VibrationEffect.EFFECT_STRENGTH_MEDIUM);
+        createController().updateAlwaysOn(1, prebaked);
 
         verify(mNativeWrapperMock).alwaysOnEnable(
                 eq(1L), eq((long) VibrationEffect.EFFECT_CLICK),
@@ -179,9 +180,9 @@
 
     @Test
     public void updateAlwaysOn_withoutCapability_ignoresEffect() {
-        VibrationEffect.Prebaked effect = (VibrationEffect.Prebaked)
-                VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK);
-        createController().updateAlwaysOn(1, effect);
+        PrebakedSegment prebaked = createPrebaked(VibrationEffect.EFFECT_CLICK,
+                VibrationEffect.EFFECT_STRENGTH_MEDIUM);
+        createController().updateAlwaysOn(1, prebaked);
 
         verify(mNativeWrapperMock, never()).alwaysOnDisable(anyLong());
         verify(mNativeWrapperMock, never()).alwaysOnEnable(anyLong(), anyLong(), anyLong());
@@ -189,6 +190,7 @@
 
     @Test
     public void on_withDuration_turnsVibratorOn() {
+        when(mNativeWrapperMock.on(anyLong(), anyLong())).thenAnswer(args -> args.getArgument(0));
         VibratorController controller = createController();
         controller.on(100, 10);
 
@@ -201,9 +203,9 @@
         when(mNativeWrapperMock.perform(anyLong(), anyLong(), anyLong())).thenReturn(10L);
         VibratorController controller = createController();
 
-        VibrationEffect.Prebaked effect = (VibrationEffect.Prebaked)
-                VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK);
-        assertEquals(10L, controller.on(effect, 11));
+        PrebakedSegment prebaked = createPrebaked(VibrationEffect.EFFECT_CLICK,
+                VibrationEffect.EFFECT_STRENGTH_MEDIUM);
+        assertEquals(10L, controller.on(prebaked, 11));
 
         assertTrue(controller.isVibrating());
         verify(mNativeWrapperMock).perform(eq((long) VibrationEffect.EFFECT_CLICK),
@@ -216,29 +218,36 @@
         when(mNativeWrapperMock.compose(any(), anyLong())).thenReturn(15L);
         VibratorController controller = createController();
 
-        VibrationEffect.Composed effect = (VibrationEffect.Composed)
-                VibrationEffect.startComposition()
-                        .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 0.5f, 10)
-                        .compose();
-        assertEquals(15L, controller.on(effect, 12));
-
-        ArgumentCaptor<VibrationEffect.Composition.PrimitiveEffect[]> primitivesCaptor =
-                ArgumentCaptor.forClass(VibrationEffect.Composition.PrimitiveEffect[].class);
+        PrimitiveSegment[] primitives = new PrimitiveSegment[]{
+                new PrimitiveSegment(VibrationEffect.Composition.PRIMITIVE_CLICK, 0.5f, 10)
+        };
+        assertEquals(15L, controller.on(primitives, 12));
 
         assertTrue(controller.isVibrating());
-        verify(mNativeWrapperMock).compose(primitivesCaptor.capture(), eq(12L));
+        verify(mNativeWrapperMock).compose(eq(primitives), eq(12L));
+    }
 
-        // Check all primitive effect fields are passed down to the HAL.
-        assertEquals(1, primitivesCaptor.getValue().length);
-        VibrationEffect.Composition.PrimitiveEffect primitive = primitivesCaptor.getValue()[0];
-        assertEquals(VibrationEffect.Composition.PRIMITIVE_CLICK, primitive.id);
-        assertEquals(0.5f, primitive.scale, /* delta= */ 1e-2);
-        assertEquals(10, primitive.delay);
+    @Test
+    public void on_withComposedPwle_performsEffect() {
+        mockVibratorCapabilities(IVibrator.CAP_COMPOSE_PWLE_EFFECTS);
+        when(mNativeWrapperMock.composePwle(any(), anyInt(), anyLong())).thenReturn(15L);
+        VibratorController controller = createController();
+
+        RampSegment[] primitives = new RampSegment[]{
+                new RampSegment(/* startAmplitude= */ 0, /* endAmplitude= */ 1,
+                        /* startFrequency= */ -1, /* endFrequency= */ 1, /* duration= */ 10)
+        };
+        assertEquals(15L, controller.on(primitives, 12));
+        assertTrue(controller.isVibrating());
+
+        verify(mNativeWrapperMock).composePwle(eq(primitives), eq(Braking.NONE), eq(12L));
     }
 
     @Test
     public void off_turnsOffVibrator() {
+        when(mNativeWrapperMock.on(anyLong(), anyLong())).thenAnswer(args -> args.getArgument(0));
         VibratorController controller = createController();
+
         controller.on(100, 1);
         assertTrue(controller.isVibrating());
 
@@ -250,6 +259,7 @@
 
     @Test
     public void registerVibratorStateListener_callbacksAreTriggered() throws Exception {
+        when(mNativeWrapperMock.on(anyLong(), anyLong())).thenAnswer(args -> args.getArgument(0));
         VibratorController controller = createController();
 
         controller.registerVibratorStateListener(mVibratorStateListenerMock);
@@ -268,6 +278,7 @@
 
     @Test
     public void unregisterVibratorStateListener_callbackNotTriggeredAfter() throws Exception {
+        when(mNativeWrapperMock.on(anyLong(), anyLong())).thenAnswer(args -> args.getArgument(0));
         VibratorController controller = createController();
 
         controller.registerVibratorStateListener(mVibratorStateListenerMock);
@@ -284,6 +295,14 @@
     }
 
     private void mockVibratorCapabilities(int capabilities) {
-        when(mNativeWrapperMock.getCapabilities()).thenReturn((long) capabilities);
+        VibratorInfo.FrequencyMapping frequencyMapping = new VibratorInfo.FrequencyMapping(
+                Float.NaN, Float.NaN, Float.NaN, Float.NaN, null);
+        when(mNativeWrapperMock.getInfo(/* suggestedFrequencyRange= */ 100)).thenReturn(
+                new VibratorInfo(VIBRATOR_ID, capabilities, null, null, null, Float.NaN,
+                        frequencyMapping));
+    }
+
+    private PrebakedSegment createPrebaked(int effectId, int effectStrength) {
+        return new PrebakedSegment(effectId, /* shouldFallback= */ false, effectStrength);
     }
 }
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 ce6639c..12ced38 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java
@@ -65,6 +65,8 @@
 import android.os.Vibrator;
 import android.os.VibratorInfo;
 import android.os.test.TestLooper;
+import android.os.vibrator.PrebakedSegment;
+import android.os.vibrator.PrimitiveSegment;
 import android.platform.test.annotations.Presubmit;
 import android.provider.Settings;
 import android.view.InputDevice;
@@ -364,13 +366,13 @@
         assertTrue(createSystemReadyService().setAlwaysOnEffect(
                 UID, PACKAGE_NAME, 1, effect, ALARM_ATTRS));
 
-        VibrationEffect.Prebaked expectedEffect = new VibrationEffect.Prebaked(
+        PrebakedSegment expected = new PrebakedSegment(
                 VibrationEffect.EFFECT_CLICK, false, VibrationEffect.EFFECT_STRENGTH_STRONG);
 
         // Only vibrators 1 and 3 have always-on capabilities.
-        assertEquals(mVibratorProviders.get(1).getAlwaysOnEffect(1), expectedEffect);
+        assertEquals(mVibratorProviders.get(1).getAlwaysOnEffect(1), expected);
         assertNull(mVibratorProviders.get(2).getAlwaysOnEffect(1));
-        assertEquals(mVibratorProviders.get(3).getAlwaysOnEffect(1), expectedEffect);
+        assertEquals(mVibratorProviders.get(3).getAlwaysOnEffect(1), expected);
     }
 
     @Test
@@ -388,10 +390,10 @@
         assertTrue(createSystemReadyService().setAlwaysOnEffect(
                 UID, PACKAGE_NAME, 1, effect, ALARM_ATTRS));
 
-        VibrationEffect.Prebaked expectedClick = new VibrationEffect.Prebaked(
+        PrebakedSegment expectedClick = new PrebakedSegment(
                 VibrationEffect.EFFECT_CLICK, false, VibrationEffect.EFFECT_STRENGTH_STRONG);
 
-        VibrationEffect.Prebaked expectedTick = new VibrationEffect.Prebaked(
+        PrebakedSegment expectedTick = new PrebakedSegment(
                 VibrationEffect.EFFECT_TICK, false, VibrationEffect.EFFECT_STRENGTH_STRONG);
 
         // Enables click on vibrator 1 and tick on vibrator 2 only.
@@ -487,8 +489,9 @@
         vibrate(service, VibrationEffect.createOneShot(40, 100), RINGTONE_ATTRS);
         assertTrue(waitUntil(s -> s.isVibrating(1), service, TEST_TIMEOUT_MILLIS));
 
-        assertEquals(2, mVibratorProviders.get(1).getEffects().size());
-        assertEquals(Arrays.asList(10, 100), mVibratorProviders.get(1).getAmplitudes());
+        assertEquals(2, mVibratorProviders.get(1).getEffectSegments().size());
+        assertEquals(Arrays.asList(10 / 255f, 100 / 255f),
+                mVibratorProviders.get(1).getAmplitudes());
     }
 
     @Test
@@ -500,19 +503,19 @@
         mRegisteredPowerModeListener.onLowPowerModeChanged(LOW_POWER_STATE);
         vibrate(service, VibrationEffect.createOneShot(1, 1), HAPTIC_FEEDBACK_ATTRS);
         vibrate(service, VibrationEffect.createOneShot(2, 2), RINGTONE_ATTRS);
-        assertTrue(waitUntil(s -> fakeVibrator.getEffects().size() == 1,
+        assertTrue(waitUntil(s -> fakeVibrator.getEffectSegments().size() == 1,
                 service, TEST_TIMEOUT_MILLIS));
 
         mRegisteredPowerModeListener.onLowPowerModeChanged(NORMAL_POWER_STATE);
         vibrate(service, VibrationEffect.createOneShot(3, 3), /* attributes= */ null);
-        assertTrue(waitUntil(s -> fakeVibrator.getEffects().size() == 2,
+        assertTrue(waitUntil(s -> fakeVibrator.getEffectSegments().size() == 2,
                 service, TEST_TIMEOUT_MILLIS));
 
         vibrate(service, VibrationEffect.createOneShot(4, 4), NOTIFICATION_ATTRS);
-        assertTrue(waitUntil(s -> fakeVibrator.getEffects().size() == 3,
+        assertTrue(waitUntil(s -> fakeVibrator.getEffectSegments().size() == 3,
                 service, TEST_TIMEOUT_MILLIS));
 
-        assertEquals(Arrays.asList(2, 3, 4), fakeVibrator.getAmplitudes());
+        assertEquals(Arrays.asList(2 / 255f, 3 / 255f, 4 / 255f), fakeVibrator.getAmplitudes());
     }
 
     @Test
@@ -579,7 +582,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).getEffects().isEmpty(),
+        assertFalse(waitUntil(s -> !mVibratorProviders.get(1).getEffectSegments().isEmpty(),
                 service, /* timeout= */ 50));
     }
 
@@ -640,8 +643,11 @@
 
         verify(mNativeWrapperMock).prepareSynced(eq(new int[]{1, 2}));
         verify(mNativeWrapperMock).triggerSynced(anyLong());
-        assertEquals(Arrays.asList(composed), mVibratorProviders.get(1).getEffects());
-        assertEquals(Arrays.asList(composed), mVibratorProviders.get(2).getEffects());
+
+        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());
     }
 
     @Test
@@ -665,7 +671,7 @@
                         .compose())
                 .combine();
         vibrate(service, effect, ALARM_ATTRS);
-        assertTrue(waitUntil(s -> !fakeVibrator1.getEffects().isEmpty(), service,
+        assertTrue(waitUntil(s -> !fakeVibrator1.getEffectSegments().isEmpty(), service,
                 TEST_TIMEOUT_MILLIS));
 
         verify(mNativeWrapperMock).prepareSynced(eq(new int[]{1, 2}));
@@ -689,7 +695,7 @@
                 .addVibrator(2, VibrationEffect.createOneShot(10, 100))
                 .combine();
         vibrate(service, effect, ALARM_ATTRS);
-        assertTrue(waitUntil(s -> !fakeVibrator1.getEffects().isEmpty(), service,
+        assertTrue(waitUntil(s -> !fakeVibrator1.getEffectSegments().isEmpty(), service,
                 TEST_TIMEOUT_MILLIS));
 
         verify(mNativeWrapperMock, never()).prepareSynced(any());
@@ -709,7 +715,7 @@
                 .addVibrator(2, VibrationEffect.createOneShot(10, 100))
                 .combine();
         vibrate(service, effect, ALARM_ATTRS);
-        assertTrue(waitUntil(s -> !mVibratorProviders.get(1).getEffects().isEmpty(), service,
+        assertTrue(waitUntil(s -> !mVibratorProviders.get(1).getEffectSegments().isEmpty(), service,
                 TEST_TIMEOUT_MILLIS));
 
         verify(mNativeWrapperMock).prepareSynced(eq(new int[]{1, 2}));
@@ -730,7 +736,7 @@
                 .addVibrator(2, VibrationEffect.createOneShot(10, 100))
                 .combine();
         vibrate(service, effect, ALARM_ATTRS);
-        assertTrue(waitUntil(s -> !mVibratorProviders.get(1).getEffects().isEmpty(), service,
+        assertTrue(waitUntil(s -> !mVibratorProviders.get(1).getEffectSegments().isEmpty(), service,
                 TEST_TIMEOUT_MILLIS));
 
         verify(mNativeWrapperMock).prepareSynced(eq(new int[]{1, 2}));
@@ -758,40 +764,38 @@
         vibrate(service, CombinedVibrationEffect.startSynced()
                 .addVibrator(1, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
                 .combine(), ALARM_ATTRS);
-        assertTrue(waitUntil(s -> fakeVibrator.getEffects().size() == 1,
+        assertTrue(waitUntil(s -> fakeVibrator.getEffectSegments().size() == 1,
                 service, TEST_TIMEOUT_MILLIS));
 
         vibrate(service, CombinedVibrationEffect.startSequential()
                 .addNext(1, VibrationEffect.createOneShot(20, 100))
                 .combine(), NOTIFICATION_ATTRS);
-        assertTrue(waitUntil(s -> fakeVibrator.getEffects().size() == 2,
+        assertTrue(waitUntil(s -> fakeVibrator.getEffectSegments().size() == 2,
                 service, TEST_TIMEOUT_MILLIS));
 
         vibrate(service, VibrationEffect.startComposition()
                 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f)
                 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK, 0.5f)
                 .compose(), HAPTIC_FEEDBACK_ATTRS);
-        assertTrue(waitUntil(s -> fakeVibrator.getEffects().size() == 3,
+        assertTrue(waitUntil(s -> fakeVibrator.getEffectSegments().size() == 4,
                 service, TEST_TIMEOUT_MILLIS));
 
         vibrate(service, VibrationEffect.get(VibrationEffect.EFFECT_CLICK), RINGTONE_ATTRS);
 
-        assertEquals(3, fakeVibrator.getEffects().size());
+        assertEquals(4, fakeVibrator.getEffectSegments().size());
         assertEquals(1, fakeVibrator.getAmplitudes().size());
 
         // Alarm vibration is always VIBRATION_INTENSITY_HIGH.
-        VibrationEffect expected = new VibrationEffect.Prebaked(VibrationEffect.EFFECT_CLICK, false,
-                VibrationEffect.EFFECT_STRENGTH_STRONG);
-        assertEquals(expected, fakeVibrator.getEffects().get(0));
+        PrebakedSegment expected = new PrebakedSegment(
+                VibrationEffect.EFFECT_CLICK, false, VibrationEffect.EFFECT_STRENGTH_STRONG);
+        assertEquals(expected, fakeVibrator.getEffectSegments().get(0));
 
         // Notification vibrations will be scaled with SCALE_VERY_HIGH.
-        assertTrue(150 < fakeVibrator.getAmplitudes().get(0));
+        assertTrue(0.6 < fakeVibrator.getAmplitudes().get(0));
 
         // Haptic feedback vibrations will be scaled with SCALE_LOW.
-        VibrationEffect.Composed played =
-                (VibrationEffect.Composed) fakeVibrator.getEffects().get(2);
-        assertTrue(0.5 < played.getPrimitiveEffects().get(0).scale);
-        assertTrue(0.5 > played.getPrimitiveEffects().get(1).scale);
+        assertTrue(0.5 < ((PrimitiveSegment) fakeVibrator.getEffectSegments().get(2)).getScale());
+        assertTrue(0.5 > ((PrimitiveSegment) fakeVibrator.getEffectSegments().get(3)).getScale());
 
         // Ring vibrations have intensity OFF and are not played.
     }
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 f5d0ca7..584bcf4 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowOrientationListenerTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowOrientationListenerTest.java
@@ -58,7 +58,6 @@
     private com.android.server.wm.WindowOrientationListener mWindowOrientationListener;
     private int mFinalizedRotation;
     private boolean mRotationResolverEnabled;
-    private boolean mCanUseRotationResolver;
     private SensorEvent mFakeSensorEvent;
     private Sensor mFakeSensor;
 
@@ -66,7 +65,6 @@
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         mRotationResolverEnabled = true;
-        mCanUseRotationResolver = true;
 
         mFakeRotationResolverInternal = new TestableRotationResolver();
         doReturn(mMockSensorManager).when(mMockContext).getSystemService(Context.SENSOR_SERVICE);
@@ -89,16 +87,6 @@
     }
 
     @Test
-    public void testOnSensorChanged_cannotUseRotationResolver_useSensorResult() {
-        mCanUseRotationResolver = false;
-
-        mWindowOrientationListener.mOrientationJudge.onSensorChanged(mFakeSensorEvent);
-
-        assertThat(mFinalizedRotation).isEqualTo(Surface.ROTATION_90);
-
-    }
-
-    @Test
     public void testOnSensorChanged_normalCase() {
         mFakeRotationResolverInternal.mResult = Surface.ROTATION_180;
 
@@ -139,11 +127,6 @@
         }
 
         @Override
-        public boolean canUseRotationResolver() {
-            return mCanUseRotationResolver;
-        }
-
-        @Override
         public boolean isRotationResolverEnabled() {
             return mRotationResolverEnabled;
         }
diff --git a/services/tests/servicestests/utils-mockito/com/android/server/testutils/MockitoUtils.kt b/services/tests/servicestests/utils-mockito/com/android/server/testutils/MockitoUtils.kt
index c6e35cf..e932905 100644
--- a/services/tests/servicestests/utils-mockito/com/android/server/testutils/MockitoUtils.kt
+++ b/services/tests/servicestests/utils-mockito/com/android/server/testutils/MockitoUtils.kt
@@ -93,3 +93,24 @@
         spyThrowOnUnmocked<T>(null, block)
 
 inline fun <reified T : Any> nullable() = ArgumentMatchers.nullable(T::class.java)
+
+/**
+ * Returns Mockito.any() as nullable type to avoid java.lang.IllegalStateException when
+ * null is returned.
+ *
+ * Generic T is nullable because implicitly bounded by Any?.
+ */
+fun <T> any(type: Class<T>): T = Mockito.any<T>(type)
+
+/**
+ * Wrapper around [Mockito.any] for generic types.
+ */
+inline fun <reified T> any() = any(T::class.java)
+
+/**
+ * Returns Mockito.eq() as nullable type to avoid java.lang.IllegalStateException when
+ * null is returned.
+ *
+ * Generic T is nullable because implicitly bounded by Any?.
+ */
+fun <T> eq(obj: T): T = Mockito.eq<T>(obj)
diff --git a/services/tests/servicestests/utils-mockito/com/android/server/testutils/OWNERS b/services/tests/servicestests/utils-mockito/com/android/server/testutils/OWNERS
new file mode 100644
index 0000000..d825dfd
--- /dev/null
+++ b/services/tests/servicestests/utils-mockito/com/android/server/testutils/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/pm/OWNERS
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
index 5462f47..ff88174 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
@@ -1688,8 +1688,8 @@
 
         @Override
         public boolean matches(VibrationEffect actual) {
-            if (actual instanceof VibrationEffect.Waveform &&
-                    ((VibrationEffect.Waveform) actual).getRepeatIndex() == mRepeatIndex) {
+            if (actual instanceof VibrationEffect.Composed
+                    && ((VibrationEffect.Composed) actual).getRepeatIndex() == mRepeatIndex) {
                 return true;
             }
             // All non-waveform effects are essentially one shots.
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java
index 07475e9..27a4826 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java
@@ -58,7 +58,6 @@
 import android.util.TypedXmlSerializer;
 import android.util.Xml;
 
-import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.util.XmlUtils;
 import com.android.server.UiServiceTestCase;
 
@@ -70,8 +69,6 @@
 import org.mockito.MockitoAnnotations;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlSerializer;
 
 import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
@@ -516,6 +513,20 @@
         assertTrue(components.contains(new ComponentName("package", "default")));
     }
 
+    @Test
+    public void resetPackage_clearsUserSet() {
+        // setup
+        ManagedServices service =
+                new TestManagedServices(
+                        getContext(), mLock, mUserProfiles, mIpm, APPROVAL_BY_COMPONENT);
+        String componentName = "package/user-allowed";
+        service.addApprovedList(componentName, 0, true);
+
+        service.resetComponents("package", 0);
+
+        assertFalse(service.isPackageOrComponentUserSet(componentName, 0));
+    }
+
     /** Test that backup only writes packages/components that belong to the target user. */
     @Test
     public void testWriteXml_onlyBackupsForTargetUser() throws Exception {
@@ -1111,7 +1122,7 @@
         when(service.asBinder()).thenReturn(mock(IBinder.class));
         ManagedServices services = new TestManagedServices(getContext(), mLock, mUserProfiles,
                 mIpm, APPROVAL_BY_PACKAGE);
-        services.registerSystemService(service, null, 10);
+        services.registerSystemService(service, null, 10, 1000);
         ManagedServices.ManagedServiceInfo info = services.checkServiceTokenLocked(service);
         info.isSystem = true;
 
@@ -1163,10 +1174,10 @@
 
         ManagedServices.ManagedServiceInfo service0 = service.new ManagedServiceInfo(
                 iInterface, ComponentName.unflattenFromString("a/a"), 0, false,
-                mock(ServiceConnection.class), 26);
+                mock(ServiceConnection.class), 26, 34);
         ManagedServices.ManagedServiceInfo service10 = service.new ManagedServiceInfo(
                 iInterface, ComponentName.unflattenFromString("b/b"), 10, false,
-                mock(ServiceConnection.class), 26);
+                mock(ServiceConnection.class), 26, 345);
         Set<ManagedServices.ManagedServiceInfo> removableBoundServices = new ArraySet<>();
         removableBoundServices.add(service0);
         removableBoundServices.add(service10);
@@ -1199,13 +1210,13 @@
 
         ManagedServices.ManagedServiceInfo service0 = service.new ManagedServiceInfo(
                 iInterface, ComponentName.unflattenFromString("a/a"), 0, false,
-                mock(ServiceConnection.class), 26);
+                mock(ServiceConnection.class), 26, 345);
         ManagedServices.ManagedServiceInfo service0a = service.new ManagedServiceInfo(
                 iInterface, ComponentName.unflattenFromString("c/c"), 0, false,
-                mock(ServiceConnection.class), 26);
+                mock(ServiceConnection.class), 26, 3456);
         ManagedServices.ManagedServiceInfo service10 = service.new ManagedServiceInfo(
                 iInterface, ComponentName.unflattenFromString("b/b"), 10, false,
-                mock(ServiceConnection.class), 26);
+                mock(ServiceConnection.class), 26, 34567);
         Set<ManagedServices.ManagedServiceInfo> removableBoundServices = new ArraySet<>();
         removableBoundServices.add(service0);
         removableBoundServices.add(service0a);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationComparatorTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationComparatorTest.java
index b9ffd65..a37d5c8 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationComparatorTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationComparatorTest.java
@@ -31,9 +31,7 @@
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
-import android.media.session.MediaSession;
 import android.os.Build;
-import android.os.Process;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.service.notification.StatusBarNotification;
@@ -73,7 +71,6 @@
     private NotificationRecord mRecordMinCallNonInterruptive;
     private NotificationRecord mRecordMinCall;
     private NotificationRecord mRecordHighCall;
-    private NotificationRecord mRecordDefaultMedia;
     private NotificationRecord mRecordEmail;
     private NotificationRecord mRecordInlineReply;
     private NotificationRecord mRecordSms;
@@ -139,15 +136,6 @@
                 new UserHandle(userId), "", 1999), getDefaultChannel());
         mRecordHighCall.setSystemImportance(NotificationManager.IMPORTANCE_HIGH);
 
-        Notification n3 = new Notification.Builder(mContext, TEST_CHANNEL_ID)
-                .setStyle(new Notification.MediaStyle()
-                        .setMediaSession(new MediaSession.Token(Process.myUid(), null)))
-                .build();
-        mRecordDefaultMedia = new NotificationRecord(mContext, new StatusBarNotification(pkg2,
-                pkg2, 1, "media", uid2, uid2, n3, new UserHandle(userId),
-                "", 1499), getDefaultChannel());
-        mRecordDefaultMedia.setSystemImportance(NotificationManager.IMPORTANCE_DEFAULT);
-
         Notification n4 = new Notification.Builder(mContext, TEST_CHANNEL_ID)
                 .setStyle(new Notification.MessagingStyle("sender!")).build();
         mRecordInlineReply = new NotificationRecord(mContext, new StatusBarNotification(pkg2,
@@ -218,7 +206,7 @@
                 .setStyle(new Notification.MediaStyle())
                 .build();
         mNoMediaSessionMedia = new NotificationRecord(mContext, new StatusBarNotification(
-                pkg2, pkg2, 1, "cheater", uid2, uid2, n12, new UserHandle(userId),
+                pkg2, pkg2, 1, "media", uid2, uid2, n12, new UserHandle(userId),
                 "", 9258), getDefaultChannel());
         mNoMediaSessionMedia.setSystemImportance(NotificationManager.IMPORTANCE_DEFAULT);
 
@@ -247,7 +235,6 @@
         final List<NotificationRecord> expected = new ArrayList<>();
         expected.add(mRecordColorizedCall);
         expected.add(mRecordColorized);
-        expected.add(mRecordDefaultMedia);
         expected.add(mRecordHighCall);
         expected.add(mRecordInlineReply);
         if (mRecordSms != null) {
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 ec3a1af..bb70c79 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -469,7 +469,7 @@
         when(mListeners.getNotificationListenerFilter(any())).thenReturn(mNlf);
         mListener = mListeners.new ManagedServiceInfo(
                 null, new ComponentName(PKG, "test_class"),
-                UserHandle.getUserId(mUid), true, null, 0);
+                UserHandle.getUserId(mUid), true, null, 0, 123);
         ComponentName defaultComponent = ComponentName.unflattenFromString("config/device");
         ArraySet<ComponentName> components = new ArraySet<>();
         components.add(defaultComponent);
@@ -900,10 +900,10 @@
 
     @Test
     public void testDefaultAssistant_overrideDefault() {
-        final int userId = 0;
+        final int userId = mContext.getUserId();
         final String testComponent = "package/class";
         final List<UserInfo> userInfos = new ArrayList<>();
-        userInfos.add(new UserInfo(0, "", 0));
+        userInfos.add(new UserInfo(userId, "", 0));
         final ArraySet<ComponentName> validAssistants = new ArraySet<>();
         validAssistants.add(ComponentName.unflattenFromString(testComponent));
         when(mActivityManager.isLowRamDevice()).thenReturn(false);
@@ -2346,7 +2346,7 @@
                 .thenReturn(mTestNotificationChannel);
 
         reset(mListeners);
-        mBinderService.updateNotificationChannelForPackage(PKG, 0, mTestNotificationChannel);
+        mBinderService.updateNotificationChannelForPackage(PKG, mUid, mTestNotificationChannel);
         verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
                 eq(Process.myUserHandle()), eq(mTestNotificationChannel),
                 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED));
@@ -2869,7 +2869,7 @@
         snoozeNotificationRunnable.run();
 
         ManagedServices.ManagedServiceInfo listener = mListeners.new ManagedServiceInfo(
-                null, new ComponentName(PKG, "test_class"), mUid, true, null, 0);
+                null, new ComponentName(PKG, "test_class"), mUid, true, null, 0, 234);
         listener.isSystem = true;
         when(mListeners.checkServiceTokenLocked(any())).thenReturn(listener);
 
@@ -2882,7 +2882,7 @@
 
     @Test
     public void testSetListenerAccessForUser() throws Exception {
-        UserHandle user = UserHandle.of(10);
+        UserHandle user = UserHandle.of(mContext.getUserId() + 10);
         ComponentName c = ComponentName.unflattenFromString("package/Component");
         mBinderService.setNotificationListenerAccessGrantedForUser(
                 c, user.getIdentifier(), true, true);
@@ -2899,20 +2899,20 @@
 
     @Test
     public void testSetAssistantAccessForUser() throws Exception {
-        UserHandle user = UserHandle.of(10);
-        List<UserInfo> uis = new ArrayList<>();
         UserInfo ui = new UserInfo();
-        ui.id = 10;
+        ui.id = mContext.getUserId() + 10;
+        UserHandle user = UserHandle.of(ui.id);
+        List<UserInfo> uis = new ArrayList<>();
         uis.add(ui);
         ComponentName c = ComponentName.unflattenFromString("package/Component");
-        when(mUm.getEnabledProfiles(10)).thenReturn(uis);
+        when(mUm.getEnabledProfiles(ui.id)).thenReturn(uis);
 
         mBinderService.setNotificationAssistantAccessGrantedForUser(c, user.getIdentifier(), true);
 
         verify(mContext, times(1)).sendBroadcastAsUser(any(), eq(user), any());
         verify(mAssistants, times(1)).setPackageOrComponentEnabled(
                 c.flattenToString(), user.getIdentifier(), true, true, true);
-        verify(mAssistants).setUserSet(10, true);
+        verify(mAssistants).setUserSet(ui.id, true);
         verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
                 c.flattenToString(), user.getIdentifier(), false, true);
         verify(mListeners, never()).setPackageOrComponentEnabled(
@@ -2921,7 +2921,7 @@
 
     @Test
     public void testGetAssistantAllowedForUser() throws Exception {
-        UserHandle user = UserHandle.of(10);
+        UserHandle user = UserHandle.of(mContext.getUserId() + 10);
         try {
             mBinderService.getAllowedNotificationAssistantForUser(user.getIdentifier());
         } catch (IllegalStateException e) {
@@ -2941,12 +2941,12 @@
                 throw e;
             }
         }
-        verify(mAssistants, times(1)).getAllowedComponents(0);
+        verify(mAssistants, times(1)).getAllowedComponents(mContext.getUserId());
     }
 
     @Test
     public void testSetDndAccessForUser() throws Exception {
-        UserHandle user = UserHandle.of(10);
+        UserHandle user = UserHandle.of(mContext.getUserId() + 10);
         ComponentName c = ComponentName.unflattenFromString("package/Component");
         mBinderService.setNotificationPolicyAccessGrantedForUser(
                 c.getPackageName(), user.getIdentifier(), true);
@@ -2966,9 +2966,9 @@
         mBinderService.setNotificationListenerAccessGranted(c, true, true);
 
         verify(mListeners, times(1)).setPackageOrComponentEnabled(
-                c.flattenToString(), 0, true, true, true);
+                c.flattenToString(), mContext.getUserId(), true, true, true);
         verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
-                c.flattenToString(), 0, false, true, true);
+                c.flattenToString(), mContext.getUserId(), false, true, true);
         verify(mAssistants, never()).setPackageOrComponentEnabled(
                 any(), anyInt(), anyBoolean(), anyBoolean(), anyBoolean());
     }
@@ -2977,7 +2977,7 @@
     public void testSetAssistantAccess() throws Exception {
         List<UserInfo> uis = new ArrayList<>();
         UserInfo ui = new UserInfo();
-        ui.id = 0;
+        ui.id = mContext.getUserId();
         uis.add(ui);
         when(mUm.getEnabledProfiles(ui.id)).thenReturn(uis);
         ComponentName c = ComponentName.unflattenFromString("package/Component");
@@ -2985,9 +2985,9 @@
         mBinderService.setNotificationAssistantAccessGranted(c, true);
 
         verify(mAssistants, times(1)).setPackageOrComponentEnabled(
-                c.flattenToString(), 0, true, true, true);
+                c.flattenToString(), ui.id, true, true, true);
         verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
-                c.flattenToString(), 0, false, true);
+                c.flattenToString(), ui.id, false, true);
         verify(mListeners, never()).setPackageOrComponentEnabled(
                 any(), anyInt(), anyBoolean(), anyBoolean());
     }
@@ -2996,10 +2996,10 @@
     public void testSetAssistantAccess_multiProfile() throws Exception {
         List<UserInfo> uis = new ArrayList<>();
         UserInfo ui = new UserInfo();
-        ui.id = 0;
+        ui.id = mContext.getUserId();
         uis.add(ui);
         UserInfo ui10 = new UserInfo();
-        ui10.id = 10;
+        ui10.id = mContext.getUserId() + 10;
         uis.add(ui10);
         when(mUm.getEnabledProfiles(ui.id)).thenReturn(uis);
         ComponentName c = ComponentName.unflattenFromString("package/Component");
@@ -3007,13 +3007,14 @@
         mBinderService.setNotificationAssistantAccessGranted(c, true);
 
         verify(mAssistants, times(1)).setPackageOrComponentEnabled(
-                c.flattenToString(), 0, true, true, true);
+                c.flattenToString(), ui.id, true, true, true);
         verify(mAssistants, times(1)).setPackageOrComponentEnabled(
-                c.flattenToString(), 10, true, true, true);
+                c.flattenToString(), ui10.id, true, true, true);
+
         verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
-                c.flattenToString(), 0, false, true);
+                c.flattenToString(), ui.id, false, true);
         verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
-                c.flattenToString(), 10, false, true);
+                c.flattenToString(), ui10.id, false, true);
         verify(mListeners, never()).setPackageOrComponentEnabled(
                 any(), anyInt(), anyBoolean(), anyBoolean());
     }
@@ -3026,16 +3027,16 @@
         when(mAssistants.getAllowedComponents(anyInt())).thenReturn(componentList);
         List<UserInfo> uis = new ArrayList<>();
         UserInfo ui = new UserInfo();
-        ui.id = 0;
+        ui.id = mContext.getUserId();
         uis.add(ui);
         when(mUm.getEnabledProfiles(ui.id)).thenReturn(uis);
 
         mBinderService.setNotificationAssistantAccessGranted(null, true);
 
         verify(mAssistants, times(1)).setPackageOrComponentEnabled(
-                c.flattenToString(), 0, true, false, true);
+                c.flattenToString(), ui.id, true, false, true);
         verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
-                c.flattenToString(), 0, false,  false);
+                c.flattenToString(), ui.id, false,  false);
         verify(mListeners, never()).setPackageOrComponentEnabled(
                 any(), anyInt(), anyBoolean(), anyBoolean());
     }
@@ -3044,21 +3045,21 @@
     public void testSetAssistantAccessForUser_nullWithAllowedAssistant() throws Exception {
         List<UserInfo> uis = new ArrayList<>();
         UserInfo ui = new UserInfo();
-        ui.id = 10;
+        ui.id = mContext.getUserId() + 10;
         uis.add(ui);
         UserHandle user = ui.getUserHandle();
         ArrayList<ComponentName> componentList = new ArrayList<>();
         ComponentName c = ComponentName.unflattenFromString("package/Component");
         componentList.add(c);
         when(mAssistants.getAllowedComponents(anyInt())).thenReturn(componentList);
-        when(mUm.getEnabledProfiles(10)).thenReturn(uis);
+        when(mUm.getEnabledProfiles(ui.id)).thenReturn(uis);
 
         mBinderService.setNotificationAssistantAccessGrantedForUser(
                 null, user.getIdentifier(), true);
 
         verify(mAssistants, times(1)).setPackageOrComponentEnabled(
                 c.flattenToString(), user.getIdentifier(), true, false, true);
-        verify(mAssistants).setUserSet(10, true);
+        verify(mAssistants).setUserSet(ui.id, true);
         verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
                 c.flattenToString(), user.getIdentifier(), false,  false);
         verify(mListeners, never()).setPackageOrComponentEnabled(
@@ -3070,10 +3071,10 @@
             throws Exception {
         List<UserInfo> uis = new ArrayList<>();
         UserInfo ui = new UserInfo();
-        ui.id = 0;
+        ui.id = mContext.getUserId();
         uis.add(ui);
         UserInfo ui10 = new UserInfo();
-        ui10.id = 10;
+        ui10.id = mContext.getUserId() + 10;
         uis.add(ui10);
         UserHandle user = ui.getUserHandle();
         ArrayList<ComponentName> componentList = new ArrayList<>();
@@ -3089,8 +3090,8 @@
                 c.flattenToString(), user.getIdentifier(), true, false, true);
         verify(mAssistants, times(1)).setPackageOrComponentEnabled(
                 c.flattenToString(), ui10.id, true, false, true);
-        verify(mAssistants).setUserSet(0, true);
-        verify(mAssistants).setUserSet(10, true);
+        verify(mAssistants).setUserSet(ui.id, true);
+        verify(mAssistants).setUserSet(ui10.id, true);
         verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
                 c.flattenToString(), user.getIdentifier(), false,  false);
         verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
@@ -3106,7 +3107,7 @@
         mBinderService.setNotificationPolicyAccessGranted(c.getPackageName(), true);
 
         verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
-                c.getPackageName(), 0, true, true);
+                c.getPackageName(), mContext.getUserId(), true, true);
         verify(mAssistants, never()).setPackageOrComponentEnabled(
                 any(), anyInt(), anyBoolean(), anyBoolean(), anyBoolean());
         verify(mListeners, never()).setPackageOrComponentEnabled(
@@ -3133,7 +3134,7 @@
         ComponentName c = ComponentName.unflattenFromString("package/Component");
         List<UserInfo> uis = new ArrayList<>();
         UserInfo ui = new UserInfo();
-        ui.id = 0;
+        ui.id = mContext.getUserId();
         uis.add(ui);
         when(mUm.getEnabledProfiles(ui.id)).thenReturn(uis);
 
@@ -3168,9 +3169,9 @@
         mBinderService.setNotificationListenerAccessGranted(c, true, true);
 
         verify(mListeners, times(1)).setPackageOrComponentEnabled(
-                c.flattenToString(), 0, true, true, true);
+                c.flattenToString(), mContext.getUserId(), true, true, true);
         verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
-                c.flattenToString(), 0, false, true, true);
+                c.flattenToString(), mContext.getUserId(), false, true, true);
         verify(mAssistants, never()).setPackageOrComponentEnabled(
                 any(), anyInt(), anyBoolean(), anyBoolean(), anyBoolean());
     }
@@ -3182,7 +3183,7 @@
         ComponentName c = ComponentName.unflattenFromString("package/Component");
         List<UserInfo> uis = new ArrayList<>();
         UserInfo ui = new UserInfo();
-        ui.id = 0;
+        ui.id = mContext.getUserId();
         uis.add(ui);
         when(mUm.getEnabledProfiles(ui.id)).thenReturn(uis);
 
@@ -3191,9 +3192,9 @@
         verify(mListeners, never()).setPackageOrComponentEnabled(
                 anyString(), anyInt(), anyBoolean(), anyBoolean());
         verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
-                c.flattenToString(), 0, false, true);
+                c.flattenToString(), ui.id, false, true);
         verify(mAssistants, times(1)).setPackageOrComponentEnabled(
-                c.flattenToString(), 0, true, true, true);
+                c.flattenToString(), ui.id, true, true, true);
     }
 
     @Test
@@ -3207,7 +3208,7 @@
         verify(mListeners, never()).setPackageOrComponentEnabled(
                 anyString(), anyInt(), anyBoolean(), anyBoolean());
         verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
-                c.getPackageName(), 0, true, true);
+                c.getPackageName(), mContext.getUserId(), true, true);
         verify(mAssistants, never()).setPackageOrComponentEnabled(
                 any(), anyInt(), anyBoolean(), anyBoolean(), anyBoolean());
     }
@@ -4910,6 +4911,7 @@
         assertEquals(0, mService.mToastQueue.size());
         mService.isSystemUid = false;
         setToastRateIsWithinQuota(true);
+        setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
 
         // package is not suspended
         when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
@@ -4933,6 +4935,7 @@
         assertEquals(0, mService.mToastQueue.size());
         mService.isSystemUid = false;
         setToastRateIsWithinQuota(true);
+        setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
 
         // package is not suspended
         when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
@@ -4952,6 +4955,7 @@
         assertEquals(0, mService.mToastQueue.size());
         mService.isSystemUid = false;
         setToastRateIsWithinQuota(true);
+        setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
 
         // package is not suspended
         when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
@@ -4974,11 +4978,12 @@
     }
 
     @Test
-    public void testToastRateLimiterCanPreventsShowCallForCustomToast() throws Exception {
+    public void testToastRateLimiterCanPreventShowCallForCustomToast() throws Exception {
         final String testPackage = "testPackageName";
         assertEquals(0, mService.mToastQueue.size());
         mService.isSystemUid = false;
         setToastRateIsWithinQuota(false); // rate limit reached
+        setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
 
         // package is not suspended
         when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
@@ -4995,12 +5000,36 @@
     }
 
     @Test
+    public void testCustomToastRateLimiterAllowsLimitAvoidanceWithPermission() throws Exception {
+        final String testPackage = "testPackageName";
+        assertEquals(0, mService.mToastQueue.size());
+        mService.isSystemUid = false;
+        setToastRateIsWithinQuota(false); // rate limit reached
+        // Avoids rate limiting.
+        setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, true);
+
+        // package is not suspended
+        when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
+                .thenReturn(false);
+
+        setAppInForegroundForToasts(mUid, true);
+
+        Binder token = new Binder();
+        ITransientNotification callback = mock(ITransientNotification.class);
+        INotificationManager nmService = (INotificationManager) mService.mService;
+
+        nmService.enqueueToast(testPackage, token, callback, 2000, 0);
+        verify(callback).show(any());
+    }
+
+    @Test
     public void testCustomToastPostedWhileInForeground_blockedIfAppGoesToBackground()
             throws Exception {
         final String testPackage = "testPackageName";
         assertEquals(0, mService.mToastQueue.size());
         mService.isSystemUid = false;
         setToastRateIsWithinQuota(true);
+        setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
 
         // package is not suspended
         when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
@@ -5034,6 +5063,7 @@
         assertEquals(0, mService.mToastQueue.size());
         mService.isSystemUid = false;
         setToastRateIsWithinQuota(true);
+        setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
 
         // package is not suspended
         when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
@@ -5053,6 +5083,7 @@
         assertEquals(0, mService.mToastQueue.size());
         mService.isSystemUid = false;
         setToastRateIsWithinQuota(true);
+        setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
 
         // package is not suspended
         when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
@@ -5072,6 +5103,7 @@
         assertEquals(0, mService.mToastQueue.size());
         mService.isSystemUid = false;
         setToastRateIsWithinQuota(true);
+        setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
 
         // package is not suspended
         when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
@@ -5095,11 +5127,12 @@
     }
 
     @Test
-    public void testToastRateLimiterCanPreventsShowCallForTextToast() throws Exception {
+    public void testToastRateLimiterCanPreventShowCallForTextToast() throws Exception {
         final String testPackage = "testPackageName";
         assertEquals(0, mService.mToastQueue.size());
         mService.isSystemUid = false;
         setToastRateIsWithinQuota(false); // rate limit reached
+        setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
 
         // package is not suspended
         when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
@@ -5114,12 +5147,32 @@
     }
 
     @Test
+    public void testTextToastRateLimiterAllowsLimitAvoidanceWithPermission() throws Exception {
+        final String testPackage = "testPackageName";
+        assertEquals(0, mService.mToastQueue.size());
+        mService.isSystemUid = false;
+        setToastRateIsWithinQuota(false); // rate limit reached
+        setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, true);
+
+        // package is not suspended
+        when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
+                .thenReturn(false);
+
+        Binder token = new Binder();
+        INotificationManager nmService = (INotificationManager) mService.mService;
+
+        nmService.enqueueTextToast(testPackage, token, "Text", 2000, 0, null);
+        verify(mStatusBar).showToast(anyInt(), any(), any(), any(), any(), anyInt(), any());
+    }
+
+    @Test
     public void backgroundSystemCustomToast_callsSetProcessImportantAsForegroundForToast() throws
             Exception {
         final String testPackage = "testPackageName";
         assertEquals(0, mService.mToastQueue.size());
         mService.isSystemUid = true;
         setToastRateIsWithinQuota(true);
+        setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
 
         // package is not suspended
         when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
@@ -5145,6 +5198,7 @@
         assertEquals(0, mService.mToastQueue.size());
         mService.isSystemUid = false;
         setToastRateIsWithinQuota(true);
+        setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
 
         // package is not suspended
         when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
@@ -5166,6 +5220,7 @@
         assertEquals(0, mService.mToastQueue.size());
         mService.isSystemUid = false;
         setToastRateIsWithinQuota(true);
+        setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
 
         // package is not suspended
         when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
@@ -5186,6 +5241,7 @@
         assertEquals(0, mService.mToastQueue.size());
         mService.isSystemUid = false;
         setToastRateIsWithinQuota(true);
+        setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
 
         // package is not suspended
         when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
@@ -5203,6 +5259,7 @@
         assertEquals(0, mService.mToastQueue.size());
         mService.isSystemUid = false;
         setToastRateIsWithinQuota(true);
+        setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
 
         // package is suspended
         when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
@@ -5224,6 +5281,7 @@
         assertEquals(0, mService.mToastQueue.size());
         mService.isSystemUid = false;
         setToastRateIsWithinQuota(true);
+        setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
 
         // package is not suspended
         when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
@@ -5247,6 +5305,7 @@
         assertEquals(0, mService.mToastQueue.size());
         mService.isSystemUid = true;
         setToastRateIsWithinQuota(true);
+        setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
 
         // package is suspended
         when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
@@ -5270,6 +5329,7 @@
         assertEquals(0, mService.mToastQueue.size());
         mService.isSystemUid = false;
         setToastRateIsWithinQuota(true);
+        setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
 
         // package is not suspended
         when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
@@ -5305,6 +5365,13 @@
                 .thenReturn(isWithinQuota);
     }
 
+    private void setIfPackageHasPermissionToAvoidToastRateLimiting(
+            String pkg, boolean hasPermission) throws Exception {
+        when(mPackageManager.checkPermission(android.Manifest.permission.UNLIMITED_TOASTS,
+                pkg, UserHandle.getUserId(mUid)))
+                .thenReturn(hasPermission ? PERMISSION_GRANTED : PERMISSION_DENIED);
+    }
+
     @Test
     public void testOnPanelRevealedAndHidden() {
         int items = 5;
@@ -6905,51 +6972,6 @@
     }
 
     @Test
-    public void deleteConversationNotificationChannels() throws Exception {
-        NotificationChannel messagesParent =
-                new NotificationChannel("messages", "messages", IMPORTANCE_HIGH);
-        Parcel msgParcel = Parcel.obtain();
-        messagesParent.writeToParcel(msgParcel, 0);
-        msgParcel.setDataPosition(0);
-
-        NotificationChannel callsParent =
-                new NotificationChannel("calls", "calls", IMPORTANCE_HIGH);
-        Parcel callParcel = Parcel.obtain();
-        callsParent.writeToParcel(callParcel, 0);
-        callParcel.setDataPosition(0);
-
-        mBinderService.createNotificationChannels(PKG, new ParceledListSlice(Arrays.asList(
-                messagesParent, callsParent)));
-
-        String conversationId = "friend";
-
-        mBinderService.createConversationNotificationChannelForPackage(
-                PKG, mUid, NotificationChannel.CREATOR.createFromParcel(msgParcel),
-                conversationId);
-        mBinderService.createConversationNotificationChannelForPackage(
-                PKG, mUid, NotificationChannel.CREATOR.createFromParcel(callParcel),
-                conversationId);
-
-        NotificationChannel messagesChild = mBinderService.getConversationNotificationChannel(
-                PKG, 0, PKG, messagesParent.getId(), false, conversationId);
-        NotificationChannel callsChild = mBinderService.getConversationNotificationChannel(
-                PKG, 0, PKG, callsParent.getId(), false, conversationId);
-
-        assertEquals(messagesParent.getId(), messagesChild.getParentChannelId());
-        assertEquals(conversationId, messagesChild.getConversationId());
-
-        assertEquals(callsParent.getId(), callsChild.getParentChannelId());
-        assertEquals(conversationId, callsChild.getConversationId());
-
-        mBinderService.deleteConversationNotificationChannels(PKG, mUid, conversationId);
-
-        assertNull(mBinderService.getConversationNotificationChannel(
-                PKG, 0, PKG, messagesParent.getId(), false, conversationId));
-        assertNull(mBinderService.getConversationNotificationChannel(
-                PKG, 0, PKG, callsParent.getId(), false, conversationId));
-    }
-
-    @Test
     public void testCorrectCategory_systemOn_appCannotTurnOff() {
         int requested = 0;
         int system = PRIORITY_CATEGORY_CALLS | PRIORITY_CATEGORY_CONVERSATIONS;
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 acda4d5..04c144a 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
@@ -71,6 +71,7 @@
 import android.app.NotificationChannel;
 import android.app.NotificationChannelGroup;
 import android.app.NotificationManager;
+import android.content.AttributionSource;
 import android.content.ContentProvider;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -86,6 +87,7 @@
 import android.os.AsyncTask;
 import android.os.Build;
 import android.os.Bundle;
+import android.os.Process;
 import android.os.RemoteCallback;
 import android.os.RemoteException;
 import android.os.UserHandle;
@@ -207,37 +209,35 @@
             throw new UnsupportedOperationException("unimplemented mock method");
         });
         doAnswer(invocation -> {
-            String callingPkg = invocation.getArgument(0);
-            String featureId = invocation.getArgument(1);
-            Uri uri = invocation.getArgument(2);
-            RemoteCallback cb = invocation.getArgument(3);
+            AttributionSource attributionSource = invocation.getArgument(0);
+            Uri uri = invocation.getArgument(1);
+            RemoteCallback cb = invocation.getArgument(2);
             IContentProvider mock = (IContentProvider) (invocation.getMock());
             AsyncTask.SERIAL_EXECUTOR.execute(() -> {
                 final Bundle bundle = new Bundle();
                 try {
                     bundle.putParcelable(ContentResolver.REMOTE_CALLBACK_RESULT,
-                            mock.canonicalize(callingPkg, featureId, uri));
+                            mock.canonicalize(attributionSource, uri));
                 } catch (RemoteException e) { /* consume */ }
                 cb.sendResult(bundle);
             });
             return null;
-        }).when(mTestIContentProvider).canonicalizeAsync(any(), any(), any(), any());
+        }).when(mTestIContentProvider).canonicalizeAsync(any(), any(), any());
         doAnswer(invocation -> {
-            String callingPkg = invocation.getArgument(0);
-            String featureId = invocation.getArgument(1);
-            Uri uri = invocation.getArgument(2);
-            RemoteCallback cb = invocation.getArgument(3);
+            AttributionSource attributionSource = invocation.getArgument(0);
+            Uri uri = invocation.getArgument(1);
+            RemoteCallback cb = invocation.getArgument(2);
             IContentProvider mock = (IContentProvider) (invocation.getMock());
             AsyncTask.SERIAL_EXECUTOR.execute(() -> {
                 final Bundle bundle = new Bundle();
                 try {
                     bundle.putParcelable(ContentResolver.REMOTE_CALLBACK_RESULT,
-                            mock.uncanonicalize(callingPkg, featureId, uri));
+                            mock.uncanonicalize(attributionSource, uri));
                 } catch (RemoteException e) { /* consume */ }
                 cb.sendResult(bundle);
             });
             return null;
-        }).when(mTestIContentProvider).uncanonicalizeAsync(any(), any(), any(), any());
+        }).when(mTestIContentProvider).uncanonicalizeAsync(any(), any(), any());
         doAnswer(invocation -> {
             Uri uri = invocation.getArgument(0);
             RemoteCallback cb = invocation.getArgument(1);
@@ -256,11 +256,11 @@
         contentResolver.addProvider(TEST_AUTHORITY, testContentProvider);
 
         doReturn(CANONICAL_SOUND_URI)
-                .when(mTestIContentProvider).canonicalize(any(), any(), eq(SOUND_URI));
+                .when(mTestIContentProvider).canonicalize(any(), eq(SOUND_URI));
         doReturn(CANONICAL_SOUND_URI)
-                .when(mTestIContentProvider).canonicalize(any(), any(), eq(CANONICAL_SOUND_URI));
+                .when(mTestIContentProvider).canonicalize(any(), eq(CANONICAL_SOUND_URI));
         doReturn(SOUND_URI)
-                .when(mTestIContentProvider).uncanonicalize(any(), any(), eq(CANONICAL_SOUND_URI));
+                .when(mTestIContentProvider).uncanonicalize(any(), eq(CANONICAL_SOUND_URI));
 
         mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0,
                 NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND, 0);
@@ -594,7 +594,7 @@
 
         // Testing that in restore we are given the canonical version
         loadStreamXml(baos, true, UserHandle.USER_SYSTEM);
-        verify(mTestIContentProvider).uncanonicalize(any(), any(), eq(CANONICAL_SOUND_URI));
+        verify(mTestIContentProvider).uncanonicalize(any(), eq(CANONICAL_SOUND_URI));
     }
 
     @Test
@@ -605,12 +605,11 @@
                 .appendQueryParameter("canonical", "1")
                 .build();
         doReturn(canonicalBasedOnLocal)
-                .when(mTestIContentProvider).canonicalize(any(), any(), eq(CANONICAL_SOUND_URI));
+                .when(mTestIContentProvider).canonicalize(any(), eq(CANONICAL_SOUND_URI));
         doReturn(localUri)
-                .when(mTestIContentProvider).uncanonicalize(any(), any(), eq(CANONICAL_SOUND_URI));
+                .when(mTestIContentProvider).uncanonicalize(any(), eq(CANONICAL_SOUND_URI));
         doReturn(localUri)
-                .when(mTestIContentProvider).uncanonicalize(any(), any(),
-                eq(canonicalBasedOnLocal));
+                .when(mTestIContentProvider).uncanonicalize(any(), eq(canonicalBasedOnLocal));
 
         NotificationChannel channel =
                 new NotificationChannel("id", "name", IMPORTANCE_LOW);
@@ -630,9 +629,9 @@
     public void testRestoreXml_withNonExistentCanonicalizedSoundUri() throws Exception {
         Thread.sleep(3000);
         doReturn(null)
-                .when(mTestIContentProvider).canonicalize(any(), any(), eq(CANONICAL_SOUND_URI));
+                .when(mTestIContentProvider).canonicalize(any(), eq(CANONICAL_SOUND_URI));
         doReturn(null)
-                .when(mTestIContentProvider).uncanonicalize(any(), any(), eq(CANONICAL_SOUND_URI));
+                .when(mTestIContentProvider).uncanonicalize(any(), eq(CANONICAL_SOUND_URI));
 
         NotificationChannel channel =
                 new NotificationChannel("id", "name", IMPORTANCE_LOW);
@@ -657,7 +656,7 @@
     public void testRestoreXml_withUncanonicalizedNonLocalSoundUri() throws Exception {
         // Not a local uncanonicalized uri, simulating that it fails to exist locally
         doReturn(null)
-                .when(mTestIContentProvider).canonicalize(any(), any(), eq(SOUND_URI));
+                .when(mTestIContentProvider).canonicalize(any(), eq(SOUND_URI));
         String id = "id";
         String backupWithUncanonicalizedSoundUri = "<ranking version=\"1\">\n"
                 + "<package name=\"" + PKG_N_MR1 + "\" show_badge=\"true\">\n"
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java
index 5018166..b83f9f2 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java
@@ -132,11 +132,11 @@
         when(testContentProvider.getIContentProvider()).thenReturn(mTestIContentProvider);
         contentResolver.addProvider(TEST_AUTHORITY, testContentProvider);
 
-        when(mTestIContentProvider.canonicalize(any(), any(), eq(SOUND_URI)))
+        when(mTestIContentProvider.canonicalize(any(), eq(SOUND_URI)))
                 .thenReturn(CANONICAL_SOUND_URI);
-        when(mTestIContentProvider.canonicalize(any(), any(), eq(CANONICAL_SOUND_URI)))
+        when(mTestIContentProvider.canonicalize(any(), eq(CANONICAL_SOUND_URI)))
                 .thenReturn(CANONICAL_SOUND_URI);
-        when(mTestIContentProvider.uncanonicalize(any(), any(), eq(CANONICAL_SOUND_URI)))
+        when(mTestIContentProvider.uncanonicalize(any(), eq(CANONICAL_SOUND_URI)))
                 .thenReturn(SOUND_URI);
 
         mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0,
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ScheduleCalendarTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ScheduleCalendarTest.java
index 3b15376..1116204 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ScheduleCalendarTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ScheduleCalendarTest.java
@@ -316,9 +316,10 @@
         mScheduleCalendar.setSchedule(mScheduleInfo);
         mScheduleInfo.nextAlarm = 2000;
 
+        // next alarm updated to 3000 (alarm for 2000 was changed to 3000)
         mScheduleCalendar.maybeSetNextAlarm(1000, 3000);
 
-        assertEquals(2000, mScheduleInfo.nextAlarm);
+        assertEquals(3000, mScheduleInfo.nextAlarm);
     }
 
     @Test
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ScheduleConditionProviderTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ScheduleConditionProviderTest.java
index 5a527a2..7446e9e 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ScheduleConditionProviderTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ScheduleConditionProviderTest.java
@@ -279,17 +279,17 @@
                 conditionId, cal, now.getTimeInMillis(), now.getTimeInMillis() + 500);
         assertEquals(Condition.STATE_TRUE, condition.state);
 
-        // in schedule, update with later alarm time, should be in dnd
+        // in schedule, update with nextAlarm = later alarm time (1000), should be in dnd
         condition = mService.evaluateSubscriptionLocked(
                 conditionId, cal, now.getTimeInMillis() + 250, now.getTimeInMillis() + 1000);
         assertEquals(Condition.STATE_TRUE, condition.state);
 
-        // at earliest alarm fire time, should exit dnd
-        assertTrue(cal.isInSchedule(now.getTimeInMillis() + 500));
+        // at next alarm fire time (1000), should exit dnd
+        assertTrue(cal.isInSchedule(now.getTimeInMillis() + 1000));
         assertTrue("" + info.nextAlarm + " " + now.getTimeInMillis(),
-                cal.shouldExitForAlarm(now.getTimeInMillis() + 500));
+                cal.shouldExitForAlarm(now.getTimeInMillis() + 1000));
         condition = mService.evaluateSubscriptionLocked(
-                conditionId, cal, now.getTimeInMillis() + 500, 0);
+                conditionId, cal, now.getTimeInMillis() + 1000, 0);
         assertEquals(Condition.STATE_FALSE, condition.state);
     }
 
diff --git a/services/tests/uiservicestests/src/com/android/server/slice/PinnedSliceStateTest.java b/services/tests/uiservicestests/src/com/android/server/slice/PinnedSliceStateTest.java
index aceed86..baae25c 100644
--- a/services/tests/uiservicestests/src/com/android/server/slice/PinnedSliceStateTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/slice/PinnedSliceStateTest.java
@@ -110,7 +110,7 @@
         mPinnedSliceManager.pin("pkg", FIRST_SPECS, mToken);
         TestableLooper.get(this).processAllMessages();
 
-        verify(mIContentProvider).call(anyString(), nullable(String.class), anyString(),
+        verify(mIContentProvider).call(any(), anyString(),
                 eq(SliceProvider.METHOD_PIN), eq(null), argThat(b -> {
                     assertEquals(TEST_URI, b.getParcelable(SliceProvider.EXTRA_BIND_URI));
                     return true;
@@ -168,8 +168,8 @@
         // Throw exception when trying to pin
         doAnswer(invocation -> {
             throw new Exception("Pin failed");
-        }).when(mIContentProvider).call(anyString(), nullable(String.class), anyString(),
-                anyString(), eq(null), any());
+        }).when(mIContentProvider).call(any(), anyString(), anyString(),
+                nullable(String.class), any());
 
         TestableLooper.get(this).processAllMessages();
 
@@ -177,7 +177,7 @@
         mPinnedSliceManager.pin("pkg", FIRST_SPECS, mToken);
         TestableLooper.get(this).processAllMessages();
 
-        verify(mIContentProvider).call(anyString(), nullable(String.class), anyString(),
+        verify(mIContentProvider).call(any(), anyString(),
                 eq(SliceProvider.METHOD_PIN), eq(null), argThat(b -> {
                     assertEquals(TEST_URI, b.getParcelable(SliceProvider.EXTRA_BIND_URI));
                     return true;
diff --git a/services/tests/wmtests/src/com/android/server/policy/SingleKeyGestureTests.java b/services/tests/wmtests/src/com/android/server/policy/SingleKeyGestureTests.java
index 3025a95..222c692 100644
--- a/services/tests/wmtests/src/com/android/server/policy/SingleKeyGestureTests.java
+++ b/services/tests/wmtests/src/com/android/server/policy/SingleKeyGestureTests.java
@@ -26,6 +26,7 @@
 import static com.android.server.policy.SingleKeyGestureDetector.KEY_VERYLONGPRESS;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
 import android.app.Instrumentation;
@@ -62,6 +63,10 @@
     private long mLongPressTime;
     private long mVeryLongPressTime;
 
+    // Allow press from non interactive mode.
+    private boolean mAllowNonInteractiveForPress = true;
+    private boolean mAllowNonInteractiveForLongPress = true;
+
     @Before
     public void setUp() {
         mDetector = new SingleKeyGestureDetector(mContext);
@@ -81,11 +86,17 @@
             }
             @Override
             public void onPress(long downTime) {
+                if (mDetector.beganFromNonInteractive() && !mAllowNonInteractiveForPress) {
+                    return;
+                }
                 mShortPressed.countDown();
             }
 
             @Override
             void onLongPress(long downTime) {
+                if (mDetector.beganFromNonInteractive() && !mAllowNonInteractiveForLongPress) {
+                    return;
+                }
                 mLongPressed.countDown();
             }
 
@@ -96,6 +107,9 @@
 
             @Override
             void onMultiPress(long downTime, int count) {
+                if (mDetector.beganFromNonInteractive() && !mAllowNonInteractiveForPress) {
+                    return;
+                }
                 mMultiPressed.countDown();
                 assertEquals(mMaxMultiPressPowerCount, count);
             }
@@ -103,9 +117,13 @@
     }
 
     private void pressKey(long eventTime, int keyCode, long pressTime) {
+        pressKey(eventTime, keyCode, pressTime, true /* interactive */);
+    }
+
+    private void pressKey(long eventTime, int keyCode, long pressTime, boolean interactive) {
         final KeyEvent keyDown = new KeyEvent(eventTime, eventTime, ACTION_DOWN,
                 keyCode, 0 /* repeat */, 0 /* metaState */);
-        mDetector.interceptKey(keyDown);
+        mDetector.interceptKey(keyDown, interactive);
 
         // keep press down.
         try {
@@ -118,7 +136,7 @@
         final KeyEvent keyUp = new KeyEvent(eventTime, eventTime, ACTION_UP,
                 keyCode, 0 /* repeat */, 0 /* metaState */);
 
-        mDetector.interceptKey(keyUp);
+        mDetector.interceptKey(keyUp, interactive);
     }
 
     @Test
@@ -149,4 +167,18 @@
         pressKey(eventTime, KEYCODE_POWER, 0 /* pressTime */);
         assertTrue(mMultiPressed.await(mWaitTimeout, TimeUnit.MILLISECONDS));
     }
+
+    @Test
+    public void testNonInteractive() throws InterruptedException {
+        long eventTime = SystemClock.uptimeMillis();
+        // Disallow short press behavior from non interactive.
+        mAllowNonInteractiveForPress = false;
+        pressKey(eventTime, KEYCODE_POWER, 0 /* pressTime */, false /* interactive */);
+        assertFalse(mShortPressed.await(mWaitTimeout, TimeUnit.MILLISECONDS));
+
+        // Allow long press behavior from non interactive.
+        eventTime = SystemClock.uptimeMillis();
+        pressKey(eventTime, KEYCODE_POWER, mLongPressTime, false /* interactive */);
+        assertTrue(mLongPressed.await(mWaitTimeout, TimeUnit.MILLISECONDS));
+    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java
deleted file mode 100644
index 1700707..0000000
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java
+++ /dev/null
@@ -1,346 +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.server.wm;
-
-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_STANDARD;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
-import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
-import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE;
-import static android.content.pm.ActivityInfo.FLAG_SHOW_WHEN_LOCKED;
-
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.clearInvocations;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.never;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
-import static com.android.server.wm.ActivityTaskSupervisor.ON_TOP;
-import static com.android.server.wm.WindowContainer.POSITION_TOP;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doAnswer;
-
-import android.platform.test.annotations.Presubmit;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/**
- * Tests for the {@link DisplayContent} class.
- *
- * Build/Install/Run:
- *  atest WmTests:ActivityDisplayTests
- */
-@SmallTest
-@Presubmit
-@RunWith(WindowTestRunner.class)
-// TODO(b/144248496): Merge to DisplayContentTests
-public class ActivityDisplayTests extends WindowTestsBase {
-
-    @Test
-    public void testLastFocusedStackIsUpdatedWhenMovingStack() {
-        // Create a stack at bottom.
-        final TaskDisplayArea taskDisplayAreas =
-                mRootWindowContainer.getDefaultDisplay().getDefaultTaskDisplayArea();
-        final Task stack =
-                new TaskBuilder(mSupervisor).setOnTop(!ON_TOP).setCreateActivity(true).build();
-        final Task prevFocusedStack = taskDisplayAreas.getFocusedRootTask();
-
-        stack.moveToFront("moveStackToFront");
-        // After moving the stack to front, the previous focused should be the last focused.
-        assertTrue(stack.isFocusedRootTaskOnDisplay());
-        assertEquals(prevFocusedStack, taskDisplayAreas.getLastFocusedRootTask());
-
-        stack.moveToBack("moveStackToBack", null /* task */);
-        // After moving the stack to back, the stack should be the last focused.
-        assertEquals(stack, taskDisplayAreas.getLastFocusedRootTask());
-    }
-
-    /**
-     * This test simulates the picture-in-picture menu activity launches an activity to fullscreen
-     * stack. The fullscreen stack should be the top focused for resuming correctly.
-     */
-    @Test
-    public void testFullscreenStackCanBeFocusedWhenFocusablePinnedStackExists() {
-        // Create a pinned stack and move to front.
-        final Task pinnedStack = mRootWindowContainer.getDefaultTaskDisplayArea()
-                .createRootTask(WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, ON_TOP);
-        final Task pinnedTask = new TaskBuilder(mAtm.mTaskSupervisor)
-                .setParentTask(pinnedStack).build();
-        new ActivityBuilder(mAtm).setActivityFlags(FLAG_ALWAYS_FOCUSABLE)
-                .setTask(pinnedTask).build();
-        pinnedStack.moveToFront("movePinnedStackToFront");
-
-        // The focused stack should be the pinned stack.
-        assertTrue(pinnedStack.isFocusedRootTaskOnDisplay());
-
-        // Create a fullscreen stack and move to front.
-        final Task fullscreenStack = createFullscreenStackWithSimpleActivityAt(
-                mRootWindowContainer.getDefaultDisplay());
-        fullscreenStack.moveToFront("moveFullscreenStackToFront");
-
-        // The focused stack should be the fullscreen stack.
-        assertTrue(fullscreenStack.isFocusedRootTaskOnDisplay());
-    }
-
-    /**
-     * Test {@link TaskDisplayArea#mPreferredTopFocusableRootTask} will be cleared when
-     * the stack is removed or moved to back, and the focused stack will be according to z-order.
-     */
-    @Test
-    public void testStackShouldNotBeFocusedAfterMovingToBackOrRemoving() {
-        // Create a display which only contains 2 stacks.
-        final DisplayContent display = addNewDisplayContentAt(POSITION_TOP);
-        final Task stack1 = createFullscreenStackWithSimpleActivityAt(display);
-        final Task stack2 = createFullscreenStackWithSimpleActivityAt(display);
-
-        // Put stack1 and stack2 on top.
-        stack1.moveToFront("moveStack1ToFront");
-        stack2.moveToFront("moveStack2ToFront");
-        assertTrue(stack2.isFocusedRootTaskOnDisplay());
-
-        // Stack1 should be focused after moving stack2 to back.
-        stack2.moveToBack("moveStack2ToBack", null /* task */);
-        assertTrue(stack1.isFocusedRootTaskOnDisplay());
-
-        // Stack2 should be focused after removing stack1.
-        stack1.getDisplayArea().removeRootTask(stack1);
-        assertTrue(stack2.isFocusedRootTaskOnDisplay());
-    }
-
-    /**
-     * Verifies {@link DisplayContent#remove} should not resume home stack on the removing display.
-     */
-    @Test
-    public void testNotResumeHomeStackOnRemovingDisplay() {
-        // Create a display which supports system decoration and allows reparenting stacks to
-        // another display when the display is removed.
-        final DisplayContent display = new TestDisplayContent.Builder(
-                mAtm, 1000, 1500).setSystemDecorations(true).build();
-        doReturn(false).when(display).shouldDestroyContentOnRemove();
-
-        // Put home stack on the display.
-        final Task homeStack = new TaskBuilder(mSupervisor)
-                .setDisplay(display).setActivityType(ACTIVITY_TYPE_HOME).build();
-
-        // Put a finishing standard activity which will be reparented.
-        final Task stack = createFullscreenStackWithSimpleActivityAt(display);
-        stack.topRunningActivity().makeFinishingLocked();
-
-        clearInvocations(homeStack);
-        display.remove();
-
-        // The removed display should have no focused stack and its home stack should never resume.
-        assertNull(display.getFocusedRootTask());
-        verify(homeStack, never()).resumeTopActivityUncheckedLocked(any(), any());
-    }
-
-    private Task createFullscreenStackWithSimpleActivityAt(DisplayContent display) {
-        final Task fullscreenStack = display.getDefaultTaskDisplayArea().createRootTask(
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, ON_TOP);
-        final Task fullscreenTask = new TaskBuilder(mAtm.mTaskSupervisor)
-                .setParentTask(fullscreenStack).build();
-        new ActivityBuilder(mAtm).setTask(fullscreenTask).build();
-        return fullscreenStack;
-    }
-
-    /**
-     * Verifies the correct activity is returned when querying the top running activity.
-     */
-    @Test
-    public void testTopRunningActivity() {
-        final DisplayContent display = mRootWindowContainer.getDefaultDisplay();
-        final KeyguardController keyguard = mSupervisor.getKeyguardController();
-        final Task stack = new TaskBuilder(mSupervisor).setCreateActivity(true).build();
-        final ActivityRecord activity = stack.getTopNonFinishingActivity();
-
-        // Create empty stack on top.
-        final Task emptyStack = new TaskBuilder(mSupervisor).build();
-
-        // Make sure the top running activity is not affected when keyguard is not locked.
-        assertTopRunningActivity(activity, display);
-
-        // Check to make sure activity not reported when it cannot show on lock and lock is on.
-        doReturn(true).when(keyguard).isKeyguardLocked();
-        assertEquals(activity, display.topRunningActivity());
-        assertNull(display.topRunningActivity(true /* considerKeyguardState */));
-
-        // Move stack with activity to top.
-        stack.moveToFront("testStackToFront");
-        assertEquals(stack, display.getFocusedRootTask());
-        assertEquals(activity, display.topRunningActivity());
-        assertNull(display.topRunningActivity(true /* considerKeyguardState */));
-
-        // Add activity that should be shown on the keyguard.
-        final ActivityRecord showWhenLockedActivity = new ActivityBuilder(mAtm)
-                .setTask(stack)
-                .setActivityFlags(FLAG_SHOW_WHEN_LOCKED)
-                .build();
-
-        // Ensure the show when locked activity is returned.
-        assertTopRunningActivity(showWhenLockedActivity, display);
-
-        // Move empty stack to front. The running activity in focusable stack which below the
-        // empty stack should be returned.
-        emptyStack.moveToFront("emptyStackToFront");
-        assertEquals(stack, display.getFocusedRootTask());
-        assertTopRunningActivity(showWhenLockedActivity, display);
-    }
-
-    private static void assertTopRunningActivity(ActivityRecord top, DisplayContent display) {
-        assertEquals(top, display.topRunningActivity());
-        assertEquals(top, display.topRunningActivity(true /* considerKeyguardState */));
-    }
-
-    /**
-     * This test enforces that alwaysOnTop stack is placed at proper position.
-     */
-    @Test
-    public void testAlwaysOnTopStackLocation() {
-        final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
-        final Task alwaysOnTopStack = taskDisplayArea.createRootTask(WINDOWING_MODE_FREEFORM,
-                ACTIVITY_TYPE_STANDARD, true /* onTop */);
-        final ActivityRecord activity = new ActivityBuilder(mAtm)
-                .setTask(alwaysOnTopStack).build();
-        alwaysOnTopStack.setAlwaysOnTop(true);
-        taskDisplayArea.positionChildAt(POSITION_TOP, alwaysOnTopStack,
-                false /* includingParents */);
-        assertTrue(alwaysOnTopStack.isAlwaysOnTop());
-        // Ensure always on top state is synced to the children of the stack.
-        assertTrue(alwaysOnTopStack.getTopNonFinishingActivity().isAlwaysOnTop());
-        assertEquals(alwaysOnTopStack, taskDisplayArea.getTopRootTask());
-
-        final Task pinnedStack = taskDisplayArea.createRootTask(
-                WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
-        assertEquals(pinnedStack, taskDisplayArea.getRootPinnedTask());
-        assertEquals(pinnedStack, taskDisplayArea.getTopRootTask());
-
-        final Task anotherAlwaysOnTopStack = taskDisplayArea.createRootTask(
-                WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD, true /* onTop */);
-        anotherAlwaysOnTopStack.setAlwaysOnTop(true);
-        taskDisplayArea.positionChildAt(POSITION_TOP, anotherAlwaysOnTopStack,
-                false /* includingParents */);
-        assertTrue(anotherAlwaysOnTopStack.isAlwaysOnTop());
-        int topPosition = taskDisplayArea.getRootTaskCount() - 1;
-        // Ensure the new alwaysOnTop stack is put below the pinned stack, but on top of the
-        // existing alwaysOnTop stack.
-        assertEquals(topPosition - 1, getTaskIndexOf(taskDisplayArea, anotherAlwaysOnTopStack));
-
-        final Task nonAlwaysOnTopStack = taskDisplayArea.createRootTask(
-                WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD, true /* onTop */);
-        assertEquals(taskDisplayArea, nonAlwaysOnTopStack.getDisplayArea());
-        topPosition = taskDisplayArea.getRootTaskCount() - 1;
-        // Ensure the non-alwaysOnTop stack is put below the three alwaysOnTop stacks, but above the
-        // existing other non-alwaysOnTop stacks.
-        assertEquals(topPosition - 3, getTaskIndexOf(taskDisplayArea, nonAlwaysOnTopStack));
-
-        anotherAlwaysOnTopStack.setAlwaysOnTop(false);
-        taskDisplayArea.positionChildAt(POSITION_TOP, anotherAlwaysOnTopStack,
-                false /* includingParents */);
-        assertFalse(anotherAlwaysOnTopStack.isAlwaysOnTop());
-        // Ensure, when always on top is turned off for a stack, the stack is put just below all
-        // other always on top stacks.
-        assertEquals(topPosition - 2, getTaskIndexOf(taskDisplayArea, anotherAlwaysOnTopStack));
-        anotherAlwaysOnTopStack.setAlwaysOnTop(true);
-
-        // Ensure always on top state changes properly when windowing mode changes.
-        anotherAlwaysOnTopStack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
-        assertFalse(anotherAlwaysOnTopStack.isAlwaysOnTop());
-        assertEquals(topPosition - 2, getTaskIndexOf(taskDisplayArea, anotherAlwaysOnTopStack));
-        anotherAlwaysOnTopStack.setWindowingMode(WINDOWING_MODE_FREEFORM);
-        assertTrue(anotherAlwaysOnTopStack.isAlwaysOnTop());
-        assertEquals(topPosition - 1, getTaskIndexOf(taskDisplayArea, anotherAlwaysOnTopStack));
-
-        final Task dreamStack = taskDisplayArea.createRootTask(
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_DREAM, true /* onTop */);
-        assertEquals(taskDisplayArea, dreamStack.getDisplayArea());
-        assertTrue(dreamStack.isAlwaysOnTop());
-        topPosition = taskDisplayArea.getRootTaskCount() - 1;
-        // Ensure dream shows above all activities, including PiP
-        assertEquals(dreamStack, taskDisplayArea.getTopRootTask());
-        assertEquals(topPosition - 1, getTaskIndexOf(taskDisplayArea, pinnedStack));
-
-        final Task assistStack = taskDisplayArea.createRootTask(
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT, true /* onTop */);
-        assertEquals(taskDisplayArea, assistStack.getDisplayArea());
-        assertFalse(assistStack.isAlwaysOnTop());
-        topPosition = taskDisplayArea.getRootTaskCount() - 1;
-
-        // Ensure Assistant shows as a non-always-on-top activity when config_assistantOnTopOfDream
-        // is false and on top of everything when true.
-        final boolean isAssistantOnTop = mContext.getResources()
-                .getBoolean(com.android.internal.R.bool.config_assistantOnTopOfDream);
-        assertEquals(isAssistantOnTop ? topPosition : topPosition - 4,
-                getTaskIndexOf(taskDisplayArea, assistStack));
-    }
-
-    @Test
-    public void testRemoveRootTaskInWindowingModes() {
-        removeStackTests(() -> mRootWindowContainer.removeRootTasksInWindowingModes(
-                WINDOWING_MODE_FULLSCREEN));
-    }
-
-    @Test
-    public void testRemoveStackWithActivityTypes() {
-        removeStackTests(() -> mRootWindowContainer.removeRootTasksWithActivityTypes(
-                ACTIVITY_TYPE_STANDARD));
-    }
-
-    private void removeStackTests(Runnable runnable) {
-        final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
-        final Task stack1 = taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
-                ACTIVITY_TYPE_STANDARD, ON_TOP);
-        final Task stack2 = taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
-                ACTIVITY_TYPE_STANDARD, ON_TOP);
-        final Task stack3 = taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
-                ACTIVITY_TYPE_STANDARD, ON_TOP);
-        final Task stack4 = taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
-                ACTIVITY_TYPE_STANDARD, ON_TOP);
-        final Task task1 = new TaskBuilder(mAtm.mTaskSupervisor).setParentTask(stack1).build();
-        final Task task2 = new TaskBuilder(mAtm.mTaskSupervisor).setParentTask(stack2).build();
-        final Task task3 = new TaskBuilder(mAtm.mTaskSupervisor).setParentTask(stack3).build();
-        final Task task4 = new TaskBuilder(mAtm.mTaskSupervisor).setParentTask(stack4).build();
-
-        // Reordering stacks while removing stacks.
-        doAnswer(invocation -> {
-            taskDisplayArea.positionChildAt(POSITION_TOP, stack3, false /*includingParents*/);
-            return true;
-        }).when(mSupervisor).removeTask(eq(task4), anyBoolean(), anyBoolean(), any());
-
-        // Removing stacks from the display while removing stacks.
-        doAnswer(invocation -> {
-            taskDisplayArea.removeRootTask(stack2);
-            return true;
-        }).when(mSupervisor).removeTask(eq(task2), anyBoolean(), anyBoolean(), any());
-
-        runnable.run();
-        verify(mSupervisor).removeTask(eq(task4), anyBoolean(), anyBoolean(), any());
-        verify(mSupervisor).removeTask(eq(task3), anyBoolean(), anyBoolean(), any());
-        verify(mSupervisor).removeTask(eq(task2), anyBoolean(), anyBoolean(), any());
-        verify(mSupervisor).removeTask(eq(task1), anyBoolean(), anyBoolean(), any());
-    }
-}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
index 002859e..7c9ff79 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
@@ -38,6 +38,7 @@
 import android.app.ActivityOptions.SourceInfo;
 import android.app.WaitResult;
 import android.content.Intent;
+import android.os.IBinder;
 import android.os.SystemClock;
 import android.platform.test.annotations.Presubmit;
 import android.util.ArrayMap;
@@ -402,6 +403,26 @@
     }
 
     @Test
+    public void testConsecutiveLaunchNewTask() {
+        final IBinder launchCookie = mock(IBinder.class);
+        mTrampolineActivity.noDisplay = true;
+        mTrampolineActivity.mLaunchCookie = launchCookie;
+        onActivityLaunched(mTrampolineActivity);
+        final ActivityRecord activityOnNewTask = new ActivityBuilder(mAtm)
+                .setCreateTask(true)
+                .build();
+        mActivityMetricsLogger.notifyActivityLaunching(activityOnNewTask.intent,
+                mTrampolineActivity /* caller */);
+        notifyActivityLaunched(START_SUCCESS, activityOnNewTask);
+
+        transitToDrawnAndVerifyOnLaunchFinished(activityOnNewTask);
+        assertWithMessage("Trampoline's cookie must be transferred").that(
+                mTrampolineActivity.mLaunchCookie).isNull();
+        assertWithMessage("The last launch task has the transferred cookie").that(
+                activityOnNewTask.mLaunchCookie).isEqualTo(launchCookie);
+    }
+
+    @Test
     public void testConsecutiveLaunchOnDifferentDisplay() {
         onActivityLaunched(mTopActivity);
 
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 ce5fc40..678defe 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
@@ -405,7 +405,7 @@
     public void testGetAnimationTargets_taskContainsMultipleTasks() {
         // [DisplayContent] - [Task] -+- [Task1] - [ActivityRecord1] (opening, invisible)
         //                            +- [Task2] - [ActivityRecord2] (closing, visible)
-        final Task parentTask = createTaskStackOnDisplay(mDisplayContent);
+        final Task parentTask = createTask(mDisplayContent);
         final ActivityRecord activity1 = createActivityRecordWithParentTask(parentTask);
         activity1.setVisible(false);
         activity1.mVisibleRequested = true;
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 83aca5e..c3279bf 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
@@ -177,13 +177,13 @@
     }
 
     @Test
-    public void testCleanAppTransitionWhenTaskStackReparent() {
+    public void testCleanAppTransitionWhenRootTaskReparent() {
         // Create 2 displays & presume both display the state is ON for ready to display & animate.
         final DisplayContent dc1 = createNewDisplay(Display.STATE_ON);
         final DisplayContent dc2 = createNewDisplay(Display.STATE_ON);
 
-        final Task stack1 = createTaskStackOnDisplay(dc1);
-        final Task task1 = createTaskInStack(stack1, 0 /* userId */);
+        final Task rootTask1 = createTask(dc1);
+        final Task task1 = createTaskInRootTask(rootTask1, 0 /* userId */);
         final ActivityRecord activity1 = createNonAttachedActivityRecord(dc1);
         task1.addChild(activity1, 0);
 
@@ -198,8 +198,8 @@
         dc1.mOpeningApps.add(activity1);
         assertTrue(dc1.mOpeningApps.size() > 0);
 
-        // Move stack to another display.
-        stack1.reparent(dc2.getDefaultTaskDisplayArea(), true);
+        // Move root task to another display.
+        rootTask1.reparent(dc2.getDefaultTaskDisplayArea(), true);
 
         // Verify if token are cleared from both pending transition list in former display.
         assertFalse(dc1.mOpeningApps.contains(activity1));
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 33bcc5b..0afd39f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -16,10 +16,12 @@
 
 package com.android.server.wm;
 
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
 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.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+import static android.content.pm.ActivityInfo.FLAG_SHOW_WHEN_LOCKED;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
@@ -46,6 +48,7 @@
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
+import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
 import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
 import static android.view.WindowManager.LayoutParams.TYPE_SCREENSHOT;
 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
@@ -64,6 +67,7 @@
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
 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;
@@ -329,21 +333,6 @@
         assertEquals(startingWin, imeTarget);
     }
 
-    @UseTestDisplay(addAllCommonWindows = true)
-    @Test
-    public void testComputeImeTarget_placeImeToTheTargetRoot() {
-        ActivityRecord activity = createActivityRecord(mDisplayContent);
-
-        final WindowState startingWin = createWindow(null, TYPE_APPLICATION_STARTING, activity,
-                "startingWin");
-        startingWin.setHasSurface(true);
-        assertTrue(startingWin.canBeImeTarget());
-        DisplayArea.Tokens imeContainer = mDisplayContent.getImeContainer();
-
-        WindowState imeTarget = mDisplayContent.computeImeTarget(true /* updateImeTarget */);
-        verify(imeTarget.getRootDisplayArea()).placeImeContainer(imeContainer);
-    }
-
     @Test
     public void testUpdateImeParent_forceUpdateRelativeLayer() {
         final DisplayArea.Tokens imeContainer = mDisplayContent.getImeContainer();
@@ -364,29 +353,29 @@
     }
 
     /**
-     * This tests stack movement between displays and proper stack's, task's and app token's display
-     * container references updates.
+     * This tests root task movement between displays and proper root task's, task's and app token's
+     * display container references updates.
      */
     @Test
-    public void testMoveStackBetweenDisplays() {
+    public void testMoveRootTaskBetweenDisplays() {
         // Create a second display.
         final DisplayContent dc = createNewDisplay();
 
-        // Add stack with activity.
-        final Task stack = createTaskStackOnDisplay(dc);
-        assertEquals(dc.getDisplayId(), stack.getDisplayContent().getDisplayId());
-        assertEquals(dc, stack.getDisplayContent());
+        // Add root task with activity.
+        final Task rootTask = createTask(dc);
+        assertEquals(dc.getDisplayId(), rootTask.getDisplayContent().getDisplayId());
+        assertEquals(dc, rootTask.getDisplayContent());
 
-        final Task task = createTaskInStack(stack, 0 /* userId */);
+        final Task task = createTaskInRootTask(rootTask, 0 /* userId */);
         final ActivityRecord activity = createNonAttachedActivityRecord(dc);
         task.addChild(activity, 0);
         assertEquals(dc, task.getDisplayContent());
         assertEquals(dc, activity.getDisplayContent());
 
-        // Move stack to first display.
-        stack.reparent(mDisplayContent.getDefaultTaskDisplayArea(), true /* onTop */);
-        assertEquals(mDisplayContent.getDisplayId(), stack.getDisplayContent().getDisplayId());
-        assertEquals(mDisplayContent, stack.getDisplayContent());
+        // Move root task to first display.
+        rootTask.reparent(mDisplayContent.getDefaultTaskDisplayArea(), true /* onTop */);
+        assertEquals(mDisplayContent.getDisplayId(), rootTask.getDisplayContent().getDisplayId());
+        assertEquals(mDisplayContent, rootTask.getDisplayContent());
         assertEquals(mDisplayContent, task.getDisplayContent());
         assertEquals(mDisplayContent, activity.getDisplayContent());
     }
@@ -438,7 +427,7 @@
     }
 
     /**
-     * Tests tapping on a stack in different display results in window gaining focus.
+     * Tests tapping on a root task in different display results in window gaining focus.
      */
     @Test
     public void testInputEventBringsCorrectDisplayInFocus() {
@@ -446,16 +435,16 @@
         // Create a second display
         final DisplayContent dc1 = createNewDisplay();
 
-        // Add stack with activity.
-        final Task stack0 = createTaskStackOnDisplay(dc0);
-        final Task task0 = createTaskInStack(stack0, 0 /* userId */);
+        // Add root task with activity.
+        final Task rootTask0 = createTask(dc0);
+        final Task task0 = createTaskInRootTask(rootTask0, 0 /* userId */);
         final ActivityRecord activity = createNonAttachedActivityRecord(dc0);
         task0.addChild(activity, 0);
         dc0.configureDisplayPolicy();
         assertNotNull(dc0.mTapDetector);
 
-        final Task stack1 = createTaskStackOnDisplay(dc1);
-        final Task task1 = createTaskInStack(stack1, 0 /* userId */);
+        final Task rootTask1 = createTask(dc1);
+        final Task task1 = createTaskInRootTask(rootTask1, 0 /* userId */);
         final ActivityRecord activity1 = createNonAttachedActivityRecord(dc0);
         task1.addChild(activity1, 0);
         dc1.configureDisplayPolicy();
@@ -903,13 +892,13 @@
         final DisplayContent newDisplay = createNewDisplay();
 
         final WindowState appWin = createWindow(null, TYPE_APPLICATION, mDisplayContent, "appWin");
-        final Task stack = mDisplayContent.getTopRootTask();
-        final ActivityRecord activity = stack.topRunningActivity();
+        final Task rootTask = mDisplayContent.getTopRootTask();
+        final ActivityRecord activity = rootTask.topRunningActivity();
         doReturn(true).when(activity).shouldBeVisibleUnchecked();
 
         final WindowState appWin1 = createWindow(null, TYPE_APPLICATION, newDisplay, "appWin1");
-        final Task stack1 = newDisplay.getTopRootTask();
-        final ActivityRecord activity1 = stack1.topRunningActivity();
+        final Task rootTask1 = newDisplay.getTopRootTask();
+        final ActivityRecord activity1 = rootTask1.topRunningActivity();
         doReturn(true).when(activity1).shouldBeVisibleUnchecked();
         appWin.setHasSurface(true);
         appWin1.setHasSurface(true);
@@ -948,28 +937,28 @@
         dc.getDisplayRotation().setFixedToUserRotation(
                 IWindowManager.FIXED_TO_USER_ROTATION_DISABLED);
 
-        final Task stack = new TaskBuilder(mSupervisor)
+        final Task rootTask = new TaskBuilder(mSupervisor)
                 .setDisplay(dc)
                 .setCreateActivity(true)
                 .build();
-        doReturn(true).when(stack).isVisible();
+        doReturn(true).when(rootTask).isVisible();
 
-        final Task freeformStack = new TaskBuilder(mSupervisor)
+        final Task freeformRootTask = new TaskBuilder(mSupervisor)
                 .setDisplay(dc)
                 .setCreateActivity(true)
                 .setWindowingMode(WINDOWING_MODE_FREEFORM)
                 .build();
-        doReturn(true).when(freeformStack).isVisible();
-        freeformStack.getTopChild().setBounds(100, 100, 300, 400);
+        doReturn(true).when(freeformRootTask).isVisible();
+        freeformRootTask.getTopChild().setBounds(100, 100, 300, 400);
 
         assertTrue(dc.getDefaultTaskDisplayArea().isRootTaskVisible(WINDOWING_MODE_FREEFORM));
 
-        freeformStack.getTopNonFinishingActivity().setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
-        stack.getTopNonFinishingActivity().setOrientation(SCREEN_ORIENTATION_PORTRAIT);
+        freeformRootTask.getTopNonFinishingActivity().setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
+        rootTask.getTopNonFinishingActivity().setOrientation(SCREEN_ORIENTATION_PORTRAIT);
         assertEquals(SCREEN_ORIENTATION_PORTRAIT, dc.getOrientation());
 
-        stack.getTopNonFinishingActivity().setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
-        freeformStack.getTopNonFinishingActivity().setOrientation(SCREEN_ORIENTATION_PORTRAIT);
+        rootTask.getTopNonFinishingActivity().setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
+        freeformRootTask.getTopNonFinishingActivity().setOrientation(SCREEN_ORIENTATION_PORTRAIT);
         assertEquals(SCREEN_ORIENTATION_LANDSCAPE, dc.getOrientation());
     }
 
@@ -1267,6 +1256,42 @@
                 is(Configuration.ORIENTATION_PORTRAIT));
     }
 
+    @Test
+    public void testHybridRotationAnimation() {
+        final DisplayContent displayContent = mDefaultDisplay;
+        final WindowState statusBar = createWindow(null, TYPE_STATUS_BAR, "statusBar");
+        final WindowState navBar = createWindow(null, TYPE_NAVIGATION_BAR, "navBar");
+        final WindowState app = createWindow(null, TYPE_BASE_APPLICATION, "app");
+        final WindowState[] windows = { statusBar, navBar, app };
+        makeWindowVisible(windows);
+        final DisplayPolicy displayPolicy = displayContent.getDisplayPolicy();
+        displayPolicy.addWindowLw(statusBar, statusBar.mAttrs);
+        displayPolicy.addWindowLw(navBar, navBar.mAttrs);
+        final ScreenRotationAnimation rotationAnim = new ScreenRotationAnimation(displayContent,
+                displayContent.getRotation());
+        spyOn(rotationAnim);
+        // Assume that the display rotation is changed so it is frozen in preparation for animation.
+        doReturn(true).when(rotationAnim).hasScreenshot();
+        mWm.mDisplayFrozen = true;
+        displayContent.setRotationAnimation(rotationAnim);
+        // The fade rotation animation also starts to hide some non-app windows.
+        assertNotNull(displayContent.getFadeRotationAnimationController());
+        assertTrue(statusBar.isAnimating(PARENTS, ANIMATION_TYPE_FIXED_TRANSFORM));
+
+        for (WindowState w : windows) {
+            w.setOrientationChanging(true);
+        }
+        // The display only waits for the app window to unfreeze.
+        assertFalse(displayContent.waitForUnfreeze(statusBar));
+        assertFalse(displayContent.waitForUnfreeze(navBar));
+        assertTrue(displayContent.waitForUnfreeze(app));
+        // If all windows animated by fade rotation animation have done the orientation change,
+        // the animation controller should be cleared.
+        statusBar.setOrientationChanging(false);
+        navBar.setOrientationChanging(false);
+        assertNull(displayContent.getFadeRotationAnimationController());
+    }
+
     @UseTestDisplay(addWindows = { W_ACTIVITY, W_WALLPAPER, W_STATUS_BAR, W_NAVIGATION_BAR })
     @Test
     public void testApplyTopFixedRotationTransform() {
@@ -1275,6 +1300,7 @@
         doReturn(false).when(displayPolicy).navigationBarCanMove();
         displayPolicy.addWindowLw(mStatusBarWindow, mStatusBarWindow.mAttrs);
         displayPolicy.addWindowLw(mNavBarWindow, mNavBarWindow.mAttrs);
+        makeWindowVisible(mStatusBarWindow, mNavBarWindow);
         final Configuration config90 = new Configuration();
         mDisplayContent.computeScreenConfiguration(config90, ROTATION_90);
 
@@ -1297,7 +1323,7 @@
                 ROTATION_0 /* oldRotation */, ROTATION_90 /* newRotation */,
                 false /* forceUpdate */));
 
-        assertNotNull(mDisplayContent.getFixedRotationAnimationController());
+        assertNotNull(mDisplayContent.getFadeRotationAnimationController());
         assertTrue(mStatusBarWindow.getParent().isAnimating(WindowContainer.AnimationFlags.PARENTS,
                 ANIMATION_TYPE_FIXED_TRANSFORM));
         assertTrue(mNavBarWindow.getParent().isAnimating(WindowContainer.AnimationFlags.PARENTS,
@@ -1381,7 +1407,7 @@
         assertFalse(app.hasFixedRotationTransform());
         assertFalse(app2.hasFixedRotationTransform());
         assertEquals(config90.orientation, mDisplayContent.getConfiguration().orientation);
-        assertNull(mDisplayContent.getFixedRotationAnimationController());
+        assertNull(mDisplayContent.getFadeRotationAnimationController());
     }
 
     @Test
@@ -1660,66 +1686,6 @@
     }
 
     @Test
-    public void testGetOrCreateRootHomeTask_defaultDisplay() {
-        TaskDisplayArea defaultTaskDisplayArea = mWm.mRoot.getDefaultTaskDisplayArea();
-
-        // Remove the current home stack if it exists so a new one can be created below.
-        Task homeTask = defaultTaskDisplayArea.getRootHomeTask();
-        if (homeTask != null) {
-            defaultTaskDisplayArea.removeChild(homeTask);
-        }
-        assertNull(defaultTaskDisplayArea.getRootHomeTask());
-
-        assertNotNull(defaultTaskDisplayArea.getOrCreateRootHomeTask());
-    }
-
-    @Test
-    public void testGetOrCreateRootHomeTask_supportedSecondaryDisplay() {
-        DisplayContent display = createNewDisplay();
-        doReturn(true).when(display).supportsSystemDecorations();
-
-        // Remove the current home stack if it exists so a new one can be created below.
-        TaskDisplayArea taskDisplayArea = display.getDefaultTaskDisplayArea();
-        Task homeTask = taskDisplayArea.getRootHomeTask();
-        if (homeTask != null) {
-            taskDisplayArea.removeChild(homeTask);
-        }
-        assertNull(taskDisplayArea.getRootHomeTask());
-
-        assertNotNull(taskDisplayArea.getOrCreateRootHomeTask());
-    }
-
-    @Test
-    public void testGetOrCreateRootHomeTask_unsupportedSystemDecorations() {
-        DisplayContent display = createNewDisplay();
-        TaskDisplayArea taskDisplayArea = display.getDefaultTaskDisplayArea();
-        doReturn(false).when(display).supportsSystemDecorations();
-
-        assertNull(taskDisplayArea.getRootHomeTask());
-        assertNull(taskDisplayArea.getOrCreateRootHomeTask());
-    }
-
-    @Test
-    public void testGetOrCreateRootHomeTask_untrustedDisplay() {
-        DisplayContent display = createNewDisplay();
-        TaskDisplayArea taskDisplayArea = display.getDefaultTaskDisplayArea();
-        doReturn(false).when(display).isTrusted();
-
-        assertNull(taskDisplayArea.getRootHomeTask());
-        assertNull(taskDisplayArea.getOrCreateRootHomeTask());
-    }
-
-    @Test
-    public void testGetOrCreateRootHomeTask_dontMoveToTop() {
-        DisplayContent display = createNewDisplay();
-        display.mDontMoveToTop = true;
-        TaskDisplayArea taskDisplayArea = display.getDefaultTaskDisplayArea();
-
-        assertNull(taskDisplayArea.getRootHomeTask());
-        assertNull(taskDisplayArea.getOrCreateRootHomeTask());
-    }
-
-    @Test
     public void testValidWindowingLayer() {
         final SurfaceControl windowingLayer = mDisplayContent.getWindowingLayer();
         assertNotNull(windowingLayer);
@@ -1738,8 +1704,8 @@
     @Test
     public void testFindScrollCaptureTargetWindow_behindWindow() {
         DisplayContent display = createNewDisplay();
-        Task stack = createTaskStackOnDisplay(display);
-        Task task = createTaskInStack(stack, 0 /* userId */);
+        Task rootTask = createTask(display);
+        Task task = createTaskInRootTask(rootTask, 0 /* userId */);
         WindowState activityWindow = createAppWindow(task, TYPE_APPLICATION, "App Window");
         WindowState behindWindow = createWindow(null, TYPE_SCREENSHOT, display, "Screenshot");
 
@@ -1751,8 +1717,8 @@
     @Test
     public void testFindScrollCaptureTargetWindow_cantReceiveKeys() {
         DisplayContent display = createNewDisplay();
-        Task stack = createTaskStackOnDisplay(display);
-        Task task = createTaskInStack(stack, 0 /* userId */);
+        Task rootTask = createTask(display);
+        Task task = createTaskInRootTask(rootTask, 0 /* userId */);
         WindowState activityWindow = createAppWindow(task, TYPE_APPLICATION, "App Window");
         WindowState invisible = createWindow(null, TYPE_APPLICATION, "invisible");
         invisible.mViewVisibility = View.INVISIBLE;  // make canReceiveKeys return false
@@ -1765,8 +1731,8 @@
     @Test
     public void testFindScrollCaptureTargetWindow_taskId() {
         DisplayContent display = createNewDisplay();
-        Task stack = createTaskStackOnDisplay(display);
-        Task task = createTaskInStack(stack, 0 /* userId */);
+        Task rootTask = createTask(display);
+        Task task = createTaskInRootTask(rootTask, 0 /* userId */);
         WindowState window = createAppWindow(task, TYPE_APPLICATION, "App Window");
         WindowState behindWindow = createWindow(null, TYPE_SCREENSHOT, display, "Screenshot");
 
@@ -1777,8 +1743,8 @@
     @Test
     public void testFindScrollCaptureTargetWindow_taskIdCantReceiveKeys() {
         DisplayContent display = createNewDisplay();
-        Task stack = createTaskStackOnDisplay(display);
-        Task task = createTaskInStack(stack, 0 /* userId */);
+        Task rootTask = createTask(display);
+        Task task = createTaskInRootTask(rootTask, 0 /* userId */);
         WindowState window = createAppWindow(task, TYPE_APPLICATION, "App Window");
         window.mViewVisibility = View.INVISIBLE;  // make canReceiveKeys return false
         WindowState behindWindow = createWindow(null, TYPE_SCREENSHOT, display, "Screenshot");
@@ -1805,7 +1771,7 @@
     @Test
     public void testSetWindowingModeAtomicallyUpdatesWindoingModeAndDisplayWindowingMode() {
         final DisplayContent dc = createNewDisplay();
-        final Task stack = new TaskBuilder(mSupervisor)
+        final Task rootTask = new TaskBuilder(mSupervisor)
                 .setDisplay(dc)
                 .build();
         doAnswer(invocation -> {
@@ -1814,7 +1780,7 @@
             assertEquals(config.windowConfiguration.getWindowingMode(),
                     config.windowConfiguration.getDisplayWindowingMode());
             return null;
-        }).when(stack).onConfigurationChanged(any());
+        }).when(rootTask).onConfigurationChanged(any());
         dc.setWindowingMode(WINDOWING_MODE_FREEFORM);
         dc.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
     }
@@ -1974,6 +1940,205 @@
         assertEquals(new Rect(500, 0, 2000, 700), rotateBounds);
     }
 
+    /**
+     * Creates a TestDisplayContent using the constructor that takes in display width and height as
+     * parameters and validates that the newly-created TestDisplayContent's DisplayInfo and
+     * WindowConfiguration match the parameters passed into the constructor. Additionally, this test
+     * checks that device-specific overrides are not applied.
+     */
+    @Test
+    public void testCreateTestDisplayContentFromDimensions() {
+        final int displayWidth = 1000;
+        final int displayHeight = 2000;
+        final int windowingMode = WINDOWING_MODE_FULLSCREEN;
+        final boolean ignoreOrientationRequests = false;
+        final float fixedOrientationLetterboxRatio = 0;
+        final DisplayContent testDisplayContent = new TestDisplayContent.Builder(mAtm, displayWidth,
+                displayHeight).build();
+
+        // test display info
+        final DisplayInfo di = testDisplayContent.getDisplayInfo();
+        assertEquals(displayWidth, di.logicalWidth);
+        assertEquals(displayHeight, di.logicalHeight);
+        assertEquals(TestDisplayContent.DEFAULT_LOGICAL_DISPLAY_DENSITY, di.logicalDensityDpi);
+
+        // test configuration
+        final WindowConfiguration windowConfig = testDisplayContent.getConfiguration()
+                .windowConfiguration;
+        assertEquals(displayWidth, windowConfig.getBounds().width());
+        assertEquals(displayHeight, windowConfig.getBounds().height());
+        assertEquals(windowingMode, windowConfig.getWindowingMode());
+
+        // test misc display overrides
+        assertEquals(ignoreOrientationRequests, testDisplayContent.mIgnoreOrientationRequest);
+        assertEquals(fixedOrientationLetterboxRatio, mWm.getFixedOrientationLetterboxAspectRatio(),
+                0 /* delta */);
+    }
+
+    /**
+     * Creates a TestDisplayContent using the constructor that takes in a DisplayInfo as a parameter
+     * and validates that the newly-created TestDisplayContent's DisplayInfo and WindowConfiguration
+     * match the width, height, and density values set in the DisplayInfo passed as a parameter.
+     * Additionally, this test checks that device-specific overrides are not applied.
+     */
+    @Test
+    public void testCreateTestDisplayContentFromDisplayInfo() {
+        final int displayWidth = 1000;
+        final int displayHeight = 2000;
+        final int windowingMode = WINDOWING_MODE_FULLSCREEN;
+        final boolean ignoreOrientationRequests = false;
+        final float fixedOrientationLetterboxRatio = 0;
+        final DisplayInfo testDisplayInfo = new DisplayInfo();
+        mContext.getDisplay().getDisplayInfo(testDisplayInfo);
+        testDisplayInfo.logicalWidth = displayWidth;
+        testDisplayInfo.logicalHeight = displayHeight;
+        testDisplayInfo.logicalDensityDpi = TestDisplayContent.DEFAULT_LOGICAL_DISPLAY_DENSITY;
+        final DisplayContent testDisplayContent = new TestDisplayContent.Builder(mAtm,
+                testDisplayInfo).build();
+
+        // test display info
+        final DisplayInfo di = testDisplayContent.getDisplayInfo();
+        assertEquals(displayWidth, di.logicalWidth);
+        assertEquals(displayHeight, di.logicalHeight);
+        assertEquals(TestDisplayContent.DEFAULT_LOGICAL_DISPLAY_DENSITY, di.logicalDensityDpi);
+
+        // test configuration
+        final WindowConfiguration windowConfig = testDisplayContent.getConfiguration()
+                .windowConfiguration;
+        assertEquals(displayWidth, windowConfig.getBounds().width());
+        assertEquals(displayHeight, windowConfig.getBounds().height());
+        assertEquals(windowingMode, windowConfig.getWindowingMode());
+
+        // test misc display overrides
+        assertEquals(ignoreOrientationRequests, testDisplayContent.mIgnoreOrientationRequest);
+        assertEquals(fixedOrientationLetterboxRatio, mWm.getFixedOrientationLetterboxAspectRatio(),
+                0 /* delta */);
+    }
+
+    /**
+     * Verifies {@link DisplayContent#remove} should not resume home root task on the removing
+     * display.
+     */
+    @Test
+    public void testNotResumeHomeRootTaskOnRemovingDisplay() {
+        // Create a display which supports system decoration and allows reparenting root tasks to
+        // another display when the display is removed.
+        final DisplayContent display = new TestDisplayContent.Builder(
+                mAtm, 1000, 1500).setSystemDecorations(true).build();
+        doReturn(false).when(display).shouldDestroyContentOnRemove();
+
+        // Put home root task on the display.
+        final Task homeRootTask = new TaskBuilder(mSupervisor)
+                .setDisplay(display).setActivityType(ACTIVITY_TYPE_HOME).build();
+
+        // Put a finishing standard activity which will be reparented.
+        final Task rootTask = createTaskWithActivity(display.getDefaultTaskDisplayArea(),
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, ON_TOP, true /* twoLevelTask */);
+        rootTask.topRunningActivity().makeFinishingLocked();
+
+        clearInvocations(homeRootTask);
+        display.remove();
+
+        // The removed display should have no focused root task and its home root task should never
+        // resume.
+        assertNull(display.getFocusedRootTask());
+        verify(homeRootTask, never()).resumeTopActivityUncheckedLocked(any(), any());
+    }
+
+    /**
+     * Verifies the correct activity is returned when querying the top running activity.
+     */
+    @Test
+    public void testTopRunningActivity() {
+        final DisplayContent display = mRootWindowContainer.getDefaultDisplay();
+        final KeyguardController keyguard = mSupervisor.getKeyguardController();
+        final Task rootTask = new TaskBuilder(mSupervisor).setCreateActivity(true).build();
+        final ActivityRecord activity = rootTask.getTopNonFinishingActivity();
+
+        // Create empty root task on top.
+        final Task emptyRootTask = new TaskBuilder(mSupervisor).build();
+
+        // Make sure the top running activity is not affected when keyguard is not locked.
+        assertTopRunningActivity(activity, display);
+
+        // Check to make sure activity not reported when it cannot show on lock and lock is on.
+        doReturn(true).when(keyguard).isKeyguardLocked();
+        assertEquals(activity, display.topRunningActivity());
+        assertNull(display.topRunningActivity(true /* considerKeyguardState */));
+
+        // Move root task with activity to top.
+        rootTask.moveToFront("testRootTaskToFront");
+        assertEquals(rootTask, display.getFocusedRootTask());
+        assertEquals(activity, display.topRunningActivity());
+        assertNull(display.topRunningActivity(true /* considerKeyguardState */));
+
+        // Add activity that should be shown on the keyguard.
+        final ActivityRecord showWhenLockedActivity = new ActivityBuilder(mAtm)
+                .setTask(rootTask)
+                .setActivityFlags(FLAG_SHOW_WHEN_LOCKED)
+                .build();
+
+        // Ensure the show when locked activity is returned.
+        assertTopRunningActivity(showWhenLockedActivity, display);
+
+        // Move empty root task to front. The running activity in focusable root task which below
+        // the empty root task should be returned.
+        emptyRootTask.moveToFront("emptyRootTaskToFront");
+        assertEquals(rootTask, display.getFocusedRootTask());
+        assertTopRunningActivity(showWhenLockedActivity, display);
+    }
+
+    private static void assertTopRunningActivity(ActivityRecord top, DisplayContent display) {
+        assertEquals(top, display.topRunningActivity());
+        assertEquals(top, display.topRunningActivity(true /* considerKeyguardState */));
+    }
+
+    @Test
+    public void testRemoveRootTaskInWindowingModes() {
+        removeRootTaskTests(() -> mRootWindowContainer.removeRootTasksInWindowingModes(
+                WINDOWING_MODE_FULLSCREEN));
+    }
+
+    @Test
+    public void testRemoveRootTaskWithActivityTypes() {
+        removeRootTaskTests(() -> mRootWindowContainer.removeRootTasksWithActivityTypes(
+                ACTIVITY_TYPE_STANDARD));
+    }
+
+    private void removeRootTaskTests(Runnable runnable) {
+        final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
+        final Task rootTask1 = taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
+                ACTIVITY_TYPE_STANDARD, ON_TOP);
+        final Task rootTask2 = taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
+                ACTIVITY_TYPE_STANDARD, ON_TOP);
+        final Task rootTask3 = taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
+                ACTIVITY_TYPE_STANDARD, ON_TOP);
+        final Task rootTask4 = taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
+                ACTIVITY_TYPE_STANDARD, ON_TOP);
+        final Task task1 = new TaskBuilder(mAtm.mTaskSupervisor).setParentTask(rootTask1).build();
+        final Task task2 = new TaskBuilder(mAtm.mTaskSupervisor).setParentTask(rootTask2).build();
+        final Task task3 = new TaskBuilder(mAtm.mTaskSupervisor).setParentTask(rootTask3).build();
+        final Task task4 = new TaskBuilder(mAtm.mTaskSupervisor).setParentTask(rootTask4).build();
+
+        // Reordering root tasks while removing root tasks.
+        doAnswer(invocation -> {
+            taskDisplayArea.positionChildAt(POSITION_TOP, rootTask3, false /*includingParents*/);
+            return true;
+        }).when(mSupervisor).removeTask(eq(task4), anyBoolean(), anyBoolean(), any());
+
+        // Removing root tasks from the display while removing root tasks.
+        doAnswer(invocation -> {
+            taskDisplayArea.removeRootTask(rootTask2);
+            return true;
+        }).when(mSupervisor).removeTask(eq(task2), anyBoolean(), anyBoolean(), any());
+
+        runnable.run();
+        verify(mSupervisor).removeTask(eq(task4), anyBoolean(), anyBoolean(), any());
+        verify(mSupervisor).removeTask(eq(task3), anyBoolean(), anyBoolean(), any());
+        verify(mSupervisor).removeTask(eq(task2), anyBoolean(), anyBoolean(), any());
+        verify(mSupervisor).removeTask(eq(task1), anyBoolean(), anyBoolean(), any());
+    }
+
     private boolean isOptionsPanelAtRight(int displayId) {
         return (mWm.getPreferredOptionsPanelGravity(displayId) & Gravity.RIGHT) == Gravity.RIGHT;
     }
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsProviderTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsProviderTests.java
index 3e05c86..18a1caa 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsProviderTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsProviderTests.java
@@ -102,7 +102,7 @@
 
         SettingsEntry expectedSettings = new SettingsEntry();
         expectedSettings.mWindowingMode = WINDOWING_MODE_PINNED;
-        readAndAssertExpectedSettings(mPrimaryDisplay, expectedSettings);
+        readAndAssertExpectedSettings(mSecondaryDisplay, expectedSettings);
     }
 
     @Test
@@ -176,17 +176,17 @@
         // Expected settings should be empty because the default is to read from the primary vendor
         // settings location.
         SettingsEntry expectedSettings = new SettingsEntry();
-        assertEquals(expectedSettings, provider.getSettings(mPrimaryDisplay.getDisplayInfo()));
+        assertEquals(expectedSettings, provider.getSettings(mSecondaryDisplay.getDisplayInfo()));
 
         // Now switch to secondary vendor settings and assert proper settings.
         provider.setBaseSettingsStorage(mSecondaryVendorSettingsStorage);
         expectedSettings.mWindowingMode = WINDOWING_MODE_FULLSCREEN;
-        assertEquals(expectedSettings, provider.getSettings(mPrimaryDisplay.getDisplayInfo()));
+        assertEquals(expectedSettings, provider.getSettings(mSecondaryDisplay.getDisplayInfo()));
 
         // Switch back to primary and assert settings are empty again.
         provider.setBaseSettingsStorage(mDefaultVendorSettingsStorage);
         expectedSettings.mWindowingMode = WINDOWING_MODE_UNDEFINED;
-        assertEquals(expectedSettings, provider.getSettings(mPrimaryDisplay.getDisplayInfo()));
+        assertEquals(expectedSettings, provider.getSettings(mSecondaryDisplay.getDisplayInfo()));
     }
 
     @Test
@@ -204,7 +204,7 @@
         // take precedence over the vendor provided settings.
         SettingsEntry expectedSettings = new SettingsEntry();
         expectedSettings.mWindowingMode = WINDOWING_MODE_PINNED;
-        assertEquals(expectedSettings, provider.getSettings(mPrimaryDisplay.getDisplayInfo()));
+        assertEquals(expectedSettings, provider.getSettings(mSecondaryDisplay.getDisplayInfo()));
     }
 
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java
index 4e2697a..1bddd7b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java
@@ -17,8 +17,6 @@
 package com.android.server.wm;
 
 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.content.ClipDescription.MIMETYPE_APPLICATION_ACTIVITY;
 import static android.content.ClipDescription.MIMETYPE_APPLICATION_SHORTCUT;
 import static android.content.ClipDescription.MIMETYPE_APPLICATION_TASK;
@@ -124,9 +122,8 @@
      */
     private WindowState createDropTargetWindow(String name, int ownerId) {
         final ActivityRecord activity = createNonAttachedActivityRecord(mDisplayContent);
-        final Task stack = createTaskStackOnDisplay(
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, mDisplayContent);
-        final Task task = createTaskInStack(stack, ownerId);
+        final Task rootTask = createTask(mDisplayContent);
+        final Task task = createTaskInRootTask(rootTask, ownerId);
         task.addChild(activity, 0);
 
         // Use a new TestIWindow so we don't collect events for other windows
diff --git a/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java
index e9c356d..e9907c1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java
@@ -311,6 +311,41 @@
     }
 
     @Test
+    public void testPlaceImeContainer_hidesImeWhenParentChanges() {
+        setupImeWindow();
+        final DisplayArea.Tokens imeContainer = mDisplay.getImeContainer();
+        final WindowToken imeToken = tokenOfType(TYPE_INPUT_METHOD);
+        final WindowState firstActivityWin =
+                createWindow(null /* parent */, TYPE_APPLICATION_STARTING, mFirstActivity,
+                        "firstActivityWin");
+        spyOn(firstActivityWin);
+        final WindowState secondActivityWin =
+                createWindow(null /* parent */, TYPE_APPLICATION_STARTING, mSecondActivity,
+                        "secondActivityWin");
+        spyOn(secondActivityWin);
+
+        // firstActivityWin should be the target
+        doReturn(true).when(firstActivityWin).canBeImeTarget();
+        doReturn(false).when(secondActivityWin).canBeImeTarget();
+
+        WindowState imeTarget = mDisplay.computeImeTarget(true /* updateImeTarget */);
+        assertThat(imeTarget).isEqualTo(firstActivityWin);
+        verify(mFirstRoot).placeImeContainer(imeContainer);
+
+        // secondActivityWin should be the target
+        doReturn(false).when(firstActivityWin).canBeImeTarget();
+        doReturn(true).when(secondActivityWin).canBeImeTarget();
+
+        spyOn(mDisplay.mInputMethodWindow);
+        imeTarget = mDisplay.computeImeTarget(true /* updateImeTarget */);
+
+        assertThat(imeTarget).isEqualTo(secondActivityWin);
+        verify(mSecondRoot).placeImeContainer(imeContainer);
+        // verify hide() was called on InputMethodWindow.
+        verify(mDisplay.mInputMethodWindow).hide(false /* doAnimation */, false /* requestAnim */);
+    }
+
+    @Test
     public void testResizableFixedOrientationApp_fixedOrientationLetterboxing() {
         mFirstRoot.setIgnoreOrientationRequest(false /* ignoreOrientationRequest */);
         mSecondRoot.setIgnoreOrientationRequest(false /* ignoreOrientationRequest */);
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
index 925b6f9..6ffdb09 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
@@ -219,7 +219,7 @@
     }
 
     @Test
-    public void testAddTasksNoMultiple_expectNoTrim() {
+    public void testAddDocumentTasksNoMultiple_expectNoTrim() {
         // Add same non-multiple-task document tasks will remove the task (to re-add it) but not
         // trim it
         Task documentTask1 = createDocumentTask(".DocumentTask1");
@@ -262,7 +262,7 @@
     }
 
     @Test
-    public void testAddTasksMultipleDocumentTasks_expectNoTrim() {
+    public void testAddMultipleDocumentTasks_expectNoTrim() {
         // Add same multiple-task document tasks does not trim the first tasks
         Task documentTask1 = createDocumentTask(".DocumentTask1",
                 FLAG_ACTIVITY_MULTIPLE_TASK);
@@ -278,9 +278,33 @@
     }
 
     @Test
-    public void testAddTasksMultipleTasks_expectRemovedNoTrim() {
-        // Add multiple same-affinity non-document tasks, ensure that it removes the other task,
-        // but that it does not trim it
+    public void testAddTasks_expectRemovedNoTrim() {
+        // Add multiple same-affinity non-document tasks, ensure that it removes, but does not trim
+        // the other task
+        Task task1 = createTaskBuilder(".Task1")
+                .setFlags(FLAG_ACTIVITY_NEW_TASK)
+                .build();
+        Task task2 = createTaskBuilder(".Task1")
+                .setFlags(FLAG_ACTIVITY_NEW_TASK)
+                .build();
+        mRecentTasks.add(task1);
+        assertThat(mCallbacksRecorder.mAdded).hasSize(1);
+        assertThat(mCallbacksRecorder.mAdded).contains(task1);
+        assertThat(mCallbacksRecorder.mTrimmed).isEmpty();
+        assertThat(mCallbacksRecorder.mRemoved).isEmpty();
+        mCallbacksRecorder.clear();
+        mRecentTasks.add(task2);
+        assertThat(mCallbacksRecorder.mAdded).hasSize(1);
+        assertThat(mCallbacksRecorder.mAdded).contains(task2);
+        assertThat(mCallbacksRecorder.mTrimmed).isEmpty();
+        assertThat(mCallbacksRecorder.mRemoved).hasSize(1);
+        assertThat(mCallbacksRecorder.mRemoved).contains(task1);
+    }
+
+    @Test
+    public void testAddMultipleTasks_expectNotRemoved() {
+        // Add multiple same-affinity non-document tasks with MULTIPLE_TASK, ensure that it does not
+        // remove the other task
         Task task1 = createTaskBuilder(".Task1")
                 .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK)
                 .build();
@@ -297,8 +321,7 @@
         assertThat(mCallbacksRecorder.mAdded).hasSize(1);
         assertThat(mCallbacksRecorder.mAdded).contains(task2);
         assertThat(mCallbacksRecorder.mTrimmed).isEmpty();
-        assertThat(mCallbacksRecorder.mRemoved).hasSize(1);
-        assertThat(mCallbacksRecorder.mRemoved).contains(task1);
+        assertThat(mCallbacksRecorder.mRemoved).isEmpty();
     }
 
     @Test
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 7a4ad74..7d137bc 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
@@ -488,9 +488,9 @@
     @Test
     public void testIsAnimatingByRecents() {
         final ActivityRecord homeActivity = createHomeActivity();
-        final Task rootTask = createTaskStackOnDisplay(mDefaultDisplay);
-        final Task childTask = createTaskInStack(rootTask, 0 /* userId */);
-        final Task leafTask = createTaskInStack(childTask, 0 /* userId */);
+        final Task rootTask = createTask(mDefaultDisplay);
+        final Task childTask = createTaskInRootTask(rootTask, 0 /* userId */);
+        final Task leafTask = createTaskInRootTask(childTask, 0 /* userId */);
         spyOn(leafTask);
         doReturn(true).when(leafTask).isVisible();
 
@@ -556,11 +556,11 @@
     }
 
     @Test
-    public void testNotAttachNavigationBar_controlledByFixedRotationAnimation() {
+    public void testNotAttachNavigationBar_controlledByFadeRotationAnimation() {
         setupForShouldAttachNavBarDuringTransition();
-        FixedRotationAnimationController mockController =
-                mock(FixedRotationAnimationController.class);
-        doReturn(mockController).when(mDefaultDisplay).getFixedRotationAnimationController();
+        FadeRotationAnimationController mockController =
+                mock(FadeRotationAnimationController.class);
+        doReturn(mockController).when(mDefaultDisplay).getFadeRotationAnimationController();
         final ActivityRecord homeActivity = createHomeActivity();
         initializeRecentsAnimationController(mController, homeActivity);
         assertFalse(mController.isNavigationBarAttachedToApp());
diff --git a/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java
index 956c277..37da529 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java
@@ -578,10 +578,10 @@
     }
 
     @Test
-    public void testNonAppTarget_notSendNavBar_controlledByFixedRotation() throws Exception {
-        final FixedRotationAnimationController mockController =
-                mock(FixedRotationAnimationController.class);
-        doReturn(mockController).when(mDisplayContent).getFixedRotationAnimationController();
+    public void testNonAppTarget_notSendNavBar_controlledByFadeRotation() throws Exception {
+        final FadeRotationAnimationController mockController =
+                mock(FadeRotationAnimationController.class);
+        doReturn(mockController).when(mDisplayContent).getFadeRotationAnimationController();
         final int transit = TRANSIT_OLD_TASK_OPEN;
         setupForNonAppTargetNavBar(transit, true);
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
deleted file mode 100644
index 8388f2a..0000000
--- a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
+++ /dev/null
@@ -1,953 +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.server.wm;
-
-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.WINDOWING_MODE_FULLSCREEN;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
-import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
-import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
-import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE;
-import static android.view.Display.DEFAULT_DISPLAY;
-import static android.view.Display.TYPE_VIRTUAL;
-import static android.window.DisplayAreaOrganizer.FEATURE_VENDOR_FIRST;
-
-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.never;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.reset;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
-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.RootWindowContainer.MATCH_ATTACHED_TASK_OR_RECENT_TASKS_AND_RESTORE;
-import static com.android.server.wm.Task.ActivityState.STOPPED;
-import static com.android.server.wm.WindowContainer.POSITION_BOTTOM;
-
-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.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.contains;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.ArgumentMatchers.refEq;
-
-import android.app.ActivityOptions;
-import android.content.Intent;
-import android.content.pm.ActivityInfo;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.ResolveInfo;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.platform.test.annotations.Presubmit;
-import android.util.MergedConfiguration;
-import android.util.Pair;
-
-import androidx.test.filters.MediumTest;
-
-import com.android.internal.app.ResolverActivity;
-import com.android.server.wm.Task.ActivityState;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.function.Consumer;
-
-/**
- * Tests for the {@link RootWindowContainer} class.
- *
- * Build/Install/Run:
- *  atest WmTests:RootActivityContainerTests
- */
-@MediumTest
-@Presubmit
-@RunWith(WindowTestRunner.class)
-public class RootActivityContainerTests extends WindowTestsBase {
-
-    @Before
-    public void setUp() throws Exception {
-        doNothing().when(mAtm).updateSleepIfNeededLocked();
-    }
-
-    /**
-     * This test ensures that we do not try to restore a task based off an invalid task id. We
-     * should expect {@code null} to be returned in this case.
-     */
-    @Test
-    public void testRestoringInvalidTask() {
-        mRootWindowContainer.getDefaultDisplay().removeAllTasks();
-        Task task = mRootWindowContainer.anyTaskForId(0 /*taskId*/,
-                MATCH_ATTACHED_TASK_OR_RECENT_TASKS_AND_RESTORE, null, false /* onTop */);
-        assertNull(task);
-    }
-
-    /**
-     * This test ensures that an existing task in the pinned stack is moved to the fullscreen
-     * activity stack when a new task is added.
-     */
-    @Test
-    public void testReplacingTaskInPinnedStack() {
-        Task fullscreenTask = mRootWindowContainer.getDefaultTaskDisplayArea().createRootTask(
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
-        final ActivityRecord firstActivity = new ActivityBuilder(mAtm)
-                .setTask(fullscreenTask).build();
-        final ActivityRecord secondActivity = new ActivityBuilder(mAtm)
-                .setTask(fullscreenTask).build();
-
-        fullscreenTask.moveToFront("testReplacingTaskInPinnedStack");
-
-        // Ensure full screen stack has both tasks.
-        ensureStackPlacement(fullscreenTask, firstActivity, secondActivity);
-
-        // Move first activity to pinned stack.
-        mRootWindowContainer.moveActivityToPinnedRootTask(firstActivity, "initialMove");
-
-        final TaskDisplayArea taskDisplayArea = fullscreenTask.getDisplayArea();
-        Task pinnedStack = taskDisplayArea.getRootPinnedTask();
-        // Ensure a task has moved over.
-        ensureStackPlacement(pinnedStack, firstActivity);
-        ensureStackPlacement(fullscreenTask, secondActivity);
-
-        // Move second activity to pinned stack.
-        mRootWindowContainer.moveActivityToPinnedRootTask(secondActivity, "secondMove");
-
-        // Need to get stacks again as a new instance might have been created.
-        pinnedStack = taskDisplayArea.getRootPinnedTask();
-        fullscreenTask = taskDisplayArea.getRootTask(WINDOWING_MODE_FULLSCREEN,
-                ACTIVITY_TYPE_STANDARD);
-        // Ensure stacks have swapped tasks.
-        ensureStackPlacement(pinnedStack, secondActivity);
-        ensureStackPlacement(fullscreenTask, firstActivity);
-    }
-
-    @Test
-    public void testMovingBottomMostStackActivityToPinnedStack() {
-        final Task fullscreenTask = mRootWindowContainer.getDefaultTaskDisplayArea().createRootTask(
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
-        final ActivityRecord firstActivity = new ActivityBuilder(mAtm)
-                .setTask(fullscreenTask).build();
-        final Task task = firstActivity.getTask();
-
-        final ActivityRecord secondActivity = new ActivityBuilder(mAtm)
-                .setTask(fullscreenTask).build();
-
-        fullscreenTask.moveTaskToBack(task);
-
-        // Ensure full screen stack has both tasks.
-        ensureStackPlacement(fullscreenTask, firstActivity, secondActivity);
-        assertEquals(task.getTopMostActivity(), secondActivity);
-        firstActivity.setState(STOPPED, "testMovingBottomMostStackActivityToPinnedStack");
-
-
-        // Move first activity to pinned stack.
-        mRootWindowContainer.moveActivityToPinnedRootTask(secondActivity, "initialMove");
-
-        assertTrue(firstActivity.mRequestForceTransition);
-    }
-
-    private static void ensureStackPlacement(Task task, ActivityRecord... activities) {
-        final ArrayList<ActivityRecord> taskActivities = new ArrayList<>();
-
-        task.forAllActivities((Consumer<ActivityRecord>) taskActivities::add, false);
-
-        assertEquals("Expecting " + Arrays.deepToString(activities) + " got " + taskActivities,
-                taskActivities.size(), activities != null ? activities.length : 0);
-
-        if (activities == null) {
-            return;
-        }
-
-        for (ActivityRecord activity : activities) {
-            assertTrue(taskActivities.contains(activity));
-        }
-    }
-
-    @Test
-    public void testApplySleepTokens() {
-        final DisplayContent display = mRootWindowContainer.getDefaultDisplay();
-        final KeyguardController keyguard = mSupervisor.getKeyguardController();
-        final Task stack = new TaskBuilder(mSupervisor)
-                .setDisplay(display)
-                .setOnTop(false)
-                .build();
-
-        // Make sure we wake and resume in the case the display is turning on and the keyguard is
-        // not showing.
-        verifySleepTokenBehavior(display, keyguard, stack, true /*displaySleeping*/,
-                false /* displayShouldSleep */, true /* isFocusedStack */,
-                false /* keyguardShowing */, true /* expectWakeFromSleep */,
-                true /* expectResumeTopActivity */);
-
-        // Make sure we wake and don't resume when the display is turning on and the keyguard is
-        // showing.
-        verifySleepTokenBehavior(display, keyguard, stack, true /*displaySleeping*/,
-                false /* displayShouldSleep */, true /* isFocusedStack */,
-                true /* keyguardShowing */, true /* expectWakeFromSleep */,
-                false /* expectResumeTopActivity */);
-
-        // Make sure we wake and don't resume when the display is turning on and the keyguard is
-        // not showing as unfocused.
-        verifySleepTokenBehavior(display, keyguard, stack, true /*displaySleeping*/,
-                false /* displayShouldSleep */, false /* isFocusedStack */,
-                false /* keyguardShowing */, true /* expectWakeFromSleep */,
-                false /* expectResumeTopActivity */);
-
-        // Should not do anything if the display state hasn't changed.
-        verifySleepTokenBehavior(display, keyguard, stack, false /*displaySleeping*/,
-                false /* displayShouldSleep */, true /* isFocusedStack */,
-                false /* keyguardShowing */, false /* expectWakeFromSleep */,
-                false /* expectResumeTopActivity */);
-    }
-
-    private void verifySleepTokenBehavior(DisplayContent display, KeyguardController keyguard,
-            Task stack, boolean displaySleeping, boolean displayShouldSleep,
-            boolean isFocusedStack, boolean keyguardShowing, boolean expectWakeFromSleep,
-            boolean expectResumeTopActivity) {
-        reset(stack);
-
-        doReturn(displayShouldSleep).when(display).shouldSleep();
-        doReturn(displaySleeping).when(display).isSleeping();
-        doReturn(keyguardShowing).when(keyguard).isKeyguardOrAodShowing(anyInt());
-
-        doReturn(isFocusedStack).when(stack).isFocusedRootTaskOnDisplay();
-        doReturn(isFocusedStack ? stack : null).when(display).getFocusedRootTask();
-        TaskDisplayArea defaultTaskDisplayArea = display.getDefaultTaskDisplayArea();
-        doReturn(isFocusedStack ? stack : null).when(defaultTaskDisplayArea).getFocusedRootTask();
-        mRootWindowContainer.applySleepTokens(true);
-        verify(stack, times(expectWakeFromSleep ? 1 : 0)).awakeFromSleepingLocked();
-        verify(stack, times(expectResumeTopActivity ? 1 : 0)).resumeTopActivityUncheckedLocked(
-                null /* target */, null /* targetOptions */);
-    }
-
-    @Test
-    public void testAwakeFromSleepingWithAppConfiguration() {
-        final DisplayContent display = mRootWindowContainer.getDefaultDisplay();
-        final ActivityRecord activity = new ActivityBuilder(mAtm).setCreateTask(true).build();
-        activity.moveFocusableActivityToTop("test");
-        assertTrue(activity.getRootTask().isFocusedRootTaskOnDisplay());
-        ActivityRecordTests.setRotatedScreenOrientationSilently(activity);
-
-        final Configuration rotatedConfig = new Configuration();
-        display.computeScreenConfiguration(rotatedConfig, display.getDisplayRotation()
-                .rotationForOrientation(activity.getOrientation(), display.getRotation()));
-        assertNotEquals(activity.getConfiguration().orientation, rotatedConfig.orientation);
-        // Assume the activity was shown in different orientation. For example, the top activity is
-        // landscape and the portrait lockscreen is shown.
-        activity.setLastReportedConfiguration(
-                new MergedConfiguration(mAtm.getGlobalConfiguration(), rotatedConfig));
-        activity.setState(ActivityState.STOPPED, "sleep");
-
-        display.setIsSleeping(true);
-        doReturn(false).when(display).shouldSleep();
-        // Allow to resume when awaking.
-        setBooted(mAtm);
-        mRootWindowContainer.applySleepTokens(true);
-
-        // The display orientation should be changed by the activity so there is no relaunch.
-        verify(activity, never()).relaunchActivityLocked(anyBoolean());
-        assertEquals(rotatedConfig.orientation, display.getConfiguration().orientation);
-    }
-
-    /**
-     * Verifies that removal of activity with task and stack is done correctly.
-     */
-    @Test
-    public void testRemovingStackOnAppCrash() {
-        final TaskDisplayArea defaultTaskDisplayArea = mRootWindowContainer
-                .getDefaultTaskDisplayArea();
-        final int originalStackCount = defaultTaskDisplayArea.getRootTaskCount();
-        final Task stack = defaultTaskDisplayArea.createRootTask(
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
-        final ActivityRecord firstActivity = new ActivityBuilder(mAtm).setTask(stack).build();
-
-        assertEquals(originalStackCount + 1, defaultTaskDisplayArea.getRootTaskCount());
-
-        // Let's pretend that the app has crashed.
-        firstActivity.app.setThread(null);
-        mRootWindowContainer.finishTopCrashedActivities(firstActivity.app, "test");
-
-        // Verify that the stack was removed.
-        assertEquals(originalStackCount, defaultTaskDisplayArea.getRootTaskCount());
-    }
-
-    /**
-     * Verifies that removal of activities with task and stack is done correctly when there are
-     * several task display areas.
-     */
-    @Test
-    public void testRemovingStackOnAppCrash_multipleDisplayAreas() {
-        final TaskDisplayArea defaultTaskDisplayArea = mRootWindowContainer
-                .getDefaultTaskDisplayArea();
-        final int originalStackCount = defaultTaskDisplayArea.getRootTaskCount();
-        final Task stack = defaultTaskDisplayArea.createRootTask(
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
-        final ActivityRecord firstActivity = new ActivityBuilder(mAtm).setTask(stack).build();
-        assertEquals(originalStackCount + 1, defaultTaskDisplayArea.getRootTaskCount());
-
-        final DisplayContent dc = defaultTaskDisplayArea.getDisplayContent();
-        final TaskDisplayArea secondTaskDisplayArea = createTaskDisplayArea(
-                dc, mRootWindowContainer.mWmService, "TestTaskDisplayArea", FEATURE_VENDOR_FIRST);
-        final Task secondStack = secondTaskDisplayArea.createRootTask(
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
-        new ActivityBuilder(mAtm).setTask(secondStack).setUseProcess(firstActivity.app).build();
-        assertEquals(1, secondTaskDisplayArea.getRootTaskCount());
-
-        // Let's pretend that the app has crashed.
-        firstActivity.app.setThread(null);
-        mRootWindowContainer.finishTopCrashedActivities(firstActivity.app, "test");
-
-        // Verify that the stacks were removed.
-        assertEquals(originalStackCount, defaultTaskDisplayArea.getRootTaskCount());
-        assertEquals(0, secondTaskDisplayArea.getRootTaskCount());
-    }
-
-    @Test
-    public void testFocusability() {
-        final TaskDisplayArea defaultTaskDisplayArea = mRootWindowContainer
-                .getDefaultTaskDisplayArea();
-        final Task stack = defaultTaskDisplayArea.createRootTask(
-                WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
-        final ActivityRecord activity = new ActivityBuilder(mAtm).setTask(stack).build();
-
-        // Created stacks are focusable by default.
-        assertTrue(stack.isTopActivityFocusable());
-        assertTrue(activity.isFocusable());
-
-        // If the stack is made unfocusable, its activities should inherit that.
-        stack.setFocusable(false);
-        assertFalse(stack.isTopActivityFocusable());
-        assertFalse(activity.isFocusable());
-
-        final Task pinnedStack = defaultTaskDisplayArea.createRootTask(
-                WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
-        final ActivityRecord pinnedActivity = new ActivityBuilder(mAtm)
-                .setTask(pinnedStack).build();
-
-        // We should not be focusable when in pinned mode
-        assertFalse(pinnedStack.isTopActivityFocusable());
-        assertFalse(pinnedActivity.isFocusable());
-
-        // Add flag forcing focusability.
-        pinnedActivity.info.flags |= FLAG_ALWAYS_FOCUSABLE;
-
-        // Task with FLAG_ALWAYS_FOCUSABLE should be focusable.
-        assertTrue(pinnedStack.isTopActivityFocusable());
-        assertTrue(pinnedActivity.isFocusable());
-    }
-
-    /**
-     * Verify that split-screen primary stack will be chosen if activity is launched that targets
-     * split-screen secondary, but a matching existing instance is found on top of split-screen
-     * primary stack.
-     */
-    @Test
-    public void testSplitScreenPrimaryChosenWhenTopActivityLaunchedToSecondary() {
-        // Create primary split-screen stack with a task and an activity.
-        final Task primaryStack = mRootWindowContainer.getDefaultTaskDisplayArea()
-                .createRootTask(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD,
-                        true /* onTop */);
-        final Task task = new TaskBuilder(mSupervisor).setParentTask(primaryStack).build();
-        final ActivityRecord r = new ActivityBuilder(mAtm).setTask(task).build();
-
-        // Find a launch stack for the top activity in split-screen primary, while requesting
-        // split-screen secondary.
-        final ActivityOptions options = ActivityOptions.makeBasic();
-        options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY);
-        final Task result =
-                mRootWindowContainer.getLaunchRootTask(r, options, task, true /* onTop */);
-
-        // Assert that the primary stack is returned.
-        assertEquals(primaryStack, result);
-    }
-
-    /**
-     * Verify that home stack would be moved to front when the top activity is Recents.
-     */
-    @Test
-    public void testFindTaskToMoveToFrontWhenRecentsOnTop() {
-        // Create stack/task on default display.
-        final Task targetStack = new TaskBuilder(mSupervisor)
-                .setCreateActivity(true)
-                .setOnTop(false)
-                .build();
-        final Task targetTask = targetStack.getBottomMostTask();
-
-        // Create Recents on top of the display.
-        final Task stack = new TaskBuilder(mSupervisor)
-                .setCreateActivity(true)
-                .setActivityType(ACTIVITY_TYPE_RECENTS)
-                .build();
-
-        final String reason = "findTaskToMoveToFront";
-        mSupervisor.findTaskToMoveToFront(targetTask, 0, ActivityOptions.makeBasic(), reason,
-                false);
-
-        final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
-        verify(taskDisplayArea).moveHomeRootTaskToFront(contains(reason));
-    }
-
-    /**
-     * Verify that home stack won't be moved to front if the top activity on other display is
-     * Recents.
-     */
-    @Test
-    public void testFindTaskToMoveToFrontWhenRecentsOnOtherDisplay() {
-        // Create tasks on default display.
-        final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
-        final Task targetRootTask = taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
-                ACTIVITY_TYPE_STANDARD, false /* onTop */);
-        final Task targetTask = new TaskBuilder(mSupervisor).setParentTask(targetRootTask).build();
-
-        // Create Recents on secondary display.
-        final TestDisplayContent secondDisplay = addNewDisplayContentAt(
-                DisplayContent.POSITION_TOP);
-        final Task rootTask = secondDisplay.getDefaultTaskDisplayArea()
-                .createRootTask(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_RECENTS, true /* onTop */);
-        new ActivityBuilder(mAtm).setTask(rootTask).build();
-
-        final String reason = "findTaskToMoveToFront";
-        mSupervisor.findTaskToMoveToFront(targetTask, 0, ActivityOptions.makeBasic(), reason,
-                false);
-
-        verify(taskDisplayArea, never()).moveHomeRootTaskToFront(contains(reason));
-    }
-
-    /**
-     * Verify if a stack is not at the topmost position, it should be able to resume its activity if
-     * the stack is the top focused.
-     */
-    @Test
-    public void testResumeActivityWhenNonTopmostStackIsTopFocused() {
-        // Create a root task at bottom.
-        final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
-        final Task rootTask = spy(taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
-                ACTIVITY_TYPE_STANDARD, false /* onTop */));
-        final ActivityRecord activity = new ActivityBuilder(mAtm).setTask(rootTask).build();
-        taskDisplayArea.positionChildAt(POSITION_BOTTOM, rootTask, false /*includingParents*/);
-
-        // Assume the task is not at the topmost position (e.g. behind always-on-top stacks) but it
-        // is the current top focused task.
-        assertFalse(rootTask.isTopRootTaskInDisplayArea());
-        doReturn(rootTask).when(mRootWindowContainer).getTopDisplayFocusedRootTask();
-
-        // Use the task as target to resume.
-        mRootWindowContainer.resumeFocusedTasksTopActivities(
-                rootTask, activity, null /* targetOptions */);
-
-        // Verify the target task should resume its activity.
-        verify(rootTask, times(1)).resumeTopActivityUncheckedLocked(
-                eq(activity), eq(null /* targetOptions */));
-    }
-
-    /**
-     * Verify that home activity will be started on a display even if another display has a
-     * focusable activity.
-     */
-    @Test
-    public void testResumeFocusedStacksStartsHomeActivity_NoActivities() {
-        final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
-        taskDisplayArea.getRootHomeTask().removeIfPossible();
-        taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP);
-
-        doReturn(true).when(mRootWindowContainer).resumeHomeActivity(any(), any(), any());
-
-        mAtm.setBooted(true);
-
-        // Trigger resume on all displays
-        mRootWindowContainer.resumeFocusedTasksTopActivities();
-
-        // Verify that home activity was started on the default display
-        verify(mRootWindowContainer).resumeHomeActivity(any(), any(), eq(taskDisplayArea));
-    }
-
-    /**
-     * Verify that home activity will be started on a display even if another display has a
-     * focusable activity.
-     */
-    @Test
-    public void testResumeFocusedStacksStartsHomeActivity_ActivityOnSecondaryScreen() {
-        final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
-        taskDisplayArea.getRootHomeTask().removeIfPossible();
-        taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP);
-
-        // Create an activity on secondary display.
-        final TestDisplayContent secondDisplay = addNewDisplayContentAt(
-                DisplayContent.POSITION_TOP);
-        final Task rootTask = secondDisplay.getDefaultTaskDisplayArea().createRootTask(
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
-        new ActivityBuilder(mAtm).setTask(rootTask).build();
-
-        doReturn(true).when(mRootWindowContainer).resumeHomeActivity(any(), any(), any());
-
-        mAtm.setBooted(true);
-
-        // Trigger resume on all displays
-        mRootWindowContainer.resumeFocusedTasksTopActivities();
-
-        // Verify that home activity was started on the default display
-        verify(mRootWindowContainer).resumeHomeActivity(any(), any(), eq(taskDisplayArea));
-    }
-
-    /**
-     * Verify that a lingering transition is being executed in case the activity to be resumed is
-     * already resumed
-     */
-    @Test
-    public void testResumeActivityLingeringTransition() {
-        // Create a root task at top.
-        final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
-        final Task rootTask = spy(taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
-                ACTIVITY_TYPE_STANDARD, false /* onTop */));
-        final ActivityRecord activity = new ActivityBuilder(mAtm)
-                .setTask(rootTask).setOnTop(true).build();
-        activity.setState(ActivityState.RESUMED, "test");
-
-        // Assume the task is at the topmost position
-        assertTrue(rootTask.isTopRootTaskInDisplayArea());
-
-        // Use the task as target to resume.
-        mRootWindowContainer.resumeFocusedTasksTopActivities();
-
-        // Verify the lingering app transition is being executed because it's already resumed
-        verify(rootTask, times(1)).executeAppTransition(any());
-    }
-
-    @Test
-    public void testResumeActivityLingeringTransition_notExecuted() {
-        // Create a root task at bottom.
-        final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
-        final Task rootTask = spy(taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
-                ACTIVITY_TYPE_STANDARD, false /* onTop */));
-        final ActivityRecord activity = new ActivityBuilder(mAtm)
-                .setTask(rootTask).setOnTop(true).build();
-        activity.setState(ActivityState.RESUMED, "test");
-        taskDisplayArea.positionChildAt(POSITION_BOTTOM, rootTask, false /*includingParents*/);
-
-        // Assume the task is at the topmost position
-        assertFalse(rootTask.isTopRootTaskInDisplayArea());
-        doReturn(rootTask).when(mRootWindowContainer).getTopDisplayFocusedRootTask();
-
-        // Use the task as target to resume.
-        mRootWindowContainer.resumeFocusedTasksTopActivities();
-
-        // Verify the lingering app transition is being executed because it's already resumed
-        verify(rootTask, never()).executeAppTransition(any());
-    }
-
-    /**
-     * Tests that home activities can be started on the displays that supports system decorations.
-     */
-    @Test
-    public void testStartHomeOnAllDisplays() {
-        mockResolveHomeActivity(true /* primaryHome */, false /* forceSystemProvided */);
-        mockResolveSecondaryHomeActivity();
-
-        // Create secondary displays.
-        final TestDisplayContent secondDisplay =
-                new TestDisplayContent.Builder(mAtm, 1000, 1500)
-                        .setSystemDecorations(true).build();
-
-        doReturn(true).when(mRootWindowContainer)
-                .ensureVisibilityAndConfig(any(), anyInt(), anyBoolean(), anyBoolean());
-        doReturn(true).when(mRootWindowContainer).canStartHomeOnDisplayArea(any(), any(),
-                anyBoolean());
-
-        mRootWindowContainer.startHomeOnAllDisplays(0, "testStartHome");
-
-        assertTrue(mRootWindowContainer.getDefaultDisplay().getTopRootTask().isActivityTypeHome());
-        assertNotNull(secondDisplay.getTopRootTask());
-        assertTrue(secondDisplay.getTopRootTask().isActivityTypeHome());
-    }
-
-    /**
-     * Tests that home activities won't be started before booting when display added.
-     */
-    @Test
-    public void testNotStartHomeBeforeBoot() {
-        final int displayId = 1;
-        final boolean isBooting = mAtm.mAmInternal.isBooting();
-        final boolean isBooted = mAtm.mAmInternal.isBooted();
-        try {
-            mAtm.mAmInternal.setBooting(false);
-            mAtm.mAmInternal.setBooted(false);
-            mRootWindowContainer.onDisplayAdded(displayId);
-            verify(mRootWindowContainer, never()).startHomeOnDisplay(anyInt(), any(), anyInt());
-        } finally {
-            mAtm.mAmInternal.setBooting(isBooting);
-            mAtm.mAmInternal.setBooted(isBooted);
-        }
-    }
-
-    /**
-     * Tests whether home can be started if being instrumented.
-     */
-    @Test
-    public void testCanStartHomeWhenInstrumented() {
-        final ActivityInfo info = new ActivityInfo();
-        info.applicationInfo = new ApplicationInfo();
-        final WindowProcessController app = mock(WindowProcessController.class);
-        doReturn(app).when(mAtm).getProcessController(any(), anyInt());
-
-        // Can not start home if we don't want to start home while home is being instrumented.
-        doReturn(true).when(app).isInstrumenting();
-        final TaskDisplayArea defaultTaskDisplayArea = mRootWindowContainer
-                .getDefaultTaskDisplayArea();
-        assertFalse(mRootWindowContainer.canStartHomeOnDisplayArea(info, defaultTaskDisplayArea,
-                false /* allowInstrumenting*/));
-
-        // Can start home for other cases.
-        assertTrue(mRootWindowContainer.canStartHomeOnDisplayArea(info, defaultTaskDisplayArea,
-                true /* allowInstrumenting*/));
-
-        doReturn(false).when(app).isInstrumenting();
-        assertTrue(mRootWindowContainer.canStartHomeOnDisplayArea(info, defaultTaskDisplayArea,
-                false /* allowInstrumenting*/));
-        assertTrue(mRootWindowContainer.canStartHomeOnDisplayArea(info, defaultTaskDisplayArea,
-                true /* allowInstrumenting*/));
-    }
-
-    /**
-     * Tests that secondary home activity should not be resolved if device is still locked.
-     */
-    @Test
-    public void testStartSecondaryHomeOnDisplayWithUserKeyLocked() {
-        // Create secondary displays.
-        final TestDisplayContent secondDisplay =
-                new TestDisplayContent.Builder(mAtm, 1000, 1500)
-                        .setSystemDecorations(true).build();
-
-        // Use invalid user id to let StorageManager.isUserKeyUnlocked() return false.
-        final int currentUser = mRootWindowContainer.mCurrentUser;
-        mRootWindowContainer.mCurrentUser = -1;
-
-        mRootWindowContainer.startHomeOnDisplay(0 /* userId */, "testStartSecondaryHome",
-                secondDisplay.mDisplayId, true /* allowInstrumenting */, true /* fromHomeKey */);
-
-        try {
-            verify(mRootWindowContainer, never()).resolveSecondaryHomeActivity(anyInt(), any());
-        } finally {
-            mRootWindowContainer.mCurrentUser = currentUser;
-        }
-    }
-
-    /**
-     * Tests that secondary home activity should not be resolved if display does not support system
-     * decorations.
-     */
-    @Test
-    public void testStartSecondaryHomeOnDisplayWithoutSysDecorations() {
-        // Create secondary displays.
-        final TestDisplayContent secondDisplay =
-                new TestDisplayContent.Builder(mAtm, 1000, 1500)
-                        .setSystemDecorations(false).build();
-
-        mRootWindowContainer.startHomeOnDisplay(0 /* userId */, "testStartSecondaryHome",
-                secondDisplay.mDisplayId, true /* allowInstrumenting */, true /* fromHomeKey */);
-
-        verify(mRootWindowContainer, never()).resolveSecondaryHomeActivity(anyInt(), any());
-    }
-
-    /**
-     * Tests that when starting {@link #ResolverActivity} for home, it should use the standard
-     * activity type (in a new stack) so the order of back stack won't be broken.
-     */
-    @Test
-    public void testStartResolverActivityForHome() {
-        final ActivityInfo info = new ActivityInfo();
-        info.applicationInfo = new ApplicationInfo();
-        info.applicationInfo.packageName = "android";
-        info.name = ResolverActivity.class.getName();
-        doReturn(info).when(mRootWindowContainer).resolveHomeActivity(anyInt(), any());
-
-        mRootWindowContainer.startHomeOnDisplay(0 /* userId */, "test", DEFAULT_DISPLAY);
-        final ActivityRecord resolverActivity = mRootWindowContainer.topRunningActivity();
-
-        assertEquals(info, resolverActivity.info);
-        assertEquals(ACTIVITY_TYPE_STANDARD, resolverActivity.getRootTask().getActivityType());
-    }
-
-    /**
-     * Tests that secondary home should be selected if primary home not set.
-     */
-    @Test
-    public void testResolveSecondaryHomeActivityWhenPrimaryHomeNotSet() {
-        // Setup: primary home not set.
-        final Intent primaryHomeIntent = mAtm.getHomeIntent();
-        final ActivityInfo aInfoPrimary = new ActivityInfo();
-        aInfoPrimary.name = ResolverActivity.class.getName();
-        doReturn(aInfoPrimary).when(mRootWindowContainer).resolveHomeActivity(anyInt(),
-                refEq(primaryHomeIntent));
-        // Setup: set secondary home.
-        mockResolveHomeActivity(false /* primaryHome */, false /* forceSystemProvided */);
-
-        // Run the test.
-        final Pair<ActivityInfo, Intent> resolvedInfo = mRootWindowContainer
-                .resolveSecondaryHomeActivity(0 /* userId */, mock(TaskDisplayArea.class));
-        final ActivityInfo aInfoSecondary = getFakeHomeActivityInfo(false /* primaryHome*/);
-        assertEquals(aInfoSecondary.name, resolvedInfo.first.name);
-        assertEquals(aInfoSecondary.applicationInfo.packageName,
-                resolvedInfo.first.applicationInfo.packageName);
-    }
-
-    /**
-     * Tests that the default secondary home activity is always picked when it is in forced by
-     * config_useSystemProvidedLauncherForSecondary.
-     */
-    @Test
-    public void testResolveSecondaryHomeActivityForced() {
-        // SetUp: set primary home.
-        mockResolveHomeActivity(true /* primaryHome */, false /* forceSystemProvided */);
-        // SetUp: set secondary home and force it.
-        mockResolveHomeActivity(false /* primaryHome */, true /* forceSystemProvided */);
-        final Intent secondaryHomeIntent =
-                mAtm.getSecondaryHomeIntent(null /* preferredPackage */);
-        final List<ResolveInfo> resolutions = new ArrayList<>();
-        final ResolveInfo resolveInfo = new ResolveInfo();
-        final ActivityInfo aInfoSecondary = getFakeHomeActivityInfo(false /* primaryHome*/);
-        resolveInfo.activityInfo = aInfoSecondary;
-        resolutions.add(resolveInfo);
-        doReturn(resolutions).when(mRootWindowContainer).resolveActivities(anyInt(),
-                refEq(secondaryHomeIntent));
-        doReturn(true).when(mRootWindowContainer).canStartHomeOnDisplayArea(any(), any(),
-                anyBoolean());
-
-        // Run the test.
-        final Pair<ActivityInfo, Intent> resolvedInfo = mRootWindowContainer
-                .resolveSecondaryHomeActivity(0 /* userId */, mock(TaskDisplayArea.class));
-        assertEquals(aInfoSecondary.name, resolvedInfo.first.name);
-        assertEquals(aInfoSecondary.applicationInfo.packageName,
-                resolvedInfo.first.applicationInfo.packageName);
-    }
-
-    /**
-     * Tests that secondary home should be selected if primary home not support secondary displays
-     * or there is no matched activity in the same package as selected primary home.
-     */
-    @Test
-    public void testResolveSecondaryHomeActivityWhenPrimaryHomeNotSupportMultiDisplay() {
-        // Setup: there is no matched activity in the same package as selected primary home.
-        mockResolveHomeActivity(true /* primaryHome */, false /* forceSystemProvided */);
-        final List<ResolveInfo> resolutions = new ArrayList<>();
-        doReturn(resolutions).when(mRootWindowContainer).resolveActivities(anyInt(), any());
-        // Setup: set secondary home.
-        mockResolveHomeActivity(false /* primaryHome */, false /* forceSystemProvided */);
-
-        // Run the test.
-        final Pair<ActivityInfo, Intent> resolvedInfo = mRootWindowContainer
-                .resolveSecondaryHomeActivity(0 /* userId */, mock(TaskDisplayArea.class));
-        final ActivityInfo aInfoSecondary = getFakeHomeActivityInfo(false /* primaryHome*/);
-        assertEquals(aInfoSecondary.name, resolvedInfo.first.name);
-        assertEquals(aInfoSecondary.applicationInfo.packageName,
-                resolvedInfo.first.applicationInfo.packageName);
-    }
-    /**
-     * Tests that primary home activity should be selected if it already support secondary displays.
-     */
-    @Test
-    public void testResolveSecondaryHomeActivityWhenPrimaryHomeSupportMultiDisplay() {
-        // SetUp: set primary home.
-        mockResolveHomeActivity(true /* primaryHome */, false /* forceSystemProvided */);
-        // SetUp: put primary home info on 2nd item
-        final List<ResolveInfo> resolutions = new ArrayList<>();
-        final ResolveInfo infoFake1 = new ResolveInfo();
-        infoFake1.activityInfo = new ActivityInfo();
-        infoFake1.activityInfo.name = "fakeActivity1";
-        infoFake1.activityInfo.applicationInfo = new ApplicationInfo();
-        infoFake1.activityInfo.applicationInfo.packageName = "fakePackage1";
-        final ResolveInfo infoFake2 = new ResolveInfo();
-        final ActivityInfo aInfoPrimary = getFakeHomeActivityInfo(true /* primaryHome */);
-        infoFake2.activityInfo = aInfoPrimary;
-        resolutions.add(infoFake1);
-        resolutions.add(infoFake2);
-        doReturn(resolutions).when(mRootWindowContainer).resolveActivities(anyInt(), any());
-
-        doReturn(true).when(mRootWindowContainer).canStartHomeOnDisplayArea(any(), any(),
-                anyBoolean());
-
-        // Run the test.
-        final Pair<ActivityInfo, Intent> resolvedInfo = mRootWindowContainer
-                .resolveSecondaryHomeActivity(0 /* userId */, mock(TaskDisplayArea.class));
-        assertEquals(aInfoPrimary.name, resolvedInfo.first.name);
-        assertEquals(aInfoPrimary.applicationInfo.packageName,
-                resolvedInfo.first.applicationInfo.packageName);
-    }
-
-    /**
-     * Tests that the first one that matches should be selected if there are multiple activities.
-     */
-    @Test
-    public void testResolveSecondaryHomeActivityWhenOtherActivitySupportMultiDisplay() {
-        // SetUp: set primary home.
-        mockResolveHomeActivity(true /* primaryHome */, false /* forceSystemProvided */);
-        // Setup: prepare two eligible activity info.
-        final List<ResolveInfo> resolutions = new ArrayList<>();
-        final ResolveInfo infoFake1 = new ResolveInfo();
-        infoFake1.activityInfo = new ActivityInfo();
-        infoFake1.activityInfo.name = "fakeActivity1";
-        infoFake1.activityInfo.applicationInfo = new ApplicationInfo();
-        infoFake1.activityInfo.applicationInfo.packageName = "fakePackage1";
-        final ResolveInfo infoFake2 = new ResolveInfo();
-        infoFake2.activityInfo = new ActivityInfo();
-        infoFake2.activityInfo.name = "fakeActivity2";
-        infoFake2.activityInfo.applicationInfo = new ApplicationInfo();
-        infoFake2.activityInfo.applicationInfo.packageName = "fakePackage2";
-        resolutions.add(infoFake1);
-        resolutions.add(infoFake2);
-        doReturn(resolutions).when(mRootWindowContainer).resolveActivities(anyInt(), any());
-
-        doReturn(true).when(mRootWindowContainer).canStartHomeOnDisplayArea(any(), any(),
-                anyBoolean());
-
-        // Use the first one of matched activities in the same package as selected primary home.
-        final Pair<ActivityInfo, Intent> resolvedInfo = mRootWindowContainer
-                .resolveSecondaryHomeActivity(0 /* userId */, mock(TaskDisplayArea.class));
-
-        assertEquals(infoFake1.activityInfo.applicationInfo.packageName,
-                resolvedInfo.first.applicationInfo.packageName);
-        assertEquals(infoFake1.activityInfo.name, resolvedInfo.first.name);
-    }
-
-    /**
-     * Test that {@link RootWindowContainer#getLaunchRootTask} with the real caller id will get the
-     * expected stack when requesting the activity launch on the secondary display.
-     */
-    @Test
-    public void testGetLaunchStackWithRealCallerId() {
-        // Create a non-system owned virtual display.
-        final TestDisplayContent secondaryDisplay =
-                new TestDisplayContent.Builder(mAtm, 1000, 1500)
-                        .setType(TYPE_VIRTUAL).setOwnerUid(100).build();
-
-        // Create an activity with specify the original launch pid / uid.
-        final ActivityRecord r = new ActivityBuilder(mAtm).setLaunchedFromPid(200)
-                .setLaunchedFromUid(200).build();
-
-        // Simulate ActivityStarter to find a launch stack for requesting the activity to launch
-        // on the secondary display with realCallerId.
-        final ActivityOptions options = ActivityOptions.makeBasic();
-        options.setLaunchDisplayId(secondaryDisplay.mDisplayId);
-        options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN);
-        doReturn(true).when(mSupervisor).canPlaceEntityOnDisplay(secondaryDisplay.mDisplayId,
-                300 /* test realCallerPid */, 300 /* test realCallerUid */, r.info);
-        final Task result = mRootWindowContainer.getLaunchRootTask(r, options,
-                null /* task */, true /* onTop */, null, 300 /* test realCallerPid */,
-                300 /* test realCallerUid */);
-
-        // Assert that the stack is returned as expected.
-        assertNotNull(result);
-        assertEquals("The display ID of the stack should same as secondary display ",
-                secondaryDisplay.mDisplayId, result.getDisplayId());
-    }
-
-    @Test
-    public void testGetValidLaunchStackOnDisplayWithCandidateRootTask() {
-        // Create a root task with an activity on secondary display.
-        final TestDisplayContent secondaryDisplay = new TestDisplayContent.Builder(mAtm, 300,
-                600).build();
-        final Task task = new TaskBuilder(mSupervisor)
-                .setDisplay(secondaryDisplay).build();
-        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 stack = mRootWindowContainer.getValidLaunchRootTaskInTaskDisplayArea(
-                mRootWindowContainer.getDefaultTaskDisplayArea(), activity, task,
-                null /* options */, null /* launchParams */);
-        assertEquals(task, stack);
-    }
-
-    @Test
-    public void testSwitchUser_missingHomeRootTask() {
-        final Task fullscreenTask = mRootWindowContainer.getDefaultTaskDisplayArea().createRootTask(
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
-        doReturn(fullscreenTask).when(mRootWindowContainer).getTopDisplayFocusedRootTask();
-
-        final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
-        Task homeStack = taskDisplayArea.getRootHomeTask();
-        if (homeStack != null) {
-            homeStack.removeImmediately();
-        }
-        assertNull(taskDisplayArea.getRootHomeTask());
-
-        int currentUser = mRootWindowContainer.mCurrentUser;
-        int otherUser = currentUser + 1;
-
-        mRootWindowContainer.switchUser(otherUser, null);
-
-        assertNotNull(taskDisplayArea.getRootHomeTask());
-        assertEquals(taskDisplayArea.getTopRootTask(), taskDisplayArea.getRootHomeTask());
-    }
-
-    /**
-     * Mock {@link RootWindowContainer#resolveHomeActivity} for returning consistent activity
-     * info for test cases.
-     *
-     * @param primaryHome Indicate to use primary home intent as parameter, otherwise, use
-     *                    secondary home intent.
-     * @param forceSystemProvided Indicate to force using system provided home activity.
-     */
-    private void mockResolveHomeActivity(boolean primaryHome, boolean forceSystemProvided) {
-        ActivityInfo targetActivityInfo = getFakeHomeActivityInfo(primaryHome);
-        Intent targetIntent;
-        if (primaryHome) {
-            targetIntent = mAtm.getHomeIntent();
-        } else {
-            Resources resources = mContext.getResources();
-            spyOn(resources);
-            doReturn(targetActivityInfo.applicationInfo.packageName).when(resources).getString(
-                    com.android.internal.R.string.config_secondaryHomePackage);
-            doReturn(forceSystemProvided).when(resources).getBoolean(
-                    com.android.internal.R.bool.config_useSystemProvidedLauncherForSecondary);
-            targetIntent = mAtm.getSecondaryHomeIntent(null /* preferredPackage */);
-        }
-        doReturn(targetActivityInfo).when(mRootWindowContainer).resolveHomeActivity(anyInt(),
-                refEq(targetIntent));
-    }
-
-    /**
-     * Mock {@link RootWindowContainer#resolveSecondaryHomeActivity} for returning consistent
-     * activity info for test cases.
-     */
-    private void mockResolveSecondaryHomeActivity() {
-        final Intent secondaryHomeIntent = mAtm
-                .getSecondaryHomeIntent(null /* preferredPackage */);
-        final ActivityInfo aInfoSecondary = getFakeHomeActivityInfo(false);
-        doReturn(Pair.create(aInfoSecondary, secondaryHomeIntent)).when(mRootWindowContainer)
-                .resolveSecondaryHomeActivity(anyInt(), any());
-    }
-
-    private ActivityInfo getFakeHomeActivityInfo(boolean primaryHome) {
-        final ActivityInfo aInfo = new ActivityInfo();
-        aInfo.name = primaryHome ? "fakeHomeActivity" : "fakeSecondaryHomeActivity";
-        aInfo.applicationInfo = new ApplicationInfo();
-        aInfo.applicationInfo.packageName =
-                primaryHome ? "fakeHomePackage" : "fakeSecondaryHomePackage";
-        return  aInfo;
-    }
-}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java b/services/tests/wmtests/src/com/android/server/wm/RootTaskTests.java
similarity index 60%
rename from services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
rename to services/tests/wmtests/src/com/android/server/wm/RootTaskTests.java
index 3a7954b..748622b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootTaskTests.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * 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.
@@ -11,7 +11,7 @@
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
  */
 
 package com.android.server.wm;
@@ -27,12 +27,14 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
 import static android.content.pm.ActivityInfo.FLAG_RESUME_WHILE_PAUSING;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doCallRealMethod;
 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.spyOn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
 import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_FREE_RESIZE;
 import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_WINDOWING_MODE_RESIZE;
@@ -49,6 +51,8 @@
 import static com.android.server.wm.Task.TASK_VISIBILITY_VISIBLE;
 import static com.android.server.wm.Task.TASK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT;
 import static com.android.server.wm.TaskDisplayArea.getRootTaskAbove;
+import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN;
+import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
 import static com.android.server.wm.WindowContainer.POSITION_BOTTOM;
 import static com.android.server.wm.WindowContainer.POSITION_TOP;
 
@@ -56,26 +60,30 @@
 
 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.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.clearInvocations;
+import static org.mockito.Mockito.mock;
 
 import android.app.ActivityManager;
 import android.app.IApplicationThread;
+import android.app.WindowConfiguration;
 import android.content.ComponentName;
 import android.content.pm.ActivityInfo;
+import android.graphics.Rect;
 import android.os.Binder;
 import android.os.UserHandle;
 import android.platform.test.annotations.Presubmit;
 
 import androidx.test.filters.SmallTest;
 
-import com.android.server.wm.TaskDisplayArea.OnRootTaskOrderChangedListener;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -84,15 +92,16 @@
 import java.util.function.Consumer;
 
 /**
- * Tests for the {@link ActivityStack} class.
+ * Tests for the root {@link Task} behavior.
  *
  * Build/Install/Run:
- *  atest WmTests:ActivityStackTests
+ *  atest WmTests:RootTaskTests
  */
 @SmallTest
 @Presubmit
 @RunWith(WindowTestRunner.class)
-public class ActivityStackTests extends WindowTestsBase {
+public class RootTaskTests extends WindowTestsBase {
+
     private TaskDisplayArea mDefaultTaskDisplayArea;
 
     @Before
@@ -101,6 +110,172 @@
     }
 
     @Test
+    public void testRootTaskPositionChildAt() {
+        final Task rootTask = createTask(mDisplayContent);
+        final Task task1 = createTaskInRootTask(rootTask, 0 /* userId */);
+        final Task task2 = createTaskInRootTask(rootTask, 1 /* userId */);
+
+        // Current user root task should be moved to top.
+        rootTask.positionChildAt(WindowContainer.POSITION_TOP, task1, false /* includingParents */);
+        assertEquals(rootTask.mChildren.get(0), task2);
+        assertEquals(rootTask.mChildren.get(1), task1);
+
+        // Non-current user won't be moved to top.
+        rootTask.positionChildAt(WindowContainer.POSITION_TOP, task2, false /* includingParents */);
+        assertEquals(rootTask.mChildren.get(0), task2);
+        assertEquals(rootTask.mChildren.get(1), task1);
+
+        // Non-leaf task should be moved to top regardless of the user id.
+        createTaskInRootTask(task2, 0 /* userId */);
+        createTaskInRootTask(task2, 1 /* userId */);
+        rootTask.positionChildAt(WindowContainer.POSITION_TOP, task2, false /* includingParents */);
+        assertEquals(rootTask.mChildren.get(0), task1);
+        assertEquals(rootTask.mChildren.get(1), task2);
+    }
+
+    @Test
+    public void testClosingAppDifferentTaskOrientation() {
+        final ActivityRecord activity1 = createActivityRecord(mDisplayContent);
+        activity1.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
+
+        final ActivityRecord activity2 = createActivityRecord(mDisplayContent);
+        activity2.setOrientation(SCREEN_ORIENTATION_PORTRAIT);
+
+        final WindowContainer parent = activity1.getTask().getParent();
+        assertEquals(SCREEN_ORIENTATION_PORTRAIT, parent.getOrientation());
+        mDisplayContent.mClosingApps.add(activity2);
+        assertEquals(SCREEN_ORIENTATION_LANDSCAPE, parent.getOrientation());
+    }
+
+    @Test
+    public void testMoveTaskToBackDifferentTaskOrientation() {
+        final ActivityRecord activity1 = createActivityRecord(mDisplayContent);
+        activity1.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
+
+        final ActivityRecord activity2 = createActivityRecord(mDisplayContent);
+        activity2.setOrientation(SCREEN_ORIENTATION_PORTRAIT);
+
+        final WindowContainer parent = activity1.getTask().getParent();
+        assertEquals(SCREEN_ORIENTATION_PORTRAIT, parent.getOrientation());
+    }
+
+    @Test
+    public void testRootTaskRemoveImmediately() {
+        final Task rootTask = createTask(mDisplayContent);
+        final Task task = createTaskInRootTask(rootTask, 0 /* userId */);
+        assertEquals(rootTask, task.getRootTask());
+
+        // Remove root task and check if its child is also removed.
+        rootTask.removeImmediately();
+        assertNull(rootTask.getDisplayContent());
+        assertNull(task.getParent());
+    }
+
+    @Test
+    public void testRemoveContainer() {
+        final Task rootTask = createTask(mDisplayContent);
+        final Task task = createTaskInRootTask(rootTask, 0 /* userId */);
+
+        assertNotNull(rootTask);
+        assertNotNull(task);
+        rootTask.removeIfPossible();
+        // Assert that the container was removed.
+        assertNull(rootTask.getParent());
+        assertEquals(0, rootTask.getChildCount());
+        assertNull(rootTask.getDisplayContent());
+        assertNull(task.getDisplayContent());
+        assertNull(task.getParent());
+    }
+
+    @Test
+    public void testRemoveContainer_deferRemoval() {
+        final Task rootTask = createTask(mDisplayContent);
+        final Task task = createTaskInRootTask(rootTask, 0 /* userId */);
+
+        // Root task removal is deferred if one of its child is animating.
+        doReturn(true).when(rootTask).hasWindowsAlive();
+        doReturn(rootTask).when(task).getAnimatingContainer(
+                eq(TRANSITION | CHILDREN), anyInt());
+
+        rootTask.removeIfPossible();
+        // For the case of deferred removal the task controller will still be connected to its
+        // container until the root task window container is removed.
+        assertNotNull(rootTask.getParent());
+        assertNotEquals(0, rootTask.getChildCount());
+        assertNotNull(task);
+
+        rootTask.removeImmediately();
+        // After removing, the task will be isolated.
+        assertNull(task.getParent());
+        assertEquals(0, task.getChildCount());
+    }
+
+    @Test
+    public void testReparent() {
+        // Create first root task on primary display.
+        final Task rootTask1 = createTask(mDisplayContent);
+        final Task task1 = createTaskInRootTask(rootTask1, 0 /* userId */);
+
+        // Create second display and put second root task on it.
+        final DisplayContent dc = createNewDisplay();
+        final Task rootTask2 = createTask(dc);
+
+        // Reparent
+        clearInvocations(task1); // reset the number of onDisplayChanged for task.
+        rootTask1.reparent(dc.getDefaultTaskDisplayArea(), true /* onTop */);
+        assertEquals(dc, rootTask1.getDisplayContent());
+        final int stack1PositionInParent = rootTask1.getParent().mChildren.indexOf(rootTask1);
+        final int stack2PositionInParent = rootTask1.getParent().mChildren.indexOf(rootTask2);
+        assertEquals(stack1PositionInParent, stack2PositionInParent + 1);
+        verify(task1, times(1)).onDisplayChanged(any());
+    }
+
+    @Test
+    public void testTaskOutset() {
+        final Task task = createTask(mDisplayContent);
+        final int taskOutset = 10;
+        spyOn(task);
+        doReturn(taskOutset).when(task).getTaskOutset();
+        doReturn(true).when(task).inMultiWindowMode();
+
+        // Mock the resolved override windowing mode to non-fullscreen
+        final WindowConfiguration windowConfiguration =
+                task.getResolvedOverrideConfiguration().windowConfiguration;
+        spyOn(windowConfiguration);
+        doReturn(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY)
+                .when(windowConfiguration).getWindowingMode();
+
+        // Prevent adjust task dimensions
+        doNothing().when(task).adjustForMinimalTaskDimensions(any(), any(), any());
+
+        final Rect taskBounds = new Rect(200, 200, 800, 1000);
+        // Update surface position and size by the given bounds.
+        task.setBounds(taskBounds);
+
+        assertEquals(taskBounds.width() + 2 * taskOutset, task.getLastSurfaceSize().x);
+        assertEquals(taskBounds.height() + 2 * taskOutset, task.getLastSurfaceSize().y);
+        assertEquals(taskBounds.left - taskOutset, task.getLastSurfacePosition().x);
+        assertEquals(taskBounds.top - taskOutset, task.getLastSurfacePosition().y);
+    }
+
+    @Test
+    public void testActivityAndTaskGetsProperType() {
+        final Task task1 = new TaskBuilder(mSupervisor).build();
+        ActivityRecord activity1 = createNonAttachedActivityRecord(mDisplayContent);
+
+        // First activity should become standard
+        task1.addChild(activity1, 0);
+        assertEquals(WindowConfiguration.ACTIVITY_TYPE_STANDARD, activity1.getActivityType());
+        assertEquals(WindowConfiguration.ACTIVITY_TYPE_STANDARD, task1.getActivityType());
+
+        // Second activity should also become standard
+        ActivityRecord activity2 = createNonAttachedActivityRecord(mDisplayContent);
+        task1.addChild(activity2, WindowContainer.POSITION_TOP);
+        assertEquals(WindowConfiguration.ACTIVITY_TYPE_STANDARD, activity2.getActivityType());
+        assertEquals(WindowConfiguration.ACTIVITY_TYPE_STANDARD, task1.getActivityType());
+    }
+
+    @Test
     public void testResumedActivity() {
         final ActivityRecord r = new ActivityBuilder(mAtm).setCreateTask(true).build();
         final Task task = r.getTask();
@@ -113,40 +288,40 @@
 
     @Test
     public void testResumedActivityFromTaskReparenting() {
-        final Task parentTask = new TaskBuilder(mSupervisor).setOnTop(true).build();
+        final Task rootTask = new TaskBuilder(mSupervisor).setOnTop(true).build();
         final ActivityRecord r = new ActivityBuilder(mAtm)
-                .setCreateTask(true).setParentTask(parentTask).build();
+                .setCreateTask(true).setParentTask(rootTask).build();
         final Task task = r.getTask();
-        // Ensure moving task between two stacks updates resumed activity
+        // Ensure moving task between two root tasks updates resumed activity
         r.setState(RESUMED, "testResumedActivityFromTaskReparenting");
-        assertEquals(r, parentTask.getResumedActivity());
+        assertEquals(r, rootTask.getResumedActivity());
 
-        final Task destStack = new TaskBuilder(mSupervisor).setOnTop(true).build();
-        task.reparent(destStack, true /* toTop */, REPARENT_KEEP_ROOT_TASK_AT_FRONT,
+        final Task destRootTask = new TaskBuilder(mSupervisor).setOnTop(true).build();
+        task.reparent(destRootTask, true /* toTop */, REPARENT_KEEP_ROOT_TASK_AT_FRONT,
                 false /* animate */, true /* deferResume*/,
                 "testResumedActivityFromTaskReparenting");
 
-        assertNull(parentTask.getResumedActivity());
-        assertEquals(r, destStack.getResumedActivity());
+        assertNull(rootTask.getResumedActivity());
+        assertEquals(r, destRootTask.getResumedActivity());
     }
 
     @Test
     public void testResumedActivityFromActivityReparenting() {
-        final Task parentTask = new TaskBuilder(mSupervisor).setOnTop(true).build();
+        final Task rootTask = new TaskBuilder(mSupervisor).setOnTop(true).build();
         final ActivityRecord r = new ActivityBuilder(mAtm)
-                .setCreateTask(true).setParentTask(parentTask).build();
+                .setCreateTask(true).setParentTask(rootTask).build();
         final Task task = r.getTask();
-        // Ensure moving task between two stacks updates resumed activity
+        // Ensure moving task between two root tasks updates resumed activity
         r.setState(RESUMED, "testResumedActivityFromActivityReparenting");
-        assertEquals(r, parentTask.getResumedActivity());
+        assertEquals(r, rootTask.getResumedActivity());
 
-        final Task destStack = new TaskBuilder(mSupervisor).setOnTop(true).build();
-        task.reparent(destStack, true /*toTop*/, REPARENT_MOVE_ROOT_TASK_TO_FRONT,
+        final Task destRootTask = new TaskBuilder(mSupervisor).setOnTop(true).build();
+        task.reparent(destRootTask, true /*toTop*/, REPARENT_MOVE_ROOT_TASK_TO_FRONT,
                 false /* animate */, false /* deferResume*/,
                 "testResumedActivityFromActivityReparenting");
 
-        assertNull(parentTask.getResumedActivity());
-        assertEquals(r, destStack.getResumedActivity());
+        assertNull(rootTask.getResumedActivity());
+        assertEquals(r, destRootTask.getResumedActivity());
     }
 
     @Test
@@ -155,7 +330,7 @@
         // We're testing an edge case here where we have primary + fullscreen rather than secondary.
         organizer.setMoveToSecondaryOnEnter(false);
 
-        // Create primary splitscreen stack.
+        // Create primary splitscreen root task.
         final Task primarySplitScreen = new TaskBuilder(mAtm.mTaskSupervisor)
                 .setParentTask(organizer.mPrimary)
                 .setOnTop(true)
@@ -168,7 +343,7 @@
         primarySplitScreen.moveToBack("testPrimarySplitScreenToFullscreenWhenMovedToBack",
                 null /* task */);
 
-        // Assert that stack is at the bottom.
+        // Assert that root task is at the bottom.
         assertEquals(0, getTaskIndexOf(mDefaultTaskDisplayArea, primarySplitScreen));
 
         // Ensure no longer in splitscreen.
@@ -182,7 +357,7 @@
     @Test
     public void testMoveToPrimarySplitScreenThenMoveToBack() {
         TestSplitOrganizer organizer = new TestSplitOrganizer(mAtm);
-        // This time, start with a fullscreen activitystack
+        // This time, start with a fullscreen activity root task.
         final Task primarySplitScreen = mDefaultTaskDisplayArea.createRootTask(
                 WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
 
@@ -196,7 +371,7 @@
         primarySplitScreen.moveToBack("testPrimarySplitScreenToFullscreenWhenMovedToBack",
                 null /* task */);
 
-        // Assert that stack is at the bottom.
+        // Assert that root task is at the bottom.
         assertEquals(primarySplitScreen, organizer.mSecondary.getChildAt(0));
 
         // Ensure that the override mode is restored to what it was (fullscreen)
@@ -208,7 +383,7 @@
     public void testSplitScreenMoveToBack() {
         TestSplitOrganizer organizer = new TestSplitOrganizer(mAtm);
         // Explicitly reparent task to primary split root to enter split mode, in which implies
-        // primary on top and secondary containing the home task below another stack.
+        // primary on top and secondary containing the home task below another root task.
         final Task primaryTask = mDefaultTaskDisplayArea.createRootTask(
                 WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
         final Task secondaryTask = mDefaultTaskDisplayArea.createRootTask(
@@ -244,24 +419,24 @@
     }
 
     @Test
-    public void testRemoveOrganizedTask_UpdateStackReference() {
+    public void testRemoveOrganizedTask_UpdateRootTaskReference() {
         final Task rootHomeTask = mDefaultTaskDisplayArea.getRootHomeTask();
         final ActivityRecord homeActivity = new ActivityBuilder(mAtm)
                 .setTask(rootHomeTask)
                 .build();
-        final Task secondaryStack = mAtm.mTaskOrganizerController.createRootTask(
+        final Task secondaryRootTask = mAtm.mTaskOrganizerController.createRootTask(
                 rootHomeTask.getDisplayContent(), WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, null);
 
-        rootHomeTask.reparent(secondaryStack, POSITION_TOP);
-        assertEquals(secondaryStack, rootHomeTask.getParent());
+        rootHomeTask.reparent(secondaryRootTask, POSITION_TOP);
+        assertEquals(secondaryRootTask, rootHomeTask.getParent());
 
-        // This should call to {@link TaskDisplayArea#removeStackReferenceIfNeeded}.
+        // This should call to {@link TaskDisplayArea#removeRootTaskReferenceIfNeeded}.
         homeActivity.removeImmediately();
         assertNull(mDefaultTaskDisplayArea.getRootHomeTask());
     }
 
     @Test
-    public void testStackInheritsDisplayWindowingMode() {
+    public void testRootTaskInheritsDisplayWindowingMode() {
         final Task primarySplitScreen = mDefaultTaskDisplayArea.createRootTask(
                 WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
 
@@ -276,7 +451,7 @@
     }
 
     @Test
-    public void testStackOverridesDisplayWindowingMode() {
+    public void testRootTaskOverridesDisplayWindowingMode() {
         final Task primarySplitScreen = mDefaultTaskDisplayArea.createRootTask(
                 WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
 
@@ -358,95 +533,92 @@
     }
 
     @Test
-    public void testMoveStackToBackIncludingParent() {
+    public void testMoveRootTaskToBackIncludingParent() {
         final TaskDisplayArea taskDisplayArea = addNewDisplayContentAt(DisplayContent.POSITION_TOP)
                 .getDefaultTaskDisplayArea();
-        final Task stack1 = createStackForShouldBeVisibleTest(taskDisplayArea,
+        final Task rootTask1 = createTaskForShouldBeVisibleTest(taskDisplayArea,
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */,
                 true /* twoLevelTask */);
-        final Task stack2 = createStackForShouldBeVisibleTest(taskDisplayArea,
+        final Task rootTask2 = createTaskForShouldBeVisibleTest(taskDisplayArea,
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */,
                 true /* twoLevelTask */);
 
-        // Do not move display to back because there is still another stack.
-        stack2.moveToBack("testMoveStackToBackIncludingParent", stack2.getTopMostTask());
-        verify(stack2).positionChildAtBottom(any(), eq(false) /* includingParents */);
+        // Do not move display to back because there is still another root task.
+        rootTask2.moveToBack("testMoveRootTaskToBackIncludingParent", rootTask2.getTopMostTask());
+        verify(rootTask2).positionChildAtBottom(any(), eq(false) /* includingParents */);
 
-        // Also move display to back because there is only one stack left.
-        taskDisplayArea.removeRootTask(stack1);
-        stack2.moveToBack("testMoveStackToBackIncludingParent", stack2.getTopMostTask());
-        verify(stack2).positionChildAtBottom(any(), eq(true) /* includingParents */);
+        // Also move display to back because there is only one root task left.
+        taskDisplayArea.removeRootTask(rootTask1);
+        rootTask2.moveToBack("testMoveRootTaskToBackIncludingParent", rootTask2.getTopMostTask());
+        verify(rootTask2).positionChildAtBottom(any(), eq(true) /* includingParents */);
     }
 
     @Test
     public void testShouldBeVisible_Fullscreen() {
-        final Task homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea,
+        final Task homeRootTask = createTaskForShouldBeVisibleTest(mDefaultTaskDisplayArea,
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
-        final Task pinnedStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea,
+        final Task pinnedRootTask = createTaskForShouldBeVisibleTest(mDefaultTaskDisplayArea,
                 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
-        // Add an activity to the pinned stack so it isn't considered empty for visibility check.
+        // Add an activity to the pinned root task so it isn't considered empty for visibility
+        // check.
         final ActivityRecord pinnedActivity = new ActivityBuilder(mAtm)
-                .setTask(pinnedStack)
+                .setTask(pinnedRootTask)
                 .build();
 
-        assertTrue(homeStack.shouldBeVisible(null /* starting */));
-        assertTrue(pinnedStack.shouldBeVisible(null /* starting */));
+        assertTrue(homeRootTask.shouldBeVisible(null /* starting */));
+        assertTrue(pinnedRootTask.shouldBeVisible(null /* starting */));
 
-        final Task fullscreenStack = createStackForShouldBeVisibleTest(
-                mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
-                true /* onTop */);
-        // Home stack shouldn't be visible behind an opaque fullscreen stack, but pinned stack
-        // should be visible since it is always on-top.
-        doReturn(false).when(fullscreenStack).isTranslucent(any());
-        assertFalse(homeStack.shouldBeVisible(null /* starting */));
-        assertTrue(pinnedStack.shouldBeVisible(null /* starting */));
-        assertTrue(fullscreenStack.shouldBeVisible(null /* starting */));
+        final Task fullscreenRootTask = createTaskForShouldBeVisibleTest(mDefaultTaskDisplayArea,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        // Home root task shouldn't be visible behind an opaque fullscreen root task, but pinned
+        // root task should be visible since it is always on-top.
+        doReturn(false).when(fullscreenRootTask).isTranslucent(any());
+        assertFalse(homeRootTask.shouldBeVisible(null /* starting */));
+        assertTrue(pinnedRootTask.shouldBeVisible(null /* starting */));
+        assertTrue(fullscreenRootTask.shouldBeVisible(null /* starting */));
 
-        // Home stack should be visible behind a translucent fullscreen stack.
-        doReturn(true).when(fullscreenStack).isTranslucent(any());
-        assertTrue(homeStack.shouldBeVisible(null /* starting */));
-        assertTrue(pinnedStack.shouldBeVisible(null /* starting */));
+        // Home root task should be visible behind a translucent fullscreen root task.
+        doReturn(true).when(fullscreenRootTask).isTranslucent(any());
+        assertTrue(homeRootTask.shouldBeVisible(null /* starting */));
+        assertTrue(pinnedRootTask.shouldBeVisible(null /* starting */));
     }
 
     @Test
     public void testShouldBeVisible_SplitScreen() {
-        final Task homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea,
+        final Task homeRootTask = createTaskForShouldBeVisibleTest(mDefaultTaskDisplayArea,
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
-        // Home stack should always be fullscreen for this test.
-        doReturn(false).when(homeStack).supportsSplitScreenWindowingMode();
-        final Task splitScreenPrimary =
-                createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea,
+        // Home root task should always be fullscreen for this test.
+        doReturn(false).when(homeRootTask).supportsSplitScreenWindowingMode();
+        final Task splitScreenPrimary = createTaskForShouldBeVisibleTest(mDefaultTaskDisplayArea,
                 WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
-        final Task splitScreenSecondary =
-                createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea,
+        final Task splitScreenSecondary = createTaskForShouldBeVisibleTest(mDefaultTaskDisplayArea,
                 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
 
-        // Home stack shouldn't be visible if both halves of split-screen are opaque.
+        // Home root task shouldn't be visible if both halves of split-screen are opaque.
         doReturn(false).when(splitScreenPrimary).isTranslucent(any());
         doReturn(false).when(splitScreenSecondary).isTranslucent(any());
-        assertFalse(homeStack.shouldBeVisible(null /* starting */));
+        assertFalse(homeRootTask.shouldBeVisible(null /* starting */));
         assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
         assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
-        assertEquals(TASK_VISIBILITY_INVISIBLE, homeStack.getVisibility(null /* starting */));
+        assertEquals(TASK_VISIBILITY_INVISIBLE, homeRootTask.getVisibility(null /* starting */));
         assertEquals(TASK_VISIBILITY_VISIBLE,
                 splitScreenPrimary.getVisibility(null /* starting */));
         assertEquals(TASK_VISIBILITY_VISIBLE,
                 splitScreenSecondary.getVisibility(null /* starting */));
 
-        // Home stack should be visible if one of the halves of split-screen is translucent.
+        // Home root task should be visible if one of the halves of split-screen is translucent.
         doReturn(true).when(splitScreenPrimary).isTranslucent(any());
-        assertTrue(homeStack.shouldBeVisible(null /* starting */));
+        assertTrue(homeRootTask.shouldBeVisible(null /* starting */));
         assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
         assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
         assertEquals(TASK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
-                homeStack.getVisibility(null /* starting */));
+                homeRootTask.getVisibility(null /* starting */));
         assertEquals(TASK_VISIBILITY_VISIBLE,
                 splitScreenPrimary.getVisibility(null /* starting */));
         assertEquals(TASK_VISIBILITY_VISIBLE,
                 splitScreenSecondary.getVisibility(null /* starting */));
 
-        final Task splitScreenSecondary2 =
-                createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea,
+        final Task splitScreenSecondary2 = createTaskForShouldBeVisibleTest(mDefaultTaskDisplayArea,
                 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
         // First split-screen secondary shouldn't be visible behind another opaque split-split
         // secondary.
@@ -468,18 +640,17 @@
         assertEquals(TASK_VISIBILITY_VISIBLE,
                 splitScreenSecondary2.getVisibility(null /* starting */));
 
-        final Task assistantStack = createStackForShouldBeVisibleTest(
-                mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT,
-                true /* onTop */);
+        final Task assistantRootTask = createTaskForShouldBeVisibleTest(mDefaultTaskDisplayArea,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT, true /* onTop */);
 
-        // Split-screen stacks shouldn't be visible behind an opaque fullscreen stack.
-        doReturn(false).when(assistantStack).isTranslucent(any());
-        assertTrue(assistantStack.shouldBeVisible(null /* starting */));
+        // Split-screen root tasks shouldn't be visible behind an opaque fullscreen root task.
+        doReturn(false).when(assistantRootTask).isTranslucent(any());
+        assertTrue(assistantRootTask.shouldBeVisible(null /* starting */));
         assertFalse(splitScreenPrimary.shouldBeVisible(null /* starting */));
         assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */));
         assertFalse(splitScreenSecondary2.shouldBeVisible(null /* starting */));
         assertEquals(TASK_VISIBILITY_VISIBLE,
-                assistantStack.getVisibility(null /* starting */));
+                assistantRootTask.getVisibility(null /* starting */));
         assertEquals(TASK_VISIBILITY_INVISIBLE,
                 splitScreenPrimary.getVisibility(null /* starting */));
         assertEquals(TASK_VISIBILITY_INVISIBLE,
@@ -487,14 +658,14 @@
         assertEquals(TASK_VISIBILITY_INVISIBLE,
                 splitScreenSecondary2.getVisibility(null /* starting */));
 
-        // Split-screen stacks should be visible behind a translucent fullscreen stack.
-        doReturn(true).when(assistantStack).isTranslucent(any());
-        assertTrue(assistantStack.shouldBeVisible(null /* starting */));
+        // Split-screen root tasks should be visible behind a translucent fullscreen root task.
+        doReturn(true).when(assistantRootTask).isTranslucent(any());
+        assertTrue(assistantRootTask.shouldBeVisible(null /* starting */));
         assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
         assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
         assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
         assertEquals(TASK_VISIBILITY_VISIBLE,
-                assistantStack.getVisibility(null /* starting */));
+                assistantRootTask.getVisibility(null /* starting */));
         assertEquals(TASK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
                 splitScreenPrimary.getVisibility(null /* starting */));
         assertEquals(TASK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
@@ -502,20 +673,20 @@
         assertEquals(TASK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
                 splitScreenSecondary2.getVisibility(null /* starting */));
 
-        // Assistant stack shouldn't be visible behind translucent split-screen stack,
+        // Assistant root task shouldn't be visible behind translucent split-screen root task,
         // unless it is configured to show on top of everything.
-        doReturn(false).when(assistantStack).isTranslucent(any());
+        doReturn(false).when(assistantRootTask).isTranslucent(any());
         doReturn(true).when(splitScreenPrimary).isTranslucent(any());
         doReturn(true).when(splitScreenSecondary2).isTranslucent(any());
         splitScreenSecondary2.moveToFront("testShouldBeVisible_SplitScreen");
         splitScreenPrimary.moveToFront("testShouldBeVisible_SplitScreen");
 
         if (isAssistantOnTop()) {
-            assertTrue(assistantStack.shouldBeVisible(null /* starting */));
+            assertTrue(assistantRootTask.shouldBeVisible(null /* starting */));
             assertFalse(splitScreenPrimary.shouldBeVisible(null /* starting */));
             assertFalse(splitScreenSecondary2.shouldBeVisible(null /* starting */));
             assertEquals(TASK_VISIBILITY_VISIBLE,
-                    assistantStack.getVisibility(null /* starting */));
+                    assistantRootTask.getVisibility(null /* starting */));
             assertEquals(TASK_VISIBILITY_INVISIBLE,
                     splitScreenPrimary.getVisibility(null /* starting */));
             assertEquals(TASK_VISIBILITY_INVISIBLE,
@@ -523,11 +694,11 @@
             assertEquals(TASK_VISIBILITY_INVISIBLE,
                     splitScreenSecondary2.getVisibility(null /* starting */));
         } else {
-            assertFalse(assistantStack.shouldBeVisible(null /* starting */));
+            assertFalse(assistantRootTask.shouldBeVisible(null /* starting */));
             assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
             assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
             assertEquals(TASK_VISIBILITY_INVISIBLE,
-                    assistantStack.getVisibility(null /* starting */));
+                    assistantRootTask.getVisibility(null /* starting */));
             assertEquals(TASK_VISIBILITY_VISIBLE,
                     splitScreenPrimary.getVisibility(null /* starting */));
             assertEquals(TASK_VISIBILITY_INVISIBLE,
@@ -539,35 +710,33 @@
 
     @Test
     public void testGetVisibility_MultiLevel() {
-        final Task homeStack = createStackForShouldBeVisibleTest(
-                mDefaultTaskDisplayArea, WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_HOME,
-                true /* onTop */);
-        final Task splitPrimary = createStackForShouldBeVisibleTest(
-                mDefaultTaskDisplayArea, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY,
-                ACTIVITY_TYPE_UNDEFINED, true /* onTop */);
-        final Task splitSecondary = createStackForShouldBeVisibleTest(
-                mDefaultTaskDisplayArea, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY,
-                ACTIVITY_TYPE_UNDEFINED, true /* onTop */);
+        final Task homeRootTask = createTaskForShouldBeVisibleTest(mDefaultTaskDisplayArea,
+                WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_HOME, true /* onTop */);
+        final Task splitPrimary = createTaskForShouldBeVisibleTest(mDefaultTaskDisplayArea,
+                WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_UNDEFINED, true /* onTop */);
+        final Task splitSecondary = createTaskForShouldBeVisibleTest(mDefaultTaskDisplayArea,
+                WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_UNDEFINED, true /* onTop */);
 
-        doReturn(false).when(homeStack).isTranslucent(any());
+        doReturn(false).when(homeRootTask).isTranslucent(any());
         doReturn(false).when(splitPrimary).isTranslucent(any());
         doReturn(false).when(splitSecondary).isTranslucent(any());
 
 
         // Re-parent home to split secondary.
-        homeStack.reparent(splitSecondary, POSITION_TOP);
+        homeRootTask.reparent(splitSecondary, POSITION_TOP);
         // Current tasks should be visible.
         assertEquals(TASK_VISIBILITY_VISIBLE, splitPrimary.getVisibility(null /* starting */));
         assertEquals(TASK_VISIBILITY_VISIBLE, splitSecondary.getVisibility(null /* starting */));
         // Home task should still be visible even though it is a child of another visible task.
-        assertEquals(TASK_VISIBILITY_VISIBLE, homeStack.getVisibility(null /* starting */));
+        assertEquals(TASK_VISIBILITY_VISIBLE, homeRootTask.getVisibility(null /* starting */));
 
 
         // Add fullscreen translucent task that partially occludes split tasks
-        final Task translucentStack = createStandardStackForVisibilityTest(
+        final Task translucentRootTask = createStandardRootTaskForVisibilityTest(
                 WINDOWING_MODE_FULLSCREEN, true /* translucent */);
         // Fullscreen translucent task should be visible
-        assertEquals(TASK_VISIBILITY_VISIBLE, translucentStack.getVisibility(null /* starting */));
+        assertEquals(TASK_VISIBILITY_VISIBLE,
+                translucentRootTask.getVisibility(null /* starting */));
         // Split tasks should be visible behind translucent
         assertEquals(TASK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
                 splitPrimary.getVisibility(null /* starting */));
@@ -576,415 +745,400 @@
         // Home task should be visible behind translucent since its parent is visible behind
         // translucent.
         assertEquals(TASK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
-                homeStack.getVisibility(null /* starting */));
+                homeRootTask.getVisibility(null /* starting */));
 
 
         // Hide split-secondary
         splitSecondary.setForceHidden(FLAG_FORCE_HIDDEN_FOR_TASK_ORG, true /* set */);
         // Home split secondary and home task should be invisible.
         assertEquals(TASK_VISIBILITY_INVISIBLE, splitSecondary.getVisibility(null /* starting */));
-        assertEquals(TASK_VISIBILITY_INVISIBLE, homeStack.getVisibility(null /* starting */));
+        assertEquals(TASK_VISIBILITY_INVISIBLE, homeRootTask.getVisibility(null /* starting */));
     }
 
     @Test
     public void testGetVisibility_FullscreenBehindTranslucent() {
-        final Task bottomStack =
-                createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
+        final Task bottomRootTask =
+                createStandardRootTaskForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
                         false /* translucent */);
-        final Task translucentStack =
-                createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
+        final Task translucentRootTask =
+                createStandardRootTaskForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
                         true /* translucent */);
 
         assertEquals(TASK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
-                bottomStack.getVisibility(null /* starting */));
+                bottomRootTask.getVisibility(null /* starting */));
         assertEquals(TASK_VISIBILITY_VISIBLE,
-                translucentStack.getVisibility(null /* starting */));
+                translucentRootTask.getVisibility(null /* starting */));
     }
 
     @Test
     public void testGetVisibility_FullscreenBehindTranslucentAndOpaque() {
-        final Task bottomStack =
-                createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
+        final Task bottomRootTask =
+                createStandardRootTaskForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
                         false /* translucent */);
-        final Task translucentStack =
-                createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
+        final Task translucentRootTask =
+                createStandardRootTaskForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
                         true /* translucent */);
-        final Task opaqueStack =
-                createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
+        final Task opaqueRootTask =
+                createStandardRootTaskForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
                         false /* translucent */);
 
-        assertEquals(TASK_VISIBILITY_INVISIBLE, bottomStack.getVisibility(null /* starting */));
+        assertEquals(TASK_VISIBILITY_INVISIBLE, bottomRootTask.getVisibility(null /* starting */));
         assertEquals(TASK_VISIBILITY_INVISIBLE,
-                translucentStack.getVisibility(null /* starting */));
-        assertEquals(TASK_VISIBILITY_VISIBLE, opaqueStack.getVisibility(null /* starting */));
+                translucentRootTask.getVisibility(null /* starting */));
+        assertEquals(TASK_VISIBILITY_VISIBLE, opaqueRootTask.getVisibility(null /* starting */));
     }
 
     @Test
     public void testGetVisibility_FullscreenBehindOpaqueAndTranslucent() {
-        final Task bottomStack =
-                createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
+        final Task bottomRootTask =
+                createStandardRootTaskForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
                         false /* translucent */);
-        final Task opaqueStack =
-                createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
+        final Task opaqueRootTask =
+                createStandardRootTaskForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
                         false /* translucent */);
-        final Task translucentStack =
-                createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
+        final Task translucentRootTask =
+                createStandardRootTaskForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
                         true /* translucent */);
 
-        assertEquals(TASK_VISIBILITY_INVISIBLE, bottomStack.getVisibility(null /* starting */));
+        assertEquals(TASK_VISIBILITY_INVISIBLE, bottomRootTask.getVisibility(null /* starting */));
         assertEquals(TASK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
-                opaqueStack.getVisibility(null /* starting */));
+                opaqueRootTask.getVisibility(null /* starting */));
         assertEquals(TASK_VISIBILITY_VISIBLE,
-                translucentStack.getVisibility(null /* starting */));
+                translucentRootTask.getVisibility(null /* starting */));
     }
 
     @Test
     public void testGetVisibility_FullscreenTranslucentBehindTranslucent() {
-        final Task bottomTranslucentStack =
-                createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
+        final Task bottomTranslucentRootTask =
+                createStandardRootTaskForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
                         true /* translucent */);
-        final Task translucentStack =
-                createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
+        final Task translucentRootTask =
+                createStandardRootTaskForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
                         true /* translucent */);
 
         assertEquals(TASK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
-                bottomTranslucentStack.getVisibility(null /* starting */));
+                bottomTranslucentRootTask.getVisibility(null /* starting */));
         assertEquals(TASK_VISIBILITY_VISIBLE,
-                translucentStack.getVisibility(null /* starting */));
+                translucentRootTask.getVisibility(null /* starting */));
     }
 
     @Test
     public void testGetVisibility_FullscreenTranslucentBehindOpaque() {
-        final Task bottomTranslucentStack =
-                createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
+        final Task bottomTranslucentRootTask =
+                createStandardRootTaskForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
                         true /* translucent */);
-        final Task opaqueStack =
-                createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
+        final Task opaqueRootTask =
+                createStandardRootTaskForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
                         false /* translucent */);
 
         assertEquals(TASK_VISIBILITY_INVISIBLE,
-                bottomTranslucentStack.getVisibility(null /* starting */));
-        assertEquals(TASK_VISIBILITY_VISIBLE, opaqueStack.getVisibility(null /* starting */));
+                bottomTranslucentRootTask.getVisibility(null /* starting */));
+        assertEquals(TASK_VISIBILITY_VISIBLE, opaqueRootTask.getVisibility(null /* starting */));
     }
 
     @Test
     public void testGetVisibility_FullscreenBehindTranslucentAndPip() {
-        final Task bottomStack =
-                createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
+        final Task bottomRootTask =
+                createStandardRootTaskForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
                         false /* translucent */);
-        final Task translucentStack =
-                createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
+        final Task translucentRootTask =
+                createStandardRootTaskForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
                         true /* translucent */);
-        final Task pinnedStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea,
+        final Task pinnedRootTask = createTaskForShouldBeVisibleTest(mDefaultTaskDisplayArea,
                 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
 
         assertEquals(TASK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
-                bottomStack.getVisibility(null /* starting */));
+                bottomRootTask.getVisibility(null /* starting */));
         assertEquals(TASK_VISIBILITY_VISIBLE,
-                translucentStack.getVisibility(null /* starting */));
-        // Add an activity to the pinned stack so it isn't considered empty for visibility check.
+                translucentRootTask.getVisibility(null /* starting */));
+        // Add an activity to the pinned root task so it isn't considered empty for visibility
+        // check.
         final ActivityRecord pinnedActivity = new ActivityBuilder(mAtm)
-                .setTask(pinnedStack)
+                .setTask(pinnedRootTask)
                 .build();
-        assertEquals(TASK_VISIBILITY_VISIBLE, pinnedStack.getVisibility(null /* starting */));
+        assertEquals(TASK_VISIBILITY_VISIBLE, pinnedRootTask.getVisibility(null /* starting */));
     }
 
     @Test
     public void testShouldBeVisible_Finishing() {
-        final Task homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea,
+        final Task homeRootTask = createTaskForShouldBeVisibleTest(mDefaultTaskDisplayArea,
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
-        ActivityRecord topRunningHomeActivity = homeStack.topRunningActivity();
+        ActivityRecord topRunningHomeActivity = homeRootTask.topRunningActivity();
         if (topRunningHomeActivity == null) {
             topRunningHomeActivity = new ActivityBuilder(mAtm)
-                    .setTask(homeStack)
+                    .setTask(homeRootTask)
                     .build();
         }
 
-        final Task translucentStack = createStackForShouldBeVisibleTest(
-                mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
-                true /* onTop */);
-        doReturn(true).when(translucentStack).isTranslucent(any());
+        final Task translucentRootTask = createTaskForShouldBeVisibleTest(mDefaultTaskDisplayArea,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        doReturn(true).when(translucentRootTask).isTranslucent(any());
 
-        assertTrue(homeStack.shouldBeVisible(null /* starting */));
-        assertTrue(translucentStack.shouldBeVisible(null /* starting */));
+        assertTrue(homeRootTask.shouldBeVisible(null /* starting */));
+        assertTrue(translucentRootTask.shouldBeVisible(null /* starting */));
 
         topRunningHomeActivity.finishing = true;
         final ActivityRecord topRunningTranslucentActivity =
-                translucentStack.topRunningActivity();
+                translucentRootTask.topRunningActivity();
         topRunningTranslucentActivity.finishing = true;
 
-        // Home stack should be visible even there are no running activities.
-        assertTrue(homeStack.shouldBeVisible(null /* starting */));
+        // Home root task should be visible even there are no running activities.
+        assertTrue(homeRootTask.shouldBeVisible(null /* starting */));
         // Home should be visible if we are starting an activity within it.
-        assertTrue(homeStack.shouldBeVisible(topRunningHomeActivity /* starting */));
-        // The translucent stack shouldn't be visible since its activity marked as finishing.
-        assertFalse(translucentStack.shouldBeVisible(null /* starting */));
+        assertTrue(homeRootTask.shouldBeVisible(topRunningHomeActivity /* starting */));
+        // The translucent root task shouldn't be visible since its activity marked as finishing.
+        assertFalse(translucentRootTask.shouldBeVisible(null /* starting */));
     }
 
     @Test
-    public void testShouldBeVisible_FullscreenBehindTranslucentInHomeStack() {
-        final Task homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea,
+    public void testShouldBeVisible_FullscreenBehindTranslucentInHomeRootTask() {
+        final Task homeRootTask = createTaskForShouldBeVisibleTest(mDefaultTaskDisplayArea,
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
 
         final ActivityRecord firstActivity = new ActivityBuilder(mAtm)
-                    .setParentTask(homeStack)
-                    .setCreateTask(true)
-                    .build();
+                .setParentTask(homeRootTask)
+                .setCreateTask(true)
+                .build();
         final Task task = firstActivity.getTask();
         final ActivityRecord secondActivity = new ActivityBuilder(mAtm)
                 .setTask(task)
                 .build();
 
         doReturn(false).when(secondActivity).occludesParent();
-        homeStack.ensureActivitiesVisible(null /* starting */, 0 /* configChanges */,
+        homeRootTask.ensureActivitiesVisible(null /* starting */, 0 /* configChanges */,
                 false /* preserveWindows */);
 
         assertTrue(firstActivity.shouldBeVisible());
     }
 
     @Test
-    public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeBehindFullscreen() {
-        final Task homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea,
+    public void testMoveHomeRootTaskBehindBottomMostVisible_NoMoveHomeBehindFullscreen() {
+        final Task homeRootTask = createTaskForShouldBeVisibleTest(mDefaultTaskDisplayArea,
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
-        final Task fullscreenStack = createStackForShouldBeVisibleTest(
-                mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
-                true /* onTop */);
-
-        doReturn(false).when(homeStack).isTranslucent(any());
-        doReturn(false).when(fullscreenStack).isTranslucent(any());
-
-        // Ensure that we don't move the home stack if it is already behind the top fullscreen stack
-        int homeStackIndex = getTaskIndexOf(mDefaultTaskDisplayArea, homeStack);
-        assertEquals(fullscreenStack, getRootTaskAbove(homeStack));
-        mDefaultTaskDisplayArea.moveRootTaskBehindBottomMostVisibleRootTask(homeStack);
-        assertEquals(homeStackIndex, getTaskIndexOf(mDefaultTaskDisplayArea, homeStack));
-    }
-
-    @Test
-    public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeBehindTranslucent() {
-        final Task homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea,
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
-        final Task fullscreenStack = createStackForShouldBeVisibleTest(
-                mDefaultTaskDisplayArea,
+        final Task fullscreenRootTask = createTaskForShouldBeVisibleTest(mDefaultTaskDisplayArea,
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
 
-        doReturn(false).when(homeStack).isTranslucent(any());
-        doReturn(true).when(fullscreenStack).isTranslucent(any());
+        doReturn(false).when(homeRootTask).isTranslucent(any());
+        doReturn(false).when(fullscreenRootTask).isTranslucent(any());
 
-        // Ensure that we don't move the home stack if it is already behind the top fullscreen stack
-        int homeStackIndex = getTaskIndexOf(mDefaultTaskDisplayArea, homeStack);
-        assertEquals(fullscreenStack, getRootTaskAbove(homeStack));
-        mDefaultTaskDisplayArea.moveRootTaskBehindBottomMostVisibleRootTask(homeStack);
-        assertEquals(homeStackIndex, getTaskIndexOf(mDefaultTaskDisplayArea, homeStack));
+        // Ensure that we don't move the home root task if it is already behind the top fullscreen
+        // root task.
+        int homeRootTaskIndex = getTaskIndexOf(mDefaultTaskDisplayArea, homeRootTask);
+        assertEquals(fullscreenRootTask, getRootTaskAbove(homeRootTask));
+        mDefaultTaskDisplayArea.moveRootTaskBehindBottomMostVisibleRootTask(homeRootTask);
+        assertEquals(homeRootTaskIndex, getTaskIndexOf(mDefaultTaskDisplayArea, homeRootTask));
     }
 
     @Test
-    public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeOnTop() {
-        final Task fullscreenStack = createStackForShouldBeVisibleTest(
-                mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
-                true /* onTop */);
-        final Task homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea,
+    public void testMoveHomeRootTaskBehindBottomMostVisible_NoMoveHomeBehindTranslucent() {
+        final Task homeRootTask = createTaskForShouldBeVisibleTest(mDefaultTaskDisplayArea,
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
+        final Task fullscreenRootTask = createTaskForShouldBeVisibleTest(mDefaultTaskDisplayArea,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
 
-        doReturn(false).when(homeStack).isTranslucent(any());
-        doReturn(false).when(fullscreenStack).isTranslucent(any());
+        doReturn(false).when(homeRootTask).isTranslucent(any());
+        doReturn(true).when(fullscreenRootTask).isTranslucent(any());
 
-        // Ensure we don't move the home stack if it is already on top
-        int homeStackIndex = getTaskIndexOf(mDefaultTaskDisplayArea, homeStack);
-        assertNull(getRootTaskAbove(homeStack));
-        mDefaultTaskDisplayArea.moveRootTaskBehindBottomMostVisibleRootTask(homeStack);
-        assertEquals(homeStackIndex, getTaskIndexOf(mDefaultTaskDisplayArea, homeStack));
+        // Ensure that we don't move the home root task if it is already behind the top fullscreen
+        // root task.
+        int homeRootTaskIndex = getTaskIndexOf(mDefaultTaskDisplayArea, homeRootTask);
+        assertEquals(fullscreenRootTask, getRootTaskAbove(homeRootTask));
+        mDefaultTaskDisplayArea.moveRootTaskBehindBottomMostVisibleRootTask(homeRootTask);
+        assertEquals(homeRootTaskIndex, getTaskIndexOf(mDefaultTaskDisplayArea, homeRootTask));
     }
 
     @Test
-    public void testMoveHomeStackBehindBottomMostVisibleStack_MoveHomeBehindFullscreen() {
-        final Task homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea,
+    public void testMoveHomeRootTaskBehindBottomMostVisible_NoMoveHomeOnTop() {
+        final Task fullscreenRootTask = createTaskForShouldBeVisibleTest(mDefaultTaskDisplayArea,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        final Task homeRootTask = createTaskForShouldBeVisibleTest(mDefaultTaskDisplayArea,
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
-        final Task fullscreenStack1 = createStackForShouldBeVisibleTest(
-                mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
-                true /* onTop */);
-        final Task fullscreenStack2 = createStackForShouldBeVisibleTest(
-                mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
-                true /* onTop */);
-        final Task pinnedStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea,
+
+        doReturn(false).when(homeRootTask).isTranslucent(any());
+        doReturn(false).when(fullscreenRootTask).isTranslucent(any());
+
+        // Ensure we don't move the home root task if it is already on top
+        int homeRootTaskIndex = getTaskIndexOf(mDefaultTaskDisplayArea, homeRootTask);
+        assertNull(getRootTaskAbove(homeRootTask));
+        mDefaultTaskDisplayArea.moveRootTaskBehindBottomMostVisibleRootTask(homeRootTask);
+        assertEquals(homeRootTaskIndex, getTaskIndexOf(mDefaultTaskDisplayArea, homeRootTask));
+    }
+
+    @Test
+    public void testMoveHomeRootTaskBehindBottomMostVisible_MoveHomeBehindFullscreen() {
+        final Task homeRootTask = createTaskForShouldBeVisibleTest(mDefaultTaskDisplayArea,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
+        final Task fullscreenRootTask1 = createTaskForShouldBeVisibleTest(mDefaultTaskDisplayArea,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        final Task fullscreenRootTask2 = createTaskForShouldBeVisibleTest(mDefaultTaskDisplayArea,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        final Task pinnedRootTask = createTaskForShouldBeVisibleTest(mDefaultTaskDisplayArea,
                 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
 
-        doReturn(false).when(homeStack).isTranslucent(any());
-        doReturn(false).when(fullscreenStack1).isTranslucent(any());
-        doReturn(false).when(fullscreenStack2).isTranslucent(any());
+        doReturn(false).when(homeRootTask).isTranslucent(any());
+        doReturn(false).when(fullscreenRootTask1).isTranslucent(any());
+        doReturn(false).when(fullscreenRootTask2).isTranslucent(any());
 
-        // Ensure that we move the home stack behind the bottom most fullscreen stack, ignoring the
-        // pinned stack
-        assertEquals(fullscreenStack1, getRootTaskAbove(homeStack));
-        mDefaultTaskDisplayArea.moveRootTaskBehindBottomMostVisibleRootTask(homeStack);
-        assertEquals(fullscreenStack2, getRootTaskAbove(homeStack));
+        // Ensure that we move the home root task behind the bottom most fullscreen root task,
+        // ignoring the pinned root task.
+        assertEquals(fullscreenRootTask1, getRootTaskAbove(homeRootTask));
+        mDefaultTaskDisplayArea.moveRootTaskBehindBottomMostVisibleRootTask(homeRootTask);
+        assertEquals(fullscreenRootTask2, getRootTaskAbove(homeRootTask));
     }
 
     @Test
     public void
-            testMoveHomeStackBehindBottomMostVisibleStack_MoveHomeBehindFullscreenAndTranslucent() {
-        final Task homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea,
+            testMoveHomeRootTaskBehindBottomMostVisible_MoveHomeBehindFullscreenAndTranslucent() {
+        final Task homeRootTask = createTaskForShouldBeVisibleTest(mDefaultTaskDisplayArea,
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
-        final Task fullscreenStack1 = createStackForShouldBeVisibleTest(
-                mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
-                true /* onTop */);
-        final Task fullscreenStack2 = createStackForShouldBeVisibleTest(
-                mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
-                true /* onTop */);
+        final Task fullscreenRootTask1 = createTaskForShouldBeVisibleTest(mDefaultTaskDisplayArea,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        final Task fullscreenRootTask2 = createTaskForShouldBeVisibleTest(mDefaultTaskDisplayArea,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
 
-        doReturn(false).when(homeStack).isTranslucent(any());
-        doReturn(false).when(fullscreenStack1).isTranslucent(any());
-        doReturn(true).when(fullscreenStack2).isTranslucent(any());
+        doReturn(false).when(homeRootTask).isTranslucent(any());
+        doReturn(false).when(fullscreenRootTask1).isTranslucent(any());
+        doReturn(true).when(fullscreenRootTask2).isTranslucent(any());
 
-        // Ensure that we move the home stack behind the bottom most non-translucent fullscreen
-        // stack
-        assertEquals(fullscreenStack1, getRootTaskAbove(homeStack));
-        mDefaultTaskDisplayArea.moveRootTaskBehindBottomMostVisibleRootTask(homeStack);
-        assertEquals(fullscreenStack1, getRootTaskAbove(homeStack));
+        // Ensure that we move the home root task behind the bottom most non-translucent fullscreen
+        // root task.
+        assertEquals(fullscreenRootTask1, getRootTaskAbove(homeRootTask));
+        mDefaultTaskDisplayArea.moveRootTaskBehindBottomMostVisibleRootTask(homeRootTask);
+        assertEquals(fullscreenRootTask1, getRootTaskAbove(homeRootTask));
     }
 
     @Test
-    public void testMoveHomeStackBehindStack_BehindHomeStack() {
-        final Task fullscreenStack1 = createStackForShouldBeVisibleTest(
-                mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
-                true /* onTop */);
-        final Task fullscreenStack2 = createStackForShouldBeVisibleTest(
-                mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
-                true /* onTop */);
-        final Task homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea,
+    public void testMoveHomeRootTaskBehindRootTask_BehindHomeRootTask() {
+        final Task fullscreenRootTask1 = createTaskForShouldBeVisibleTest(mDefaultTaskDisplayArea,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        final Task fullscreenRootTask2 = createTaskForShouldBeVisibleTest(mDefaultTaskDisplayArea,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        final Task homeRootTask = createTaskForShouldBeVisibleTest(mDefaultTaskDisplayArea,
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
 
-        doReturn(false).when(homeStack).isTranslucent(any());
-        doReturn(false).when(fullscreenStack1).isTranslucent(any());
-        doReturn(false).when(fullscreenStack2).isTranslucent(any());
+        doReturn(false).when(homeRootTask).isTranslucent(any());
+        doReturn(false).when(fullscreenRootTask1).isTranslucent(any());
+        doReturn(false).when(fullscreenRootTask2).isTranslucent(any());
 
-        // Ensure we don't move the home stack behind itself
-        int homeStackIndex = getTaskIndexOf(mDefaultTaskDisplayArea, homeStack);
-        mDefaultTaskDisplayArea.moveRootTaskBehindRootTask(homeStack, homeStack);
-        assertEquals(homeStackIndex, getTaskIndexOf(mDefaultTaskDisplayArea, homeStack));
+        // Ensure we don't move the home root task behind itself
+        int homeRootTaskIndex = getTaskIndexOf(mDefaultTaskDisplayArea, homeRootTask);
+        mDefaultTaskDisplayArea.moveRootTaskBehindRootTask(homeRootTask, homeRootTask);
+        assertEquals(homeRootTaskIndex, getTaskIndexOf(mDefaultTaskDisplayArea, homeRootTask));
     }
 
     @Test
-    public void testMoveHomeStackBehindStack() {
-        final Task fullscreenStack1 = createStackForShouldBeVisibleTest(
-                mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
-                true /* onTop */);
-        final Task fullscreenStack2 = createStackForShouldBeVisibleTest(
-                mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
-                true /* onTop */);
-        final Task fullscreenStack3 = createStackForShouldBeVisibleTest(
-                mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
-                true /* onTop */);
-        final Task fullscreenStack4 = createStackForShouldBeVisibleTest(
-                mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
-                true /* onTop */);
-        final Task homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea,
+    public void testMoveHomeRootTaskBehindRootTask() {
+        final Task fullscreenRootTask1 = createTaskForShouldBeVisibleTest(mDefaultTaskDisplayArea,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        final Task fullscreenRootTask2 = createTaskForShouldBeVisibleTest(mDefaultTaskDisplayArea,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        final Task fullscreenRootTask3 = createTaskForShouldBeVisibleTest(mDefaultTaskDisplayArea,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        final Task fullscreenRootTask4 = createTaskForShouldBeVisibleTest(mDefaultTaskDisplayArea,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        final Task homeRootTask = createTaskForShouldBeVisibleTest(mDefaultTaskDisplayArea,
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
 
-        mDefaultTaskDisplayArea.moveRootTaskBehindRootTask(homeStack, fullscreenStack1);
-        assertEquals(fullscreenStack1, getRootTaskAbove(homeStack));
-        mDefaultTaskDisplayArea.moveRootTaskBehindRootTask(homeStack, fullscreenStack2);
-        assertEquals(fullscreenStack2, getRootTaskAbove(homeStack));
-        mDefaultTaskDisplayArea.moveRootTaskBehindRootTask(homeStack, fullscreenStack4);
-        assertEquals(fullscreenStack4, getRootTaskAbove(homeStack));
-        mDefaultTaskDisplayArea.moveRootTaskBehindRootTask(homeStack, fullscreenStack2);
-        assertEquals(fullscreenStack2, getRootTaskAbove(homeStack));
+        mDefaultTaskDisplayArea.moveRootTaskBehindRootTask(homeRootTask, fullscreenRootTask1);
+        assertEquals(fullscreenRootTask1, getRootTaskAbove(homeRootTask));
+        mDefaultTaskDisplayArea.moveRootTaskBehindRootTask(homeRootTask, fullscreenRootTask2);
+        assertEquals(fullscreenRootTask2, getRootTaskAbove(homeRootTask));
+        mDefaultTaskDisplayArea.moveRootTaskBehindRootTask(homeRootTask, fullscreenRootTask4);
+        assertEquals(fullscreenRootTask4, getRootTaskAbove(homeRootTask));
+        mDefaultTaskDisplayArea.moveRootTaskBehindRootTask(homeRootTask, fullscreenRootTask2);
+        assertEquals(fullscreenRootTask2, getRootTaskAbove(homeRootTask));
     }
 
     @Test
     public void testSetAlwaysOnTop() {
-        final Task homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea,
+        final Task homeRootTask = createTaskForShouldBeVisibleTest(mDefaultTaskDisplayArea,
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
-        final Task pinnedStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea,
+        final Task pinnedRootTask = createTaskForShouldBeVisibleTest(mDefaultTaskDisplayArea,
                 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
-        assertEquals(pinnedStack, getRootTaskAbove(homeStack));
+        assertEquals(pinnedRootTask, getRootTaskAbove(homeRootTask));
 
-        final Task alwaysOnTopStack = createStackForShouldBeVisibleTest(
-                mDefaultTaskDisplayArea, WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD,
-                true /* onTop */);
-        alwaysOnTopStack.setAlwaysOnTop(true);
-        assertTrue(alwaysOnTopStack.isAlwaysOnTop());
-        // Ensure (non-pinned) always on top stack is put below pinned stack.
-        assertEquals(pinnedStack, getRootTaskAbove(alwaysOnTopStack));
+        final Task alwaysOnTopRootTask = createTaskForShouldBeVisibleTest(mDefaultTaskDisplayArea,
+                WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        alwaysOnTopRootTask.setAlwaysOnTop(true);
+        assertTrue(alwaysOnTopRootTask.isAlwaysOnTop());
+        // Ensure (non-pinned) always on top root task is put below pinned root task.
+        assertEquals(pinnedRootTask, getRootTaskAbove(alwaysOnTopRootTask));
 
-        final Task nonAlwaysOnTopStack = createStackForShouldBeVisibleTest(
+        final Task nonAlwaysOnTopRootTask = createTaskForShouldBeVisibleTest(
                 mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
                 true /* onTop */);
-        // Ensure non always on top stack is put below always on top stacks.
-        assertEquals(alwaysOnTopStack, getRootTaskAbove(nonAlwaysOnTopStack));
+        // Ensure non always on top root task is put below always on top root tasks.
+        assertEquals(alwaysOnTopRootTask, getRootTaskAbove(nonAlwaysOnTopRootTask));
 
-        final Task alwaysOnTopStack2 = createStackForShouldBeVisibleTest(
-                mDefaultTaskDisplayArea, WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD,
-                true /* onTop */);
-        alwaysOnTopStack2.setAlwaysOnTop(true);
-        assertTrue(alwaysOnTopStack2.isAlwaysOnTop());
-        // Ensure newly created always on top stack is placed above other all always on top stacks.
-        assertEquals(pinnedStack, getRootTaskAbove(alwaysOnTopStack2));
+        final Task alwaysOnTopRootTask2 = createTaskForShouldBeVisibleTest(mDefaultTaskDisplayArea,
+                WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        alwaysOnTopRootTask2.setAlwaysOnTop(true);
+        assertTrue(alwaysOnTopRootTask2.isAlwaysOnTop());
+        // Ensure newly created always on top root task is placed above other all always on top
+        // root tasks.
+        assertEquals(pinnedRootTask, getRootTaskAbove(alwaysOnTopRootTask2));
 
-        alwaysOnTopStack2.setAlwaysOnTop(false);
-        // Ensure, when always on top is turned off for a stack, the stack is put just below all
-        // other always on top stacks.
-        assertEquals(alwaysOnTopStack, getRootTaskAbove(alwaysOnTopStack2));
-        alwaysOnTopStack2.setAlwaysOnTop(true);
+        alwaysOnTopRootTask2.setAlwaysOnTop(false);
+        // Ensure, when always on top is turned off for a root task, the root task is put just below
+        // all other always on top root tasks.
+        assertEquals(alwaysOnTopRootTask, getRootTaskAbove(alwaysOnTopRootTask2));
+        alwaysOnTopRootTask2.setAlwaysOnTop(true);
 
         // Ensure always on top state changes properly when windowing mode changes.
-        alwaysOnTopStack2.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
-        assertFalse(alwaysOnTopStack2.isAlwaysOnTop());
-        assertEquals(alwaysOnTopStack, getRootTaskAbove(alwaysOnTopStack2));
-        alwaysOnTopStack2.setWindowingMode(WINDOWING_MODE_FREEFORM);
-        assertTrue(alwaysOnTopStack2.isAlwaysOnTop());
-        assertEquals(pinnedStack, getRootTaskAbove(alwaysOnTopStack2));
+        alwaysOnTopRootTask2.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+        assertFalse(alwaysOnTopRootTask2.isAlwaysOnTop());
+        assertEquals(alwaysOnTopRootTask, getRootTaskAbove(alwaysOnTopRootTask2));
+        alwaysOnTopRootTask2.setWindowingMode(WINDOWING_MODE_FREEFORM);
+        assertTrue(alwaysOnTopRootTask2.isAlwaysOnTop());
+        assertEquals(pinnedRootTask, getRootTaskAbove(alwaysOnTopRootTask2));
     }
 
     @Test
     public void testSplitScreenMoveToFront() {
-        final Task splitScreenPrimary = createStackForShouldBeVisibleTest(
-                mDefaultTaskDisplayArea, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY,
-                ACTIVITY_TYPE_STANDARD, true /* onTop */);
-        final Task splitScreenSecondary = createStackForShouldBeVisibleTest(
-                mDefaultTaskDisplayArea, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY,
-                ACTIVITY_TYPE_STANDARD, true /* onTop */);
-        final Task assistantStack = createStackForShouldBeVisibleTest(
-                mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT,
-                true /* onTop */);
+        final Task splitScreenPrimary = createTaskForShouldBeVisibleTest(mDefaultTaskDisplayArea,
+                WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        final Task splitScreenSecondary = createTaskForShouldBeVisibleTest(mDefaultTaskDisplayArea,
+                WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        final Task assistantRootTask = createTaskForShouldBeVisibleTest(mDefaultTaskDisplayArea,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT, true /* onTop */);
 
         doReturn(false).when(splitScreenPrimary).isTranslucent(any());
         doReturn(false).when(splitScreenSecondary).isTranslucent(any());
-        doReturn(false).when(assistantStack).isTranslucent(any());
+        doReturn(false).when(assistantRootTask).isTranslucent(any());
 
         assertFalse(splitScreenPrimary.shouldBeVisible(null /* starting */));
         assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */));
-        assertTrue(assistantStack.shouldBeVisible(null /* starting */));
+        assertTrue(assistantRootTask.shouldBeVisible(null /* starting */));
 
         splitScreenSecondary.moveToFront("testSplitScreenMoveToFront");
 
         if (isAssistantOnTop()) {
             assertFalse(splitScreenPrimary.shouldBeVisible(null /* starting */));
             assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */));
-            assertTrue(assistantStack.shouldBeVisible(null /* starting */));
+            assertTrue(assistantRootTask.shouldBeVisible(null /* starting */));
         } else {
             assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
             assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
-            assertFalse(assistantStack.shouldBeVisible(null /* starting */));
+            assertFalse(assistantRootTask.shouldBeVisible(null /* starting */));
         }
     }
 
-    private Task createStandardStackForVisibilityTest(int windowingMode,
+    private Task createStandardRootTaskForVisibilityTest(int windowingMode,
             boolean translucent) {
-        final Task stack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea,
+        final Task rootTask = createTaskForShouldBeVisibleTest(mDefaultTaskDisplayArea,
                 windowingMode, ACTIVITY_TYPE_STANDARD, true /* onTop */);
-        doReturn(translucent).when(stack).isTranslucent(any());
-        return stack;
+        doReturn(translucent).when(rootTask).isTranslucent(any());
+        return rootTask;
     }
 
-    private Task createStackForShouldBeVisibleTest(
+    private Task createTaskForShouldBeVisibleTest(
             TaskDisplayArea taskDisplayArea, int windowingMode, int activityType, boolean onTop) {
-        return createStackForShouldBeVisibleTest(taskDisplayArea,
+        return createTaskForShouldBeVisibleTest(taskDisplayArea,
                 windowingMode, activityType, onTop, false /* twoLevelTask */);
     }
 
     @SuppressWarnings("TypeParameterUnusedInFormals")
-    private Task createStackForShouldBeVisibleTest(TaskDisplayArea taskDisplayArea,
+    private Task createTaskForShouldBeVisibleTest(TaskDisplayArea taskDisplayArea,
             int windowingMode, int activityType, boolean onTop, boolean twoLevelTask) {
         final Task task;
         if (activityType == ACTIVITY_TYPE_HOME) {
@@ -1157,20 +1311,20 @@
     }
 
     @Test
-    public void testWontFinishHomeStackImmediately() {
-        final Task homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea,
+    public void testWontFinishHomeRootTaskImmediately() {
+        final Task homeRootTask = createTaskForShouldBeVisibleTest(mDefaultTaskDisplayArea,
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
 
-        ActivityRecord activity = homeStack.topRunningActivity();
+        ActivityRecord activity = homeRootTask.topRunningActivity();
         if (activity == null) {
             activity = new ActivityBuilder(mAtm)
-                    .setParentTask(homeStack)
+                    .setParentTask(homeRootTask)
                     .setCreateTask(true)
                     .build();
         }
 
-        // Home stack should not be destroyed immediately.
-        final ActivityRecord activity1 = finishTopActivity(homeStack);
+        // Home root task should not be destroyed immediately.
+        final ActivityRecord activity1 = finishTopActivity(homeRootTask);
         assertEquals(FINISHING, activity1.getState());
     }
 
@@ -1178,30 +1332,28 @@
     public void testFinishCurrentActivity() {
         // Create 2 activities on a new display.
         final DisplayContent display = addNewDisplayContentAt(DisplayContent.POSITION_TOP);
-        final Task stack1 = createStackForShouldBeVisibleTest(
-                display.getDefaultTaskDisplayArea(),
+        final Task rootTask1 = createTaskForShouldBeVisibleTest(display.getDefaultTaskDisplayArea(),
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
-        final Task stack2 = createStackForShouldBeVisibleTest(
-                display.getDefaultTaskDisplayArea(),
+        final Task rootTask2 = createTaskForShouldBeVisibleTest(display.getDefaultTaskDisplayArea(),
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
 
-        // There is still an activity1 in stack1 so the activity2 should be added to finishing list
-        // that will be destroyed until idle.
-        stack2.getTopNonFinishingActivity().mVisibleRequested = true;
-        final ActivityRecord activity2 = finishTopActivity(stack2);
+        // There is still an activity1 in rootTask1 so the activity2 should be added to finishing
+        // list that will be destroyed until idle.
+        rootTask2.getTopNonFinishingActivity().mVisibleRequested = true;
+        final ActivityRecord activity2 = finishTopActivity(rootTask2);
         assertEquals(STOPPING, activity2.getState());
         assertThat(mSupervisor.mStoppingActivities).contains(activity2);
 
         // The display becomes empty. Since there is no next activity to be idle, the activity
         // should be destroyed immediately with updating configuration to restore original state.
-        final ActivityRecord activity1 = finishTopActivity(stack1);
+        final ActivityRecord activity1 = finishTopActivity(rootTask1);
         assertEquals(DESTROYING, activity1.getState());
         verify(mRootWindowContainer).ensureVisibilityAndConfig(eq(null) /* starting */,
                 eq(display.mDisplayId), anyBoolean(), anyBoolean());
     }
 
-    private ActivityRecord finishTopActivity(Task stack) {
-        final ActivityRecord activity = stack.topRunningActivity();
+    private ActivityRecord finishTopActivity(Task task) {
+        final ActivityRecord activity = task.topRunningActivity();
         assertNotNull(activity);
         activity.setState(STOPPED, "finishTopActivity");
         activity.makeFinishingLocked();
@@ -1214,24 +1366,24 @@
         // When focused activity and keyguard is going away, we should not sleep regardless
         // of the display state, but keyguard-going-away should only take effects on default
         // display since there is no keyguard on secondary displays (yet).
-        verifyShouldSleepActivities(true /* focusedStack */, true /*keyguardGoingAway*/,
+        verifyShouldSleepActivities(true /* focusedRootTask */, true /*keyguardGoingAway*/,
                 true /* displaySleeping */, true /* isDefaultDisplay */, false /* expected */);
-        verifyShouldSleepActivities(true /* focusedStack */, true /*keyguardGoingAway*/,
+        verifyShouldSleepActivities(true /* focusedRootTask */, true /*keyguardGoingAway*/,
                 true /* displaySleeping */, false /* isDefaultDisplay */, true /* expected */);
 
-        // When not the focused stack, defer to display sleeping state.
-        verifyShouldSleepActivities(false /* focusedStack */, true /*keyguardGoingAway*/,
+        // When not the focused root task, defer to display sleeping state.
+        verifyShouldSleepActivities(false /* focusedRootTask */, true /*keyguardGoingAway*/,
                 true /* displaySleeping */, true /* isDefaultDisplay */, true /* expected */);
 
         // If keyguard is going away, defer to the display sleeping state.
-        verifyShouldSleepActivities(true /* focusedStack */, false /*keyguardGoingAway*/,
+        verifyShouldSleepActivities(true /* focusedRootTask */, false /*keyguardGoingAway*/,
                 true /* displaySleeping */, true /* isDefaultDisplay */, true /* expected */);
-        verifyShouldSleepActivities(true /* focusedStack */, false /*keyguardGoingAway*/,
+        verifyShouldSleepActivities(true /* focusedRootTask */, false /*keyguardGoingAway*/,
                 false /* displaySleeping */, true /* isDefaultDisplay */, false /* expected */);
     }
 
     @Test
-    public void testStackOrderChangedOnRemoveStack() {
+    public void testRootTaskOrderChangedOnRemoveRootTask() {
         final Task task = new TaskBuilder(mSupervisor).build();
         RootTaskOrderChangedListener listener = new RootTaskOrderChangedListener();
         mDefaultTaskDisplayArea.registerRootTaskOrderChangedListener(listener);
@@ -1244,7 +1396,7 @@
     }
 
     @Test
-    public void testStackOrderChangedOnAddPositionStack() {
+    public void testRootTaskOrderChangedOnAddPositionRootTask() {
         final Task task = new TaskBuilder(mSupervisor).build();
         mDefaultTaskDisplayArea.removeRootTask(task);
 
@@ -1260,14 +1412,14 @@
     }
 
     @Test
-    public void testStackOrderChangedOnPositionStack() {
+    public void testRootTaskOrderChangedOnPositionRootTask() {
         RootTaskOrderChangedListener listener = new RootTaskOrderChangedListener();
         try {
-            final Task fullscreenStack1 = createStackForShouldBeVisibleTest(
+            final Task fullscreenRootTask1 = createTaskForShouldBeVisibleTest(
                     mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
                     true /* onTop */);
             mDefaultTaskDisplayArea.registerRootTaskOrderChangedListener(listener);
-            mDefaultTaskDisplayArea.positionChildAt(POSITION_BOTTOM, fullscreenStack1,
+            mDefaultTaskDisplayArea.positionChildAt(POSITION_BOTTOM, fullscreenRootTask1,
                     false /*includingParents*/);
         } finally {
             mDefaultTaskDisplayArea.unregisterRootTaskOrderChangedListener(listener);
@@ -1443,7 +1595,7 @@
                 com.android.internal.R.bool.config_assistantOnTopOfDream);
     }
 
-    private void verifyShouldSleepActivities(boolean focusedStack,
+    private void verifyShouldSleepActivities(boolean focusedRootTask,
             boolean keyguardGoingAway, boolean displaySleeping, boolean isDefaultDisplay,
             boolean expected) {
         final Task task = new TaskBuilder(mSupervisor).build();
@@ -1454,13 +1606,13 @@
         task.mDisplayContent = display;
         doReturn(keyguardGoingAway).when(keyguardController).isKeyguardGoingAway();
         doReturn(displaySleeping).when(display).isSleeping();
-        doReturn(focusedStack).when(task).isFocusedRootTaskOnDisplay();
+        doReturn(focusedRootTask).when(task).isFocusedRootTaskOnDisplay();
 
         assertEquals(expected, task.shouldSleepActivities());
     }
 
     private static class RootTaskOrderChangedListener
-            implements OnRootTaskOrderChangedListener {
+            implements TaskDisplayArea.OnRootTaskOrderChangedListener {
         public boolean mChanged = false;
 
         @Override
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 1b114c1..20bced2 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
@@ -16,42 +16,93 @@
 
 package com.android.server.wm;
 
+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.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
+import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE;
 import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.Display.TYPE_VIRTUAL;
+import static android.window.DisplayAreaOrganizer.FEATURE_VENDOR_FIRST;
 
+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;
+import static com.android.server.wm.ActivityTaskSupervisor.ON_TOP;
+import static com.android.server.wm.RootWindowContainer.MATCH_ATTACHED_TASK_OR_RECENT_TASKS_AND_RESTORE;
 import static com.android.server.wm.Task.ActivityState.FINISHING;
 import static com.android.server.wm.Task.ActivityState.PAUSED;
 import static com.android.server.wm.Task.ActivityState.PAUSING;
 import static com.android.server.wm.Task.ActivityState.STOPPED;
 import static com.android.server.wm.Task.ActivityState.STOPPING;
+import static com.android.server.wm.WindowContainer.POSITION_BOTTOM;
 
 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.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.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.contains;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.refEq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
 
+import android.app.ActivityOptions;
 import android.app.WindowConfiguration;
 import android.content.ComponentName;
+import android.content.Intent;
 import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.ResolveInfo;
+import android.content.res.Configuration;
+import android.content.res.Resources;
 import android.platform.test.annotations.Presubmit;
+import android.util.MergedConfiguration;
+import android.util.Pair;
 
-import androidx.test.filters.SmallTest;
+import androidx.test.filters.MediumTest;
 
+import com.android.internal.app.ResolverActivity;
+
+import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.Consumer;
+
 /**
- * Tests for RootWindowContainer.
+ * Tests for {@link RootWindowContainer}.
  *
  * Build/Install/Run:
  *  atest WmTests:RootWindowContainerTests
  */
-@SmallTest
+@MediumTest
 @Presubmit
 @RunWith(WindowTestRunner.class)
 public class RootWindowContainerTests extends WindowTestsBase {
 
+    @Before
+    public void setUp() throws Exception {
+        doNothing().when(mAtm).updateSleepIfNeededLocked();
+    }
+
     @Test
     public void testUpdateDefaultDisplayWindowingModeOnSettingsRetrieved() {
         assertEquals(WindowConfiguration.WINDOWING_MODE_FULLSCREEN,
@@ -166,5 +217,860 @@
         assertFalse(task.hasChild());
         assertFalse(wpc.hasActivities());
     }
+
+    /**
+     * This test ensures that we do not try to restore a task based off an invalid task id. We
+     * should expect {@code null} to be returned in this case.
+     */
+    @Test
+    public void testRestoringInvalidTask() {
+        mRootWindowContainer.getDefaultDisplay().removeAllTasks();
+        Task task = mRootWindowContainer.anyTaskForId(0 /*taskId*/,
+                MATCH_ATTACHED_TASK_OR_RECENT_TASKS_AND_RESTORE, null, false /* onTop */);
+        assertNull(task);
+    }
+
+    /**
+     * This test ensures that an existing task in the pinned root task is moved to the fullscreen
+     * activity root task when a new task is added.
+     */
+    @Test
+    public void testReplacingTaskInPinnedRootTask() {
+        Task fullscreenTask = mRootWindowContainer.getDefaultTaskDisplayArea().createRootTask(
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        final ActivityRecord firstActivity = new ActivityBuilder(mAtm)
+                .setTask(fullscreenTask).build();
+        final ActivityRecord secondActivity = new ActivityBuilder(mAtm)
+                .setTask(fullscreenTask).build();
+
+        fullscreenTask.moveToFront("testReplacingTaskInPinnedRootTask");
+
+        // Ensure full screen root task has both tasks.
+        ensureTaskPlacement(fullscreenTask, firstActivity, secondActivity);
+
+        // Move first activity to pinned root task.
+        mRootWindowContainer.moveActivityToPinnedRootTask(firstActivity, "initialMove");
+
+        final TaskDisplayArea taskDisplayArea = fullscreenTask.getDisplayArea();
+        Task pinnedRootTask = taskDisplayArea.getRootPinnedTask();
+        // Ensure a task has moved over.
+        ensureTaskPlacement(pinnedRootTask, firstActivity);
+        ensureTaskPlacement(fullscreenTask, secondActivity);
+
+        // Move second activity to pinned root task.
+        mRootWindowContainer.moveActivityToPinnedRootTask(secondActivity, "secondMove");
+
+        // Need to get root tasks again as a new instance might have been created.
+        pinnedRootTask = taskDisplayArea.getRootPinnedTask();
+        fullscreenTask = taskDisplayArea.getRootTask(WINDOWING_MODE_FULLSCREEN,
+                ACTIVITY_TYPE_STANDARD);
+        // Ensure root tasks have swapped tasks.
+        ensureTaskPlacement(pinnedRootTask, secondActivity);
+        ensureTaskPlacement(fullscreenTask, firstActivity);
+    }
+
+    @Test
+    public void testMovingBottomMostRootTaskActivityToPinnedRootTask() {
+        final Task fullscreenTask = mRootWindowContainer.getDefaultTaskDisplayArea().createRootTask(
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        final ActivityRecord firstActivity = new ActivityBuilder(mAtm)
+                .setTask(fullscreenTask).build();
+        final Task task = firstActivity.getTask();
+
+        final ActivityRecord secondActivity = new ActivityBuilder(mAtm)
+                .setTask(fullscreenTask).build();
+
+        fullscreenTask.moveTaskToBack(task);
+
+        // Ensure full screen task has both tasks.
+        ensureTaskPlacement(fullscreenTask, firstActivity, secondActivity);
+        assertEquals(task.getTopMostActivity(), secondActivity);
+        firstActivity.setState(STOPPED, "testMovingBottomMostRootTaskActivityToPinnedRootTask");
+
+
+        // Move first activity to pinned root task.
+        mRootWindowContainer.moveActivityToPinnedRootTask(secondActivity, "initialMove");
+
+        assertTrue(firstActivity.mRequestForceTransition);
+    }
+
+    private static void ensureTaskPlacement(Task task, ActivityRecord... activities) {
+        final ArrayList<ActivityRecord> taskActivities = new ArrayList<>();
+
+        task.forAllActivities((Consumer<ActivityRecord>) taskActivities::add, false);
+
+        assertEquals("Expecting " + Arrays.deepToString(activities) + " got " + taskActivities,
+                taskActivities.size(), activities != null ? activities.length : 0);
+
+        if (activities == null) {
+            return;
+        }
+
+        for (ActivityRecord activity : activities) {
+            assertTrue(taskActivities.contains(activity));
+        }
+    }
+
+    @Test
+    public void testApplySleepTokens() {
+        final DisplayContent display = mRootWindowContainer.getDefaultDisplay();
+        final KeyguardController keyguard = mSupervisor.getKeyguardController();
+        final Task task = new TaskBuilder(mSupervisor)
+                .setDisplay(display)
+                .setOnTop(false)
+                .build();
+
+        // Make sure we wake and resume in the case the display is turning on and the keyguard is
+        // not showing.
+        verifySleepTokenBehavior(display, keyguard, task, true /*displaySleeping*/,
+                false /* displayShouldSleep */, true /* isFocusedTask */,
+                false /* keyguardShowing */, true /* expectWakeFromSleep */,
+                true /* expectResumeTopActivity */);
+
+        // Make sure we wake and don't resume when the display is turning on and the keyguard is
+        // showing.
+        verifySleepTokenBehavior(display, keyguard, task, true /*displaySleeping*/,
+                false /* displayShouldSleep */, true /* isFocusedTask */,
+                true /* keyguardShowing */, true /* expectWakeFromSleep */,
+                false /* expectResumeTopActivity */);
+
+        // Make sure we wake and don't resume when the display is turning on and the keyguard is
+        // not showing as unfocused.
+        verifySleepTokenBehavior(display, keyguard, task, true /*displaySleeping*/,
+                false /* displayShouldSleep */, false /* isFocusedTask */,
+                false /* keyguardShowing */, true /* expectWakeFromSleep */,
+                false /* expectResumeTopActivity */);
+
+        // Should not do anything if the display state hasn't changed.
+        verifySleepTokenBehavior(display, keyguard, task, false /*displaySleeping*/,
+                false /* displayShouldSleep */, true /* isFocusedTask */,
+                false /* keyguardShowing */, false /* expectWakeFromSleep */,
+                false /* expectResumeTopActivity */);
+    }
+
+    private void verifySleepTokenBehavior(DisplayContent display, KeyguardController keyguard,
+            Task task, boolean displaySleeping, boolean displayShouldSleep,
+            boolean isFocusedTask, boolean keyguardShowing, boolean expectWakeFromSleep,
+            boolean expectResumeTopActivity) {
+        reset(task);
+
+        doReturn(displayShouldSleep).when(display).shouldSleep();
+        doReturn(displaySleeping).when(display).isSleeping();
+        doReturn(keyguardShowing).when(keyguard).isKeyguardOrAodShowing(anyInt());
+
+        doReturn(isFocusedTask).when(task).isFocusedRootTaskOnDisplay();
+        doReturn(isFocusedTask ? task : null).when(display).getFocusedRootTask();
+        TaskDisplayArea defaultTaskDisplayArea = display.getDefaultTaskDisplayArea();
+        doReturn(isFocusedTask ? task : null).when(defaultTaskDisplayArea).getFocusedRootTask();
+        mRootWindowContainer.applySleepTokens(true);
+        verify(task, times(expectWakeFromSleep ? 1 : 0)).awakeFromSleepingLocked();
+        verify(task, times(expectResumeTopActivity ? 1 : 0)).resumeTopActivityUncheckedLocked(
+                null /* target */, null /* targetOptions */);
+    }
+
+    @Test
+    public void testAwakeFromSleepingWithAppConfiguration() {
+        final DisplayContent display = mRootWindowContainer.getDefaultDisplay();
+        final ActivityRecord activity = new ActivityBuilder(mAtm).setCreateTask(true).build();
+        activity.moveFocusableActivityToTop("test");
+        assertTrue(activity.getRootTask().isFocusedRootTaskOnDisplay());
+        ActivityRecordTests.setRotatedScreenOrientationSilently(activity);
+
+        final Configuration rotatedConfig = new Configuration();
+        display.computeScreenConfiguration(rotatedConfig, display.getDisplayRotation()
+                .rotationForOrientation(activity.getOrientation(), display.getRotation()));
+        assertNotEquals(activity.getConfiguration().orientation, rotatedConfig.orientation);
+        // Assume the activity was shown in different orientation. For example, the top activity is
+        // landscape and the portrait lockscreen is shown.
+        activity.setLastReportedConfiguration(
+                new MergedConfiguration(mAtm.getGlobalConfiguration(), rotatedConfig));
+        activity.setState(Task.ActivityState.STOPPED, "sleep");
+
+        display.setIsSleeping(true);
+        doReturn(false).when(display).shouldSleep();
+        // Allow to resume when awaking.
+        setBooted(mAtm);
+        mRootWindowContainer.applySleepTokens(true);
+
+        // The display orientation should be changed by the activity so there is no relaunch.
+        verify(activity, never()).relaunchActivityLocked(anyBoolean());
+        assertEquals(rotatedConfig.orientation, display.getConfiguration().orientation);
+    }
+
+    /**
+     * Verifies that removal of activity with task and root task is done correctly.
+     */
+    @Test
+    public void testRemovingRootTaskOnAppCrash() {
+        final TaskDisplayArea defaultTaskDisplayArea = mRootWindowContainer
+                .getDefaultTaskDisplayArea();
+        final int originalRootTaskCount = defaultTaskDisplayArea.getRootTaskCount();
+        final Task rootTask = defaultTaskDisplayArea.createRootTask(
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
+        final ActivityRecord firstActivity = new ActivityBuilder(mAtm).setTask(rootTask).build();
+
+        assertEquals(originalRootTaskCount + 1, defaultTaskDisplayArea.getRootTaskCount());
+
+        // Let's pretend that the app has crashed.
+        firstActivity.app.setThread(null);
+        mRootWindowContainer.finishTopCrashedActivities(firstActivity.app, "test");
+
+        // Verify that the root task was removed.
+        assertEquals(originalRootTaskCount, defaultTaskDisplayArea.getRootTaskCount());
+    }
+
+    /**
+     * Verifies that removal of activities with task and root task is done correctly when there are
+     * several task display areas.
+     */
+    @Test
+    public void testRemovingRootTaskOnAppCrash_multipleDisplayAreas() {
+        final TaskDisplayArea defaultTaskDisplayArea = mRootWindowContainer
+                .getDefaultTaskDisplayArea();
+        final int originalRootTaskCount = defaultTaskDisplayArea.getRootTaskCount();
+        final Task rootTask = defaultTaskDisplayArea.createRootTask(
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
+        final ActivityRecord firstActivity = new ActivityBuilder(mAtm).setTask(rootTask).build();
+        assertEquals(originalRootTaskCount + 1, defaultTaskDisplayArea.getRootTaskCount());
+
+        final DisplayContent dc = defaultTaskDisplayArea.getDisplayContent();
+        final TaskDisplayArea secondTaskDisplayArea = createTaskDisplayArea(
+                dc, mRootWindowContainer.mWmService, "TestTaskDisplayArea", FEATURE_VENDOR_FIRST);
+        final Task secondRootTask = secondTaskDisplayArea.createRootTask(
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
+        new ActivityBuilder(mAtm).setTask(secondRootTask).setUseProcess(firstActivity.app).build();
+        assertEquals(1, secondTaskDisplayArea.getRootTaskCount());
+
+        // Let's pretend that the app has crashed.
+        firstActivity.app.setThread(null);
+        mRootWindowContainer.finishTopCrashedActivities(firstActivity.app, "test");
+
+        // Verify that the root tasks were removed.
+        assertEquals(originalRootTaskCount, defaultTaskDisplayArea.getRootTaskCount());
+        assertEquals(0, secondTaskDisplayArea.getRootTaskCount());
+    }
+
+    @Test
+    public void testFocusability() {
+        final TaskDisplayArea defaultTaskDisplayArea = mRootWindowContainer
+                .getDefaultTaskDisplayArea();
+        final Task task = defaultTaskDisplayArea.createRootTask(
+                WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        final ActivityRecord activity = new ActivityBuilder(mAtm).setTask(task).build();
+
+        // Created tasks are focusable by default.
+        assertTrue(task.isTopActivityFocusable());
+        assertTrue(activity.isFocusable());
+
+        // If the task is made unfocusable, its activities should inherit that.
+        task.setFocusable(false);
+        assertFalse(task.isTopActivityFocusable());
+        assertFalse(activity.isFocusable());
+
+        final Task pinnedTask = defaultTaskDisplayArea.createRootTask(
+                WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        final ActivityRecord pinnedActivity = new ActivityBuilder(mAtm)
+                .setTask(pinnedTask).build();
+
+        // We should not be focusable when in pinned mode
+        assertFalse(pinnedTask.isTopActivityFocusable());
+        assertFalse(pinnedActivity.isFocusable());
+
+        // Add flag forcing focusability.
+        pinnedActivity.info.flags |= FLAG_ALWAYS_FOCUSABLE;
+
+        // Task with FLAG_ALWAYS_FOCUSABLE should be focusable.
+        assertTrue(pinnedTask.isTopActivityFocusable());
+        assertTrue(pinnedActivity.isFocusable());
+    }
+
+    /**
+     * Verify that split-screen primary root task will be chosen if activity is launched that
+     * targets split-screen secondary, but a matching existing instance is found on top of
+     * split-screen primary root task.
+     */
+    @Test
+    public void testSplitScreenPrimaryChosenWhenTopActivityLaunchedToSecondary() {
+        // Create primary split-screen root task with a task and an activity.
+        final Task primaryRootTask = mRootWindowContainer.getDefaultTaskDisplayArea()
+                .createRootTask(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD,
+                        true /* onTop */);
+        final Task task = new TaskBuilder(mSupervisor).setParentTask(primaryRootTask).build();
+        final ActivityRecord r = new ActivityBuilder(mAtm).setTask(task).build();
+
+        // Find a launch root task for the top activity in split-screen primary, while requesting
+        // split-screen secondary.
+        final ActivityOptions options = ActivityOptions.makeBasic();
+        options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY);
+        final Task result =
+                mRootWindowContainer.getLaunchRootTask(r, options, task, true /* onTop */);
+
+        // Assert that the primary root task is returned.
+        assertEquals(primaryRootTask, result);
+    }
+
+    /**
+     * Verify that home root task would be moved to front when the top activity is Recents.
+     */
+    @Test
+    public void testFindTaskToMoveToFrontWhenRecentsOnTop() {
+        // Create root task/task on default display.
+        final Task targetRootTask = new TaskBuilder(mSupervisor)
+                .setCreateActivity(true)
+                .setOnTop(false)
+                .build();
+        final Task targetTask = targetRootTask.getBottomMostTask();
+
+        // Create Recents on top of the display.
+        final Task rootTask = new TaskBuilder(mSupervisor)
+                .setCreateActivity(true)
+                .setActivityType(ACTIVITY_TYPE_RECENTS)
+                .build();
+
+        final String reason = "findTaskToMoveToFront";
+        mSupervisor.findTaskToMoveToFront(targetTask, 0, ActivityOptions.makeBasic(), reason,
+                false);
+
+        final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
+        verify(taskDisplayArea).moveHomeRootTaskToFront(contains(reason));
+    }
+
+    /**
+     * Verify that home root task won't be moved to front if the top activity on other display is
+     * Recents.
+     */
+    @Test
+    public void testFindTaskToMoveToFrontWhenRecentsOnOtherDisplay() {
+        // Create tasks on default display.
+        final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
+        final Task targetRootTask = taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
+                ACTIVITY_TYPE_STANDARD, false /* onTop */);
+        final Task targetTask = new TaskBuilder(mSupervisor).setParentTask(targetRootTask).build();
+
+        // Create Recents on secondary display.
+        final TestDisplayContent secondDisplay = addNewDisplayContentAt(
+                DisplayContent.POSITION_TOP);
+        final Task rootTask = secondDisplay.getDefaultTaskDisplayArea()
+                .createRootTask(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_RECENTS, true /* onTop */);
+        new ActivityBuilder(mAtm).setTask(rootTask).build();
+
+        final String reason = "findTaskToMoveToFront";
+        mSupervisor.findTaskToMoveToFront(targetTask, 0, ActivityOptions.makeBasic(), reason,
+                false);
+
+        verify(taskDisplayArea, never()).moveHomeRootTaskToFront(contains(reason));
+    }
+
+    /**
+     * Verify if a root task is not at the topmost position, it should be able to resume its
+     * activity if the root task is the top focused.
+     */
+    @Test
+    public void testResumeActivityWhenNonTopmostRootTaskIsTopFocused() {
+        // Create a root task at bottom.
+        final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
+        final Task rootTask = spy(taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
+                ACTIVITY_TYPE_STANDARD, false /* onTop */));
+        final ActivityRecord activity = new ActivityBuilder(mAtm).setTask(rootTask).build();
+        taskDisplayArea.positionChildAt(POSITION_BOTTOM, rootTask, false /*includingParents*/);
+
+        // Assume the task is not at the topmost position (e.g. behind always-on-top root tasks)
+        // but it is the current top focused task.
+        assertFalse(rootTask.isTopRootTaskInDisplayArea());
+        doReturn(rootTask).when(mRootWindowContainer).getTopDisplayFocusedRootTask();
+
+        // Use the task as target to resume.
+        mRootWindowContainer.resumeFocusedTasksTopActivities(
+                rootTask, activity, null /* targetOptions */);
+
+        // Verify the target task should resume its activity.
+        verify(rootTask, times(1)).resumeTopActivityUncheckedLocked(
+                eq(activity), eq(null /* targetOptions */));
+    }
+
+    /**
+     * Verify that home activity will be started on a display even if another display has a
+     * focusable activity.
+     */
+    @Test
+    public void testResumeFocusedRootTasksStartsHomeActivity_NoActivities() {
+        final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
+        taskDisplayArea.getRootHomeTask().removeIfPossible();
+        taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP);
+
+        doReturn(true).when(mRootWindowContainer).resumeHomeActivity(any(), any(), any());
+
+        mAtm.setBooted(true);
+
+        // Trigger resume on all displays
+        mRootWindowContainer.resumeFocusedTasksTopActivities();
+
+        // Verify that home activity was started on the default display
+        verify(mRootWindowContainer).resumeHomeActivity(any(), any(), eq(taskDisplayArea));
+    }
+
+    /**
+     * Verify that home activity will be started on a display even if another display has a
+     * focusable activity.
+     */
+    @Test
+    public void testResumeFocusedRootTasksStartsHomeActivity_ActivityOnSecondaryScreen() {
+        final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
+        taskDisplayArea.getRootHomeTask().removeIfPossible();
+        taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP);
+
+        // Create an activity on secondary display.
+        final TestDisplayContent secondDisplay = addNewDisplayContentAt(
+                DisplayContent.POSITION_TOP);
+        final Task rootTask = secondDisplay.getDefaultTaskDisplayArea().createRootTask(
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        new ActivityBuilder(mAtm).setTask(rootTask).build();
+
+        doReturn(true).when(mRootWindowContainer).resumeHomeActivity(any(), any(), any());
+
+        mAtm.setBooted(true);
+
+        // Trigger resume on all displays
+        mRootWindowContainer.resumeFocusedTasksTopActivities();
+
+        // Verify that home activity was started on the default display
+        verify(mRootWindowContainer).resumeHomeActivity(any(), any(), eq(taskDisplayArea));
+    }
+
+    /**
+     * Verify that a lingering transition is being executed in case the activity to be resumed is
+     * already resumed
+     */
+    @Test
+    public void testResumeActivityLingeringTransition() {
+        // Create a root task at top.
+        final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
+        final Task rootTask = spy(taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
+                ACTIVITY_TYPE_STANDARD, false /* onTop */));
+        final ActivityRecord activity = new ActivityBuilder(mAtm)
+                .setTask(rootTask).setOnTop(true).build();
+        activity.setState(Task.ActivityState.RESUMED, "test");
+
+        // Assume the task is at the topmost position
+        assertTrue(rootTask.isTopRootTaskInDisplayArea());
+
+        // Use the task as target to resume.
+        mRootWindowContainer.resumeFocusedTasksTopActivities();
+
+        // Verify the lingering app transition is being executed because it's already resumed
+        verify(rootTask, times(1)).executeAppTransition(any());
+    }
+
+    @Test
+    public void testResumeActivityLingeringTransition_notExecuted() {
+        // Create a root task at bottom.
+        final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
+        final Task rootTask = spy(taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
+                ACTIVITY_TYPE_STANDARD, false /* onTop */));
+        final ActivityRecord activity = new ActivityBuilder(mAtm)
+                .setTask(rootTask).setOnTop(true).build();
+        activity.setState(Task.ActivityState.RESUMED, "test");
+        taskDisplayArea.positionChildAt(POSITION_BOTTOM, rootTask, false /*includingParents*/);
+
+        // Assume the task is at the topmost position
+        assertFalse(rootTask.isTopRootTaskInDisplayArea());
+        doReturn(rootTask).when(mRootWindowContainer).getTopDisplayFocusedRootTask();
+
+        // Use the task as target to resume.
+        mRootWindowContainer.resumeFocusedTasksTopActivities();
+
+        // Verify the lingering app transition is being executed because it's already resumed
+        verify(rootTask, never()).executeAppTransition(any());
+    }
+
+    /**
+     * Tests that home activities can be started on the displays that supports system decorations.
+     */
+    @Test
+    public void testStartHomeOnAllDisplays() {
+        mockResolveHomeActivity(true /* primaryHome */, false /* forceSystemProvided */);
+        mockResolveSecondaryHomeActivity();
+
+        // Create secondary displays.
+        final TestDisplayContent secondDisplay =
+                new TestDisplayContent.Builder(mAtm, 1000, 1500)
+                        .setSystemDecorations(true).build();
+
+        doReturn(true).when(mRootWindowContainer)
+                .ensureVisibilityAndConfig(any(), anyInt(), anyBoolean(), anyBoolean());
+        doReturn(true).when(mRootWindowContainer).canStartHomeOnDisplayArea(any(), any(),
+                anyBoolean());
+
+        mRootWindowContainer.startHomeOnAllDisplays(0, "testStartHome");
+
+        assertTrue(mRootWindowContainer.getDefaultDisplay().getTopRootTask().isActivityTypeHome());
+        assertNotNull(secondDisplay.getTopRootTask());
+        assertTrue(secondDisplay.getTopRootTask().isActivityTypeHome());
+    }
+
+    /**
+     * Tests that home activities won't be started before booting when display added.
+     */
+    @Test
+    public void testNotStartHomeBeforeBoot() {
+        final int displayId = 1;
+        final boolean isBooting = mAtm.mAmInternal.isBooting();
+        final boolean isBooted = mAtm.mAmInternal.isBooted();
+        try {
+            mAtm.mAmInternal.setBooting(false);
+            mAtm.mAmInternal.setBooted(false);
+            mRootWindowContainer.onDisplayAdded(displayId);
+            verify(mRootWindowContainer, never()).startHomeOnDisplay(anyInt(), any(), anyInt());
+        } finally {
+            mAtm.mAmInternal.setBooting(isBooting);
+            mAtm.mAmInternal.setBooted(isBooted);
+        }
+    }
+
+    /**
+     * Tests whether home can be started if being instrumented.
+     */
+    @Test
+    public void testCanStartHomeWhenInstrumented() {
+        final ActivityInfo info = new ActivityInfo();
+        info.applicationInfo = new ApplicationInfo();
+        final WindowProcessController app = mock(WindowProcessController.class);
+        doReturn(app).when(mAtm).getProcessController(any(), anyInt());
+
+        // Can not start home if we don't want to start home while home is being instrumented.
+        doReturn(true).when(app).isInstrumenting();
+        final TaskDisplayArea defaultTaskDisplayArea = mRootWindowContainer
+                .getDefaultTaskDisplayArea();
+        assertFalse(mRootWindowContainer.canStartHomeOnDisplayArea(info, defaultTaskDisplayArea,
+                false /* allowInstrumenting*/));
+
+        // Can start home for other cases.
+        assertTrue(mRootWindowContainer.canStartHomeOnDisplayArea(info, defaultTaskDisplayArea,
+                true /* allowInstrumenting*/));
+
+        doReturn(false).when(app).isInstrumenting();
+        assertTrue(mRootWindowContainer.canStartHomeOnDisplayArea(info, defaultTaskDisplayArea,
+                false /* allowInstrumenting*/));
+        assertTrue(mRootWindowContainer.canStartHomeOnDisplayArea(info, defaultTaskDisplayArea,
+                true /* allowInstrumenting*/));
+    }
+
+    /**
+     * Tests that secondary home activity should not be resolved if device is still locked.
+     */
+    @Test
+    public void testStartSecondaryHomeOnDisplayWithUserKeyLocked() {
+        // Create secondary displays.
+        final TestDisplayContent secondDisplay =
+                new TestDisplayContent.Builder(mAtm, 1000, 1500)
+                        .setSystemDecorations(true).build();
+
+        // Use invalid user id to let StorageManager.isUserKeyUnlocked() return false.
+        final int currentUser = mRootWindowContainer.mCurrentUser;
+        mRootWindowContainer.mCurrentUser = -1;
+
+        mRootWindowContainer.startHomeOnDisplay(0 /* userId */, "testStartSecondaryHome",
+                secondDisplay.mDisplayId, true /* allowInstrumenting */, true /* fromHomeKey */);
+
+        try {
+            verify(mRootWindowContainer, never()).resolveSecondaryHomeActivity(anyInt(), any());
+        } finally {
+            mRootWindowContainer.mCurrentUser = currentUser;
+        }
+    }
+
+    /**
+     * Tests that secondary home activity should not be resolved if display does not support system
+     * decorations.
+     */
+    @Test
+    public void testStartSecondaryHomeOnDisplayWithoutSysDecorations() {
+        // Create secondary displays.
+        final TestDisplayContent secondDisplay =
+                new TestDisplayContent.Builder(mAtm, 1000, 1500)
+                        .setSystemDecorations(false).build();
+
+        mRootWindowContainer.startHomeOnDisplay(0 /* userId */, "testStartSecondaryHome",
+                secondDisplay.mDisplayId, true /* allowInstrumenting */, true /* fromHomeKey */);
+
+        verify(mRootWindowContainer, never()).resolveSecondaryHomeActivity(anyInt(), any());
+    }
+
+    /**
+     * Tests that when starting {@link #ResolverActivity} for home, it should use the standard
+     * activity type (in a new root task) so the order of back stack won't be broken.
+     */
+    @Test
+    public void testStartResolverActivityForHome() {
+        final ActivityInfo info = new ActivityInfo();
+        info.applicationInfo = new ApplicationInfo();
+        info.applicationInfo.packageName = "android";
+        info.name = ResolverActivity.class.getName();
+        doReturn(info).when(mRootWindowContainer).resolveHomeActivity(anyInt(), any());
+
+        mRootWindowContainer.startHomeOnDisplay(0 /* userId */, "test", DEFAULT_DISPLAY);
+        final ActivityRecord resolverActivity = mRootWindowContainer.topRunningActivity();
+
+        assertEquals(info, resolverActivity.info);
+        assertEquals(ACTIVITY_TYPE_STANDARD, resolverActivity.getRootTask().getActivityType());
+    }
+
+    /**
+     * Tests that secondary home should be selected if primary home not set.
+     */
+    @Test
+    public void testResolveSecondaryHomeActivityWhenPrimaryHomeNotSet() {
+        // Setup: primary home not set.
+        final Intent primaryHomeIntent = mAtm.getHomeIntent();
+        final ActivityInfo aInfoPrimary = new ActivityInfo();
+        aInfoPrimary.name = ResolverActivity.class.getName();
+        doReturn(aInfoPrimary).when(mRootWindowContainer).resolveHomeActivity(anyInt(),
+                refEq(primaryHomeIntent));
+        // Setup: set secondary home.
+        mockResolveHomeActivity(false /* primaryHome */, false /* forceSystemProvided */);
+
+        // Run the test.
+        final Pair<ActivityInfo, Intent> resolvedInfo = mRootWindowContainer
+                .resolveSecondaryHomeActivity(0 /* userId */, mock(TaskDisplayArea.class));
+        final ActivityInfo aInfoSecondary = getFakeHomeActivityInfo(false /* primaryHome*/);
+        assertEquals(aInfoSecondary.name, resolvedInfo.first.name);
+        assertEquals(aInfoSecondary.applicationInfo.packageName,
+                resolvedInfo.first.applicationInfo.packageName);
+    }
+
+    /**
+     * Tests that the default secondary home activity is always picked when it is in forced by
+     * config_useSystemProvidedLauncherForSecondary.
+     */
+    @Test
+    public void testResolveSecondaryHomeActivityForced() {
+        // SetUp: set primary home.
+        mockResolveHomeActivity(true /* primaryHome */, false /* forceSystemProvided */);
+        // SetUp: set secondary home and force it.
+        mockResolveHomeActivity(false /* primaryHome */, true /* forceSystemProvided */);
+        final Intent secondaryHomeIntent =
+                mAtm.getSecondaryHomeIntent(null /* preferredPackage */);
+        final List<ResolveInfo> resolutions = new ArrayList<>();
+        final ResolveInfo resolveInfo = new ResolveInfo();
+        final ActivityInfo aInfoSecondary = getFakeHomeActivityInfo(false /* primaryHome*/);
+        resolveInfo.activityInfo = aInfoSecondary;
+        resolutions.add(resolveInfo);
+        doReturn(resolutions).when(mRootWindowContainer).resolveActivities(anyInt(),
+                refEq(secondaryHomeIntent));
+        doReturn(true).when(mRootWindowContainer).canStartHomeOnDisplayArea(any(), any(),
+                anyBoolean());
+
+        // Run the test.
+        final Pair<ActivityInfo, Intent> resolvedInfo = mRootWindowContainer
+                .resolveSecondaryHomeActivity(0 /* userId */, mock(TaskDisplayArea.class));
+        assertEquals(aInfoSecondary.name, resolvedInfo.first.name);
+        assertEquals(aInfoSecondary.applicationInfo.packageName,
+                resolvedInfo.first.applicationInfo.packageName);
+    }
+
+    /**
+     * Tests that secondary home should be selected if primary home not support secondary displays
+     * or there is no matched activity in the same package as selected primary home.
+     */
+    @Test
+    public void testResolveSecondaryHomeActivityWhenPrimaryHomeNotSupportMultiDisplay() {
+        // Setup: there is no matched activity in the same package as selected primary home.
+        mockResolveHomeActivity(true /* primaryHome */, false /* forceSystemProvided */);
+        final List<ResolveInfo> resolutions = new ArrayList<>();
+        doReturn(resolutions).when(mRootWindowContainer).resolveActivities(anyInt(), any());
+        // Setup: set secondary home.
+        mockResolveHomeActivity(false /* primaryHome */, false /* forceSystemProvided */);
+
+        // Run the test.
+        final Pair<ActivityInfo, Intent> resolvedInfo = mRootWindowContainer
+                .resolveSecondaryHomeActivity(0 /* userId */, mock(TaskDisplayArea.class));
+        final ActivityInfo aInfoSecondary = getFakeHomeActivityInfo(false /* primaryHome*/);
+        assertEquals(aInfoSecondary.name, resolvedInfo.first.name);
+        assertEquals(aInfoSecondary.applicationInfo.packageName,
+                resolvedInfo.first.applicationInfo.packageName);
+    }
+    /**
+     * Tests that primary home activity should be selected if it already support secondary displays.
+     */
+    @Test
+    public void testResolveSecondaryHomeActivityWhenPrimaryHomeSupportMultiDisplay() {
+        // SetUp: set primary home.
+        mockResolveHomeActivity(true /* primaryHome */, false /* forceSystemProvided */);
+        // SetUp: put primary home info on 2nd item
+        final List<ResolveInfo> resolutions = new ArrayList<>();
+        final ResolveInfo infoFake1 = new ResolveInfo();
+        infoFake1.activityInfo = new ActivityInfo();
+        infoFake1.activityInfo.name = "fakeActivity1";
+        infoFake1.activityInfo.applicationInfo = new ApplicationInfo();
+        infoFake1.activityInfo.applicationInfo.packageName = "fakePackage1";
+        final ResolveInfo infoFake2 = new ResolveInfo();
+        final ActivityInfo aInfoPrimary = getFakeHomeActivityInfo(true /* primaryHome */);
+        infoFake2.activityInfo = aInfoPrimary;
+        resolutions.add(infoFake1);
+        resolutions.add(infoFake2);
+        doReturn(resolutions).when(mRootWindowContainer).resolveActivities(anyInt(), any());
+
+        doReturn(true).when(mRootWindowContainer).canStartHomeOnDisplayArea(any(), any(),
+                anyBoolean());
+
+        // Run the test.
+        final Pair<ActivityInfo, Intent> resolvedInfo = mRootWindowContainer
+                .resolveSecondaryHomeActivity(0 /* userId */, mock(TaskDisplayArea.class));
+        assertEquals(aInfoPrimary.name, resolvedInfo.first.name);
+        assertEquals(aInfoPrimary.applicationInfo.packageName,
+                resolvedInfo.first.applicationInfo.packageName);
+    }
+
+    /**
+     * Tests that the first one that matches should be selected if there are multiple activities.
+     */
+    @Test
+    public void testResolveSecondaryHomeActivityWhenOtherActivitySupportMultiDisplay() {
+        // SetUp: set primary home.
+        mockResolveHomeActivity(true /* primaryHome */, false /* forceSystemProvided */);
+        // Setup: prepare two eligible activity info.
+        final List<ResolveInfo> resolutions = new ArrayList<>();
+        final ResolveInfo infoFake1 = new ResolveInfo();
+        infoFake1.activityInfo = new ActivityInfo();
+        infoFake1.activityInfo.name = "fakeActivity1";
+        infoFake1.activityInfo.applicationInfo = new ApplicationInfo();
+        infoFake1.activityInfo.applicationInfo.packageName = "fakePackage1";
+        final ResolveInfo infoFake2 = new ResolveInfo();
+        infoFake2.activityInfo = new ActivityInfo();
+        infoFake2.activityInfo.name = "fakeActivity2";
+        infoFake2.activityInfo.applicationInfo = new ApplicationInfo();
+        infoFake2.activityInfo.applicationInfo.packageName = "fakePackage2";
+        resolutions.add(infoFake1);
+        resolutions.add(infoFake2);
+        doReturn(resolutions).when(mRootWindowContainer).resolveActivities(anyInt(), any());
+
+        doReturn(true).when(mRootWindowContainer).canStartHomeOnDisplayArea(any(), any(),
+                anyBoolean());
+
+        // Use the first one of matched activities in the same package as selected primary home.
+        final Pair<ActivityInfo, Intent> resolvedInfo = mRootWindowContainer
+                .resolveSecondaryHomeActivity(0 /* userId */, mock(TaskDisplayArea.class));
+
+        assertEquals(infoFake1.activityInfo.applicationInfo.packageName,
+                resolvedInfo.first.applicationInfo.packageName);
+        assertEquals(infoFake1.activityInfo.name, resolvedInfo.first.name);
+    }
+
+    /**
+     * Test that {@link RootWindowContainer#getLaunchRootTask} with the real caller id will get the
+     * expected root task when requesting the activity launch on the secondary display.
+     */
+    @Test
+    public void testGetLaunchRootTaskWithRealCallerId() {
+        // Create a non-system owned virtual display.
+        final TestDisplayContent secondaryDisplay =
+                new TestDisplayContent.Builder(mAtm, 1000, 1500)
+                        .setType(TYPE_VIRTUAL).setOwnerUid(100).build();
+
+        // Create an activity with specify the original launch pid / uid.
+        final ActivityRecord r = new ActivityBuilder(mAtm).setLaunchedFromPid(200)
+                .setLaunchedFromUid(200).build();
+
+        // Simulate ActivityStarter to find a launch root task for requesting the activity to launch
+        // on the secondary display with realCallerId.
+        final ActivityOptions options = ActivityOptions.makeBasic();
+        options.setLaunchDisplayId(secondaryDisplay.mDisplayId);
+        options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN);
+        doReturn(true).when(mSupervisor).canPlaceEntityOnDisplay(secondaryDisplay.mDisplayId,
+                300 /* test realCallerPid */, 300 /* test realCallerUid */, r.info);
+        final Task result = mRootWindowContainer.getLaunchRootTask(r, options,
+                null /* task */, true /* onTop */, null, 300 /* test realCallerPid */,
+                300 /* test realCallerUid */);
+
+        // Assert that the root task is returned as expected.
+        assertNotNull(result);
+        assertEquals("The display ID of the root task should same as secondary display ",
+                secondaryDisplay.mDisplayId, result.getDisplayId());
+    }
+
+    @Test
+    public void testGetValidLaunchRootTaskOnDisplayWithCandidateRootTask() {
+        // Create a root task with an activity on secondary display.
+        final TestDisplayContent secondaryDisplay = new TestDisplayContent.Builder(mAtm, 300,
+                600).build();
+        final Task task = new TaskBuilder(mSupervisor)
+                .setDisplay(secondaryDisplay).build();
+        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 */);
+        assertEquals(task, rootTask);
+    }
+
+    @Test
+    public void testSwitchUser_missingHomeRootTask() {
+        final Task fullscreenTask = mRootWindowContainer.getDefaultTaskDisplayArea().createRootTask(
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        doReturn(fullscreenTask).when(mRootWindowContainer).getTopDisplayFocusedRootTask();
+
+        final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
+        Task rootHomeTask = taskDisplayArea.getRootHomeTask();
+        if (rootHomeTask != null) {
+            rootHomeTask.removeImmediately();
+        }
+        assertNull(taskDisplayArea.getRootHomeTask());
+
+        int currentUser = mRootWindowContainer.mCurrentUser;
+        int otherUser = currentUser + 1;
+
+        mRootWindowContainer.switchUser(otherUser, null);
+
+        assertNotNull(taskDisplayArea.getRootHomeTask());
+        assertEquals(taskDisplayArea.getTopRootTask(), taskDisplayArea.getRootHomeTask());
+    }
+
+    /**
+     * Mock {@link RootWindowContainer#resolveHomeActivity} for returning consistent activity
+     * info for test cases.
+     *
+     * @param primaryHome Indicate to use primary home intent as parameter, otherwise, use
+     *                    secondary home intent.
+     * @param forceSystemProvided Indicate to force using system provided home activity.
+     */
+    private void mockResolveHomeActivity(boolean primaryHome, boolean forceSystemProvided) {
+        ActivityInfo targetActivityInfo = getFakeHomeActivityInfo(primaryHome);
+        Intent targetIntent;
+        if (primaryHome) {
+            targetIntent = mAtm.getHomeIntent();
+        } else {
+            Resources resources = mContext.getResources();
+            spyOn(resources);
+            doReturn(targetActivityInfo.applicationInfo.packageName).when(resources).getString(
+                    com.android.internal.R.string.config_secondaryHomePackage);
+            doReturn(forceSystemProvided).when(resources).getBoolean(
+                    com.android.internal.R.bool.config_useSystemProvidedLauncherForSecondary);
+            targetIntent = mAtm.getSecondaryHomeIntent(null /* preferredPackage */);
+        }
+        doReturn(targetActivityInfo).when(mRootWindowContainer).resolveHomeActivity(anyInt(),
+                refEq(targetIntent));
+    }
+
+    /**
+     * Mock {@link RootWindowContainer#resolveSecondaryHomeActivity} for returning consistent
+     * activity info for test cases.
+     */
+    private void mockResolveSecondaryHomeActivity() {
+        final Intent secondaryHomeIntent = mAtm
+                .getSecondaryHomeIntent(null /* preferredPackage */);
+        final ActivityInfo aInfoSecondary = getFakeHomeActivityInfo(false);
+        doReturn(Pair.create(aInfoSecondary, secondaryHomeIntent)).when(mRootWindowContainer)
+                .resolveSecondaryHomeActivity(anyInt(), any());
+    }
+
+    private ActivityInfo getFakeHomeActivityInfo(boolean primaryHome) {
+        final ActivityInfo aInfo = new ActivityInfo();
+        aInfo.name = primaryHome ? "fakeHomeActivity" : "fakeSecondaryHomeActivity";
+        aInfo.applicationInfo = new ApplicationInfo();
+        aInfo.applicationInfo.packageName =
+                primaryHome ? "fakeHomePackage" : "fakeSecondaryHomePackage";
+        return  aInfo;
+    }
 }
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
index 70c2971..97cead1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -132,8 +132,8 @@
         mTask.setBounds(bounds);
         prepareUnresizable(mActivity, -1.f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
         assertEquals(bounds, mActivity.getBounds());
-        // Activity is not yet in size compat mode; it is filling the freeform window.
-        assertMaxBoundsInheritDisplayAreaBounds();
+        // Activity is not yet in size compat mode; it is filling the freeform task window.
+        assertActivityMaxBoundsSandboxed();
 
         // The activity should be able to accept negative x position [-150, 100 - 150, 600].
         final int dx = bounds.left + bounds.width() / 2;
@@ -1388,7 +1388,7 @@
     }
 
     @Test
-    public void testSupportsNonResizableInSplitScreen() {
+    public void testSupportsNonResizableInSplitScreen_letterboxForDifferentOrientation() {
         // Support non resizable in multi window
         mAtm.mSupportsNonResizableMultiWindow = true;
         setUpDisplaySizeWithApp(1000, 2800);
@@ -1399,16 +1399,18 @@
         prepareUnresizable(mActivity, SCREEN_ORIENTATION_LANDSCAPE);
         final Rect originalBounds = new Rect(mActivity.getBounds());
 
-        // Move activity to split screen
+        // Move activity to split screen which takes half of the screen.
         mTask.reparent(organizer.mPrimary, POSITION_TOP,
                 false /*moveParents*/, "test");
+        organizer.mPrimary.setBounds(0, 0, 1000, 1400);
         assertEquals(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, mTask.getWindowingMode());
         assertEquals(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, mActivity.getWindowingMode());
 
         // Non-resizable activity in size compat mode
         assertScaled();
-        assertEquals(originalBounds,
-                mActivity.getConfiguration().windowConfiguration.getBounds());
+        final Rect newBounds = new Rect(mActivity.getWindowConfiguration().getBounds());
+        assertEquals(originalBounds.width(), newBounds.width());
+        assertEquals(originalBounds.height(), newBounds.height());
         assertActivityMaxBoundsSandboxed();
 
         // Recompute the natural configuration of the non-resizable activity and the split screen.
@@ -1440,6 +1442,54 @@
                 mActivity.getLetterboxInsets());
     }
 
+    @Test
+    public void testSupportsNonResizableInSplitScreen_fillTaskForSameOrientation() {
+        // Support non resizable in multi window
+        mAtm.mSupportsNonResizableMultiWindow = true;
+        setUpDisplaySizeWithApp(1000, 2800);
+        final TestSplitOrganizer organizer =
+                new TestSplitOrganizer(mAtm, mActivity.getDisplayContent());
+
+        // Non-resizable portrait activity
+        prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT);
+        final Rect originalBounds = new Rect(mActivity.getBounds());
+
+        // Move activity to split screen which takes half of the screen.
+        mTask.reparent(organizer.mPrimary, POSITION_TOP,
+                false /*moveParents*/, "test");
+        organizer.mPrimary.setBounds(0, 0, 1000, 1400);
+        assertEquals(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, mTask.getWindowingMode());
+        assertEquals(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, mActivity.getWindowingMode());
+
+        // Non-resizable activity in size compat mode
+        assertScaled();
+        final Rect newBounds = new Rect(mActivity.getWindowConfiguration().getBounds());
+        assertEquals(originalBounds.width(), newBounds.width());
+        assertEquals(originalBounds.height(), newBounds.height());
+        assertActivityMaxBoundsSandboxed();
+
+        // Recompute the natural configuration of the non-resizable activity and the split screen.
+        mActivity.clearSizeCompatMode();
+        mActivity.setVisible(false);
+        mActivity.mDisplayContent.prepareAppTransition(WindowManager.TRANSIT_OPEN);
+        mActivity.mDisplayContent.mOpeningApps.add(mActivity);
+        addWindowToActivity(mActivity);
+        mActivity.mRootWindowContainer.performSurfacePlacement();
+
+        // Split screen is also in portrait [1000,1400], which meets the activity request. It should
+        // sandbox to the activity bounds for non-resizable.
+        assertEquals(ORIENTATION_PORTRAIT, mTask.getConfiguration().orientation);
+        assertEquals(ORIENTATION_PORTRAIT, mActivity.getConfiguration().orientation);
+        assertFitted();
+        assertFalse(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+        assertActivityMaxBoundsSandboxed();
+
+        // Activity bounds fill split screen.
+        final Rect primarySplitBounds = new Rect(organizer.mPrimary.getBounds());
+        final Rect letterboxedBounds = new Rect(mActivity.getBounds());
+        assertEquals(primarySplitBounds, letterboxedBounds);
+    }
+
     private static WindowState addWindowToActivity(ActivityRecord activity) {
         final WindowManager.LayoutParams params = new WindowManager.LayoutParams();
         params.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java
index eba5634..92d4ede 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java
@@ -28,6 +28,7 @@
 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.WINDOWING_MODE_UNDEFINED;
+import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE;
 import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
@@ -35,13 +36,16 @@
 
 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.ActivityTaskSupervisor.ON_TOP;
 import static com.android.server.wm.Task.ActivityState.RESUMED;
+import static com.android.server.wm.WindowContainer.POSITION_TOP;
 
 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.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.anyInt;
@@ -56,8 +60,6 @@
 
 import com.android.server.wm.LaunchParamsController.LaunchParams;
 
-import org.junit.After;
-import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -72,35 +74,17 @@
 @RunWith(WindowTestRunner.class)
 public class TaskDisplayAreaTests extends WindowTestsBase {
 
-    private Task mPinnedTask;
-
-    @Before
-    public void setUp() throws Exception {
-        mPinnedTask = createTaskStackOnDisplay(
-                WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, mDisplayContent);
-        // Stack should contain visible app window to be considered visible.
-        assertFalse(mPinnedTask.isVisible());
-        final ActivityRecord pinnedApp = createNonAttachedActivityRecord(mDisplayContent);
-        mPinnedTask.addChild(pinnedApp, 0 /* addPos */);
-        assertTrue(mPinnedTask.isVisible());
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        mPinnedTask.removeImmediately();
-    }
-
     @Test
     public void getOrCreateLaunchRootRespectsResolvedWindowingMode() {
-        final Task rootTask = createTaskStackOnDisplay(
-                WINDOWING_MODE_MULTI_WINDOW, ACTIVITY_TYPE_STANDARD, mDisplayContent);
+        final Task rootTask = createTask(
+                mDisplayContent, WINDOWING_MODE_MULTI_WINDOW, ACTIVITY_TYPE_STANDARD);
         rootTask.mCreatedByOrganizer = true;
         final TaskDisplayArea taskDisplayArea = rootTask.getDisplayArea();
         taskDisplayArea.setLaunchRootTask(
                 rootTask, new int[]{WINDOWING_MODE_FREEFORM}, new int[]{ACTIVITY_TYPE_STANDARD});
 
-        final Task candidateRootTask = createTaskStackOnDisplay(
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, mDisplayContent);
+        final Task candidateRootTask = createTask(
+                mDisplayContent, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
         final ActivityRecord activity = createNonAttachedActivityRecord(mDisplayContent);
         final LaunchParams launchParams = new LaunchParams();
         launchParams.mWindowingMode = WINDOWING_MODE_FREEFORM;
@@ -113,15 +97,15 @@
 
     @Test
     public void getOrCreateLaunchRootUsesActivityOptionsWindowingMode() {
-        final Task rootTask = createTaskStackOnDisplay(
-                WINDOWING_MODE_MULTI_WINDOW, ACTIVITY_TYPE_STANDARD, mDisplayContent);
+        final Task rootTask = createTask(
+                mDisplayContent, WINDOWING_MODE_MULTI_WINDOW, ACTIVITY_TYPE_STANDARD);
         rootTask.mCreatedByOrganizer = true;
         final TaskDisplayArea taskDisplayArea = rootTask.getDisplayArea();
         taskDisplayArea.setLaunchRootTask(
                 rootTask, new int[]{WINDOWING_MODE_FREEFORM}, new int[]{ACTIVITY_TYPE_STANDARD});
 
-        final Task candidateRootTask = createTaskStackOnDisplay(
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, mDisplayContent);
+        final Task candidateRootTask = createTask(
+                mDisplayContent, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
         final ActivityRecord activity = createNonAttachedActivityRecord(mDisplayContent);
         final ActivityOptions options = ActivityOptions.makeBasic();
         options.setLaunchWindowingMode(WINDOWING_MODE_FREEFORM);
@@ -134,9 +118,8 @@
 
     @Test
     public void testActivityWithZBoost_taskDisplayAreaDoesNotMoveUp() {
-        final Task stack = createTaskStackOnDisplay(
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, mDisplayContent);
-        final Task task = createTaskInStack(stack, 0 /* userId */);
+        final Task rootTask = createTask(mDisplayContent);
+        final Task task = createTaskInRootTask(rootTask, 0 /* userId */);
         final ActivityRecord activity = createNonAttachedActivityRecord(mDisplayContent);
         task.addChild(activity, 0 /* addPos */);
         final TaskDisplayArea taskDisplayArea = activity.getDisplayArea();
@@ -152,87 +135,103 @@
     }
 
     @Test
-    public void testStackPositionChildAt() {
-        // Test that always-on-top stack can't be moved to position other than top.
-        final Task stack1 = createTaskStackOnDisplay(mDisplayContent);
-        final Task stack2 = createTaskStackOnDisplay(mDisplayContent);
+    public void testRootTaskPositionChildAt() {
+        Task pinnedTask = createTask(
+                mDisplayContent, WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD);
+        // Root task should contain visible app window to be considered visible.
+        assertFalse(pinnedTask.isVisible());
+        final ActivityRecord pinnedApp = createNonAttachedActivityRecord(mDisplayContent);
+        pinnedTask.addChild(pinnedApp, 0 /* addPos */);
+        assertTrue(pinnedTask.isVisible());
 
-        final WindowContainer taskStackContainer = stack1.getParent();
+        // Test that always-on-top root task can't be moved to position other than top.
+        final Task rootTask1 = createTask(mDisplayContent);
+        final Task rootTask2 = createTask(mDisplayContent);
 
-        final int stack1Pos = taskStackContainer.mChildren.indexOf(stack1);
-        final int stack2Pos = taskStackContainer.mChildren.indexOf(stack2);
-        final int pinnedStackPos = taskStackContainer.mChildren.indexOf(mPinnedTask);
-        assertThat(pinnedStackPos).isGreaterThan(stack2Pos);
-        assertThat(stack2Pos).isGreaterThan(stack1Pos);
+        final WindowContainer taskContainer = rootTask1.getParent();
 
-        taskStackContainer.positionChildAt(WindowContainer.POSITION_BOTTOM, mPinnedTask, false);
-        assertEquals(taskStackContainer.mChildren.get(stack1Pos), stack1);
-        assertEquals(taskStackContainer.mChildren.get(stack2Pos), stack2);
-        assertEquals(taskStackContainer.mChildren.get(pinnedStackPos), mPinnedTask);
+        final int rootTask1Pos = taskContainer.mChildren.indexOf(rootTask1);
+        final int rootTask2Pos = taskContainer.mChildren.indexOf(rootTask2);
+        final int pinnedTaskPos = taskContainer.mChildren.indexOf(pinnedTask);
+        assertThat(pinnedTaskPos).isGreaterThan(rootTask2Pos);
+        assertThat(rootTask2Pos).isGreaterThan(rootTask1Pos);
 
-        taskStackContainer.positionChildAt(1, mPinnedTask, false);
-        assertEquals(taskStackContainer.mChildren.get(stack1Pos), stack1);
-        assertEquals(taskStackContainer.mChildren.get(stack2Pos), stack2);
-        assertEquals(taskStackContainer.mChildren.get(pinnedStackPos), mPinnedTask);
+        taskContainer.positionChildAt(WindowContainer.POSITION_BOTTOM, pinnedTask, false);
+        assertEquals(taskContainer.mChildren.get(rootTask1Pos), rootTask1);
+        assertEquals(taskContainer.mChildren.get(rootTask2Pos), rootTask2);
+        assertEquals(taskContainer.mChildren.get(pinnedTaskPos), pinnedTask);
+
+        taskContainer.positionChildAt(1, pinnedTask, false);
+        assertEquals(taskContainer.mChildren.get(rootTask1Pos), rootTask1);
+        assertEquals(taskContainer.mChildren.get(rootTask2Pos), rootTask2);
+        assertEquals(taskContainer.mChildren.get(pinnedTaskPos), pinnedTask);
     }
 
     @Test
-    public void testStackPositionBelowPinnedStack() {
-        // Test that no stack can be above pinned stack.
-        final Task stack1 = createTaskStackOnDisplay(mDisplayContent);
+    public void testRootTaskPositionBelowPinnedRootTask() {
+        Task pinnedTask = createTask(
+                mDisplayContent, WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD);
+        // Root task should contain visible app window to be considered visible.
+        assertFalse(pinnedTask.isVisible());
+        final ActivityRecord pinnedApp = createNonAttachedActivityRecord(mDisplayContent);
+        pinnedTask.addChild(pinnedApp, 0 /* addPos */);
+        assertTrue(pinnedTask.isVisible());
 
-        final WindowContainer taskStackContainer = stack1.getParent();
+        // Test that no root task can be above pinned root task.
+        final Task rootTask1 = createTask(mDisplayContent);
 
-        final int stackPos = taskStackContainer.mChildren.indexOf(stack1);
-        final int pinnedStackPos = taskStackContainer.mChildren.indexOf(mPinnedTask);
-        assertThat(pinnedStackPos).isGreaterThan(stackPos);
+        final WindowContainer taskContainer = rootTask1.getParent();
 
-        taskStackContainer.positionChildAt(WindowContainer.POSITION_TOP, stack1, false);
-        assertEquals(taskStackContainer.mChildren.get(stackPos), stack1);
-        assertEquals(taskStackContainer.mChildren.get(pinnedStackPos), mPinnedTask);
+        final int rootTaskPos = taskContainer.mChildren.indexOf(rootTask1);
+        final int pinnedTaskPos = taskContainer.mChildren.indexOf(pinnedTask);
+        assertThat(pinnedTaskPos).isGreaterThan(rootTaskPos);
 
-        taskStackContainer.positionChildAt(taskStackContainer.mChildren.size() - 1, stack1, false);
-        assertEquals(taskStackContainer.mChildren.get(stackPos), stack1);
-        assertEquals(taskStackContainer.mChildren.get(pinnedStackPos), mPinnedTask);
+        taskContainer.positionChildAt(WindowContainer.POSITION_TOP, rootTask1, false);
+        assertEquals(taskContainer.mChildren.get(rootTaskPos), rootTask1);
+        assertEquals(taskContainer.mChildren.get(pinnedTaskPos), pinnedTask);
+
+        taskContainer.positionChildAt(taskContainer.mChildren.size() - 1, rootTask1, false);
+        assertEquals(taskContainer.mChildren.get(rootTaskPos), rootTask1);
+        assertEquals(taskContainer.mChildren.get(pinnedTaskPos), pinnedTask);
     }
 
     @Test
-    public void testDisplayPositionWithPinnedStack() {
-        // Make sure the display is trusted display which capable to move the stack to top.
+    public void testDisplayPositionWithPinnedRootTask() {
+        // Make sure the display is trusted display which capable to move the root task to top.
         spyOn(mDisplayContent);
         doReturn(true).when(mDisplayContent).isTrusted();
 
-        // Allow child stack to move to top.
+        // Allow child root task to move to top.
         mDisplayContent.mDontMoveToTop = false;
 
-        // The display contains pinned stack that was added in {@link #setUp}.
-        final Task stack = createTaskStackOnDisplay(mDisplayContent);
-        final Task task = createTaskInStack(stack, 0 /* userId */);
+        // The display contains pinned root task that was added in {@link #setUp}.
+        final Task rootTask = createTask(mDisplayContent);
+        final Task task = createTaskInRootTask(rootTask, 0 /* userId */);
 
         // Add another display at top.
         mWm.mRoot.positionChildAt(WindowContainer.POSITION_TOP, createNewDisplay(),
                 false /* includingParents */);
 
         // Move the task of {@code mDisplayContent} to top.
-        stack.positionChildAt(WindowContainer.POSITION_TOP, task, true /* includingParents */);
-        final int indexOfDisplayWithPinnedStack = mWm.mRoot.mChildren.indexOf(mDisplayContent);
+        rootTask.positionChildAt(WindowContainer.POSITION_TOP, task, true /* includingParents */);
+        final int indexOfDisplayWithPinnedRootTask = mWm.mRoot.mChildren.indexOf(mDisplayContent);
 
         assertEquals("The testing DisplayContent should be moved to top with task",
-                mWm.mRoot.getChildCount() - 1, indexOfDisplayWithPinnedStack);
+                mWm.mRoot.getChildCount() - 1, indexOfDisplayWithPinnedRootTask);
     }
 
     @Test
     public void testMovingChildTaskOnTop() {
-        // Make sure the display is trusted display which capable to move the stack to top.
+        // Make sure the display is trusted display which capable to move the root task to top.
         spyOn(mDisplayContent);
         doReturn(true).when(mDisplayContent).isTrusted();
 
-        // Allow child stack to move to top.
+        // Allow child root task to move to top.
         mDisplayContent.mDontMoveToTop = false;
 
-        // The display contains pinned stack that was added in {@link #setUp}.
-        Task stack = createTaskStackOnDisplay(mDisplayContent);
-        Task task = createTaskInStack(stack, 0 /* userId */);
+        // The display contains pinned root task that was added in {@link #setUp}.
+        Task rootTask = createTask(mDisplayContent);
+        Task task = createTaskInRootTask(rootTask, 0 /* userId */);
 
         // Add another display at top.
         mWm.mRoot.positionChildAt(WindowContainer.POSITION_TOP, createNewDisplay(),
@@ -243,7 +242,7 @@
                 mWm.mRoot.getChildCount() - 2, mWm.mRoot.mChildren.indexOf(mDisplayContent));
 
         // Move the task of {@code mDisplayContent} to top.
-        stack.positionChildAt(WindowContainer.POSITION_TOP, task, true /* includingParents */);
+        rootTask.positionChildAt(WindowContainer.POSITION_TOP, task, true /* includingParents */);
 
         // Ensure that original display ({@code mDisplayContent}) is now on the top.
         assertEquals("The testing DisplayContent should be moved to top with task",
@@ -252,16 +251,16 @@
 
     @Test
     public void testDontMovingChildTaskOnTop() {
-        // Make sure the display is trusted display which capable to move the stack to top.
+        // Make sure the display is trusted display which capable to move the root task to top.
         spyOn(mDisplayContent);
         doReturn(true).when(mDisplayContent).isTrusted();
 
-        // Allow child stack to move to top.
+        // Allow child root task to move to top.
         mDisplayContent.mDontMoveToTop = true;
 
-        // The display contains pinned stack that was added in {@link #setUp}.
-        Task stack = createTaskStackOnDisplay(mDisplayContent);
-        Task task = createTaskInStack(stack, 0 /* userId */);
+        // The display contains pinned root task that was added in {@link #setUp}.
+        Task rootTask = createTask(mDisplayContent);
+        Task task = createTaskInRootTask(rootTask, 0 /* userId */);
 
         // Add another display at top.
         mWm.mRoot.positionChildAt(WindowContainer.POSITION_TOP, createNewDisplay(),
@@ -272,7 +271,7 @@
                 mWm.mRoot.getChildCount() - 2, mWm.mRoot.mChildren.indexOf(mDisplayContent));
 
         // Try moving the task of {@code mDisplayContent} to top.
-        stack.positionChildAt(WindowContainer.POSITION_TOP, task, true /* includingParents */);
+        rootTask.positionChildAt(WindowContainer.POSITION_TOP, task, true /* includingParents */);
 
         // Ensure that original display ({@code mDisplayContent}) hasn't moved and is not
         // on the top.
@@ -282,8 +281,7 @@
 
     @Test
     public void testReuseTaskAsRootTask() {
-        final Task candidateTask = createTaskStackOnDisplay(WINDOWING_MODE_FULLSCREEN,
-                ACTIVITY_TYPE_STANDARD, mDisplayContent);
+        final Task candidateTask = createTask(mDisplayContent);
         final int type = ACTIVITY_TYPE_STANDARD;
         assertGetOrCreateRootTask(WINDOWING_MODE_FULLSCREEN, type, candidateTask,
                 true /* reuseCandidate */);
@@ -312,7 +310,7 @@
     }
 
     @Test
-    public void testGetOrientation_nonResizableHomeStackWithHomeActivityPendingVisibilityChange() {
+    public void testGetOrientation_nonResizableHomeTaskWithHomeActivityPendingVisibilityChange() {
         final RootWindowContainer rootWindowContainer = mWm.mAtmService.mRootWindowContainer;
         final TaskDisplayArea defaultTaskDisplayArea =
                 rootWindowContainer.getDefaultTaskDisplayArea();
@@ -330,7 +328,7 @@
         ActivityRecord primarySplitActivity = primarySplitTask.getTopNonFinishingActivity();
         assertNotNull(primarySplitActivity);
         primarySplitActivity.setState(RESUMED,
-                "testGetOrientation_nonResizableHomeStackWithHomeActivityPendingVisibilityChange");
+                "testGetOrientation_nonResizableHomeTaskWithHomeActivityPendingVisibilityChange");
 
         ActivityRecord homeActivity = rootHomeTask.getTopNonFinishingActivity();
         if (homeActivity == null) {
@@ -350,14 +348,14 @@
         final TaskDisplayArea secondTaskDisplayArea = createTaskDisplayArea(
                 mDisplayContent, mRootWindowContainer.mWmService, "TestTaskDisplayArea",
                 FEATURE_VENDOR_FIRST);
-        final Task firstStack = firstTaskDisplayArea.createRootTask(
+        final Task firstRootTask = firstTaskDisplayArea.createRootTask(
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
-        final Task secondStack = secondTaskDisplayArea.createRootTask(
+        final Task secondRootTask = secondTaskDisplayArea.createRootTask(
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
         final ActivityRecord firstActivity = new ActivityBuilder(mAtm)
-                .setTask(firstStack).build();
+                .setTask(firstRootTask).build();
         final ActivityRecord secondActivity = new ActivityBuilder(mAtm)
-                .setTask(secondStack).build();
+                .setTask(secondRootTask).build();
 
         // Activity on TDA1 is focused
         mDisplayContent.setFocusedApp(firstActivity);
@@ -384,14 +382,14 @@
         final TaskDisplayArea secondTaskDisplayArea = createTaskDisplayArea(
                 mDisplayContent, mRootWindowContainer.mWmService, "TestTaskDisplayArea",
                 FEATURE_VENDOR_FIRST);
-        final Task firstStack = firstTaskDisplayArea.createRootTask(
+        final Task firstRootTask = firstTaskDisplayArea.createRootTask(
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
-        final Task secondStack = secondTaskDisplayArea.createRootTask(
+        final Task secondRootTask = secondTaskDisplayArea.createRootTask(
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
         final ActivityRecord firstActivity = new ActivityBuilder(mAtm)
-                .setTask(firstStack).build();
+                .setTask(firstRootTask).build();
         final ActivityRecord secondActivity = new ActivityBuilder(mAtm)
-                .setTask(secondStack).build();
+                .setTask(secondRootTask).build();
         firstTaskDisplayArea.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
         secondTaskDisplayArea.setIgnoreOrientationRequest(false /* ignoreOrientationRequest */);
 
@@ -411,9 +409,9 @@
     @Test
     public void testIgnoreOrientationRequest() {
         final TaskDisplayArea taskDisplayArea = mDisplayContent.getDefaultTaskDisplayArea();
-        final Task stack = taskDisplayArea.createRootTask(
+        final Task task = taskDisplayArea.createRootTask(
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
-        final ActivityRecord activity = new ActivityBuilder(mAtm).setTask(stack).build();
+        final ActivityRecord activity = new ActivityBuilder(mAtm).setTask(task).build();
 
         mDisplayContent.setFocusedApp(activity);
         activity.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE);
@@ -428,7 +426,7 @@
     @Test
     @UseTestDisplay
     public void testRemove_reparentToDefault() {
-        final Task task = createTaskStackOnDisplay(mDisplayContent);
+        final Task task = createTask(mDisplayContent);
         final TaskDisplayArea displayArea = task.getDisplayArea();
         displayArea.remove();
         assertTrue(displayArea.isRemoved());
@@ -442,8 +440,8 @@
 
     @Test
     @UseTestDisplay
-    public void testRemove_stackCreatedByOrganizer() {
-        final Task task = createTaskStackOnDisplay(mDisplayContent);
+    public void testRemove_rootTaskCreatedByOrganizer() {
+        final Task task = createTask(mDisplayContent);
         task.mCreatedByOrganizer = true;
         final TaskDisplayArea displayArea = task.getDisplayArea();
         displayArea.remove();
@@ -464,4 +462,221 @@
                 null /* activityOptions */);
         assertEquals(reuseCandidate, rootTask == candidateTask);
     }
+
+    @Test
+    public void testGetOrCreateRootHomeTask_defaultDisplay() {
+        TaskDisplayArea defaultTaskDisplayArea = mWm.mRoot.getDefaultTaskDisplayArea();
+
+        // Remove the current home root task if it exists so a new one can be created below.
+        Task homeTask = defaultTaskDisplayArea.getRootHomeTask();
+        if (homeTask != null) {
+            defaultTaskDisplayArea.removeChild(homeTask);
+        }
+        assertNull(defaultTaskDisplayArea.getRootHomeTask());
+
+        assertNotNull(defaultTaskDisplayArea.getOrCreateRootHomeTask());
+    }
+
+    @Test
+    public void testGetOrCreateRootHomeTask_supportedSecondaryDisplay() {
+        DisplayContent display = createNewDisplay();
+        doReturn(true).when(display).supportsSystemDecorations();
+
+        // Remove the current home root task if it exists so a new one can be created below.
+        TaskDisplayArea taskDisplayArea = display.getDefaultTaskDisplayArea();
+        Task homeTask = taskDisplayArea.getRootHomeTask();
+        if (homeTask != null) {
+            taskDisplayArea.removeChild(homeTask);
+        }
+        assertNull(taskDisplayArea.getRootHomeTask());
+
+        assertNotNull(taskDisplayArea.getOrCreateRootHomeTask());
+    }
+
+    @Test
+    public void testGetOrCreateRootHomeTask_unsupportedSystemDecorations() {
+        DisplayContent display = createNewDisplay();
+        TaskDisplayArea taskDisplayArea = display.getDefaultTaskDisplayArea();
+        doReturn(false).when(display).supportsSystemDecorations();
+
+        assertNull(taskDisplayArea.getRootHomeTask());
+        assertNull(taskDisplayArea.getOrCreateRootHomeTask());
+    }
+
+    @Test
+    public void testGetOrCreateRootHomeTask_untrustedDisplay() {
+        DisplayContent display = createNewDisplay();
+        TaskDisplayArea taskDisplayArea = display.getDefaultTaskDisplayArea();
+        doReturn(false).when(display).isTrusted();
+
+        assertNull(taskDisplayArea.getRootHomeTask());
+        assertNull(taskDisplayArea.getOrCreateRootHomeTask());
+    }
+
+    @Test
+    public void testGetOrCreateRootHomeTask_dontMoveToTop() {
+        DisplayContent display = createNewDisplay();
+        display.mDontMoveToTop = true;
+        TaskDisplayArea taskDisplayArea = display.getDefaultTaskDisplayArea();
+
+        assertNull(taskDisplayArea.getRootHomeTask());
+        assertNull(taskDisplayArea.getOrCreateRootHomeTask());
+    }
+
+    @Test
+    public void testLastFocusedRootTaskIsUpdatedWhenMovingRootTask() {
+        // Create a root task at bottom.
+        final TaskDisplayArea taskDisplayAreas =
+                mRootWindowContainer.getDefaultDisplay().getDefaultTaskDisplayArea();
+        final Task rootTask =
+                new TaskBuilder(mSupervisor).setOnTop(!ON_TOP).setCreateActivity(true).build();
+        final Task prevFocusedRootTask = taskDisplayAreas.getFocusedRootTask();
+
+        rootTask.moveToFront("moveRootTaskToFront");
+        // After moving the root task to front, the previous focused should be the last focused.
+        assertTrue(rootTask.isFocusedRootTaskOnDisplay());
+        assertEquals(prevFocusedRootTask, taskDisplayAreas.getLastFocusedRootTask());
+
+        rootTask.moveToBack("moveRootTaskToBack", null /* task */);
+        // After moving the root task to back, the root task should be the last focused.
+        assertEquals(rootTask, taskDisplayAreas.getLastFocusedRootTask());
+    }
+
+    /**
+     * This test simulates the picture-in-picture menu activity launches an activity to fullscreen
+     * root task. The fullscreen root task should be the top focused for resuming correctly.
+     */
+    @Test
+    public void testFullscreenRootTaskCanBeFocusedWhenFocusablePinnedRootTaskExists() {
+        // Create a pinned root task and move to front.
+        final Task pinnedRootTask = mRootWindowContainer.getDefaultTaskDisplayArea()
+                .createRootTask(WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, ON_TOP);
+        final Task pinnedTask = new TaskBuilder(mAtm.mTaskSupervisor)
+                .setParentTask(pinnedRootTask).build();
+        new ActivityBuilder(mAtm).setActivityFlags(FLAG_ALWAYS_FOCUSABLE)
+                .setTask(pinnedTask).build();
+        pinnedRootTask.moveToFront("movePinnedRootTaskToFront");
+
+        // The focused root task should be the pinned root task.
+        assertTrue(pinnedRootTask.isFocusedRootTaskOnDisplay());
+
+        // Create a fullscreen root task and move to front.
+        final Task fullscreenRootTask = createTaskWithActivity(
+                mRootWindowContainer.getDefaultTaskDisplayArea(),
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, ON_TOP, true);
+        fullscreenRootTask.moveToFront("moveFullscreenRootTaskToFront");
+
+        // The focused root task should be the fullscreen root task.
+        assertTrue(fullscreenRootTask.isFocusedRootTaskOnDisplay());
+    }
+
+    /**
+     * Test {@link TaskDisplayArea#mPreferredTopFocusableRootTask} will be cleared when
+     * the root task is removed or moved to back, and the focused root task will be according to
+     * z-order.
+     */
+    @Test
+    public void testRootTaskShouldNotBeFocusedAfterMovingToBackOrRemoving() {
+        // Create a display which only contains 2 root task.
+        final DisplayContent display = addNewDisplayContentAt(POSITION_TOP);
+        final Task rootTask1 = createTaskWithActivity(display.getDefaultTaskDisplayArea(),
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, ON_TOP, true /* twoLevelTask */);
+        final Task rootTask2 = createTaskWithActivity(display.getDefaultTaskDisplayArea(),
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, ON_TOP, true /* twoLevelTask */);
+
+        // Put rootTask1 and rootTask2 on top.
+        rootTask1.moveToFront("moveRootTask1ToFront");
+        rootTask2.moveToFront("moveRootTask2ToFront");
+        assertTrue(rootTask2.isFocusedRootTaskOnDisplay());
+
+        // rootTask1 should be focused after moving rootTask2 to back.
+        rootTask2.moveToBack("moveRootTask2ToBack", null /* task */);
+        assertTrue(rootTask1.isFocusedRootTaskOnDisplay());
+
+        // rootTask2 should be focused after removing rootTask1.
+        rootTask1.getDisplayArea().removeRootTask(rootTask1);
+        assertTrue(rootTask2.isFocusedRootTaskOnDisplay());
+    }
+
+    /**
+     * This test enforces that alwaysOnTop root task is placed at proper position.
+     */
+    @Test
+    public void testAlwaysOnTopRootTaskLocation() {
+        final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
+        final Task alwaysOnTopRootTask = taskDisplayArea.createRootTask(WINDOWING_MODE_FREEFORM,
+                ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        final ActivityRecord activity = new ActivityBuilder(mAtm)
+                .setTask(alwaysOnTopRootTask).build();
+        alwaysOnTopRootTask.setAlwaysOnTop(true);
+        taskDisplayArea.positionChildAt(POSITION_TOP, alwaysOnTopRootTask,
+                false /* includingParents */);
+        assertTrue(alwaysOnTopRootTask.isAlwaysOnTop());
+        // Ensure always on top state is synced to the children of the root task.
+        assertTrue(alwaysOnTopRootTask.getTopNonFinishingActivity().isAlwaysOnTop());
+        assertEquals(alwaysOnTopRootTask, taskDisplayArea.getTopRootTask());
+
+        final Task pinnedRootTask = taskDisplayArea.createRootTask(
+                WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        assertEquals(pinnedRootTask, taskDisplayArea.getRootPinnedTask());
+        assertEquals(pinnedRootTask, taskDisplayArea.getTopRootTask());
+
+        final Task anotherAlwaysOnTopRootTask = taskDisplayArea.createRootTask(
+                WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        anotherAlwaysOnTopRootTask.setAlwaysOnTop(true);
+        taskDisplayArea.positionChildAt(POSITION_TOP, anotherAlwaysOnTopRootTask,
+                false /* includingParents */);
+        assertTrue(anotherAlwaysOnTopRootTask.isAlwaysOnTop());
+        int topPosition = taskDisplayArea.getRootTaskCount() - 1;
+        // Ensure the new alwaysOnTop root task is put below the pinned root task, but on top of the
+        // existing alwaysOnTop root task.
+        assertEquals(topPosition - 1, getTaskIndexOf(taskDisplayArea, anotherAlwaysOnTopRootTask));
+
+        final Task nonAlwaysOnTopRootTask = taskDisplayArea.createRootTask(
+                WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        assertEquals(taskDisplayArea, nonAlwaysOnTopRootTask.getDisplayArea());
+        topPosition = taskDisplayArea.getRootTaskCount() - 1;
+        // Ensure the non-alwaysOnTop root task is put below the three alwaysOnTop root tasks, but
+        // above the existing other non-alwaysOnTop root tasks.
+        assertEquals(topPosition - 3, getTaskIndexOf(taskDisplayArea, nonAlwaysOnTopRootTask));
+
+        anotherAlwaysOnTopRootTask.setAlwaysOnTop(false);
+        taskDisplayArea.positionChildAt(POSITION_TOP, anotherAlwaysOnTopRootTask,
+                false /* includingParents */);
+        assertFalse(anotherAlwaysOnTopRootTask.isAlwaysOnTop());
+        // Ensure, when always on top is turned off for a root task, the root task is put just below
+        // all other always on top root tasks.
+        assertEquals(topPosition - 2, getTaskIndexOf(taskDisplayArea, anotherAlwaysOnTopRootTask));
+        anotherAlwaysOnTopRootTask.setAlwaysOnTop(true);
+
+        // Ensure always on top state changes properly when windowing mode changes.
+        anotherAlwaysOnTopRootTask.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+        assertFalse(anotherAlwaysOnTopRootTask.isAlwaysOnTop());
+        assertEquals(topPosition - 2, getTaskIndexOf(taskDisplayArea, anotherAlwaysOnTopRootTask));
+        anotherAlwaysOnTopRootTask.setWindowingMode(WINDOWING_MODE_FREEFORM);
+        assertTrue(anotherAlwaysOnTopRootTask.isAlwaysOnTop());
+        assertEquals(topPosition - 1, getTaskIndexOf(taskDisplayArea, anotherAlwaysOnTopRootTask));
+
+        final Task dreamRootTask = taskDisplayArea.createRootTask(
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_DREAM, true /* onTop */);
+        assertEquals(taskDisplayArea, dreamRootTask.getDisplayArea());
+        assertTrue(dreamRootTask.isAlwaysOnTop());
+        topPosition = taskDisplayArea.getRootTaskCount() - 1;
+        // Ensure dream shows above all activities, including PiP
+        assertEquals(dreamRootTask, taskDisplayArea.getTopRootTask());
+        assertEquals(topPosition - 1, getTaskIndexOf(taskDisplayArea, pinnedRootTask));
+
+        final Task assistRootTask = taskDisplayArea.createRootTask(
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT, true /* onTop */);
+        assertEquals(taskDisplayArea, assistRootTask.getDisplayArea());
+        assertFalse(assistRootTask.isAlwaysOnTop());
+        topPosition = taskDisplayArea.getRootTaskCount() - 1;
+
+        // Ensure Assistant shows as a non-always-on-top activity when config_assistantOnTopOfDream
+        // is false and on top of everything when true.
+        final boolean isAssistantOnTop = mContext.getResources()
+                .getBoolean(com.android.internal.R.bool.config_assistantOnTopOfDream);
+        assertEquals(isAssistantOnTop ? topPosition : topPosition - 4,
+                getTaskIndexOf(taskDisplayArea, assistRootTask));
+    }
 }
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 ed57294..de4c40d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
@@ -403,8 +403,8 @@
     public void testOverridesDisplayAreaWithStandardTypeAndFullscreenMode() {
         final TaskDisplayArea secondaryDisplayArea = createTaskDisplayArea(mDefaultDisplay,
                 mWm, "SecondaryDisplayArea", FEATURE_RUNTIME_TASK_CONTAINER_FIRST);
-        final Task launchRoot = createTaskStackOnTaskDisplayArea(WINDOWING_MODE_FULLSCREEN,
-                ACTIVITY_TYPE_STANDARD, secondaryDisplayArea);
+        final Task launchRoot = createTask(secondaryDisplayArea, WINDOWING_MODE_FULLSCREEN,
+                ACTIVITY_TYPE_STANDARD);
         launchRoot.mCreatedByOrganizer = true;
 
         secondaryDisplayArea.setLaunchRootTask(launchRoot, new int[] { WINDOWING_MODE_FULLSCREEN },
@@ -419,8 +419,8 @@
     public void testOverridesDisplayAreaWithHomeTypeAndFullscreenMode() {
         final TaskDisplayArea secondaryDisplayArea = createTaskDisplayArea(mDefaultDisplay,
                 mWm, "SecondaryDisplayArea", FEATURE_RUNTIME_TASK_CONTAINER_FIRST);
-        final Task launchRoot = createTaskStackOnTaskDisplayArea(WINDOWING_MODE_FULLSCREEN,
-                ACTIVITY_TYPE_STANDARD, secondaryDisplayArea);
+        final Task launchRoot = createTask(secondaryDisplayArea, WINDOWING_MODE_FULLSCREEN,
+                ACTIVITY_TYPE_STANDARD);
         launchRoot.mCreatedByOrganizer = true;
 
         mActivity.setActivityType(ACTIVITY_TYPE_HOME);
@@ -438,8 +438,8 @@
                 WINDOWING_MODE_FREEFORM);
         final TaskDisplayArea secondaryDisplayArea = createTaskDisplayArea(freeformDisplay,
                 mWm, "SecondaryDisplayArea", FEATURE_RUNTIME_TASK_CONTAINER_FIRST);
-        final Task launchRoot = createTaskStackOnTaskDisplayArea(WINDOWING_MODE_FULLSCREEN,
-                ACTIVITY_TYPE_STANDARD, secondaryDisplayArea);
+        final Task launchRoot = createTask(secondaryDisplayArea, WINDOWING_MODE_FULLSCREEN,
+                ACTIVITY_TYPE_STANDARD);
         launchRoot.mCreatedByOrganizer = true;
 
         secondaryDisplayArea.setLaunchRootTask(launchRoot, new int[] { WINDOWING_MODE_FREEFORM },
@@ -455,8 +455,8 @@
     public void testNotOverrideDisplayAreaWhenActivityOptionsHasDisplayArea() {
         final TaskDisplayArea secondaryDisplayArea = createTaskDisplayArea(mDefaultDisplay,
                 mWm, "SecondaryDisplayArea", FEATURE_RUNTIME_TASK_CONTAINER_FIRST);
-        final Task launchRoot = createTaskStackOnTaskDisplayArea(WINDOWING_MODE_FULLSCREEN,
-                ACTIVITY_TYPE_STANDARD, secondaryDisplayArea);
+        final Task launchRoot = createTask(secondaryDisplayArea, WINDOWING_MODE_FULLSCREEN,
+                ACTIVITY_TYPE_STANDARD);
         launchRoot.mCreatedByOrganizer = true;
 
         secondaryDisplayArea.setLaunchRootTask(launchRoot, new int[] { WINDOWING_MODE_FULLSCREEN },
@@ -481,8 +481,8 @@
                 mWm, "SecondaryDisplayArea", FEATURE_RUNTIME_TASK_CONTAINER_FIRST);
         secondaryDisplayArea.setBounds(DISPLAY_BOUNDS.width() / 2, 0,
                         DISPLAY_BOUNDS.width(), DISPLAY_BOUNDS.height());
-        final Task launchRoot = createTaskStackOnTaskDisplayArea(WINDOWING_MODE_FULLSCREEN,
-                ACTIVITY_TYPE_STANDARD, secondaryDisplayArea);
+        final Task launchRoot = createTask(secondaryDisplayArea, WINDOWING_MODE_FULLSCREEN,
+                ACTIVITY_TYPE_STANDARD);
         launchRoot.mCreatedByOrganizer = true;
         secondaryDisplayArea.setLaunchRootTask(launchRoot, new int[] { WINDOWING_MODE_FREEFORM },
                 new int[] { ACTIVITY_TYPE_STANDARD });
@@ -512,8 +512,8 @@
                 mWm, "SecondaryDisplayArea", FEATURE_RUNTIME_TASK_CONTAINER_FIRST);
         secondaryDisplayArea.setBounds(DISPLAY_BOUNDS.width() / 2, 0,
                 DISPLAY_BOUNDS.width(), DISPLAY_BOUNDS.height());
-        final Task launchRoot = createTaskStackOnTaskDisplayArea(WINDOWING_MODE_FULLSCREEN,
-                ACTIVITY_TYPE_STANDARD, secondaryDisplayArea);
+        final Task launchRoot = createTask(secondaryDisplayArea, WINDOWING_MODE_FULLSCREEN,
+                ACTIVITY_TYPE_STANDARD);
         launchRoot.mCreatedByOrganizer = true;
         secondaryDisplayArea.setLaunchRootTask(launchRoot, new int[] { WINDOWING_MODE_FREEFORM },
                 new int[] { ACTIVITY_TYPE_STANDARD });
@@ -1687,16 +1687,16 @@
     }
 
     private ActivityRecord createSourceActivity(TestDisplayContent display) {
-        final Task stack = display.getDefaultTaskDisplayArea()
+        final Task rootTask = display.getDefaultTaskDisplayArea()
                 .createRootTask(display.getWindowingMode(), ACTIVITY_TYPE_STANDARD, true);
-        return new ActivityBuilder(mAtm).setTask(stack).build();
+        return new ActivityBuilder(mAtm).setTask(rootTask).build();
     }
 
     private void addFreeformTaskTo(TestDisplayContent display, Rect bounds) {
-        final Task stack = display.getDefaultTaskDisplayArea()
+        final Task rootTask = display.getDefaultTaskDisplayArea()
                 .createRootTask(display.getWindowingMode(), ACTIVITY_TYPE_STANDARD, true);
-        stack.setWindowingMode(WINDOWING_MODE_FREEFORM);
-        final Task task = new TaskBuilder(mSupervisor).setParentTask(stack).build();
+        rootTask.setWindowingMode(WINDOWING_MODE_FREEFORM);
+        final Task task = new TaskBuilder(mSupervisor).setParentTask(rootTask).build();
         // Just work around the unnecessary adjustments for bounds.
         task.getWindowConfiguration().setBounds(bounds);
     }
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
deleted file mode 100644
index d853b93..0000000
--- a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
+++ /dev/null
@@ -1,1161 +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.server.wm;
-
-import static android.app.ActivityTaskManager.INVALID_TASK_ID;
-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.app.WindowConfiguration.WINDOWING_MODE_PINNED;
-import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
-import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
-import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
-import static android.content.pm.ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY;
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
-import static android.util.DisplayMetrics.DENSITY_DEFAULT;
-import static android.view.IWindowManager.FIXED_TO_USER_ROTATION_ENABLED;
-import static android.view.Surface.ROTATION_0;
-import static android.view.Surface.ROTATION_90;
-import static android.window.DisplayAreaOrganizer.FEATURE_VENDOR_FIRST;
-
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq;
-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.spyOn;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
-import static com.android.server.policy.WindowManagerPolicy.USER_ROTATION_FREE;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.hamcrest.Matchers.not;
-import static org.hamcrest.Matchers.sameInstance;
-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;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.same;
-
-import android.app.ActivityManager;
-import android.app.TaskInfo;
-import android.app.WindowConfiguration;
-import android.content.ComponentName;
-import android.content.Intent;
-import android.content.pm.ActivityInfo;
-import android.content.pm.ApplicationInfo;
-import android.content.res.Configuration;
-import android.graphics.Rect;
-import android.os.IBinder;
-import android.platform.test.annotations.Presubmit;
-import android.util.DisplayMetrics;
-import android.util.TypedXmlPullParser;
-import android.util.TypedXmlSerializer;
-import android.util.Xml;
-import android.view.DisplayInfo;
-
-import androidx.test.filters.MediumTest;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.Reader;
-
-/**
- * Tests for exercising {@link Task}.
- *
- * Build/Install/Run:
- *  atest WmTests:TaskRecordTests
- */
-@MediumTest
-@Presubmit
-@RunWith(WindowTestRunner.class)
-public class TaskRecordTests extends WindowTestsBase {
-
-    private static final String TASK_TAG = "task";
-
-    private Rect mParentBounds;
-
-    @Before
-    public void setUp() throws Exception {
-        mParentBounds = new Rect(10 /*left*/, 30 /*top*/, 80 /*right*/, 60 /*bottom*/);
-        removeGlobalMinSizeRestriction();
-    }
-
-    @Test
-    public void testRestoreWindowedTask() throws Exception {
-        final Task expected = createTask(64);
-        expected.mLastNonFullscreenBounds = new Rect(50, 50, 100, 100);
-
-        final byte[] serializedBytes = serializeToBytes(expected);
-        final Task actual = restoreFromBytes(serializedBytes);
-        assertEquals(expected.mTaskId, actual.mTaskId);
-        assertEquals(expected.mLastNonFullscreenBounds, actual.mLastNonFullscreenBounds);
-    }
-
-    /** Ensure we have no chance to modify the original intent. */
-    @Test
-    public void testCopyBaseIntentForTaskInfo() {
-        final Task task = createTask(1);
-        task.setTaskDescription(new ActivityManager.TaskDescription());
-        final TaskInfo info = task.getTaskInfo();
-
-        // The intent of info should be a copy so assert that they are different instances.
-        assertThat(info.baseIntent, not(sameInstance(task.getBaseIntent())));
-    }
-
-    @Test
-    public void testReturnsToHomeStack() throws Exception {
-        final Task task = createTask(1);
-        spyOn(task);
-        doReturn(true).when(task).hasChild();
-        assertFalse(task.returnsToHomeRootTask());
-        task.intent = null;
-        assertFalse(task.returnsToHomeRootTask());
-        task.intent = new Intent();
-        assertFalse(task.returnsToHomeRootTask());
-        task.intent.addFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME);
-        assertTrue(task.returnsToHomeRootTask());
-    }
-
-    /** Ensures that empty bounds cause appBounds to inherit from parent. */
-    @Test
-    public void testAppBounds_EmptyBounds() {
-        final Rect emptyBounds = new Rect();
-        testStackBoundsConfiguration(WINDOWING_MODE_FULLSCREEN, mParentBounds, emptyBounds,
-                mParentBounds);
-    }
-
-    /** Ensures that bounds on freeform stacks are not clipped. */
-    @Test
-    public void testAppBounds_FreeFormBounds() {
-        final Rect freeFormBounds = new Rect(mParentBounds);
-        freeFormBounds.offset(10, 10);
-        testStackBoundsConfiguration(WINDOWING_MODE_FREEFORM, mParentBounds, freeFormBounds,
-                freeFormBounds);
-    }
-
-    /** Ensures that fully contained bounds are not clipped. */
-    @Test
-    public void testAppBounds_ContainedBounds() {
-        final Rect insetBounds = new Rect(mParentBounds);
-        insetBounds.inset(5, 5, 5, 5);
-        testStackBoundsConfiguration(
-                WINDOWING_MODE_FREEFORM, mParentBounds, insetBounds, insetBounds);
-    }
-
-    @Test
-    public void testFitWithinBounds() {
-        final Rect parentBounds = new Rect(10, 10, 200, 200);
-        TaskDisplayArea taskDisplayArea = mAtm.mRootWindowContainer.getDefaultTaskDisplayArea();
-        Task stack = taskDisplayArea.createRootTask(WINDOWING_MODE_FREEFORM,
-                ACTIVITY_TYPE_STANDARD, true /* onTop */);
-        Task task = new TaskBuilder(mSupervisor).setParentTask(stack).build();
-        final Configuration parentConfig = stack.getConfiguration();
-        parentConfig.windowConfiguration.setBounds(parentBounds);
-        parentConfig.densityDpi = DisplayMetrics.DENSITY_DEFAULT;
-
-        // check top and left
-        Rect reqBounds = new Rect(-190, -190, 0, 0);
-        task.setBounds(reqBounds);
-        // Make sure part of it is exposed
-        assertTrue(task.getBounds().right > parentBounds.left);
-        assertTrue(task.getBounds().bottom > parentBounds.top);
-        // Should still be more-or-less in that corner
-        assertTrue(task.getBounds().left <= parentBounds.left);
-        assertTrue(task.getBounds().top <= parentBounds.top);
-
-        assertEquals(reqBounds.width(), task.getBounds().width());
-        assertEquals(reqBounds.height(), task.getBounds().height());
-
-        // check bottom and right
-        reqBounds = new Rect(210, 210, 400, 400);
-        task.setBounds(reqBounds);
-        // Make sure part of it is exposed
-        assertTrue(task.getBounds().left < parentBounds.right);
-        assertTrue(task.getBounds().top < parentBounds.bottom);
-        // Should still be more-or-less in that corner
-        assertTrue(task.getBounds().right >= parentBounds.right);
-        assertTrue(task.getBounds().bottom >= parentBounds.bottom);
-
-        assertEquals(reqBounds.width(), task.getBounds().width());
-        assertEquals(reqBounds.height(), task.getBounds().height());
-    }
-
-    /** Tests that the task bounds adjust properly to changes between FULLSCREEN and FREEFORM */
-    @Test
-    public void testBoundsOnModeChangeFreeformToFullscreen() {
-        DisplayContent display = mAtm.mRootWindowContainer.getDefaultDisplay();
-        Task stack = new TaskBuilder(mSupervisor).setDisplay(display).setCreateActivity(true)
-                .setWindowingMode(WINDOWING_MODE_FREEFORM).build();
-        Task task = stack.getBottomMostTask();
-        task.getRootActivity().setOrientation(SCREEN_ORIENTATION_UNSPECIFIED);
-        DisplayInfo info = new DisplayInfo();
-        display.mDisplay.getDisplayInfo(info);
-        final Rect fullScreenBounds = new Rect(0, 0, info.logicalWidth, info.logicalHeight);
-        final Rect freeformBounds = new Rect(fullScreenBounds);
-        freeformBounds.inset((int) (freeformBounds.width() * 0.2),
-                (int) (freeformBounds.height() * 0.2));
-        task.setBounds(freeformBounds);
-
-        assertEquals(freeformBounds, task.getBounds());
-
-        // FULLSCREEN inherits bounds
-        stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
-        assertEquals(fullScreenBounds, task.getBounds());
-        assertEquals(freeformBounds, task.mLastNonFullscreenBounds);
-
-        // FREEFORM restores bounds
-        stack.setWindowingMode(WINDOWING_MODE_FREEFORM);
-        assertEquals(freeformBounds, task.getBounds());
-    }
-
-    /**
-     * Tests that a task with forced orientation has orientation-consistent bounds within the
-     * parent.
-     */
-    @Test
-    public void testFullscreenBoundsForcedOrientation() {
-        final Rect fullScreenBounds = new Rect(0, 0, 1920, 1080);
-        final Rect fullScreenBoundsPort = new Rect(0, 0, 1080, 1920);
-        final DisplayContent display = new TestDisplayContent.Builder(mAtm,
-                fullScreenBounds.width(), fullScreenBounds.height()).setCanRotate(false).build();
-        assertNotNull(mRootWindowContainer.getDisplayContent(display.mDisplayId));
-        // Fix the display orientation to landscape which is the natural rotation (0) for the test
-        // display.
-        final DisplayRotation dr = display.mDisplayContent.getDisplayRotation();
-        dr.setFixedToUserRotation(FIXED_TO_USER_ROTATION_ENABLED);
-        dr.setUserRotation(USER_ROTATION_FREE, ROTATION_0);
-
-        final Task stack = new TaskBuilder(mSupervisor).setCreateActivity(true)
-                .setWindowingMode(WINDOWING_MODE_FULLSCREEN).setDisplay(display).build();
-        final Task task = stack.getBottomMostTask();
-        final ActivityRecord root = task.getTopNonFinishingActivity();
-
-        assertEquals(fullScreenBounds, task.getBounds());
-
-        // Setting app to fixed portrait fits within parent
-        root.setRequestedOrientation(SCREEN_ORIENTATION_PORTRAIT);
-        assertEquals(root, task.getRootActivity());
-        assertEquals(SCREEN_ORIENTATION_PORTRAIT, task.getRootActivity().getOrientation());
-        // Portrait orientation is enforced on activity level. Task should fill fullscreen bounds.
-        assertThat(task.getBounds().height()).isLessThan(task.getBounds().width());
-        assertEquals(fullScreenBounds, task.getBounds());
-
-        // Top activity gets used
-        final ActivityRecord top = new ActivityBuilder(mAtm).setTask(task).setParentTask(stack)
-                .build();
-        assertEquals(top, task.getTopNonFinishingActivity());
-        top.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE);
-        assertThat(task.getBounds().width()).isGreaterThan(task.getBounds().height());
-        assertEquals(task.getBounds().width(), fullScreenBounds.width());
-
-        // Setting app to unspecified restores
-        top.setRequestedOrientation(SCREEN_ORIENTATION_UNSPECIFIED);
-        assertEquals(fullScreenBounds, task.getBounds());
-
-        // Setting app to fixed landscape and changing display
-        top.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE);
-        // Fix the display orientation to portrait which is 90 degrees for the test display.
-        dr.setUserRotation(USER_ROTATION_FREE, ROTATION_90);
-
-        // Fixed orientation request should be resolved on activity level. Task fills display
-        // bounds.
-        assertThat(task.getBounds().height()).isGreaterThan(task.getBounds().width());
-        assertThat(top.getBounds().width()).isGreaterThan(top.getBounds().height());
-        assertEquals(fullScreenBoundsPort, task.getBounds());
-
-        // in FREEFORM, no constraint
-        final Rect freeformBounds = new Rect(display.getBounds());
-        freeformBounds.inset((int) (freeformBounds.width() * 0.2),
-                (int) (freeformBounds.height() * 0.2));
-        stack.setWindowingMode(WINDOWING_MODE_FREEFORM);
-        task.setBounds(freeformBounds);
-        assertEquals(freeformBounds, task.getBounds());
-
-        // FULLSCREEN letterboxes bounds on activity level, no constraint on task level.
-        stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
-        assertThat(task.getBounds().height()).isGreaterThan(task.getBounds().width());
-        assertThat(top.getBounds().width()).isGreaterThan(top.getBounds().height());
-        assertEquals(fullScreenBoundsPort, task.getBounds());
-
-        // FREEFORM restores bounds as before
-        stack.setWindowingMode(WINDOWING_MODE_FREEFORM);
-        assertEquals(freeformBounds, task.getBounds());
-    }
-
-    @Test
-    public void testReportsOrientationRequestInLetterboxForOrientation() {
-        final Rect fullScreenBounds = new Rect(0, 0, 1920, 1080);
-        final Rect fullScreenBoundsPort = new Rect(0, 0, 1080, 1920);
-        final DisplayContent display = new TestDisplayContent.Builder(mAtm,
-                fullScreenBounds.width(), fullScreenBounds.height()).setCanRotate(false).build();
-        assertNotNull(mRootWindowContainer.getDisplayContent(display.mDisplayId));
-        // Fix the display orientation to landscape which is the natural rotation (0) for the test
-        // display.
-        final DisplayRotation dr = display.mDisplayContent.getDisplayRotation();
-        dr.setFixedToUserRotation(FIXED_TO_USER_ROTATION_ENABLED);
-        dr.setUserRotation(USER_ROTATION_FREE, ROTATION_0);
-
-        final Task stack = new TaskBuilder(mSupervisor).setCreateActivity(true)
-                .setWindowingMode(WINDOWING_MODE_FULLSCREEN).setDisplay(display).build();
-        final Task task = stack.getBottomMostTask();
-        ActivityRecord root = task.getTopNonFinishingActivity();
-
-        assertEquals(fullScreenBounds, task.getBounds());
-
-        // Setting app to fixed portrait fits within parent on activity level. Task fills parent.
-        root.setRequestedOrientation(SCREEN_ORIENTATION_PORTRAIT);
-        assertThat(root.getBounds().width()).isLessThan(root.getBounds().height());
-        assertEquals(task.getBounds(), fullScreenBounds);
-
-        assertEquals(SCREEN_ORIENTATION_PORTRAIT, task.getOrientation());
-    }
-
-    @Test
-    public void testIgnoresForcedOrientationWhenParentHandles() {
-        final Rect fullScreenBounds = new Rect(0, 0, 1920, 1080);
-        DisplayContent display = new TestDisplayContent.Builder(
-                mAtm, fullScreenBounds.width(), fullScreenBounds.height()).build();
-
-        display.getRequestedOverrideConfiguration().orientation =
-                Configuration.ORIENTATION_LANDSCAPE;
-        display.onRequestedOverrideConfigurationChanged(
-                display.getRequestedOverrideConfiguration());
-        Task stack = new TaskBuilder(mSupervisor).setCreateActivity(true)
-                .setWindowingMode(WINDOWING_MODE_FULLSCREEN).setDisplay(display).build();
-        Task task = stack.getBottomMostTask();
-        ActivityRecord root = task.getTopNonFinishingActivity();
-
-        final WindowContainer parentWindowContainer =
-                new WindowContainer(mSystemServicesTestRule.getWindowManagerService());
-        spyOn(parentWindowContainer);
-        parentWindowContainer.setBounds(fullScreenBounds);
-        doReturn(parentWindowContainer).when(task).getParent();
-        doReturn(display.getDefaultTaskDisplayArea()).when(task).getDisplayArea();
-        doReturn(stack).when(task).getRootTask();
-        doReturn(true).when(parentWindowContainer).handlesOrientationChangeFromDescendant();
-
-        // Setting app to fixed portrait fits within parent, but Task shouldn't adjust the
-        // bounds because its parent says it will handle it at a later time.
-        root.setRequestedOrientation(SCREEN_ORIENTATION_PORTRAIT);
-        assertEquals(root, task.getRootActivity());
-        assertEquals(SCREEN_ORIENTATION_PORTRAIT, task.getRootActivity().getOrientation());
-        assertEquals(fullScreenBounds, task.getBounds());
-    }
-
-    @Test
-    public void testComputeConfigResourceOverrides() {
-        final Rect fullScreenBounds = new Rect(0, 0, 1080, 1920);
-        TestDisplayContent display = new TestDisplayContent.Builder(
-                mAtm, fullScreenBounds.width(), fullScreenBounds.height()).build();
-        final Task task = new TaskBuilder(mSupervisor).setDisplay(display).build();
-        final Configuration inOutConfig = new Configuration();
-        final Configuration parentConfig = new Configuration();
-        final int longSide = 1200;
-        final int shortSide = 600;
-        final Rect parentBounds = new Rect(0, 0, 250, 500);
-        final Rect parentAppBounds = new Rect(0, 0, 250, 480);
-        parentConfig.windowConfiguration.setBounds(parentBounds);
-        parentConfig.windowConfiguration.setAppBounds(parentAppBounds);
-        parentConfig.densityDpi = 400;
-        parentConfig.screenHeightDp = (parentBounds.bottom * 160) / parentConfig.densityDpi; // 200
-        parentConfig.screenWidthDp = (parentBounds.right * 160) / parentConfig.densityDpi; // 100
-        parentConfig.windowConfiguration.setRotation(ROTATION_0);
-
-        // By default, the input bounds will fill parent.
-        task.computeConfigResourceOverrides(inOutConfig, parentConfig);
-
-        assertEquals(parentConfig.screenHeightDp, inOutConfig.screenHeightDp);
-        assertEquals(parentConfig.screenWidthDp, inOutConfig.screenWidthDp);
-        assertEquals(parentAppBounds, inOutConfig.windowConfiguration.getAppBounds());
-        assertEquals(Configuration.ORIENTATION_PORTRAIT, inOutConfig.orientation);
-
-        // If bounds are overridden, config properties should be made to match. Surface hierarchy
-        // will crop for policy.
-        inOutConfig.setToDefaults();
-        final Rect largerPortraitBounds = new Rect(0, 0, shortSide, longSide);
-        inOutConfig.windowConfiguration.setBounds(largerPortraitBounds);
-        task.computeConfigResourceOverrides(inOutConfig, parentConfig);
-        // The override bounds are beyond the parent, the out appBounds should not be intersected
-        // by parent appBounds.
-        assertEquals(largerPortraitBounds, inOutConfig.windowConfiguration.getAppBounds());
-        assertEquals(longSide, inOutConfig.screenHeightDp * parentConfig.densityDpi / 160);
-        assertEquals(shortSide, inOutConfig.screenWidthDp * parentConfig.densityDpi / 160);
-
-        inOutConfig.setToDefaults();
-        // Landscape bounds.
-        final Rect largerLandscapeBounds = new Rect(0, 0, longSide, shortSide);
-        inOutConfig.windowConfiguration.setBounds(largerLandscapeBounds);
-
-        // Setup the display with a top stable inset. The later assertion will ensure the inset is
-        // excluded from screenHeightDp.
-        final int statusBarHeight = 100;
-        final DisplayPolicy policy = display.getDisplayPolicy();
-        doAnswer(invocationOnMock -> {
-            final Rect insets = invocationOnMock.<Rect>getArgument(0);
-            insets.top = statusBarHeight;
-            return null;
-        }).when(policy).convertNonDecorInsetsToStableInsets(any(), eq(ROTATION_0));
-
-        // Without limiting to be inside the parent bounds, the out screen size should keep relative
-        // to the input bounds.
-        final ActivityRecord activity = new ActivityBuilder(mAtm).setTask(task).build();
-        final ActivityRecord.CompatDisplayInsets compatIntsets =
-                new ActivityRecord.CompatDisplayInsets(
-                        display, activity, /* fixedOrientationBounds= */ null);
-        task.computeConfigResourceOverrides(inOutConfig, parentConfig, compatIntsets);
-
-        assertEquals(largerLandscapeBounds, inOutConfig.windowConfiguration.getAppBounds());
-        assertEquals((shortSide - statusBarHeight) * DENSITY_DEFAULT / parentConfig.densityDpi,
-                inOutConfig.screenHeightDp);
-        assertEquals(longSide * DENSITY_DEFAULT / parentConfig.densityDpi,
-                inOutConfig.screenWidthDp);
-        assertEquals(Configuration.ORIENTATION_LANDSCAPE, inOutConfig.orientation);
-    }
-
-    @Test
-    public void testComputeConfigResourceLayoutOverrides() {
-        final Rect fullScreenBounds = new Rect(0, 0, 1000, 2500);
-        TestDisplayContent display = new TestDisplayContent.Builder(
-                mAtm, fullScreenBounds.width(), fullScreenBounds.height()).build();
-        final Task task = new TaskBuilder(mSupervisor).setDisplay(display).build();
-        final Configuration inOutConfig = new Configuration();
-        final Configuration parentConfig = new Configuration();
-        final Rect nonLongBounds = new Rect(0, 0, 1000, 1250);
-        parentConfig.windowConfiguration.setBounds(fullScreenBounds);
-        parentConfig.windowConfiguration.setAppBounds(fullScreenBounds);
-        parentConfig.densityDpi = 400;
-        parentConfig.screenHeightDp = (fullScreenBounds.bottom * 160) / parentConfig.densityDpi;
-        parentConfig.screenWidthDp = (fullScreenBounds.right * 160) / parentConfig.densityDpi;
-        parentConfig.windowConfiguration.setRotation(ROTATION_0);
-
-        // Set BOTH screenW/H to an override value
-        inOutConfig.screenWidthDp = nonLongBounds.width() * 160 / parentConfig.densityDpi;
-        inOutConfig.screenHeightDp = nonLongBounds.height() * 160 / parentConfig.densityDpi;
-        task.computeConfigResourceOverrides(inOutConfig, parentConfig);
-
-        // screenLayout should honor override when both screenW/H are set.
-        assertTrue((inOutConfig.screenLayout & Configuration.SCREENLAYOUT_LONG_NO) != 0);
-    }
-
-    @Test
-    public void testComputeNestedConfigResourceOverrides() {
-        final Task task = new TaskBuilder(mSupervisor).build();
-        assertTrue(task.getResolvedOverrideBounds().isEmpty());
-        int origScreenH = task.getConfiguration().screenHeightDp;
-        Configuration stackConfig = new Configuration();
-        stackConfig.setTo(task.getRootTask().getRequestedOverrideConfiguration());
-        stackConfig.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM);
-
-        // Set bounds on stack (not task) and verify that the task resource configuration changes
-        // despite it's override bounds being empty.
-        Rect bounds = new Rect(task.getRootTask().getBounds());
-        bounds.bottom = (int) (bounds.bottom * 0.6f);
-        stackConfig.windowConfiguration.setBounds(bounds);
-        task.getRootTask().onRequestedOverrideConfigurationChanged(stackConfig);
-        assertNotEquals(origScreenH, task.getConfiguration().screenHeightDp);
-    }
-
-    @Test
-    public void testFullScreenTaskNotAdjustedByMinimalSize() {
-        final Task fullscreenTask = new TaskBuilder(mSupervisor).build();
-        final Rect originalTaskBounds = new Rect(fullscreenTask.getBounds());
-        final ActivityInfo aInfo = new ActivityInfo();
-        aInfo.windowLayout = new ActivityInfo.WindowLayout(0 /* width */, 0 /* widthFraction */,
-                    0 /* height */, 0 /* heightFraction */, 0 /* gravity */,
-                    originalTaskBounds.width() * 2 /* minWidth */,
-                    originalTaskBounds.height() * 2 /* minHeight */);
-        fullscreenTask.setMinDimensions(aInfo);
-        fullscreenTask.onConfigurationChanged(fullscreenTask.getParent().getConfiguration());
-
-        assertEquals(originalTaskBounds, fullscreenTask.getBounds());
-    }
-
-    @Test
-    public void testInsetDisregardedWhenFreeformOverlapsNavBar() {
-        TaskDisplayArea taskDisplayArea = mAtm.mRootWindowContainer.getDefaultTaskDisplayArea();
-        Task stack = taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
-                ACTIVITY_TYPE_STANDARD, true /* onTop */);
-        DisplayInfo displayInfo = new DisplayInfo();
-        mAtm.mContext.getDisplay().getDisplayInfo(displayInfo);
-        final int displayHeight = displayInfo.logicalHeight;
-        final Task task = new TaskBuilder(mSupervisor).setParentTask(stack).build();
-        final Configuration inOutConfig = new Configuration();
-        final Configuration parentConfig = new Configuration();
-        final int longSide = 1200;
-        final int shortSide = 600;
-        parentConfig.densityDpi = 400;
-        parentConfig.screenHeightDp = 200; // 200 * 400 / 160 = 500px
-        parentConfig.screenWidthDp = 100; // 100 * 400 / 160 = 250px
-        parentConfig.windowConfiguration.setRotation(ROTATION_0);
-
-        final int longSideDp = 480; // longSide / density = 1200 / 400 * 160
-        final int shortSideDp = 240; // shortSide / density = 600 / 400 * 160
-        final int screenLayout = parentConfig.screenLayout
-                & (Configuration.SCREENLAYOUT_LONG_MASK | Configuration.SCREENLAYOUT_SIZE_MASK);
-        final int reducedScreenLayout =
-                Configuration.reduceScreenLayout(screenLayout, longSideDp, shortSideDp);
-
-        // Portrait bounds overlapping with navigation bar, without insets.
-        final Rect freeformBounds = new Rect(0,
-                displayHeight - 10 - longSide,
-                shortSide,
-                displayHeight - 10);
-        inOutConfig.windowConfiguration.setBounds(freeformBounds);
-        // Set to freeform mode to verify bug fix.
-        inOutConfig.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM);
-
-        task.computeConfigResourceOverrides(inOutConfig, parentConfig);
-
-        // screenW/H should not be effected by parent since overridden and freeform
-        assertEquals(freeformBounds.width() * 160 / parentConfig.densityDpi,
-                inOutConfig.screenWidthDp);
-        assertEquals(freeformBounds.height() * 160 / parentConfig.densityDpi,
-                inOutConfig.screenHeightDp);
-        assertEquals(reducedScreenLayout, inOutConfig.screenLayout);
-
-        inOutConfig.setToDefaults();
-        // Landscape bounds overlapping with navigtion bar, without insets.
-        freeformBounds.set(0,
-                displayHeight - 10 - shortSide,
-                longSide,
-                displayHeight - 10);
-        inOutConfig.windowConfiguration.setBounds(freeformBounds);
-        inOutConfig.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM);
-
-        task.computeConfigResourceOverrides(inOutConfig, parentConfig);
-
-        assertEquals(freeformBounds.width() * 160 / parentConfig.densityDpi,
-                inOutConfig.screenWidthDp);
-        assertEquals(freeformBounds.height() * 160 / parentConfig.densityDpi,
-                inOutConfig.screenHeightDp);
-        assertEquals(reducedScreenLayout, inOutConfig.screenLayout);
-    }
-
-    /** Ensures that the alias intent won't have target component resolved. */
-    @Test
-    public void testTaskIntentActivityAlias() {
-        final String aliasClassName = DEFAULT_COMPONENT_PACKAGE_NAME + ".aliasActivity";
-        final String targetClassName = DEFAULT_COMPONENT_PACKAGE_NAME + ".targetActivity";
-        final ComponentName aliasComponent =
-                new ComponentName(DEFAULT_COMPONENT_PACKAGE_NAME, aliasClassName);
-        final ComponentName targetComponent =
-                new ComponentName(DEFAULT_COMPONENT_PACKAGE_NAME, targetClassName);
-
-        final Intent intent = new Intent();
-        intent.setComponent(aliasComponent);
-        final ActivityInfo info = new ActivityInfo();
-        info.applicationInfo = new ApplicationInfo();
-        info.packageName = DEFAULT_COMPONENT_PACKAGE_NAME;
-        info.targetActivity = targetClassName;
-
-        final Task task = new Task.Builder(mAtm)
-                .setTaskId(1)
-                .setActivityInfo(info)
-                .setIntent(intent)
-                .build();
-        assertEquals("The alias activity component should be saved in task intent.", aliasClassName,
-                task.intent.getComponent().getClassName());
-
-        ActivityRecord aliasActivity = new ActivityBuilder(mAtm).setComponent(
-                aliasComponent).setTargetActivity(targetClassName).build();
-        assertEquals("Should be the same intent filter.", true,
-                task.isSameIntentFilter(aliasActivity));
-
-        ActivityRecord targetActivity = new ActivityBuilder(mAtm).setComponent(
-                targetComponent).build();
-        assertEquals("Should be the same intent filter.", true,
-                task.isSameIntentFilter(targetActivity));
-
-        ActivityRecord defaultActivity = new ActivityBuilder(mAtm).build();
-        assertEquals("Should not be the same intent filter.", false,
-                task.isSameIntentFilter(defaultActivity));
-    }
-
-    /** Test that root activity index is reported correctly for several activities in the task. */
-    @Test
-    public void testFindRootIndex() {
-        final Task task = getTestTask();
-        // Add an extra activity on top of the root one
-        new ActivityBuilder(mAtm).setTask(task).build();
-
-        assertEquals("The root activity in the task must be reported.", task.getChildAt(0),
-                task.getRootActivity(
-                        true /*ignoreRelinquishIdentity*/, true /*setToBottomIfNone*/));
-    }
-
-    /**
-     * Test that root activity index is reported correctly for several activities in the task when
-     * the activities on the bottom are finishing.
-     */
-    @Test
-    public void testFindRootIndex_finishing() {
-        final Task task = getTestTask();
-        // Add extra two activities and mark the two on the bottom as finishing.
-        final ActivityRecord activity0 = task.getBottomMostActivity();
-        activity0.finishing = true;
-        final ActivityRecord activity1 = new ActivityBuilder(mAtm).setTask(task).build();
-        activity1.finishing = true;
-        new ActivityBuilder(mAtm).setTask(task).build();
-
-        assertEquals("The first non-finishing activity in the task must be reported.",
-                task.getChildAt(2), task.getRootActivity(
-                        true /*ignoreRelinquishIdentity*/, true /*setToBottomIfNone*/));
-    }
-
-    /**
-     * Test that root activity index is reported correctly for several activities in the task when
-     * looking for the 'effective root'.
-     */
-    @Test
-    public void testFindRootIndex_effectiveRoot() {
-        final Task task = getTestTask();
-        // Add an extra activity on top of the root one
-        new ActivityBuilder(mAtm).setTask(task).build();
-
-        assertEquals("The root activity in the task must be reported.",
-                task.getChildAt(0), task.getRootActivity(
-                        false /*ignoreRelinquishIdentity*/, true /*setToBottomIfNone*/));
-    }
-
-    /**
-     * Test that root activity index is reported correctly when looking for the 'effective root' in
-     * case when bottom activities are relinquishing task identity or finishing.
-     */
-    @Test
-    public void testFindRootIndex_effectiveRoot_finishingAndRelinquishing() {
-        final Task task = getTestTask();
-        // Add extra two activities. Mark the one on the bottom with "relinquishTaskIdentity" and
-        // one above as finishing.
-        final ActivityRecord activity0 = task.getBottomMostActivity();
-        activity0.info.flags |= FLAG_RELINQUISH_TASK_IDENTITY;
-        final ActivityRecord activity1 = new ActivityBuilder(mAtm).setTask(task).build();
-        activity1.finishing = true;
-        new ActivityBuilder(mAtm).setTask(task).build();
-
-        assertEquals("The first non-finishing activity and non-relinquishing task identity "
-                + "must be reported.", task.getChildAt(2), task.getRootActivity(
-                        false /*ignoreRelinquishIdentity*/, true /*setToBottomIfNone*/));
-    }
-
-    /**
-     * Test that root activity index is reported correctly when looking for the 'effective root'
-     * for the case when there is only a single activity that also has relinquishTaskIdentity set.
-     */
-    @Test
-    public void testFindRootIndex_effectiveRoot_relinquishingAndSingleActivity() {
-        final Task task = getTestTask();
-        // Set relinquishTaskIdentity for the only activity in the task
-        task.getBottomMostActivity().info.flags |= FLAG_RELINQUISH_TASK_IDENTITY;
-
-        assertEquals("The root activity in the task must be reported.",
-                task.getChildAt(0), task.getRootActivity(
-                        false /*ignoreRelinquishIdentity*/, true /*setToBottomIfNone*/));
-    }
-
-    /**
-     * Test that the topmost activity index is reported correctly when looking for the
-     * 'effective root' for the case when all activities have relinquishTaskIdentity set.
-     */
-    @Test
-    public void testFindRootIndex_effectiveRoot_relinquishingMultipleActivities() {
-        final Task task = getTestTask();
-        // Set relinquishTaskIdentity for all activities in the task
-        final ActivityRecord activity0 = task.getBottomMostActivity();
-        activity0.info.flags |= FLAG_RELINQUISH_TASK_IDENTITY;
-        final ActivityRecord activity1 = new ActivityBuilder(mAtm).setTask(task).build();
-        activity1.info.flags |= FLAG_RELINQUISH_TASK_IDENTITY;
-
-        assertEquals("The topmost activity in the task must be reported.",
-                task.getChildAt(task.getChildCount() - 1), task.getRootActivity(
-                        false /*ignoreRelinquishIdentity*/, true /*setToBottomIfNone*/));
-    }
-
-    /** Test that bottom-most activity is reported in {@link Task#getRootActivity()}. */
-    @Test
-    public void testGetRootActivity() {
-        final Task task = getTestTask();
-        // Add an extra activity on top of the root one
-        new ActivityBuilder(mAtm).setTask(task).build();
-
-        assertEquals("The root activity in the task must be reported.",
-                task.getBottomMostActivity(), task.getRootActivity());
-    }
-
-    /**
-     * Test that first non-finishing activity is reported in {@link Task#getRootActivity()}.
-     */
-    @Test
-    public void testGetRootActivity_finishing() {
-        final Task task = getTestTask();
-        // Add an extra activity on top of the root one
-        new ActivityBuilder(mAtm).setTask(task).build();
-        // Mark the root as finishing
-        task.getBottomMostActivity().finishing = true;
-
-        assertEquals("The first non-finishing activity in the task must be reported.",
-                task.getChildAt(1), task.getRootActivity());
-    }
-
-    /**
-     * Test that relinquishTaskIdentity flag is ignored in {@link Task#getRootActivity()}.
-     */
-    @Test
-    public void testGetRootActivity_relinquishTaskIdentity() {
-        final Task task = getTestTask();
-        // Mark the bottom-most activity with FLAG_RELINQUISH_TASK_IDENTITY.
-        final ActivityRecord activity0 = task.getBottomMostActivity();
-        activity0.info.flags |= FLAG_RELINQUISH_TASK_IDENTITY;
-        // Add an extra activity on top of the root one.
-        new ActivityBuilder(mAtm).setTask(task).build();
-
-        assertEquals("The root activity in the task must be reported.",
-                task.getBottomMostActivity(), task.getRootActivity());
-    }
-
-    /**
-     * Test that no activity is reported in {@link Task#getRootActivity()} when all activities
-     * in the task are finishing.
-     */
-    @Test
-    public void testGetRootActivity_allFinishing() {
-        final Task task = getTestTask();
-        // Mark the bottom-most activity as finishing.
-        final ActivityRecord activity0 = task.getBottomMostActivity();
-        activity0.finishing = true;
-        // Add an extra activity on top of the root one and mark it as finishing
-        final ActivityRecord activity1 = new ActivityBuilder(mAtm).setTask(task).build();
-        activity1.finishing = true;
-
-        assertNull("No activity must be reported if all are finishing", task.getRootActivity());
-    }
-
-    /**
-     * Test that first non-finishing activity is the root of task.
-     */
-    @Test
-    public void testIsRootActivity() {
-        final Task task = getTestTask();
-        // Mark the bottom-most activity as finishing.
-        final ActivityRecord activity0 = task.getBottomMostActivity();
-        activity0.finishing = true;
-        // Add an extra activity on top of the root one.
-        final ActivityRecord activity1 = new ActivityBuilder(mAtm).setTask(task).build();
-
-        assertFalse("Finishing activity must not be the root of task", activity0.isRootOfTask());
-        assertTrue("Non-finishing activity must be the root of task", activity1.isRootOfTask());
-    }
-
-    /**
-     * Test that if all activities in the task are finishing, then the one on the bottom is the
-     * root of task.
-     */
-    @Test
-    public void testIsRootActivity_allFinishing() {
-        final Task task = getTestTask();
-        // Mark the bottom-most activity as finishing.
-        final ActivityRecord activity0 = task.getBottomMostActivity();
-        activity0.finishing = true;
-        // Add an extra activity on top of the root one and mark it as finishing
-        final ActivityRecord activity1 = new ActivityBuilder(mAtm).setTask(task).build();
-        activity1.finishing = true;
-
-        assertTrue("Bottom activity must be the root of task", activity0.isRootOfTask());
-        assertFalse("Finishing activity on top must not be the root of task",
-                activity1.isRootOfTask());
-    }
-
-    /**
-     * Test {@link ActivityRecord#getTaskForActivityLocked(IBinder, boolean)}.
-     */
-    @Test
-    public void testGetTaskForActivity() {
-        final Task task0 = getTestTask();
-        final ActivityRecord activity0 = task0.getBottomMostActivity();
-
-        final Task task1 = getTestTask();
-        final ActivityRecord activity1 = task1.getBottomMostActivity();
-
-        assertEquals(task0.mTaskId,
-                ActivityRecord.getTaskForActivityLocked(activity0.appToken, false /* onlyRoot */));
-        assertEquals(task1.mTaskId,
-                ActivityRecord.getTaskForActivityLocked(activity1.appToken,  false /* onlyRoot */));
-    }
-
-    /**
-     * Test {@link ActivityRecord#getTaskForActivityLocked(IBinder, boolean)} with finishing
-     * activity.
-     */
-    @Test
-    public void testGetTaskForActivity_onlyRoot_finishing() {
-        final Task task = getTestTask();
-        // Make the current root activity finishing
-        final ActivityRecord activity0 = task.getBottomMostActivity();
-        activity0.finishing = true;
-        // Add an extra activity on top - this will be the new root
-        final ActivityRecord activity1 = new ActivityBuilder(mAtm).setTask(task).build();
-        // Add one more on top
-        final ActivityRecord activity2 = new ActivityBuilder(mAtm).setTask(task).build();
-
-        assertEquals(task.mTaskId,
-                ActivityRecord.getTaskForActivityLocked(activity0.appToken, true /* onlyRoot */));
-        assertEquals(task.mTaskId,
-                ActivityRecord.getTaskForActivityLocked(activity1.appToken, true /* onlyRoot */));
-        assertEquals("No task must be reported for activity that is above root", INVALID_TASK_ID,
-                ActivityRecord.getTaskForActivityLocked(activity2.appToken, true /* onlyRoot */));
-    }
-
-    /**
-     * Test {@link ActivityRecord#getTaskForActivityLocked(IBinder, boolean)} with activity that
-     * relinquishes task identity.
-     */
-    @Test
-    public void testGetTaskForActivity_onlyRoot_relinquishTaskIdentity() {
-        final Task task = getTestTask();
-        // Make the current root activity relinquish task identity
-        final ActivityRecord activity0 = task.getBottomMostActivity();
-        activity0.info.flags |= FLAG_RELINQUISH_TASK_IDENTITY;
-        // Add an extra activity on top - this will be the new root
-        final ActivityRecord activity1 = new ActivityBuilder(mAtm).setTask(task).build();
-        // Add one more on top
-        final ActivityRecord activity2 = new ActivityBuilder(mAtm).setTask(task).build();
-
-        assertEquals(task.mTaskId,
-                ActivityRecord.getTaskForActivityLocked(activity0.appToken, true /* onlyRoot */));
-        assertEquals(task.mTaskId,
-                ActivityRecord.getTaskForActivityLocked(activity1.appToken, true /* onlyRoot */));
-        assertEquals("No task must be reported for activity that is above root", INVALID_TASK_ID,
-                ActivityRecord.getTaskForActivityLocked(activity2.appToken, true /* onlyRoot */));
-    }
-
-    /**
-     * Test {@link ActivityRecord#getTaskForActivityLocked(IBinder, boolean)} allowing non-root
-     * entries.
-     */
-    @Test
-    public void testGetTaskForActivity_notOnlyRoot() {
-        final Task task = getTestTask();
-        // Mark the bottom-most activity as finishing.
-        final ActivityRecord activity0 = task.getBottomMostActivity();
-        activity0.finishing = true;
-
-        // Add an extra activity on top of the root one and make it relinquish task identity
-        final ActivityRecord activity1 = new ActivityBuilder(mAtm).setTask(task).build();
-        activity1.info.flags |= FLAG_RELINQUISH_TASK_IDENTITY;
-
-        // Add one more activity on top
-        final ActivityRecord activity2 = new ActivityBuilder(mAtm).setTask(task).build();
-
-        assertEquals(task.mTaskId,
-                ActivityRecord.getTaskForActivityLocked(activity0.appToken, false /* onlyRoot */));
-        assertEquals(task.mTaskId,
-                ActivityRecord.getTaskForActivityLocked(activity1.appToken, false /* onlyRoot */));
-        assertEquals(task.mTaskId,
-                ActivityRecord.getTaskForActivityLocked(activity2.appToken, false /* onlyRoot */));
-    }
-
-    /**
-     * Test {@link Task#updateEffectiveIntent()}.
-     */
-    @Test
-    public void testUpdateEffectiveIntent() {
-        // Test simple case with a single activity.
-        final Task task = getTestTask();
-        final ActivityRecord activity0 = task.getBottomMostActivity();
-
-        spyOn(task);
-        task.updateEffectiveIntent();
-        verify(task).setIntent(eq(activity0));
-    }
-
-    /**
-     * Test {@link Task#updateEffectiveIntent()} with root activity marked as finishing. This
-     * should make the task use the second activity when updating the intent.
-     */
-    @Test
-    public void testUpdateEffectiveIntent_rootFinishing() {
-        // Test simple case with a single activity.
-        final Task task = getTestTask();
-        final ActivityRecord activity0 = task.getBottomMostActivity();
-        // Mark the bottom-most activity as finishing.
-        activity0.finishing = true;
-        // Add an extra activity on top of the root one
-        final ActivityRecord activity1 = new ActivityBuilder(mAtm).setTask(task).build();
-
-        spyOn(task);
-        task.updateEffectiveIntent();
-        verify(task).setIntent(eq(activity1));
-    }
-
-    /**
-     * Test {@link Task#updateEffectiveIntent()} when all activities are finishing or
-     * relinquishing task identity. In this case the root activity should still be used when
-     * updating the intent (legacy behavior).
-     */
-    @Test
-    public void testUpdateEffectiveIntent_allFinishing() {
-        // Test simple case with a single activity.
-        final Task task = getTestTask();
-        final ActivityRecord activity0 = task.getBottomMostActivity();
-        // Mark the bottom-most activity as finishing.
-        activity0.finishing = true;
-        // Add an extra activity on top of the root one and make it relinquish task identity
-        final ActivityRecord activity1 = new ActivityBuilder(mAtm).setTask(task).build();
-        activity1.finishing = true;
-
-        // Task must still update the intent using the root activity (preserving legacy behavior).
-        spyOn(task);
-        task.updateEffectiveIntent();
-        verify(task).setIntent(eq(activity0));
-    }
-
-    @Test
-    public void testSaveLaunchingStateWhenConfigurationChanged() {
-        LaunchParamsPersister persister = mAtm.mTaskSupervisor.mLaunchParamsPersister;
-        spyOn(persister);
-
-        final Task task = getTestTask();
-        task.setHasBeenVisible(false);
-        task.getDisplayContent().setDisplayWindowingMode(WINDOWING_MODE_FREEFORM);
-        task.getRootTask().setWindowingMode(WINDOWING_MODE_FULLSCREEN);
-
-        task.setHasBeenVisible(true);
-        task.onConfigurationChanged(task.getParent().getConfiguration());
-
-        verify(persister).saveTask(task, task.getDisplayContent());
-    }
-
-    @Test
-    public void testSaveLaunchingStateWhenClearingParent() {
-        LaunchParamsPersister persister = mAtm.mTaskSupervisor.mLaunchParamsPersister;
-        spyOn(persister);
-
-        final Task task = getTestTask();
-        task.setHasBeenVisible(false);
-        task.getDisplayContent().setWindowingMode(WindowConfiguration.WINDOWING_MODE_FREEFORM);
-        task.getRootTask().setWindowingMode(WINDOWING_MODE_FULLSCREEN);
-        final DisplayContent oldDisplay = task.getDisplayContent();
-
-        LaunchParamsController.LaunchParams params = new LaunchParamsController.LaunchParams();
-        params.mWindowingMode = WINDOWING_MODE_UNDEFINED;
-        persister.getLaunchParams(task, null, params);
-        assertEquals(WINDOWING_MODE_UNDEFINED, params.mWindowingMode);
-
-        task.setHasBeenVisible(true);
-        task.removeImmediately();
-
-        verify(persister).saveTask(task, oldDisplay);
-
-        persister.getLaunchParams(task, null, params);
-        assertEquals(WINDOWING_MODE_FULLSCREEN, params.mWindowingMode);
-    }
-
-    @Test
-    public void testNotSaveLaunchingStateNonFreeformDisplay() {
-        LaunchParamsPersister persister = mAtm.mTaskSupervisor.mLaunchParamsPersister;
-        spyOn(persister);
-
-        final Task task = getTestTask();
-        task.setHasBeenVisible(false);
-        task.getRootTask().setWindowingMode(WINDOWING_MODE_FULLSCREEN);
-
-        task.setHasBeenVisible(true);
-        task.onConfigurationChanged(task.getParent().getConfiguration());
-
-        verify(persister, never()).saveTask(same(task), any());
-    }
-
-    @Test
-    public void testNotSaveLaunchingStateWhenNotFullscreenOrFreeformWindow() {
-        LaunchParamsPersister persister = mAtm.mTaskSupervisor.mLaunchParamsPersister;
-        spyOn(persister);
-
-        final Task task = getTestTask();
-        task.setHasBeenVisible(false);
-        task.getDisplayContent().setDisplayWindowingMode(WINDOWING_MODE_FREEFORM);
-        task.getRootTask().setWindowingMode(WINDOWING_MODE_PINNED);
-
-        task.setHasBeenVisible(true);
-        task.onConfigurationChanged(task.getParent().getConfiguration());
-
-        verify(persister, never()).saveTask(same(task), any());
-    }
-
-    @Test
-    public void testNotSaveLaunchingStateForNonLeafTask() {
-        LaunchParamsPersister persister = mAtm.mTaskSupervisor.mLaunchParamsPersister;
-        spyOn(persister);
-
-        final Task task = getTestTask();
-        task.setHasBeenVisible(false);
-        task.getDisplayContent().setDisplayWindowingMode(WINDOWING_MODE_FREEFORM);
-        task.getRootTask().setWindowingMode(WINDOWING_MODE_FULLSCREEN);
-
-        final Task leafTask = createTaskInStack(task, 0 /* userId */);
-
-        leafTask.setHasBeenVisible(true);
-        task.setHasBeenVisible(true);
-        task.onConfigurationChanged(task.getParent().getConfiguration());
-
-        verify(persister, never()).saveTask(same(task), any());
-        verify(persister).saveTask(same(leafTask), any());
-    }
-
-    @Test
-    public void testNotSpecifyOrientationByFloatingTask() {
-        final Task task = new TaskBuilder(mSupervisor)
-                .setCreateActivity(true).setCreateParentTask(true).build();
-        final ActivityRecord activity = task.getTopMostActivity();
-        final WindowContainer<?> parentContainer = task.getParent();
-        final TaskDisplayArea taskDisplayArea = task.getDisplayArea();
-        activity.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE);
-
-        assertEquals(SCREEN_ORIENTATION_LANDSCAPE, parentContainer.getOrientation());
-        assertEquals(SCREEN_ORIENTATION_LANDSCAPE, taskDisplayArea.getOrientation());
-
-        task.setWindowingMode(WINDOWING_MODE_PINNED);
-
-        // TDA returns the last orientation when child returns UNSET
-        assertEquals(SCREEN_ORIENTATION_UNSET, parentContainer.getOrientation());
-        assertEquals(SCREEN_ORIENTATION_LANDSCAPE, taskDisplayArea.getOrientation());
-    }
-
-    @Test
-    public void testNotSpecifyOrientation_taskDisplayAreaNotFocused() {
-        final TaskDisplayArea firstTaskDisplayArea = mDisplayContent.getDefaultTaskDisplayArea();
-        final TaskDisplayArea secondTaskDisplayArea = createTaskDisplayArea(
-                mDisplayContent, mRootWindowContainer.mWmService, "TestTaskDisplayArea",
-                FEATURE_VENDOR_FIRST);
-        final Task firstStack = firstTaskDisplayArea.createRootTask(
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
-        final Task secondStack = secondTaskDisplayArea.createRootTask(
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
-        final ActivityRecord firstActivity = new ActivityBuilder(mAtm)
-                .setTask(firstStack).build();
-        final ActivityRecord secondActivity = new ActivityBuilder(mAtm)
-                .setTask(secondStack).build();
-        firstActivity.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE);
-        secondActivity.setRequestedOrientation(SCREEN_ORIENTATION_PORTRAIT);
-
-        // Activity on TDA1 is focused
-        mDisplayContent.setFocusedApp(firstActivity);
-
-        assertEquals(SCREEN_ORIENTATION_LANDSCAPE, firstTaskDisplayArea.getOrientation());
-        assertEquals(SCREEN_ORIENTATION_UNSET, secondTaskDisplayArea.getOrientation());
-
-        // No focused app, TDA1 is still recorded as last focused.
-        mDisplayContent.setFocusedApp(null);
-
-        assertEquals(SCREEN_ORIENTATION_LANDSCAPE, firstTaskDisplayArea.getOrientation());
-        assertEquals(SCREEN_ORIENTATION_UNSET, secondTaskDisplayArea.getOrientation());
-
-        // Activity on TDA2 is focused
-        mDisplayContent.setFocusedApp(secondActivity);
-
-        assertEquals(SCREEN_ORIENTATION_UNSET, firstTaskDisplayArea.getOrientation());
-        assertEquals(SCREEN_ORIENTATION_PORTRAIT, secondTaskDisplayArea.getOrientation());
-    }
-
-    @Test
-    public void testNotifyOrientationChangeCausedByConfigurationChange() {
-        final Task task = getTestTask();
-        final ActivityRecord activity = task.getTopMostActivity();
-        final DisplayContent display = task.getDisplayContent();
-        display.setWindowingMode(WINDOWING_MODE_FREEFORM);
-
-        activity.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE);
-        assertEquals(SCREEN_ORIENTATION_UNSET, task.getOrientation());
-        verify(display).onDescendantOrientationChanged(same(task));
-        reset(display);
-
-        display.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
-        assertEquals(SCREEN_ORIENTATION_LANDSCAPE, task.getOrientation());
-        verify(display).onDescendantOrientationChanged(same(task));
-    }
-
-    private Task getTestTask() {
-        final Task stack = new TaskBuilder(mSupervisor).setCreateActivity(true).build();
-        return stack.getBottomMostTask();
-    }
-
-    private void testStackBoundsConfiguration(int windowingMode, Rect parentBounds, Rect bounds,
-            Rect expectedConfigBounds) {
-
-        TaskDisplayArea taskDisplayArea = mAtm.mRootWindowContainer.getDefaultTaskDisplayArea();
-        Task stack = taskDisplayArea.createRootTask(windowingMode, ACTIVITY_TYPE_STANDARD,
-                true /* onTop */);
-        Task task = new TaskBuilder(mSupervisor).setParentTask(stack).build();
-
-        final Configuration parentConfig = stack.getConfiguration();
-        parentConfig.windowConfiguration.setAppBounds(parentBounds);
-        task.setBounds(bounds);
-
-        task.resolveOverrideConfiguration(parentConfig);
-        // Assert that both expected and actual are null or are equal to each other
-        assertEquals(expectedConfigBounds,
-                task.getResolvedOverrideConfiguration().windowConfiguration.getAppBounds());
-    }
-
-    private byte[] serializeToBytes(Task r) throws Exception {
-        try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
-            final TypedXmlSerializer serializer = Xml.newFastSerializer();
-            serializer.setOutput(os, "UTF-8");
-            serializer.startDocument(null, true);
-            serializer.startTag(null, TASK_TAG);
-            r.saveToXml(serializer);
-            serializer.endTag(null, TASK_TAG);
-            serializer.endDocument();
-
-            os.flush();
-            return os.toByteArray();
-        }
-    }
-
-    private Task restoreFromBytes(byte[] in) throws IOException, XmlPullParserException {
-        try (Reader reader = new InputStreamReader(new ByteArrayInputStream(in))) {
-            final TypedXmlPullParser parser = Xml.newFastPullParser();
-            parser.setInput(reader);
-            assertEquals(XmlPullParser.START_TAG, parser.next());
-            assertEquals(TASK_TAG, parser.getName());
-            return Task.restoreFromXml(parser, mAtm.mTaskSupervisor);
-        }
-    }
-
-    private Task createTask(int taskId) {
-        return new Task.Builder(mAtm)
-                .setTaskId(taskId)
-                .setIntent(new Intent())
-                .setRealActivity(ActivityBuilder.getDefaultComponent())
-                .setEffectiveUid(10050)
-                .buildInner();
-    }
-}
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java
deleted file mode 100644
index e58c162..0000000
--- a/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java
+++ /dev/null
@@ -1,225 +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.server.wm;
-
-import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
-
-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;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
-import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN;
-import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
-
-import static org.junit.Assert.assertEquals;
-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.clearInvocations;
-
-import android.app.WindowConfiguration;
-import android.graphics.Rect;
-import android.platform.test.annotations.Presubmit;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/**
- * Tests for the {@link Task} class.
- *
- * Build/Install/Run:
- *  atest WmTests:TaskStackTests
- */
-@SmallTest
-@Presubmit
-@RunWith(WindowTestRunner.class)
-public class TaskStackTests extends WindowTestsBase {
-
-    @Test
-    public void testStackPositionChildAt() {
-        final Task stack = createTaskStackOnDisplay(mDisplayContent);
-        final Task task1 = createTaskInStack(stack, 0 /* userId */);
-        final Task task2 = createTaskInStack(stack, 1 /* userId */);
-
-        // Current user task should be moved to top.
-        stack.positionChildAt(WindowContainer.POSITION_TOP, task1, false /* includingParents */);
-        assertEquals(stack.mChildren.get(0), task2);
-        assertEquals(stack.mChildren.get(1), task1);
-
-        // Non-current user won't be moved to top.
-        stack.positionChildAt(WindowContainer.POSITION_TOP, task2, false /* includingParents */);
-        assertEquals(stack.mChildren.get(0), task2);
-        assertEquals(stack.mChildren.get(1), task1);
-
-        // Non-leaf task should be moved to top regardless of the user id.
-        createTaskInStack(task2, 0 /* userId */);
-        createTaskInStack(task2, 1 /* userId */);
-        stack.positionChildAt(WindowContainer.POSITION_TOP, task2, false /* includingParents */);
-        assertEquals(stack.mChildren.get(0), task1);
-        assertEquals(stack.mChildren.get(1), task2);
-    }
-
-    @Test
-    public void testClosingAppDifferentTaskOrientation() {
-        final ActivityRecord activity1 = createActivityRecord(mDisplayContent);
-        activity1.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
-
-        final ActivityRecord activity2 = createActivityRecord(mDisplayContent);
-        activity2.setOrientation(SCREEN_ORIENTATION_PORTRAIT);
-
-        final WindowContainer parent = activity1.getTask().getParent();
-        assertEquals(SCREEN_ORIENTATION_PORTRAIT, parent.getOrientation());
-        mDisplayContent.mClosingApps.add(activity2);
-        assertEquals(SCREEN_ORIENTATION_LANDSCAPE, parent.getOrientation());
-    }
-
-    @Test
-    public void testMoveTaskToBackDifferentTaskOrientation() {
-        final ActivityRecord activity1 = createActivityRecord(mDisplayContent);
-        activity1.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
-
-        final ActivityRecord activity2 = createActivityRecord(mDisplayContent);
-        activity2.setOrientation(SCREEN_ORIENTATION_PORTRAIT);
-
-        final WindowContainer parent = activity1.getTask().getParent();
-        assertEquals(SCREEN_ORIENTATION_PORTRAIT, parent.getOrientation());
-    }
-
-    @Test
-    public void testStackRemoveImmediately() {
-        final Task stack = createTaskStackOnDisplay(mDisplayContent);
-        final Task task = createTaskInStack(stack, 0 /* userId */);
-        assertEquals(stack, task.getRootTask());
-
-        // Remove stack and check if its child is also removed.
-        stack.removeImmediately();
-        assertNull(stack.getDisplayContent());
-        assertNull(task.getParent());
-    }
-
-    @Test
-    public void testRemoveContainer() {
-        final Task stack = createTaskStackOnDisplay(mDisplayContent);
-        final Task task = createTaskInStack(stack, 0 /* userId */);
-
-        assertNotNull(stack);
-        assertNotNull(task);
-        stack.removeIfPossible();
-        // Assert that the container was removed.
-        assertNull(stack.getParent());
-        assertEquals(0, stack.getChildCount());
-        assertNull(stack.getDisplayContent());
-        assertNull(task.getDisplayContent());
-        assertNull(task.getParent());
-    }
-
-    @Test
-    public void testRemoveContainer_deferRemoval() {
-        final Task stack = createTaskStackOnDisplay(mDisplayContent);
-        final Task task = createTaskInStack(stack, 0 /* userId */);
-
-        // Stack removal is deferred if one of its child is animating.
-        doReturn(true).when(stack).hasWindowsAlive();
-        doReturn(stack).when(task).getAnimatingContainer(
-                eq(TRANSITION | CHILDREN), anyInt());
-
-        stack.removeIfPossible();
-        // For the case of deferred removal the task controller will still be connected to the its
-        // container until the stack window container is removed.
-        assertNotNull(stack.getParent());
-        assertNotEquals(0, stack.getChildCount());
-        assertNotNull(task);
-
-        stack.removeImmediately();
-        // After removing, the task will be isolated.
-        assertNull(task.getParent());
-        assertEquals(0, task.getChildCount());
-    }
-
-    @Test
-    public void testReparent() {
-        // Create first stack on primary display.
-        final Task stack1 = createTaskStackOnDisplay(mDisplayContent);
-        final Task task1 = createTaskInStack(stack1, 0 /* userId */);
-
-        // Create second display and put second stack on it.
-        final DisplayContent dc = createNewDisplay();
-        final Task stack2 = createTaskStackOnDisplay(dc);
-
-        // Reparent
-        clearInvocations(task1); // reset the number of onDisplayChanged for task.
-        stack1.reparent(dc.getDefaultTaskDisplayArea(), true /* onTop */);
-        assertEquals(dc, stack1.getDisplayContent());
-        final int stack1PositionInParent = stack1.getParent().mChildren.indexOf(stack1);
-        final int stack2PositionInParent = stack1.getParent().mChildren.indexOf(stack2);
-        assertEquals(stack1PositionInParent, stack2PositionInParent + 1);
-        verify(task1, times(1)).onDisplayChanged(any());
-    }
-
-    @Test
-    public void testStackOutset() {
-        final Task stack = createTaskStackOnDisplay(mDisplayContent);
-        final int stackOutset = 10;
-        spyOn(stack);
-        doReturn(stackOutset).when(stack).getTaskOutset();
-        doReturn(true).when(stack).inMultiWindowMode();
-
-        // Mock the resolved override windowing mode to non-fullscreen
-        final WindowConfiguration windowConfiguration =
-                stack.getResolvedOverrideConfiguration().windowConfiguration;
-        spyOn(windowConfiguration);
-        doReturn(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY)
-                .when(windowConfiguration).getWindowingMode();
-
-        // Prevent adjust task dimensions
-        doNothing().when(stack).adjustForMinimalTaskDimensions(any(), any(), any());
-
-        final Rect stackBounds = new Rect(200, 200, 800, 1000);
-        // Update surface position and size by the given bounds.
-        stack.setBounds(stackBounds);
-
-        assertEquals(stackBounds.width() + 2 * stackOutset, stack.getLastSurfaceSize().x);
-        assertEquals(stackBounds.height() + 2 * stackOutset, stack.getLastSurfaceSize().y);
-        assertEquals(stackBounds.left - stackOutset, stack.getLastSurfacePosition().x);
-        assertEquals(stackBounds.top - stackOutset, stack.getLastSurfacePosition().y);
-    }
-
-    @Test
-    public void testActivityAndTaskGetsProperType() {
-        final Task task1 = new TaskBuilder(mSupervisor).build();
-        ActivityRecord activity1 = createNonAttachedActivityRecord(mDisplayContent);
-
-        // First activity should become standard
-        task1.addChild(activity1, 0);
-        assertEquals(WindowConfiguration.ACTIVITY_TYPE_STANDARD, activity1.getActivityType());
-        assertEquals(WindowConfiguration.ACTIVITY_TYPE_STANDARD, task1.getActivityType());
-
-        // Second activity should also become standard
-        ActivityRecord activity2 = createNonAttachedActivityRecord(mDisplayContent);
-        task1.addChild(activity2, WindowContainer.POSITION_TOP);
-        assertEquals(WindowConfiguration.ACTIVITY_TYPE_STANDARD, activity2.getActivityType());
-        assertEquals(WindowConfiguration.ACTIVITY_TYPE_STANDARD, task1.getActivityType());
-    }
-}
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
index dca6b08..2389d2d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
@@ -16,20 +16,39 @@
 
 package com.android.server.wm;
 
+import static android.app.ActivityTaskManager.INVALID_TASK_ID;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
 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.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.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
+import static android.content.pm.ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+import static android.util.DisplayMetrics.DENSITY_DEFAULT;
+import static android.view.IWindowManager.FIXED_TO_USER_ROTATION_ENABLED;
+import static android.view.Surface.ROTATION_0;
+import static android.view.Surface.ROTATION_90;
+import static android.window.DisplayAreaOrganizer.FEATURE_VENDOR_FIRST;
 
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
+import static com.android.server.policy.WindowManagerPolicy.USER_ROTATION_FREE;
 import static com.android.server.wm.Task.FLAG_FORCE_HIDDEN_FOR_TASK_ORG;
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.hamcrest.Matchers.not;
+import static org.hamcrest.Matchers.sameInstance;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
@@ -39,18 +58,45 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.same;
 import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
 
+import android.app.ActivityManager;
+import android.app.TaskInfo;
 import android.app.WindowConfiguration;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
 import android.content.res.Configuration;
 import android.graphics.Point;
 import android.graphics.Rect;
+import android.os.IBinder;
 import android.platform.test.annotations.Presubmit;
+import android.util.DisplayMetrics;
+import android.util.TypedXmlPullParser;
+import android.util.TypedXmlSerializer;
+import android.util.Xml;
+import android.view.DisplayInfo;
 
-import androidx.test.filters.SmallTest;
+import androidx.test.filters.MediumTest;
 
+import org.junit.Assert;
+import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
 
 /**
  * Test class for {@link Task}.
@@ -58,15 +104,25 @@
  * Build/Install/Run:
  *  atest WmTests:TaskTests
  */
-@SmallTest
+@MediumTest
 @Presubmit
 @RunWith(WindowTestRunner.class)
 public class TaskTests extends WindowTestsBase {
 
+    private static final String TASK_TAG = "task";
+
+    private Rect mParentBounds;
+
+    @Before
+    public void setUp() throws Exception {
+        mParentBounds = new Rect(10 /*left*/, 30 /*top*/, 80 /*right*/, 60 /*bottom*/);
+        removeGlobalMinSizeRestriction();
+    }
+
     @Test
     public void testRemoveContainer() {
-        final Task stackController1 = createTaskStackOnDisplay(mDisplayContent);
-        final Task task = createTaskInStack(stackController1, 0 /* userId */);
+        final Task taskController1 = createTask(mDisplayContent);
+        final Task task = createTaskInRootTask(taskController1, 0 /* userId */);
         final ActivityRecord activity = createActivityRecord(mDisplayContent, task);
 
         task.removeIfPossible();
@@ -78,8 +134,8 @@
 
     @Test
     public void testRemoveContainer_deferRemoval() {
-        final Task stackController1 = createTaskStackOnDisplay(mDisplayContent);
-        final Task task = createTaskInStack(stackController1, 0 /* userId */);
+        final Task taskController1 = createTask(mDisplayContent);
+        final Task task = createTaskInRootTask(taskController1, 0 /* userId */);
         final ActivityRecord activity = createActivityRecord(mDisplayContent, task);
 
         doReturn(true).when(task).shouldDeferRemoval();
@@ -99,14 +155,14 @@
 
     @Test
     public void testReparent() {
-        final Task stackController1 = createTaskStackOnDisplay(mDisplayContent);
-        final Task task = createTaskInStack(stackController1, 0 /* userId */);
-        final Task stackController2 = createTaskStackOnDisplay(mDisplayContent);
-        final Task task2 = createTaskInStack(stackController2, 0 /* userId */);
+        final Task taskController1 = createTask(mDisplayContent);
+        final Task task = createTaskInRootTask(taskController1, 0 /* userId */);
+        final Task taskController2 = createTask(mDisplayContent);
+        final Task task2 = createTaskInRootTask(taskController2, 0 /* userId */);
 
         boolean gotException = false;
         try {
-            task.reparent(stackController1, 0, false/* moveParents */, "testReparent");
+            task.reparent(taskController1, 0, false/* moveParents */, "testReparent");
         } catch (IllegalArgumentException e) {
             gotException = true;
         }
@@ -118,29 +174,29 @@
         } catch (Exception e) {
             gotException = true;
         }
-        assertTrue("Should not be able to reparent to a stack that doesn't exist", gotException);
+        assertTrue("Should not be able to reparent to a task that doesn't exist", gotException);
 
-        task.reparent(stackController2, 0, false/* moveParents */, "testReparent");
-        assertEquals(stackController2, task.getParent());
+        task.reparent(taskController2, 0, false/* moveParents */, "testReparent");
+        assertEquals(taskController2, task.getParent());
         assertEquals(0, task.getParent().mChildren.indexOf(task));
         assertEquals(1, task2.getParent().mChildren.indexOf(task2));
     }
 
     @Test
     public void testReparent_BetweenDisplays() {
-        // Create first stack on primary display.
-        final Task stack1 = createTaskStackOnDisplay(mDisplayContent);
-        final Task task = createTaskInStack(stack1, 0 /* userId */);
-        assertEquals(mDisplayContent, stack1.getDisplayContent());
+        // Create first task on primary display.
+        final Task rootTask1 = createTask(mDisplayContent);
+        final Task task = createTaskInRootTask(rootTask1, 0 /* userId */);
+        assertEquals(mDisplayContent, rootTask1.getDisplayContent());
 
-        // Create second display and put second stack on it.
+        // Create second display and put second task on it.
         final DisplayContent dc = createNewDisplay();
-        final Task stack2 = createTaskStackOnDisplay(dc);
-        final Task task2 = createTaskInStack(stack2, 0 /* userId */);
+        final Task rootTask2 = createTask(dc);
+        final Task task2 = createTaskInRootTask(rootTask2, 0 /* userId */);
         // Reparent and check state
         clearInvocations(task);  // reset the number of onDisplayChanged for task.
-        task.reparent(stack2, 0, false /* moveParents */, "testReparent_BetweenDisplays");
-        assertEquals(stack2, task.getParent());
+        task.reparent(rootTask2, 0, false /* moveParents */, "testReparent_BetweenDisplays");
+        assertEquals(rootTask2, task.getParent());
         assertEquals(0, task.getParent().mChildren.indexOf(task));
         assertEquals(1, task2.getParent().mChildren.indexOf(task2));
         verify(task, times(1)).onDisplayChanged(any());
@@ -148,8 +204,8 @@
 
     @Test
     public void testBounds() {
-        final Task stack1 = createTaskStackOnDisplay(mDisplayContent);
-        final Task task = createTaskInStack(stack1, 0 /* userId */);
+        final Task rootTask1 = createTask(mDisplayContent);
+        final Task task = createTaskInRootTask(rootTask1, 0 /* userId */);
 
         // Check that setting bounds also updates surface position
         task.setWindowingMode(WINDOWING_MODE_FREEFORM);
@@ -159,9 +215,9 @@
     }
 
     @Test
-    public void testIsInStack() {
-        final Task task1 = createTaskStackOnDisplay(mDisplayContent);
-        final Task task2 = createTaskStackOnDisplay(mDisplayContent);
+    public void testIsInTask() {
+        final Task task1 = createTask(mDisplayContent);
+        final Task task2 = createTask(mDisplayContent);
         final ActivityRecord activity1 = createActivityRecord(mDisplayContent, task1);
         final ActivityRecord activity2 = createActivityRecord(mDisplayContent, task2);
         assertEquals(activity1, task1.isInTask(activity1));
@@ -170,7 +226,7 @@
 
     @Test
     public void testRemoveChildForOverlayTask() {
-        final Task task = createTaskStackOnDisplay(mDisplayContent);
+        final Task task = createTask(mDisplayContent);
         final int taskId = task.mTaskId;
         final ActivityRecord activity1 = createActivityRecord(mDisplayContent, task);
         final ActivityRecord activity2 = createActivityRecord(mDisplayContent, task);
@@ -193,10 +249,10 @@
 
     @Test
     public void testSwitchUser() {
-        final Task rootTask = createTaskStackOnDisplay(mDisplayContent);
-        final Task childTask = createTaskInStack(rootTask, 0 /* userId */);
-        final Task leafTask1 = createTaskInStack(childTask, 10 /* userId */);
-        final Task leafTask2 = createTaskInStack(childTask, 0 /* userId */);
+        final Task rootTask = createTask(mDisplayContent);
+        final Task childTask = createTaskInRootTask(rootTask, 0 /* userId */);
+        final Task leafTask1 = createTaskInRootTask(childTask, 10 /* userId */);
+        final Task leafTask2 = createTaskInRootTask(childTask, 0 /* userId */);
         assertEquals(1, rootTask.getChildCount());
         assertEquals(leafTask2, childTask.getTopChild());
 
@@ -208,9 +264,9 @@
 
     @Test
     public void testEnsureActivitiesVisible() {
-        final Task rootTask = createTaskStackOnDisplay(mDisplayContent);
-        final Task leafTask1 = createTaskInStack(rootTask, 0 /* userId */);
-        final Task leafTask2 = createTaskInStack(rootTask, 0 /* userId */);
+        final Task rootTask = createTask(mDisplayContent);
+        final Task leafTask1 = createTaskInRootTask(rootTask, 0 /* userId */);
+        final Task leafTask2 = createTaskInRootTask(rootTask, 0 /* userId */);
         final ActivityRecord activity1 = createActivityRecord(mDisplayContent, leafTask1);
         final ActivityRecord activity2 = createActivityRecord(mDisplayContent, leafTask2);
 
@@ -233,7 +289,7 @@
 
     @Test
     public void testResolveNonResizableTaskWindowingMode() {
-        final Task task = createTaskStackOnDisplay(mDisplayContent);
+        final Task task = createTask(mDisplayContent);
         Configuration parentConfig = task.getParent().getConfiguration();
         parentConfig.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM);
         doReturn(false).when(task).isResizeable();
@@ -264,10 +320,10 @@
 
     @Test
     public void testHandlesOrientationChangeFromDescendant() {
-        final Task rootTask = createTaskStackOnDisplay(WINDOWING_MODE_MULTI_WINDOW,
-                ACTIVITY_TYPE_STANDARD, mDisplayContent);
-        final Task leafTask1 = createTaskInStack(rootTask, 0 /* userId */);
-        final Task leafTask2 = createTaskInStack(rootTask, 0 /* userId */);
+        final Task rootTask = createTask(mDisplayContent,
+                WINDOWING_MODE_MULTI_WINDOW, ACTIVITY_TYPE_STANDARD);
+        final Task leafTask1 = createTaskInRootTask(rootTask, 0 /* userId */);
+        final Task leafTask2 = createTaskInRootTask(rootTask, 0 /* userId */);
         leafTask1.getWindowConfiguration().setActivityType(ACTIVITY_TYPE_HOME);
         leafTask2.getWindowConfiguration().setActivityType(ACTIVITY_TYPE_STANDARD);
 
@@ -281,7 +337,7 @@
 
     @Test
     public void testAlwaysOnTop() {
-        final Task task = createTaskStackOnDisplay(mDisplayContent);
+        final Task task = createTask(mDisplayContent);
         task.setAlwaysOnTop(true);
         task.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
         assertTrue(task.isAlwaysOnTop());
@@ -289,4 +345,1053 @@
         task.setForceHidden(FLAG_FORCE_HIDDEN_FOR_TASK_ORG, true /* set */);
         assertFalse(task.isAlwaysOnTop());
     }
+
+    @Test
+    public void testRestoreWindowedTask() throws Exception {
+        final Task expected = createTask(64);
+        expected.mLastNonFullscreenBounds = new Rect(50, 50, 100, 100);
+
+        final byte[] serializedBytes = serializeToBytes(expected);
+        final Task actual = restoreFromBytes(serializedBytes);
+        assertEquals(expected.mTaskId, actual.mTaskId);
+        assertEquals(expected.mLastNonFullscreenBounds, actual.mLastNonFullscreenBounds);
+    }
+
+    /** Ensure we have no chance to modify the original intent. */
+    @Test
+    public void testCopyBaseIntentForTaskInfo() {
+        final Task task = createTask(1);
+        task.setTaskDescription(new ActivityManager.TaskDescription());
+        final TaskInfo info = task.getTaskInfo();
+
+        // The intent of info should be a copy so assert that they are different instances.
+        Assert.assertThat(info.baseIntent, not(sameInstance(task.getBaseIntent())));
+    }
+
+    @Test
+    public void testReturnsToHomeRootTask() throws Exception {
+        final Task task = createTask(1);
+        spyOn(task);
+        doReturn(true).when(task).hasChild();
+        assertFalse(task.returnsToHomeRootTask());
+        task.intent = null;
+        assertFalse(task.returnsToHomeRootTask());
+        task.intent = new Intent();
+        assertFalse(task.returnsToHomeRootTask());
+        task.intent.addFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME);
+        assertTrue(task.returnsToHomeRootTask());
+    }
+
+    /** Ensures that empty bounds cause appBounds to inherit from parent. */
+    @Test
+    public void testAppBounds_EmptyBounds() {
+        final Rect emptyBounds = new Rect();
+        testRootTaskBoundsConfiguration(WINDOWING_MODE_FULLSCREEN, mParentBounds, emptyBounds,
+                mParentBounds);
+    }
+
+    /** Ensures that bounds on freeform root tasks are not clipped. */
+    @Test
+    public void testAppBounds_FreeFormBounds() {
+        final Rect freeFormBounds = new Rect(mParentBounds);
+        freeFormBounds.offset(10, 10);
+        testRootTaskBoundsConfiguration(WINDOWING_MODE_FREEFORM, mParentBounds, freeFormBounds,
+                freeFormBounds);
+    }
+
+    /** Ensures that fully contained bounds are not clipped. */
+    @Test
+    public void testAppBounds_ContainedBounds() {
+        final Rect insetBounds = new Rect(mParentBounds);
+        insetBounds.inset(5, 5, 5, 5);
+        testRootTaskBoundsConfiguration(
+                WINDOWING_MODE_FREEFORM, mParentBounds, insetBounds, insetBounds);
+    }
+
+    @Test
+    public void testFitWithinBounds() {
+        final Rect parentBounds = new Rect(10, 10, 200, 200);
+        TaskDisplayArea taskDisplayArea = mAtm.mRootWindowContainer.getDefaultTaskDisplayArea();
+        Task rootTask = taskDisplayArea.createRootTask(WINDOWING_MODE_FREEFORM,
+                ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        Task task = new TaskBuilder(mSupervisor).setParentTask(rootTask).build();
+        final Configuration parentConfig = rootTask.getConfiguration();
+        parentConfig.windowConfiguration.setBounds(parentBounds);
+        parentConfig.densityDpi = DisplayMetrics.DENSITY_DEFAULT;
+
+        // check top and left
+        Rect reqBounds = new Rect(-190, -190, 0, 0);
+        task.setBounds(reqBounds);
+        // Make sure part of it is exposed
+        assertTrue(task.getBounds().right > parentBounds.left);
+        assertTrue(task.getBounds().bottom > parentBounds.top);
+        // Should still be more-or-less in that corner
+        assertTrue(task.getBounds().left <= parentBounds.left);
+        assertTrue(task.getBounds().top <= parentBounds.top);
+
+        assertEquals(reqBounds.width(), task.getBounds().width());
+        assertEquals(reqBounds.height(), task.getBounds().height());
+
+        // check bottom and right
+        reqBounds = new Rect(210, 210, 400, 400);
+        task.setBounds(reqBounds);
+        // Make sure part of it is exposed
+        assertTrue(task.getBounds().left < parentBounds.right);
+        assertTrue(task.getBounds().top < parentBounds.bottom);
+        // Should still be more-or-less in that corner
+        assertTrue(task.getBounds().right >= parentBounds.right);
+        assertTrue(task.getBounds().bottom >= parentBounds.bottom);
+
+        assertEquals(reqBounds.width(), task.getBounds().width());
+        assertEquals(reqBounds.height(), task.getBounds().height());
+    }
+
+    /** Tests that the task bounds adjust properly to changes between FULLSCREEN and FREEFORM */
+    @Test
+    public void testBoundsOnModeChangeFreeformToFullscreen() {
+        DisplayContent display = mAtm.mRootWindowContainer.getDefaultDisplay();
+        Task rootTask = new TaskBuilder(mSupervisor).setDisplay(display).setCreateActivity(true)
+                .setWindowingMode(WINDOWING_MODE_FREEFORM).build();
+        Task task = rootTask.getBottomMostTask();
+        task.getRootActivity().setOrientation(SCREEN_ORIENTATION_UNSPECIFIED);
+        DisplayInfo info = new DisplayInfo();
+        display.mDisplay.getDisplayInfo(info);
+        final Rect fullScreenBounds = new Rect(0, 0, info.logicalWidth, info.logicalHeight);
+        final Rect freeformBounds = new Rect(fullScreenBounds);
+        freeformBounds.inset((int) (freeformBounds.width() * 0.2),
+                (int) (freeformBounds.height() * 0.2));
+        task.setBounds(freeformBounds);
+
+        assertEquals(freeformBounds, task.getBounds());
+
+        // FULLSCREEN inherits bounds
+        rootTask.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+        assertEquals(fullScreenBounds, task.getBounds());
+        assertEquals(freeformBounds, task.mLastNonFullscreenBounds);
+
+        // FREEFORM restores bounds
+        rootTask.setWindowingMode(WINDOWING_MODE_FREEFORM);
+        assertEquals(freeformBounds, task.getBounds());
+    }
+
+    /**
+     * Tests that a task with forced orientation has orientation-consistent bounds within the
+     * parent.
+     */
+    @Test
+    public void testFullscreenBoundsForcedOrientation() {
+        final Rect fullScreenBounds = new Rect(0, 0, 1920, 1080);
+        final Rect fullScreenBoundsPort = new Rect(0, 0, 1080, 1920);
+        final DisplayContent display = new TestDisplayContent.Builder(mAtm,
+                fullScreenBounds.width(), fullScreenBounds.height()).setCanRotate(false).build();
+        assertNotNull(mRootWindowContainer.getDisplayContent(display.mDisplayId));
+        // Fix the display orientation to landscape which is the natural rotation (0) for the test
+        // display.
+        final DisplayRotation dr = display.mDisplayContent.getDisplayRotation();
+        dr.setFixedToUserRotation(FIXED_TO_USER_ROTATION_ENABLED);
+        dr.setUserRotation(USER_ROTATION_FREE, ROTATION_0);
+
+        final Task rootTask = new TaskBuilder(mSupervisor).setCreateActivity(true)
+                .setWindowingMode(WINDOWING_MODE_FULLSCREEN).setDisplay(display).build();
+        final Task task = rootTask.getBottomMostTask();
+        final ActivityRecord root = task.getTopNonFinishingActivity();
+
+        assertEquals(fullScreenBounds, task.getBounds());
+
+        // Setting app to fixed portrait fits within parent
+        root.setRequestedOrientation(SCREEN_ORIENTATION_PORTRAIT);
+        assertEquals(root, task.getRootActivity());
+        assertEquals(SCREEN_ORIENTATION_PORTRAIT, task.getRootActivity().getOrientation());
+        // Portrait orientation is enforced on activity level. Task should fill fullscreen bounds.
+        assertThat(task.getBounds().height()).isLessThan(task.getBounds().width());
+        assertEquals(fullScreenBounds, task.getBounds());
+
+        // Top activity gets used
+        final ActivityRecord top = new ActivityBuilder(mAtm).setTask(task).setParentTask(rootTask)
+                .build();
+        assertEquals(top, task.getTopNonFinishingActivity());
+        top.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE);
+        assertThat(task.getBounds().width()).isGreaterThan(task.getBounds().height());
+        assertEquals(task.getBounds().width(), fullScreenBounds.width());
+
+        // Setting app to unspecified restores
+        top.setRequestedOrientation(SCREEN_ORIENTATION_UNSPECIFIED);
+        assertEquals(fullScreenBounds, task.getBounds());
+
+        // Setting app to fixed landscape and changing display
+        top.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE);
+        // Fix the display orientation to portrait which is 90 degrees for the test display.
+        dr.setUserRotation(USER_ROTATION_FREE, ROTATION_90);
+
+        // Fixed orientation request should be resolved on activity level. Task fills display
+        // bounds.
+        assertThat(task.getBounds().height()).isGreaterThan(task.getBounds().width());
+        assertThat(top.getBounds().width()).isGreaterThan(top.getBounds().height());
+        assertEquals(fullScreenBoundsPort, task.getBounds());
+
+        // in FREEFORM, no constraint
+        final Rect freeformBounds = new Rect(display.getBounds());
+        freeformBounds.inset((int) (freeformBounds.width() * 0.2),
+                (int) (freeformBounds.height() * 0.2));
+        rootTask.setWindowingMode(WINDOWING_MODE_FREEFORM);
+        task.setBounds(freeformBounds);
+        assertEquals(freeformBounds, task.getBounds());
+
+        // FULLSCREEN letterboxes bounds on activity level, no constraint on task level.
+        rootTask.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+        assertThat(task.getBounds().height()).isGreaterThan(task.getBounds().width());
+        assertThat(top.getBounds().width()).isGreaterThan(top.getBounds().height());
+        assertEquals(fullScreenBoundsPort, task.getBounds());
+
+        // FREEFORM restores bounds as before
+        rootTask.setWindowingMode(WINDOWING_MODE_FREEFORM);
+        assertEquals(freeformBounds, task.getBounds());
+    }
+
+    @Test
+    public void testReportsOrientationRequestInLetterboxForOrientation() {
+        final Rect fullScreenBounds = new Rect(0, 0, 1920, 1080);
+        final Rect fullScreenBoundsPort = new Rect(0, 0, 1080, 1920);
+        final DisplayContent display = new TestDisplayContent.Builder(mAtm,
+                fullScreenBounds.width(), fullScreenBounds.height()).setCanRotate(false).build();
+        assertNotNull(mRootWindowContainer.getDisplayContent(display.mDisplayId));
+        // Fix the display orientation to landscape which is the natural rotation (0) for the test
+        // display.
+        final DisplayRotation dr = display.mDisplayContent.getDisplayRotation();
+        dr.setFixedToUserRotation(FIXED_TO_USER_ROTATION_ENABLED);
+        dr.setUserRotation(USER_ROTATION_FREE, ROTATION_0);
+
+        final Task rootTask = new TaskBuilder(mSupervisor).setCreateActivity(true)
+                .setWindowingMode(WINDOWING_MODE_FULLSCREEN).setDisplay(display).build();
+        final Task task = rootTask.getBottomMostTask();
+        ActivityRecord root = task.getTopNonFinishingActivity();
+
+        assertEquals(fullScreenBounds, task.getBounds());
+
+        // Setting app to fixed portrait fits within parent on activity level. Task fills parent.
+        root.setRequestedOrientation(SCREEN_ORIENTATION_PORTRAIT);
+        assertThat(root.getBounds().width()).isLessThan(root.getBounds().height());
+        assertEquals(task.getBounds(), fullScreenBounds);
+
+        assertEquals(SCREEN_ORIENTATION_PORTRAIT, task.getOrientation());
+    }
+
+    @Test
+    public void testIgnoresForcedOrientationWhenParentHandles() {
+        final Rect fullScreenBounds = new Rect(0, 0, 1920, 1080);
+        DisplayContent display = new TestDisplayContent.Builder(
+                mAtm, fullScreenBounds.width(), fullScreenBounds.height()).build();
+
+        display.getRequestedOverrideConfiguration().orientation =
+                Configuration.ORIENTATION_LANDSCAPE;
+        display.onRequestedOverrideConfigurationChanged(
+                display.getRequestedOverrideConfiguration());
+        Task rootTask = new TaskBuilder(mSupervisor).setCreateActivity(true)
+                .setWindowingMode(WINDOWING_MODE_FULLSCREEN).setDisplay(display).build();
+        Task task = rootTask.getBottomMostTask();
+        ActivityRecord root = task.getTopNonFinishingActivity();
+
+        final WindowContainer parentWindowContainer =
+                new WindowContainer(mSystemServicesTestRule.getWindowManagerService());
+        spyOn(parentWindowContainer);
+        parentWindowContainer.setBounds(fullScreenBounds);
+        doReturn(parentWindowContainer).when(task).getParent();
+        doReturn(display.getDefaultTaskDisplayArea()).when(task).getDisplayArea();
+        doReturn(rootTask).when(task).getRootTask();
+        doReturn(true).when(parentWindowContainer).handlesOrientationChangeFromDescendant();
+
+        // Setting app to fixed portrait fits within parent, but Task shouldn't adjust the
+        // bounds because its parent says it will handle it at a later time.
+        root.setRequestedOrientation(SCREEN_ORIENTATION_PORTRAIT);
+        assertEquals(root, task.getRootActivity());
+        assertEquals(SCREEN_ORIENTATION_PORTRAIT, task.getRootActivity().getOrientation());
+        assertEquals(fullScreenBounds, task.getBounds());
+    }
+
+    @Test
+    public void testComputeConfigResourceOverrides() {
+        final Rect fullScreenBounds = new Rect(0, 0, 1080, 1920);
+        TestDisplayContent display = new TestDisplayContent.Builder(
+                mAtm, fullScreenBounds.width(), fullScreenBounds.height()).build();
+        final Task task = new TaskBuilder(mSupervisor).setDisplay(display).build();
+        final Configuration inOutConfig = new Configuration();
+        final Configuration parentConfig = new Configuration();
+        final int longSide = 1200;
+        final int shortSide = 600;
+        final Rect parentBounds = new Rect(0, 0, 250, 500);
+        final Rect parentAppBounds = new Rect(0, 0, 250, 480);
+        parentConfig.windowConfiguration.setBounds(parentBounds);
+        parentConfig.windowConfiguration.setAppBounds(parentAppBounds);
+        parentConfig.densityDpi = 400;
+        parentConfig.screenHeightDp = (parentBounds.bottom * 160) / parentConfig.densityDpi; // 200
+        parentConfig.screenWidthDp = (parentBounds.right * 160) / parentConfig.densityDpi; // 100
+        parentConfig.windowConfiguration.setRotation(ROTATION_0);
+
+        // By default, the input bounds will fill parent.
+        task.computeConfigResourceOverrides(inOutConfig, parentConfig);
+
+        assertEquals(parentConfig.screenHeightDp, inOutConfig.screenHeightDp);
+        assertEquals(parentConfig.screenWidthDp, inOutConfig.screenWidthDp);
+        assertEquals(parentAppBounds, inOutConfig.windowConfiguration.getAppBounds());
+        assertEquals(Configuration.ORIENTATION_PORTRAIT, inOutConfig.orientation);
+
+        // If bounds are overridden, config properties should be made to match. Surface hierarchy
+        // will crop for policy.
+        inOutConfig.setToDefaults();
+        final Rect largerPortraitBounds = new Rect(0, 0, shortSide, longSide);
+        inOutConfig.windowConfiguration.setBounds(largerPortraitBounds);
+        task.computeConfigResourceOverrides(inOutConfig, parentConfig);
+        // The override bounds are beyond the parent, the out appBounds should not be intersected
+        // by parent appBounds.
+        assertEquals(largerPortraitBounds, inOutConfig.windowConfiguration.getAppBounds());
+        assertEquals(longSide, inOutConfig.screenHeightDp * parentConfig.densityDpi / 160);
+        assertEquals(shortSide, inOutConfig.screenWidthDp * parentConfig.densityDpi / 160);
+
+        inOutConfig.setToDefaults();
+        // Landscape bounds.
+        final Rect largerLandscapeBounds = new Rect(0, 0, longSide, shortSide);
+        inOutConfig.windowConfiguration.setBounds(largerLandscapeBounds);
+
+        // Setup the display with a top stable inset. The later assertion will ensure the inset is
+        // excluded from screenHeightDp.
+        final int statusBarHeight = 100;
+        final DisplayPolicy policy = display.getDisplayPolicy();
+        doAnswer(invocationOnMock -> {
+            final Rect insets = invocationOnMock.<Rect>getArgument(0);
+            insets.top = statusBarHeight;
+            return null;
+        }).when(policy).convertNonDecorInsetsToStableInsets(any(), eq(ROTATION_0));
+
+        // Without limiting to be inside the parent bounds, the out screen size should keep relative
+        // to the input bounds.
+        final ActivityRecord activity = new ActivityBuilder(mAtm).setTask(task).build();
+        final ActivityRecord.CompatDisplayInsets compatIntsets =
+                new ActivityRecord.CompatDisplayInsets(
+                        display, activity, /* fixedOrientationBounds= */ null);
+        task.computeConfigResourceOverrides(inOutConfig, parentConfig, compatIntsets);
+
+        assertEquals(largerLandscapeBounds, inOutConfig.windowConfiguration.getAppBounds());
+        assertEquals((shortSide - statusBarHeight) * DENSITY_DEFAULT / parentConfig.densityDpi,
+                inOutConfig.screenHeightDp);
+        assertEquals(longSide * DENSITY_DEFAULT / parentConfig.densityDpi,
+                inOutConfig.screenWidthDp);
+        assertEquals(Configuration.ORIENTATION_LANDSCAPE, inOutConfig.orientation);
+    }
+
+    @Test
+    public void testComputeConfigResourceLayoutOverrides() {
+        final Rect fullScreenBounds = new Rect(0, 0, 1000, 2500);
+        TestDisplayContent display = new TestDisplayContent.Builder(
+                mAtm, fullScreenBounds.width(), fullScreenBounds.height()).build();
+        final Task task = new TaskBuilder(mSupervisor).setDisplay(display).build();
+        final Configuration inOutConfig = new Configuration();
+        final Configuration parentConfig = new Configuration();
+        final Rect nonLongBounds = new Rect(0, 0, 1000, 1250);
+        parentConfig.windowConfiguration.setBounds(fullScreenBounds);
+        parentConfig.windowConfiguration.setAppBounds(fullScreenBounds);
+        parentConfig.densityDpi = 400;
+        parentConfig.screenHeightDp = (fullScreenBounds.bottom * 160) / parentConfig.densityDpi;
+        parentConfig.screenWidthDp = (fullScreenBounds.right * 160) / parentConfig.densityDpi;
+        parentConfig.windowConfiguration.setRotation(ROTATION_0);
+
+        // Set BOTH screenW/H to an override value
+        inOutConfig.screenWidthDp = nonLongBounds.width() * 160 / parentConfig.densityDpi;
+        inOutConfig.screenHeightDp = nonLongBounds.height() * 160 / parentConfig.densityDpi;
+        task.computeConfigResourceOverrides(inOutConfig, parentConfig);
+
+        // screenLayout should honor override when both screenW/H are set.
+        assertTrue((inOutConfig.screenLayout & Configuration.SCREENLAYOUT_LONG_NO) != 0);
+    }
+
+    @Test
+    public void testComputeNestedConfigResourceOverrides() {
+        final Task task = new TaskBuilder(mSupervisor).build();
+        assertTrue(task.getResolvedOverrideBounds().isEmpty());
+        int origScreenH = task.getConfiguration().screenHeightDp;
+        Configuration rootTaskConfig = new Configuration();
+        rootTaskConfig.setTo(task.getRootTask().getRequestedOverrideConfiguration());
+        rootTaskConfig.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM);
+
+        // Set bounds on root task (not task) and verify that the task resource configuration
+        // changes despite it's override bounds being empty.
+        Rect bounds = new Rect(task.getRootTask().getBounds());
+        bounds.bottom = (int) (bounds.bottom * 0.6f);
+        rootTaskConfig.windowConfiguration.setBounds(bounds);
+        task.getRootTask().onRequestedOverrideConfigurationChanged(rootTaskConfig);
+        assertNotEquals(origScreenH, task.getConfiguration().screenHeightDp);
+    }
+
+    @Test
+    public void testFullScreenTaskNotAdjustedByMinimalSize() {
+        final Task fullscreenTask = new TaskBuilder(mSupervisor).build();
+        final Rect originalTaskBounds = new Rect(fullscreenTask.getBounds());
+        final ActivityInfo aInfo = new ActivityInfo();
+        aInfo.windowLayout = new ActivityInfo.WindowLayout(0 /* width */, 0 /* widthFraction */,
+                0 /* height */, 0 /* heightFraction */, 0 /* gravity */,
+                originalTaskBounds.width() * 2 /* minWidth */,
+                originalTaskBounds.height() * 2 /* minHeight */);
+        fullscreenTask.setMinDimensions(aInfo);
+        fullscreenTask.onConfigurationChanged(fullscreenTask.getParent().getConfiguration());
+
+        assertEquals(originalTaskBounds, fullscreenTask.getBounds());
+    }
+
+    @Test
+    public void testInsetDisregardedWhenFreeformOverlapsNavBar() {
+        TaskDisplayArea taskDisplayArea = mAtm.mRootWindowContainer.getDefaultTaskDisplayArea();
+        Task rootTask = taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
+                ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        DisplayInfo displayInfo = new DisplayInfo();
+        mAtm.mContext.getDisplay().getDisplayInfo(displayInfo);
+        final int displayHeight = displayInfo.logicalHeight;
+        final Task task = new TaskBuilder(mSupervisor).setParentTask(rootTask).build();
+        final Configuration inOutConfig = new Configuration();
+        final Configuration parentConfig = new Configuration();
+        final int longSide = 1200;
+        final int shortSide = 600;
+        parentConfig.densityDpi = 400;
+        parentConfig.screenHeightDp = 200; // 200 * 400 / 160 = 500px
+        parentConfig.screenWidthDp = 100; // 100 * 400 / 160 = 250px
+        parentConfig.windowConfiguration.setRotation(ROTATION_0);
+
+        final int longSideDp = 480; // longSide / density = 1200 / 400 * 160
+        final int shortSideDp = 240; // shortSide / density = 600 / 400 * 160
+        final int screenLayout = parentConfig.screenLayout
+                & (Configuration.SCREENLAYOUT_LONG_MASK | Configuration.SCREENLAYOUT_SIZE_MASK);
+        final int reducedScreenLayout =
+                Configuration.reduceScreenLayout(screenLayout, longSideDp, shortSideDp);
+
+        // Portrait bounds overlapping with navigation bar, without insets.
+        final Rect freeformBounds = new Rect(0,
+                displayHeight - 10 - longSide,
+                shortSide,
+                displayHeight - 10);
+        inOutConfig.windowConfiguration.setBounds(freeformBounds);
+        // Set to freeform mode to verify bug fix.
+        inOutConfig.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM);
+
+        task.computeConfigResourceOverrides(inOutConfig, parentConfig);
+
+        // screenW/H should not be effected by parent since overridden and freeform
+        assertEquals(freeformBounds.width() * 160 / parentConfig.densityDpi,
+                inOutConfig.screenWidthDp);
+        assertEquals(freeformBounds.height() * 160 / parentConfig.densityDpi,
+                inOutConfig.screenHeightDp);
+        assertEquals(reducedScreenLayout, inOutConfig.screenLayout);
+
+        inOutConfig.setToDefaults();
+        // Landscape bounds overlapping with navigtion bar, without insets.
+        freeformBounds.set(0,
+                displayHeight - 10 - shortSide,
+                longSide,
+                displayHeight - 10);
+        inOutConfig.windowConfiguration.setBounds(freeformBounds);
+        inOutConfig.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM);
+
+        task.computeConfigResourceOverrides(inOutConfig, parentConfig);
+
+        assertEquals(freeformBounds.width() * 160 / parentConfig.densityDpi,
+                inOutConfig.screenWidthDp);
+        assertEquals(freeformBounds.height() * 160 / parentConfig.densityDpi,
+                inOutConfig.screenHeightDp);
+        assertEquals(reducedScreenLayout, inOutConfig.screenLayout);
+    }
+
+    /** Ensures that the alias intent won't have target component resolved. */
+    @Test
+    public void testTaskIntentActivityAlias() {
+        final String aliasClassName = DEFAULT_COMPONENT_PACKAGE_NAME + ".aliasActivity";
+        final String targetClassName = DEFAULT_COMPONENT_PACKAGE_NAME + ".targetActivity";
+        final ComponentName aliasComponent =
+                new ComponentName(DEFAULT_COMPONENT_PACKAGE_NAME, aliasClassName);
+        final ComponentName targetComponent =
+                new ComponentName(DEFAULT_COMPONENT_PACKAGE_NAME, targetClassName);
+
+        final Intent intent = new Intent();
+        intent.setComponent(aliasComponent);
+        final ActivityInfo info = new ActivityInfo();
+        info.applicationInfo = new ApplicationInfo();
+        info.packageName = DEFAULT_COMPONENT_PACKAGE_NAME;
+        info.targetActivity = targetClassName;
+
+        final Task task = new Task.Builder(mAtm)
+                .setTaskId(1)
+                .setActivityInfo(info)
+                .setIntent(intent)
+                .build();
+        assertEquals("The alias activity component should be saved in task intent.", aliasClassName,
+                task.intent.getComponent().getClassName());
+
+        ActivityRecord aliasActivity = new ActivityBuilder(mAtm).setComponent(
+                aliasComponent).setTargetActivity(targetClassName).build();
+        assertEquals("Should be the same intent filter.", true,
+                task.isSameIntentFilter(aliasActivity));
+
+        ActivityRecord targetActivity = new ActivityBuilder(mAtm).setComponent(
+                targetComponent).build();
+        assertEquals("Should be the same intent filter.", true,
+                task.isSameIntentFilter(targetActivity));
+
+        ActivityRecord defaultActivity = new ActivityBuilder(mAtm).build();
+        assertEquals("Should not be the same intent filter.", false,
+                task.isSameIntentFilter(defaultActivity));
+    }
+
+    /** Test that root activity index is reported correctly for several activities in the task. */
+    @Test
+    public void testFindRootIndex() {
+        final Task task = getTestTask();
+        // Add an extra activity on top of the root one
+        new ActivityBuilder(mAtm).setTask(task).build();
+
+        assertEquals("The root activity in the task must be reported.", task.getChildAt(0),
+                task.getRootActivity(
+                        true /*ignoreRelinquishIdentity*/, true /*setToBottomIfNone*/));
+    }
+
+    /**
+     * Test that root activity index is reported correctly for several activities in the task when
+     * the activities on the bottom are finishing.
+     */
+    @Test
+    public void testFindRootIndex_finishing() {
+        final Task task = getTestTask();
+        // Add extra two activities and mark the two on the bottom as finishing.
+        final ActivityRecord activity0 = task.getBottomMostActivity();
+        activity0.finishing = true;
+        final ActivityRecord activity1 = new ActivityBuilder(mAtm).setTask(task).build();
+        activity1.finishing = true;
+        new ActivityBuilder(mAtm).setTask(task).build();
+
+        assertEquals("The first non-finishing activity in the task must be reported.",
+                task.getChildAt(2), task.getRootActivity(
+                        true /*ignoreRelinquishIdentity*/, true /*setToBottomIfNone*/));
+    }
+
+    /**
+     * Test that root activity index is reported correctly for several activities in the task when
+     * looking for the 'effective root'.
+     */
+    @Test
+    public void testFindRootIndex_effectiveRoot() {
+        final Task task = getTestTask();
+        // Add an extra activity on top of the root one
+        new ActivityBuilder(mAtm).setTask(task).build();
+
+        assertEquals("The root activity in the task must be reported.",
+                task.getChildAt(0), task.getRootActivity(
+                        false /*ignoreRelinquishIdentity*/, true /*setToBottomIfNone*/));
+    }
+
+    /**
+     * Test that root activity index is reported correctly when looking for the 'effective root' in
+     * case when bottom activities are relinquishing task identity or finishing.
+     */
+    @Test
+    public void testFindRootIndex_effectiveRoot_finishingAndRelinquishing() {
+        final Task task = getTestTask();
+        // Add extra two activities. Mark the one on the bottom with "relinquishTaskIdentity" and
+        // one above as finishing.
+        final ActivityRecord activity0 = task.getBottomMostActivity();
+        activity0.info.flags |= FLAG_RELINQUISH_TASK_IDENTITY;
+        final ActivityRecord activity1 = new ActivityBuilder(mAtm).setTask(task).build();
+        activity1.finishing = true;
+        new ActivityBuilder(mAtm).setTask(task).build();
+
+        assertEquals("The first non-finishing activity and non-relinquishing task identity "
+                + "must be reported.", task.getChildAt(2), task.getRootActivity(
+                false /*ignoreRelinquishIdentity*/, true /*setToBottomIfNone*/));
+    }
+
+    /**
+     * Test that root activity index is reported correctly when looking for the 'effective root'
+     * for the case when there is only a single activity that also has relinquishTaskIdentity set.
+     */
+    @Test
+    public void testFindRootIndex_effectiveRoot_relinquishingAndSingleActivity() {
+        final Task task = getTestTask();
+        // Set relinquishTaskIdentity for the only activity in the task
+        task.getBottomMostActivity().info.flags |= FLAG_RELINQUISH_TASK_IDENTITY;
+
+        assertEquals("The root activity in the task must be reported.",
+                task.getChildAt(0), task.getRootActivity(
+                        false /*ignoreRelinquishIdentity*/, true /*setToBottomIfNone*/));
+    }
+
+    /**
+     * Test that the topmost activity index is reported correctly when looking for the
+     * 'effective root' for the case when all activities have relinquishTaskIdentity set.
+     */
+    @Test
+    public void testFindRootIndex_effectiveRoot_relinquishingMultipleActivities() {
+        final Task task = getTestTask();
+        // Set relinquishTaskIdentity for all activities in the task
+        final ActivityRecord activity0 = task.getBottomMostActivity();
+        activity0.info.flags |= FLAG_RELINQUISH_TASK_IDENTITY;
+        final ActivityRecord activity1 = new ActivityBuilder(mAtm).setTask(task).build();
+        activity1.info.flags |= FLAG_RELINQUISH_TASK_IDENTITY;
+
+        assertEquals("The topmost activity in the task must be reported.",
+                task.getChildAt(task.getChildCount() - 1), task.getRootActivity(
+                        false /*ignoreRelinquishIdentity*/, true /*setToBottomIfNone*/));
+    }
+
+    /** Test that bottom-most activity is reported in {@link Task#getRootActivity()}. */
+    @Test
+    public void testGetRootActivity() {
+        final Task task = getTestTask();
+        // Add an extra activity on top of the root one
+        new ActivityBuilder(mAtm).setTask(task).build();
+
+        assertEquals("The root activity in the task must be reported.",
+                task.getBottomMostActivity(), task.getRootActivity());
+    }
+
+    /**
+     * Test that first non-finishing activity is reported in {@link Task#getRootActivity()}.
+     */
+    @Test
+    public void testGetRootActivity_finishing() {
+        final Task task = getTestTask();
+        // Add an extra activity on top of the root one
+        new ActivityBuilder(mAtm).setTask(task).build();
+        // Mark the root as finishing
+        task.getBottomMostActivity().finishing = true;
+
+        assertEquals("The first non-finishing activity in the task must be reported.",
+                task.getChildAt(1), task.getRootActivity());
+    }
+
+    /**
+     * Test that relinquishTaskIdentity flag is ignored in {@link Task#getRootActivity()}.
+     */
+    @Test
+    public void testGetRootActivity_relinquishTaskIdentity() {
+        final Task task = getTestTask();
+        // Mark the bottom-most activity with FLAG_RELINQUISH_TASK_IDENTITY.
+        final ActivityRecord activity0 = task.getBottomMostActivity();
+        activity0.info.flags |= FLAG_RELINQUISH_TASK_IDENTITY;
+        // Add an extra activity on top of the root one.
+        new ActivityBuilder(mAtm).setTask(task).build();
+
+        assertEquals("The root activity in the task must be reported.",
+                task.getBottomMostActivity(), task.getRootActivity());
+    }
+
+    /**
+     * Test that no activity is reported in {@link Task#getRootActivity()} when all activities
+     * in the task are finishing.
+     */
+    @Test
+    public void testGetRootActivity_allFinishing() {
+        final Task task = getTestTask();
+        // Mark the bottom-most activity as finishing.
+        final ActivityRecord activity0 = task.getBottomMostActivity();
+        activity0.finishing = true;
+        // Add an extra activity on top of the root one and mark it as finishing
+        final ActivityRecord activity1 = new ActivityBuilder(mAtm).setTask(task).build();
+        activity1.finishing = true;
+
+        assertNull("No activity must be reported if all are finishing", task.getRootActivity());
+    }
+
+    /**
+     * Test that first non-finishing activity is the root of task.
+     */
+    @Test
+    public void testIsRootActivity() {
+        final Task task = getTestTask();
+        // Mark the bottom-most activity as finishing.
+        final ActivityRecord activity0 = task.getBottomMostActivity();
+        activity0.finishing = true;
+        // Add an extra activity on top of the root one.
+        final ActivityRecord activity1 = new ActivityBuilder(mAtm).setTask(task).build();
+
+        assertFalse("Finishing activity must not be the root of task", activity0.isRootOfTask());
+        assertTrue("Non-finishing activity must be the root of task", activity1.isRootOfTask());
+    }
+
+    /**
+     * Test that if all activities in the task are finishing, then the one on the bottom is the
+     * root of task.
+     */
+    @Test
+    public void testIsRootActivity_allFinishing() {
+        final Task task = getTestTask();
+        // Mark the bottom-most activity as finishing.
+        final ActivityRecord activity0 = task.getBottomMostActivity();
+        activity0.finishing = true;
+        // Add an extra activity on top of the root one and mark it as finishing
+        final ActivityRecord activity1 = new ActivityBuilder(mAtm).setTask(task).build();
+        activity1.finishing = true;
+
+        assertTrue("Bottom activity must be the root of task", activity0.isRootOfTask());
+        assertFalse("Finishing activity on top must not be the root of task",
+                activity1.isRootOfTask());
+    }
+
+    /**
+     * Test {@link ActivityRecord#getTaskForActivityLocked(IBinder, boolean)}.
+     */
+    @Test
+    public void testGetTaskForActivity() {
+        final Task task0 = getTestTask();
+        final ActivityRecord activity0 = task0.getBottomMostActivity();
+
+        final Task task1 = getTestTask();
+        final ActivityRecord activity1 = task1.getBottomMostActivity();
+
+        assertEquals(task0.mTaskId,
+                ActivityRecord.getTaskForActivityLocked(activity0.appToken, false /* onlyRoot */));
+        assertEquals(task1.mTaskId,
+                ActivityRecord.getTaskForActivityLocked(activity1.appToken,  false /* onlyRoot */));
+    }
+
+    /**
+     * Test {@link ActivityRecord#getTaskForActivityLocked(IBinder, boolean)} with finishing
+     * activity.
+     */
+    @Test
+    public void testGetTaskForActivity_onlyRoot_finishing() {
+        final Task task = getTestTask();
+        // Make the current root activity finishing
+        final ActivityRecord activity0 = task.getBottomMostActivity();
+        activity0.finishing = true;
+        // Add an extra activity on top - this will be the new root
+        final ActivityRecord activity1 = new ActivityBuilder(mAtm).setTask(task).build();
+        // Add one more on top
+        final ActivityRecord activity2 = new ActivityBuilder(mAtm).setTask(task).build();
+
+        assertEquals(task.mTaskId,
+                ActivityRecord.getTaskForActivityLocked(activity0.appToken, true /* onlyRoot */));
+        assertEquals(task.mTaskId,
+                ActivityRecord.getTaskForActivityLocked(activity1.appToken, true /* onlyRoot */));
+        assertEquals("No task must be reported for activity that is above root", INVALID_TASK_ID,
+                ActivityRecord.getTaskForActivityLocked(activity2.appToken, true /* onlyRoot */));
+    }
+
+    /**
+     * Test {@link ActivityRecord#getTaskForActivityLocked(IBinder, boolean)} with activity that
+     * relinquishes task identity.
+     */
+    @Test
+    public void testGetTaskForActivity_onlyRoot_relinquishTaskIdentity() {
+        final Task task = getTestTask();
+        // Make the current root activity relinquish task identity
+        final ActivityRecord activity0 = task.getBottomMostActivity();
+        activity0.info.flags |= FLAG_RELINQUISH_TASK_IDENTITY;
+        // Add an extra activity on top - this will be the new root
+        final ActivityRecord activity1 = new ActivityBuilder(mAtm).setTask(task).build();
+        // Add one more on top
+        final ActivityRecord activity2 = new ActivityBuilder(mAtm).setTask(task).build();
+
+        assertEquals(task.mTaskId,
+                ActivityRecord.getTaskForActivityLocked(activity0.appToken, true /* onlyRoot */));
+        assertEquals(task.mTaskId,
+                ActivityRecord.getTaskForActivityLocked(activity1.appToken, true /* onlyRoot */));
+        assertEquals("No task must be reported for activity that is above root", INVALID_TASK_ID,
+                ActivityRecord.getTaskForActivityLocked(activity2.appToken, true /* onlyRoot */));
+    }
+
+    /**
+     * Test {@link ActivityRecord#getTaskForActivityLocked(IBinder, boolean)} allowing non-root
+     * entries.
+     */
+    @Test
+    public void testGetTaskForActivity_notOnlyRoot() {
+        final Task task = getTestTask();
+        // Mark the bottom-most activity as finishing.
+        final ActivityRecord activity0 = task.getBottomMostActivity();
+        activity0.finishing = true;
+
+        // Add an extra activity on top of the root one and make it relinquish task identity
+        final ActivityRecord activity1 = new ActivityBuilder(mAtm).setTask(task).build();
+        activity1.info.flags |= FLAG_RELINQUISH_TASK_IDENTITY;
+
+        // Add one more activity on top
+        final ActivityRecord activity2 = new ActivityBuilder(mAtm).setTask(task).build();
+
+        assertEquals(task.mTaskId,
+                ActivityRecord.getTaskForActivityLocked(activity0.appToken, false /* onlyRoot */));
+        assertEquals(task.mTaskId,
+                ActivityRecord.getTaskForActivityLocked(activity1.appToken, false /* onlyRoot */));
+        assertEquals(task.mTaskId,
+                ActivityRecord.getTaskForActivityLocked(activity2.appToken, false /* onlyRoot */));
+    }
+
+    /**
+     * Test {@link Task#updateEffectiveIntent()}.
+     */
+    @Test
+    public void testUpdateEffectiveIntent() {
+        // Test simple case with a single activity.
+        final Task task = getTestTask();
+        final ActivityRecord activity0 = task.getBottomMostActivity();
+
+        spyOn(task);
+        task.updateEffectiveIntent();
+        verify(task).setIntent(eq(activity0));
+    }
+
+    /**
+     * Test {@link Task#updateEffectiveIntent()} with root activity marked as finishing. This
+     * should make the task use the second activity when updating the intent.
+     */
+    @Test
+    public void testUpdateEffectiveIntent_rootFinishing() {
+        // Test simple case with a single activity.
+        final Task task = getTestTask();
+        final ActivityRecord activity0 = task.getBottomMostActivity();
+        // Mark the bottom-most activity as finishing.
+        activity0.finishing = true;
+        // Add an extra activity on top of the root one
+        final ActivityRecord activity1 = new ActivityBuilder(mAtm).setTask(task).build();
+
+        spyOn(task);
+        task.updateEffectiveIntent();
+        verify(task).setIntent(eq(activity1));
+    }
+
+    /**
+     * Test {@link Task#updateEffectiveIntent()} when all activities are finishing or
+     * relinquishing task identity. In this case the root activity should still be used when
+     * updating the intent (legacy behavior).
+     */
+    @Test
+    public void testUpdateEffectiveIntent_allFinishing() {
+        // Test simple case with a single activity.
+        final Task task = getTestTask();
+        final ActivityRecord activity0 = task.getBottomMostActivity();
+        // Mark the bottom-most activity as finishing.
+        activity0.finishing = true;
+        // Add an extra activity on top of the root one and make it relinquish task identity
+        final ActivityRecord activity1 = new ActivityBuilder(mAtm).setTask(task).build();
+        activity1.finishing = true;
+
+        // Task must still update the intent using the root activity (preserving legacy behavior).
+        spyOn(task);
+        task.updateEffectiveIntent();
+        verify(task).setIntent(eq(activity0));
+    }
+
+    @Test
+    public void testSaveLaunchingStateWhenConfigurationChanged() {
+        LaunchParamsPersister persister = mAtm.mTaskSupervisor.mLaunchParamsPersister;
+        spyOn(persister);
+
+        final Task task = getTestTask();
+        task.setHasBeenVisible(false);
+        task.getDisplayContent().setDisplayWindowingMode(WINDOWING_MODE_FREEFORM);
+        task.getRootTask().setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+
+        task.setHasBeenVisible(true);
+        task.onConfigurationChanged(task.getParent().getConfiguration());
+
+        verify(persister).saveTask(task, task.getDisplayContent());
+    }
+
+    @Test
+    public void testSaveLaunchingStateWhenClearingParent() {
+        LaunchParamsPersister persister = mAtm.mTaskSupervisor.mLaunchParamsPersister;
+        spyOn(persister);
+
+        final Task task = getTestTask();
+        task.setHasBeenVisible(false);
+        task.getDisplayContent().setWindowingMode(WindowConfiguration.WINDOWING_MODE_FREEFORM);
+        task.getRootTask().setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+        final DisplayContent oldDisplay = task.getDisplayContent();
+
+        LaunchParamsController.LaunchParams params = new LaunchParamsController.LaunchParams();
+        params.mWindowingMode = WINDOWING_MODE_UNDEFINED;
+        persister.getLaunchParams(task, null, params);
+        assertEquals(WINDOWING_MODE_UNDEFINED, params.mWindowingMode);
+
+        task.setHasBeenVisible(true);
+        task.removeImmediately();
+
+        verify(persister).saveTask(task, oldDisplay);
+
+        persister.getLaunchParams(task, null, params);
+        assertEquals(WINDOWING_MODE_FULLSCREEN, params.mWindowingMode);
+    }
+
+    @Test
+    public void testNotSaveLaunchingStateNonFreeformDisplay() {
+        LaunchParamsPersister persister = mAtm.mTaskSupervisor.mLaunchParamsPersister;
+        spyOn(persister);
+
+        final Task task = getTestTask();
+        task.setHasBeenVisible(false);
+        task.getRootTask().setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+
+        task.setHasBeenVisible(true);
+        task.onConfigurationChanged(task.getParent().getConfiguration());
+
+        Mockito.verify(persister, never()).saveTask(same(task), any());
+    }
+
+    @Test
+    public void testNotSaveLaunchingStateWhenNotFullscreenOrFreeformWindow() {
+        LaunchParamsPersister persister = mAtm.mTaskSupervisor.mLaunchParamsPersister;
+        spyOn(persister);
+
+        final Task task = getTestTask();
+        task.setHasBeenVisible(false);
+        task.getDisplayContent().setDisplayWindowingMode(WINDOWING_MODE_FREEFORM);
+        task.getRootTask().setWindowingMode(WINDOWING_MODE_PINNED);
+
+        task.setHasBeenVisible(true);
+        task.onConfigurationChanged(task.getParent().getConfiguration());
+
+        Mockito.verify(persister, never()).saveTask(same(task), any());
+    }
+
+    @Test
+    public void testNotSaveLaunchingStateForNonLeafTask() {
+        LaunchParamsPersister persister = mAtm.mTaskSupervisor.mLaunchParamsPersister;
+        spyOn(persister);
+
+        final Task task = getTestTask();
+        task.setHasBeenVisible(false);
+        task.getDisplayContent().setDisplayWindowingMode(WINDOWING_MODE_FREEFORM);
+        task.getRootTask().setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+
+        final Task leafTask = createTaskInRootTask(task, 0 /* userId */);
+
+        leafTask.setHasBeenVisible(true);
+        task.setHasBeenVisible(true);
+        task.onConfigurationChanged(task.getParent().getConfiguration());
+
+        Mockito.verify(persister, never()).saveTask(same(task), any());
+        verify(persister).saveTask(same(leafTask), any());
+    }
+
+    @Test
+    public void testNotSpecifyOrientationByFloatingTask() {
+        final Task task = new TaskBuilder(mSupervisor)
+                .setCreateActivity(true).setCreateParentTask(true).build();
+        final ActivityRecord activity = task.getTopMostActivity();
+        final WindowContainer<?> parentContainer = task.getParent();
+        final TaskDisplayArea taskDisplayArea = task.getDisplayArea();
+        activity.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE);
+
+        assertEquals(SCREEN_ORIENTATION_LANDSCAPE, parentContainer.getOrientation());
+        assertEquals(SCREEN_ORIENTATION_LANDSCAPE, taskDisplayArea.getOrientation());
+
+        task.setWindowingMode(WINDOWING_MODE_PINNED);
+
+        // TDA returns the last orientation when child returns UNSET
+        assertEquals(SCREEN_ORIENTATION_UNSET, parentContainer.getOrientation());
+        assertEquals(SCREEN_ORIENTATION_LANDSCAPE, taskDisplayArea.getOrientation());
+    }
+
+    @Test
+    public void testNotSpecifyOrientation_taskDisplayAreaNotFocused() {
+        final TaskDisplayArea firstTaskDisplayArea = mDisplayContent.getDefaultTaskDisplayArea();
+        final TaskDisplayArea secondTaskDisplayArea = createTaskDisplayArea(
+                mDisplayContent, mRootWindowContainer.mWmService, "TestTaskDisplayArea",
+                FEATURE_VENDOR_FIRST);
+        final Task firstRootTask = firstTaskDisplayArea.createRootTask(
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
+        final Task secondRootTask = secondTaskDisplayArea.createRootTask(
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
+        final ActivityRecord firstActivity = new ActivityBuilder(mAtm)
+                .setTask(firstRootTask).build();
+        final ActivityRecord secondActivity = new ActivityBuilder(mAtm)
+                .setTask(secondRootTask).build();
+        firstActivity.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE);
+        secondActivity.setRequestedOrientation(SCREEN_ORIENTATION_PORTRAIT);
+
+        // Activity on TDA1 is focused
+        mDisplayContent.setFocusedApp(firstActivity);
+
+        assertEquals(SCREEN_ORIENTATION_LANDSCAPE, firstTaskDisplayArea.getOrientation());
+        assertEquals(SCREEN_ORIENTATION_UNSET, secondTaskDisplayArea.getOrientation());
+
+        // No focused app, TDA1 is still recorded as last focused.
+        mDisplayContent.setFocusedApp(null);
+
+        assertEquals(SCREEN_ORIENTATION_LANDSCAPE, firstTaskDisplayArea.getOrientation());
+        assertEquals(SCREEN_ORIENTATION_UNSET, secondTaskDisplayArea.getOrientation());
+
+        // Activity on TDA2 is focused
+        mDisplayContent.setFocusedApp(secondActivity);
+
+        assertEquals(SCREEN_ORIENTATION_UNSET, firstTaskDisplayArea.getOrientation());
+        assertEquals(SCREEN_ORIENTATION_PORTRAIT, secondTaskDisplayArea.getOrientation());
+    }
+
+    @Test
+    public void testNotifyOrientationChangeCausedByConfigurationChange() {
+        final Task task = getTestTask();
+        final ActivityRecord activity = task.getTopMostActivity();
+        final DisplayContent display = task.getDisplayContent();
+        display.setWindowingMode(WINDOWING_MODE_FREEFORM);
+
+        activity.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE);
+        assertEquals(SCREEN_ORIENTATION_UNSET, task.getOrientation());
+        verify(display).onDescendantOrientationChanged(same(task));
+        reset(display);
+
+        display.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+        assertEquals(SCREEN_ORIENTATION_LANDSCAPE, task.getOrientation());
+        verify(display).onDescendantOrientationChanged(same(task));
+    }
+
+    private Task getTestTask() {
+        final Task task = new TaskBuilder(mSupervisor).setCreateActivity(true).build();
+        return task.getBottomMostTask();
+    }
+
+    private void testRootTaskBoundsConfiguration(int windowingMode, Rect parentBounds, Rect bounds,
+            Rect expectedConfigBounds) {
+
+        TaskDisplayArea taskDisplayArea = mAtm.mRootWindowContainer.getDefaultTaskDisplayArea();
+        Task rootTask = taskDisplayArea.createRootTask(windowingMode, ACTIVITY_TYPE_STANDARD,
+                true /* onTop */);
+        Task task = new TaskBuilder(mSupervisor).setParentTask(rootTask).build();
+
+        final Configuration parentConfig = rootTask.getConfiguration();
+        parentConfig.windowConfiguration.setAppBounds(parentBounds);
+        task.setBounds(bounds);
+
+        task.resolveOverrideConfiguration(parentConfig);
+        // Assert that both expected and actual are null or are equal to each other
+        assertEquals(expectedConfigBounds,
+                task.getResolvedOverrideConfiguration().windowConfiguration.getAppBounds());
+    }
+
+    private byte[] serializeToBytes(Task r) throws Exception {
+        try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
+            final TypedXmlSerializer serializer = Xml.newFastSerializer();
+            serializer.setOutput(os, "UTF-8");
+            serializer.startDocument(null, true);
+            serializer.startTag(null, TASK_TAG);
+            r.saveToXml(serializer);
+            serializer.endTag(null, TASK_TAG);
+            serializer.endDocument();
+
+            os.flush();
+            return os.toByteArray();
+        }
+    }
+
+    private Task restoreFromBytes(byte[] in) throws IOException, XmlPullParserException {
+        try (Reader reader = new InputStreamReader(new ByteArrayInputStream(in))) {
+            final TypedXmlPullParser parser = Xml.newFastPullParser();
+            parser.setInput(reader);
+            assertEquals(XmlPullParser.START_TAG, parser.next());
+            assertEquals(TASK_TAG, parser.getName());
+            return Task.restoreFromXml(parser, mAtm.mTaskSupervisor);
+        }
+    }
+
+    private Task createTask(int taskId) {
+        return new Task.Builder(mAtm)
+                .setTaskId(taskId)
+                .setIntent(new Intent())
+                .setRealActivity(ActivityBuilder.getDefaultComponent())
+                .setEffectiveUid(10050)
+                .buildInner();
+    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java b/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java
index 21536a6..777149b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java
@@ -37,6 +37,8 @@
 
 class TestDisplayContent extends DisplayContent {
 
+    public static final int DEFAULT_LOGICAL_DISPLAY_DENSITY = 300;
+
     /** Please use the {@link Builder} to create, visible for use in test builder overrides only. */
     TestDisplayContent(RootWindowContainer rootWindowContainer, Display display) {
         super(display, rootWindowContainer);
@@ -82,12 +84,21 @@
             mService.mContext.getDisplay().getDisplayInfo(mInfo);
             mInfo.logicalWidth = width;
             mInfo.logicalHeight = height;
-            mInfo.logicalDensityDpi = 300;
+            mInfo.logicalDensityDpi = DEFAULT_LOGICAL_DISPLAY_DENSITY;
             mInfo.displayCutout = null;
+            // Set unique ID so physical display overrides are not inheritted from
+            // DisplayWindowSettings.
+            mInfo.uniqueId = generateUniqueId();
         }
         Builder(ActivityTaskManagerService service, DisplayInfo info) {
             mService = service;
             mInfo = info;
+            // Set unique ID so physical display overrides are not inheritted from
+            // DisplayWindowSettings.
+            mInfo.uniqueId = generateUniqueId();
+        }
+        private String generateUniqueId() {
+            return "TEST_DISPLAY_CONTENT_" + System.currentTimeMillis();
         }
         Builder setSystemDecorations(boolean yes) {
             mSystemDecorations = yes;
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 79ef868..2dfb3a1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
@@ -69,10 +69,8 @@
         ArrayMap<WindowContainer, Transition.ChangeInfo> changes = transition.mChanges;
         ArraySet<WindowContainer> participants = transition.mParticipants;
 
-        final Task newTask = createTaskStackOnDisplay(WINDOWING_MODE_FULLSCREEN,
-                ACTIVITY_TYPE_STANDARD, mDisplayContent);
-        final Task oldTask = createTaskStackOnDisplay(WINDOWING_MODE_FULLSCREEN,
-                ACTIVITY_TYPE_STANDARD, mDisplayContent);
+        final Task newTask = createTask(mDisplayContent);
+        final Task oldTask = createTask(mDisplayContent);
         final ActivityRecord closing = createActivityRecord(oldTask);
         final ActivityRecord opening = createActivityRecord(newTask);
         // Start states.
@@ -128,12 +126,10 @@
         ArrayMap<WindowContainer, Transition.ChangeInfo> changes = transition.mChanges;
         ArraySet<WindowContainer> participants = transition.mParticipants;
 
-        final Task newTask = createTaskStackOnDisplay(WINDOWING_MODE_FULLSCREEN,
-                ACTIVITY_TYPE_STANDARD, mDisplayContent);
-        final Task newNestedTask = createTaskInStack(newTask, 0);
-        final Task newNestedTask2 = createTaskInStack(newTask, 0);
-        final Task oldTask = createTaskStackOnDisplay(WINDOWING_MODE_FULLSCREEN,
-                ACTIVITY_TYPE_STANDARD, mDisplayContent);
+        final Task newTask = createTask(mDisplayContent);
+        final Task newNestedTask = createTaskInRootTask(newTask, 0);
+        final Task newNestedTask2 = createTaskInRootTask(newTask, 0);
+        final Task oldTask = createTask(mDisplayContent);
         final ActivityRecord closing = createActivityRecord(oldTask);
         final ActivityRecord opening = createActivityRecord(newNestedTask);
         final ActivityRecord opening2 = createActivityRecord(newNestedTask2);
@@ -179,11 +175,9 @@
         final Transition transition = createTestTransition(TRANSIT_OLD_TASK_OPEN);
         ArrayMap<WindowContainer, Transition.ChangeInfo> changes = transition.mChanges;
         ArraySet<WindowContainer> participants = transition.mParticipants;
-        final Task showTask = createTaskStackOnDisplay(WINDOWING_MODE_FULLSCREEN,
-                ACTIVITY_TYPE_STANDARD, mDisplayContent);
-        final Task showNestedTask = createTaskInStack(showTask, 0);
-        final Task showTask2 = createTaskStackOnDisplay(WINDOWING_MODE_FULLSCREEN,
-                ACTIVITY_TYPE_STANDARD, mDisplayContent);
+        final Task showTask = createTask(mDisplayContent);
+        final Task showNestedTask = createTaskInRootTask(showTask, 0);
+        final Task showTask2 = createTask(mDisplayContent);
         final DisplayArea tda = showTask.getDisplayArea();
         final ActivityRecord showing = createActivityRecord(showNestedTask);
         final ActivityRecord showing2 = createActivityRecord(showTask2);
@@ -231,12 +225,10 @@
     public void testCreateInfo_existenceChange() {
         final Transition transition = createTestTransition(TRANSIT_OLD_TASK_OPEN);
 
-        final Task openTask = createTaskStackOnDisplay(WINDOWING_MODE_FULLSCREEN,
-                ACTIVITY_TYPE_STANDARD, mDisplayContent);
+        final Task openTask = createTask(mDisplayContent);
         final ActivityRecord opening = createActivityRecord(openTask);
         opening.mVisibleRequested = false; // starts invisible
-        final Task closeTask = createTaskStackOnDisplay(WINDOWING_MODE_FULLSCREEN,
-                ACTIVITY_TYPE_STANDARD, mDisplayContent);
+        final Task closeTask = createTask(mDisplayContent);
         final ActivityRecord closing = createActivityRecord(closeTask);
         closing.mVisibleRequested = true; // starts visible
 
@@ -268,8 +260,8 @@
         final Task[] tasks = new Task[taskCount];
         for (int i = 0; i < taskCount; ++i) {
             // Each add goes on top, so at the end of this, task[9] should be on top
-            tasks[i] = createTaskStackOnDisplay(WINDOWING_MODE_FREEFORM,
-                    ACTIVITY_TYPE_STANDARD, mDisplayContent);
+            tasks[i] = createTask(mDisplayContent,
+                    WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD);
             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
@@ -305,8 +297,8 @@
         final Task[] tasks = new Task[taskCount];
         for (int i = 0; i < taskCount; ++i) {
             // Each add goes on top, so at the end of this, task[9] should be on top
-            tasks[i] = createTaskStackOnDisplay(WINDOWING_MODE_FULLSCREEN,
-                    ACTIVITY_TYPE_STANDARD, mDisplayContent);
+            tasks[i] = createTask(mDisplayContent,
+                    WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
             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
@@ -353,15 +345,13 @@
         ArraySet<WindowContainer> participants = transition.mParticipants;
         ITaskOrganizer mockOrg = mock(ITaskOrganizer.class);
 
-        final Task openTask = createTaskStackOnDisplay(WINDOWING_MODE_FULLSCREEN,
-                ACTIVITY_TYPE_STANDARD, mDisplayContent);
-        final Task openInOpenTask = createTaskInStack(openTask, 0);
+        final Task openTask = createTask(mDisplayContent);
+        final Task openInOpenTask = createTaskInRootTask(openTask, 0);
         final ActivityRecord openInOpen = createActivityRecord(openInOpenTask);
 
-        final Task changeTask = createTaskStackOnDisplay(WINDOWING_MODE_FULLSCREEN,
-                ACTIVITY_TYPE_STANDARD, mDisplayContent);
-        final Task changeInChangeTask = createTaskInStack(changeTask, 0);
-        final Task openInChangeTask = createTaskInStack(changeTask, 0);
+        final Task changeTask = createTask(mDisplayContent);
+        final Task changeInChangeTask = createTaskInRootTask(changeTask, 0);
+        final Task openInChangeTask = createTaskInRootTask(changeTask, 0);
         final ActivityRecord changeInChange = createActivityRecord(changeInChangeTask);
         final ActivityRecord openInChange = createActivityRecord(openInChangeTask);
         // set organizer for everything so that they all get added to transition info
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 b88173d..6919c4c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
@@ -811,18 +811,18 @@
 
     @Test
     public void testOnDisplayChanged() {
-        final Task stack = createTaskStackOnDisplay(mDisplayContent);
-        final Task task = createTaskInStack(stack, 0 /* userId */);
+        final Task rootTask = createTask(mDisplayContent);
+        final Task task = createTaskInRootTask(rootTask, 0 /* userId */);
         final ActivityRecord activity = createActivityRecord(mDisplayContent, task);
 
         final DisplayContent newDc = createNewDisplay();
-        stack.getDisplayArea().removeRootTask(stack);
-        newDc.getDefaultTaskDisplayArea().addChild(stack, POSITION_TOP);
+        rootTask.getDisplayArea().removeRootTask(rootTask);
+        newDc.getDefaultTaskDisplayArea().addChild(rootTask, POSITION_TOP);
 
-        verify(stack).onDisplayChanged(newDc);
+        verify(rootTask).onDisplayChanged(newDc);
         verify(task).onDisplayChanged(newDc);
         verify(activity).onDisplayChanged(newDc);
-        assertEquals(newDc, stack.mDisplayContent);
+        assertEquals(newDc, rootTask.mDisplayContent);
         assertEquals(newDc, task.mDisplayContent);
         assertEquals(newDc, activity.mDisplayContent);
     }
@@ -854,21 +854,21 @@
 
     @Test
     public void testTaskCanApplyAnimation() {
-        final Task stack = createTaskStackOnDisplay(mDisplayContent);
-        final Task task = createTaskInStack(stack, 0 /* userId */);
+        final Task rootTask = createTask(mDisplayContent);
+        final Task task = createTaskInRootTask(rootTask, 0 /* userId */);
         final ActivityRecord activity2 = createActivityRecord(mDisplayContent, task);
         final ActivityRecord activity1 = createActivityRecord(mDisplayContent, task);
         verifyWindowContainerApplyAnimation(task, activity1, activity2);
     }
 
     @Test
-    public void testStackCanApplyAnimation() {
-        final Task stack = createTaskStackOnDisplay(mDisplayContent);
+    public void testRootTaskCanApplyAnimation() {
+        final Task rootTask = createTask(mDisplayContent);
         final ActivityRecord activity2 = createActivityRecord(mDisplayContent,
-                createTaskInStack(stack, 0 /* userId */));
+                createTaskInRootTask(rootTask, 0 /* userId */));
         final ActivityRecord activity1 = createActivityRecord(mDisplayContent,
-                createTaskInStack(stack, 0 /* userId */));
-        verifyWindowContainerApplyAnimation(stack, activity1, activity2);
+                createTaskInRootTask(rootTask, 0 /* userId */));
+        verifyWindowContainerApplyAnimation(rootTask, activity1, activity2);
     }
 
     @Test
@@ -878,21 +878,21 @@
 
         assertNull(windowContainer.getDisplayArea());
 
-        // ActivityStack > WindowContainer
-        final Task activityStack = createTaskStackOnDisplay(mDisplayContent);
-        activityStack.addChild(windowContainer, 0);
-        activityStack.setParent(null);
+        // Task > WindowContainer
+        final Task task = createTask(mDisplayContent);
+        task.addChild(windowContainer, 0);
+        task.setParent(null);
 
         assertNull(windowContainer.getDisplayArea());
-        assertNull(activityStack.getDisplayArea());
+        assertNull(task.getDisplayArea());
 
-        // TaskDisplayArea > ActivityStack > WindowContainer
+        // TaskDisplayArea > Task > WindowContainer
         final TaskDisplayArea taskDisplayArea = new TaskDisplayArea(
                 mDisplayContent, mWm, "TaskDisplayArea", FEATURE_DEFAULT_TASK_CONTAINER);
-        taskDisplayArea.addChild(activityStack, 0);
+        taskDisplayArea.addChild(task, 0);
 
         assertEquals(taskDisplayArea, windowContainer.getDisplayArea());
-        assertEquals(taskDisplayArea, activityStack.getDisplayArea());
+        assertEquals(taskDisplayArea, task.getDisplayArea());
         assertEquals(taskDisplayArea, taskDisplayArea.getDisplayArea());
 
         // DisplayArea
@@ -986,8 +986,8 @@
 
     @Test
     public void testFreezeInsets() {
-        final Task stack = createTaskStackOnDisplay(mDisplayContent);
-        final ActivityRecord activity = createActivityRecord(mDisplayContent, stack);
+        final Task task = createTask(mDisplayContent);
+        final ActivityRecord activity = createActivityRecord(mDisplayContent, task);
         final WindowState win = createWindow(null, TYPE_BASE_APPLICATION, activity, "win");
 
         // Set visibility to false, verify the main window of the task will be set the frozen
@@ -1002,8 +1002,8 @@
 
     @Test
     public void testFreezeInsetsStateWhenAppTransition() {
-        final Task stack = createTaskStackOnDisplay(mDisplayContent);
-        final Task task = createTaskInStack(stack, 0 /* userId */);
+        final Task rootTask = createTask(mDisplayContent);
+        final Task task = createTaskInRootTask(rootTask, 0 /* userId */);
         final ActivityRecord activity = createActivityRecord(mDisplayContent, task);
         final WindowState win = createWindow(null, TYPE_BASE_APPLICATION, activity, "win");
         task.getDisplayContent().prepareAppTransition(TRANSIT_CLOSE);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
index 6d0e510..baf072d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
@@ -80,18 +80,18 @@
     }
 
     @Test
-    public void testTaskFocusChange_stackNotHomeType_focusChanges() throws RemoteException {
+    public void testTaskFocusChange_rootTaskNotHomeType_focusChanges() throws RemoteException {
         DisplayContent display = createNewDisplay();
         // Current focused window
-        Task focusedStack = createTaskStackOnDisplay(
-                WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD, display);
-        Task focusedTask = createTaskInStack(focusedStack, 0 /* userId */);
+        Task focusedRootTask = createTask(
+                display, WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD);
+        Task focusedTask = createTaskInRootTask(focusedRootTask, 0 /* userId */);
         WindowState focusedWindow = createAppWindow(focusedTask, TYPE_APPLICATION, "App Window");
         mDisplayContent.mCurrentFocus = focusedWindow;
         // Tapped task
-        Task tappedStack = createTaskStackOnDisplay(
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, display);
-        Task tappedTask = createTaskInStack(tappedStack, 0 /* userId */);
+        Task tappedRootTask = createTask(
+                display, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+        Task tappedTask = createTaskInRootTask(tappedRootTask, 0 /* userId */);
         spyOn(mWm.mAtmService);
 
         mWm.handleTaskFocusChange(tappedTask);
@@ -100,19 +100,19 @@
     }
 
     @Test
-    public void testTaskFocusChange_stackHomeTypeWithSameTaskDisplayArea_focusDoesNotChange()
+    public void testTaskFocusChange_rootTaskHomeTypeWithSameTaskDisplayArea_focusDoesNotChange()
             throws RemoteException {
         DisplayContent display = createNewDisplay();
         // Current focused window
-        Task focusedStack = createTaskStackOnDisplay(
-                WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD, display);
-        Task focusedTask = createTaskInStack(focusedStack, 0 /* userId */);
+        Task focusedRootTask = createTask(
+                display, WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD);
+        Task focusedTask = createTaskInRootTask(focusedRootTask, 0 /* userId */);
         WindowState focusedWindow = createAppWindow(focusedTask, TYPE_APPLICATION, "App Window");
         mDisplayContent.mCurrentFocus = focusedWindow;
         // Tapped home task
-        Task tappedStack = createTaskStackOnDisplay(
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, display);
-        Task tappedTask = createTaskInStack(tappedStack, 0 /* userId */);
+        Task tappedRootTask = createTask(
+                display, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME);
+        Task tappedTask = createTaskInRootTask(tappedRootTask, 0 /* userId */);
         spyOn(mWm.mAtmService);
 
         mWm.handleTaskFocusChange(tappedTask);
@@ -121,21 +121,21 @@
     }
 
     @Test
-    public void testTaskFocusChange_stackHomeTypeWithDifferentTaskDisplayArea_focusChanges()
+    public void testTaskFocusChange_rootTaskHomeTypeWithDifferentTaskDisplayArea_focusChanges()
             throws RemoteException {
         final DisplayContent display = createNewDisplay();
         final TaskDisplayArea secondTda = createTaskDisplayArea(
                 display, mWm, "Tapped TDA", FEATURE_VENDOR_FIRST);
         // Current focused window
-        Task focusedStack = createTaskStackOnDisplay(
-                WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD, display);
-        Task focusedTask = createTaskInStack(focusedStack, 0 /* userId */);
+        Task focusedRootTask = createTask(
+                display, WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD);
+        Task focusedTask = createTaskInRootTask(focusedRootTask, 0 /* userId */);
         WindowState focusedWindow = createAppWindow(focusedTask, TYPE_APPLICATION, "App Window");
         mDisplayContent.mCurrentFocus = focusedWindow;
         // Tapped home task on another task display area
-        Task tappedStack = createTaskStackOnTaskDisplayArea(
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, secondTda);
-        Task tappedTask = createTaskInStack(tappedStack, 0 /* userId */);
+        Task tappedRootTask = createTask(secondTda, WINDOWING_MODE_FULLSCREEN,
+                ACTIVITY_TYPE_STANDARD);
+        Task tappedTask = createTaskInRootTask(tappedRootTask, 0 /* userId */);
         spyOn(mWm.mAtmService);
 
         mWm.handleTaskFocusChange(tappedTask);
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 01c503e..e2b58bc 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
@@ -125,8 +125,8 @@
         return registerMockOrganizer(null);
     }
 
-    Task createTask(Task stack, boolean fakeDraw) {
-        final Task task = createTaskInStack(stack, 0);
+    Task createTask(Task rootTask, boolean fakeDraw) {
+        final Task task = createTaskInRootTask(rootTask, 0);
 
         if (fakeDraw) {
             task.setHasBeenVisible(true);
@@ -134,13 +134,13 @@
         return task;
     }
 
-    Task createTask(Task stack) {
+    Task createTask(Task rootTask) {
         // Fake draw notifications for most of our tests.
-        return createTask(stack, true);
+        return createTask(rootTask, true);
     }
 
-    Task createStack() {
-        return createTaskStackOnDisplay(mDisplayContent);
+    Task createRootTask() {
+        return createTask(mDisplayContent);
     }
 
     @Before
@@ -153,14 +153,14 @@
     @Test
     public void testAppearVanish() throws RemoteException {
         final ITaskOrganizer organizer = registerMockOrganizer();
-        final Task stack = createStack();
-        final Task task = createTask(stack);
+        final Task rootTask = createRootTask();
+        final Task task = createTask(rootTask);
         // Ensure events dispatch to organizer.
         mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
 
         verify(organizer).onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class));
 
-        stack.removeImmediately();
+        rootTask.removeImmediately();
         // Ensure events dispatch to organizer.
         mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
         verify(organizer).onTaskVanished(any());
@@ -169,21 +169,21 @@
     @Test
     public void testAppearWaitsForVisibility() throws RemoteException {
         final ITaskOrganizer organizer = registerMockOrganizer();
-        final Task stack = createStack();
-        final Task task = createTask(stack, false);
+        final Task rootTask = createRootTask();
+        final Task task = createTask(rootTask, false);
         // Ensure events dispatch to organizer.
         mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
 
         verify(organizer, never())
                 .onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class));
-        stack.setHasBeenVisible(true);
+        rootTask.setHasBeenVisible(true);
         // Ensure events dispatch to organizer.
         mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
-        assertTrue(stack.getHasBeenVisible());
+        assertTrue(rootTask.getHasBeenVisible());
 
         verify(organizer).onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class));
 
-        stack.removeImmediately();
+        rootTask.removeImmediately();
         // Ensure events dispatch to organizer.
         mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
         verify(organizer).onTaskVanished(any());
@@ -192,108 +192,108 @@
     @Test
     public void testNoVanishedIfNoAppear() throws RemoteException {
         final ITaskOrganizer organizer = registerMockOrganizer();
-        final Task stack = createStack();
-        final Task task = createTask(stack, false /* hasBeenVisible */);
+        final Task rootTask = createRootTask();
+        final Task task = createTask(rootTask, false /* hasBeenVisible */);
 
         // In this test we skip making the Task visible, and verify
         // that even though a TaskOrganizer is set remove doesn't emit
         // a vanish callback, because we never emitted appear.
-        stack.setTaskOrganizer(organizer);
+        rootTask.setTaskOrganizer(organizer);
         verify(organizer, never())
                 .onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class));
-        stack.removeImmediately();
+        rootTask.removeImmediately();
         verify(organizer, never()).onTaskVanished(any());
     }
 
     @Test
     public void testTaskNoDraw() throws RemoteException {
         final ITaskOrganizer organizer = registerMockOrganizer();
-        final Task stack = createStack();
-        final Task task = createTask(stack, false /* fakeDraw */);
+        final Task rootTask = createRootTask();
+        final Task task = createTask(rootTask, false /* fakeDraw */);
         // Ensure events dispatch to organizer.
         mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
 
         verify(organizer, never())
                 .onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class));
-        assertTrue(stack.isOrganized());
+        assertTrue(rootTask.isOrganized());
 
         mWm.mAtmService.mTaskOrganizerController.unregisterTaskOrganizer(organizer);
         // Ensure events dispatch to organizer.
         mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
-        assertTaskVanished(organizer, false /* expectVanished */, stack);
-        assertFalse(stack.isOrganized());
+        assertTaskVanished(organizer, false /* expectVanished */, rootTask);
+        assertFalse(rootTask.isOrganized());
     }
 
     @Test
     public void testClearOrganizer() throws RemoteException {
         final ITaskOrganizer organizer = registerMockOrganizer();
-        final Task stack = createStack();
-        final Task task = createTask(stack);
+        final Task rootTask = createRootTask();
+        final Task task = createTask(rootTask);
         // Ensure events dispatch to organizer.
         mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
 
         verify(organizer).onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class));
-        assertTrue(stack.isOrganized());
+        assertTrue(rootTask.isOrganized());
 
-        stack.setTaskOrganizer(null);
+        rootTask.setTaskOrganizer(null);
         // Ensure events dispatch to organizer.
         mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
 
         verify(organizer).onTaskVanished(any());
-        assertFalse(stack.isOrganized());
+        assertFalse(rootTask.isOrganized());
     }
 
     @Test
     public void testUnregisterOrganizer() throws RemoteException {
         final ITaskOrganizer organizer = registerMockOrganizer();
-        final Task stack = createStack();
-        final Task task = createTask(stack);
+        final Task rootTask = createRootTask();
+        final Task task = createTask(rootTask);
         // Ensure events dispatch to organizer.
         mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
 
         verify(organizer).onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class));
-        assertTrue(stack.isOrganized());
+        assertTrue(rootTask.isOrganized());
 
         mWm.mAtmService.mTaskOrganizerController.unregisterTaskOrganizer(organizer);
         // Ensure events dispatch to organizer.
         mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
 
-        assertTaskVanished(organizer, true /* expectVanished */, stack);
-        assertFalse(stack.isOrganized());
+        assertTaskVanished(organizer, true /* expectVanished */, rootTask);
+        assertFalse(rootTask.isOrganized());
     }
 
     @Test
     public void testUnregisterOrganizerReturnsRegistrationToPrevious() throws RemoteException {
-        final Task stack = createStack();
-        final Task task = createTask(stack);
-        final Task stack2 = createStack();
-        final Task task2 = createTask(stack2);
-        final Task stack3 = createStack();
-        final Task task3 = createTask(stack3);
+        final Task rootTask = createRootTask();
+        final Task task = createTask(rootTask);
+        final Task rootTask2 = createRootTask();
+        final Task task2 = createTask(rootTask2);
+        final Task rootTask3 = createRootTask();
+        final Task task3 = createTask(rootTask3);
         final ArrayList<TaskAppearedInfo> existingTasks = new ArrayList<>();
         final ITaskOrganizer organizer = registerMockOrganizer(existingTasks);
         // Ensure events dispatch to organizer.
         mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
 
         // verify that tasks are returned and taskAppeared is not called
-        assertContainsTasks(existingTasks, stack, stack2, stack3);
+        assertContainsTasks(existingTasks, rootTask, rootTask2, rootTask3);
         verify(organizer, times(0)).onTaskAppeared(any(RunningTaskInfo.class),
                 any(SurfaceControl.class));
         verify(organizer, times(0)).onTaskVanished(any());
-        assertTrue(stack.isOrganized());
+        assertTrue(rootTask.isOrganized());
 
         // Now we replace the registration and verify the new organizer receives existing tasks
         final ArrayList<TaskAppearedInfo> existingTasks2 = new ArrayList<>();
         final ITaskOrganizer organizer2 = registerMockOrganizer(existingTasks2);
         // Ensure events dispatch to organizer.
         mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
-        assertContainsTasks(existingTasks2, stack, stack2, stack3);
+        assertContainsTasks(existingTasks2, rootTask, rootTask2, rootTask3);
         verify(organizer2, times(0)).onTaskAppeared(any(RunningTaskInfo.class),
                 any(SurfaceControl.class));
         verify(organizer2, times(0)).onTaskVanished(any());
         // Removed tasks from the original organizer
-        assertTaskVanished(organizer, true /* expectVanished */, stack, stack2, stack3);
-        assertTrue(stack2.isOrganized());
+        assertTaskVanished(organizer, true /* expectVanished */, rootTask, rootTask2, rootTask3);
+        assertTrue(rootTask2.isOrganized());
 
         // Now we unregister the second one, the first one should automatically be reregistered
         // so we verify that it's now seeing changes.
@@ -302,18 +302,18 @@
         mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
         verify(organizer, times(3))
                 .onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class));
-        assertTaskVanished(organizer2, true /* expectVanished */, stack, stack2, stack3);
+        assertTaskVanished(organizer2, true /* expectVanished */, rootTask, rootTask2, rootTask3);
     }
 
     @Test
     public void testRegisterTaskOrganizerWithExistingTasks() throws RemoteException {
-        final Task stack = createStack();
-        final Task task = createTask(stack);
-        final Task stack2 = createStack();
-        final Task task2 = createTask(stack2);
+        final Task rootTask = createRootTask();
+        final Task task = createTask(rootTask);
+        final Task rootTask2 = createRootTask();
+        final Task task2 = createTask(rootTask2);
         ArrayList<TaskAppearedInfo> existingTasks = new ArrayList<>();
         final ITaskOrganizer organizer = registerMockOrganizer(existingTasks);
-        assertContainsTasks(existingTasks, stack, stack2);
+        assertContainsTasks(existingTasks, rootTask, rootTask2);
 
         // Verify we don't get onTaskAppeared if we are returned the tasks
         verify(organizer, never())
@@ -323,21 +323,21 @@
     @Test
     public void testTaskTransaction() {
         removeGlobalMinSizeRestriction();
-        final Task stack = new TaskBuilder(mSupervisor)
+        final Task rootTask = new TaskBuilder(mSupervisor)
                 .setWindowingMode(WINDOWING_MODE_FREEFORM).build();
-        final Task task = stack.getTopMostTask();
+        final Task task = rootTask.getTopMostTask();
         testTransaction(task);
     }
 
     @Test
-    public void testStackTransaction() {
+    public void testRootTaskTransaction() {
         removeGlobalMinSizeRestriction();
-        final Task stack = new TaskBuilder(mSupervisor)
+        final Task rootTask = new TaskBuilder(mSupervisor)
                 .setWindowingMode(WINDOWING_MODE_FREEFORM).build();
         RootTaskInfo info =
                 mWm.mAtmService.getRootTaskInfo(WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD);
-        assertEquals(stack.mRemoteToken.toWindowContainerToken(), info.token);
-        testTransaction(stack);
+        assertEquals(rootTask.mRemoteToken.toWindowContainerToken(), info.token);
+        testTransaction(rootTask);
     }
 
     @Test
@@ -357,9 +357,9 @@
 
     @Test
     public void testSetWindowingMode() {
-        final Task stack = new TaskBuilder(mSupervisor)
+        final Task rootTask = new TaskBuilder(mSupervisor)
                 .setWindowingMode(WINDOWING_MODE_FREEFORM).build();
-        testSetWindowingMode(stack);
+        testSetWindowingMode(rootTask);
 
         final DisplayArea displayArea = new DisplayArea<>(mWm, ABOVE_TASKS, "DisplayArea");
         displayArea.setWindowingMode(WINDOWING_MODE_FREEFORM);
@@ -376,30 +376,30 @@
     @Test
     public void testSetActivityWindowingMode() {
         final ActivityRecord record = makePipableActivity();
-        final Task stack = record.getRootTask();
+        final Task rootTask = record.getRootTask();
         final WindowContainerTransaction t = new WindowContainerTransaction();
 
-        t.setWindowingMode(stack.mRemoteToken.toWindowContainerToken(), WINDOWING_MODE_PINNED);
+        t.setWindowingMode(rootTask.mRemoteToken.toWindowContainerToken(), WINDOWING_MODE_PINNED);
         t.setActivityWindowingMode(
-                stack.mRemoteToken.toWindowContainerToken(), WINDOWING_MODE_FULLSCREEN);
+                rootTask.mRemoteToken.toWindowContainerToken(), WINDOWING_MODE_FULLSCREEN);
         mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
 
         assertEquals(WINDOWING_MODE_FULLSCREEN, record.getWindowingMode());
-        assertEquals(WINDOWING_MODE_PINNED, stack.getWindowingMode());
+        assertEquals(WINDOWING_MODE_PINNED, rootTask.getWindowingMode());
     }
 
     @Test
     public void testContainerFocusableChanges() {
         removeGlobalMinSizeRestriction();
-        final Task stack = new TaskBuilder(mSupervisor)
+        final Task rootTask = new TaskBuilder(mSupervisor)
                 .setWindowingMode(WINDOWING_MODE_FREEFORM).build();
-        final Task task = stack.getTopMostTask();
+        final Task task = rootTask.getTopMostTask();
         WindowContainerTransaction t = new WindowContainerTransaction();
         assertTrue(task.isFocusable());
-        t.setFocusable(stack.mRemoteToken.toWindowContainerToken(), false);
+        t.setFocusable(rootTask.mRemoteToken.toWindowContainerToken(), false);
         mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
         assertFalse(task.isFocusable());
-        t.setFocusable(stack.mRemoteToken.toWindowContainerToken(), true);
+        t.setFocusable(rootTask.mRemoteToken.toWindowContainerToken(), true);
         mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
         assertTrue(task.isFocusable());
     }
@@ -407,25 +407,25 @@
     @Test
     public void testContainerHiddenChanges() {
         removeGlobalMinSizeRestriction();
-        final Task stack = new TaskBuilder(mSupervisor).setCreateActivity(true)
+        final Task rootTask = new TaskBuilder(mSupervisor).setCreateActivity(true)
                 .setWindowingMode(WINDOWING_MODE_FREEFORM).build();
         WindowContainerTransaction t = new WindowContainerTransaction();
-        assertTrue(stack.shouldBeVisible(null));
-        t.setHidden(stack.mRemoteToken.toWindowContainerToken(), true);
+        assertTrue(rootTask.shouldBeVisible(null));
+        t.setHidden(rootTask.mRemoteToken.toWindowContainerToken(), true);
         mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
-        assertFalse(stack.shouldBeVisible(null));
-        t.setHidden(stack.mRemoteToken.toWindowContainerToken(), false);
+        assertFalse(rootTask.shouldBeVisible(null));
+        t.setHidden(rootTask.mRemoteToken.toWindowContainerToken(), false);
         mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
-        assertTrue(stack.shouldBeVisible(null));
+        assertTrue(rootTask.shouldBeVisible(null));
     }
 
     @Test
     public void testSetIgnoreOrientationRequest_taskDisplayArea() {
         removeGlobalMinSizeRestriction();
         final TaskDisplayArea taskDisplayArea = mDisplayContent.getDefaultTaskDisplayArea();
-        final Task stack = taskDisplayArea.createRootTask(
+        final Task rootTask = taskDisplayArea.createRootTask(
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
-        final ActivityRecord activity = new ActivityBuilder(mAtm).setTask(stack).build();
+        final ActivityRecord activity = new ActivityBuilder(mAtm).setTask(rootTask).build();
         taskDisplayArea.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
         mDisplayContent.setFocusedApp(activity);
         activity.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE);
@@ -461,9 +461,9 @@
     public void testSetIgnoreOrientationRequest_displayContent() {
         removeGlobalMinSizeRestriction();
         final TaskDisplayArea taskDisplayArea = mDisplayContent.getDefaultTaskDisplayArea();
-        final Task stack = taskDisplayArea.createRootTask(
+        final Task rootTask = taskDisplayArea.createRootTask(
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
-        final ActivityRecord activity = new ActivityBuilder(mAtm).setTask(stack).build();
+        final ActivityRecord activity = new ActivityBuilder(mAtm).setTask(rootTask).build();
         mDisplayContent.setFocusedApp(activity);
         activity.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE);
 
@@ -491,21 +491,21 @@
     @Test
     public void testOverrideConfigSize() {
         removeGlobalMinSizeRestriction();
-        final Task stack = new TaskBuilder(mSupervisor)
+        final Task rootTask = new TaskBuilder(mSupervisor)
                 .setWindowingMode(WINDOWING_MODE_FREEFORM).build();
-        final Task task = stack.getTopMostTask();
+        final Task task = rootTask.getTopMostTask();
         WindowContainerTransaction t = new WindowContainerTransaction();
         mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
         final int origScreenWDp = task.getConfiguration().screenHeightDp;
         final int origScreenHDp = task.getConfiguration().screenHeightDp;
         t = new WindowContainerTransaction();
         // verify that setting config overrides on parent restricts children.
-        t.setScreenSizeDp(stack.mRemoteToken
+        t.setScreenSizeDp(rootTask.mRemoteToken
                 .toWindowContainerToken(), origScreenWDp, origScreenHDp / 2);
         mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
         assertEquals(origScreenHDp / 2, task.getConfiguration().screenHeightDp);
         t = new WindowContainerTransaction();
-        t.setScreenSizeDp(stack.mRemoteToken.toWindowContainerToken(), SCREEN_WIDTH_DP_UNDEFINED,
+        t.setScreenSizeDp(rootTask.mRemoteToken.toWindowContainerToken(), SCREEN_WIDTH_DP_UNDEFINED,
                 SCREEN_HEIGHT_DP_UNDEFINED);
         mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
         assertEquals(origScreenHDp, task.getConfiguration().screenHeightDp);
@@ -572,14 +572,14 @@
                 mDisplayContent, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, null);
         RunningTaskInfo info1 = task.getTaskInfo();
 
-        final Task stack = createTaskStackOnDisplay(
-                WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, mDisplayContent);
-        assertEquals(mDisplayContent.getWindowingMode(), stack.getWindowingMode());
+        final Task rootTask = createTask(
+                mDisplayContent, WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD);
+        assertEquals(mDisplayContent.getWindowingMode(), rootTask.getWindowingMode());
         WindowContainerTransaction wct = new WindowContainerTransaction();
-        wct.reparent(stack.mRemoteToken.toWindowContainerToken(), info1.token, true /* onTop */);
+        wct.reparent(rootTask.mRemoteToken.toWindowContainerToken(), info1.token, true /* onTop */);
         mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
         assertEquals(info1.configuration.windowConfiguration.getWindowingMode(),
-                stack.getWindowingMode());
+                rootTask.getWindowingMode());
 
         // Info should reflect new membership
         List<Task> infos = getTasksCreatedByOrganizer(mDisplayContent);
@@ -591,14 +591,14 @@
         Task task1 = WindowContainer.fromBinder(info1.token.asBinder()).asTask();
         Configuration c = new Configuration(task1.getRequestedOverrideConfiguration());
         c.windowConfiguration.setBounds(newSize);
-        doNothing().when(stack).adjustForMinimalTaskDimensions(any(), any(), any());
+        doNothing().when(rootTask).adjustForMinimalTaskDimensions(any(), any(), any());
         task1.onRequestedOverrideConfigurationChanged(c);
-        assertEquals(newSize, stack.getBounds());
+        assertEquals(newSize, rootTask.getBounds());
 
         wct = new WindowContainerTransaction();
-        wct.reparent(stack.mRemoteToken.toWindowContainerToken(), null, true /* onTop */);
+        wct.reparent(rootTask.mRemoteToken.toWindowContainerToken(), null, true /* onTop */);
         mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
-        assertEquals(mDisplayContent.getWindowingMode(), stack.getWindowingMode());
+        assertEquals(mDisplayContent.getWindowingMode(), rootTask.getWindowingMode());
         infos = getTasksCreatedByOrganizer(mDisplayContent);
         info1 = infos.get(0).getTaskInfo();
         assertEquals(ACTIVITY_TYPE_UNDEFINED, info1.topActivityType);
@@ -644,36 +644,39 @@
         lastReportedTiles.clear();
         called[0] = false;
 
-        final Task stack = createTaskStackOnDisplay(
-                WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, mDisplayContent);
+        final Task rootTask = createTask(
+                mDisplayContent, WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD);
         Task task1 = WindowContainer.fromBinder(info1.token.asBinder()).asTask();
         WindowContainerTransaction wct = new WindowContainerTransaction();
-        wct.reparent(stack.mRemoteToken.toWindowContainerToken(), info1.token, true /* onTop */);
+        wct.reparent(rootTask.mRemoteToken.toWindowContainerToken(), info1.token, true /* onTop */);
         mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
         assertTrue(called[0]);
         assertEquals(ACTIVITY_TYPE_STANDARD, lastReportedTiles.get(0).topActivityType);
 
         lastReportedTiles.clear();
         called[0] = false;
-        final Task stack2 = createTaskStackOnDisplay(
-                WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_HOME, mDisplayContent);
+        final Task rootTask2 = createTask(
+                mDisplayContent, WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_HOME);
         wct = new WindowContainerTransaction();
-        wct.reparent(stack2.mRemoteToken.toWindowContainerToken(), info1.token, true /* onTop */);
+        wct.reparent(rootTask2.mRemoteToken.toWindowContainerToken(),
+                info1.token, true /* onTop */);
         mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
         assertTrue(called[0]);
         assertEquals(ACTIVITY_TYPE_HOME, lastReportedTiles.get(0).topActivityType);
 
         lastReportedTiles.clear();
         called[0] = false;
-        task1.positionChildAt(POSITION_TOP, stack, false /* includingParents */);
+        task1.positionChildAt(POSITION_TOP, rootTask, false /* includingParents */);
         assertTrue(called[0]);
         assertEquals(ACTIVITY_TYPE_STANDARD, lastReportedTiles.get(0).topActivityType);
 
         lastReportedTiles.clear();
         called[0] = false;
         wct = new WindowContainerTransaction();
-        wct.reparent(stack.mRemoteToken.toWindowContainerToken(), null, true /* onTop */);
-        wct.reparent(stack2.mRemoteToken.toWindowContainerToken(), null, true /* onTop */);
+        wct.reparent(rootTask.mRemoteToken.toWindowContainerToken(),
+                null, true /* onTop */);
+        wct.reparent(rootTask2.mRemoteToken.toWindowContainerToken(),
+                null, true /* onTop */);
         mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
         assertTrue(called[0]);
         assertEquals(ACTIVITY_TYPE_UNDEFINED, lastReportedTiles.get(0).topActivityType);
@@ -723,10 +726,10 @@
         final int initialRootTaskCount = mWm.mAtmService.mTaskOrganizerController.getRootTasks(
                 mDisplayContent.mDisplayId, null /* activityTypes */).size();
 
-        final Task stack = createTaskStackOnDisplay(
-                WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, mDisplayContent);
-        final Task stack2 = createTaskStackOnDisplay(
-                WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_HOME, mDisplayContent);
+        final Task rootTask = createTask(
+                mDisplayContent, WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD);
+        final Task rootTask2 = createTask(
+                mDisplayContent, WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_HOME);
 
         // Check getRootTasks works
         List<RunningTaskInfo> roots = mWm.mAtmService.mTaskOrganizerController.getRootTasks(
@@ -735,8 +738,10 @@
 
         lastReportedTiles.clear();
         WindowContainerTransaction wct = new WindowContainerTransaction();
-        wct.reparent(stack.mRemoteToken.toWindowContainerToken(), info1.token, true /* onTop */);
-        wct.reparent(stack2.mRemoteToken.toWindowContainerToken(), info2.token, true /* onTop */);
+        wct.reparent(rootTask.mRemoteToken.toWindowContainerToken(),
+                info1.token, true /* onTop */);
+        wct.reparent(rootTask2.mRemoteToken.toWindowContainerToken(),
+                info2.token, true /* onTop */);
         mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
         assertFalse(lastReportedTiles.isEmpty());
         assertEquals(ACTIVITY_TYPE_STANDARD,
@@ -746,7 +751,8 @@
 
         lastReportedTiles.clear();
         wct = new WindowContainerTransaction();
-        wct.reparent(stack2.mRemoteToken.toWindowContainerToken(), info1.token, false /* onTop */);
+        wct.reparent(rootTask2.mRemoteToken.toWindowContainerToken(),
+                info1.token, false /* onTop */);
         mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
         assertFalse(lastReportedTiles.isEmpty());
         // Standard should still be on top of tile 1, so no change there
@@ -771,7 +777,7 @@
 
         lastReportedTiles.clear();
         wct = new WindowContainerTransaction();
-        wct.reorder(stack2.mRemoteToken.toWindowContainerToken(), true /* onTop */);
+        wct.reorder(rootTask2.mRemoteToken.toWindowContainerToken(), true /* onTop */);
         mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
         // Home should now be on top. No change occurs in second tile, so not reported
         assertEquals(1, lastReportedTiles.size());
@@ -780,10 +786,10 @@
 
         // This just needs to not crash (ie. it should be possible to reparent to display twice)
         wct = new WindowContainerTransaction();
-        wct.reparent(stack2.mRemoteToken.toWindowContainerToken(), null, true /* onTop */);
+        wct.reparent(rootTask2.mRemoteToken.toWindowContainerToken(), null, true /* onTop */);
         mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
         wct = new WindowContainerTransaction();
-        wct.reparent(stack2.mRemoteToken.toWindowContainerToken(), null, true /* onTop */);
+        wct.reparent(rootTask2.mRemoteToken.toWindowContainerToken(), null, true /* onTop */);
         mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
     }
 
@@ -799,8 +805,8 @@
 
     @Test
     public void testBLASTCallbackWithActivityChildren() {
-        final Task stackController1 = createStack();
-        final Task task = createTask(stackController1);
+        final Task rootTaskController1 = createRootTask();
+        final Task task = createTask(rootTaskController1);
         final WindowState w = createAppWindow(task, TYPE_APPLICATION, "Enlightened Window");
 
         w.mActivityRecord.mVisibleRequested = true;
@@ -926,11 +932,11 @@
         ChangeSavingOrganizer o = new ChangeSavingOrganizer();
         mWm.mAtmService.mTaskOrganizerController.registerTaskOrganizer(o);
 
-        final Task stack = createStack();
-        final Task task = createTask(stack);
-        final ActivityRecord record = createActivityRecord(stack.mDisplayContent, task);
+        final Task rootTask = createRootTask();
+        final Task task = createTask(rootTask);
+        final ActivityRecord record = createActivityRecord(rootTask.mDisplayContent, task);
 
-        stack.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
+        rootTask.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
         record.setTaskDescription(new ActivityManager.TaskDescription("TestDescription"));
         waitUntilHandlersIdle();
         assertEquals("TestDescription", o.mChangedInfo.taskDescription.getLabel());
@@ -939,29 +945,29 @@
     @Test
     public void testPreventDuplicateAppear() throws RemoteException {
         final ITaskOrganizer organizer = registerMockOrganizer();
-        final Task stack = createStack();
-        final Task task = createTask(stack, false /* fakeDraw */);
+        final Task rootTask = createRootTask();
+        final Task task = createTask(rootTask, false /* fakeDraw */);
 
-        stack.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
-        stack.setTaskOrganizer(organizer);
+        rootTask.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
+        rootTask.setTaskOrganizer(organizer);
         // setHasBeenVisible was already called once by the set-up code.
-        stack.setHasBeenVisible(true);
+        rootTask.setHasBeenVisible(true);
         // Ensure events dispatch to organizer.
         mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
         verify(organizer, times(1))
                 .onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class));
 
-        stack.setTaskOrganizer(null);
+        rootTask.setTaskOrganizer(null);
         // Ensure events dispatch to organizer.
         mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
         verify(organizer, times(1)).onTaskVanished(any());
-        stack.setTaskOrganizer(organizer);
+        rootTask.setTaskOrganizer(organizer);
         // Ensure events dispatch to organizer.
         mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
         verify(organizer, times(2))
                 .onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class));
 
-        stack.removeImmediately();
+        rootTask.removeImmediately();
         // Ensure events dispatch to organizer.
         mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
         verify(organizer, times(2)).onTaskVanished(any());
@@ -970,15 +976,15 @@
     @Test
     public void testInterceptBackPressedOnTaskRoot() throws RemoteException {
         final ITaskOrganizer organizer = registerMockOrganizer();
-        final Task stack = createStack();
-        final Task task = createTask(stack);
-        final ActivityRecord activity = createActivityRecord(stack.mDisplayContent, task);
-        final Task stack2 = createStack();
-        final Task task2 = createTask(stack2);
-        final ActivityRecord activity2 = createActivityRecord(stack.mDisplayContent, task2);
+        final Task rootTask = createRootTask();
+        final Task task = createTask(rootTask);
+        final ActivityRecord activity = createActivityRecord(rootTask.mDisplayContent, task);
+        final Task rootTask2 = createRootTask();
+        final Task task2 = createTask(rootTask2);
+        final ActivityRecord activity2 = createActivityRecord(rootTask.mDisplayContent, task2);
 
-        assertTrue(stack.isOrganized());
-        assertTrue(stack2.isOrganized());
+        assertTrue(rootTask.isOrganized());
+        assertTrue(rootTask2.isOrganized());
 
         // Verify a back pressed does not call the organizer
         mWm.mAtmService.mActivityClientController.onBackPressedOnTaskRoot(activity.token,
@@ -989,7 +995,7 @@
 
         // Enable intercepting back
         mWm.mAtmService.mTaskOrganizerController.setInterceptBackPressedOnTaskRoot(
-                stack.mRemoteToken.toWindowContainerToken(), true);
+                rootTask.mRemoteToken.toWindowContainerToken(), true);
 
         // Verify now that the back press does call the organizer
         mWm.mAtmService.mActivityClientController.onBackPressedOnTaskRoot(activity.token,
@@ -1000,7 +1006,7 @@
 
         // Disable intercepting back
         mWm.mAtmService.mTaskOrganizerController.setInterceptBackPressedOnTaskRoot(
-                stack.mRemoteToken.toWindowContainerToken(), false);
+                rootTask.mRemoteToken.toWindowContainerToken(), false);
 
         // Verify now that the back press no longer calls the organizer
         mWm.mAtmService.mActivityClientController.onBackPressedOnTaskRoot(activity.token,
@@ -1012,8 +1018,8 @@
 
     @Test
     public void testBLASTCallbackWithWindows() throws Exception {
-        final Task stackController = createStack();
-        final Task task = createTask(stackController);
+        final Task rootTaskController = createRootTask();
+        final Task task = createTask(rootTaskController);
         final WindowState w1 = createAppWindow(task, TYPE_APPLICATION, "Enlightened Window 1");
         final WindowState w2 = createAppWindow(task, TYPE_APPLICATION, "Enlightened Window 2");
         makeWindowVisible(w1);
@@ -1077,7 +1083,7 @@
         final ITaskOrganizer organizer = registerMockOrganizer();
         Task rootTask = mWm.mAtmService.mTaskOrganizerController.createRootTask(
                 mDisplayContent, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, null);
-        final Task task1 = createStack();
+        final Task task1 = createRootTask();
         final Task task2 = createTask(rootTask, false /* fakeDraw */);
         WindowContainerTransaction wct = new WindowContainerTransaction();
         wct.reparent(task1.mRemoteToken.toWindowContainerToken(),
@@ -1090,19 +1096,19 @@
     @Test
     public void testAppearDeferThenInfoChange() {
         final ITaskOrganizer organizer = registerMockOrganizer();
-        final Task stack = createStack();
+        final Task rootTask = createRootTask();
 
         // Assume layout defer
         mWm.mWindowPlacerLocked.deferLayout();
 
-        final Task task = createTask(stack);
-        final ActivityRecord record = createActivityRecord(stack.mDisplayContent, task);
+        final Task task = createTask(rootTask);
+        final ActivityRecord record = createActivityRecord(rootTask.mDisplayContent, task);
 
-        stack.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
+        rootTask.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
         record.setTaskDescription(new ActivityManager.TaskDescription("TestDescription"));
         waitUntilHandlersIdle();
 
-        ArrayList<PendingTaskEvent> pendingEvents = getTaskPendingEvent(stack);
+        ArrayList<PendingTaskEvent> pendingEvents = getTaskPendingEvent(rootTask);
         assertEquals(1, pendingEvents.size());
         assertEquals(PendingTaskEvent.EVENT_APPEARED, pendingEvents.get(0).mEventType);
         assertEquals("TestDescription",
@@ -1112,35 +1118,35 @@
     @Test
     public void testAppearDeferThenVanish() {
         final ITaskOrganizer organizer = registerMockOrganizer();
-        final Task stack = createStack();
+        final Task rootTask = createRootTask();
 
         // Assume layout defer
         mWm.mWindowPlacerLocked.deferLayout();
 
-        final Task task = createTask(stack);
+        final Task task = createTask(rootTask);
 
-        stack.removeImmediately();
+        rootTask.removeImmediately();
         waitUntilHandlersIdle();
 
-        ArrayList<PendingTaskEvent> pendingEvents = getTaskPendingEvent(stack);
+        ArrayList<PendingTaskEvent> pendingEvents = getTaskPendingEvent(rootTask);
         assertEquals(0, pendingEvents.size());
     }
 
     @Test
     public void testInfoChangeDeferMultiple() {
         final ITaskOrganizer organizer = registerMockOrganizer();
-        final Task stack = createStack();
-        final Task task = createTask(stack);
-        final ActivityRecord record = createActivityRecord(stack.mDisplayContent, task);
+        final Task rootTask = createRootTask();
+        final Task task = createTask(rootTask);
+        final ActivityRecord record = createActivityRecord(rootTask.mDisplayContent, task);
 
         // Assume layout defer
         mWm.mWindowPlacerLocked.deferLayout();
 
-        stack.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
+        rootTask.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
         record.setTaskDescription(new ActivityManager.TaskDescription("TestDescription"));
         waitUntilHandlersIdle();
 
-        ArrayList<PendingTaskEvent> pendingEvents = getTaskPendingEvent(stack);
+        ArrayList<PendingTaskEvent> pendingEvents = getTaskPendingEvent(rootTask);
         assertEquals(1, pendingEvents.size());
         assertEquals(PendingTaskEvent.EVENT_INFO_CHANGED, pendingEvents.get(0).mEventType);
         assertEquals("TestDescription",
@@ -1149,7 +1155,7 @@
         record.setTaskDescription(new ActivityManager.TaskDescription("TestDescription2"));
         waitUntilHandlersIdle();
 
-        pendingEvents = getTaskPendingEvent(stack);
+        pendingEvents = getTaskPendingEvent(rootTask);
         assertEquals(1, pendingEvents.size());
         assertEquals(PendingTaskEvent.EVENT_INFO_CHANGED, pendingEvents.get(0).mEventType);
         assertEquals("TestDescription2",
@@ -1159,20 +1165,20 @@
     @Test
     public void testInfoChangDeferThenVanish() {
         final ITaskOrganizer organizer = registerMockOrganizer();
-        final Task stack = createStack();
-        final Task task = createTask(stack);
-        final ActivityRecord record = createActivityRecord(stack.mDisplayContent, task);
+        final Task rootTask = createRootTask();
+        final Task task = createTask(rootTask);
+        final ActivityRecord record = createActivityRecord(rootTask.mDisplayContent, task);
 
         // Assume layout defer
         mWm.mWindowPlacerLocked.deferLayout();
 
-        stack.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
+        rootTask.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
         record.setTaskDescription(new ActivityManager.TaskDescription("TestDescription"));
 
-        stack.removeImmediately();
+        rootTask.removeImmediately();
         waitUntilHandlersIdle();
 
-        ArrayList<PendingTaskEvent> pendingEvents = getTaskPendingEvent(stack);
+        ArrayList<PendingTaskEvent> pendingEvents = getTaskPendingEvent(rootTask);
         assertEquals(1, pendingEvents.size());
         assertEquals(PendingTaskEvent.EVENT_VANISHED, pendingEvents.get(0).mEventType);
         assertEquals("TestDescription",
@@ -1182,18 +1188,18 @@
     @Test
     public void testVanishDeferThenInfoChange() {
         final ITaskOrganizer organizer = registerMockOrganizer();
-        final Task stack = createStack();
-        final Task task = createTask(stack);
-        final ActivityRecord record = createActivityRecord(stack.mDisplayContent, task);
+        final Task rootTask = createRootTask();
+        final Task task = createTask(rootTask);
+        final ActivityRecord record = createActivityRecord(rootTask.mDisplayContent, task);
 
         // Assume layout defer
         mWm.mWindowPlacerLocked.deferLayout();
 
-        stack.removeImmediately();
-        stack.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
+        rootTask.removeImmediately();
+        rootTask.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
         waitUntilHandlersIdle();
 
-        ArrayList<PendingTaskEvent> pendingEvents = getTaskPendingEvent(stack);
+        ArrayList<PendingTaskEvent> pendingEvents = getTaskPendingEvent(rootTask);
         assertEquals(1, pendingEvents.size());
         assertEquals(PendingTaskEvent.EVENT_VANISHED, pendingEvents.get(0).mEventType);
     }
@@ -1201,19 +1207,19 @@
     @Test
     public void testVanishDeferThenBackOnRoot() {
         final ITaskOrganizer organizer = registerMockOrganizer();
-        final Task stack = createStack();
-        final Task task = createTask(stack);
-        final ActivityRecord record = createActivityRecord(stack.mDisplayContent, task);
+        final Task rootTask = createRootTask();
+        final Task task = createTask(rootTask);
+        final ActivityRecord record = createActivityRecord(rootTask.mDisplayContent, task);
 
         // Assume layout defer
         mWm.mWindowPlacerLocked.deferLayout();
 
-        stack.removeImmediately();
+        rootTask.removeImmediately();
         mWm.mAtmService.mActivityClientController.onBackPressedOnTaskRoot(record.token,
                 new IRequestFinishCallback.Default());
         waitUntilHandlersIdle();
 
-        ArrayList<PendingTaskEvent> pendingEvents = getTaskPendingEvent(stack);
+        ArrayList<PendingTaskEvent> pendingEvents = getTaskPendingEvent(rootTask);
         assertEquals(1, pendingEvents.size());
         assertEquals(PendingTaskEvent.EVENT_VANISHED, pendingEvents.get(0).mEventType);
     }
@@ -1264,7 +1270,7 @@
     @Test
     public void testSizeCompatModeChangedOnFirstOrganizedTask() throws RemoteException {
         final ITaskOrganizer organizer = registerMockOrganizer();
-        final Task rootTask = createStack();
+        final Task rootTask = createRootTask();
         final Task task = createTask(rootTask);
         final ActivityRecord activity = createActivityRecord(rootTask.mDisplayContent, task);
         final ArgumentCaptor<RunningTaskInfo> infoCaptor =
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 5b5b1da..bfbe203 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -249,21 +249,22 @@
         assertFalse(appWindow.canBeImeTarget());
         assertFalse(imeWindow.canBeImeTarget());
 
-        // Simulate the window is in split screen primary stack and the current state is
-        // minimized and home stack is resizable, so that we should ignore input for the stack.
+        // Simulate the window is in split screen primary root task and the current state is
+        // minimized and home root task is resizable, so that we should ignore input for the
+        // root task.
         final DockedTaskDividerController controller =
                 mDisplayContent.getDockedDividerController();
-        final Task stack = createTaskStackOnDisplay(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY,
-                ACTIVITY_TYPE_STANDARD, mDisplayContent);
+        final Task rootTask = createTask(mDisplayContent,
+                WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD);
         spyOn(appWindow);
         spyOn(controller);
-        spyOn(stack);
-        stack.setFocusable(false);
-        doReturn(stack).when(appWindow).getRootTask();
+        spyOn(rootTask);
+        rootTask.setFocusable(false);
+        doReturn(rootTask).when(appWindow).getRootTask();
 
         // Make sure canBeImeTarget is false due to shouldIgnoreInput is true;
         assertFalse(appWindow.canBeImeTarget());
-        assertTrue(stack.shouldIgnoreInput());
+        assertTrue(rootTask.shouldIgnoreInput());
     }
 
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
index b210dfb..e9e0c99 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -429,35 +429,55 @@
         return newTaskDisplayArea;
     }
 
-    /** Creates a {@link Task} and adds it to the specified {@link DisplayContent}. */
-    Task createTaskStackOnDisplay(DisplayContent dc) {
-        return createTaskStackOnDisplay(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, dc);
+    /**
+     *  Creates a {@link Task} with a simple {@link ActivityRecord} and adds to the given
+     *  {@link TaskDisplayArea}.
+     */
+    Task createTaskWithActivity(TaskDisplayArea taskDisplayArea,
+            int windowingMode, int activityType, boolean onTop, boolean twoLevelTask) {
+        return createTask(taskDisplayArea, windowingMode, activityType,
+                onTop, true /* createActivity */, twoLevelTask);
     }
 
-    Task createTaskStackOnDisplay(int windowingMode, int activityType, DisplayContent dc) {
-        return new TaskBuilder(dc.mAtmService.mTaskSupervisor)
-                .setDisplay(dc)
+    /** Creates a {@link Task} and adds to the given {@link DisplayContent}. */
+    Task createTask(DisplayContent dc) {
+        return createTask(dc.getDefaultTaskDisplayArea(),
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+    }
+
+    Task createTask(DisplayContent dc, int windowingMode, int activityType) {
+        return createTask(dc.getDefaultTaskDisplayArea(), windowingMode, activityType);
+    }
+
+    Task createTask(TaskDisplayArea taskDisplayArea, int windowingMode, int activityType) {
+        return createTask(taskDisplayArea, windowingMode, activityType,
+                true /* onTop */, false /* createActivity */, false /* twoLevelTask */);
+    }
+
+    /** Creates a {@link Task} and adds to the given {@link TaskDisplayArea}. */
+    Task createTask(TaskDisplayArea taskDisplayArea, int windowingMode, int activityType,
+            boolean onTop, boolean createActivity, boolean twoLevelTask) {
+        final TaskBuilder builder = new TaskBuilder(mSupervisor)
+                .setTaskDisplayArea(taskDisplayArea)
                 .setWindowingMode(windowingMode)
                 .setActivityType(activityType)
-                .setIntent(new Intent())
-                .build();
+                .setOnTop(onTop)
+                .setCreateActivity(createActivity);
+        if (twoLevelTask) {
+            return builder
+                    .setCreateParentTask(true)
+                    .build()
+                    .getRootTask();
+        } else {
+            return builder.build();
+        }
     }
 
-    Task createTaskStackOnTaskDisplayArea(int windowingMode, int activityType,
-            TaskDisplayArea tda) {
-        return new TaskBuilder(tda.mDisplayContent.mAtmService.mTaskSupervisor)
-                .setTaskDisplayArea(tda)
-                .setWindowingMode(windowingMode)
-                .setActivityType(activityType)
-                .setIntent(new Intent())
-                .build();
-    }
-
-    /** Creates a {@link Task} and adds it to the specified {@link Task}. */
-    Task createTaskInStack(Task stack, int userId) {
-        final Task task = new TaskBuilder(stack.mTaskSupervisor)
+    /** Creates a {@link Task} and adds to the given root {@link Task}. */
+    Task createTaskInRootTask(Task rootTask, int userId) {
+        final Task task = new TaskBuilder(rootTask.mTaskSupervisor)
                 .setUserId(userId)
-                .setParentTask(stack)
+                .setParentTask(rootTask)
                 .build();
         return task;
     }
@@ -485,7 +505,7 @@
      */
     ActivityRecord createActivityRecord(DisplayContent dc, int windowingMode,
             int activityType) {
-        final Task task = createTaskStackOnDisplay(windowingMode, activityType, dc);
+        final Task task = createTask(dc, windowingMode, activityType);
         return createActivityRecord(dc, task);
     }
 
@@ -517,7 +537,7 @@
      */
     ActivityRecord createActivityRecordWithParentTask(DisplayContent dc, int windowingMode,
             int activityType) {
-        final Task task = createTaskStackOnDisplay(windowingMode, activityType, dc);
+        final Task task = createTask(dc, windowingMode, activityType);
         return createActivityRecordWithParentTask(task);
     }
 
@@ -871,7 +891,7 @@
                         .setParentTask(mParentTask).build();
             } else if (mTask == null && mParentTask != null && DisplayContent.alwaysCreateRootTask(
                     mParentTask.getWindowingMode(), mParentTask.getActivityType())) {
-                // The stack can be the task root.
+                // The parent task can be the task root.
                 mTask = mParentTask;
             }
 
@@ -921,9 +941,9 @@
                 doReturn(true).when(activity).fillsParent();
                 mTask.addChild(activity);
                 if (mOnTop) {
-                    // Move the task to front after activity added.
-                    // Or {@link TaskDisplayArea#mPreferredTopFocusableStack} could be other stacks
-                    // (e.g. home stack).
+                    // Move the task to front after activity is added.
+                    // Or {@link TaskDisplayArea#mPreferredTopFocusableRootTask} could be other
+                    // root tasks (e.g. home root task).
                     mTask.moveToFront("createActivity");
                 }
                 // Make visible by default...
@@ -1127,8 +1147,8 @@
                         .build();
                 if (mOnTop) {
                     // We move the task to front again in order to regain focus after activity
-                    // added to the stack. Or {@link TaskDisplayArea#mPreferredTopFocusableStack}
-                    // could be other stacks (e.g. home stack).
+                    // is added. Or {@link TaskDisplayArea#mPreferredTopFocusableRootTask} could be
+                    // other root tasks (e.g. home root task).
                     task.moveToFront("createActivityTask");
                 } else {
                     task.moveToBack("createActivityTask", null);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java
index e2585e5..ed5f1d8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java
@@ -16,6 +16,7 @@
 
 package com.android.server.wm;
 
+import static android.view.InsetsState.ITYPE_IME;
 import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
@@ -37,6 +38,7 @@
 import android.os.Bundle;
 import android.os.IBinder;
 import android.platform.test.annotations.Presubmit;
+import android.window.WindowContext;
 
 import androidx.test.filters.SmallTest;
 
@@ -207,7 +209,7 @@
 
     /**
      * Test that {@link android.view.SurfaceControl} should not be created for the
-     * {@link WindowToken} which was created for {@link android.app.WindowContext} initially, the
+     * {@link WindowToken} which was created for {@link WindowContext} initially, the
      * surface should be create after addWindow for this token.
      */
     @Test
@@ -250,4 +252,29 @@
 
         verify(selectFunc).apply(token2.windowType, options);
     }
+
+    /**
+     * Test that {@link WindowToken#setInsetsFrozen(boolean)} will set the frozen insets
+     * states for its children windows and by default it shouldn't let IME window setting
+     * the frozen insets state even the window of the window token is the IME layering target.
+     */
+    @UseTestDisplay(addWindows = W_INPUT_METHOD)
+    @Test
+    public void testSetInsetsFrozen_notAffectImeWindowState() {
+        // Pre-condition: make the IME window be controlled by IME insets provider.
+        mDisplayContent.getInsetsStateController().getSourceProvider(ITYPE_IME).setWindow(
+                mDisplayContent.mInputMethodWindow, null, null);
+
+        // Simulate an app window to be the IME layering target, assume the app window has no
+        // frozen insets state by default.
+        final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
+        mDisplayContent.setImeLayeringTarget(app);
+        assertNull(app.getFrozenInsetsState());
+        assertTrue(app.isImeLayeringTarget());
+
+        // Verify invoking setInsetsFrozen shouldn't let IME window setting the frozen insets state.
+        app.mToken.setInsetsFrozen(true);
+        assertNotNull(app.getFrozenInsetsState());
+        assertNull(mDisplayContent.mInputMethodWindow.getFrozenInsetsState());
+    }
 }
diff --git a/services/translation/java/com/android/server/translation/RemoteTranslationService.java b/services/translation/java/com/android/server/translation/RemoteTranslationService.java
index 0c7e617..82cb728 100644
--- a/services/translation/java/com/android/server/translation/RemoteTranslationService.java
+++ b/services/translation/java/com/android/server/translation/RemoteTranslationService.java
@@ -20,9 +20,11 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.os.ResultReceiver;
 import android.service.translation.ITranslationService;
 import android.service.translation.TranslationService;
 import android.util.Slog;
+import android.view.translation.TranslationContext;
 import android.view.translation.TranslationSpec;
 
 import com.android.internal.infra.AbstractRemoteService;
@@ -80,8 +82,14 @@
         return mIdleUnbindTimeoutMs;
     }
 
-    public void onSessionCreated(@NonNull TranslationSpec sourceSpec,
-            @NonNull TranslationSpec destSpec, int sessionId, IResultReceiver resultReceiver) {
-        run((s) -> s.onCreateTranslationSession(sourceSpec, destSpec, sessionId, resultReceiver));
+    public void onSessionCreated(@NonNull TranslationContext translationContext, int sessionId,
+            IResultReceiver resultReceiver) {
+        run((s) -> s.onCreateTranslationSession(translationContext, sessionId, resultReceiver));
+    }
+
+    public void onTranslationCapabilitiesRequest(@TranslationSpec.DataFormat int sourceFormat,
+            @TranslationSpec.DataFormat int targetFormat,
+            @NonNull ResultReceiver resultReceiver) {
+        run((s) -> s.onTranslationCapabilitiesRequest(sourceFormat, targetFormat, resultReceiver));
     }
 }
diff --git a/services/translation/java/com/android/server/translation/TranslationManagerService.java b/services/translation/java/com/android/server/translation/TranslationManagerService.java
index 72e1e33..f132b49 100644
--- a/services/translation/java/com/android/server/translation/TranslationManagerService.java
+++ b/services/translation/java/com/android/server/translation/TranslationManagerService.java
@@ -17,13 +17,19 @@
 package com.android.server.translation;
 
 import static android.Manifest.permission.MANAGE_UI_TRANSLATION;
+import static android.app.PendingIntent.FLAG_IMMUTABLE;
 import static android.content.Context.TRANSLATION_MANAGER_SERVICE;
 import static android.view.translation.TranslationManager.STATUS_SYNC_CALL_FAIL;
+import static android.view.translation.TranslationManager.STATUS_SYNC_CALL_SUCCESS;
+
+import static com.android.internal.util.SyncResultReceiver.bundleFor;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.PendingIntent;
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.os.Binder;
 import android.os.IBinder;
@@ -31,9 +37,11 @@
 import android.os.RemoteException;
 import android.os.ResultReceiver;
 import android.os.ShellCallback;
+import android.os.UserHandle;
 import android.util.Slog;
 import android.view.autofill.AutofillId;
 import android.view.translation.ITranslationManager;
+import android.view.translation.TranslationContext;
 import android.view.translation.TranslationSpec;
 import android.view.translation.UiTranslationManager.UiTranslationState;
 
@@ -142,29 +150,33 @@
     }
 
     final class TranslationManagerServiceStub extends ITranslationManager.Stub {
+
         @Override
-        public void getSupportedLocales(IResultReceiver receiver, int userId)
+        public void onTranslationCapabilitiesRequest(@TranslationSpec.DataFormat int sourceFormat,
+                @TranslationSpec.DataFormat int targetFormat,
+                ResultReceiver receiver, int userId)
                 throws RemoteException {
             synchronized (mLock) {
                 final TranslationManagerServiceImpl service = getServiceForUserLocked(userId);
                 if (service != null && (isDefaultServiceLocked(userId)
-                        || isCalledByServiceAppLocked(userId, "getSupportedLocales"))) {
-                    service.getSupportedLocalesLocked(receiver);
+                        || isCalledByServiceAppLocked(userId, "getTranslationCapabilities"))) {
+                    service.onTranslationCapabilitiesRequestLocked(sourceFormat, targetFormat,
+                            receiver);
                 } else {
-                    Slog.v(TAG, "getSupportedLocales(): no service for " + userId);
+                    Slog.v(TAG, "onGetTranslationCapabilitiesLocked(): no service for " + userId);
                     receiver.send(STATUS_SYNC_CALL_FAIL, null);
                 }
             }
         }
 
         @Override
-        public void onSessionCreated(TranslationSpec sourceSpec, TranslationSpec destSpec,
+        public void onSessionCreated(TranslationContext translationContext,
                 int sessionId, IResultReceiver receiver, int userId) throws RemoteException {
             synchronized (mLock) {
                 final TranslationManagerServiceImpl service = getServiceForUserLocked(userId);
                 if (service != null && (isDefaultServiceLocked(userId)
                         || isCalledByServiceAppLocked(userId, "onSessionCreated"))) {
-                    service.onSessionCreatedLocked(sourceSpec, destSpec, sessionId, receiver);
+                    service.onSessionCreatedLocked(translationContext, sessionId, receiver);
                 } else {
                     Slog.v(TAG, "onSessionCreated(): no service for " + userId);
                     receiver.send(STATUS_SYNC_CALL_FAIL, null);
@@ -174,7 +186,7 @@
 
         @Override
         public void updateUiTranslationStateByTaskId(@UiTranslationState int state,
-                TranslationSpec sourceSpec, TranslationSpec destSpec, List<AutofillId> viewIds,
+                TranslationSpec sourceSpec, TranslationSpec targetSpec, List<AutofillId> viewIds,
                 int taskId, int userId) {
             // deprecated
             enforceCallerHasPermission(MANAGE_UI_TRANSLATION);
@@ -183,7 +195,7 @@
                 if (service != null && (isDefaultServiceLocked(userId)
                         || isCalledByServiceAppLocked(userId,
                         "updateUiTranslationStateByTaskId"))) {
-                    service.updateUiTranslationStateLocked(state, sourceSpec, destSpec, viewIds,
+                    service.updateUiTranslationStateLocked(state, sourceSpec, targetSpec, viewIds,
                             taskId);
                 }
             }
@@ -191,14 +203,14 @@
 
         @Override
         public void updateUiTranslationState(@UiTranslationState int state,
-                TranslationSpec sourceSpec, TranslationSpec destSpec, List<AutofillId> viewIds,
+                TranslationSpec sourceSpec, TranslationSpec targetSpec, List<AutofillId> viewIds,
                 IBinder token, int taskId, int userId) {
             enforceCallerHasPermission(MANAGE_UI_TRANSLATION);
             synchronized (mLock) {
                 final TranslationManagerServiceImpl service = getServiceForUserLocked(userId);
                 if (service != null && (isDefaultServiceLocked(userId)
                         || isCalledByServiceAppLocked(userId, "updateUiTranslationState"))) {
-                    service.updateUiTranslationStateLocked(state, sourceSpec, destSpec, viewIds,
+                    service.updateUiTranslationStateLocked(state, sourceSpec, targetSpec, viewIds,
                             token, taskId);
                 }
             }
@@ -226,6 +238,46 @@
             }
         }
 
+        @Override
+        public void getServiceSettingsActivity(IResultReceiver result, int userId) {
+            final TranslationManagerServiceImpl service;
+            synchronized (mLock) {
+                service = getServiceForUserLocked(userId);
+            }
+            if (service != null) {
+                final ComponentName componentName = service.getServiceSettingsActivityLocked();
+                if (componentName == null) {
+                    try {
+                        result.send(STATUS_SYNC_CALL_SUCCESS, null);
+                    } catch (RemoteException e) {
+                        Slog.w(TAG, "Unable to send getServiceSettingsActivity(): " + e);
+                    }
+                }
+                final Intent intent = new Intent();
+                intent.setComponent(componentName);
+                final long identity = Binder.clearCallingIdentity();
+                try {
+                    final PendingIntent pendingIntent =
+                            PendingIntent.getActivityAsUser(getContext(), 0, intent, FLAG_IMMUTABLE,
+                                    null, new UserHandle(userId));
+                    try {
+
+                        result.send(STATUS_SYNC_CALL_SUCCESS, bundleFor(pendingIntent));
+                    } catch (RemoteException e) {
+                        Slog.w(TAG, "Unable to send getServiceSettingsActivity(): " + e);
+                    }
+                } finally {
+                    Binder.restoreCallingIdentity(identity);
+                }
+            } else {
+                try {
+                    result.send(STATUS_SYNC_CALL_FAIL, null);
+                } catch (RemoteException e) {
+                    Slog.w(TAG, "Unable to send getServiceSettingsActivity(): " + e);
+                }
+            }
+        }
+
         /**
          * Dump the service state into the given stream. You run "adb shell dumpsys translation".
         */
diff --git a/services/translation/java/com/android/server/translation/TranslationManagerServiceImpl.java b/services/translation/java/com/android/server/translation/TranslationManagerServiceImpl.java
index 1ca07cb..2cd41ba 100644
--- a/services/translation/java/com/android/server/translation/TranslationManagerServiceImpl.java
+++ b/services/translation/java/com/android/server/translation/TranslationManagerServiceImpl.java
@@ -16,7 +16,6 @@
 
 package com.android.server.translation;
 
-import static android.view.translation.TranslationManager.STATUS_SYNC_CALL_SUCCESS;
 import static android.view.translation.UiTranslationManager.EXTRA_SOURCE_LOCALE;
 import static android.view.translation.UiTranslationManager.EXTRA_STATE;
 import static android.view.translation.UiTranslationManager.EXTRA_TARGET_LOCALE;
@@ -31,23 +30,23 @@
 import android.os.IRemoteCallback;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
+import android.os.ResultReceiver;
 import android.service.translation.TranslationServiceInfo;
 import android.util.Slog;
 import android.view.autofill.AutofillId;
 import android.view.inputmethod.InputMethodInfo;
+import android.view.translation.TranslationContext;
 import android.view.translation.TranslationSpec;
 import android.view.translation.UiTranslationManager.UiTranslationState;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.os.IResultReceiver;
-import com.android.internal.util.SyncResultReceiver;
 import com.android.server.LocalServices;
 import com.android.server.infra.AbstractPerUserSystemService;
 import com.android.server.inputmethod.InputMethodManagerInternal;
 import com.android.server.wm.ActivityTaskManagerInternal;
 import com.android.server.wm.ActivityTaskManagerInternal.ActivityTokens;
 
-import java.util.ArrayList;
 import java.util.List;
 
 final class TranslationManagerServiceImpl extends
@@ -63,6 +62,9 @@
     @Nullable
     private ServiceInfo mRemoteTranslationServiceInfo;
 
+    @GuardedBy("mLock")
+    private TranslationServiceInfo mTranslationServiceInfo;
+
     private ActivityTaskManagerInternal mActivityTaskManagerInternal;
 
     protected TranslationManagerServiceImpl(
@@ -77,10 +79,10 @@
     @Override // from PerUserSystemService
     protected ServiceInfo newServiceInfoLocked(@NonNull ComponentName serviceComponent)
             throws PackageManager.NameNotFoundException {
-        final TranslationServiceInfo info = new TranslationServiceInfo(getContext(),
+        mTranslationServiceInfo = new TranslationServiceInfo(getContext(),
                 serviceComponent, isTemporaryServiceSetLocked(), mUserId);
-        mRemoteTranslationServiceInfo = info.getServiceInfo();
-        return info.getServiceInfo();
+        mRemoteTranslationServiceInfo = mTranslationServiceInfo.getServiceInfo();
+        return mTranslationServiceInfo.getServiceInfo();
     }
 
     @GuardedBy("mLock")
@@ -122,28 +124,28 @@
     }
 
     @GuardedBy("mLock")
-    void getSupportedLocalesLocked(@NonNull IResultReceiver resultReceiver) {
-        // TODO: implement this
-        try {
-            resultReceiver.send(STATUS_SYNC_CALL_SUCCESS,
-                    SyncResultReceiver.bundleFor(new ArrayList<>()));
-        } catch (RemoteException e) {
-            Slog.w(TAG, "RemoteException returning supported locales: " + e);
+    void onTranslationCapabilitiesRequestLocked(@TranslationSpec.DataFormat int sourceFormat,
+            @TranslationSpec.DataFormat int destFormat,
+            @NonNull ResultReceiver resultReceiver) {
+        final RemoteTranslationService remoteService = ensureRemoteServiceLocked();
+        if (remoteService != null) {
+            remoteService.onTranslationCapabilitiesRequest(sourceFormat, destFormat,
+                    resultReceiver);
         }
     }
 
     @GuardedBy("mLock")
-    void onSessionCreatedLocked(@NonNull TranslationSpec sourceSpec,
-            @NonNull TranslationSpec destSpec, int sessionId, IResultReceiver resultReceiver) {
+    void onSessionCreatedLocked(@NonNull TranslationContext translationContext, int sessionId,
+            IResultReceiver resultReceiver) {
         final RemoteTranslationService remoteService = ensureRemoteServiceLocked();
         if (remoteService != null) {
-            remoteService.onSessionCreated(sourceSpec, destSpec, sessionId, resultReceiver);
+            remoteService.onSessionCreated(translationContext, sessionId, resultReceiver);
         }
     }
 
     @GuardedBy("mLock")
     public void updateUiTranslationStateLocked(@UiTranslationState int state,
-            TranslationSpec sourceSpec, TranslationSpec destSpec, List<AutofillId> viewIds,
+            TranslationSpec sourceSpec, TranslationSpec targetSpec, List<AutofillId> viewIds,
             int taskId) {
         // deprecated
         final ActivityTokens taskTopActivityTokens =
@@ -152,13 +154,13 @@
             Slog.w(TAG, "Unknown activity to query for update translation state.");
             return;
         }
-        updateUiTranslationStateByActivityTokens(taskTopActivityTokens, state, sourceSpec, destSpec,
-                viewIds);
+        updateUiTranslationStateByActivityTokens(taskTopActivityTokens, state, sourceSpec,
+                targetSpec, viewIds);
     }
 
     @GuardedBy("mLock")
     public void updateUiTranslationStateLocked(@UiTranslationState int state,
-            TranslationSpec sourceSpec, TranslationSpec destSpec, List<AutofillId> viewIds,
+            TranslationSpec sourceSpec, TranslationSpec targetSpec, List<AutofillId> viewIds,
             IBinder token, int taskId) {
         // Get top activity for a given task id
         final ActivityTokens taskTopActivityTokens =
@@ -169,20 +171,20 @@
                     + "translation state for token=" + token + " taskId=" + taskId);
             return;
         }
-        updateUiTranslationStateByActivityTokens(taskTopActivityTokens, state, sourceSpec, destSpec,
-                viewIds);
+        updateUiTranslationStateByActivityTokens(taskTopActivityTokens, state, sourceSpec,
+                targetSpec, viewIds);
     }
 
     private void updateUiTranslationStateByActivityTokens(ActivityTokens tokens,
-            @UiTranslationState int state, TranslationSpec sourceSpec, TranslationSpec destSpec,
+            @UiTranslationState int state, TranslationSpec sourceSpec, TranslationSpec targetSpec,
             List<AutofillId> viewIds) {
         try {
             tokens.getApplicationThread().updateUiTranslationState(tokens.getActivityToken(), state,
-                    sourceSpec, destSpec, viewIds);
+                    sourceSpec, targetSpec, viewIds);
         } catch (RemoteException e) {
             Slog.w(TAG, "Update UiTranslationState fail: " + e);
         }
-        invokeCallbacks(state, sourceSpec, destSpec);
+        invokeCallbacks(state, sourceSpec, targetSpec);
     }
 
     private void invokeCallbacks(
@@ -228,4 +230,16 @@
     }
 
     private final RemoteCallbackList<IRemoteCallback> mCallbacks = new RemoteCallbackList<>();
+
+    public ComponentName getServiceSettingsActivityLocked() {
+        if (mTranslationServiceInfo == null) {
+            return null;
+        }
+        final String activityName = mTranslationServiceInfo.getSettingsActivity();
+        if (activityName == null) {
+            return null;
+        }
+        final String packageName = mTranslationServiceInfo.getServiceInfo().packageName;
+        return new ComponentName(packageName, activityName);
+    }
 }
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index afa35fe..2e692e6 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -917,20 +917,31 @@
                     boolean prevHostConnected = mHostConnected;
                     UsbPort port = (UsbPort) args.arg1;
                     UsbPortStatus status = (UsbPortStatus) args.arg2;
-                    mHostConnected = status.getCurrentDataRole() == DATA_ROLE_HOST;
-                    mSourcePower = status.getCurrentPowerRole() == POWER_ROLE_SOURCE;
-                    mSinkPower = status.getCurrentPowerRole() == POWER_ROLE_SINK;
-                    mAudioAccessoryConnected = (status.getCurrentMode() == MODE_AUDIO_ACCESSORY);
+
+                    if (status != null) {
+                        mHostConnected = status.getCurrentDataRole() == DATA_ROLE_HOST;
+                        mSourcePower = status.getCurrentPowerRole() == POWER_ROLE_SOURCE;
+                        mSinkPower = status.getCurrentPowerRole() == POWER_ROLE_SINK;
+                        mAudioAccessoryConnected = (status.getCurrentMode() == MODE_AUDIO_ACCESSORY);
+
+                        // Ideally we want to see if PR_SWAP and DR_SWAP is supported.
+                        // But, this should be suffice, since, all four combinations are only supported
+                        // when PR_SWAP and DR_SWAP are supported.
+                        mSupportsAllCombinations = status.isRoleCombinationSupported(
+                                POWER_ROLE_SOURCE, DATA_ROLE_HOST)
+                                && status.isRoleCombinationSupported(POWER_ROLE_SINK, DATA_ROLE_HOST)
+                                && status.isRoleCombinationSupported(POWER_ROLE_SOURCE,
+                                DATA_ROLE_DEVICE)
+                                && status.isRoleCombinationSupported(POWER_ROLE_SINK, DATA_ROLE_DEVICE);
+                    } else {
+                        mHostConnected = false;
+                        mSourcePower = false;
+                        mSinkPower = false;
+                        mAudioAccessoryConnected = false;
+                        mSupportsAllCombinations = false;
+                    }
+
                     mAudioAccessorySupported = port.isModeSupported(MODE_AUDIO_ACCESSORY);
-                    // Ideally we want to see if PR_SWAP and DR_SWAP is supported.
-                    // But, this should be suffice, since, all four combinations are only supported
-                    // when PR_SWAP and DR_SWAP are supported.
-                    mSupportsAllCombinations = status.isRoleCombinationSupported(
-                            POWER_ROLE_SOURCE, DATA_ROLE_HOST)
-                            && status.isRoleCombinationSupported(POWER_ROLE_SINK, DATA_ROLE_HOST)
-                            && status.isRoleCombinationSupported(POWER_ROLE_SOURCE,
-                            DATA_ROLE_DEVICE)
-                            && status.isRoleCombinationSupported(POWER_ROLE_SINK, DATA_ROLE_DEVICE);
 
                     args.recycle();
                     updateUsbNotification(false);
diff --git a/services/voiceinteraction/TEST_MAPPING b/services/voiceinteraction/TEST_MAPPING
index 748e5df..22a6445 100644
--- a/services/voiceinteraction/TEST_MAPPING
+++ b/services/voiceinteraction/TEST_MAPPING
@@ -7,6 +7,14 @@
           "exclude-annotation": "androidx.test.filters.FlakyTest"
         }
       ]
+    },
+    {
+      "name": "CtsAssistTestCases",
+      "options": [
+        {
+          "exclude-annotation": "androidx.test.filters.FlakyTest"
+        }
+      ]
     }
   ]
 }
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
index e089995a..5d541e9 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
@@ -16,6 +16,9 @@
 
 package com.android.server.voiceinteraction;
 
+import static android.service.voice.HotwordDetectionService.AUDIO_SOURCE_EXTERNAL;
+import static android.service.voice.HotwordDetectionService.AUDIO_SOURCE_MICROPHONE;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.ComponentName;
@@ -24,23 +27,30 @@
 import android.hardware.soundtrigger.IRecognitionStatusCallback;
 import android.hardware.soundtrigger.SoundTrigger;
 import android.media.AudioAttributes;
+import android.media.AudioFormat;
+import android.media.AudioManager;
 import android.media.AudioRecord;
 import android.media.MediaRecorder;
-import android.os.Bundle;
 import android.os.ParcelFileDescriptor;
+import android.os.PersistableBundle;
 import android.os.RemoteException;
 import android.os.SharedMemory;
-import android.service.voice.AlwaysOnHotwordDetector;
+import android.service.voice.HotwordDetectedResult;
 import android.service.voice.HotwordDetectionService;
+import android.service.voice.HotwordRejectedResult;
 import android.service.voice.IDspHotwordDetectionCallback;
 import android.service.voice.IHotwordDetectionService;
+import android.service.voice.IMicrophoneHotwordDetectionVoiceInteractionCallback;
 import android.util.Pair;
 import android.util.Slog;
 
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.app.IHotwordRecognitionStatusCallback;
 import com.android.internal.infra.ServiceConnector;
 
+import java.io.Closeable;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.PrintWriter;
 import java.util.concurrent.Executor;
@@ -63,6 +73,8 @@
     private static final long VALIDATION_TIMEOUT_MILLIS = 3000;
     private static final long VOICE_INTERACTION_TIMEOUT_TO_OPEN_MIC_MILLIS = 2000;
     private static final int MAX_STREAMING_SECONDS = 10;
+    private static final int MICROPHONE_BUFFER_LENGTH_SECONDS = 8;
+    private static final int HOTWORD_AUDIO_LENGTH_SECONDS = 3;
 
     private final Executor mAudioCopyExecutor = Executors.newCachedThreadPool();
     // TODO: This may need to be a Handler(looper)
@@ -76,9 +88,12 @@
     final @NonNull ServiceConnector<IHotwordDetectionService> mRemoteHotwordDetectionService;
     boolean mBound;
 
+    @GuardedBy("mLock")
+    private ParcelFileDescriptor mCurrentAudioSink;
+
     HotwordDetectionConnection(Object lock, Context context, ComponentName serviceName,
-            int userId, boolean bindInstantServiceAllowed, @Nullable Bundle options,
-            @Nullable SharedMemory sharedMemory) {
+            int userId, boolean bindInstantServiceAllowed, @Nullable PersistableBundle options,
+            @Nullable SharedMemory sharedMemory, IHotwordRecognitionStatusCallback callback) {
         mLock = lock;
         mContext = context;
         mDetectionComponentName = serviceName;
@@ -96,10 +111,10 @@
                     mBound = connected;
                     if (connected) {
                         try {
-                            service.setConfig(options, sharedMemory);
+                            service.updateState(options, sharedMemory, callback);
                         } catch (RemoteException e) {
                             // TODO: (b/181842909) Report an error to voice interactor
-                            Slog.w(TAG, "Failed to setConfig for HotwordDetectionService", e);
+                            Slog.w(TAG, "Failed to updateState for HotwordDetectionService", e);
                         }
                     }
                 }
@@ -129,9 +144,65 @@
         }
     }
 
-    void setConfigLocked(Bundle options, SharedMemory sharedMemory) {
+    void updateStateLocked(PersistableBundle options, SharedMemory sharedMemory) {
         mRemoteHotwordDetectionService.run(
-                service -> service.setConfig(options, sharedMemory));
+                service -> service.updateState(options, sharedMemory, null /* callback */));
+    }
+
+    void startListeningFromMic(
+            AudioFormat audioFormat,
+            IMicrophoneHotwordDetectionVoiceInteractionCallback callback) {
+        if (DEBUG) {
+            Slog.d(TAG, "startListeningFromMic");
+        }
+
+        AudioRecord audioRecord = createMicAudioRecord(audioFormat);
+        if (audioRecord == null) {
+            // TODO: Callback.onError();
+            return;
+        }
+
+        handleSoftwareHotwordDetection(
+                audioFormat,
+                AudioReader.createFromAudioRecord(audioRecord),
+                AUDIO_SOURCE_MICROPHONE,
+                // TODO: handle bundles better.
+                new PersistableBundle(),
+                callback);
+    }
+
+    public void startListeningFromExternalSource(
+            ParcelFileDescriptor audioStream,
+            AudioFormat audioFormat,
+            @Nullable PersistableBundle options,
+            IMicrophoneHotwordDetectionVoiceInteractionCallback callback) {
+        if (DEBUG) {
+            Slog.d(TAG, "startListeningFromExternalSource");
+        }
+
+        ParcelFileDescriptor.AutoCloseInputStream audioReader =
+                new ParcelFileDescriptor.AutoCloseInputStream(audioStream);
+
+        handleSoftwareHotwordDetection(
+                audioFormat,
+                AudioReader.createFromInputStream(audioReader),
+                AUDIO_SOURCE_EXTERNAL,
+                options,
+                callback);
+    }
+
+    void stopListening() {
+        if (DEBUG) {
+            Slog.d(TAG, "stopListening");
+        }
+
+        synchronized (mLock) {
+            if (mCurrentAudioSink != null) {
+                Slog.i(TAG, "Closing audio stream to hotword detector: stopping requested");
+                bestEffortClose(mCurrentAudioSink);
+            }
+            mCurrentAudioSink = null;
+        }
     }
 
     private void detectFromDspSource(SoundTrigger.KeyphraseRecognitionEvent recognitionEvent,
@@ -175,7 +246,7 @@
 
         Runnable cancellingJob = () -> {
             record.stop();
-            bestEffortCloseFileDescriptor(audioSink);
+            bestEffortClose(audioSink);
             // TODO: consider calling externalCallback.onRejected(ERROR_TIMEOUT).
         };
 
@@ -186,11 +257,11 @@
         // TODO: consider making this a non-anonymous class.
         IDspHotwordDetectionCallback internalCallback = new IDspHotwordDetectionCallback.Stub() {
             @Override
-            public void onDetected() throws RemoteException {
+            public void onDetected(HotwordDetectedResult result) throws RemoteException {
                 if (DEBUG) {
                     Slog.d(TAG, "onDetected");
                 }
-                bestEffortCloseFileDescriptor(audioSink);
+                bestEffortClose(audioSink);
                 cancelingFuture.cancel(true);
 
                 // Give 2 more seconds for the interactor to start consuming the mic. If it fails to
@@ -202,17 +273,17 @@
                         VOICE_INTERACTION_TIMEOUT_TO_OPEN_MIC_MILLIS,
                         TimeUnit.MILLISECONDS);
 
+                // TODO: Propagate the HotwordDetectedResult.
                 externalCallback.onKeyphraseDetected(recognitionEvent);
             }
 
             @Override
-            public void onRejected() throws RemoteException {
+            public void onRejected(HotwordRejectedResult result) throws RemoteException {
                 if (DEBUG) {
                     Slog.d(TAG, "onRejected");
                 }
                 cancelingFuture.cancel(true);
-                externalCallback.onRejected(
-                        AlwaysOnHotwordDetector.HOTWORD_DETECTION_FALSE_ALERT);
+                externalCallback.onRejected(result);
             }
         };
 
@@ -222,7 +293,7 @@
                         recognitionEvent.getCaptureFormat(),
                         VALIDATION_TIMEOUT_MILLIS,
                         internalCallback));
-        bestEffortCloseFileDescriptor(clientRead);
+        bestEffortClose(clientRead);
     }
 
     static final class SoundTriggerCallback extends IRecognitionStatusCallback.Stub {
@@ -284,16 +355,48 @@
                 new AudioAttributes.Builder()
                         .setInternalCapturePreset(MediaRecorder.AudioSource.HOTWORD).build(),
                 recognitionEvent.getCaptureFormat(),
-                getBufferSizeInBytes(sampleRate, MAX_STREAMING_SECONDS),
+                getBufferSizeInBytes(
+                        sampleRate,
+                        MAX_STREAMING_SECONDS,
+                        recognitionEvent.getCaptureFormat().getChannelCount()),
                 recognitionEvent.getCaptureSession());
     }
 
+    @Nullable
+    private AudioRecord createMicAudioRecord(AudioFormat audioFormat) {
+        if (DEBUG) {
+            Slog.i(TAG, "#createAudioRecord");
+        }
+        try {
+            AudioRecord audioRecord = new AudioRecord(
+                    new AudioAttributes.Builder().setHotwordMode().build(),
+                    audioFormat,
+                    getBufferSizeInBytes(
+                            audioFormat.getSampleRate(),
+                            MICROPHONE_BUFFER_LENGTH_SECONDS,
+                            audioFormat.getChannelCount()),
+                    AudioManager.AUDIO_SESSION_ID_GENERATE);
+
+            if (audioRecord.getState() != AudioRecord.STATE_INITIALIZED) {
+                Slog.w(TAG, "Failed to initialize AudioRecord");
+                audioRecord.release();
+                return null;
+            }
+
+            return audioRecord;
+        } catch (IllegalArgumentException e) {
+            Slog.e(TAG, "Failed to create AudioRecord", e);
+            return null;
+        }
+    }
+
     /**
      * Returns the number of bytes required to store {@code bufferLengthSeconds} of audio sampled at
      * {@code sampleRate} Hz, using the format returned by DSP audio capture.
      */
-    private static int getBufferSizeInBytes(int sampleRate, int bufferLengthSeconds) {
-        return BYTES_PER_SAMPLE * sampleRate * bufferLengthSeconds;
+    private static int getBufferSizeInBytes(
+            int sampleRate, int bufferLengthSeconds, int intChannelCount) {
+        return BYTES_PER_SAMPLE * sampleRate * bufferLengthSeconds * intChannelCount;
     }
 
     private static Pair<ParcelFileDescriptor, ParcelFileDescriptor> createPipe() {
@@ -308,17 +411,176 @@
         return Pair.create(fileDescriptors[0], fileDescriptors[1]);
     }
 
-    private static void bestEffortCloseFileDescriptor(ParcelFileDescriptor fd) {
-        try {
-            fd.close();
-        } catch (IOException e) {
-            if (DEBUG) {
-                Slog.w(TAG, "Failed closing file descriptor", e);
-            }
+    public void dump(String prefix, PrintWriter pw) {
+        pw.print(prefix); pw.print("mBound="); pw.println(mBound);
+    }
+
+    private interface AudioReader extends Closeable {
+        int read(byte[] dest, int offset, int length) throws IOException;
+
+        static AudioReader createFromInputStream(InputStream is) {
+            return new AudioReader() {
+                @Override
+                public int read(byte[] dest, int offset, int length) throws IOException {
+                    return is.read(dest, offset, length);
+                }
+
+                @Override
+                public void close() throws IOException {
+                    is.close();
+                }
+            };
+        }
+
+        static AudioReader createFromAudioRecord(AudioRecord record) {
+            record.startRecording();
+
+            return new AudioReader() {
+                @Override
+                public int read(byte[] dest, int offset, int length) throws IOException {
+                    return record.read(dest, offset, length);
+                }
+
+                @Override
+                public void close() throws IOException {
+                    record.stop();
+                    record.release();
+                }
+            };
         }
     }
 
-    public void dump(String prefix, PrintWriter pw) {
-        pw.print(prefix); pw.print("mBound="); pw.println(mBound);
+    private void handleSoftwareHotwordDetection(
+            AudioFormat audioFormat,
+            AudioReader audioSource,
+            int audioSourceValue,
+            @Nullable PersistableBundle options,
+            IMicrophoneHotwordDetectionVoiceInteractionCallback callback) {
+        Pair<ParcelFileDescriptor, ParcelFileDescriptor> clientPipe = createPipe();
+
+        if (clientPipe == null) {
+            // TODO: Need to propagate as unknown error or something?
+            return;
+        }
+        ParcelFileDescriptor serviceAudioSink = clientPipe.second;
+        ParcelFileDescriptor serviceAudioSource = clientPipe.first;
+
+        synchronized (mLock) {
+            mCurrentAudioSink = serviceAudioSink;
+        }
+
+        mAudioCopyExecutor.execute(() -> {
+            try (AudioReader source = audioSource;
+                 OutputStream fos =
+                         new ParcelFileDescriptor.AutoCloseOutputStream(serviceAudioSink)) {
+                byte[] buffer = new byte[1024];
+
+                while (true) {
+                    int bytesRead = source.read(buffer, 0, 1024);
+
+                    if (bytesRead < 0) {
+                        break;
+                    }
+
+                    // TODO: First write to ring buffer to make sure we don't lose data if the next
+                    // statement fails.
+                    // ringBuffer.append(buffer, bytesRead);
+                    fos.write(buffer, 0, bytesRead);
+                }
+            } catch (IOException e) {
+                Slog.w(TAG, "Failed supplying audio data to validator", e);
+            } finally {
+                synchronized (mLock) {
+                    mCurrentAudioSink = null;
+                }
+            }
+        });
+
+        // TODO: handle cancellations well
+        // TODO: what if we cancelled and started a new one?
+        mRemoteHotwordDetectionService.run(
+                service -> service.detectFromMicrophoneSource(
+                        serviceAudioSource,
+                        // TODO: consider making a proxy callback + copy of audio format
+                        audioSourceValue, audioFormat, options,
+                        new IDspHotwordDetectionCallback.Stub() {
+                            @Override
+                            public void onRejected(@Nullable HotwordRejectedResult result)
+                                    throws RemoteException {
+                                // TODO: Propagate the HotwordRejectedResult.
+                            }
+
+                            @Override
+                            public void onDetected(@Nullable HotwordDetectedResult triggerResult)
+                                    throws RemoteException {
+                                // Stop
+                                bestEffortClose(serviceAudioSink);
+
+                                if (audioSourceValue == AUDIO_SOURCE_EXTERNAL) {
+                                    callback.onDetected(triggerResult, null, null);
+                                    // TODO: Add a delay before closing.
+                                    bestEffortClose(audioSource);
+                                }
+
+                                Pair<ParcelFileDescriptor, ParcelFileDescriptor> clientPipe =
+                                        createPipe();
+
+                                if (clientPipe == null) {
+                                    // Error.
+                                    // Need to propagate as unknown error or something?
+                                    return;
+                                }
+                                ParcelFileDescriptor callbackAudioSink = clientPipe.second;
+                                ParcelFileDescriptor callbackClientRead = clientPipe.first;
+
+                                mAudioCopyExecutor.execute(() -> {
+                                    try (AudioReader source = audioSource;
+                                         OutputStream fos =
+                                                 new ParcelFileDescriptor.AutoCloseOutputStream(
+                                                         callbackAudioSink)) {
+
+                                        // TODO: get ring buffer suffix here
+                                        // fos.write(lastSeveralSeconds);
+
+                                        byte[] buffer = new byte[1024];
+                                        while (true) {
+                                            int bytesRead = source.read(buffer, 0, 1024);
+
+                                            if (bytesRead < 0) {
+                                                break;
+                                            }
+
+                                            fos.write(buffer, 0, bytesRead);
+                                        }
+                                    } catch (IOException e) {
+                                        Slog.w(TAG, "Failed supplying audio data to validator", e);
+                                    } finally {
+                                        synchronized (mLock) {
+                                            mCurrentAudioSink = null;
+                                        }
+                                    }
+                                });
+
+                                // TODO: noteOp here.
+                                // Remove hotword offset from trigger result
+                                // TODO: consider propagating only capture session.
+                                callback.onDetected(triggerResult, null, callbackClientRead);
+                                // TODO: Add a delay before closing.
+                                bestEffortClose(callbackClientRead);
+                            }
+                        }));
+
+        // TODO: verify this is the right thing to do here.
+        bestEffortClose(serviceAudioSource);
+    }
+
+    private static void bestEffortClose(Closeable closeable) {
+        try {
+            closeable.close();
+        } catch (IOException e) {
+            if (DEBUG) {
+                Slog.w(TAG, "Failed closing", e);
+            }
+        }
     }
 };
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/RecognitionServiceInfo.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/RecognitionServiceInfo.java
new file mode 100644
index 0000000..05d4b93
--- /dev/null
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/RecognitionServiceInfo.java
@@ -0,0 +1,148 @@
+/*
+ * 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.voiceinteraction;
+
+import android.annotation.NonNull;
+import android.annotation.UserIdInt;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
+import android.speech.RecognitionService;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.Xml;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+// TODO: Move this class somewhere else, along with the default recognizer logic in
+//  VoiceInteractionManagerService.
+// TODO: Use this class in com.android.settings.applications.assist.VoiceInputHelper.
+
+/**
+ * {@link ServiceInfo} and parsed metadata for a {@link RecognitionService}.
+ */
+class RecognitionServiceInfo {
+    private static final String TAG = "RecognitionServiceInfo";
+
+    private final String mParseError;
+    private final ServiceInfo mServiceInfo;
+    private final boolean mSelectableAsDefault;
+
+    /**
+     * Queries the valid recognition services available for the user.
+     */
+    static List<RecognitionServiceInfo> getAvailableServices(
+            @NonNull Context context, @UserIdInt int user) {
+        List<RecognitionServiceInfo> services = new ArrayList<>();
+
+        List<ResolveInfo> resolveInfos =
+                context.getPackageManager().queryIntentServicesAsUser(
+                        new Intent(RecognitionService.SERVICE_INTERFACE),
+                        PackageManager.MATCH_DIRECT_BOOT_AWARE
+                                | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
+                        user);
+        for (ResolveInfo resolveInfo : resolveInfos) {
+            RecognitionServiceInfo service =
+                    parseInfo(context.getPackageManager(), resolveInfo.serviceInfo);
+            if (!TextUtils.isEmpty(service.mParseError)) {
+                Log.w(TAG, "Parse error in getAvailableServices: " + service.mParseError);
+                // We still use the recognizer to preserve pre-existing behavior.
+            }
+            services.add(service);
+        }
+        return services;
+    }
+
+    /**
+     * Loads the service metadata published by the component. Success is indicated by {@link
+     * #getParseError()}.
+     *
+     * @param pm A PackageManager from which the XML can be loaded; usually the
+     *         PackageManager from which {@code si} was originally retrieved.
+     * @param si The {@link android.speech.RecognitionService} info.
+     */
+    static RecognitionServiceInfo parseInfo(@NonNull PackageManager pm, @NonNull ServiceInfo si) {
+        String parseError = "";
+        boolean selectableAsDefault = true; // default
+        try (XmlResourceParser parser = si.loadXmlMetaData(
+                pm,
+                RecognitionService.SERVICE_META_DATA)) {
+            if (parser == null) {
+                parseError = "No " + RecognitionService.SERVICE_META_DATA
+                        + " meta-data for " + si.packageName;
+                return new RecognitionServiceInfo(si, selectableAsDefault, parseError);
+            }
+            Resources res = pm.getResourcesForApplication(si.applicationInfo);
+            AttributeSet attrs = Xml.asAttributeSet(parser);
+
+            int type = 0;
+            while (type != XmlPullParser.END_DOCUMENT && type != XmlPullParser.START_TAG) {
+                type = parser.next();
+            }
+
+            String nodeName = parser.getName();
+            if (!"recognition-service".equals(nodeName)) {
+                throw new XmlPullParserException(
+                        "Meta-data does not start with recognition-service tag");
+            }
+
+            TypedArray values =
+                    res.obtainAttributes(
+                            attrs, com.android.internal.R.styleable.RecognitionService);
+            selectableAsDefault =
+                    values.getBoolean(
+                            com.android.internal.R.styleable.RecognitionService_selectableAsDefault,
+                            selectableAsDefault);
+            values.recycle();
+        } catch (XmlPullParserException | IOException | PackageManager.NameNotFoundException e) {
+            parseError = "Error parsing recognition service meta-data: " + e;
+        }
+        return new RecognitionServiceInfo(si, selectableAsDefault, parseError);
+    }
+
+    private RecognitionServiceInfo(
+            @NonNull ServiceInfo si, boolean selectableAsDefault, @NonNull String parseError) {
+        mServiceInfo = si;
+        mSelectableAsDefault = selectableAsDefault;
+        mParseError = parseError;
+    }
+
+    @NonNull
+    public String getParseError() {
+        return mParseError;
+    }
+
+    @NonNull
+    public ServiceInfo getServiceInfo() {
+        return mServiceInfo;
+    }
+
+    public boolean isSelectableAsDefault() {
+        return mSelectableAsDefault;
+    }
+}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index 80d4f8f..ccaeaf9 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -48,6 +48,7 @@
 import android.hardware.soundtrigger.SoundTrigger.ModelParamRange;
 import android.hardware.soundtrigger.SoundTrigger.ModuleProperties;
 import android.hardware.soundtrigger.SoundTrigger.RecognitionConfig;
+import android.media.AudioFormat;
 import android.media.permission.Identity;
 import android.media.permission.PermissionUtil;
 import android.media.permission.SafeCloseable;
@@ -56,6 +57,8 @@
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Parcel;
+import android.os.ParcelFileDescriptor;
+import android.os.PersistableBundle;
 import android.os.RemoteCallback;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
@@ -65,12 +68,12 @@
 import android.os.Trace;
 import android.os.UserHandle;
 import android.provider.Settings;
+import android.service.voice.IMicrophoneHotwordDetectionVoiceInteractionCallback;
 import android.service.voice.IVoiceInteractionSession;
 import android.service.voice.VoiceInteractionManagerInternal;
 import android.service.voice.VoiceInteractionService;
 import android.service.voice.VoiceInteractionServiceInfo;
 import android.service.voice.VoiceInteractionSession;
-import android.speech.RecognitionService;
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
@@ -102,6 +105,7 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.lang.ref.WeakReference;
+import java.util.ArrayList;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.ListIterator;
@@ -403,9 +407,30 @@
                 ComponentName curInteractor = !TextUtils.isEmpty(curInteractorStr)
                         ? ComponentName.unflattenFromString(curInteractorStr) : null;
                 try {
-                    recognizerInfo = pm.getServiceInfo(curRecognizer,
+                    recognizerInfo = pm.getServiceInfo(
+                            curRecognizer,
                             PackageManager.MATCH_DIRECT_BOOT_AWARE
-                                    | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, userHandle);
+                                    | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
+                                    | PackageManager.GET_META_DATA,
+                            userHandle);
+                    if (recognizerInfo != null) {
+                        RecognitionServiceInfo rsi =
+                                RecognitionServiceInfo.parseInfo(
+                                        mContext.getPackageManager(), recognizerInfo);
+                        if (!TextUtils.isEmpty(rsi.getParseError())) {
+                            Log.w(TAG, "Parse error in getAvailableServices: "
+                                    + rsi.getParseError());
+                            // We still use the recognizer to preserve pre-existing behavior.
+                        }
+                        if (!rsi.isSelectableAsDefault()) {
+                            if (DEBUG) {
+                                Slog.d(TAG, "Found non selectableAsDefault recognizer as"
+                                        + " default. Unsetting the default and looking for another"
+                                        + " one.");
+                            }
+                            recognizerInfo = null;
+                        }
+                    }
                     if (curInteractor != null) {
                         interactorInfo = pm.getServiceInfo(curInteractor,
                                 PackageManager.MATCH_DIRECT_BOOT_AWARE
@@ -649,19 +674,23 @@
                 prefPackage = getDefaultRecognizer();
             }
 
-            List<ResolveInfo> available =
-                    mContext.getPackageManager().queryIntentServicesAsUser(
-                            new Intent(RecognitionService.SERVICE_INTERFACE),
-                            PackageManager.MATCH_DIRECT_BOOT_AWARE
-                                    | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, userHandle);
-            int numAvailable = available.size();
-            if (numAvailable == 0) {
+            List<RecognitionServiceInfo> available =
+                    RecognitionServiceInfo.getAvailableServices(mContext, userHandle);
+            if (available.size() == 0) {
                 Slog.w(TAG, "no available voice recognition services found for user " + userHandle);
                 return null;
             } else {
+                List<RecognitionServiceInfo> nonSelectableAsDefault =
+                        removeNonSelectableAsDefault(available);
+                if (available.size() == 0) {
+                    Slog.w(TAG, "No selectableAsDefault recognition services found for user "
+                            + userHandle + ". Falling back to non selectableAsDefault ones.");
+                    available = nonSelectableAsDefault;
+                }
+                int numAvailable = available.size();
                 if (prefPackage != null) {
-                    for (int i=0; i<numAvailable; i++) {
-                        ServiceInfo serviceInfo = available.get(i).serviceInfo;
+                    for (int i = 0; i < numAvailable; i++) {
+                        ServiceInfo serviceInfo = available.get(i).getServiceInfo();
                         if (prefPackage.equals(serviceInfo.packageName)) {
                             return new ComponentName(serviceInfo.packageName, serviceInfo.name);
                         }
@@ -671,11 +700,22 @@
                     Slog.w(TAG, "more than one voice recognition service found, picking first");
                 }
 
-                ServiceInfo serviceInfo = available.get(0).serviceInfo;
+                ServiceInfo serviceInfo = available.get(0).getServiceInfo();
                 return new ComponentName(serviceInfo.packageName, serviceInfo.name);
             }
         }
 
+        private List<RecognitionServiceInfo> removeNonSelectableAsDefault(
+                List<RecognitionServiceInfo> services) {
+            List<RecognitionServiceInfo> nonSelectableAsDefault = new ArrayList<>();
+            for (int i = services.size() - 1; i >= 0; i--) {
+                if (!services.get(i).isSelectableAsDefault()) {
+                    nonSelectableAsDefault.add(services.remove(i));
+                }
+            }
+            return nonSelectableAsDefault;
+        }
+
         @Nullable
         public String getDefaultRecognizer() {
             String recognizer = mContext.getString(R.string.config_systemSpeechRecognizer);
@@ -982,22 +1022,22 @@
             }
         }
 
+        //----------------- Hotword Detection/Validation APIs --------------------------------//
+
         @Override
-        public void setHotwordDetectionServiceConfig(@Nullable Bundle options,
-                @Nullable SharedMemory sharedMemory) {
+        public void updateState(@Nullable PersistableBundle options,
+                @Nullable SharedMemory sharedMemory, IHotwordRecognitionStatusCallback callback) {
             enforceCallingPermission(Manifest.permission.MANAGE_HOTWORD_DETECTION);
             synchronized (this) {
                 enforceIsCurrentVoiceInteractionService();
 
                 if (mImpl == null) {
-                    Slog.w(TAG,
-                            "setHotwordDetectionServiceConfig without running voice"
-                                    + " interaction service");
+                    Slog.w(TAG, "updateState without running voice interaction service");
                     return;
                 }
                 final long caller = Binder.clearCallingIdentity();
                 try {
-                    mImpl.setHotwordDetectionServiceConfigLocked(options, sharedMemory);
+                    mImpl.updateStateLocked(options, sharedMemory, callback);
                 } finally {
                     Binder.restoreCallingIdentity(caller);
                 }
@@ -1024,6 +1064,72 @@
             }
         }
 
+        @Override
+        public void startListeningFromMic(
+                AudioFormat audioFormat,
+                IMicrophoneHotwordDetectionVoiceInteractionCallback callback)
+                throws RemoteException {
+            enforceCallingPermission(Manifest.permission.RECORD_AUDIO);
+            enforceCallingPermission(Manifest.permission.CAPTURE_AUDIO_HOTWORD);
+            synchronized (this) {
+                enforceIsCurrentVoiceInteractionService();
+
+                if (mImpl == null) {
+                    Slog.w(TAG, "startListeningFromMic without running voice interaction service");
+                    return;
+                }
+                final long caller = Binder.clearCallingIdentity();
+                try {
+                    mImpl.startListeningFromMicLocked(audioFormat, callback);
+                } finally {
+                    Binder.restoreCallingIdentity(caller);
+                }
+            }
+        }
+
+        @Override
+        public void startListeningFromExternalSource(
+                ParcelFileDescriptor audioStream,
+                AudioFormat audioFormat,
+                PersistableBundle options,
+                IMicrophoneHotwordDetectionVoiceInteractionCallback callback)
+                throws RemoteException {
+            synchronized (this) {
+                enforceIsCurrentVoiceInteractionService();
+
+                if (mImpl == null) {
+                    Slog.w(TAG, "startListeningFromExternalSource without running voice"
+                            + " interaction service");
+                    return;
+                }
+                final long caller = Binder.clearCallingIdentity();
+                try {
+                    mImpl.startListeningFromExternalSourceLocked(
+                            audioStream, audioFormat, options, callback);
+                } finally {
+                    Binder.restoreCallingIdentity(caller);
+                }
+            }
+        }
+
+        @Override
+        public void stopListeningFromMic() throws RemoteException {
+            synchronized (this) {
+                enforceIsCurrentVoiceInteractionService();
+
+                if (mImpl == null) {
+                    Slog.w(TAG, "stopListeningFromMic without running voice interaction service");
+                    return;
+                }
+                final long caller = Binder.clearCallingIdentity();
+                try {
+                    mImpl.stopListeningFromMicLocked();
+                } finally {
+                    Binder.restoreCallingIdentity(caller);
+                }
+            }
+        }
+
         //----------------- Model management APIs --------------------------------//
 
         @Override
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
index 05573f1..6922ccc 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
@@ -27,6 +27,7 @@
 import android.app.ActivityManager;
 import android.app.ActivityOptions;
 import android.app.ActivityTaskManager;
+import android.app.AppGlobals;
 import android.app.IActivityManager;
 import android.app.IActivityTaskManager;
 import android.content.BroadcastReceiver;
@@ -35,22 +36,27 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.ServiceConnection;
+import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
+import android.content.pm.ServiceInfo;
 import android.hardware.soundtrigger.IRecognitionStatusCallback;
+import android.media.AudioFormat;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
+import android.os.PersistableBundle;
 import android.os.RemoteCallback;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SharedMemory;
 import android.os.UserHandle;
+import android.service.voice.IMicrophoneHotwordDetectionVoiceInteractionCallback;
 import android.service.voice.IVoiceInteractionService;
 import android.service.voice.IVoiceInteractionSession;
 import android.service.voice.VoiceInteractionService;
 import android.service.voice.VoiceInteractionServiceInfo;
 import android.system.OsConstants;
-import android.util.Pair;
 import android.util.PrintWriterPrinter;
 import android.util.Slog;
 import android.view.IWindowManager;
@@ -60,6 +66,7 @@
 import com.android.internal.app.IVoiceInteractionSessionShowCallback;
 import com.android.internal.app.IVoiceInteractor;
 import com.android.server.LocalServices;
+import com.android.server.wm.ActivityAssistInfo;
 import com.android.server.wm.ActivityTaskManagerInternal;
 import com.android.server.wm.ActivityTaskManagerInternal.ActivityTokens;
 
@@ -167,12 +174,8 @@
         mSessionComponentName = new ComponentName(service.getPackageName(),
                 mInfo.getSessionService());
         final String hotwordDetectionServiceName = mInfo.getHotwordDetectionService();
-        if (hotwordDetectionServiceName != null) {
-            mHotwordDetectionComponentName = new ComponentName(service.getPackageName(),
-                    hotwordDetectionServiceName);
-        } else {
-            mHotwordDetectionComponentName = null;
-        }
+        mHotwordDetectionComponentName = hotwordDetectionServiceName != null
+                ? new ComponentName(service.getPackageName(), hotwordDetectionServiceName) : null;
         mIWindowManager = IWindowManager.Stub.asInterface(
                 ServiceManager.getService(Context.WINDOW_SERVICE));
         IntentFilter filter = new IntentFilter();
@@ -187,24 +190,23 @@
                     mSessionComponentName, mUser, mContext, this,
                     mInfo.getServiceInfo().applicationInfo.uid, mHandler);
         }
-        List<Pair<IBinder, Integer>> allVisibleActivities =
+        List<ActivityAssistInfo> allVisibleActivities =
                 LocalServices.getService(ActivityTaskManagerInternal.class)
                         .getTopVisibleActivities();
 
-        List<Pair<IBinder, Integer>> visibleActivities = null;
+        List<ActivityAssistInfo> visibleActivities = null;
         if (activityToken != null) {
             visibleActivities = new ArrayList();
             int activitiesCount = allVisibleActivities.size();
             for (int i = 0; i < activitiesCount; i++) {
-                if (allVisibleActivities.get(i).first == activityToken) {
-                    visibleActivities.add(
-                            new Pair<>(activityToken, allVisibleActivities.get(i).second));
+                ActivityAssistInfo info = allVisibleActivities.get(i);
+                if (info.getActivityToken() == activityToken) {
+                    visibleActivities.add(info);
                     break;
                 }
             }
         } else {
-            visibleActivities = LocalServices.getService(ActivityTaskManagerInternal.class)
-                    .getTopVisibleActivities();
+            visibleActivities = allVisibleActivities;
         }
         return mActiveSession.showLocked(args, flags, mDisabledShowContext, showCallback,
                 visibleActivities);
@@ -402,10 +404,10 @@
         return mInfo.getSupportsLocalInteraction();
     }
 
-    public void setHotwordDetectionServiceConfigLocked(@Nullable Bundle options,
-            @Nullable SharedMemory sharedMemory) {
+    public void updateStateLocked(@Nullable PersistableBundle options,
+            @Nullable SharedMemory sharedMemory, IHotwordRecognitionStatusCallback callback) {
         if (DEBUG) {
-            Slog.d(TAG, "setHotwordDetectionServiceConfigLocked");
+            Slog.d(TAG, "updateStateLocked");
         }
         if (mHotwordDetectionComponentName == null) {
             Slog.w(TAG, "Hotword detection service name not found");
@@ -416,7 +418,6 @@
             throw new IllegalStateException("Hotword detection service not in isolated process");
         }
         // TODO : Need to check related permissions for hotword detection service
-        // TODO : Sanitize for bundle
 
         if (sharedMemory != null && !sharedMemory.setProtect(OsConstants.PROT_READ)) {
             Slog.w(TAG, "Can't set sharedMemory to be read-only");
@@ -426,9 +427,9 @@
         if (mHotwordDetectionConnection == null) {
             mHotwordDetectionConnection = new HotwordDetectionConnection(mServiceStub, mContext,
                     mHotwordDetectionComponentName, mUser, /* bindInstantServiceAllowed= */ false,
-                    options, sharedMemory);
+                    options, sharedMemory, callback);
         } else {
-            mHotwordDetectionConnection.setConfigLocked(options, sharedMemory);
+            mHotwordDetectionConnection.updateStateLocked(options, sharedMemory);
         }
     }
 
@@ -446,6 +447,52 @@
         mHotwordDetectionConnection = null;
     }
 
+    public void startListeningFromMicLocked(
+            AudioFormat audioFormat,
+            IMicrophoneHotwordDetectionVoiceInteractionCallback callback) {
+        if (DEBUG) {
+            Slog.d(TAG, "startListeningFromMic");
+        }
+
+        if (mHotwordDetectionConnection == null) {
+            // TODO: callback.onError();
+            return;
+        }
+
+        mHotwordDetectionConnection.startListeningFromMic(audioFormat, callback);
+    }
+
+    public void startListeningFromExternalSourceLocked(
+            ParcelFileDescriptor audioStream,
+            AudioFormat audioFormat,
+            @Nullable PersistableBundle options,
+            IMicrophoneHotwordDetectionVoiceInteractionCallback callback) {
+        if (DEBUG) {
+            Slog.d(TAG, "startListeningFromExternalSource");
+        }
+
+        if (mHotwordDetectionConnection == null) {
+            // TODO: callback.onError();
+            return;
+        }
+
+        mHotwordDetectionConnection
+                .startListeningFromExternalSource(audioStream, audioFormat, options, callback);
+    }
+
+    public void stopListeningFromMicLocked() {
+        if (DEBUG) {
+            Slog.d(TAG, "stopListeningFromMic");
+        }
+
+        if (mHotwordDetectionConnection == null) {
+            Slog.w(TAG, "stopListeningFromMic() called but connection isn't established");
+            return;
+        }
+
+        mHotwordDetectionConnection.stopListening();
+    }
+
     public IRecognitionStatusCallback createSoundTriggerCallbackLocked(
             IHotwordRecognitionStatusCallback callback) {
         if (DEBUG) {
@@ -456,8 +503,22 @@
     }
 
     boolean isIsolatedProcessLocked(ComponentName componentName) {
-        // TODO : Need to make sure this component exists and is :isolated.
-        return true;
+        IPackageManager pm = AppGlobals.getPackageManager();
+        try {
+            ServiceInfo serviceInfo = pm.getServiceInfo(componentName,
+                    PackageManager.GET_META_DATA
+                            | PackageManager.MATCH_DIRECT_BOOT_AWARE
+                            | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, mUser);
+            if (serviceInfo != null) {
+                return (serviceInfo.flags & ServiceInfo.FLAG_ISOLATED_PROCESS) != 0
+                        && (serviceInfo.flags & ServiceInfo.FLAG_EXTERNAL_SERVICE) == 0;
+            }
+        } catch (RemoteException e) {
+            if (DEBUG) {
+                Slog.w(TAG, "isIsolatedProcess RemoteException : " + e);
+            }
+        }
+        return false;
     }
 
     public void dumpLocked(FileDescriptor fd, PrintWriter pw, String[] args) {
@@ -476,6 +537,7 @@
         pw.println("  Service info:");
         mInfo.getServiceInfo().dump(new PrintWriterPrinter(pw), "    ");
         pw.print("  Recognition service="); pw.println(mInfo.getRecognitionService());
+        pw.print("  Hotword detection service="); pw.println(mInfo.getHotwordDetectionService());
         pw.print("  Settings activity="); pw.println(mInfo.getSettingsActivity());
         pw.print("  Supports assist="); pw.println(mInfo.getSupportsAssist());
         pw.print("  Supports launch from keyguard=");
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
index 428d342..cc021a9 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
@@ -56,7 +56,6 @@
 import android.service.voice.IVoiceInteractionSessionService;
 import android.service.voice.VoiceInteractionService;
 import android.service.voice.VoiceInteractionSession;
-import android.util.Pair;
 import android.util.Slog;
 import android.view.IWindowManager;
 
@@ -68,6 +67,7 @@
 import com.android.server.am.AssistDataRequester.AssistDataRequesterCallbacks;
 import com.android.server.statusbar.StatusBarManagerInternal;
 import com.android.server.uri.UriGrantsManagerInternal;
+import com.android.server.wm.ActivityAssistInfo;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -102,6 +102,7 @@
     IVoiceInteractionSession mSession;
     IVoiceInteractor mInteractor;
     ArrayList<IVoiceInteractionSessionShowCallback> mPendingShowCallbacks = new ArrayList<>();
+    private List<ActivityAssistInfo> mPendingHandleAssistWithoutData = new ArrayList<>();
     AssistDataRequester mAssistDataRequester;
 
     IVoiceInteractionSessionShowCallback mShowCallback =
@@ -192,7 +193,7 @@
 
     public boolean showLocked(Bundle args, int flags, int disabledContext,
             IVoiceInteractionSessionShowCallback showCallback,
-            List<Pair<IBinder, Integer>> topActivities) {
+            List<ActivityAssistInfo> topActivities) {
         if (mBound) {
             if (!mFullyBound) {
                 mFullyBound = mContext.bindServiceAsUser(mBindIntent, mFullConnection,
@@ -216,7 +217,7 @@
                 int topActivitiesCount = topActivities.size();
                 final ArrayList<IBinder> topActivitiesToken = new ArrayList<>(topActivitiesCount);
                 for (int i = 0; i < topActivitiesCount; i++) {
-                    topActivitiesToken.add(topActivities.get(i).first);
+                    topActivitiesToken.add(topActivities.get(i).getActivityToken());
                 }
                 mAssistDataRequester.requestAssistData(topActivitiesToken,
                         fetchData,
@@ -243,8 +244,16 @@
                 } else {
                     doHandleAssistWithoutData(topActivities);
                 }
-            } else if (showCallback != null) {
-                mPendingShowCallbacks.add(showCallback);
+            } else {
+                if (showCallback != null) {
+                    mPendingShowCallbacks.add(showCallback);
+                }
+                if (!assistDataRequestNeeded) {
+                    // If no data are required we are not passing trough mAssistDataRequester. As
+                    // a consequence, when a new session is delivered it is needed to process those
+                    // requests manually.
+                    mPendingHandleAssistWithoutData = topActivities;
+                }
             }
             mCallback.onSessionShown(this);
             return true;
@@ -258,17 +267,17 @@
         return false;
     }
 
-    private void doHandleAssistWithoutData(List<Pair<IBinder, Integer>> topActivities) {
+    private void doHandleAssistWithoutData(List<ActivityAssistInfo> topActivities) {
         final int activityCount = topActivities.size();
         for (int i = 0; i < activityCount; i++) {
-            final Pair<IBinder, Integer> topActivity = topActivities.get(i);
-            final IBinder activityId = topActivity.first;
-            final int taskId = topActivity.second;
+            final ActivityAssistInfo topActivity = topActivities.get(i);
+            final IBinder assistToken = topActivity.getAssistToken();
+            final int taskId = topActivity.getTaskId();
             final int activityIndex = i;
             try {
                 mSession.handleAssist(
                         taskId,
-                        activityId,
+                        assistToken,
                         /* assistData = */ null,
                         /* assistStructure = */ null,
                         /* assistContent = */ null,
@@ -468,6 +477,10 @@
             } catch (RemoteException e) {
             }
             mAssistDataRequester.processPendingAssistData();
+            if (!mPendingHandleAssistWithoutData.isEmpty()) {
+                doHandleAssistWithoutData(mPendingHandleAssistWithoutData);
+                mPendingHandleAssistWithoutData.clear();
+            }
         }
         return true;
     }
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index 2a5ddfd..d77ab2b 100755
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -138,6 +138,27 @@
     public static final int STATE_SIMULATED_RINGING = 13;
 
     /**
+     * @hide
+     */
+    @IntDef(prefix = { "STATE_" },
+            value = {
+                    STATE_NEW,
+                    STATE_DIALING,
+                    STATE_RINGING,
+                    STATE_HOLDING,
+                    STATE_ACTIVE,
+                    STATE_DISCONNECTED,
+                    STATE_SELECT_PHONE_ACCOUNT,
+                    STATE_CONNECTING,
+                    STATE_DISCONNECTING,
+                    STATE_PULLING_CALL,
+                    STATE_AUDIO_PROCESSING,
+                    STATE_SIMULATED_RINGING
+            })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface CallState {};
+
+    /**
      * The key to retrieve the optional {@code PhoneAccount}s Telecom can bundle with its Call
      * extras. Used to pass the phone accounts to display on the front end to the user in order to
      * select phone accounts to (for example) place a call.
@@ -666,7 +687,11 @@
         public static final int PROPERTY_IS_ADHOC_CONFERENCE = 0x00002000;
 
         /**
-         * Connection is using Cross SIM Calling.
+         * Connection is using cross sim technology.
+         * <p>
+         * Indicates that the {@link Connection} is using a cross sim technology which would
+         * register IMS over internet APN of default data subscription.
+         * <p>
          */
         public static final int PROPERTY_CROSS_SIM = 0x00004000;
 
@@ -674,6 +699,7 @@
         // Next PROPERTY value: 0x00004000
         //******************************************************************************************
 
+        private final @CallState int mState;
         private final String mTelecomCallId;
         private final Uri mHandle;
         private final int mHandlePresentation;
@@ -868,6 +894,13 @@
             return builder.toString();
         }
 
+        /**
+         * @return the state of the {@link Call} represented by this {@link Call.Details}.
+         */
+        public final @CallState int getState() {
+            return mState;
+        }
+
         /** {@hide} */
         @TestApi
         public String getTelecomCallId() {
@@ -1069,6 +1102,7 @@
             if (o instanceof Details) {
                 Details d = (Details) o;
                 return
+                        Objects.equals(mState, d.mState) &&
                         Objects.equals(mHandle, d.mHandle) &&
                         Objects.equals(mHandlePresentation, d.mHandlePresentation) &&
                         Objects.equals(mCallerDisplayName, d.mCallerDisplayName) &&
@@ -1095,7 +1129,8 @@
 
         @Override
         public int hashCode() {
-            return Objects.hash(mHandle,
+            return Objects.hash(mState,
+                            mHandle,
                             mHandlePresentation,
                             mCallerDisplayName,
                             mCallerDisplayNamePresentation,
@@ -1117,6 +1152,7 @@
 
         /** {@hide} */
         public Details(
+                @CallState int state,
                 String telecomCallId,
                 Uri handle,
                 int handlePresentation,
@@ -1136,6 +1172,7 @@
                 String contactDisplayName,
                 int callDirection,
                 int callerNumberVerificationStatus) {
+            mState = state;
             mTelecomCallId = telecomCallId;
             mHandle = handle;
             mHandlePresentation = handlePresentation;
@@ -1160,6 +1197,7 @@
         /** {@hide} */
         public static Details createFromParcelableCall(ParcelableCall parcelableCall) {
             return new Details(
+                    parcelableCall.getState(),
                     parcelableCall.getId(),
                     parcelableCall.getHandle(),
                     parcelableCall.getHandlePresentation(),
@@ -1186,6 +1224,8 @@
             StringBuilder sb = new StringBuilder();
             sb.append("[id: ");
             sb.append(mTelecomCallId);
+            sb.append(", state: ");
+            sb.append(Call.stateToString(mState));
             sb.append(", pa: ");
             sb.append(mAccountHandle);
             sb.append(", hdl: ");
@@ -1302,7 +1342,7 @@
          * @param call The {@code Call} invoking this method.
          * @param state The new state of the {@code Call}.
          */
-        public void onStateChanged(Call call, int state) {}
+        public void onStateChanged(Call call, @CallState int state) {}
 
         /**
          * Invoked when the parent of this {@code Call} has changed. See {@link #getParent()}.
@@ -2171,9 +2211,11 @@
     /**
      * Obtains the state of this {@code Call}.
      *
-     * @return A state value, chosen from the {@code STATE_*} constants.
+     * @return The call state.
+     * @deprecated The call state is available via {@link Call.Details#getState()}.
      */
-    public int getState() {
+    @Deprecated
+    public @CallState int getState() {
         return mState;
     }
 
@@ -2551,6 +2593,30 @@
     final void internalSetDisconnected() {
         if (mState != Call.STATE_DISCONNECTED) {
             mState = Call.STATE_DISCONNECTED;
+            if (mDetails != null) {
+                mDetails = new Details(mState,
+                        mDetails.getTelecomCallId(),
+                        mDetails.getHandle(),
+                        mDetails.getHandlePresentation(),
+                        mDetails.getCallerDisplayName(),
+                        mDetails.getCallerDisplayNamePresentation(),
+                        mDetails.getAccountHandle(),
+                        mDetails.getCallCapabilities(),
+                        mDetails.getCallProperties(),
+                        mDetails.getDisconnectCause(),
+                        mDetails.getConnectTimeMillis(),
+                        mDetails.getGatewayInfo(),
+                        mDetails.getVideoState(),
+                        mDetails.getStatusHints(),
+                        mDetails.getExtras(),
+                        mDetails.getIntentExtras(),
+                        mDetails.getCreationTimeMillis(),
+                        mDetails.getContactDisplayName(),
+                        mDetails.getCallDirection(),
+                        mDetails.getCallerNumberVerificationStatus()
+                        );
+                fireDetailsChanged(mDetails);
+            }
             fireStateChanged(mState);
             fireCallDestroyed();
         }
diff --git a/telecomm/java/android/telecom/ParcelableCall.java b/telecomm/java/android/telecom/ParcelableCall.java
index 182dc8b..320308c 100644
--- a/telecomm/java/android/telecom/ParcelableCall.java
+++ b/telecomm/java/android/telecom/ParcelableCall.java
@@ -399,7 +399,7 @@
     }
 
     /** The current state of the call. */
-    public int getState() {
+    public @Call.CallState int getState() {
         return mState;
     }
 
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 1677c8c..4886789 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -25,6 +25,8 @@
 import android.annotation.SuppressLint;
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledSince;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.ComponentName;
 import android.content.Context;
@@ -1004,6 +1006,17 @@
             PRESENTATION_PAYPHONE})
     public @interface Presentation {}
 
+
+    /**
+     * Enable READ_PHONE_STATE protection on APIs querying and notifying call state, such as
+     * {@code TelecomManager#getCallState}, {@link TelephonyManager#getCallStateForSubscription()},
+     * and {@link android.telephony.TelephonyCallback.CallStateListener}.
+     */
+    @ChangeId
+    @EnabledSince(targetSdkVersion = Build.VERSION_CODES.S)
+    // this magic number is a bug ID
+    public static final long ENABLE_GET_CALL_STATE_PERMISSION_PROTECTION = 157233955L;
+
     private static final String TAG = "TelecomManager";
 
 
@@ -1758,21 +1771,23 @@
      * {@link TelephonyManager#CALL_STATE_OFFHOOK}
      * {@link TelephonyManager#CALL_STATE_IDLE}
      *
-     * Note that this API does not require the
-     * {@link android.Manifest.permission#READ_PHONE_STATE} permission. This is intentional, to
-     * preserve the behavior of {@link TelephonyManager#getCallState()}, which also did not require
-     * the permission.
-     *
      * Takes into consideration both managed and self-managed calls.
+     * <p>
+     * Requires Permission:
+     * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} for applications
+     * targeting API level 31+.
      *
      * @hide
      */
+    @RequiresPermission(anyOf = {READ_PRIVILEGED_PHONE_STATE,
+            android.Manifest.permission.READ_PHONE_STATE}, conditional = true)
     @SystemApi
     public @CallState int getCallState() {
         ITelecomService service = getTelecomService();
         if (service != null) {
             try {
-                return service.getCallState();
+                return service.getCallStateUsingPackage(mContext.getPackageName(),
+                        mContext.getAttributionTag());
             } catch (RemoteException e) {
                 Log.d(TAG, "RemoteException calling getCallState().", e);
             }
diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
index 78283fa..18afde7 100644
--- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
+++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
@@ -195,11 +195,18 @@
 
     /**
      * @see TelecomServiceImpl#getCallState
+     * Note: only kept around to not break app compat, however this will throw a SecurityException
+     * on API 31+.
      */
     @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     int getCallState();
 
     /**
+     * @see TelecomServiceImpl#getCallState
+     */
+    int getCallStateUsingPackage(String callingPackage, String callingFeatureId);
+
+    /**
      * @see TelecomServiceImpl#endCall
      */
     boolean endCall(String callingPackage);
diff --git a/telephony/java/android/telephony/Annotation.java b/telephony/java/android/telephony/Annotation.java
index 4ae11b8..23cf511 100644
--- a/telephony/java/android/telephony/Annotation.java
+++ b/telephony/java/android/telephony/Annotation.java
@@ -447,6 +447,9 @@
             DataFailCause.VSNCP_RECONNECT_NOT_ALLOWED,
             DataFailCause.IPV6_PREFIX_UNAVAILABLE,
             DataFailCause.HANDOFF_PREFERENCE_CHANGED,
+            DataFailCause.SLICE_REJECTED,
+            DataFailCause.MATCH_ALL_RULE_NOT_ALLOWED,
+            DataFailCause.ALL_MATCHING_RULES_FAILED,
             DataFailCause.OEM_DCFAILCAUSE_1,
             DataFailCause.OEM_DCFAILCAUSE_2,
             DataFailCause.OEM_DCFAILCAUSE_3,
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 04a0aba..3db31ec 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -4254,6 +4254,14 @@
         public static final String KEY_NON_RCS_CAPABILITIES_CACHE_EXPIRATION_SEC_INT =
                 KEY_PREFIX + "non_rcs_capabilities_cache_expiration_sec_int";
 
+        /**
+         * Specifies the RCS feature tag allowed for the carrier.
+         *
+         * <p>The values refer to RCC.07 2.4.4.
+         */
+        public static final String KEY_RCS_FEATURE_TAG_ALLOWED_STRING_ARRAY =
+                KEY_PREFIX + "rcs_feature_tag_allowed_string_array";
+
         private Ims() {}
 
         private static PersistableBundle getDefaults() {
@@ -4267,6 +4275,27 @@
             defaults.putBoolean(KEY_RCS_BULK_CAPABILITY_EXCHANGE_BOOL, false);
             defaults.putBoolean(KEY_ENABLE_PRESENCE_GROUP_SUBSCRIBE_BOOL, true);
             defaults.putInt(KEY_NON_RCS_CAPABILITIES_CACHE_EXPIRATION_SEC_INT, 30 * 24 * 60 * 60);
+            defaults.putStringArray(KEY_RCS_FEATURE_TAG_ALLOWED_STRING_ARRAY, new String[]{
+                    "+g.3gpp.icsi-ref=\"urn%3Aurn-7%3A3gpp-service.ims.icsi.oma.cpm.msg\"",
+                    "+g.3gpp.icsi-ref=\"urn%3Aurn-7%3A3gpp-service.ims.icsi.oma.cpm.largemsg\"",
+                    "+g.3gpp.icsi-ref=\"urn%3Aurn-7%3A3gpp-service.ims.icsi.oma.cpm.deferred\"",
+                    "+g.gsma.rcs.cpm.pager-large",
+                    "+g.3gpp.icsi-ref=\"urn%3Aurn-7%3A3gpp-service.ims.icsi.oma.cpm.session\"",
+                    "+g.3gpp.icsi-ref=\"urn%3Aurn-7%3A3gpp-service.ims.icsi.oma.cpm.session\"",
+                    "+g.3gpp.iari-ref=\"urn%3Aurn-7%3A3gpp-application.ims.iari.rcs.fthttp\"",
+                    "+g.3gpp.iari-ref=\"urn%3Aurn-7%3A3gpp-application.ims.iari.rcs.ftsms\"",
+                    "+g.3gpp.iari-ref=\"urn%3Aurn-7%3A3gpp-service.ims.icsi.gsma.callcomposer\"",
+                    "+g.gsma.callcomposer",
+                    "+g.3gpp.icsi-ref=\"urn%3Aurn-7%3A3gpp-service.ims.icsi.gsma.callunanswered\"",
+                    "+g.3gpp.icsi-ref=\"urn%3Aurn-7%3A3gpp-service.ims.icsi.gsma.sharedmap\"",
+                    "+g.3gpp.icsi-ref=\"urn%3Aurn-7%3A3gpp-service.ims.icsi.gsma.sharedsketch\"",
+                    "+g.3gpp.iari-ref=\"urn%3Aurn-7%3A3gpp-application.ims.iari.rcs.geopush\"",
+                    "+g.3gpp.iari-ref=\"urn%3Aurn-7%3A3gpp-application.ims.iari.rcs.geosms\"",
+                    "+g.3gpp.iari-ref=\"urn%3Aurn-7%3A3gpp-application.ims.iari.rcs.chatbot\"",
+                    "+g.3gpp.iari-ref=\"urn%3Aurn-7%3A3gpp-application.ims.iari.rcs.chatbot.sa\"",
+                    "+g.gsma.rcs.botversion=\"#=1,#=2\"",
+                    "+g.gsma.rcs.cpimext"});
+
             return defaults;
         }
     }
@@ -4849,6 +4878,30 @@
     public static final String KEY_CARRIER_PROVISIONS_WIFI_MERGED_NETWORKS_BOOL =
             "carrier_provisions_wifi_merged_networks_bool";
 
+    /**
+     * Determines whether or not to use (IP) data connectivity as a supplemental condition to
+     * control the visibility of the no-calling indicator for this carrier in the System UI. Setting
+     * the configuration to true may make sense to a carrier which provides OTT calling.
+     *
+     * Config = true: do not show no-calling indication if (IP) data connectivity is available
+     *                or telephony has voice registration.
+     * Config = false: do not show no-calling indication if telephony has voice registration.
+     */
+    public static final String KEY_HIDE_NO_CALLING_INDICATOR_ON_DATA_NETWORK_BOOL =
+            "hide_no_calling_indicator_on_data_network_bool";
+
+    /**
+     * Determine whether or not to display a call strength indicator for this carrier in the System
+     * UI. Disabling the indication may be reasonable if the carrier's calling is not integrated
+     * into the Android telephony stack (e.g. it is OTT).
+     *
+     * true: Use telephony APIs to detect the current networking medium of calling and display a
+     *       UI indication based on the current strength (e.g. signal level) of that medium.
+     * false: Do not display the call strength indicator.
+     */
+    public static final String KEY_DISPLAY_CALL_STRENGTH_INDICATOR_BOOL =
+            "display_call_strength_indicator_bool";
+
     /** The default value for every variable. */
     private final static PersistableBundle sDefaults;
 
@@ -5422,6 +5475,8 @@
         sDefaults.putStringArray(KEY_ALLOWED_INITIAL_ATTACH_APN_TYPES_STRING_ARRAY,
                 new String[]{"ia", "default", "ims", "mms", "dun", "emergency"});
         sDefaults.putBoolean(KEY_CARRIER_PROVISIONS_WIFI_MERGED_NETWORKS_BOOL, false);
+        sDefaults.putBoolean(KEY_HIDE_NO_CALLING_INDICATOR_ON_DATA_NETWORK_BOOL, false);
+        sDefaults.putBoolean(KEY_DISPLAY_CALL_STRENGTH_INDICATOR_BOOL, true);
         sDefaults.putString(KEY_CARRIER_PROVISIONING_APP_STRING, "");
     }
 
diff --git a/telephony/java/android/telephony/DataSpecificRegistrationInfo.java b/telephony/java/android/telephony/DataSpecificRegistrationInfo.java
index 597fe8f..957f683 100644
--- a/telephony/java/android/telephony/DataSpecificRegistrationInfo.java
+++ b/telephony/java/android/telephony/DataSpecificRegistrationInfo.java
@@ -68,22 +68,22 @@
     public final boolean isEnDcAvailable;
 
     /**
-     * Provides network support info for LTE VoPS and LTE Emergency bearer support
+     * Provides network support info for VoPS and Emergency bearer support
      */
     @Nullable
-    private final LteVopsSupportInfo mLteVopsSupportInfo;
+    private final VopsSupportInfo mVopsSupportInfo;
 
     /**
      * @hide
      */
     DataSpecificRegistrationInfo(
             int maxDataCalls, boolean isDcNrRestricted, boolean isNrAvailable,
-            boolean isEnDcAvailable, @Nullable LteVopsSupportInfo lteVops) {
+            boolean isEnDcAvailable, @Nullable VopsSupportInfo vops) {
         this.maxDataCalls = maxDataCalls;
         this.isDcNrRestricted = isDcNrRestricted;
         this.isNrAvailable = isNrAvailable;
         this.isEnDcAvailable = isEnDcAvailable;
-        this.mLteVopsSupportInfo = lteVops;
+        this.mVopsSupportInfo = vops;
     }
 
     /**
@@ -97,7 +97,7 @@
         isDcNrRestricted = dsri.isDcNrRestricted;
         isNrAvailable = dsri.isNrAvailable;
         isEnDcAvailable = dsri.isEnDcAvailable;
-        mLteVopsSupportInfo = dsri.mLteVopsSupportInfo;
+        mVopsSupportInfo = dsri.mVopsSupportInfo;
     }
 
     private DataSpecificRegistrationInfo(/* @NonNull */ Parcel source) {
@@ -105,7 +105,7 @@
         isDcNrRestricted = source.readBoolean();
         isNrAvailable = source.readBoolean();
         isEnDcAvailable = source.readBoolean();
-        mLteVopsSupportInfo = LteVopsSupportInfo.CREATOR.createFromParcel(source);
+        mVopsSupportInfo = source.readParcelable(VopsSupportInfo.class.getClassLoader());
     }
 
     @Override
@@ -114,7 +114,7 @@
         dest.writeBoolean(isDcNrRestricted);
         dest.writeBoolean(isNrAvailable);
         dest.writeBoolean(isEnDcAvailable);
-        mLteVopsSupportInfo.writeToParcel(dest, flags);
+        dest.writeParcelable(mVopsSupportInfo, flags);
     }
 
     @Override
@@ -131,15 +131,15 @@
                 .append(" isDcNrRestricted = " + isDcNrRestricted)
                 .append(" isNrAvailable = " + isNrAvailable)
                 .append(" isEnDcAvailable = " + isEnDcAvailable)
-                .append(" " + mLteVopsSupportInfo)
+                .append(" " + mVopsSupportInfo)
                 .append(" }")
                 .toString();
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(maxDataCalls, isDcNrRestricted, isNrAvailable, isEnDcAvailable,
-                mLteVopsSupportInfo);
+        return Objects.hash(maxDataCalls, isDcNrRestricted, isNrAvailable,
+                isEnDcAvailable, mVopsSupportInfo);
     }
 
     @Override
@@ -153,7 +153,7 @@
                 && this.isDcNrRestricted == other.isDcNrRestricted
                 && this.isNrAvailable == other.isNrAvailable
                 && this.isEnDcAvailable == other.isEnDcAvailable
-                && Objects.equals(mLteVopsSupportInfo, other.mLteVopsSupportInfo);
+                && Objects.equals(mVopsSupportInfo, other.mVopsSupportInfo);
     }
 
     public static final @NonNull Parcelable.Creator<DataSpecificRegistrationInfo> CREATOR =
@@ -171,10 +171,26 @@
 
     /**
      * @return The LTE VOPS (Voice over Packet Switched) support information
+     *
+     * @deprecated use {@link #getVopsSupportInfo()}
      */
+    @Deprecated
     @NonNull
     public LteVopsSupportInfo getLteVopsSupportInfo() {
-        return mLteVopsSupportInfo;
+        return mVopsSupportInfo instanceof LteVopsSupportInfo
+                ? (LteVopsSupportInfo) mVopsSupportInfo
+                : new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE,
+                LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE);
     }
 
+    /**
+     * @return The VOPS (Voice over Packet Switched) support information.
+     *
+     * The instance of {@link LTEVopsSupportInfo}, or {@link NrVopsSupportInfo},
+     * null if there is there is no VOPS support information available.
+     */
+    @Nullable
+    public VopsSupportInfo getVopsSupportInfo() {
+        return mVopsSupportInfo;
+    }
 }
diff --git a/telephony/java/android/telephony/DataThrottlingRequest.java b/telephony/java/android/telephony/DataThrottlingRequest.java
index f50bb58..2827e8d 100644
--- a/telephony/java/android/telephony/DataThrottlingRequest.java
+++ b/telephony/java/android/telephony/DataThrottlingRequest.java
@@ -17,6 +17,7 @@
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
+import android.annotation.RequiresFeature;
 import android.annotation.SystemApi;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -52,6 +53,9 @@
      * @hide
      */
     @SystemApi
+    @RequiresFeature(
+            enforcement = "android.telephony.TelephonyManager#isRadioInterfaceCapabilitySupported",
+            value = TelephonyManager.CAPABILITY_THERMAL_MITIGATION_DATA_THROTTLING)
     public static final int DATA_THROTTLING_ACTION_THROTTLE_SECONDARY_CARRIER = 1;
 
     /**
@@ -63,6 +67,9 @@
      * @hide
      */
     @SystemApi
+    @RequiresFeature(
+            enforcement = "android.telephony.TelephonyManager#isRadioInterfaceCapabilitySupported",
+            value = TelephonyManager.CAPABILITY_THERMAL_MITIGATION_DATA_THROTTLING)
     public static final int DATA_THROTTLING_ACTION_THROTTLE_PRIMARY_CARRIER = 2;
 
     /**
@@ -76,6 +83,9 @@
      * @hide
      */
     @SystemApi
+    @RequiresFeature(
+            enforcement = "android.telephony.TelephonyManager#isRadioInterfaceCapabilitySupported",
+            value = TelephonyManager.CAPABILITY_THERMAL_MITIGATION_DATA_THROTTLING)
     public static final int DATA_THROTTLING_ACTION_HOLD = 3;
 
     /**
diff --git a/telephony/java/android/telephony/LteVopsSupportInfo.java b/telephony/java/android/telephony/LteVopsSupportInfo.java
index 83e41bf..87761e2 100644
--- a/telephony/java/android/telephony/LteVopsSupportInfo.java
+++ b/telephony/java/android/telephony/LteVopsSupportInfo.java
@@ -21,7 +21,7 @@
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.os.Parcel;
-import android.os.Parcelable;
+import android.telephony.AccessNetworkConstants.AccessNetworkType;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -32,7 +32,7 @@
  * @hide
  */
 @SystemApi
-public final class LteVopsSupportInfo implements Parcelable {
+public final class LteVopsSupportInfo extends VopsSupportInfo {
 
     /**@hide*/
     @Retention(RetentionPolicy.SOURCE)
@@ -42,7 +42,10 @@
     public @interface LteVopsStatus {}
     /**
      * Indicates information not available from modem.
+     *
+     * @deprecated as no instance will be created in this case
      */
+    @Deprecated
     public static final int LTE_STATUS_NOT_AVAILABLE = 1;
 
     /**
@@ -82,13 +85,38 @@
         return mEmcBearerSupport;
     }
 
+    /**
+     * Returns whether VoPS is supported by the network
+     */
+    @Override
+    public boolean isVopsSupported() {
+        return mVopsSupport == LTE_STATUS_SUPPORTED;
+    }
+
+    /**
+     * Returns whether emergency service is supported by the network
+     */
+    @Override
+    public boolean isEmergencyServiceSupported() {
+        return mEmcBearerSupport == LTE_STATUS_SUPPORTED;
+    }
+
+    /**
+     * Returns whether emergency service fallback is supported by the network
+     */
+    @Override
+    public boolean isEmergencyServiceFallbackSupported() {
+        return false;
+    }
+
     @Override
     public int describeContents() {
         return 0;
     }
 
     @Override
-    public void writeToParcel(Parcel out, int flags) {
+    public void writeToParcel(@NonNull Parcel out, int flags) {
+        super.writeToParcel(out, flags, AccessNetworkType.EUTRAN);
         out.writeInt(mVopsSupport);
         out.writeInt(mEmcBearerSupport);
     }
@@ -124,6 +152,8 @@
             new Creator<LteVopsSupportInfo>() {
         @Override
         public LteVopsSupportInfo createFromParcel(Parcel in) {
+            // Skip the type info.
+            in.readInt();
             return new LteVopsSupportInfo(in);
         }
 
@@ -133,6 +163,11 @@
         }
     };
 
+    /** @hide */
+    protected static LteVopsSupportInfo createFromParcelBody(Parcel in) {
+        return new LteVopsSupportInfo(in);
+    }
+
     private LteVopsSupportInfo(Parcel in) {
         mVopsSupport = in.readInt();
         mEmcBearerSupport = in.readInt();
diff --git a/telephony/java/android/telephony/NetworkRegistrationInfo.java b/telephony/java/android/telephony/NetworkRegistrationInfo.java
index a78f813..5fb60d7 100644
--- a/telephony/java/android/telephony/NetworkRegistrationInfo.java
+++ b/telephony/java/android/telephony/NetworkRegistrationInfo.java
@@ -293,11 +293,12 @@
                                    @Nullable CellIdentity cellIdentity, @Nullable String rplmn,
                                    int maxDataCalls, boolean isDcNrRestricted,
                                    boolean isNrAvailable, boolean isEndcAvailable,
-                                   LteVopsSupportInfo lteVopsSupportInfo) {
+                                   @Nullable VopsSupportInfo vopsSupportInfo) {
         this(domain, transportType, registrationState, accessNetworkTechnology, rejectCause,
                 emergencyOnly, availableServices, cellIdentity, rplmn);
         mDataSpecificInfo = new DataSpecificRegistrationInfo(
-                maxDataCalls, isDcNrRestricted, isNrAvailable, isEndcAvailable, lteVopsSupportInfo);
+                maxDataCalls, isDcNrRestricted, isNrAvailable,
+                isEndcAvailable, vopsSupportInfo);
         updateNrState();
     }
 
diff --git a/telephony/java/android/telephony/NrVopsSupportInfo.aidl b/telephony/java/android/telephony/NrVopsSupportInfo.aidl
new file mode 100644
index 0000000..460a589
--- /dev/null
+++ b/telephony/java/android/telephony/NrVopsSupportInfo.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+parcelable NrVopsSupportInfo;
diff --git a/telephony/java/android/telephony/NrVopsSupportInfo.java b/telephony/java/android/telephony/NrVopsSupportInfo.java
new file mode 100644
index 0000000..155ee38
--- /dev/null
+++ b/telephony/java/android/telephony/NrVopsSupportInfo.java
@@ -0,0 +1,260 @@
+/*
+ * 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 android.telephony;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.telephony.AccessNetworkConstants.AccessNetworkType;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+
+/**
+ * Class stores information related to NR network VoPS support
+ * @hide
+ */
+@SystemApi
+public final class NrVopsSupportInfo extends VopsSupportInfo {
+
+    /**
+     * Indicates network does not support vops
+     */
+    public static final int NR_STATUS_VOPS_NOT_SUPPORTED = 0;
+
+    /**
+     * Indicates network supports vops over 3gpp access.
+     */
+    public static final int NR_STATUS_VOPS_3GPP_SUPPORTED = 1;
+
+    /**
+     * Indicates network supports vops over non 3gpp access
+     */
+    public static final int NR_STATUS_VOPS_NON_3GPP_SUPPORTED = 2;
+
+    /**@hide*/
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(
+        prefix = {"NR_STATUS_VOPS_"},
+        value = {
+            NR_STATUS_VOPS_NOT_SUPPORTED,
+            NR_STATUS_VOPS_3GPP_SUPPORTED,
+            NR_STATUS_VOPS_NON_3GPP_SUPPORTED
+        })
+    public @interface NrVopsStatus {}
+
+    /**
+     * Indicates network does not support emergency service
+     */
+    public static final int NR_STATUS_EMC_NOT_SUPPORTED = 0;
+
+    /**
+     * Indicates network supports emergency service in NR connected to 5GCN only
+     */
+    public static final int NR_STATUS_EMC_5GCN_ONLY = 1;
+
+    /**
+     * Indicates network supports emergency service in E-UTRA connected to 5GCN only
+     */
+    public static final int NR_STATUS_EMC_EUTRA_5GCN_ONLY = 2;
+
+    /**
+     * Indicates network supports emergency service in NR connected to 5GCN and
+     * E-UTRA connected to 5GCN
+     */
+    public static final int NR_STATUS_EMC_NR_EUTRA_5GCN = 3;
+
+    /**@hide*/
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(
+        prefix = {"NR_STATUS_EMC_"},
+        value = {
+            NR_STATUS_EMC_NOT_SUPPORTED,
+            NR_STATUS_EMC_5GCN_ONLY,
+            NR_STATUS_EMC_EUTRA_5GCN_ONLY,
+            NR_STATUS_EMC_NR_EUTRA_5GCN
+        })
+    public @interface NrEmcStatus {}
+
+    /**
+     * Indicates network does not support emergency service
+     */
+    public static final int NR_STATUS_EMF_NOT_SUPPORTED = 0;
+
+    /**
+     * Indicates network supports emergency service fallback in NR connected to 5GCN only
+     */
+    public static final int NR_STATUS_EMF_5GCN_ONLY = 1;
+
+    /**
+     * Indicates network supports emergency service fallback in E-UTRA connected to 5GCN only
+     */
+    public static final int NR_STATUS_EMF_EUTRA_5GCN_ONLY = 2;
+
+    /**
+     * Indicates network supports emergency service fallback in NR connected to 5GCN
+     * and E-UTRA connected to 5GCN
+     */
+    public static final int NR_STATUS_EMF_NR_EUTRA_5GCN = 3;
+
+    /**@hide*/
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(
+        prefix = {"NR_STATUS_EMF_"},
+        value = {
+            NR_STATUS_EMF_NOT_SUPPORTED,
+            NR_STATUS_EMF_5GCN_ONLY,
+            NR_STATUS_EMF_EUTRA_5GCN_ONLY,
+            NR_STATUS_EMF_NR_EUTRA_5GCN
+        })
+    public @interface NrEmfStatus {}
+
+    @NrVopsStatus
+    private final int mVopsSupport;
+    @NrEmcStatus
+    private final int mEmcSupport;
+    @NrEmfStatus
+    private final int mEmfSupport;
+
+    public NrVopsSupportInfo(@NrVopsStatus int vops, @NrEmcStatus int emc, @NrEmcStatus int emf) {
+        mVopsSupport = vops;
+        mEmcSupport = emc;
+        mEmfSupport = emf;
+    }
+
+    /**
+     * Provides the NR VoPS support capability as described in:
+     * 3GPP 24.501 EPS network feature support -> IMS VoPS
+     */
+    public @NrVopsStatus int getVopsSupport() {
+        return mVopsSupport;
+    }
+
+    /**
+     * Provides the NR Emergency bearer support capability as described in:
+     * 3GPP 24.501 EPS network feature support -> EMC, and
+     * 38.331 SIB1 : ims-EmergencySupport
+     */
+    public @NrEmcStatus int getEmcSupport() {
+        return mEmcSupport;
+    }
+
+    /**
+     * Provides the NR emergency service fallback support capability as
+     * described in 3GPP 24.501 EPS network feature support -> EMF
+     */
+    public @NrEmfStatus int getEmfSupport() {
+        return mEmfSupport;
+    }
+
+    /**
+     * Returns whether VoPS is supported by the network
+     */
+    @Override
+    public boolean isVopsSupported() {
+        return mVopsSupport != NR_STATUS_VOPS_NOT_SUPPORTED;
+    }
+
+    /**
+     * Returns whether emergency service is supported by the network
+     */
+    @Override
+    public boolean isEmergencyServiceSupported() {
+        return mEmcSupport != NR_STATUS_EMC_NOT_SUPPORTED;
+    }
+
+    /**
+     * Returns whether emergency service fallback is supported by the network
+     */
+    public boolean isEmergencyServiceFallbackSupported() {
+        return mEmfSupport != NR_STATUS_EMF_NOT_SUPPORTED;
+    }
+
+    /**
+     * Implement the Parcelable interface
+     */
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel out, int flags) {
+        super.writeToParcel(out, flags, AccessNetworkType.NGRAN);
+        out.writeInt(mVopsSupport);
+        out.writeInt(mEmcSupport);
+        out.writeInt(mEmfSupport);
+    }
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        if (o == null || !(o instanceof NrVopsSupportInfo)) {
+            return false;
+        }
+        if (this == o) return true;
+        NrVopsSupportInfo other = (NrVopsSupportInfo) o;
+        return mVopsSupport == other.mVopsSupport
+            && mEmcSupport == other.mEmcSupport
+            && mEmfSupport == other.mEmfSupport;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mVopsSupport, mEmcSupport, mEmfSupport);
+    }
+
+    /**
+     * @return string representation.
+     */
+    @NonNull
+    @Override
+    public String toString() {
+        return ("NrVopsSupportInfo : "
+                + " mVopsSupport = " + mVopsSupport
+                + " mEmcSupport = " + mEmcSupport
+                + " mEmfSupport = " + mEmfSupport);
+    }
+
+    public static final @android.annotation.NonNull Creator<NrVopsSupportInfo> CREATOR =
+            new Creator<NrVopsSupportInfo>() {
+        @Override
+        public NrVopsSupportInfo createFromParcel(Parcel in) {
+            // Skip the type info.
+            in.readInt();
+            return new NrVopsSupportInfo(in);
+        }
+
+        @Override
+        public NrVopsSupportInfo[] newArray(int size) {
+            return new NrVopsSupportInfo[size];
+        }
+    };
+
+    /** @hide */
+    protected static NrVopsSupportInfo createFromParcelBody(Parcel in) {
+        return new NrVopsSupportInfo(in);
+    }
+
+    private NrVopsSupportInfo(Parcel in) {
+        mVopsSupport = in.readInt();
+        mEmcSupport = in.readInt();
+        mEmfSupport = in.readInt();
+    }
+}
diff --git a/telephony/java/android/telephony/PhoneCapability.java b/telephony/java/android/telephony/PhoneCapability.java
index 30480d1..a3aaf61 100644
--- a/telephony/java/android/telephony/PhoneCapability.java
+++ b/telephony/java/android/telephony/PhoneCapability.java
@@ -26,6 +26,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;
 
@@ -47,26 +48,18 @@
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
     @IntDef(prefix = { "DEVICE_NR_CAPABILITY_" }, value = {
-            DEVICE_NR_CAPABILITY_NONE,
             DEVICE_NR_CAPABILITY_NSA,
             DEVICE_NR_CAPABILITY_SA,
     })
     public @interface DeviceNrCapability {}
 
     /**
-     * Indicates DEVICE_NR_CAPABILITY_NONE determine that the device does not enable 5G NR.
-     * @hide
-     */
-    @SystemApi
-    public static final int DEVICE_NR_CAPABILITY_NONE = 0;
-
-    /**
      * Indicates DEVICE_NR_CAPABILITY_NSA determine that the device enable the non-standalone
      * (NSA) mode of 5G NR.
      * @hide
      */
     @SystemApi
-    public static final int DEVICE_NR_CAPABILITY_NSA = 1 << 0;
+    public static final int DEVICE_NR_CAPABILITY_NSA = 1;
 
     /**
      * Indicates DEVICE_NR_CAPABILITY_SA determine that the device enable the standalone (SA)
@@ -74,7 +67,7 @@
      * @hide
      */
     @SystemApi
-    public static final int DEVICE_NR_CAPABILITY_SA = 1 << 1;
+    public static final int DEVICE_NR_CAPABILITY_SA = 2;
 
     static {
         ModemInfo modemInfo1 = new ModemInfo(0, 0, true, true);
@@ -83,31 +76,34 @@
         List<ModemInfo> logicalModemList = new ArrayList<>();
         logicalModemList.add(modemInfo1);
         logicalModemList.add(modemInfo2);
+        int[] deviceNrCapabilities = new int[0];
+
         DEFAULT_DSDS_CAPABILITY = new PhoneCapability(1, 1, logicalModemList, false,
-                DEVICE_NR_CAPABILITY_NONE);
+                deviceNrCapabilities);
 
         logicalModemList = new ArrayList<>();
         logicalModemList.add(modemInfo1);
         DEFAULT_SSSS_CAPABILITY = new PhoneCapability(1, 1, logicalModemList, false,
-                DEVICE_NR_CAPABILITY_NONE);
+                deviceNrCapabilities);
     }
 
     /**
-     * MaxActivePsVoice defines the maximum number of active voice calls.  For a dual sim dual
-     * standby (DSDS) modem it would be one, but for a dual sim dual active modem it would be 2.
+     * mMaxActiveVoiceSubscriptions defines the maximum subscriptions that can support
+     * simultaneous voice calls. For a dual sim dual standby (DSDS) device it would be one, but
+     * for a dual sim dual active device it would be 2.
      *
      * @hide
      */
-    private final int mMaxActivePsVoice;
+    private final int mMaxActiveVoiceSubscriptions;
 
     /**
-     * MaxActiveInternetData defines how many logical modems can have
-     * PS attached simultaneously. For example, for L+L modem it
-     * should be 2.
+     * mMaxActiveDataSubscriptions defines the maximum subscriptions that can support
+     * simultaneous data connections.
+     * For example, for L+L device it should be 2.
      *
      * @hide
      */
-    private final int mMaxActiveInternetData;
+    private final int mMaxActiveDataSubscriptions;
 
     /**
      * Whether modem supports both internet PDN up so
@@ -126,42 +122,45 @@
      *
      * @hide
      */
-    private final int mDeviceNrCapability;
+    private final int[] mDeviceNrCapabilities;
 
     /** @hide */
-    public PhoneCapability(int maxActivePsVoice, int maxActiveInternetData,
+    public PhoneCapability(int maxActiveVoiceSubscriptions, int maxActiveDataSubscriptions,
             List<ModemInfo> logicalModemList, boolean networkValidationBeforeSwitchSupported,
-            int deviceNrCapability) {
-        this.mMaxActivePsVoice = maxActivePsVoice;
-        this.mMaxActiveInternetData = maxActiveInternetData;
+            int[] deviceNrCapabilities) {
+        this.mMaxActiveVoiceSubscriptions = maxActiveVoiceSubscriptions;
+        this.mMaxActiveDataSubscriptions = maxActiveDataSubscriptions;
         // Make sure it's not null.
         this.mLogicalModemList = logicalModemList == null ? new ArrayList<>() : logicalModemList;
         this.mNetworkValidationBeforeSwitchSupported = networkValidationBeforeSwitchSupported;
-        this.mDeviceNrCapability = deviceNrCapability;
+        this.mDeviceNrCapabilities = deviceNrCapabilities;
     }
 
     @Override
     public String toString() {
-        return "mMaxActivePsVoice=" + mMaxActivePsVoice
-                + " mMaxActiveInternetData=" + mMaxActiveInternetData
+        return "mMaxActiveVoiceSubscriptions=" + mMaxActiveVoiceSubscriptions
+                + " mMaxActiveDataSubscriptions=" + mMaxActiveDataSubscriptions
                 + " mNetworkValidationBeforeSwitchSupported="
                 + mNetworkValidationBeforeSwitchSupported
-                + " mDeviceNrCapability " + mDeviceNrCapability;
+                + " mDeviceNrCapability " + Arrays.toString(mDeviceNrCapabilities);
     }
 
     private PhoneCapability(Parcel in) {
-        mMaxActivePsVoice = in.readInt();
-        mMaxActiveInternetData = in.readInt();
+        mMaxActiveVoiceSubscriptions = in.readInt();
+        mMaxActiveDataSubscriptions = in.readInt();
         mNetworkValidationBeforeSwitchSupported = in.readBoolean();
         mLogicalModemList = new ArrayList<>();
         in.readList(mLogicalModemList, ModemInfo.class.getClassLoader());
-        mDeviceNrCapability = in.readInt();
+        mDeviceNrCapabilities = in.createIntArray();
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(mMaxActivePsVoice, mMaxActiveInternetData, mLogicalModemList,
-                mNetworkValidationBeforeSwitchSupported, mDeviceNrCapability);
+        return Objects.hash(mMaxActiveVoiceSubscriptions,
+                mMaxActiveDataSubscriptions,
+                mLogicalModemList,
+                mNetworkValidationBeforeSwitchSupported,
+                Arrays.hashCode(mDeviceNrCapabilities));
     }
 
     @Override
@@ -176,12 +175,12 @@
 
         PhoneCapability s = (PhoneCapability) o;
 
-        return (mMaxActivePsVoice == s.mMaxActivePsVoice
-                && mMaxActiveInternetData == s.mMaxActiveInternetData
+        return (mMaxActiveVoiceSubscriptions == s.mMaxActiveVoiceSubscriptions
+                && mMaxActiveDataSubscriptions == s.mMaxActiveDataSubscriptions
                 && mNetworkValidationBeforeSwitchSupported
                 == s.mNetworkValidationBeforeSwitchSupported
                 && mLogicalModemList.equals(s.mLogicalModemList)
-                && mDeviceNrCapability == s.mDeviceNrCapability);
+                && Arrays.equals(mDeviceNrCapabilities, s.mDeviceNrCapabilities));
     }
 
     /**
@@ -195,11 +194,11 @@
      * {@link Parcelable#writeToParcel}
      */
     public void writeToParcel(@NonNull Parcel dest, @Parcelable.WriteFlags int flags) {
-        dest.writeInt(mMaxActivePsVoice);
-        dest.writeInt(mMaxActiveInternetData);
+        dest.writeInt(mMaxActiveVoiceSubscriptions);
+        dest.writeInt(mMaxActiveDataSubscriptions);
         dest.writeBoolean(mNetworkValidationBeforeSwitchSupported);
         dest.writeList(mLogicalModemList);
-        dest.writeInt(mDeviceNrCapability);
+        dest.writeIntArray(mDeviceNrCapabilities);
     }
 
     public static final @android.annotation.NonNull Parcelable.Creator<PhoneCapability> CREATOR =
@@ -214,25 +213,24 @@
     };
 
     /**
-     * @return the maximum number of active packet-switched calls.  For a dual
-     * sim dual standby (DSDS) modem it would be one, but for a dual sim dual active modem it
+     * @return the maximum subscriptions that can support simultaneous voice calls. For a dual
+     * sim dual standby (DSDS) device it would be one, but for a dual sim dual active device it
      * would be 2.
      * @hide
      */
     @SystemApi
-    public @IntRange(from = 1) int getMaxActivePacketSwitchedVoiceCalls() {
-        return mMaxActivePsVoice;
+    public @IntRange(from = 1) int getMaxActiveVoiceSubscriptions() {
+        return mMaxActiveVoiceSubscriptions;
     }
 
     /**
-     * @return MaxActiveInternetData defines how many logical modems can have PS attached
-     * simultaneously.
-     * For example, for L+L modem it should be 2.
+     * @return the maximum subscriptions that can support simultaneous data connections.
+     * For example, for L+L device it should be 2.
      * @hide
      */
     @SystemApi
-    public @IntRange(from = 1) int getMaxActiveInternetData() {
-        return mMaxActiveInternetData;
+    public @IntRange(from = 1) int getMaxActiveDataSubscriptions() {
+        return mMaxActiveDataSubscriptions;
     }
 
     /**
@@ -254,13 +252,16 @@
     }
 
     /**
-     * Return the device's NR capability.
+     * Return List of the device's NR capability. If the device doesn't support NR capability,
+     * then this api return empty array.
+     * @see DEVICE_NR_CAPABILITY_NSA
+     * @see DEVICE_NR_CAPABILITY_SA
      *
-     * @return {@link DeviceNrCapability} the device's NR capability.
+     * @return List of the device's NR capability.
      * @hide
      */
     @SystemApi
-    public @DeviceNrCapability int getDeviceNrCapabilityBitmask() {
-        return mDeviceNrCapability;
+    public @NonNull @DeviceNrCapability int[] getDeviceNrCapabilities() {
+        return mDeviceNrCapabilities == null ? (new int[0]) : mDeviceNrCapabilities;
     }
 }
diff --git a/telephony/java/android/telephony/PhysicalChannelConfig.java b/telephony/java/android/telephony/PhysicalChannelConfig.java
index a012498..3b28616 100644
--- a/telephony/java/android/telephony/PhysicalChannelConfig.java
+++ b/telephony/java/android/telephony/PhysicalChannelConfig.java
@@ -293,6 +293,14 @@
     }
 
     /**
+     * Return a copy of this PhysicalChannelConfig object but redact all the location info.
+     * @hide
+     */
+    public PhysicalChannelConfig createLocationInfoSanitizedCopy() {
+        return new Builder(this).setPhysicalCellId(PHYSICAL_CELL_ID_UNKNOWN).build();
+    }
+
+    /**
      * @return String representation of the connection status
      * @hide
      */
@@ -541,6 +549,23 @@
             mBand = BAND_UNKNOWN;
         }
 
+        /**
+         * Builder object constructed from existing PhysicalChannelConfig object.
+         * @hide
+         */
+        public Builder(PhysicalChannelConfig config) {
+            mNetworkType = config.getNetworkType();
+            mFrequencyRange = config.getFrequencyRange();
+            mDownlinkChannelNumber = config.getDownlinkChannelNumber();
+            mUplinkChannelNumber = config.getUplinkChannelNumber();
+            mCellBandwidthDownlinkKhz = config.getCellBandwidthDownlinkKhz();
+            mCellBandwidthUplinkKhz = config.getCellBandwidthUplinkKhz();
+            mCellConnectionStatus = config.getConnectionStatus();
+            mContextIds = Arrays.copyOf(config.getContextIds(), config.getContextIds().length);
+            mPhysicalCellId = config.getPhysicalCellId();
+            mBand = config.getBand();
+        }
+
         public PhysicalChannelConfig build() {
             return new PhysicalChannelConfig(this);
         }
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index f110dae..2d06062 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -564,6 +564,7 @@
      * @hide
      */
     @UnsupportedAppUsage
+    @TestApi
     public int getDataRegState() {
         return mDataRegState;
     }
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index 17af463..a527e8d 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -2219,7 +2219,7 @@
                 ret = iccISms.getSmsCapacityOnIccForSubscriber(getSubscriptionId());
             }
         } catch (RemoteException ex) {
-            throw new RuntimeException(ex);
+            Log.e(TAG, "getSmsCapacityOnIcc() RemoteException", ex);
         }
         return ret;
     }
diff --git a/telephony/java/android/telephony/SmsMessage.java b/telephony/java/android/telephony/SmsMessage.java
index cfb29f1..5a12865 100644
--- a/telephony/java/android/telephony/SmsMessage.java
+++ b/telephony/java/android/telephony/SmsMessage.java
@@ -300,9 +300,12 @@
      * @param data Message data.
      * @param isCdma Indicates weather the type of the SMS is CDMA.
      * @return An SmsMessage representing the message.
+     *
+     * @hide
      */
+    @SystemApi
     @Nullable
-    public static SmsMessage createSmsSubmitPdu(@NonNull byte[] data, boolean isCdma) {
+    public static SmsMessage createFromNativeSmsSubmitPdu(@NonNull byte[] data, boolean isCdma) {
         SmsMessageBase wrappedMessage;
 
         if (isCdma) {
@@ -318,23 +321,6 @@
     }
 
     /**
-     * Create an SmsMessage from a native SMS-Submit PDU, specified by Bluetooth Message Access
-     * Profile Specification v1.4.2 5.8.
-     * This is used by Bluetooth MAP profile to decode message when sending non UTF-8 SMS messages.
-     *
-     * @param data Message data.
-     * @param isCdma Indicates weather the type of the SMS is CDMA.
-     * @return An SmsMessage representing the message.
-     *
-     * @hide
-     */
-    @SystemApi
-    @Nullable
-    public static SmsMessage createFromNativeSmsSubmitPdu(@NonNull byte[] data, boolean isCdma) {
-        return null;
-    }
-
-    /**
      * Get the TP-Layer-Length for the given SMS-SUBMIT PDU Basically, the
      * length in bytes (not hex chars) less the SMSC header
      *
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index f7580d7..67fe783 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -56,6 +56,7 @@
 import android.provider.Telephony.SimInfo;
 import android.telephony.euicc.EuiccManager;
 import android.telephony.ims.ImsMmTelManager;
+import android.util.Base64;
 import android.util.Log;
 import android.util.Pair;
 
@@ -67,6 +68,11 @@
 import com.android.internal.util.Preconditions;
 import com.android.telephony.Rlog;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
@@ -612,9 +618,9 @@
     public static final int D2D_SHARING_ALL_CONTACTS = 1;
 
     /**
-     * Device status is shared with all starred contacts.
+     * Device status is shared with all selected contacts.
      */
-    public static final int D2D_SHARING_STARRED_CONTACTS = 2;
+    public static final int D2D_SHARING_SELECTED_CONTACTS = 2;
 
     /**
      * Device status is shared whenever possible.
@@ -627,10 +633,10 @@
             value = {
                     D2D_SHARING_DISABLED,
                     D2D_SHARING_ALL_CONTACTS,
-                    D2D_SHARING_STARRED_CONTACTS,
+                    D2D_SHARING_SELECTED_CONTACTS,
                     D2D_SHARING_ALL
             })
-    public @interface DeviceToDeviceStatusSharing {}
+    public @interface DeviceToDeviceStatusSharingPreference {}
 
     /**
      * TelephonyProvider column name for device to device sharing status.
@@ -639,6 +645,13 @@
     public static final String D2D_STATUS_SHARING = SimInfo.COLUMN_D2D_STATUS_SHARING;
 
     /**
+     * TelephonyProvider column name for contacts information that allow device to device sharing.
+     * <P>Type: TEXT (String)</P>
+     */
+    public static final String D2D_STATUS_SHARING_SELECTED_CONTACTS =
+            SimInfo.COLUMN_D2D_STATUS_SHARING_SELECTED_CONTACTS;
+
+    /**
      * TelephonyProvider column name for the color of a SIM.
      * <P>Type: INTEGER (int)</P>
      */
@@ -2439,6 +2452,57 @@
     }
 
     /**
+     * Serialize list of contacts uri to string
+     * @hide
+     */
+    public static String serializeUriLists(List<Uri> uris) {
+        List<String> contacts = new ArrayList<>();
+        for (Uri uri : uris) {
+            contacts.add(uri.toString());
+        }
+        try {
+            ByteArrayOutputStream bos = new ByteArrayOutputStream();
+            ObjectOutputStream oos = new ObjectOutputStream(bos);
+            oos.writeObject(contacts);
+            oos.flush();
+            return Base64.encodeToString(bos.toByteArray(), Base64.DEFAULT);
+        } catch (IOException e) {
+            logd("serializeUriLists IO exception");
+        }
+        return "";
+    }
+
+    /**
+     * Return list of contacts uri corresponding to query result.
+     * @param subId Subscription Id of Subscription
+     * @param propKey Column name in SubscriptionInfo database
+     * @return list of contacts uri to be returned
+     * @hide
+     */
+    private static List<Uri> getContactsFromSubscriptionProperty(int subId, String propKey,
+            Context context) {
+        String result = getSubscriptionProperty(subId, propKey, context);
+        if (result != null) {
+            try {
+                byte[] b = Base64.decode(result, Base64.DEFAULT);
+                ByteArrayInputStream bis = new ByteArrayInputStream(b);
+                ObjectInputStream ois = new ObjectInputStream(bis);
+                List<String> contacts = ArrayList.class.cast(ois.readObject());
+                List<Uri> uris = new ArrayList<>();
+                for (String contact : contacts) {
+                    uris.add(Uri.parse(contact));
+                }
+                return uris;
+            } catch (IOException e) {
+                logd("getContactsFromSubscriptionProperty IO exception");
+            } catch (ClassNotFoundException e) {
+                logd("getContactsFromSubscriptionProperty ClassNotFound exception");
+            }
+        }
+        return new ArrayList<>();
+    }
+
+    /**
      * Store properties associated with SubscriptionInfo in database
      * @param subId Subscription Id of Subscription
      * @param propKey Column name in SubscriptionInfo database
@@ -3415,29 +3479,65 @@
      * app uses this method to indicate with whom they wish to share device to device status
      * information.
      * @param sharing the status sharing preference
-     * @param subId the unique Subscription ID in database
+     * @param subscriptionId the unique Subscription ID in database
      */
     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
-    public void setDeviceToDeviceStatusSharing(@DeviceToDeviceStatusSharing int sharing,
-            int subId) {
+    public void setDeviceToDeviceStatusSharingPreference(
+            @DeviceToDeviceStatusSharingPreference int sharing, int subscriptionId) {
         if (VDBG) {
-            logd("[setDeviceToDeviceStatusSharing] + sharing: " + sharing + " subId: " + subId);
+            logd("[setDeviceToDeviceStatusSharing] + sharing: " + sharing + " subId: "
+                    + subscriptionId);
         }
-        setSubscriptionPropertyHelper(subId, "setDeviceToDeviceSharingStatus",
-                (iSub)->iSub.setDeviceToDeviceStatusSharing(sharing, subId));
+        setSubscriptionPropertyHelper(subscriptionId, "setDeviceToDeviceSharingStatus",
+                (iSub)->iSub.setDeviceToDeviceStatusSharing(sharing, subscriptionId));
     }
 
     /**
      * Returns the user-chosen device to device status sharing preference
-     * @param subId Subscription id of subscription
+     * @param subscriptionId Subscription id of subscription
      * @return The device to device status sharing preference
      */
-    public @DeviceToDeviceStatusSharing int getDeviceToDeviceStatusSharing(int subId) {
+    public @DeviceToDeviceStatusSharingPreference int getDeviceToDeviceStatusSharingPreference(
+            int subscriptionId) {
         if (VDBG) {
-            logd("[getDeviceToDeviceStatusSharing] + subId: " + subId);
+            logd("[getDeviceToDeviceStatusSharing] + subId: " + subscriptionId);
         }
-        return getIntegerSubscriptionProperty(subId, D2D_STATUS_SHARING, D2D_SHARING_DISABLED,
-                mContext);
+        return getIntegerSubscriptionProperty(subscriptionId, D2D_STATUS_SHARING,
+                D2D_SHARING_DISABLED, mContext);
+    }
+
+    /**
+     * Set the list of contacts that allow device to device status sharing for a subscription ID.
+     * The setting app uses this method to indicate with whom they wish to share device to device
+     * status information.
+     * @param contacts The list of contacts that allow device to device status sharing
+     * @param subscriptionId The unique Subscription ID in database
+     */
+    @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
+    public void setDeviceToDeviceStatusSharingContacts(@NonNull List<Uri> contacts,
+            int subscriptionId) {
+        String contactString = serializeUriLists(contacts);
+        if (VDBG) {
+            logd("[setDeviceToDeviceStatusSharingContacts] + contacts: " + contactString
+                    + " subId: " + subscriptionId);
+        }
+        setSubscriptionPropertyHelper(subscriptionId, "setDeviceToDeviceSharingStatus",
+                (iSub)->iSub.setDeviceToDeviceStatusSharingContacts(serializeUriLists(contacts),
+                        subscriptionId));
+    }
+
+    /**
+     * Returns the list of contacts that allow device to device status sharing.
+     * @param subscriptionId Subscription id of subscription
+     * @return The list of contacts that allow device to device status sharing
+     */
+    public @NonNull List<Uri> getDeviceToDeviceStatusSharingContacts(
+            int subscriptionId) {
+        if (VDBG) {
+            logd("[getDeviceToDeviceStatusSharingContacts] + subId: " + subscriptionId);
+        }
+        return getContactsFromSubscriptionProperty(subscriptionId,
+                D2D_STATUS_SHARING_SELECTED_CONTACTS, mContext);
     }
 
     /**
diff --git a/telephony/java/android/telephony/TelephonyDisplayInfo.java b/telephony/java/android/telephony/TelephonyDisplayInfo.java
index 2f89bfb..88c66ac 100644
--- a/telephony/java/android/telephony/TelephonyDisplayInfo.java
+++ b/telephony/java/android/telephony/TelephonyDisplayInfo.java
@@ -84,7 +84,7 @@
      * </ul>
      * One of the use case is that UX can show a different icon, for example, "5G+"
      */
-    public static final int OVERRIDE_NETWORK_TYPE_NR_ADVANCED = 4;
+    public static final int OVERRIDE_NETWORK_TYPE_NR_ADVANCED = 5;
 
     @NetworkType
     private final  int mNetworkType;
@@ -186,7 +186,8 @@
             case OVERRIDE_NETWORK_TYPE_LTE_CA: return "LTE_CA";
             case OVERRIDE_NETWORK_TYPE_LTE_ADVANCED_PRO: return "LTE_ADV_PRO";
             case OVERRIDE_NETWORK_TYPE_NR_NSA: return "NR_NSA";
-            case OVERRIDE_NETWORK_TYPE_NR_ADVANCED: return "NR_NSA_MMWAVE";
+            case OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE: return "NR_NSA_MMWAVE";
+            case OVERRIDE_NETWORK_TYPE_NR_ADVANCED: return "NR_ADVANCED";
             default: return "UNKNOWN";
         }
     }
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 5a94a8a..653aa9c 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -90,6 +90,7 @@
 import android.telephony.VisualVoicemailService.VisualVoicemailTask;
 import android.telephony.data.ApnSetting;
 import android.telephony.data.ApnSetting.MvnoType;
+import android.telephony.data.SlicingConfig;
 import android.telephony.emergency.EmergencyNumber;
 import android.telephony.emergency.EmergencyNumber.EmergencyServiceCategories;
 import android.telephony.gba.UaSecurityProtocolIdentifier;
@@ -104,6 +105,7 @@
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.os.BackgroundThread;
 import com.android.internal.telephony.CellNetworkScanResult;
 import com.android.internal.telephony.IBooleanConsumer;
 import com.android.internal.telephony.ICallForwardingInfoCallback;
@@ -138,6 +140,7 @@
 import java.util.Objects;
 import java.util.UUID;
 import java.util.concurrent.Executor;
+import java.util.concurrent.RejectedExecutionException;
 import java.util.function.Consumer;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
@@ -430,6 +433,27 @@
     }
 
     /**
+     * Post a runnable to the BackgroundThread.
+     *
+     * Used to invoke user callbacks without calling into the caller's executor from the caller's
+     * calling thread context, for example to provide asynchronous error information that is
+     * generated locally (not over a binder thread).
+     *
+     * <p>This is not necessary unless you are invoking caller's code asynchronously from within
+     * the caller's thread context.
+     *
+     * @param r a runnable.
+     */
+    private static void runOnBackgroundThread(@NonNull Runnable r) {
+        try {
+            BackgroundThread.getExecutor().execute(r);
+        } catch (RejectedExecutionException e) {
+            throw new IllegalStateException(
+                    "Failed to post a callback from the caller's thread context.", e);
+        }
+    }
+
+    /**
      * Returns the multi SIM variant
      * Returns DSDS for Dual SIM Dual Standby
      * Returns DSDA for Dual SIM Dual Active
@@ -5701,9 +5725,20 @@
      * Note: The call state returned via this method may differ from what is reported by
      * {@link PhoneStateListener#onCallStateChanged(int, String)}, as that callback only considers
      * Telephony (mobile) calls.
+     * <p>
+     * Requires Permission:
+     * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} for applications
+     * targeting API level 31+.
      *
      * @return the current call state.
+     * @deprecated Use {@link #getCallStateForSubscription} to retrieve the call state for a
+     * specific telephony subscription (which allows carrier privileged apps),
+     * {@link TelephonyCallback.CallStateListener} for real-time call state updates, or
+     * {@link TelecomManager#isInCall()}, which supplies an aggregate "in call" state for the entire
+     * device.
      */
+    @RequiresPermission(value = android.Manifest.permission.READ_PHONE_STATE, conditional = true)
+    @Deprecated
     public @CallState int getCallState() {
         if (mContext != null) {
             TelecomManager telecomManager = mContext.getSystemService(TelecomManager.class);
@@ -5715,19 +5750,48 @@
     }
 
     /**
+     * Retrieve the call state for a specific subscription that was specified when this
+     * TelephonyManager instance was created.
+     * <p>Requires Permission:
+     * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} or that the calling
+     * application has carrier privileges (see {@link #hasCarrierPrivileges}).
+     * @see TelephonyManager#createForSubscriptionId(int)
+     * @see TelephonyManager#createForPhoneAccountHandle(PhoneAccountHandle)
+     * @return The call state of the subscription associated with this TelephonyManager instance.
+     */
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+    public @CallState int getCallStateForSubscription() {
+        return getCallState(getSubId());
+    }
+
+    /**
      * Returns the Telephony call state for calls on a specific subscription.
      * <p>
      * Note: This method considers ONLY telephony/mobile calls, where {@link #getCallState()}
      * considers the state of calls from other {@link android.telecom.ConnectionService}
      * implementations.
+     * <p>
+     * Requires Permission:
+     * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} for applications
+     * targeting API level 31+ or that the calling application has carrier privileges
+     * (see {@link #hasCarrierPrivileges()}).
      *
      * @param subId the subscription to check call state for.
      * @hide
      */
     @UnsupportedAppUsage
+    @RequiresPermission(value = android.Manifest.permission.READ_PHONE_STATE, conditional = true)
     public @CallState int getCallState(int subId) {
-        int phoneId = SubscriptionManager.getPhoneId(subId);
-        return getCallStateForSlot(phoneId);
+        ITelephony telephony = getITelephony();
+        if (telephony == null) {
+            return CALL_STATE_IDLE;
+        }
+        try {
+            return telephony.getCallStateForSubscription(subId, mContext.getPackageName(),
+                    mContext.getAttributionTag());
+        } catch (RemoteException e) {
+            return CALL_STATE_IDLE;
+        }
     }
 
     /**
@@ -5744,22 +5808,28 @@
      * Note: This method considers ONLY telephony/mobile calls, where {@link #getCallState()}
      * considers the state of calls from other {@link android.telecom.ConnectionService}
      * implementations.
+     * <p>
+     * Requires Permission:
+     * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} for applications
+     * targeting API level 31+ or that the calling application has carrier privileges
+     * (see {@link #hasCarrierPrivileges()}).
      *
      * @param slotIndex the SIM slot index to check call state for.
      * @hide
      */
+    @RequiresPermission(value = android.Manifest.permission.READ_PHONE_STATE, conditional = true)
     public @CallState int getCallStateForSlot(int slotIndex) {
         try {
+            int[] subId = SubscriptionManager.getSubId(slotIndex);
             ITelephony telephony = getITelephony();
-            if (telephony == null)
+            if (telephony == null || subId == null || subId.length  == 0) {
                 return CALL_STATE_IDLE;
-            return telephony.getCallStateForSlot(slotIndex);
-        } catch (RemoteException ex) {
+            }
+            return telephony.getCallStateForSubscription(subId[0], mContext.getPackageName(),
+                    mContext.getAttributionTag());
+        } catch (RemoteException | NullPointerException ex) {
             // the phone process is restarting.
             return CALL_STATE_IDLE;
-        } catch (NullPointerException ex) {
-          // the phone process is restarting.
-          return CALL_STATE_IDLE;
         }
     }
 
@@ -6239,7 +6309,7 @@
 
         /**
          * Error response to
-         * {@link android.telephony.TelephonyManager#requestCellInfoUpdate requestCellInfoUpdate()}.
+         * {@link TelephonyManager#requestCellInfoUpdate requestCellInfoUpdate()}.
          *
          * Invoked when an error condition prevents updated {@link CellInfo} from being fetched
          * and returned from the modem. Callers of requestCellInfoUpdate() should override this
@@ -6257,6 +6327,20 @@
     };
 
     /**
+     * Used for checking if the target SDK version for the current process is S or above.
+     *
+     * <p> Applies to the following methods:
+     * {@link #requestCellInfoUpdate},
+     * {@link #setPreferredOpportunisticDataSubscription},
+     * {@link #updateAvailableNetworks},
+     * requestNumberVerification(),
+     * setSimPowerStateForSlot(),
+     */
+    @ChangeId
+    @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.R)
+    private static final long NULL_TELEPHONY_THROW_NO_CB = 182185642L;
+
+    /**
      * Requests all available cell information from the current subscription for observed
      * camped/registered, serving, and neighboring cells.
      *
@@ -6276,7 +6360,14 @@
             @NonNull @CallbackExecutor Executor executor, @NonNull CellInfoCallback callback) {
         try {
             ITelephony telephony = getITelephony();
-            if (telephony == null) return;
+            if (telephony == null) {
+                if (Compatibility.isChangeEnabled(NULL_TELEPHONY_THROW_NO_CB)) {
+                    throw new IllegalStateException("Telephony is null");
+                } else {
+                    return;
+                }
+            }
+
             telephony.requestCellInfoUpdate(
                     getSubId(),
                     new ICellInfoCallback.Stub() {
@@ -6303,6 +6394,8 @@
                         }
                     }, getOpPackageName(), getAttributionTag());
         } catch (RemoteException ex) {
+            runOnBackgroundThread(() -> executor.execute(
+                    () -> callback.onError(CellInfoCallback.ERROR_MODEM_ERROR, ex)));
         }
     }
 
@@ -6330,7 +6423,14 @@
             @NonNull @CallbackExecutor Executor executor, @NonNull CellInfoCallback callback) {
         try {
             ITelephony telephony = getITelephony();
-            if (telephony == null) return;
+            if (telephony == null) {
+                if (Compatibility.isChangeEnabled(NULL_TELEPHONY_THROW_NO_CB)) {
+                    throw new IllegalStateException("Telephony is null");
+                } else {
+                    return;
+                }
+            }
+
             telephony.requestCellInfoUpdateWithWorkSource(
                     getSubId(),
                     new ICellInfoCallback.Stub() {
@@ -6358,6 +6458,8 @@
                         }
                     }, getOpPackageName(), getAttributionTag(), workSource);
         } catch (RemoteException ex) {
+            runOnBackgroundThread(() -> executor.execute(
+                    () -> callback.onError(CellInfoCallback.ERROR_MODEM_ERROR, ex)));
         }
     }
 
@@ -7324,14 +7426,21 @@
 
         try {
             ITelephony telephony = getITelephony();
-            if (telephony != null) {
-                telephony.requestNumberVerification(range, timeoutMillis, internalCallback,
-                        getOpPackageName());
+            if (telephony == null) {
+                if (Compatibility.isChangeEnabled(NULL_TELEPHONY_THROW_NO_CB)) {
+                    throw new IllegalStateException("Telephony is null");
+                } else {
+                    return;
+                }
             }
+
+            telephony.requestNumberVerification(range, timeoutMillis, internalCallback,
+                    getOpPackageName());
         } catch (RemoteException ex) {
             Rlog.e(TAG, "requestNumberVerification RemoteException", ex);
-            executor.execute(() ->
-                    callback.onVerificationFailed(NumberVerificationCallback.REASON_UNSPECIFIED));
+            runOnBackgroundThread(() -> executor.execute(
+                    () -> callback.onVerificationFailed(
+                            NumberVerificationCallback.REASON_UNSPECIFIED)));
         }
     }
 
@@ -10700,6 +10809,8 @@
         }
         try {
             ITelephony telephony = getITelephony();
+            if (telephony == null) throw new IllegalStateException("Telephony is null.");
+
             IIntegerConsumer internalCallback = new IIntegerConsumer.Stub() {
                 @Override
                 public void accept(int result) {
@@ -10707,11 +10818,18 @@
                             Binder.withCleanCallingIdentity(() -> callback.accept(result)));
                 }
             };
-            if (telephony != null) {
-                telephony.setSimPowerStateForSlotWithCallback(slotIndex, state, internalCallback);
+            if (telephony == null) {
+                if (Compatibility.isChangeEnabled(NULL_TELEPHONY_THROW_NO_CB)) {
+                    throw new IllegalStateException("Telephony is null");
+                } else {
+                    return;
+                }
             }
+            telephony.setSimPowerStateForSlotWithCallback(slotIndex, state, internalCallback);
         } catch (RemoteException e) {
             Log.e(TAG, "Error calling ITelephony#setSimPowerStateForSlot", e);
+            runOnBackgroundThread(() -> executor.execute(
+                    () -> callback.accept(SET_SIM_POWER_STATE_MODEM_ERROR)));
         } catch (SecurityException e) {
             Log.e(TAG, "Permission error calling ITelephony#setSimPowerStateForSlot",
                     e);
@@ -11036,6 +11154,25 @@
     }
 
     /**
+     * Determines the {@link PhoneAccountHandle} associated with this TelephonyManager.
+     *
+     * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the
+     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultSubscriptionId()}
+     *
+     * <p>Requires Permission android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE or that the
+     * calling app has carrier privileges (see {@link #hasCarrierPrivileges})
+     *
+     * @return The {@link PhoneAccountHandle} associated with the TelphonyManager, or {@code null}
+     * if there is no associated {@link PhoneAccountHandle}; this can happen if the subscription is
+     * data-only or an opportunistic subscription.
+     */
+    @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
+    @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    public @Nullable PhoneAccountHandle getPhoneAccountHandle() {
+        return getPhoneAccountHandleForSubscriptionId(getSubId());
+    }
+
+    /**
      * Determines the {@link PhoneAccountHandle} associated with a subscription Id.
      *
      * @param subscriptionId The subscription Id to check.
@@ -12387,12 +12524,6 @@
      * "Data capable" means that this device supports packet-switched
      * data connections over the telephony network.
      * <p>
-     * Note: the meaning of this flag is subtly different from the
-     * PackageManager.FEATURE_TELEPHONY system feature, which is available
-     * on any device with a telephony radio, even if the device is
-     * voice-only.
-     *
-     * @hide
      */
     public boolean isDataCapable() {
         if (mContext == null) return true;
@@ -13271,22 +13402,12 @@
         try {
             IOns iOpportunisticNetworkService = getIOns();
             if (iOpportunisticNetworkService == null) {
-                if (executor == null || callback == null) {
-                    return;
+                if (Compatibility.isChangeEnabled(NULL_TELEPHONY_THROW_NO_CB)) {
+                    throw new IllegalStateException("Opportunistic Network Service is null");
+                } else {
+                    // Let the general remote exception handling catch this.
+                    throw new RemoteException("Null Opportunistic Network Service!");
                 }
-                final long identity = Binder.clearCallingIdentity();
-                try {
-                    executor.execute(() -> {
-                        if (Compatibility.isChangeEnabled(CALLBACK_ON_MORE_ERROR_CODE_CHANGE)) {
-                            callback.accept(SET_OPPORTUNISTIC_SUB_REMOTE_SERVICE_EXCEPTION);
-                        } else {
-                            callback.accept(SET_OPPORTUNISTIC_SUB_INACTIVE_SUBSCRIPTION);
-                        }
-                    });
-                } finally {
-                    Binder.restoreCallingIdentity(identity);
-                }
-                return;
             }
             ISetOpportunisticDataCallback callbackStub = new ISetOpportunisticDataCallback.Stub() {
                 @Override
@@ -13309,9 +13430,18 @@
                     .setPreferredDataSubscriptionId(subId, needValidation, callbackStub,
                             pkgForDebug);
         } catch (RemoteException ex) {
-            Rlog.e(TAG, "setPreferredDataSubscriptionId RemoteException", ex);
+            Rlog.e(TAG, "setPreferredOpportunisticDataSubscription RemoteException", ex);
+            if (executor == null || callback == null) {
+                return;
+            }
+            runOnBackgroundThread(() -> executor.execute(() -> {
+                if (Compatibility.isChangeEnabled(CALLBACK_ON_MORE_ERROR_CODE_CHANGE)) {
+                    callback.accept(SET_OPPORTUNISTIC_SUB_REMOTE_SERVICE_EXCEPTION);
+                } else {
+                    callback.accept(SET_OPPORTUNISTIC_SUB_INACTIVE_SUBSCRIPTION);
+                }
+            }));
         }
-        return;
     }
 
     /**
@@ -13368,37 +13498,18 @@
             @Nullable @CallbackExecutor Executor executor,
             @UpdateAvailableNetworksResult @Nullable Consumer<Integer> callback) {
         String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
+        Objects.requireNonNull(availableNetworks, "availableNetworks must not be null.");
         try {
             IOns iOpportunisticNetworkService = getIOns();
-            if (iOpportunisticNetworkService == null || availableNetworks == null) {
-                if (executor == null || callback == null) {
-                    return;
-                }
-                if (iOpportunisticNetworkService == null) {
-                    final long identity = Binder.clearCallingIdentity();
-                    try {
-                        executor.execute(() -> {
-                            if (Compatibility.isChangeEnabled(CALLBACK_ON_MORE_ERROR_CODE_CHANGE)) {
-                                callback.accept(UPDATE_AVAILABLE_NETWORKS_REMOTE_SERVICE_EXCEPTION);
-                            } else {
-                                callback.accept(UPDATE_AVAILABLE_NETWORKS_UNKNOWN_FAILURE);
-                            }
-                        });
-                    } finally {
-                        Binder.restoreCallingIdentity(identity);
-                    }
+            if (iOpportunisticNetworkService == null) {
+                if (Compatibility.isChangeEnabled(NULL_TELEPHONY_THROW_NO_CB)) {
+                    throw new IllegalStateException("Opportunistic Network Service is null");
                 } else {
-                    final long identity = Binder.clearCallingIdentity();
-                    try {
-                        executor.execute(() -> {
-                            callback.accept(UPDATE_AVAILABLE_NETWORKS_INVALID_ARGUMENTS);
-                        });
-                    } finally {
-                        Binder.restoreCallingIdentity(identity);
-                    }
+                    // Let the general remote exception handling catch this.
+                    throw new RemoteException("Null Opportunistic Network Service!");
                 }
-                return;
             }
+
             IUpdateAvailableNetworksCallback callbackStub =
                     new IUpdateAvailableNetworksCallback.Stub() {
                         @Override
@@ -13406,20 +13517,25 @@
                             if (executor == null || callback == null) {
                                 return;
                             }
-                            final long identity = Binder.clearCallingIdentity();
-                            try {
-                                executor.execute(() -> {
-                                    callback.accept(result);
-                                });
-                            } finally {
-                                Binder.restoreCallingIdentity(identity);
-                            }
+                            Binder.withCleanCallingIdentity(() -> {
+                                executor.execute(() -> callback.accept(result));
+                            });
                         }
                     };
-            iOpportunisticNetworkService.updateAvailableNetworks(availableNetworks, callbackStub,
-                    pkgForDebug);
+            iOpportunisticNetworkService
+                    .updateAvailableNetworks(availableNetworks, callbackStub, pkgForDebug);
         } catch (RemoteException ex) {
             Rlog.e(TAG, "updateAvailableNetworks RemoteException", ex);
+            if (executor == null || callback == null) {
+                return;
+            }
+            runOnBackgroundThread(() -> executor.execute(() -> {
+                if (Compatibility.isChangeEnabled(CALLBACK_ON_MORE_ERROR_CODE_CHANGE)) {
+                    callback.accept(UPDATE_AVAILABLE_NETWORKS_REMOTE_SERVICE_EXCEPTION);
+                } else {
+                    callback.accept(UPDATE_AVAILABLE_NETWORKS_UNKNOWN_FAILURE);
+                }
+            }));
         }
     }
 
@@ -14927,12 +15043,31 @@
     public static final String CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE =
             "CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE";
 
+    /**
+     * Indicates whether a data throttling request sent with {@link #sendThermalMitigationRequest}
+     * is supported. See comments on {@link #sendThermalMitigationRequest} for more information.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String CAPABILITY_THERMAL_MITIGATION_DATA_THROTTLING =
+            "CAPABILITY_THERMAL_MITIGATION_DATA_THROTTLING";
+
+    /**
+     * Indicates whether {@link #getNetworkSlicingConfiguration} is supported. See comments on
+     * respective methods for more information.
+     */
+    public static final String CAPABILITY_SLICING_CONFIG_SUPPORTED =
+            "CAPABILITY_SLICING_CONFIG_SUPPORTED";
+
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
     @StringDef(prefix = "CAPABILITY_", value = {
             CAPABILITY_SECONDARY_LINK_BANDWIDTH_VISIBLE,
             CAPABILITY_ALLOWED_NETWORK_TYPES_USED,
-            CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE
+            CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE,
+            CAPABILITY_THERMAL_MITIGATION_DATA_THROTTLING,
+            CAPABILITY_SLICING_CONFIG_SUPPORTED,
     })
     public @interface RadioInterfaceCapability {}
 
@@ -15042,11 +15177,29 @@
      * and can be used at any time during data throttling to hold onto the current level of data
      * throttling.
      *
+     * <p> If {@link android.telephony.TelephonyManager#isRadioInterfaceCapabilitySupported}({@link
+     * #CAPABILITY_THERMAL_MITIGATION_DATA_THROTTLING}) returns false, then sending a {@link
+     * DataThrottlingRequest#DATA_THROTTLING_ACTION_HOLD}, {@link
+     * DataThrottlingRequest#DATA_THROTTLING_ACTION_THROTTLE_SECONDARY_CARRIER}, or {@link
+     * DataThrottlingRequest#DATA_THROTTLING_ACTION_THROTTLE_PRIMARY_CARRIER} will result in {@link
+     * IllegalArgumentException} being thrown. However, on devices that do not
+     * support data throttling, {@link
+     * DataThrottlingRequest#DATA_THROTTLING_ACTION_NO_DATA_THROTTLING} can still be requested in
+     * order to undo the mitigations above it (i.e {@link
+     * ThermalMitigationRequest#THERMAL_MITIGATION_ACTION_VOICE_ONLY} and/or {@link
+     * ThermalMitigationRequest#THERMAL_MITIGATION_ACTION_RADIO_OFF}). </p>
+     *
+     * <p> In addition to the {@link Manifest.permission#MODIFY_PHONE_STATE} permission, callers of
+     * this API must also be listed in the device configuration as an authorized app in
+     * {@code packages/services/Telephony/res/values/config.xml} under the
+     * {@code thermal_mitigation_allowlisted_packages} key. </p>
+     *
      * @param thermalMitigationRequest Thermal mitigation request. See {@link
      * ThermalMitigationRequest} for details.
      *
      * @throws IllegalStateException if the Telephony process is not currently available.
-     * @throws IllegalArgumentException if the thermalMitigationRequest had invalid parameters.
+     * @throws IllegalArgumentException if the thermalMitigationRequest had invalid parameters or
+     * if the device's modem does not support data throttling.
      *
      * @hide
      */
@@ -15058,7 +15211,8 @@
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
-                return telephony.sendThermalMitigationRequest(getSubId(), thermalMitigationRequest);
+                return telephony.sendThermalMitigationRequest(getSubId(), thermalMitigationRequest,
+                        getOpPackageName());
             }
             throw new IllegalStateException("telephony service is null.");
         } catch (RemoteException ex) {
@@ -15506,4 +15660,102 @@
         }
         return PREPARE_UNATTENDED_REBOOT_ERROR;
     }
+
+    /**
+     * Exception that may be supplied to the callback in {@link #getNetworkSlicingConfiguration} if
+     * something goes awry.
+     */
+    public static class SlicingException extends Exception {
+        /**
+         * Getting the current slicing configuration successfully. Used internally only.
+         * @hide
+         */
+        public static final int SUCCESS = 0;
+
+        /**
+         * The system timed out waiting for a response from the Radio.
+         */
+        public static final int ERROR_TIMEOUT = 1;
+
+        /**
+         * The modem returned a failure.
+         */
+        public static final int ERROR_MODEM_ERROR = 2;
+
+        /** @hide */
+        @IntDef(prefix = {"ERROR_"}, value = {
+                ERROR_TIMEOUT,
+                ERROR_MODEM_ERROR,
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface SlicingError {}
+
+        private final int mErrorCode;
+
+        public SlicingException(@SlicingError int errorCode) {
+            mErrorCode = errorCode;
+        }
+
+        /**
+         * Fetches the error code associated with this exception.
+         * @return An error code.
+         */
+        public @SlicingError int getErrorCode() {
+            return mErrorCode;
+        }
+    }
+
+    /** @hide */
+    public static final String KEY_SLICING_CONFIG_HANDLE = "slicing_config_handle";
+
+    /**
+     * Request to get the current slicing configuration including URSP rules and
+     * NSSAIs (configured, allowed and rejected).
+     *
+     * This method can be invoked if one of the following requirements is met:
+     * <ul>
+     *     <li>If the calling app has been granted the READ_PRIVILEGED_PHONE_STATE permission; this
+     *     is a privileged permission that can only be granted to apps preloaded on the device.
+     *     <li>If the calling app has carrier privileges (see {@link #hasCarrierPrivileges}).
+     * </ul>
+     *
+     * This will be invalid if the device does not support
+     * android.telephony.TelephonyManager#CAPABILITY_SLICING_CONFIG_SUPPORTED.
+     *
+     * @param executor the executor on which callback will be invoked.
+     * @param callback a callback to receive the current slicing configuration.
+     */
+    @RequiresFeature(
+            enforcement = "android.telephony.TelephonyManager#isRadioInterfaceCapabilitySupported",
+            value = TelephonyManager.CAPABILITY_SLICING_CONFIG_SUPPORTED)
+    @SuppressAutoDoc // No support for carrier privileges (b/72967236).
+    @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    public void getNetworkSlicingConfiguration(
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull OutcomeReceiver<SlicingConfig, SlicingException> callback) {
+        Objects.requireNonNull(executor);
+        Objects.requireNonNull(callback);
+
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony == null) {
+                throw new IllegalStateException("telephony service is null.");
+            }
+            telephony.getSlicingConfig(new ResultReceiver(null) {
+                    @Override
+                    protected void onReceiveResult(int resultCode, Bundle result) {
+                        if (resultCode != SlicingException.SUCCESS) {
+                            executor.execute(() -> callback.onError(
+                                    new SlicingException(resultCode)));
+                            return;
+                        }
+                        SlicingConfig slicingConfig =
+                                result.getParcelable(KEY_SLICING_CONFIG_HANDLE);
+                        executor.execute(() -> callback.onResult(slicingConfig));
+                    }
+            });
+        } catch (RemoteException ex) {
+            ex.rethrowAsRuntimeException();
+        }
+    }
 }
diff --git a/telephony/java/android/telephony/VopsSupportInfo.aidl b/telephony/java/android/telephony/VopsSupportInfo.aidl
new file mode 100644
index 0000000..31c608f
--- /dev/null
+++ b/telephony/java/android/telephony/VopsSupportInfo.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+parcelable VopsSupportInfo;
diff --git a/telephony/java/android/telephony/VopsSupportInfo.java b/telephony/java/android/telephony/VopsSupportInfo.java
new file mode 100644
index 0000000..f89bfa9
--- /dev/null
+++ b/telephony/java/android/telephony/VopsSupportInfo.java
@@ -0,0 +1,103 @@
+/*
+ * 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 android.telephony;
+
+import android.annotation.NonNull;
+import android.annotation.SuppressLint;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.telephony.AccessNetworkConstants.AccessNetworkType;
+
+/**
+ * Abstract base class for the information related to network VoPS support.
+ * This is the base class for XxVopsSupportInfo which represent VoPS support
+ * information for specific network access techonology.
+ * @hide
+ */
+@SuppressLint("ParcelNotFinal")
+@SystemApi
+public abstract class VopsSupportInfo implements Parcelable {
+
+    /**
+     * @hide
+     */
+    public VopsSupportInfo() {}
+
+    /**
+     * Returns whether VoPS is supported by the network
+     */
+    public abstract boolean isVopsSupported();
+
+    /**
+     * Returns whether emergency service is supported by the network
+     */
+    public abstract boolean isEmergencyServiceSupported();
+
+    /**
+     * Returns whether emergency service fallback is supported by the network
+     */
+    public abstract boolean isEmergencyServiceFallbackSupported();
+
+    /**
+     * Implement the Parcelable interface
+     */
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /** Implement the Parcelable interface */
+    @Override
+    public abstract void writeToParcel(@NonNull Parcel dest, int flags);
+
+    /**
+     * Used by child classes for parceling.
+     *
+     * @hide
+     */
+    protected void writeToParcel(@NonNull Parcel dest, int flags, int type) {
+        dest.writeInt(type);
+    }
+
+    /** Implement the Parcelable interface */
+    public static final @android.annotation.NonNull Creator<VopsSupportInfo> CREATOR =
+            new Creator<VopsSupportInfo>() {
+        @Override
+        public VopsSupportInfo createFromParcel(Parcel in) {
+                int type = in.readInt();
+                switch (type) {
+                    case AccessNetworkType.EUTRAN:
+                        return LteVopsSupportInfo.createFromParcelBody(in);
+                    case AccessNetworkType.NGRAN:
+                        return NrVopsSupportInfo.createFromParcelBody(in);
+                    default: throw new RuntimeException("Bad VopsSupportInfo Parcel");
+                }
+        }
+
+        @Override
+        public VopsSupportInfo[] newArray(int size) {
+            return new VopsSupportInfo[size];
+        }
+    };
+
+    @Override
+    public abstract int hashCode();
+
+    @Override
+    public abstract boolean equals(Object o);
+}
diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java
index b503733..08f5613 100644
--- a/telephony/java/android/telephony/data/ApnSetting.java
+++ b/telephony/java/android/telephony/data/ApnSetting.java
@@ -114,11 +114,15 @@
     public static final int TYPE_MCX = ApnTypes.MCX;
     /** APN type for XCAP. */
     public static final int TYPE_XCAP = ApnTypes.XCAP;
+    /** APN type for VSIM. */
+    public static final int TYPE_VSIM = 1 << 12;  // TODO: Refer to ApnTypes.VSIM
+    /** APN type for BIP. */
+    public static final int TYPE_BIP = 1 << 13;   // TODO: Refer to ApnTypes.BIP
     /**
      * APN type for ENTERPRISE.
      * @hide
      */
-    public static final int TYPE_ENTERPRISE = TYPE_XCAP << 1;
+    public static final int TYPE_ENTERPRISE = TYPE_BIP << 1;
 
     /** @hide */
     @IntDef(flag = true, prefix = {"TYPE_"}, value = {
@@ -134,6 +138,8 @@
             TYPE_EMERGENCY,
             TYPE_MCX,
             TYPE_XCAP,
+            TYPE_BIP,
+            TYPE_VSIM,
             TYPE_ENTERPRISE,
     })
     @Retention(RetentionPolicy.SOURCE)
@@ -174,6 +180,8 @@
             TYPE_MMS_STRING,
             TYPE_SUPL_STRING,
             TYPE_XCAP_STRING,
+            TYPE_VSIM_STRING,
+            TYPE_BIP_STRING,
             TYPE_ENTERPRISE_STRING,
     }, prefix = "TYPE_", suffix = "_STRING")
     @Retention(RetentionPolicy.SOURCE)
@@ -315,8 +323,33 @@
     @SystemApi
     public static final String TYPE_XCAP_STRING = "xcap";
 
+
+
+    /**
+     * APN type for Virtual SIM service.
+     *
+     * Note: String representations of APN types are intended for system apps to communicate with
+     * modem components or carriers. Non-system apps should use the integer variants instead.
+     * @hide
+     */
+    @SystemApi
+    public static final String TYPE_VSIM_STRING = "vsim";
+
+    /**
+     * APN type for Bearer Independent Protocol.
+     *
+     * Note: String representations of APN types are intended for system apps to communicate with
+     * modem components or carriers. Non-system apps should use the integer variants instead.
+     * @hide
+     */
+    @SystemApi
+    public static final String TYPE_BIP_STRING = "bip";
+
     /**
      * APN type for ENTERPRISE traffic.
+     *
+     * Note: String representations of APN types are intended for system apps to communicate with
+     * modem components or carriers. Non-system apps should use the integer variants instead.
      * @hide
      */
     public static final String TYPE_ENTERPRISE_STRING = "enterprise";
@@ -401,6 +434,8 @@
         APN_TYPE_STRING_MAP.put(TYPE_MCX_STRING, TYPE_MCX);
         APN_TYPE_STRING_MAP.put(TYPE_XCAP_STRING, TYPE_XCAP);
         APN_TYPE_STRING_MAP.put(TYPE_ENTERPRISE_STRING, TYPE_ENTERPRISE);
+        APN_TYPE_STRING_MAP.put(TYPE_VSIM_STRING, TYPE_VSIM);
+        APN_TYPE_STRING_MAP.put(TYPE_BIP_STRING, TYPE_BIP);
 
         APN_TYPE_INT_MAP = new ArrayMap<>();
         APN_TYPE_INT_MAP.put(TYPE_DEFAULT, TYPE_DEFAULT_STRING);
@@ -416,6 +451,8 @@
         APN_TYPE_INT_MAP.put(TYPE_MCX, TYPE_MCX_STRING);
         APN_TYPE_INT_MAP.put(TYPE_XCAP, TYPE_XCAP_STRING);
         APN_TYPE_INT_MAP.put(TYPE_ENTERPRISE, TYPE_ENTERPRISE_STRING);
+        APN_TYPE_INT_MAP.put(TYPE_VSIM, TYPE_VSIM_STRING);
+        APN_TYPE_INT_MAP.put(TYPE_BIP, TYPE_BIP_STRING);
 
         PROTOCOL_STRING_MAP = new ArrayMap<>();
         PROTOCOL_STRING_MAP.put("IP", PROTOCOL_IP);
@@ -2194,7 +2231,7 @@
         public ApnSetting build() {
             if ((mApnTypeBitmask & (TYPE_DEFAULT | TYPE_MMS | TYPE_SUPL | TYPE_DUN | TYPE_HIPRI
                     | TYPE_FOTA | TYPE_IMS | TYPE_CBS | TYPE_IA | TYPE_EMERGENCY | TYPE_MCX
-                    | TYPE_XCAP | TYPE_ENTERPRISE)) == 0
+                    | TYPE_XCAP | TYPE_VSIM | TYPE_BIP | TYPE_ENTERPRISE)) == 0
                 || TextUtils.isEmpty(mApnName) || TextUtils.isEmpty(mEntryName)) {
                 return null;
             }
diff --git a/telephony/java/android/telephony/data/EpsBearerQosSessionAttributes.java b/telephony/java/android/telephony/data/EpsBearerQosSessionAttributes.java
index 406c38b..9bc7a5c 100644
--- a/telephony/java/android/telephony/data/EpsBearerQosSessionAttributes.java
+++ b/telephony/java/android/telephony/data/EpsBearerQosSessionAttributes.java
@@ -53,7 +53,7 @@
      *
      * @return the qci of the session
      */
-    public int getQci() {
+    public int getQosIdentifier() {
         return mQci;
     }
 
@@ -66,7 +66,7 @@
      *
      * @return the guaranteed bit rate in kbps
      */
-    public long getGuaranteedUplinkBitRate() {
+    public long getGuaranteedUplinkBitRateKbps() {
         return mGuaranteedUplinkBitRate;
     }
 
@@ -79,7 +79,7 @@
      *
      * @return the guaranteed bit rate in kbps
      */
-    public long getGuaranteedDownlinkBitRate() {
+    public long getGuaranteedDownlinkBitRateKbps() {
         return mGuaranteedDownlinkBitRate;
     }
 
@@ -92,7 +92,7 @@
      *
      * @return the max uplink bit rate in kbps
      */
-    public long getMaxUplinkBitRate() {
+    public long getMaxUplinkBitRateKbps() {
         return mMaxUplinkBitRate;
     }
 
@@ -105,7 +105,7 @@
      *
      * @return the max downlink bit rate in kbps
      */
-    public long getMaxDownlinkBitRate() {
+    public long getMaxDownlinkBitRateKbps() {
         return mMaxDownlinkBitRate;
     }
 
diff --git a/telephony/java/android/telephony/data/NetworkSliceInfo.java b/telephony/java/android/telephony/data/NetworkSliceInfo.java
index 1d90095..232a930 100644
--- a/telephony/java/android/telephony/data/NetworkSliceInfo.java
+++ b/telephony/java/android/telephony/data/NetworkSliceInfo.java
@@ -19,8 +19,6 @@
 import android.annotation.IntDef;
 import android.annotation.IntRange;
 import android.annotation.NonNull;
-import android.annotation.SuppressLint;
-import android.annotation.SystemApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -35,10 +33,7 @@
  * SliceServiceType defines the type of service provided by the slice, and SliceDifferentiator is
  * used to differentiate between multiple slices of the same type. If the devices is not on HPLMN,
  * the mappedHplmn versions of these 2 fields indicate the corresponding values in HPLMN.
- *
- * @hide
  */
-@SystemApi
 public final class NetworkSliceInfo implements Parcelable {
     /**
      * When set on a Slice Differentiator, this value indicates that there is no corresponding
@@ -68,14 +63,14 @@
 
     /**
      * The min acceptable value for a Slice Differentiator
+     * @hide
      */
-    @SuppressLint("MinMaxConstant")
     public static final int MIN_SLICE_DIFFERENTIATOR = -1;
 
     /**
      * The max acceptable value for a Slice Differentiator
+     * @hide
      */
-    @SuppressLint("MinMaxConstant")
     public static final int MAX_SLICE_DIFFERENTIATOR = 0xFFFFFE;
 
     /** @hide */
@@ -88,6 +83,62 @@
     @Retention(RetentionPolicy.SOURCE)
     public @interface SliceServiceType {}
 
+    /**
+     * The slice status is unknown. This can happen during IWLAN->cellular handover when the
+     * NetworkSliceInfo is received over IWLAN.
+     */
+    public static final int SLICE_STATUS_UNKNOWN = 0;
+
+    /**
+     * The slice is configured but not allowed or rejected yet.
+     */
+    public static final int SLICE_STATUS_CONFIGURED = 1;
+
+    /**
+     * The slice is allowed to be used.
+     */
+    public static final int SLICE_STATUS_ALLOWED = 2;
+
+    /**
+     * The slice is rejected because not available in PLMN.
+     */
+    public static final int SLICE_STATUS_REJECTED_NOT_AVAILABLE_IN_PLMN = 3;
+
+    /**
+     * The slice is rejected because not available in registered area.
+     */
+    public static final int SLICE_STATUS_REJECTED_NOT_AVAILABLE_IN_REGISTERED_AREA = 4;
+
+    /**
+     * The slice is configured by home operator(HPLMN) in default and is used if configured/allowed
+     * slices are not available for the serving PLMN.
+     */
+    public static final int SLICE_STATUS_DEFAULT_CONFIGURED = 5;
+
+    /**
+     * The min acceptable value for a slice status.
+     * @hide
+     */
+    public static final int MIN_SLICE_STATUS = SLICE_STATUS_UNKNOWN;
+
+    /**
+     * The max acceptable value for a slice status.
+     * @hide
+     */
+    public static final int MAX_SLICE_STATUS = SLICE_STATUS_DEFAULT_CONFIGURED;
+
+    /** @hide */
+    @IntDef(prefix = { "SLICE_STATUS_" }, value = {
+            SLICE_STATUS_UNKNOWN,
+            SLICE_STATUS_CONFIGURED,
+            SLICE_STATUS_ALLOWED,
+            SLICE_STATUS_REJECTED_NOT_AVAILABLE_IN_PLMN,
+            SLICE_STATUS_REJECTED_NOT_AVAILABLE_IN_REGISTERED_AREA,
+            SLICE_STATUS_DEFAULT_CONFIGURED,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface SliceStatus {}
+
 
     @SliceServiceType
     private final int mSliceServiceType;
@@ -97,14 +148,18 @@
     private final int mMappedHplmnSliceServiceType;
     @IntRange(from = MIN_SLICE_DIFFERENTIATOR, to = MAX_SLICE_DIFFERENTIATOR)
     private final int mMappedHplmnSliceDifferentiator;
+    @SliceStatus
+    @IntRange(from = MIN_SLICE_STATUS, to = MAX_SLICE_STATUS)
+    private final int mStatus;
 
     private NetworkSliceInfo(@SliceServiceType int sliceServiceType,
             int sliceDifferentiator, int mappedHplmnSliceServiceType,
-            int mappedHplmnSliceDifferentiator) {
+            int mappedHplmnSliceDifferentiator, int status) {
         mSliceServiceType = sliceServiceType;
         mSliceDifferentiator = sliceDifferentiator;
         mMappedHplmnSliceDifferentiator = mappedHplmnSliceDifferentiator;
         mMappedHplmnSliceServiceType = mappedHplmnSliceServiceType;
+        mStatus = status;
     }
 
     /**
@@ -157,11 +212,21 @@
         return mMappedHplmnSliceDifferentiator;
     }
 
+    /**
+     * Field to indicate the current status of the slice.
+     * @return the current status for this slice info.
+     */
+    @SliceStatus
+    public int getStatus() {
+        return mStatus;
+    }
+
     private NetworkSliceInfo(@NonNull Parcel in) {
         mSliceServiceType = in.readInt();
         mSliceDifferentiator = in.readInt();
         mMappedHplmnSliceServiceType = in.readInt();
         mMappedHplmnSliceDifferentiator = in.readInt();
+        mStatus = in.readInt();
     }
 
     @Override
@@ -175,6 +240,7 @@
         dest.writeInt(mSliceDifferentiator);
         dest.writeInt(mMappedHplmnSliceServiceType);
         dest.writeInt(mMappedHplmnSliceDifferentiator);
+        dest.writeInt(mStatus);
     }
 
     public static final @android.annotation.NonNull Parcelable.Creator<NetworkSliceInfo> CREATOR =
@@ -200,6 +266,7 @@
                 + ", mMappedHplmnSliceServiceType="
                 + sliceServiceTypeToString(mMappedHplmnSliceServiceType)
                 + ", mMappedHplmnSliceDifferentiator=" + mMappedHplmnSliceDifferentiator
+                + ", mStatus=" + sliceStatusToString(mStatus)
                 + '}';
     }
 
@@ -218,6 +285,25 @@
         }
     }
 
+    private static String sliceStatusToString(@SliceStatus int sliceStatus) {
+        switch(sliceStatus) {
+            case SLICE_STATUS_UNKNOWN:
+                return "UNKNOWN";
+            case SLICE_STATUS_CONFIGURED:
+                return "CONFIGURED";
+            case SLICE_STATUS_ALLOWED:
+                return "ALLOWED";
+            case SLICE_STATUS_REJECTED_NOT_AVAILABLE_IN_PLMN:
+                return "REJECTED_NOT_AVAILABLE_IN_PLMN";
+            case SLICE_STATUS_REJECTED_NOT_AVAILABLE_IN_REGISTERED_AREA:
+                return "REJECTED_NOT_AVAILABLE_IN_REGISTERED_AREA";
+            case SLICE_STATUS_DEFAULT_CONFIGURED:
+                return "DEFAULT_CONFIGURED";
+            default:
+                return Integer.toString(sliceStatus);
+        }
+    }
+
     @Override
     public boolean equals(Object o) {
         if (this == o) return true;
@@ -226,13 +312,14 @@
         return mSliceServiceType == sliceInfo.mSliceServiceType
                 && mSliceDifferentiator == sliceInfo.mSliceDifferentiator
                 && mMappedHplmnSliceServiceType == sliceInfo.mMappedHplmnSliceServiceType
-                && mMappedHplmnSliceDifferentiator == sliceInfo.mMappedHplmnSliceDifferentiator;
+                && mMappedHplmnSliceDifferentiator == sliceInfo.mMappedHplmnSliceDifferentiator
+                && mStatus == sliceInfo.mStatus;
     }
 
     @Override
     public int hashCode() {
         return Objects.hash(mSliceServiceType, mSliceDifferentiator, mMappedHplmnSliceServiceType,
-                mMappedHplmnSliceDifferentiator);
+                mMappedHplmnSliceDifferentiator, mStatus);
     }
 
     /**
@@ -257,6 +344,9 @@
         private int mMappedHplmnSliceServiceType = SLICE_SERVICE_TYPE_NONE;
         @IntRange(from = MIN_SLICE_DIFFERENTIATOR, to = MAX_SLICE_DIFFERENTIATOR)
         private int mMappedHplmnSliceDifferentiator = SLICE_DIFFERENTIATOR_NO_SLICE;
+        @SliceStatus
+        @IntRange(from = MIN_SLICE_STATUS, to = MAX_SLICE_STATUS)
+        private int mStatus = SLICE_STATUS_UNKNOWN;
 
         /**
          * Default constructor for Builder.
@@ -281,8 +371,7 @@
          * A value of {@link #SLICE_DIFFERENTIATOR_NO_SLICE} indicates that there is no
          * corresponding Slice.
          *
-         * @throws IllegalArgumentException if the parameter is not between
-         * {@link #MIN_SLICE_DIFFERENTIATOR} and {@link #MAX_SLICE_DIFFERENTIATOR}.
+         * @throws IllegalArgumentException if the parameter is not in the expected range.
          *
          * @return The same instance of the builder.
          */
@@ -316,8 +405,7 @@
          * A value of {@link #SLICE_DIFFERENTIATOR_NO_SLICE} indicates that there is no
          * corresponding Slice of the HPLMN.
          *
-         * @throws IllegalArgumentException if the parameter is not between
-         * {@link #MIN_SLICE_DIFFERENTIATOR} and {@link #MAX_SLICE_DIFFERENTIATOR}.
+         * @throws IllegalArgumentException if the parameter is not in the expected range.
          *
          * @return The same instance of the builder.
          */
@@ -334,6 +422,22 @@
         }
 
         /**
+         * Set the slice status.
+         *
+         * @throws IllegalArgumentException if the status is invalid.
+         *
+         * @return The same instance of the builder.
+         */
+        @NonNull
+        public Builder setStatus(@SliceStatus int status) {
+            if (status < MIN_SLICE_STATUS || status > MAX_SLICE_STATUS) {
+                throw new IllegalArgumentException("The slice status is not valid");
+            }
+            this.mStatus = status;
+            return this;
+        }
+
+        /**
          * Build the {@link NetworkSliceInfo}.
          *
          * @return the {@link NetworkSliceInfo} object.
@@ -341,7 +445,8 @@
         @NonNull
         public NetworkSliceInfo build() {
             return new NetworkSliceInfo(this.mSliceServiceType, this.mSliceDifferentiator,
-                    this.mMappedHplmnSliceServiceType, this.mMappedHplmnSliceDifferentiator);
+                    this.mMappedHplmnSliceServiceType, this.mMappedHplmnSliceDifferentiator,
+                    this.mStatus);
         }
     }
 }
diff --git a/telephony/java/android/telephony/data/NrQos.java b/telephony/java/android/telephony/data/NrQos.java
index 2011eed..fe124ac 100644
--- a/telephony/java/android/telephony/data/NrQos.java
+++ b/telephony/java/android/telephony/data/NrQos.java
@@ -50,6 +50,18 @@
         return new NrQos(in);
     }
 
+    public int get5Qi() {
+        return fiveQi;
+    }
+
+    public int getQfi() {
+        return qosFlowId;
+    }
+
+    public int getAveragingWindow() {
+        return averagingWindowMs;
+    }
+
     @Override
     public void writeToParcel(@NonNull Parcel dest, int flags) {
         super.writeToParcel(Qos.QOS_TYPE_NR, dest, flags);
diff --git a/services/core/java/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneIdValidator.java b/telephony/java/android/telephony/data/NrQosSessionAttributes.aidl
similarity index 61%
copy from services/core/java/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneIdValidator.java
copy to telephony/java/android/telephony/data/NrQosSessionAttributes.aidl
index cab5ad2..fd3bbb0 100644
--- a/services/core/java/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneIdValidator.java
+++ b/telephony/java/android/telephony/data/NrQosSessionAttributes.aidl
@@ -14,17 +14,6 @@
  * limitations under the License.
  */
 
-package com.android.server.timezonedetector.location;
+ package android.telephony.data;
 
-import android.annotation.NonNull;
-
-import com.android.i18n.timezone.ZoneInfoDb;
-
-class ZoneInfoDbTimeZoneIdValidator implements
-        LocationTimeZoneProvider.TimeZoneIdValidator {
-
-    @Override
-    public boolean isValid(@NonNull String timeZoneId) {
-        return ZoneInfoDb.getInstance().hasTimeZone(timeZoneId);
-    }
-}
+ parcelable NrQosSessionAttributes;
diff --git a/telephony/java/android/telephony/data/NrQosSessionAttributes.java b/telephony/java/android/telephony/data/NrQosSessionAttributes.java
new file mode 100644
index 0000000..4c37687
--- /dev/null
+++ b/telephony/java/android/telephony/data/NrQosSessionAttributes.java
@@ -0,0 +1,259 @@
+/*
+ * 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 android.telephony.data;
+
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.net.QosSessionAttributes;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.UnknownHostException;
+import java.time.Duration;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Provides Qos attributes of an NR bearer.
+ *
+ * {@hide}
+ */
+@SystemApi
+public final class NrQosSessionAttributes implements Parcelable, QosSessionAttributes {
+    private static final String TAG = NrQosSessionAttributes.class.getSimpleName();
+    private final int m5Qi;
+    private final @IntRange(from=1, to=63) int mQfi;
+    private final long mMaxUplinkBitRate;
+    private final long mMaxDownlinkBitRate;
+    private final long mGuaranteedUplinkBitRate;
+    private final long mGuaranteedDownlinkBitRate;
+    private final long mAveragingWindow;
+    @NonNull private final List<InetSocketAddress> mRemoteAddresses;
+
+    /**
+     * 5G QOS Identifier (5QI), see 3GPP TS 24.501 and 23.501.
+     * The allowed values are standard values(1-9, 65-68, 69-70, 75, 79-80, 82-85)
+     * defined in the spec and operator specific values in the range 128-254.
+     *
+     * @return the 5QI of the QOS flow
+     */
+    public int getQosIdentifier() {
+        return m5Qi;
+    }
+
+    /**
+     * QOS flow identifier of the QOS flow description in the
+     * range of 1 to 63. see 3GPP TS 24.501 and 23.501.
+     *
+     * @return the QOS flow identifier of the session
+     */
+    public @IntRange(from=1, to=63) int getQosFlowIdentifier() {
+        return mQfi;
+    }
+
+    /**
+     * Minimum bit rate in kbps that is guaranteed to be provided by the network on the uplink.
+     *
+     * see 3GPP TS 24.501 section 6.2.5
+     *
+     * Note: The Qos Session may be shared with OTHER applications besides yours.
+     *
+     * @return the guaranteed bit rate in kbps
+     */
+    public long getGuaranteedUplinkBitRateKbps() {
+        return mGuaranteedUplinkBitRate;
+    }
+
+    /**
+     * Minimum bit rate in kbps that is guaranteed to be provided by the network on the downlink.
+     *
+     * see 3GPP TS 24.501 section 6.2.5
+     *
+     * Note: The Qos Session may be shared with OTHER applications besides yours.
+     *
+     * @return the guaranteed bit rate in kbps
+     */
+    public long getGuaranteedDownlinkBitRateKbps() {
+        return mGuaranteedDownlinkBitRate;
+    }
+
+    /**
+     * The maximum uplink kbps that the network will accept.
+     *
+     * see 3GPP TS 24.501 section 6.2.5
+     *
+     * Note: The Qos Session may be shared with OTHER applications besides yours.
+     *
+     * @return the max uplink bit rate in kbps
+     */
+    public long getMaxUplinkBitRateKbps() {
+        return mMaxUplinkBitRate;
+    }
+
+    /**
+     * The maximum downlink kbps that the network can provide.
+     *
+     * see 3GPP TS 24.501 section 6.2.5
+     *
+     * Note: The Qos Session may be shared with OTHER applications besides yours.
+     *
+     * @return the max downlink bit rate in kbps
+     */
+    public long getMaxDownlinkBitRateKbps() {
+        return mMaxDownlinkBitRate;
+    }
+
+    /**
+     * The duration in milliseconds over which the maximum bit rates and guaranteed bit rates
+     * are calculated
+     *
+     * see 3GPP TS 24.501 section 6.2.5
+     *
+     * @return the averaging window duration in milliseconds
+     */
+    @NonNull
+    public Duration getBitRateWindowDuration() {
+        return Duration.ofMillis(mAveragingWindow);
+    }
+
+    /**
+     * List of remote addresses associated with the Qos Session.  The given uplink bit rates apply
+     * to this given list of remote addresses.
+     *
+     * Note: In the event that the list is empty, it is assumed that the uplink bit rates apply to
+     * all remote addresses that are not contained in a different set of attributes.
+     *
+     * @return list of remote socket addresses that the attributes apply to
+     */
+    @NonNull
+    public List<InetSocketAddress> getRemoteAddresses() {
+        return mRemoteAddresses;
+    }
+
+    /**
+     * ..ctor for attributes
+     *
+     * @param fiveQi 5G quality class indicator
+     * @param qfi QOS flow identifier
+     * @param maxDownlinkBitRate the max downlink bit rate in kbps
+     * @param maxUplinkBitRate the max uplink bit rate in kbps
+     * @param guaranteedDownlinkBitRate the guaranteed downlink bit rate in kbps
+     * @param guaranteedUplinkBitRate the guaranteed uplink bit rate in kbps
+     * @param averagingWindow the averaging window duration in milliseconds
+     * @param remoteAddresses the remote addresses that the uplink bit rates apply to
+     *
+     * @hide
+     */
+    public NrQosSessionAttributes(final int fiveQi, final int qfi,
+            final long maxDownlinkBitRate, final long maxUplinkBitRate,
+            final long guaranteedDownlinkBitRate, final long guaranteedUplinkBitRate,
+            final long averagingWindow, @NonNull final List<InetSocketAddress> remoteAddresses) {
+        Objects.requireNonNull(remoteAddresses, "remoteAddress must be non-null");
+        m5Qi = fiveQi;
+        mQfi = qfi;
+        mMaxDownlinkBitRate = maxDownlinkBitRate;
+        mMaxUplinkBitRate = maxUplinkBitRate;
+        mGuaranteedDownlinkBitRate = guaranteedDownlinkBitRate;
+        mGuaranteedUplinkBitRate = guaranteedUplinkBitRate;
+        mAveragingWindow = averagingWindow;
+
+        final List<InetSocketAddress> remoteAddressesTemp = copySocketAddresses(remoteAddresses);
+        mRemoteAddresses = Collections.unmodifiableList(remoteAddressesTemp);
+    }
+
+    private static List<InetSocketAddress> copySocketAddresses(
+            @NonNull final List<InetSocketAddress> remoteAddresses) {
+        final List<InetSocketAddress> remoteAddressesTemp = new ArrayList<>();
+        for (final InetSocketAddress socketAddress : remoteAddresses) {
+            if (socketAddress != null && socketAddress.getAddress() != null) {
+                remoteAddressesTemp.add(socketAddress);
+            }
+        }
+        return remoteAddressesTemp;
+    }
+
+    private NrQosSessionAttributes(@NonNull final Parcel in) {
+        m5Qi = in.readInt();
+        mQfi = in.readInt();
+        mMaxDownlinkBitRate = in.readLong();
+        mMaxUplinkBitRate = in.readLong();
+        mGuaranteedDownlinkBitRate = in.readLong();
+        mGuaranteedUplinkBitRate = in.readLong();
+        mAveragingWindow = in.readLong();
+
+        final int size = in.readInt();
+        final List<InetSocketAddress> remoteAddresses = new ArrayList<>(size);
+        for (int i = 0; i < size; i++) {
+            final byte[] addressBytes = in.createByteArray();
+            final int port = in.readInt();
+            try {
+                remoteAddresses.add(
+                        new InetSocketAddress(InetAddress.getByAddress(addressBytes), port));
+            } catch (final UnknownHostException e) {
+                // Impossible case since its filtered out the null values in the ..ctor
+                Log.e(TAG, "unable to unparcel remote address at index: " + i, e);
+            }
+        }
+        mRemoteAddresses = Collections.unmodifiableList(remoteAddresses);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull final Parcel dest, final int flags) {
+        dest.writeInt(m5Qi);
+        dest.writeInt(mQfi);
+        dest.writeLong(mMaxDownlinkBitRate);
+        dest.writeLong(mMaxUplinkBitRate);
+        dest.writeLong(mGuaranteedDownlinkBitRate);
+        dest.writeLong(mGuaranteedUplinkBitRate);
+        dest.writeLong(mAveragingWindow);
+
+        final int size = mRemoteAddresses.size();
+        dest.writeInt(size);
+        for (int i = 0; i < size; i++) {
+            final InetSocketAddress address = mRemoteAddresses.get(i);
+            dest.writeByteArray(address.getAddress().getAddress());
+            dest.writeInt(address.getPort());
+        }
+    }
+
+    @NonNull
+    public static final Creator<NrQosSessionAttributes> CREATOR =
+            new Creator<NrQosSessionAttributes>() {
+        @NonNull
+        @Override
+        public NrQosSessionAttributes createFromParcel(@NonNull final Parcel in) {
+            return new NrQosSessionAttributes(in);
+        }
+
+        @NonNull
+        @Override
+        public NrQosSessionAttributes[] newArray(final int size) {
+            return new NrQosSessionAttributes[size];
+        }
+    };
+}
diff --git a/telephony/java/android/telephony/data/RouteSelectionDescriptor.aidl b/telephony/java/android/telephony/data/RouteSelectionDescriptor.aidl
new file mode 100644
index 0000000..563a00e
--- /dev/null
+++ b/telephony/java/android/telephony/data/RouteSelectionDescriptor.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.data;
+
+parcelable RouteSelectionDescriptor;
diff --git a/telephony/java/android/telephony/data/RouteSelectionDescriptor.java b/telephony/java/android/telephony/data/RouteSelectionDescriptor.java
new file mode 100644
index 0000000..c2457f2
--- /dev/null
+++ b/telephony/java/android/telephony/data/RouteSelectionDescriptor.java
@@ -0,0 +1,263 @@
+/**
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.data;
+
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Represents a single route selection descriptor as defined in
+ * 3GPP TS 24.526.
+ */
+public final class RouteSelectionDescriptor implements Parcelable {
+    /**
+     * The min acceptable value for the precedence of a route selection descriptor.
+     * @hide
+     */
+    public static final int MIN_ROUTE_PRECEDENCE = 0;
+
+    /**
+     * The max acceptable value for the precedence of a route selection descriptor.
+     * @hide
+     */
+    public static final int MAX_ROUTE_PRECEDENCE = 255;
+
+    /**
+     * The route selection descriptor is for the session with IPV4 type.
+     */
+    public static final int SESSION_TYPE_IPV4 = 0;
+
+    /**
+     * The route selection descriptor is for the session with IPV6 type.
+     */
+    public static final int SESSION_TYPE_IPV6 = 1;
+
+    /**
+     * The route selection descriptor is for the session with both IP and IPV6 types.
+     */
+    public static final int SESSION_TYPE_IPV4V6 = 2;
+
+    /** @hide */
+    @IntDef(prefix = { "SESSION_TYPE_" }, value = {
+            SESSION_TYPE_IPV4,
+            SESSION_TYPE_IPV6,
+            SESSION_TYPE_IPV4V6,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface RouteSessionType {}
+
+    /**
+     * The route selection descriptor is using SSC mode 1. The session will provide continual
+     * support when UE's location is updated.
+     */
+    public static final int ROUTE_SSC_MODE_1 = 1;
+
+    /**
+     * The route selection descriptor is using SSC mode 2. The new session for the same network
+     * will be established after releasing the old session when UE's location is updated.
+     */
+    public static final int ROUTE_SSC_MODE_2 = 2;
+
+    /**
+     * The route selection descriptor is using SSC mode 3. The new session for the same network is
+     * allowed to be established before releasing the old session when UE's location is updated.
+     */
+    public static final int ROUTE_SSC_MODE_3 = 3;
+
+    /**
+     * The min acceptable value for the SSC mode of a route selection descriptor.
+     * @hide
+     */
+    public static final int MIN_ROUTE_SSC_MODE = ROUTE_SSC_MODE_1;
+
+    /**
+     * The max acceptable value for the SSC mode of a route selection descriptor.
+     * @hide
+     */
+    public static final int MAX_ROUTE_SSC_MODE = ROUTE_SSC_MODE_3;
+
+    /** @hide */
+    @IntDef(prefix = { "ROUTE_SSC_MODE_" }, value = {
+            ROUTE_SSC_MODE_1,
+            ROUTE_SSC_MODE_2,
+            ROUTE_SSC_MODE_3,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface RouteSscMode {}
+
+    @IntRange(from = MIN_ROUTE_PRECEDENCE, to = MAX_ROUTE_PRECEDENCE)
+    private final int mPrecedence;
+    @RouteSessionType
+    private final int mSessionType;
+    @RouteSscMode
+    @IntRange(from = MIN_ROUTE_SSC_MODE, to = MAX_ROUTE_SSC_MODE)
+    private final int mSscMode;
+    private final List<NetworkSliceInfo> mSliceInfo;
+    private final List<String> mDnn;
+
+    /** @hide */
+    RouteSelectionDescriptor(android.hardware.radio.V1_6.RouteSelectionDescriptor rsd) {
+        this(rsd.precedence, rsd.sessionType.value(), rsd.sscMode.value(), rsd.sliceInfo,
+                rsd.dnn);
+    }
+
+    /** @hide */
+    public RouteSelectionDescriptor(int precedence, int sessionType, int sscMode,
+            List<android.hardware.radio.V1_6.SliceInfo> sliceInfo, List<String> dnn) {
+        mPrecedence = precedence;
+        mSessionType = sessionType;
+        mSscMode = sscMode;
+        mSliceInfo = new ArrayList<NetworkSliceInfo>();
+        for (android.hardware.radio.V1_6.SliceInfo si : sliceInfo) {
+            mSliceInfo.add(sliceInfoBuilder(si));
+        }
+        mDnn = new ArrayList<String>();
+        mDnn.addAll(dnn);
+    }
+
+    private NetworkSliceInfo sliceInfoBuilder(android.hardware.radio.V1_6.SliceInfo si) {
+        NetworkSliceInfo.Builder builder = new NetworkSliceInfo.Builder()
+                .setSliceServiceType(si.sst)
+                .setMappedHplmnSliceServiceType(si.mappedHplmnSst);
+        if (si.sliceDifferentiator != NetworkSliceInfo.SLICE_DIFFERENTIATOR_NO_SLICE) {
+            builder
+                .setSliceDifferentiator(si.sliceDifferentiator)
+                .setMappedHplmnSliceDifferentiator(si.mappedHplmnSD);
+        }
+        return builder.build();
+    }
+
+    private RouteSelectionDescriptor(Parcel p) {
+        mPrecedence = p.readInt();
+        mSessionType = p.readInt();
+        mSscMode = p.readInt();
+        mSliceInfo = p.createTypedArrayList(NetworkSliceInfo.CREATOR);
+        mDnn = new ArrayList<String>();
+        p.readStringList(mDnn);
+    }
+
+    /**
+     * Precedence value in the range of 0 to 255. Higher value has lower precedence.
+     * @return the precedence value for this route selection descriptor.
+     */
+    @IntRange(from = MIN_ROUTE_PRECEDENCE, to = MAX_ROUTE_PRECEDENCE)
+    public int getPrecedence() {
+        return mPrecedence;
+    }
+
+    /**
+     * This is used for checking which session type defined in 3GPP TS 23.501 is allowed for the
+     * route in a route selection descriptor.
+     * @return the session type for this route selection descriptor.
+     */
+    @RouteSessionType
+    public int getSessionType() {
+        return mSessionType;
+    }
+
+    /**
+     * SSC mode stands for Session and Service Continuity mode (which specifies the IP continuity
+     * mode) as defined in 3GPP TS 23.501.
+     * @return the SSC mode for this route selection descriptor.
+     */
+    @RouteSscMode
+    public int getSscMode() {
+        return mSscMode;
+    }
+
+    /**
+     * This is the list of all the slices available in the route selection descriptor as indicated
+     * by the network. These are the slices that can be used by the device if this route selection
+     * descriptor is used based the traffic (see 3GPP TS 23.501 for details).
+     * @return the list of all the slices available in the route selection descriptor.
+     */
+    public @NonNull List<NetworkSliceInfo> getSliceInfo() {
+        return mSliceInfo;
+    }
+
+    /**
+     * DNN stands for Data Network Name and represents an APN as defined in 3GPP TS 23.003. There
+     * can be 0 or more DNNs specified in a route selection descriptor.
+     * @return the list of DNN for this route selection descriptor.
+     */
+    public @NonNull List<String> getDataNetworkName() {
+        return mDnn;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeInt(mPrecedence);
+        dest.writeInt(mSessionType);
+        dest.writeInt(mSscMode);
+        dest.writeTypedList(mSliceInfo, flags);
+        dest.writeStringList(mDnn);
+    }
+
+    public static final @NonNull Parcelable.Creator<RouteSelectionDescriptor> CREATOR =
+            new Parcelable.Creator<RouteSelectionDescriptor>() {
+                @Override
+                public RouteSelectionDescriptor createFromParcel(Parcel source) {
+                    return new RouteSelectionDescriptor(source);
+                }
+
+                @Override
+                public RouteSelectionDescriptor[] newArray(int size) {
+                    return new RouteSelectionDescriptor[size];
+                }
+            };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        RouteSelectionDescriptor that = (RouteSelectionDescriptor) o;
+        return mPrecedence == that.mPrecedence
+                && mSessionType == that.mSessionType
+                && mSscMode == that.mSscMode
+                && mSliceInfo.size() == that.mSliceInfo.size()
+                && mSliceInfo.containsAll(that.mSliceInfo)
+                && mDnn.size() == that.mDnn.size()
+                && mDnn.containsAll(that.mDnn);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mPrecedence, mSessionType, mSscMode, mSliceInfo, mDnn);
+    }
+
+    @Override
+    public String toString() {
+        return "{.precedence = " + mPrecedence + ", .sessionType = " + mSessionType
+                + ", .sscMode = " + mSscMode + ", .sliceInfo = " + mSliceInfo
+                + ", .dnn = " + mDnn + "}";
+    }
+}
diff --git a/telephony/java/android/telephony/data/SlicingConfig.aidl b/telephony/java/android/telephony/data/SlicingConfig.aidl
new file mode 100644
index 0000000..ad93d8c
--- /dev/null
+++ b/telephony/java/android/telephony/data/SlicingConfig.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.data;
+
+parcelable SlicingConfig;
diff --git a/telephony/java/android/telephony/data/SlicingConfig.java b/telephony/java/android/telephony/data/SlicingConfig.java
new file mode 100644
index 0000000..990e4d2
--- /dev/null
+++ b/telephony/java/android/telephony/data/SlicingConfig.java
@@ -0,0 +1,137 @@
+/**
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.data;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Represents a slicing configuration
+ */
+public final class SlicingConfig implements Parcelable {
+    private final List<UrspRule> mUrspRules;
+    private final List<NetworkSliceInfo> mSliceInfo;
+
+    public SlicingConfig() {
+        mUrspRules = new ArrayList<UrspRule>();
+        mSliceInfo = new ArrayList<NetworkSliceInfo>();
+    }
+
+    /** @hide */
+    public SlicingConfig(android.hardware.radio.V1_6.SlicingConfig sc) {
+        this(sc.urspRules, sc.sliceInfo);
+    }
+
+    /** @hide */
+    public SlicingConfig(List<android.hardware.radio.V1_6.UrspRule> urspRules,
+            List<android.hardware.radio.V1_6.SliceInfo> sliceInfo) {
+        mUrspRules = new ArrayList<UrspRule>();
+        for (android.hardware.radio.V1_6.UrspRule ur : urspRules) {
+            mUrspRules.add(new UrspRule(ur.precedence, ur.trafficDescriptors,
+                    ur.routeSelectionDescriptor));
+        }
+        mSliceInfo = new ArrayList<NetworkSliceInfo>();
+        for (android.hardware.radio.V1_6.SliceInfo si : sliceInfo) {
+            mSliceInfo.add(sliceInfoBuilder(si));
+        }
+    }
+
+    private NetworkSliceInfo sliceInfoBuilder(android.hardware.radio.V1_6.SliceInfo si) {
+        NetworkSliceInfo.Builder builder = new NetworkSliceInfo.Builder()
+                .setSliceServiceType(si.sst)
+                .setMappedHplmnSliceServiceType(si.mappedHplmnSst);
+        if (si.sliceDifferentiator != NetworkSliceInfo.SLICE_DIFFERENTIATOR_NO_SLICE) {
+            builder
+                .setSliceDifferentiator(si.sliceDifferentiator)
+                .setMappedHplmnSliceDifferentiator(si.mappedHplmnSD);
+        }
+        return builder.build();
+    }
+
+    /** @hide */
+    public SlicingConfig(Parcel p) {
+        mUrspRules = p.createTypedArrayList(UrspRule.CREATOR);
+        mSliceInfo = p.createTypedArrayList(NetworkSliceInfo.CREATOR);
+    }
+
+    /**
+     * This list contains the current URSP rules. Empty list represents that no rules are
+     * configured.
+     * @return the current URSP rules for this slicing configuration.
+     */
+    public @NonNull List<UrspRule> getUrspRules() {
+        return mUrspRules;
+    }
+
+    /**
+     * @return the list of all slices for this slicing configuration.
+     */
+    public @NonNull List<NetworkSliceInfo> getSliceInfo() {
+        return mSliceInfo;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeTypedList(mUrspRules, flags);
+        dest.writeTypedList(mSliceInfo, flags);
+    }
+
+    public static final @NonNull Parcelable.Creator<SlicingConfig> CREATOR =
+            new Parcelable.Creator<SlicingConfig>() {
+                @Override
+                public SlicingConfig createFromParcel(Parcel source) {
+                    return new SlicingConfig(source);
+                }
+
+                @Override
+                public SlicingConfig[] newArray(int size) {
+                    return new SlicingConfig[size];
+                }
+            };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        SlicingConfig that = (SlicingConfig) o;
+        return mUrspRules.size() == that.mUrspRules.size()
+                && mUrspRules.containsAll(that.mUrspRules)
+                && mSliceInfo.size() == that.mSliceInfo.size()
+                && mSliceInfo.containsAll(that.mSliceInfo);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mUrspRules, mSliceInfo);
+    }
+
+    @Override
+    public String toString() {
+        return "{.urspRules = " + mUrspRules + ", .sliceInfo = " + mSliceInfo + "}";
+    }
+}
diff --git a/telephony/java/android/telephony/data/TrafficDescriptor.java b/telephony/java/android/telephony/data/TrafficDescriptor.java
index 480379d..d813bc5 100644
--- a/telephony/java/android/telephony/data/TrafficDescriptor.java
+++ b/telephony/java/android/telephony/data/TrafficDescriptor.java
@@ -18,20 +18,17 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.annotation.SystemApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 
 import java.util.Objects;
 
 /**
- * A traffic descriptor, as defined in 3GPP TS 24.526 Section 5.2. It is used for URSP traffic
- * matching as described in 3GPP TS 24.526 Section 4.2.2. It includes an optional DNN, which,
- * if present, must be used for traffic matching; it does not specify the end point to be used for
- * the data call.
- * @hide
+ * A traffic descriptor, as defined in 3GPP TS 24.526 Section 5.2. It is used for UE Route Selection
+ * Policy(URSP) traffic matching as described in 3GPP TS 24.526 Section 4.2.2. It includes an
+ * optional Data Network Name(DNN), which, if present, must be used for traffic matching; it does
+ * not specify the end point to be used for the data call.
  */
-@SystemApi
 public final class TrafficDescriptor implements Parcelable {
     private final String mDnn;
     private final String mOsAppId;
@@ -45,8 +42,10 @@
      * Create a traffic descriptor, as defined in 3GPP TS 24.526 Section 5.2
      * @param dnn optional DNN, which must be used for traffic matching, if present
      * @param osAppId OsId + osAppId of the traffic descriptor
+     *
+     * @hide
      */
-    public TrafficDescriptor(@Nullable String dnn, @Nullable String osAppId) {
+    public TrafficDescriptor(String dnn, String osAppId) {
         mDnn = dnn;
         mOsAppId = osAppId;
     }
@@ -55,12 +54,13 @@
      * DNN stands for Data Network Name and represents an APN as defined in 3GPP TS 23.003.
      * @return the DNN of this traffic descriptor.
      */
-    public @Nullable String getDnn() {
+    public @Nullable String getDataNetworkName() {
         return mDnn;
     }
 
     /**
-     * OsAppId represents the OsId + OsAppId as defined in 3GPP TS 24.526 Section 5.2.
+     * OsAppId is the app id as defined in 3GPP TS 24.526 Section 5.2, and it identifies a traffic
+     * category.
      * @return the OS App ID of this traffic descriptor.
      */
     public @Nullable String getOsAppId() {
@@ -108,4 +108,65 @@
     public int hashCode() {
         return Objects.hash(mDnn, mOsAppId);
     }
+
+    /**
+     * Provides a convenient way to set the fields of a {@link TrafficDescriptor} when creating a
+     * new instance.
+     *
+     * <p>The example below shows how you might create a new {@code TrafficDescriptor}:
+     *
+     * <pre><code>
+     *
+     * TrafficDescriptor response = new TrafficDescriptor.Builder()
+     *     .setDnn("")
+     *     .build();
+     * </code></pre>
+     */
+    public static final class Builder {
+        private String mDnn = null;
+        private String mOsAppId = null;
+
+        /**
+         * Default constructor for Builder.
+         */
+        public Builder() {
+        }
+
+        /**
+         * Set the Data Network Name(DNN).
+         *
+         * @return The same instance of the builder.
+         */
+        @NonNull
+        public Builder setDataNetworkName(@NonNull String dnn) {
+            this.mDnn = dnn;
+            return this;
+        }
+
+        /**
+         * Set the OS App ID.
+         *
+         * @return The same instance of the builder.
+         */
+        @NonNull
+        public Builder setOsAppId(@NonNull String osAppId) {
+            this.mOsAppId = osAppId;
+            return this;
+        }
+
+        /**
+         * Build the {@link TrafficDescriptor}.
+         *
+         * @throws IllegalArgumentException if DNN and OS App ID are null.
+         *
+         * @return the {@link TrafficDescriptor} object.
+         */
+        @NonNull
+        public TrafficDescriptor build() {
+            if (this.mDnn == null && this.mOsAppId == null) {
+                throw new IllegalArgumentException("DNN and OS App ID are null");
+            }
+            return new TrafficDescriptor(this.mDnn, this.mOsAppId);
+        }
+    }
 }
diff --git a/telephony/java/android/telephony/data/UrspRule.aidl b/telephony/java/android/telephony/data/UrspRule.aidl
new file mode 100644
index 0000000..2bed583
--- /dev/null
+++ b/telephony/java/android/telephony/data/UrspRule.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.data;
+
+parcelable UrspRule;
diff --git a/telephony/java/android/telephony/data/UrspRule.java b/telephony/java/android/telephony/data/UrspRule.java
new file mode 100644
index 0000000..e2c47fd
--- /dev/null
+++ b/telephony/java/android/telephony/data/UrspRule.java
@@ -0,0 +1,178 @@
+/**
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.data;
+
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.hardware.radio.V1_6.OptionalDnn;
+import android.hardware.radio.V1_6.OptionalOsAppId;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Represents a single URSP rule as defined in 3GPP TS 24.526. URSP stands for UE Route Selection
+ * Policy. In 5G, network can provide URSP information to devices which provides information on
+ * what connection parameters should be used for what traffic.
+ */
+public final class UrspRule implements Parcelable {
+    /**
+     * The min acceptable value for the precedence of a URSP rule.
+     * @hide
+     */
+    public static final int MIN_URSP_PRECEDENCE = 0;
+
+    /**
+     * The max acceptable value for the precedence of a URSP rule.
+     * @hide
+     */
+    public static final int MAX_URSP_PRECEDENCE = 255;
+
+    @IntRange(from = MIN_URSP_PRECEDENCE, to = MAX_URSP_PRECEDENCE)
+    private final int mPrecedence;
+    private final List<TrafficDescriptor> mTrafficDescriptors;
+    private final List<RouteSelectionDescriptor> mRouteSelectionDescriptor;
+
+    UrspRule(android.hardware.radio.V1_6.UrspRule ur) {
+        this(ur.precedence, ur.trafficDescriptors, ur.routeSelectionDescriptor);
+    }
+
+    /** @hide */
+    public UrspRule(int precedence,
+            List<android.hardware.radio.V1_6.TrafficDescriptor> trafficDescriptors,
+            List<android.hardware.radio.V1_6.RouteSelectionDescriptor> routeSelectionDescriptor) {
+        mPrecedence = precedence;
+        mTrafficDescriptors = new ArrayList<TrafficDescriptor>();
+        for (android.hardware.radio.V1_6.TrafficDescriptor td : trafficDescriptors) {
+            mTrafficDescriptors.add(convertToTrafficDescriptor(td));
+        }
+        mRouteSelectionDescriptor = new ArrayList<RouteSelectionDescriptor>();
+        for (android.hardware.radio.V1_6.RouteSelectionDescriptor rsd : routeSelectionDescriptor) {
+            mRouteSelectionDescriptor.add(new RouteSelectionDescriptor(rsd));
+        }
+    }
+
+    /** Convert an ArrayList of Bytes to an exactly-sized primitive array */
+    private byte[] arrayListToPrimitiveArray(ArrayList<Byte> bytes) {
+        byte[] ret = new byte[bytes.size()];
+        for (int i = 0; i < ret.length; i++) {
+            ret[i] = bytes.get(i);
+        }
+        return ret;
+    }
+
+    private TrafficDescriptor convertToTrafficDescriptor(
+            android.hardware.radio.V1_6.TrafficDescriptor td) {
+        String dnn = td.dnn.getDiscriminator() == OptionalDnn.hidl_discriminator.noinit
+                ? null : td.dnn.value();
+        String osAppId = td.osAppId.getDiscriminator() == OptionalOsAppId.hidl_discriminator.noinit
+                ? null : new String(arrayListToPrimitiveArray(td.osAppId.value().osAppId));
+        TrafficDescriptor.Builder builder = new TrafficDescriptor.Builder();
+        if (dnn != null) {
+            builder.setDataNetworkName(dnn);
+        }
+        if (osAppId != null) {
+            builder.setOsAppId(osAppId);
+        }
+        return builder.build();
+    }
+
+    private UrspRule(Parcel p) {
+        mPrecedence = p.readInt();
+        mTrafficDescriptors = p.createTypedArrayList(TrafficDescriptor.CREATOR);
+        mRouteSelectionDescriptor = p.createTypedArrayList(RouteSelectionDescriptor.CREATOR);
+    }
+
+    /**
+     * Precedence value in the range of 0 to 255. Higher value has lower precedence.
+     * @return the precedence value for this URSP rule.
+     */
+    @IntRange(from = MIN_URSP_PRECEDENCE, to = MAX_URSP_PRECEDENCE)
+    public int getPrecedence() {
+        return mPrecedence;
+    }
+
+    /**
+     * These traffic descriptors are used as a matcher for network requests.
+     * @return the traffic descriptors which are associated to this URSP rule.
+     */
+    public @NonNull List<TrafficDescriptor> getTrafficDescriptors() {
+        return mTrafficDescriptors;
+    }
+
+    /**
+     * List of routes (connection parameters) that must be used by the device for requests matching
+     * a traffic descriptor.
+     * @return the route selection descriptors which are associated to this URSP rule.
+     */
+    public @NonNull List<RouteSelectionDescriptor> getRouteSelectionDescriptor() {
+        return mRouteSelectionDescriptor;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeInt(mPrecedence);
+        dest.writeTypedList(mTrafficDescriptors, flags);
+        dest.writeTypedList(mRouteSelectionDescriptor, flags);
+    }
+
+    public static final @NonNull Parcelable.Creator<UrspRule> CREATOR =
+            new Parcelable.Creator<UrspRule>() {
+                @Override
+                public UrspRule createFromParcel(Parcel source) {
+                    return new UrspRule(source);
+                }
+
+                @Override
+                public UrspRule[] newArray(int size) {
+                    return new UrspRule[size];
+                }
+            };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        UrspRule that = (UrspRule) o;
+        return mPrecedence == that.mPrecedence
+                && mTrafficDescriptors.size() == that.mTrafficDescriptors.size()
+                && mTrafficDescriptors.containsAll(that.mTrafficDescriptors)
+                && mRouteSelectionDescriptor.size() == that.mRouteSelectionDescriptor.size()
+                && mRouteSelectionDescriptor.containsAll(that.mRouteSelectionDescriptor);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mPrecedence, mTrafficDescriptors, mRouteSelectionDescriptor);
+    }
+
+    @Override
+    public String toString() {
+        return "{.precedence = " + mPrecedence + ", .trafficDescriptors = " + mTrafficDescriptors
+                + ", .routeSelectionDescriptor = " + mRouteSelectionDescriptor + "}";
+    }
+}
diff --git a/telephony/java/android/telephony/ims/RcsContactUceCapability.java b/telephony/java/android/telephony/ims/RcsContactUceCapability.java
index 52d0f03..a133ead 100644
--- a/telephony/java/android/telephony/ims/RcsContactUceCapability.java
+++ b/telephony/java/android/telephony/ims/RcsContactUceCapability.java
@@ -29,7 +29,9 @@
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 /**
  * Contains the User Capability Exchange capabilities corresponding to a contact's URI.
@@ -110,7 +112,6 @@
     /**
      * Builder to help construct {@link RcsContactUceCapability} instances when capabilities were
      * queried through SIP OPTIONS.
-     * @hide
      */
     public static final class OptionsBuilder {
 
@@ -151,7 +152,7 @@
          * @param tags the list of the supported feature tags
          * @return this OptionBuilder
          */
-        public @NonNull OptionsBuilder addFeatureTags(@NonNull List<String> tags) {
+        public @NonNull OptionsBuilder addFeatureTags(@NonNull Set<String> tags) {
             mCapabilities.mFeatureTags.addAll(tags);
             return this;
         }
@@ -220,7 +221,7 @@
     private @CapabilityMechanism int mCapabilityMechanism;
     private @RequestResult int mRequestResult;
 
-    private final List<String> mFeatureTags = new ArrayList<>();
+    private final Set<String> mFeatureTags = new HashSet<>();
     private final List<RcsContactPresenceTuple> mPresenceTuples = new ArrayList<>();
 
     private RcsContactUceCapability(@NonNull Uri contactUri, @CapabilityMechanism int mechanism,
@@ -235,7 +236,9 @@
         mCapabilityMechanism = in.readInt();
         mSourceType = in.readInt();
         mRequestResult = in.readInt();
-        in.readStringList(mFeatureTags);
+        List<String> featureTagList = new ArrayList<>();
+        in.readStringList(featureTagList);
+        mFeatureTags.addAll(featureTagList);
         in.readParcelableList(mPresenceTuples, RcsContactPresenceTuple.class.getClassLoader());
     }
 
@@ -245,7 +248,7 @@
         out.writeInt(mCapabilityMechanism);
         out.writeInt(mSourceType);
         out.writeInt(mRequestResult);
-        out.writeStringList(mFeatureTags);
+        out.writeStringList(new ArrayList<>(mFeatureTags));
         out.writeParcelableList(mPresenceTuples, flags);
     }
 
@@ -285,7 +288,20 @@
         if (mCapabilityMechanism != CAPABILITY_MECHANISM_OPTIONS) {
             return Collections.emptyList();
         }
-        return Collections.unmodifiableList(mFeatureTags);
+        return Collections.unmodifiableList(new ArrayList<>(mFeatureTags));
+    }
+
+    /**
+     * @return The feature tags present in the OPTIONS response from the network.
+     * <p>
+     * Note: this is only populated if {@link #getCapabilityMechanism} is
+     * {@link RcsContactUceCapability#CAPABILITY_MECHANISM_OPTIONS}
+     */
+    public @NonNull Set<String> getFeatureTags() {
+        if (mCapabilityMechanism != CAPABILITY_MECHANISM_OPTIONS) {
+            return Collections.emptySet();
+        }
+        return Collections.unmodifiableSet(mFeatureTags);
     }
 
     /**
diff --git a/telephony/java/android/telephony/ims/aidl/CapabilityExchangeAidlWrapper.java b/telephony/java/android/telephony/ims/aidl/CapabilityExchangeAidlWrapper.java
index a217d13..c3d7325 100644
--- a/telephony/java/android/telephony/ims/aidl/CapabilityExchangeAidlWrapper.java
+++ b/telephony/java/android/telephony/ims/aidl/CapabilityExchangeAidlWrapper.java
@@ -26,7 +26,8 @@
 import android.telephony.ims.stub.CapabilityExchangeEventListener;
 import android.util.Log;
 
-import java.util.List;
+import java.util.ArrayList;
+import java.util.Set;
 
 /**
  * The ICapabilityExchangeEventListener wrapper class to store the listener which is registered by
@@ -84,7 +85,7 @@
      * request to the framework.
      */
     public void onRemoteCapabilityRequest(@NonNull Uri contactUri,
-            @NonNull List<String> remoteCapabilities, @NonNull OptionsRequestCallback callback)
+            @NonNull Set<String> remoteCapabilities, @NonNull OptionsRequestCallback callback)
             throws ImsException {
         ICapabilityExchangeEventListener listener = mListenerBinder;
         if (listener == null) {
@@ -114,7 +115,8 @@
         };
 
         try {
-            listener.onRemoteCapabilityRequest(contactUri, remoteCapabilities, internalCallback);
+            listener.onRemoteCapabilityRequest(contactUri, new ArrayList<>(remoteCapabilities),
+                    internalCallback);
         } catch (RemoteException e) {
             Log.w(LOG_TAG, "Remote capability request exception: " + e);
             throw new ImsException("Remote is not available",
diff --git a/telephony/java/android/telephony/ims/feature/RcsFeature.java b/telephony/java/android/telephony/ims/feature/RcsFeature.java
index 85703f8..b384e50 100644
--- a/telephony/java/android/telephony/ims/feature/RcsFeature.java
+++ b/telephony/java/android/telephony/ims/feature/RcsFeature.java
@@ -47,6 +47,7 @@
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.HashSet;
 import java.util.List;
 import java.util.concurrent.CancellationException;
 import java.util.concurrent.CompletableFuture;
@@ -145,8 +146,8 @@
                 throws RemoteException {
             OptionsResponseCallback callbackWrapper = new RcsOptionsResponseAidlWrapper(callback);
             executeMethodAsync(() -> mReference.getCapabilityExchangeImplBaseInternal()
-                    .sendOptionsCapabilityRequest(contactUri, myCapabilities, callbackWrapper),
-                    "sendOptionsCapabilityRequest");
+                    .sendOptionsCapabilityRequest(contactUri, new HashSet<>(myCapabilities),
+                        callbackWrapper), "sendOptionsCapabilityRequest");
         }
 
         // Call the methods with a clean calling identity on the executor and wait indefinitely for
@@ -390,6 +391,7 @@
      * event to the framework.
      * @return An instance of {@link RcsCapabilityExchangeImplBase} that implements capability
      * exchange if it is supported by the device.
+     * @hide
      */
     public @NonNull RcsCapabilityExchangeImplBase createCapabilityExchangeImpl(
             @NonNull Executor executor, @NonNull CapabilityExchangeEventListener listener) {
@@ -398,14 +400,45 @@
     }
 
     /**
+     * Retrieve the implementation of UCE for this {@link RcsFeature}, which can use either
+     * presence or OPTIONS for capability exchange.
+     *
+     * Will only be requested by the framework if capability exchange is configured
+     * as capable during a
+     * {@link #changeEnabledCapabilities(CapabilityChangeRequest, CapabilityCallbackProxy)}
+     * operation and the RcsFeature sets the status of the capability to true using
+     * {@link #notifyCapabilitiesStatusChanged(RcsImsCapabilities)}.
+     *
+     * @param listener A {@link CapabilityExchangeEventListener} to send the capability exchange
+     * event to the framework.
+     * @return An instance of {@link RcsCapabilityExchangeImplBase} that implements capability
+     * exchange if it is supported by the device.
+     */
+    public @NonNull RcsCapabilityExchangeImplBase createCapabilityExchangeImpl(
+            @NonNull CapabilityExchangeEventListener listener) {
+        // Base Implementation, override to implement functionality
+        return new RcsCapabilityExchangeImplBase();
+    }
+
+    /**
      * Remove the given CapabilityExchangeImplBase instance.
      * @param capExchangeImpl The {@link RcsCapabilityExchangeImplBase} instance to be removed.
+     * @hide
      */
     public void removeCapabilityExchangeImpl(
             @NonNull RcsCapabilityExchangeImplBase capExchangeImpl) {
         // Override to implement the process of removing RcsCapabilityExchangeImplBase instance.
     }
 
+    /**
+     * Remove the given CapabilityExchangeImplBase instance.
+     * @param capExchangeImpl The {@link RcsCapabilityExchangeImplBase} instance to be destroyed.
+     */
+    public void destroyCapabilityExchangeImpl(
+            @NonNull RcsCapabilityExchangeImplBase capExchangeImpl) {
+        // Override to implement the process of destroying RcsCapabilityExchangeImplBase instance.
+    }
+
     /**{@inheritDoc}*/
     @Override
     public void onFeatureRemoved() {
diff --git a/telephony/java/android/telephony/ims/stub/CapabilityExchangeEventListener.java b/telephony/java/android/telephony/ims/stub/CapabilityExchangeEventListener.java
index 6295548..a3be8da 100644
--- a/telephony/java/android/telephony/ims/stub/CapabilityExchangeEventListener.java
+++ b/telephony/java/android/telephony/ims/stub/CapabilityExchangeEventListener.java
@@ -26,7 +26,7 @@
 import android.telephony.ims.feature.ImsFeature;
 import android.telephony.ims.feature.RcsFeature;
 
-import java.util.List;
+import java.util.Set;
 
 /**
  * The interface that is used by the framework to listen to events from the vendor RCS stack
@@ -98,7 +98,8 @@
      * {@link OptionsRequestCallback#onRespondToCapabilityRequestWithError}.
      * @param contactUri The URI associated with the remote contact that is
      * requesting capabilities.
-     * @param remoteCapabilities The remote contact's capability information.
+     * @param remoteCapabilities The remote contact's capability information. The capability
+     * information is in the format defined in RCC.07 section 2.6.1.3.
      * @param callback The callback of this request which is sent from the remote user.
      * @throws ImsException If this {@link RcsCapabilityExchangeImplBase} instance is not
      * currently connected to the framework. This can happen if the {@link RcsFeature} is not
@@ -107,6 +108,6 @@
      * cases when the Telephony stack has crashed.
      */
     void onRemoteCapabilityRequest(@NonNull Uri contactUri,
-            @NonNull List<String> remoteCapabilities,
+            @NonNull Set<String> remoteCapabilities,
             @NonNull OptionsRequestCallback callback) throws ImsException;
 }
diff --git a/telephony/java/android/telephony/ims/stub/RcsCapabilityExchangeImplBase.java b/telephony/java/android/telephony/ims/stub/RcsCapabilityExchangeImplBase.java
index 03e17fb..a117adc 100644
--- a/telephony/java/android/telephony/ims/stub/RcsCapabilityExchangeImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/RcsCapabilityExchangeImplBase.java
@@ -33,6 +33,7 @@
 import java.lang.annotation.RetentionPolicy;
 import java.util.Collection;
 import java.util.List;
+import java.util.Set;
 import java.util.concurrent.Executor;
 
 /**
@@ -355,12 +356,13 @@
         void onTerminated(@NonNull String reason, long retryAfterMilliseconds) throws ImsException;
     }
 
-    private final Executor mBinderExecutor;
+    private Executor mBinderExecutor;
 
     /**
      * Create a new RcsCapabilityExchangeImplBase instance.
      *
      * @param executor The executor that remote calls from the framework will be called on.
+     * @hide
      */
     public RcsCapabilityExchangeImplBase(@NonNull Executor executor) {
         if (executor == null) {
@@ -370,6 +372,12 @@
     }
 
     /**
+     * Create a new RcsCapabilityExchangeImplBase instance.
+     */
+    public RcsCapabilityExchangeImplBase() {
+    }
+
+    /**
      * The user capabilities of one or multiple contacts have been requested by the framework.
      * <p>
      * The implementer must follow up this call with an
@@ -433,6 +441,7 @@
      * @param contactUri The URI of the remote user that we wish to get the capabilities of.
      * @param myCapabilities The capabilities of this device to send to the remote user.
      * @param callback The callback of this request which is sent from the remote user.
+     * @hide
      */
     // executor used is defined in the constructor.
     @SuppressLint("ExecutorRegistration")
@@ -446,4 +455,27 @@
             // Do not do anything, this is a stub implementation.
         }
     }
+
+    /**
+     * Push one's own capabilities to a remote user via the SIP OPTIONS presence exchange mechanism
+     * in order to receive the capabilities of the remote user in response.
+     * <p>
+     * The implementer must use {@link OptionsResponseCallback} to send the response of
+     * this query from the network back to the framework.
+     * @param contactUri The URI of the remote user that we wish to get the capabilities of.
+     * @param myCapabilities The capabilities of this device to send to the remote user.
+     * @param callback The callback of this request which is sent from the remote user.
+     */
+    // executor used is defined in the constructor.
+    @SuppressLint("ExecutorRegistration")
+    public void sendOptionsCapabilityRequest(@NonNull Uri contactUri,
+            @NonNull Set<String> myCapabilities, @NonNull OptionsResponseCallback callback) {
+        // Stub - to be implemented by service
+        Log.w(LOG_TAG, "sendOptionsCapabilityRequest called with no implementation.");
+        try {
+            callback.onCommandError(COMMAND_CODE_NOT_SUPPORTED);
+        } catch (ImsException e) {
+            // Do not do anything, this is a stub implementation.
+        }
+    }
 }
diff --git a/telephony/java/com/android/internal/telephony/ISub.aidl b/telephony/java/com/android/internal/telephony/ISub.aidl
index 9493c76..6493772 100755
--- a/telephony/java/com/android/internal/telephony/ISub.aidl
+++ b/telephony/java/com/android/internal/telephony/ISub.aidl
@@ -302,4 +302,6 @@
     int setUiccApplicationsEnabled(boolean enabled, int subscriptionId);
 
     int setDeviceToDeviceStatusSharing(int sharing, int subId);
+
+    int setDeviceToDeviceStatusSharingContacts(String contacts, int subscriptionId);
 }
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 96af172..afc538d 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -298,9 +298,9 @@
     int getCallState();
 
     /**
-     * Returns the call state for a slot.
+     * Returns the call state for a specific subscriiption.
      */
-    int getCallStateForSlot(int slotIndex);
+    int getCallStateForSubscription(int subId, String callingPackage, String featureId);
 
     /**
      * Replaced by getDataActivityForSubId.
@@ -2250,10 +2250,12 @@
      *
      * @param subId the id of the subscription
      * @param thermalMitigationRequest holds the parameters necessary for the request.
+     * @param callingPackage the package name of the calling package.
      * @throws InvalidThermalMitigationRequestException if the parametes are invalid.
      */
     int sendThermalMitigationRequest(int subId,
-            in ThermalMitigationRequest thermalMitigationRequest);
+            in ThermalMitigationRequest thermalMitigationRequest,
+            String callingPackage);
 
     /**
      * get the Generic Bootstrapping Architecture authentication keys
@@ -2349,6 +2351,16 @@
     boolean getCarrierSingleRegistrationEnabled(int subId);
 
     /**
+     * Overrides the ims feature validation result
+     */
+    boolean setImsFeatureValidationOverride(int subId, String enabled);
+
+    /**
+     * Gets the ims feature validation override value
+     */
+    boolean getImsFeatureValidationOverride(int subId);
+
+    /**
      *  Return the mobile provisioning url that is used to launch a browser to allow users to manage
      *  their mobile plan.
      */
@@ -2440,4 +2452,10 @@
      * of error.
      */
     int prepareForUnattendedReboot();
+
+    /**
+     * Request to get the current slicing configuration including URSP rules and
+     * NSSAIs (configured, allowed and rejected).
+     */
+    void getSlicingConfig(in ResultReceiver callback);
 }
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index 3eda748..1d1eddf 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -524,6 +524,7 @@
     int RIL_REQUEST_SET_DATA_THROTTLING = 221;
     int RIL_REQUEST_SET_ALLOWED_NETWORK_TYPES_BITMAP = 222;
     int RIL_REQUEST_GET_ALLOWED_NETWORK_TYPES_BITMAP = 223;
+    int RIL_REQUEST_GET_SLICING_CONFIG = 224;
 
     /* Responses begin */
     int RIL_RESPONSE_ACKNOWLEDGEMENT = 800;
diff --git a/test-mock/src/android/test/mock/MockContentProvider.java b/test-mock/src/android/test/mock/MockContentProvider.java
index 5b9f67e..7be42f4 100644
--- a/test-mock/src/android/test/mock/MockContentProvider.java
+++ b/test-mock/src/android/test/mock/MockContentProvider.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.content.AttributionSource;
 import android.content.ContentProvider;
 import android.content.ContentProviderOperation;
 import android.content.ContentProviderResult;
@@ -60,21 +61,20 @@
      */
     private class InversionIContentProvider implements IContentProvider {
         @Override
-        public ContentProviderResult[] applyBatch(String callingPackage,
-                @Nullable String featureId, String authority,
-                ArrayList<ContentProviderOperation> operations)
+        public ContentProviderResult[] applyBatch(@NonNull AttributionSource attributionSource,
+                String authority, ArrayList<ContentProviderOperation> operations)
                 throws RemoteException, OperationApplicationException {
             return MockContentProvider.this.applyBatch(authority, operations);
         }
 
         @Override
-        public int bulkInsert(String callingPackage, @Nullable String featureId, Uri url,
+        public int bulkInsert(@NonNull AttributionSource attributionSource, Uri url,
                 ContentValues[] initialValues) throws RemoteException {
             return MockContentProvider.this.bulkInsert(url, initialValues);
         }
 
         @Override
-        public int delete(String callingPackage, @Nullable String featureId, Uri url,
+        public int delete(@NonNull AttributionSource attributionSource, Uri url,
                 Bundle extras) throws RemoteException {
             return MockContentProvider.this.delete(url, extras);
         }
@@ -90,40 +90,40 @@
         }
 
         @Override
-        public Uri insert(String callingPackage, @Nullable String featureId, Uri url,
+        public Uri insert(@NonNull AttributionSource attributionSource, Uri url,
                 ContentValues initialValues, Bundle extras) throws RemoteException {
             return MockContentProvider.this.insert(url, initialValues, extras);
         }
 
         @Override
-        public AssetFileDescriptor openAssetFile(String callingPackage,
-                @Nullable String featureId, Uri url, String mode, ICancellationSignal signal)
+        public AssetFileDescriptor openAssetFile(@NonNull AttributionSource attributionSource,
+                Uri url, String mode, ICancellationSignal signal)
                 throws RemoteException, FileNotFoundException {
             return MockContentProvider.this.openAssetFile(url, mode);
         }
 
         @Override
-        public ParcelFileDescriptor openFile(String callingPackage, @Nullable String featureId,
-                Uri url, String mode, ICancellationSignal signal, IBinder callerToken)
+        public ParcelFileDescriptor openFile(@NonNull AttributionSource attributionSource,
+                Uri url, String mode, ICancellationSignal signal)
                 throws RemoteException, FileNotFoundException {
             return MockContentProvider.this.openFile(url, mode);
         }
 
         @Override
-        public Cursor query(String callingPackage, @Nullable String featureId, Uri url,
+        public Cursor query(@NonNull AttributionSource attributionSource, Uri url,
                 @Nullable String[] projection, @Nullable Bundle queryArgs,
                 @Nullable ICancellationSignal cancellationSignal) throws RemoteException {
             return MockContentProvider.this.query(url, projection, queryArgs, null);
         }
 
         @Override
-        public int update(String callingPackage, @Nullable String featureId, Uri url,
+        public int update(@NonNull AttributionSource attributionSource, Uri url,
                 ContentValues values, Bundle extras) throws RemoteException {
             return MockContentProvider.this.update(url, values, extras);
         }
 
         @Override
-        public Bundle call(String callingPackage, @Nullable String featureId, String authority,
+        public Bundle call(@NonNull AttributionSource attributionSource, String authority,
                 String method, String request, Bundle args) throws RemoteException {
             return MockContentProvider.this.call(authority, method, request, args);
         }
@@ -139,9 +139,10 @@
         }
 
         @Override
-        public AssetFileDescriptor openTypedAssetFile(String callingPackage,
-                @Nullable String featureId, Uri url, String mimeType, Bundle opts,
-                ICancellationSignal signal) throws RemoteException, FileNotFoundException {
+        public AssetFileDescriptor openTypedAssetFile(
+                @NonNull AttributionSource attributionSource, Uri url, String mimeType,
+                Bundle opts, ICancellationSignal signal)
+                throws RemoteException, FileNotFoundException {
             return MockContentProvider.this.openTypedAssetFile(url, mimeType, opts);
         }
 
@@ -151,37 +152,37 @@
         }
 
         @Override
-        public Uri canonicalize(String callingPkg, @Nullable String featureId, Uri uri)
+        public Uri canonicalize(@NonNull AttributionSource attributionSource, Uri uri)
                 throws RemoteException {
             return MockContentProvider.this.canonicalize(uri);
         }
 
         @Override
-        public void canonicalizeAsync(String callingPkg, String featureId, Uri uri,
+        public void canonicalizeAsync(@NonNull AttributionSource attributionSource, Uri uri,
                 RemoteCallback callback) {
             MockContentProvider.this.canonicalizeAsync(uri, callback);
         }
 
         @Override
-        public Uri uncanonicalize(String callingPkg, @Nullable String featureId, Uri uri)
+        public Uri uncanonicalize(@NonNull AttributionSource attributionSource, Uri uri)
                 throws RemoteException {
             return MockContentProvider.this.uncanonicalize(uri);
         }
 
         @Override
-        public void uncanonicalizeAsync(String callingPkg, String featureId, Uri uri,
+        public void uncanonicalizeAsync(@NonNull AttributionSource attributionSource, Uri uri,
                 RemoteCallback callback) {
             MockContentProvider.this.uncanonicalizeAsync(uri, callback);
         }
 
         @Override
-        public boolean refresh(String callingPkg, @Nullable String featureId, Uri url,
+        public boolean refresh(@NonNull AttributionSource attributionSource, Uri url,
                 Bundle args, ICancellationSignal cancellationSignal) throws RemoteException {
             return MockContentProvider.this.refresh(url, args);
         }
 
         @Override
-        public int checkUriPermission(String callingPkg, @Nullable String featureId, Uri uri,
+        public int checkUriPermission(@NonNull AttributionSource attributionSource, Uri uri,
                 int uid, int modeFlags) {
             return MockContentProvider.this.checkUriPermission(uri, uid, modeFlags);
         }
diff --git a/test-mock/src/android/test/mock/MockIContentProvider.java b/test-mock/src/android/test/mock/MockIContentProvider.java
index 82a1cf7..b81c707 100644
--- a/test-mock/src/android/test/mock/MockIContentProvider.java
+++ b/test-mock/src/android/test/mock/MockIContentProvider.java
@@ -16,7 +16,9 @@
 
 package android.test.mock;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.content.AttributionSource;
 import android.content.ContentProviderOperation;
 import android.content.ContentProviderResult;
 import android.content.ContentResolver;
@@ -46,14 +48,14 @@
  */
 public class MockIContentProvider implements IContentProvider {
     @Override
-    public int bulkInsert(String callingPackage, @Nullable String featureId, Uri url,
+    public int bulkInsert(@NonNull AttributionSource attributionSource, Uri url,
             ContentValues[] initialValues) {
         throw new UnsupportedOperationException("unimplemented mock method");
     }
 
     @Override
     @SuppressWarnings("unused")
-    public int delete(String callingPackage, @Nullable String featureId, Uri url,
+    public int delete(@NonNull AttributionSource attributionSource, Uri url,
             Bundle extras) throws RemoteException {
         throw new UnsupportedOperationException("unimplemented mock method");
     }
@@ -75,31 +77,31 @@
 
     @Override
     @SuppressWarnings("unused")
-    public Uri insert(String callingPackage, @Nullable String featureId, Uri url,
+    public Uri insert(@NonNull AttributionSource attributionSource, Uri url,
             ContentValues initialValues, Bundle extras) throws RemoteException {
         throw new UnsupportedOperationException("unimplemented mock method");
     }
 
     @Override
-    public ParcelFileDescriptor openFile(String callingPackage, @Nullable String featureId,
-            Uri url, String mode, ICancellationSignal signal, IBinder callerToken) {
+    public ParcelFileDescriptor openFile(@NonNull AttributionSource attributionSource,
+            Uri url, String mode, ICancellationSignal signal) {
         throw new UnsupportedOperationException("unimplemented mock method");
     }
 
     @Override
-    public AssetFileDescriptor openAssetFile(String callingPackage, @Nullable String featureId,
+    public AssetFileDescriptor openAssetFile(@NonNull AttributionSource attributionSource,
             Uri uri, String mode, ICancellationSignal signal) {
         throw new UnsupportedOperationException("unimplemented mock method");
     }
 
     @Override
-    public ContentProviderResult[] applyBatch(String callingPackage, @Nullable String featureId,
+    public ContentProviderResult[] applyBatch(@NonNull AttributionSource attributionSource,
             String authority, ArrayList<ContentProviderOperation> operations) {
         throw new UnsupportedOperationException("unimplemented mock method");
     }
 
     @Override
-    public Cursor query(String callingPackage, @Nullable String featureId, Uri url,
+    public Cursor query(@NonNull AttributionSource attributionSource, Uri url,
             @Nullable String[] projection, @Nullable Bundle queryArgs,
             @Nullable ICancellationSignal cancellationSignal) {
         throw new UnsupportedOperationException("unimplemented mock method");
@@ -111,13 +113,13 @@
     }
 
     @Override
-    public int update(String callingPackage, @Nullable String featureId, Uri url,
+    public int update(@NonNull AttributionSource attributionSource, Uri url,
             ContentValues values, Bundle extras) throws RemoteException {
         throw new UnsupportedOperationException("unimplemented mock method");
     }
 
     @Override
-    public Bundle call(String callingPackage, @Nullable String featureId, String authority,
+    public Bundle call(@NonNull AttributionSource attributionSource, String authority,
             String method, String request, Bundle args) throws RemoteException {
         throw new UnsupportedOperationException("unimplemented mock method");
     }
@@ -133,9 +135,9 @@
     }
 
     @Override
-    public AssetFileDescriptor openTypedAssetFile(String callingPackage,
-            @Nullable String featureId, Uri url, String mimeType, Bundle opts,
-            ICancellationSignal signal) throws RemoteException, FileNotFoundException {
+    public AssetFileDescriptor openTypedAssetFile(@NonNull AttributionSource attributionSource,
+            Uri url, String mimeType, Bundle opts, ICancellationSignal signal)
+            throws RemoteException, FileNotFoundException {
         throw new UnsupportedOperationException("unimplemented mock method");
     }
 
@@ -145,48 +147,48 @@
     }
 
     @Override
-    public Uri canonicalize(String callingPkg, @Nullable String featureId, Uri uri) {
+    public Uri canonicalize(@NonNull AttributionSource attributionSource, Uri uri) {
         throw new UnsupportedOperationException("unimplemented mock method");
     }
 
     @Override
     @SuppressWarnings("deprecation")
-    public void canonicalizeAsync(String callingPkg, String featureId, Uri uri,
+    public void canonicalizeAsync(@NonNull AttributionSource attributionSource, Uri uri,
             RemoteCallback remoteCallback) {
         AsyncTask.SERIAL_EXECUTOR.execute(() -> {
             final Bundle bundle = new Bundle();
             bundle.putParcelable(ContentResolver.REMOTE_CALLBACK_RESULT,
-                    canonicalize(callingPkg, featureId, uri));
+                    canonicalize(attributionSource, uri));
             remoteCallback.sendResult(bundle);
         });
     }
 
     @Override
-    public Uri uncanonicalize(String callingPkg, @Nullable String featureId, Uri uri) {
+    public Uri uncanonicalize(@NonNull AttributionSource attributionSource, Uri uri) {
         throw new UnsupportedOperationException("unimplemented mock method");
     }
 
     @Override
     @SuppressWarnings("deprecation")
-    public void uncanonicalizeAsync(String callingPkg, String featureId, Uri uri,
+    public void uncanonicalizeAsync(@NonNull AttributionSource attributionSource, Uri uri,
             RemoteCallback remoteCallback) {
         AsyncTask.SERIAL_EXECUTOR.execute(() -> {
             final Bundle bundle = new Bundle();
             bundle.putParcelable(ContentResolver.REMOTE_CALLBACK_RESULT,
-                    uncanonicalize(callingPkg, featureId, uri));
+                    uncanonicalize(attributionSource, uri));
             remoteCallback.sendResult(bundle);
         });
     }
 
     @Override
-    public boolean refresh(String callingPkg, @Nullable String featureId, Uri url, Bundle args,
+    public boolean refresh(@NonNull AttributionSource attributionSource, Uri url, Bundle args,
             ICancellationSignal cancellationSignal) throws RemoteException {
         throw new UnsupportedOperationException("unimplemented mock method");
     }
 
     /** {@hide} */
     @Override
-    public int checkUriPermission(String callingPkg, @Nullable String featureId, Uri uri, int uid,
+    public int checkUriPermission(@NonNull AttributionSource attributionSource, Uri uri, int uid,
             int modeFlags) {
         throw new UnsupportedOperationException("unimplemented mock method call");
     }
diff --git a/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassBase.java b/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassBase.java
index f49d4fc..4259a86 100644
--- a/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassBase.java
+++ b/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassBase.java
@@ -32,7 +32,7 @@
 
 
 
-    // Code below generated by codegen v1.0.20.
+    // Code below generated by codegen v1.0.23.
     //
     // DO NOT MODIFY!
     // CHECKSTYLE:OFF Generated code
@@ -98,8 +98,8 @@
     };
 
     @DataClass.Generated(
-            time = 1604522375155L,
-            codegenVersion = "1.0.20",
+            time = 1616541542813L,
+            codegenVersion = "1.0.23",
             sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassBase.java",
             inputSignatures = "private  int mBaseData\nclass HierrarchicalDataClassBase extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genConstructor=false, genSetters=true)")
     @Deprecated
diff --git a/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassChild.java b/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassChild.java
index e8cce23..677094b 100644
--- a/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassChild.java
+++ b/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassChild.java
@@ -46,7 +46,7 @@
 
 
 
-    // Code below generated by codegen v1.0.20.
+    // Code below generated by codegen v1.0.23.
     //
     // DO NOT MODIFY!
     // CHECKSTYLE:OFF Generated code
@@ -120,8 +120,8 @@
     };
 
     @DataClass.Generated(
-            time = 1604522376059L,
-            codegenVersion = "1.0.20",
+            time = 1616541543730L,
+            codegenVersion = "1.0.23",
             sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassChild.java",
             inputSignatures = "private @android.annotation.NonNull java.lang.String mChildData\nclass HierrarchicalDataClassChild extends com.android.codegentest.HierrarchicalDataClassBase implements []\n@com.android.internal.util.DataClass(genParcelable=true, genConstructor=false, genSetters=true)")
     @Deprecated
diff --git a/tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java b/tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java
index 9de6552..eb260ab 100644
--- a/tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java
+++ b/tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java
@@ -54,7 +54,7 @@
 
 
 
-    // Code below generated by codegen v1.0.20.
+    // Code below generated by codegen v1.0.23.
     //
     // DO NOT MODIFY!
     // CHECKSTYLE:OFF Generated code
@@ -412,8 +412,8 @@
     }
 
     @DataClass.Generated(
-            time = 1604522374190L,
-            codegenVersion = "1.0.20",
+            time = 1616541541942L,
+            codegenVersion = "1.0.23",
             sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java",
             inputSignatures = " @android.annotation.NonNull java.lang.String[] mStringArray\n @android.annotation.NonNull int[] mIntArray\n @android.annotation.NonNull java.util.List<java.lang.String> mStringList\n @android.annotation.NonNull java.util.Map<java.lang.String,com.android.codegentest.SampleWithCustomBuilder> mMap\n @android.annotation.NonNull java.util.Map<java.lang.String,java.lang.String> mStringMap\n @android.annotation.NonNull android.util.SparseArray<com.android.codegentest.SampleWithCustomBuilder> mSparseArray\n @android.annotation.NonNull android.util.SparseIntArray mSparseIntArray\n @java.lang.SuppressWarnings @android.annotation.Nullable java.lang.Boolean mNullableBoolean\nclass ParcelAllTheThingsDataClass extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genBuilder=true, genAidl=false, genToString=true)")
     @Deprecated
diff --git a/tests/Codegen/src/com/android/codegentest/SampleDataClass.java b/tests/Codegen/src/com/android/codegentest/SampleDataClass.java
index 5a3e273..158e065 100644
--- a/tests/Codegen/src/com/android/codegentest/SampleDataClass.java
+++ b/tests/Codegen/src/com/android/codegentest/SampleDataClass.java
@@ -23,8 +23,11 @@
 import android.annotation.StringDef;
 import android.annotation.StringRes;
 import android.annotation.UserIdInt;
+import android.companion.ICompanionDeviceManager;
 import android.content.pm.PackageManager;
 import android.net.LinkAddress;
+import android.os.Binder;
+import android.os.IBinder;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.view.accessibility.AccessibilityNodeInfo;
@@ -282,6 +285,16 @@
 
 
     /**
+     * Binder types are also supported
+     */
+    private @NonNull IBinder mToken = new Binder();
+    /**
+     * AIDL interface types are also supported
+     */
+    private @Nullable ICompanionDeviceManager mIPCInterface = null;
+
+
+    /**
      * Manually declaring any method that would otherwise be generated suppresses its generation,
      * allowing for fine-grained overrides of the generated behavior.
      */
@@ -344,7 +357,7 @@
 
 
 
-    // Code below generated by codegen v1.0.20.
+    // Code below generated by codegen v1.0.23.
     //
     // DO NOT MODIFY!
     // CHECKSTYLE:OFF Generated code
@@ -492,6 +505,10 @@
      *
      *   Validation annotations following {@link Each} annotation, will be applied for each
      *   array/collection element instead.
+     * @param token
+     *   Binder types are also supported
+     * @param iPCInterface
+     *   AIDL interface types are also supported
      */
     @DataClass.Generated.Member
     public SampleDataClass(
@@ -514,7 +531,9 @@
             @Nullable LinkAddress[] linkAddresses5,
             @StringRes int stringRes,
             @android.annotation.IntRange(from = 0, to = 6) int dayOfWeek,
-            @Size(2) @NonNull @FloatRange(from = 0f) float[] coords) {
+            @Size(2) @NonNull @FloatRange(from = 0f) float[] coords,
+            @NonNull IBinder token,
+            @Nullable ICompanionDeviceManager iPCInterface) {
         this.mNum = num;
         this.mNum2 = num2;
         this.mNum4 = num4;
@@ -597,6 +616,10 @@
                     "from", 0f);
         }
 
+        this.mToken = token;
+        AnnotationValidations.validate(
+                NonNull.class, null, mToken);
+        this.mIPCInterface = iPCInterface;
 
         onConstructed();
     }
@@ -797,6 +820,22 @@
     }
 
     /**
+     * Binder types are also supported
+     */
+    @DataClass.Generated.Member
+    public @NonNull IBinder getToken() {
+        return mToken;
+    }
+
+    /**
+     * AIDL interface types are also supported
+     */
+    @DataClass.Generated.Member
+    public @Nullable ICompanionDeviceManager getIPCInterface() {
+        return mIPCInterface;
+    }
+
+    /**
      * When using transient fields for caching it's often also a good idea to initialize them
      * lazily.
      *
@@ -1089,6 +1128,26 @@
         return this;
     }
 
+    /**
+     * Binder types are also supported
+     */
+    @DataClass.Generated.Member
+    public @NonNull SampleDataClass setToken(@NonNull IBinder value) {
+        mToken = value;
+        AnnotationValidations.validate(
+                NonNull.class, null, mToken);
+        return this;
+    }
+
+    /**
+     * AIDL interface types are also supported
+     */
+    @DataClass.Generated.Member
+    public @NonNull SampleDataClass setIPCInterface(@NonNull ICompanionDeviceManager value) {
+        mIPCInterface = value;
+        return this;
+    }
+
     @Override
     @DataClass.Generated.Member
     public String toString() {
@@ -1115,7 +1174,9 @@
                 "linkAddresses5 = " + java.util.Arrays.toString(mLinkAddresses5) + ", " +
                 "stringRes = " + mStringRes + ", " +
                 "dayOfWeek = " + mDayOfWeek + ", " +
-                "coords = " + java.util.Arrays.toString(mCoords) +
+                "coords = " + java.util.Arrays.toString(mCoords) + ", " +
+                "token = " + mToken + ", " +
+                "iPCInterface = " + mIPCInterface +
         " }";
     }
 
@@ -1151,7 +1212,9 @@
                 && java.util.Arrays.equals(mLinkAddresses5, that.mLinkAddresses5)
                 && mStringRes == that.mStringRes
                 && mDayOfWeek == that.mDayOfWeek
-                && java.util.Arrays.equals(mCoords, that.mCoords);
+                && java.util.Arrays.equals(mCoords, that.mCoords)
+                && Objects.equals(mToken, that.mToken)
+                && Objects.equals(mIPCInterface, that.mIPCInterface);
     }
 
     @Override
@@ -1181,6 +1244,8 @@
         _hash = 31 * _hash + mStringRes;
         _hash = 31 * _hash + mDayOfWeek;
         _hash = 31 * _hash + java.util.Arrays.hashCode(mCoords);
+        _hash = 31 * _hash + Objects.hashCode(mToken);
+        _hash = 31 * _hash + Objects.hashCode(mIPCInterface);
         return _hash;
     }
 
@@ -1208,6 +1273,8 @@
         actionInt.acceptInt(this, "stringRes", mStringRes);
         actionInt.acceptInt(this, "dayOfWeek", mDayOfWeek);
         actionObject.acceptObject(this, "coords", mCoords);
+        actionObject.acceptObject(this, "token", mToken);
+        actionObject.acceptObject(this, "iPCInterface", mIPCInterface);
     }
 
     /** @deprecated May cause boxing allocations - use with caution! */
@@ -1234,6 +1301,8 @@
         action.acceptObject(this, "stringRes", mStringRes);
         action.acceptObject(this, "dayOfWeek", mDayOfWeek);
         action.acceptObject(this, "coords", mCoords);
+        action.acceptObject(this, "token", mToken);
+        action.acceptObject(this, "iPCInterface", mIPCInterface);
     }
 
     @DataClass.Generated.Member
@@ -1269,6 +1338,7 @@
         if (mOtherParcelable != null) flg |= 0x40;
         if (mLinkAddresses4 != null) flg |= 0x800;
         if (mLinkAddresses5 != null) flg |= 0x10000;
+        if (mIPCInterface != null) flg |= 0x200000;
         dest.writeLong(flg);
         dest.writeInt(mNum);
         dest.writeInt(mNum2);
@@ -1290,6 +1360,8 @@
         dest.writeInt(mStringRes);
         dest.writeInt(mDayOfWeek);
         dest.writeFloatArray(mCoords);
+        dest.writeStrongBinder(mToken);
+        if (mIPCInterface != null) dest.writeStrongInterface(mIPCInterface);
     }
 
     @Override
@@ -1326,6 +1398,8 @@
         int stringRes = in.readInt();
         int dayOfWeek = in.readInt();
         float[] coords = in.createFloatArray();
+        IBinder token = (IBinder) in.readStrongBinder();
+        ICompanionDeviceManager iPCInterface = (flg & 0x200000) == 0 ? null : ICompanionDeviceManager.Stub.asInterface(in.readStrongBinder());
 
         this.mNum = num;
         this.mNum2 = num2;
@@ -1409,6 +1483,10 @@
                     "from", 0f);
         }
 
+        this.mToken = token;
+        AnnotationValidations.validate(
+                NonNull.class, null, mToken);
+        this.mIPCInterface = iPCInterface;
 
         onConstructed();
     }
@@ -1454,6 +1532,8 @@
         private @StringRes int mStringRes;
         private @android.annotation.IntRange(from = 0, to = 6) int mDayOfWeek;
         private @Size(2) @NonNull @FloatRange(from = 0f) float[] mCoords;
+        private @NonNull IBinder mToken;
+        private @Nullable ICompanionDeviceManager mIPCInterface;
 
         private long mBuilderFieldsSet = 0L;
 
@@ -1794,10 +1874,32 @@
             return this;
         }
 
+        /**
+         * Binder types are also supported
+         */
+        @DataClass.Generated.Member
+        public @NonNull Builder setToken(@NonNull IBinder value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x100000;
+            mToken = value;
+            return this;
+        }
+
+        /**
+         * AIDL interface types are also supported
+         */
+        @DataClass.Generated.Member
+        public @NonNull Builder setIPCInterface(@NonNull ICompanionDeviceManager value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x200000;
+            mIPCInterface = value;
+            return this;
+        }
+
         /** Builds the instance. This builder should not be touched after calling this! */
         public @NonNull SampleDataClass build() {
             checkNotUsed();
-            mBuilderFieldsSet |= 0x100000; // Mark builder used
+            mBuilderFieldsSet |= 0x400000; // Mark builder used
 
             if ((mBuilderFieldsSet & 0x10) == 0) {
                 mName2 = "Bob";
@@ -1841,6 +1943,12 @@
             if ((mBuilderFieldsSet & 0x80000) == 0) {
                 mCoords = new float[] { 0f, 0f };
             }
+            if ((mBuilderFieldsSet & 0x100000) == 0) {
+                mToken = new Binder();
+            }
+            if ((mBuilderFieldsSet & 0x200000) == 0) {
+                mIPCInterface = null;
+            }
             SampleDataClass o = new SampleDataClass(
                     mNum,
                     mNum2,
@@ -1861,12 +1969,14 @@
                     mLinkAddresses5,
                     mStringRes,
                     mDayOfWeek,
-                    mCoords);
+                    mCoords,
+                    mToken,
+                    mIPCInterface);
             return o;
         }
 
         private void checkNotUsed() {
-            if ((mBuilderFieldsSet & 0x100000) != 0) {
+            if ((mBuilderFieldsSet & 0x400000) != 0) {
                 throw new IllegalStateException(
                         "This Builder should not be reused. Use a new Builder instance instead");
             }
@@ -1874,10 +1984,10 @@
     }
 
     @DataClass.Generated(
-            time = 1604522372172L,
-            codegenVersion = "1.0.20",
+            time = 1616541539978L,
+            codegenVersion = "1.0.23",
             sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/SampleDataClass.java",
-            inputSignatures = "public static final  java.lang.String STATE_NAME_UNDEFINED\npublic static final  java.lang.String STATE_NAME_ON\npublic static final  java.lang.String STATE_NAME_OFF\npublic static final  int STATE_ON\npublic static final  int STATE_OFF\npublic static final  int STATE_UNDEFINED\npublic static final @com.android.codegentest.SampleDataClass.RequestFlags int FLAG_MANUAL_REQUEST\npublic static final @com.android.codegentest.SampleDataClass.RequestFlags int FLAG_COMPATIBILITY_MODE_REQUEST\npublic static final @com.android.codegentest.SampleDataClass.RequestFlags int FLAG_AUGMENTED_REQUEST\nprivate  int mNum\nprivate  int mNum2\nprivate  int mNum4\nprivate @android.annotation.Nullable java.lang.String mName\nprivate @android.annotation.NonNull java.lang.String mName2\nprivate @android.annotation.NonNull java.lang.String mName4\nprivate @android.annotation.Nullable android.view.accessibility.AccessibilityNodeInfo mOtherParcelable\nprivate @com.android.internal.util.DataClass.ParcelWith(com.android.codegentest.MyDateParcelling.class) @android.annotation.NonNull java.util.Date mDate\nprivate @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForPattern.class) @android.annotation.NonNull java.util.regex.Pattern mPattern\nprivate @android.annotation.NonNull java.util.List<android.net.LinkAddress> mLinkAddresses2\nprivate @com.android.internal.util.DataClass.PluralOf(\"linkAddress\") @android.annotation.NonNull java.util.ArrayList<android.net.LinkAddress> mLinkAddresses\nprivate @android.annotation.Nullable android.net.LinkAddress[] mLinkAddresses4\nprivate @com.android.codegentest.SampleDataClass.StateName @android.annotation.NonNull java.lang.String mStateName\nprivate @com.android.codegentest.SampleDataClass.RequestFlags int mFlags\nprivate @com.android.codegentest.SampleDataClass.State int mState\npublic @android.annotation.NonNull java.lang.CharSequence charSeq\nprivate final @android.annotation.Nullable android.net.LinkAddress[] mLinkAddresses5\nprivate transient  android.net.LinkAddress[] mLinkAddresses6\ntransient  int[] mTmpStorage\nprivate @android.annotation.StringRes int mStringRes\nprivate @android.annotation.IntRange int mDayOfWeek\nprivate @android.annotation.Size @android.annotation.NonNull @com.android.internal.util.DataClass.Each @android.annotation.FloatRange float[] mCoords\nprivate static  java.lang.String defaultName4()\nprivate  int[] lazyInitTmpStorage()\npublic  android.net.LinkAddress[] getLinkAddresses4()\nprivate  boolean patternEquals(java.util.regex.Pattern)\nprivate  int patternHashCode()\nprivate  void onConstructed()\npublic  void dump(java.io.PrintWriter)\nclass SampleDataClass extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genBuilder=true, genConstructor=true, genEqualsHashCode=true, genToString=true, genForEachField=true, genSetters=true)")
+            inputSignatures = "public static final  java.lang.String STATE_NAME_UNDEFINED\npublic static final  java.lang.String STATE_NAME_ON\npublic static final  java.lang.String STATE_NAME_OFF\npublic static final  int STATE_ON\npublic static final  int STATE_OFF\npublic static final  int STATE_UNDEFINED\npublic static final @com.android.codegentest.SampleDataClass.RequestFlags int FLAG_MANUAL_REQUEST\npublic static final @com.android.codegentest.SampleDataClass.RequestFlags int FLAG_COMPATIBILITY_MODE_REQUEST\npublic static final @com.android.codegentest.SampleDataClass.RequestFlags int FLAG_AUGMENTED_REQUEST\nprivate  int mNum\nprivate  int mNum2\nprivate  int mNum4\nprivate @android.annotation.Nullable java.lang.String mName\nprivate @android.annotation.NonNull java.lang.String mName2\nprivate @android.annotation.NonNull java.lang.String mName4\nprivate @android.annotation.Nullable android.view.accessibility.AccessibilityNodeInfo mOtherParcelable\nprivate @com.android.internal.util.DataClass.ParcelWith(com.android.codegentest.MyDateParcelling.class) @android.annotation.NonNull java.util.Date mDate\nprivate @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForPattern.class) @android.annotation.NonNull java.util.regex.Pattern mPattern\nprivate @android.annotation.NonNull java.util.List<android.net.LinkAddress> mLinkAddresses2\nprivate @com.android.internal.util.DataClass.PluralOf(\"linkAddress\") @android.annotation.NonNull java.util.ArrayList<android.net.LinkAddress> mLinkAddresses\nprivate @android.annotation.Nullable android.net.LinkAddress[] mLinkAddresses4\nprivate @com.android.codegentest.SampleDataClass.StateName @android.annotation.NonNull java.lang.String mStateName\nprivate @com.android.codegentest.SampleDataClass.RequestFlags int mFlags\nprivate @com.android.codegentest.SampleDataClass.State int mState\npublic @android.annotation.NonNull java.lang.CharSequence charSeq\nprivate final @android.annotation.Nullable android.net.LinkAddress[] mLinkAddresses5\nprivate transient  android.net.LinkAddress[] mLinkAddresses6\ntransient  int[] mTmpStorage\nprivate @android.annotation.StringRes int mStringRes\nprivate @android.annotation.IntRange int mDayOfWeek\nprivate @android.annotation.Size @android.annotation.NonNull @com.android.internal.util.DataClass.Each @android.annotation.FloatRange float[] mCoords\nprivate @android.annotation.NonNull android.os.IBinder mToken\nprivate @android.annotation.Nullable android.companion.ICompanionDeviceManager mIPCInterface\nprivate static  java.lang.String defaultName4()\nprivate  int[] lazyInitTmpStorage()\npublic  android.net.LinkAddress[] getLinkAddresses4()\nprivate  boolean patternEquals(java.util.regex.Pattern)\nprivate  int patternHashCode()\nprivate  void onConstructed()\npublic  void dump(java.io.PrintWriter)\nclass SampleDataClass extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genBuilder=true, genConstructor=true, genEqualsHashCode=true, genToString=true, genForEachField=true, genSetters=true)")
     @Deprecated
     private void __metadata() {}
 
diff --git a/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java b/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java
index 3ab3445..a535e22 100644
--- a/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java
+++ b/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java
@@ -85,7 +85,7 @@
 
 
 
-    // Code below generated by codegen v1.0.20.
+    // Code below generated by codegen v1.0.23.
     //
     // DO NOT MODIFY!
     // CHECKSTYLE:OFF Generated code
@@ -253,8 +253,8 @@
     }
 
     @DataClass.Generated(
-            time = 1604522373190L,
-            codegenVersion = "1.0.20",
+            time = 1616541540898L,
+            codegenVersion = "1.0.23",
             sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java",
             inputSignatures = "  long delayAmount\n @android.annotation.NonNull java.util.concurrent.TimeUnit delayUnit\n  long creationTimestamp\nprivate static  java.util.concurrent.TimeUnit unparcelDelayUnit(android.os.Parcel)\nprivate  void parcelDelayUnit(android.os.Parcel,int)\nclass SampleWithCustomBuilder extends java.lang.Object implements [android.os.Parcelable]\nabstract  com.android.codegentest.SampleWithCustomBuilder.Builder setDelayAmount(long)\npublic abstract  com.android.codegentest.SampleWithCustomBuilder.Builder setDelayUnit(java.util.concurrent.TimeUnit)\npublic  com.android.codegentest.SampleWithCustomBuilder.Builder setDelay(long,java.util.concurrent.TimeUnit)\nclass BaseBuilder extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genBuilder=true, genAidl=false, genToString=true)\nabstract  com.android.codegentest.SampleWithCustomBuilder.Builder setDelayAmount(long)\npublic abstract  com.android.codegentest.SampleWithCustomBuilder.Builder setDelayUnit(java.util.concurrent.TimeUnit)\npublic  com.android.codegentest.SampleWithCustomBuilder.Builder setDelay(long,java.util.concurrent.TimeUnit)\nclass BaseBuilder extends java.lang.Object implements []")
     @Deprecated
diff --git a/tests/Codegen/src/com/android/codegentest/SampleWithNestedDataClasses.java b/tests/Codegen/src/com/android/codegentest/SampleWithNestedDataClasses.java
index 8901cac..d409624 100644
--- a/tests/Codegen/src/com/android/codegentest/SampleWithNestedDataClasses.java
+++ b/tests/Codegen/src/com/android/codegentest/SampleWithNestedDataClasses.java
@@ -36,7 +36,7 @@
 
 
 
-        // Code below generated by codegen v1.0.20.
+        // Code below generated by codegen v1.0.23.
         //
         // DO NOT MODIFY!
         // CHECKSTYLE:OFF Generated code
@@ -135,8 +135,8 @@
         };
 
         @DataClass.Generated(
-                time = 1604522377998L,
-                codegenVersion = "1.0.20",
+                time = 1616541545539L,
+                codegenVersion = "1.0.23",
                 sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/SampleWithNestedDataClasses.java",
                 inputSignatures = " @android.annotation.NonNull java.lang.String mBar\nclass NestedDataClass extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true)")
         @Deprecated
@@ -160,7 +160,7 @@
 
 
 
-            // Code below generated by codegen v1.0.20.
+            // Code below generated by codegen v1.0.23.
             //
             // DO NOT MODIFY!
             // CHECKSTYLE:OFF Generated code
@@ -259,8 +259,8 @@
             };
 
             @DataClass.Generated(
-                    time = 1604522378007L,
-                    codegenVersion = "1.0.20",
+                    time = 1616541545548L,
+                    codegenVersion = "1.0.23",
                     sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/SampleWithNestedDataClasses.java",
                     inputSignatures = " @android.annotation.NonNull long mBaz2\nclass NestedDataClass3 extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true)")
             @Deprecated
@@ -274,7 +274,7 @@
 
 
 
-        // Code below generated by codegen v1.0.20.
+        // Code below generated by codegen v1.0.23.
         //
         // DO NOT MODIFY!
         // CHECKSTYLE:OFF Generated code
@@ -373,8 +373,8 @@
         };
 
         @DataClass.Generated(
-                time = 1604522378015L,
-                codegenVersion = "1.0.20",
+                time = 1616541545552L,
+                codegenVersion = "1.0.23",
                 sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/SampleWithNestedDataClasses.java",
                 inputSignatures = " @android.annotation.NonNull java.lang.String mBaz\nclass NestedDataClass2 extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true)")
         @Deprecated
diff --git a/tests/Codegen/src/com/android/codegentest/StaleDataclassDetectorFalsePositivesTest.java b/tests/Codegen/src/com/android/codegentest/StaleDataclassDetectorFalsePositivesTest.java
index ac776f3..3583b95 100644
--- a/tests/Codegen/src/com/android/codegentest/StaleDataclassDetectorFalsePositivesTest.java
+++ b/tests/Codegen/src/com/android/codegentest/StaleDataclassDetectorFalsePositivesTest.java
@@ -64,7 +64,7 @@
 
 
 
-    // Code below generated by codegen v1.0.20.
+    // Code below generated by codegen v1.0.23.
     //
     // DO NOT MODIFY!
     // CHECKSTYLE:OFF Generated code
@@ -89,8 +89,8 @@
     }
 
     @DataClass.Generated(
-            time = 1604522377011L,
-            codegenVersion = "1.0.20",
+            time = 1616541544639L,
+            codegenVersion = "1.0.23",
             sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/StaleDataclassDetectorFalsePositivesTest.java",
             inputSignatures = "private @android.annotation.Nullable java.util.List<java.util.Set<?>> mUsesWildcards\npublic @android.annotation.NonNull java.lang.String someMethod(int)\nprivate @android.annotation.IntRange void annotatedWithConstArg()\nclass StaleDataclassDetectorFalsePositivesTest extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genBuilder=false)")
     @Deprecated
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt
index e6a4501..ed0a98d 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt
@@ -101,10 +101,10 @@
         }
     } else {
         assertLayersStart {
-            this.coversAtLeast(startingBounds)
+            this.visibleRegion().coversAtLeast(startingBounds)
         }
         assertLayersEnd {
-            this.coversAtLeast(endingBounds)
+            this.visibleRegion().coversAtLeast(endingBounds)
         }
     }
 }
@@ -152,10 +152,10 @@
     val endingPos = WindowUtils.getNavigationBarPosition(endRotation)
 
     assertLayersStart {
-        this.coversExactly(startingPos, NAV_BAR_LAYER_NAME)
+        this.visibleRegion(NAV_BAR_LAYER_NAME).coversExactly(startingPos)
     }
     assertLayersEnd {
-        this.coversExactly(endingPos, NAV_BAR_LAYER_NAME)
+        this.visibleRegion(NAV_BAR_LAYER_NAME).coversExactly(endingPos)
     }
 }
 
@@ -168,10 +168,10 @@
     val endingPos = WindowUtils.getStatusBarPosition(endRotation)
 
     assertLayersStart {
-        this.coversExactly(startingPos, STATUS_BAR_WINDOW_NAME)
+        this.visibleRegion(STATUS_BAR_WINDOW_NAME).coversExactly(startingPos)
     }
     assertLayersEnd {
-        this.coversExactly(endingPos, STATUS_BAR_WINDOW_NAME)
+        this.visibleRegion(STATUS_BAR_WINDOW_NAME).coversExactly(endingPos)
     }
 }
 
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 e118363..a524466 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
@@ -19,6 +19,7 @@
 import android.app.Instrumentation
 import android.platform.test.annotations.Presubmit
 import android.view.Surface
+import androidx.test.filters.FlakyTest
 import androidx.test.platform.app.InstrumentationRegistry
 import com.android.server.wm.flicker.FlickerBuilderProvider
 import com.android.server.wm.flicker.FlickerTestParameter
@@ -87,13 +88,13 @@
         testSpec.statusBarLayerIsAlwaysVisible()
     }
 
-    @Presubmit
+    @FlakyTest
     @Test
     open fun navBarLayerRotatesAndScales() {
         testSpec.navBarLayerRotatesAndScales(testSpec.config.startRotation, Surface.ROTATION_0)
     }
 
-    @Presubmit
+    @FlakyTest
     @Test
     open fun statusBarLayerRotatesScales() {
         testSpec.statusBarLayerRotatesScales(testSpec.config.startRotation, Surface.ROTATION_0)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppAutoFocusHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppAutoFocusHelper.kt
index 619a05e..bd7c185 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppAutoFocusHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppAutoFocusHelper.kt
@@ -34,7 +34,7 @@
         wmHelper: WindowManagerStateHelper?
     ) {
         // do nothing (the app is focused automatically)
-        waitAndAssertIMEShown(device, wmHelper)
+        waitIMEShown(device, wmHelper)
     }
 
     override fun open() {
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 d8091a9..83fddae 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
@@ -51,17 +51,17 @@
                 "was left in an unknown state (e.g. in split screen)"
         }
         editText.click()
-        waitAndAssertIMEShown(device, wmHelper)
+        waitIMEShown(device, wmHelper)
     }
 
-    protected fun waitAndAssertIMEShown(
+    protected fun waitIMEShown(
         device: UiDevice,
         wmHelper: WindowManagerStateHelper? = null
     ) {
         if (wmHelper == null) {
             device.waitForIdle()
         } else {
-            require(wmHelper.waitImeWindowShown()) { "IME did not appear" }
+            wmHelper.waitImeWindowShown()
         }
     }
 
@@ -78,7 +78,7 @@
         if (wmHelper == null) {
             device.waitForIdle()
         } else {
-            require(wmHelper.waitImeWindowGone()) { "IME did did not close" }
+            wmHelper.waitImeWindowGone()
         }
     }
 }
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt
index b25bc99..dfb229d 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt
@@ -136,7 +136,7 @@
     @Test
     fun statusBarLayerIsAlwaysVisible() = testSpec.statusBarLayerIsAlwaysVisible()
 
-    @Presubmit
+    @FlakyTest
     @Test
     fun visibleLayersShownMoreThanOneConsecutiveEntry() {
         testSpec.assertLayers {
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt
index d39044ab..7ba9db1 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt
@@ -20,6 +20,7 @@
 import android.platform.test.annotations.Presubmit
 import android.view.Surface
 import android.view.WindowManagerPolicyConstants
+import androidx.test.filters.FlakyTest
 import androidx.test.filters.RequiresDevice
 import androidx.test.platform.app.InstrumentationRegistry
 import com.android.server.wm.flicker.FlickerBuilderProvider
@@ -134,7 +135,7 @@
         }
     }
 
-    @Presubmit
+    @FlakyTest
     @Test
     fun visibleWindowsShownMoreThanOneConsecutiveEntry() {
         testSpec.assertWm {
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 95b1d3c..be0357e 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
@@ -153,7 +153,7 @@
         testSpec.statusBarLayerRotatesScales(Surface.ROTATION_0, testSpec.config.endRotation)
     }
 
-    @Presubmit
+    @FlakyTest
     @Test
     fun visibleLayersShownMoreThanOneConsecutiveEntry() {
         testSpec.assertLayers {
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt
index a9888b1..a3d1395 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.server.wm.flicker.launch
 
+import androidx.test.filters.FlakyTest
 import androidx.test.filters.RequiresDevice
 import com.android.server.wm.flicker.FlickerParametersRunnerFactory
 import com.android.server.wm.flicker.FlickerTestParameter
@@ -24,6 +25,7 @@
 import com.android.server.wm.flicker.startRotation
 import com.android.server.wm.flicker.dsl.FlickerBuilder
 import org.junit.FixMethodOrder
+import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.MethodSorters
 import org.junit.runners.Parameterized
@@ -56,6 +58,12 @@
             }
         }
 
+    @FlakyTest
+    @Test
+    override fun visibleLayersShownMoreThanOneConsecutiveEntry() {
+        super.visibleLayersShownMoreThanOneConsecutiveEntry()
+    }
+
     companion object {
         @Parameterized.Parameters(name = "{0}")
         @JvmStatic
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt
index a19a95d..62b9b81 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt
@@ -80,6 +80,24 @@
         super.navBarLayerRotatesAndScales()
     }
 
+    @FlakyTest
+    @Test
+    override fun statusBarLayerRotatesScales() {
+        super.statusBarLayerRotatesScales()
+    }
+
+    @FlakyTest
+    @Test
+    override fun visibleLayersShownMoreThanOneConsecutiveEntry() {
+        super.visibleLayersShownMoreThanOneConsecutiveEntry()
+    }
+
+    @FlakyTest
+    @Test
+    override fun focusChanges() {
+        super.focusChanges()
+    }
+
     companion object {
         @Parameterized.Parameters(name = "{0}")
         @JvmStatic
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt
index dcc64c9..38af8a7d 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.server.wm.flicker.launch
 
+import androidx.test.filters.FlakyTest
 import androidx.test.filters.RequiresDevice
 import com.android.server.wm.flicker.FlickerParametersRunnerFactory
 import com.android.server.wm.flicker.FlickerTestParameter
@@ -24,6 +25,7 @@
 import com.android.server.wm.flicker.startRotation
 import com.android.server.wm.flicker.dsl.FlickerBuilder
 import org.junit.FixMethodOrder
+import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.MethodSorters
 import org.junit.runners.Parameterized
@@ -61,6 +63,18 @@
             }
         }
 
+    @FlakyTest
+    @Test
+    override fun focusChanges() {
+        super.focusChanges()
+    }
+
+    @FlakyTest
+    @Test
+    override fun visibleLayersShownMoreThanOneConsecutiveEntry() {
+        super.visibleLayersShownMoreThanOneConsecutiveEntry()
+    }
+
     companion object {
         @Parameterized.Parameters(name = "{0}")
         @JvmStatic
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
index f037f1d..35ad597 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
@@ -24,7 +24,6 @@
 import com.android.server.wm.flicker.FlickerTestParameterFactory
 import com.android.server.wm.flicker.dsl.FlickerBuilder
 import com.android.server.wm.flicker.helpers.SimpleAppHelper
-import org.junit.Assume
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -61,20 +60,6 @@
 
     @Presubmit
     @Test
-    override fun navBarLayerRotatesAndScales() {
-        Assume.assumeFalse(testSpec.isRotated)
-        super.navBarLayerRotatesAndScales()
-    }
-
-    @FlakyTest(bugId = 140855415)
-    @Test
-    fun navBarLayerRotatesAndScales_flaky() {
-        Assume.assumeTrue(testSpec.isRotated)
-        super.navBarLayerRotatesAndScales()
-    }
-
-    @Presubmit
-    @Test
     fun screenshotLayerBecomesInvisible() {
         testSpec.assertLayers {
             this.isVisible(testApp.getPackage())
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/RotationTransition.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/RotationTransition.kt
index 6d2a923..2989035 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/RotationTransition.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/RotationTransition.kt
@@ -18,6 +18,7 @@
 
 import android.app.Instrumentation
 import android.platform.test.annotations.Presubmit
+import androidx.test.filters.FlakyTest
 import androidx.test.platform.app.InstrumentationRegistry
 import com.android.server.wm.flicker.FlickerBuilderProvider
 import com.android.server.wm.flicker.FlickerTestParameter
@@ -79,7 +80,7 @@
         testSpec.navBarLayerIsAlwaysVisible()
     }
 
-    @Presubmit
+    @FlakyTest
     @Test
     open fun navBarLayerRotatesAndScales() {
         testSpec.navBarLayerRotatesAndScales(
@@ -98,14 +99,14 @@
         testSpec.statusBarLayerIsAlwaysVisible()
     }
 
-    @Presubmit
+    @FlakyTest
     @Test
     open fun statusBarLayerRotatesScales() {
         testSpec.statusBarLayerRotatesScales(
             testSpec.config.startRotation, testSpec.config.endRotation)
     }
 
-    @Presubmit
+    @FlakyTest
     @Test
     open fun visibleLayersShownMoreThanOneConsecutiveEntry() {
         testSpec.assertLayers {
@@ -121,7 +122,7 @@
         }
     }
 
-    @Presubmit
+    @FlakyTest
     @Test
     open fun noUncoveredRegions() {
         testSpec.noUncoveredRegions(testSpec.config.startRotation,
@@ -134,19 +135,19 @@
         testSpec.focusDoesNotChange()
     }
 
-    @Presubmit
+    @FlakyTest
     @Test
     open fun appLayerRotates_StartingPos() {
         testSpec.assertLayersStart {
-            this.coversExactly(startingPos, testApp.getPackage())
+            this.visibleRegion(testApp.getPackage()).coversExactly(startingPos)
         }
     }
 
-    @Presubmit
+    @FlakyTest
     @Test
     open fun appLayerRotates_EndingPos() {
         testSpec.assertLayersEnd {
-            this.coversExactly(endingPos, testApp.getPackage())
+            this.visibleRegion(testApp.getPackage()).coversExactly(endingPos)
         }
     }
 }
\ No newline at end of file
diff --git a/tests/Input/src/com/android/test/input/InputEventAssignerTest.kt b/tests/Input/src/com/android/test/input/InputEventAssignerTest.kt
index b9b347b..c1a86b3 100644
--- a/tests/Input/src/com/android/test/input/InputEventAssignerTest.kt
+++ b/tests/Input/src/com/android/test/input/InputEventAssignerTest.kt
@@ -87,7 +87,7 @@
         assertEquals(down.id, eventId)
 
         // Now send CALLBACK_INPUT to the assigner. It should provide the latest motion event
-        assigner.onChoreographerCallback()
+        assigner.notifyFrameProcessed()
         eventId = assigner.processEvent(move3)
         assertEquals(move3.id, eventId)
         eventId = assigner.processEvent(move4)
@@ -122,7 +122,7 @@
         eventId = assigner.processEvent(up)
         // DOWN is only sticky for Motions, not for keys
         assertEquals(up.id, eventId)
-        assigner.onChoreographerCallback()
+        assigner.notifyFrameProcessed()
         val down2 = createKeyEvent(KeyEvent.ACTION_DOWN, 22)
         eventId = assigner.processEvent(down2)
         assertEquals(down2.id, eventId)
diff --git a/tests/Input/src/com/android/test/input/InputEventSenderAndReceiverTest.kt b/tests/Input/src/com/android/test/input/InputEventSenderAndReceiverTest.kt
index 4f95ce5..b134fe7 100644
--- a/tests/Input/src/com/android/test/input/InputEventSenderAndReceiverTest.kt
+++ b/tests/Input/src/com/android/test/input/InputEventSenderAndReceiverTest.kt
@@ -17,6 +17,7 @@
 package com.android.test.input
 
 import android.os.HandlerThread
+import android.os.InputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS
 import android.os.Looper
 import android.view.InputChannel
 import android.view.InputEvent
@@ -24,7 +25,8 @@
 import android.view.InputEventSender
 import android.view.KeyEvent
 import android.view.MotionEvent
-import java.util.concurrent.CountDownLatch
+import java.util.concurrent.LinkedBlockingQueue
+import java.util.concurrent.TimeUnit
 import org.junit.Assert.assertEquals
 import org.junit.After
 import org.junit.Before
@@ -44,41 +46,44 @@
     assertEquals(expected.displayId, received.displayId)
 }
 
+private fun <T> getEvent(queue: LinkedBlockingQueue<T>): T {
+    try {
+        return queue.poll(DEFAULT_DISPATCHING_TIMEOUT_MILLIS.toLong(), TimeUnit.MILLISECONDS)
+    } catch (e: InterruptedException) {
+        throw RuntimeException("Unexpectedly interrupted while waiting for event")
+    }
+}
+
 class TestInputEventReceiver(channel: InputChannel, looper: Looper) :
         InputEventReceiver(channel, looper) {
-    companion object {
-        const val TAG = "TestInputEventReceiver"
-    }
-
-    var lastEvent: InputEvent? = null
+    private val mInputEvents = LinkedBlockingQueue<InputEvent>()
 
     override fun onInputEvent(event: InputEvent) {
-        lastEvent = when (event) {
-            is KeyEvent -> KeyEvent.obtain(event)
-            is MotionEvent -> MotionEvent.obtain(event)
+        when (event) {
+            is KeyEvent -> mInputEvents.put(KeyEvent.obtain(event))
+            is MotionEvent -> mInputEvents.put(MotionEvent.obtain(event))
             else -> throw Exception("Received $event is neither a key nor a motion")
         }
         finishInputEvent(event, true /*handled*/)
     }
+
+    fun getInputEvent(): InputEvent {
+        return getEvent(mInputEvents)
+    }
 }
 
 class TestInputEventSender(channel: InputChannel, looper: Looper) :
         InputEventSender(channel, looper) {
-    companion object {
-        const val TAG = "TestInputEventSender"
-    }
-    data class FinishedResult(val seq: Int, val handled: Boolean)
+    data class FinishedSignal(val seq: Int, val handled: Boolean)
 
-    private var mFinishedSignal = CountDownLatch(1)
+    private val mFinishedSignals = LinkedBlockingQueue<FinishedSignal>()
+
     override fun onInputEventFinished(seq: Int, handled: Boolean) {
-        finishedResult = FinishedResult(seq, handled)
-        mFinishedSignal.countDown()
+        mFinishedSignals.put(FinishedSignal(seq, handled))
     }
-    lateinit var finishedResult: FinishedResult
 
-    fun waitForFinish() {
-        mFinishedSignal.await()
-        mFinishedSignal = CountDownLatch(1) // Ready for next event
+    fun getFinishedSignal(): FinishedSignal {
+        return getEvent(mFinishedSignals)
     }
 }
 
@@ -111,13 +116,13 @@
                 KeyEvent.KEYCODE_A, 0 /*repeat*/)
         val seq = 10
         mSender.sendInputEvent(seq, key)
-        mSender.waitForFinish()
+        val receivedKey = mReceiver.getInputEvent() as KeyEvent
+        val finishedSignal = mSender.getFinishedSignal()
 
         // Check receiver
-        assertKeyEvent(key, mReceiver.lastEvent!! as KeyEvent)
+        assertKeyEvent(key, receivedKey)
 
         // Check sender
-        assertEquals(seq, mSender.finishedResult.seq)
-        assertEquals(true, mSender.finishedResult.handled)
+        assertEquals(TestInputEventSender.FinishedSignal(seq, handled = true), finishedSignal)
     }
 }
diff --git a/tests/StagedInstallTest/Android.bp b/tests/StagedInstallTest/Android.bp
index 2e57467..c679d04 100644
--- a/tests/StagedInstallTest/Android.bp
+++ b/tests/StagedInstallTest/Android.bp
@@ -25,17 +25,24 @@
     name: "StagedInstallInternalTestApp",
     manifest: "app/AndroidManifest.xml",
     srcs: ["app/src/**/*.java"],
-    static_libs: ["androidx.test.rules", "cts-install-lib"],
+    static_libs: [
+        "androidx.test.rules",
+        "cts-install-lib",
+    ],
     test_suites: ["general-tests"],
     java_resources: [
         ":com.android.apex.apkrollback.test_v2",
+        ":StagedInstallTestApexV2_WrongSha",
     ],
 }
 
 java_test_host {
     name: "StagedInstallInternalTest",
     srcs: ["src/**/*.java"],
-    libs: ["tradefed", "cts-shim-host-lib"],
+    libs: [
+        "tradefed",
+        "cts-shim-host-lib",
+    ],
     static_libs: [
         "testng",
         "compatibility-tradefed",
diff --git a/tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java b/tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java
index ad8aac1..e633c87 100644
--- a/tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java
+++ b/tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java
@@ -17,6 +17,7 @@
 package com.android.tests.stagedinstallinternal;
 
 import static com.android.cts.install.lib.InstallUtils.getPackageInstaller;
+import static com.android.cts.shim.lib.ShimPackage.SHIM_APEX_PACKAGE_NAME;
 
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.common.truth.Truth.assertWithMessage;
@@ -50,6 +51,9 @@
     private static final String APK_IN_APEX_TESTAPEX_NAME = "com.android.apex.apkrollback.test";
     private static final TestApp TEST_APEX_WITH_APK_V2 = new TestApp("TestApexWithApkV2",
             APK_IN_APEX_TESTAPEX_NAME, 2, /*isApex*/true, APK_IN_APEX_TESTAPEX_NAME + "_v2.apex");
+    private static final TestApp APEX_WRONG_SHA_V2 = new TestApp(
+            "ApexWrongSha2", SHIM_APEX_PACKAGE_NAME, 2, /*isApex*/true,
+            "com.android.apex.cts.shim.v2_wrong_sha.apex");
 
     private File mTestStateFile = new File(
             InstrumentationRegistry.getInstrumentation().getContext().getFilesDir(),
@@ -128,6 +132,26 @@
     }
 
     @Test
+    public void testStagedSessionShouldCleanUpOnVerificationFailure() throws Exception {
+        InstallUtils.commitExpectingFailure(AssertionError.class, "apexd verification failed",
+                Install.single(APEX_WRONG_SHA_V2).setStaged());
+    }
+
+    @Test
+    public void testStagedSessionShouldCleanUpOnOnSuccess_Commit() throws Exception {
+        int sessionId = Install.single(TestApp.A1).setStaged().commit();
+        storeSessionId(sessionId);
+    }
+
+    @Test
+    public void testStagedSessionShouldCleanUpOnOnSuccess_Verify() throws Exception {
+        int sessionId = retrieveLastSessionId();
+        PackageInstaller.SessionInfo info = InstallUtils.getStagedSessionInfo(sessionId);
+        assertThat(info).isNotNull();
+        assertThat(info.isStagedSessionApplied()).isTrue();
+    }
+
+    @Test
     public void testStagedInstallationShouldCleanUpOnValidationFailure() throws Exception {
         InstallUtils.commitExpectingFailure(AssertionError.class, "INSTALL_FAILED_INVALID_APK",
                 Install.single(TestApp.AIncompleteSplit).setStaged());
diff --git a/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java b/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java
index 8dc53ac..9fd190c 100644
--- a/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java
+++ b/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java
@@ -44,7 +44,6 @@
 import org.junit.runner.RunWith;
 
 import java.io.File;
-import java.util.Collections;
 import java.util.List;
 import java.util.stream.Collectors;
 
@@ -252,6 +251,28 @@
     }
 
     @Test
+    public void testStagedSessionShouldCleanUpOnVerificationFailure() throws Exception {
+        assumeTrue("Device does not support updating APEX",
+                mHostUtils.isApexUpdateSupported());
+        List<String> before = getStagingDirectories();
+        runPhase("testStagedSessionShouldCleanUpOnVerificationFailure");
+        List<String> after = getStagingDirectories();
+        assertThat(after).isEqualTo(before);
+    }
+
+    @Test
+    @LargeTest
+    public void testStagedSessionShouldCleanUpOnOnSuccess() throws Exception {
+        List<String> before = getStagingDirectories();
+        runPhase("testStagedSessionShouldCleanUpOnOnSuccess_Commit");
+        assertThat(getStagingDirectories()).isNotEqualTo(before);
+        getDevice().reboot();
+        runPhase("testStagedSessionShouldCleanUpOnOnSuccess_Verify");
+        List<String> after = getStagingDirectories();
+        assertThat(after).isEqualTo(before);
+    }
+
+    @Test
     public void testStagedInstallationShouldCleanUpOnValidationFailure() throws Exception {
         List<String> before = getStagingDirectories();
         runPhase("testStagedInstallationShouldCleanUpOnValidationFailure");
@@ -273,12 +294,14 @@
         //create random directories in /data/app-staging folder
         getDevice().enableAdbRoot();
         getDevice().executeShellCommand("mkdir /data/app-staging/session_123");
-        getDevice().executeShellCommand("mkdir /data/app-staging/random_name");
+        getDevice().executeShellCommand("mkdir /data/app-staging/session_456");
         getDevice().disableAdbRoot();
 
-        assertThat(getStagingDirectories()).isNotEmpty();
+        assertThat(getStagingDirectories()).contains("session_123");
+        assertThat(getStagingDirectories()).contains("session_456");
         getDevice().reboot();
-        assertThat(getStagingDirectories()).isEmpty();
+        assertThat(getStagingDirectories()).doesNotContain("session_123");
+        assertThat(getStagingDirectories()).doesNotContain("session_456");
     }
 
     @Test
@@ -304,9 +327,6 @@
                     .stream().filter(entry -> entry.getName().matches("session_\\d+"))
                     .map(entry -> entry.getName())
                     .collect(Collectors.toList());
-        } catch (Exception e) {
-            // Return an empty list if any error
-            return Collections.EMPTY_LIST;
         } finally {
             getDevice().disableAdbRoot();
         }
diff --git a/tests/UsesFeature2Test/AndroidManifest.xml b/tests/UsesFeature2Test/AndroidManifest.xml
index 8caf4a1..1f1a909 100644
--- a/tests/UsesFeature2Test/AndroidManifest.xml
+++ b/tests/UsesFeature2Test/AndroidManifest.xml
@@ -22,6 +22,9 @@
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
     <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
     <uses-permission android:name="android.permission.BLUETOOTH" />
+    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
+    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
+    <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
 
     <uses-feature android:name="android.hardware.sensor.accelerometer" />
     <feature-group android:label="@string/minimal">
diff --git a/tests/net/common/java/android/net/NetworkAgentConfigTest.kt b/tests/net/common/java/android/net/NetworkAgentConfigTest.kt
index a4d8353..1e54093 100644
--- a/tests/net/common/java/android/net/NetworkAgentConfigTest.kt
+++ b/tests/net/common/java/android/net/NetworkAgentConfigTest.kt
@@ -19,6 +19,7 @@
 import android.os.Build
 import androidx.test.filters.SmallTest
 import androidx.test.runner.AndroidJUnit4
+import com.android.modules.utils.build.SdkLevel.isAtLeastS
 import com.android.testutils.DevSdkIgnoreRule
 import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
 import com.android.testutils.assertParcelSane
@@ -44,7 +45,13 @@
             setPartialConnectivityAcceptable(false)
             setUnvalidatedConnectivityAcceptable(true)
         }.build()
-        assertParcelSane(config, 10)
+        if (isAtLeastS()) {
+            // From S, the config will have 12 items
+            assertParcelSane(config, 12)
+        } else {
+            // For R or below, the config will have 10 items
+            assertParcelSane(config, 10)
+        }
     }
 
     @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
diff --git a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
index a7ad695..e7718b5 100644
--- a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
+++ b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
@@ -35,14 +35,15 @@
 import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_WIFI_P2P;
-import static android.net.NetworkCapabilities.RESTRICTED_CAPABILITIES;
+import static android.net.NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION;
+import static android.net.NetworkCapabilities.REDACT_FOR_LOCAL_MAC_ADDRESS;
+import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS;
 import static android.net.NetworkCapabilities.SIGNAL_STRENGTH_UNSPECIFIED;
 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
 import static android.net.NetworkCapabilities.TRANSPORT_TEST;
 import static android.net.NetworkCapabilities.TRANSPORT_VPN;
 import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
 import static android.net.NetworkCapabilities.TRANSPORT_WIFI_AWARE;
-import static android.net.NetworkCapabilities.UNRESTRICTED_CAPABILITIES;
 import static android.os.Process.INVALID_UID;
 
 import static com.android.modules.utils.build.SdkLevel.isAtLeastR;
@@ -51,7 +52,6 @@
 import static com.android.testutils.MiscAsserts.assertThrows;
 import static com.android.testutils.ParcelUtils.assertParcelSane;
 import static com.android.testutils.ParcelUtils.assertParcelingIsLossless;
-import static com.android.testutils.ParcelUtils.parcelingRoundTrip;
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
@@ -62,7 +62,6 @@
 import static org.junit.Assert.fail;
 import static org.junit.Assume.assumeTrue;
 
-import android.net.wifi.WifiInfo;
 import android.net.wifi.aware.DiscoverySession;
 import android.net.wifi.aware.PeerHandle;
 import android.net.wifi.aware.WifiAwareNetworkSpecifier;
@@ -102,20 +101,6 @@
 
     @Test
     public void testMaybeMarkCapabilitiesRestricted() {
-        // verify EIMS is restricted
-        assertEquals((1 << NET_CAPABILITY_EIMS) & RESTRICTED_CAPABILITIES,
-                (1 << NET_CAPABILITY_EIMS));
-
-        // verify CBS is also restricted
-        assertEquals((1 << NET_CAPABILITY_CBS) & RESTRICTED_CAPABILITIES,
-                (1 << NET_CAPABILITY_CBS));
-
-        // verify default is not restricted
-        assertEquals((1 << NET_CAPABILITY_INTERNET) & RESTRICTED_CAPABILITIES, 0);
-
-        // just to see
-        assertEquals(RESTRICTED_CAPABILITIES & UNRESTRICTED_CAPABILITIES, 0);
-
         // check that internet does not get restricted
         NetworkCapabilities netCap = new NetworkCapabilities();
         netCap.addCapability(NET_CAPABILITY_INTERNET);
@@ -328,7 +313,8 @@
         if (isAtLeastS()) {
             netCap.setSubIds(Set.of(TEST_SUBID1, TEST_SUBID2));
             netCap.setUids(uids);
-        } else if (isAtLeastR()) {
+        }
+        if (isAtLeastR()) {
             netCap.setOwnerUid(123);
             netCap.setAdministratorUids(new int[] {5, 11});
         }
@@ -352,55 +338,6 @@
         testParcelSane(netCap);
     }
 
-    private NetworkCapabilities createNetworkCapabilitiesWithWifiInfo() {
-        // uses a real WifiInfo to test parceling of sensitive data.
-        final WifiInfo wifiInfo = new WifiInfo.Builder()
-                .setSsid("sssid1234".getBytes())
-                .setBssid("00:11:22:33:44:55")
-                .build();
-        return new NetworkCapabilities()
-                .addCapability(NET_CAPABILITY_INTERNET)
-                .addCapability(NET_CAPABILITY_EIMS)
-                .addCapability(NET_CAPABILITY_NOT_METERED)
-                .setSSID(TEST_SSID)
-                .setTransportInfo(wifiInfo)
-                .setRequestorPackageName("com.android.test")
-                .setRequestorUid(9304);
-    }
-
-    @Test
-    public void testParcelNetworkCapabilitiesWithLocationSensitiveFields() {
-        assumeTrue(isAtLeastS());
-
-        final NetworkCapabilities netCap = createNetworkCapabilitiesWithWifiInfo();
-        final NetworkCapabilities netCapWithLocationSensitiveFields =
-                new NetworkCapabilities(netCap, true);
-
-        assertParcelingIsLossless(netCapWithLocationSensitiveFields);
-        testParcelSane(netCapWithLocationSensitiveFields);
-
-        assertEquals(netCapWithLocationSensitiveFields,
-                parcelingRoundTrip(netCapWithLocationSensitiveFields));
-    }
-
-    @Test
-    public void testParcelNetworkCapabilitiesWithoutLocationSensitiveFields() {
-        assumeTrue(isAtLeastS());
-
-        final NetworkCapabilities netCap = createNetworkCapabilitiesWithWifiInfo();
-        final NetworkCapabilities netCapWithoutLocationSensitiveFields =
-                new NetworkCapabilities(netCap, false);
-
-        final NetworkCapabilities sanitizedNetCap =
-                new NetworkCapabilities(netCapWithoutLocationSensitiveFields);
-        final WifiInfo sanitizedWifiInfo = new WifiInfo.Builder()
-                .setSsid(new byte[0])
-                .setBssid(WifiInfo.DEFAULT_MAC_ADDRESS)
-                .build();
-        sanitizedNetCap.setTransportInfo(sanitizedWifiInfo);
-        assertEquals(sanitizedNetCap, parcelingRoundTrip(netCapWithoutLocationSensitiveFields));
-    }
-
     private void testParcelSane(NetworkCapabilities cap) {
         if (isAtLeastS()) {
             assertParcelSane(cap, 17);
@@ -411,6 +348,45 @@
         }
     }
 
+    private static NetworkCapabilities createNetworkCapabilitiesWithTransportInfo() {
+        return new NetworkCapabilities()
+                .addCapability(NET_CAPABILITY_INTERNET)
+                .addCapability(NET_CAPABILITY_EIMS)
+                .addCapability(NET_CAPABILITY_NOT_METERED)
+                .setSSID(TEST_SSID)
+                .setTransportInfo(new TestTransportInfo())
+                .setRequestorPackageName("com.android.test")
+                .setRequestorUid(9304);
+    }
+
+    @Test
+    public void testNetworkCapabilitiesCopyWithNoRedactions() {
+        assumeTrue(isAtLeastS());
+
+        final NetworkCapabilities netCap = createNetworkCapabilitiesWithTransportInfo();
+        final NetworkCapabilities netCapWithNoRedactions =
+                new NetworkCapabilities(netCap, NetworkCapabilities.REDACT_NONE);
+        TestTransportInfo testTransportInfo =
+                (TestTransportInfo) netCapWithNoRedactions.getTransportInfo();
+        assertFalse(testTransportInfo.locationRedacted);
+        assertFalse(testTransportInfo.localMacAddressRedacted);
+        assertFalse(testTransportInfo.settingsRedacted);
+    }
+
+    @Test
+    public void testNetworkCapabilitiesCopyWithoutLocationSensitiveFields() {
+        assumeTrue(isAtLeastS());
+
+        final NetworkCapabilities netCap = createNetworkCapabilitiesWithTransportInfo();
+        final NetworkCapabilities netCapWithNoRedactions =
+                new NetworkCapabilities(netCap, REDACT_FOR_ACCESS_FINE_LOCATION);
+        TestTransportInfo testTransportInfo =
+                (TestTransportInfo) netCapWithNoRedactions.getTransportInfo();
+        assertTrue(testTransportInfo.locationRedacted);
+        assertFalse(testTransportInfo.localMacAddressRedacted);
+        assertFalse(testTransportInfo.settingsRedacted);
+    }
+
     @Test
     public void testOemPaid() {
         NetworkCapabilities nc = new NetworkCapabilities();
@@ -540,11 +516,22 @@
         assertFalse(nc1.equalsNetCapabilities(nc2));
         nc2.addUnwantedCapability(NET_CAPABILITY_INTERNET);
         assertTrue(nc1.equalsNetCapabilities(nc2));
+        if (isAtLeastS()) {
+            // Remove a required capability doesn't affect unwanted capabilities.
+            // This is a behaviour change from S.
+            nc1.removeCapability(NET_CAPABILITY_INTERNET);
+            assertTrue(nc1.equalsNetCapabilities(nc2));
 
-        nc1.removeCapability(NET_CAPABILITY_INTERNET);
-        assertFalse(nc1.equalsNetCapabilities(nc2));
-        nc2.removeCapability(NET_CAPABILITY_INTERNET);
-        assertTrue(nc1.equalsNetCapabilities(nc2));
+            nc1.removeUnwantedCapability(NET_CAPABILITY_INTERNET);
+            assertFalse(nc1.equalsNetCapabilities(nc2));
+            nc2.removeUnwantedCapability(NET_CAPABILITY_INTERNET);
+            assertTrue(nc1.equalsNetCapabilities(nc2));
+        } else {
+            nc1.removeCapability(NET_CAPABILITY_INTERNET);
+            assertFalse(nc1.equalsNetCapabilities(nc2));
+            nc2.removeCapability(NET_CAPABILITY_INTERNET);
+            assertTrue(nc1.equalsNetCapabilities(nc2));
+        }
     }
 
     @Test
@@ -605,11 +592,21 @@
         // This will effectively move NOT_ROAMING capability from required to unwanted for nc1.
         nc1.addUnwantedCapability(NET_CAPABILITY_NOT_ROAMING);
 
-        nc2.combineCapabilities(nc1);
-        // We will get this capability in both requested and unwanted lists thus this request
-        // will never be satisfied.
-        assertTrue(nc2.hasCapability(NET_CAPABILITY_NOT_ROAMING));
-        assertTrue(nc2.hasUnwantedCapability(NET_CAPABILITY_NOT_ROAMING));
+        if (isAtLeastS()) {
+            // From S, it is not allowed to have the same capability in both wanted and
+            // unwanted list.
+            assertThrows(IllegalArgumentException.class, () -> nc2.combineCapabilities(nc1));
+            // Remove unwanted capability to continue other tests.
+            nc1.removeUnwantedCapability(NET_CAPABILITY_NOT_ROAMING);
+        } else {
+            nc2.combineCapabilities(nc1);
+            // We will get this capability in both requested and unwanted lists thus this request
+            // will never be satisfied.
+            assertTrue(nc2.hasCapability(NET_CAPABILITY_NOT_ROAMING));
+            assertTrue(nc2.hasUnwantedCapability(NET_CAPABILITY_NOT_ROAMING));
+            // For R or below, remove unwanted capability via removeCapability.
+            nc1.removeCapability(NET_CAPABILITY_NOT_ROAMING);
+        }
 
         nc1.setSSID(TEST_SSID);
         nc2.combineCapabilities(nc1);
@@ -972,26 +969,6 @@
         assertNotEquals(-50, nc.getSignalStrength());
     }
 
-    @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
-    public void testDeduceRestrictedCapability() {
-        final NetworkCapabilities nc = new NetworkCapabilities();
-        // Default capabilities don't have restricted capability.
-        assertFalse(nc.deduceRestrictedCapability());
-        // If there is a force restricted capability, then the network capabilities is restricted.
-        nc.addCapability(NET_CAPABILITY_OEM_PAID);
-        nc.addCapability(NET_CAPABILITY_INTERNET);
-        assertTrue(nc.deduceRestrictedCapability());
-        // Except for the force restricted capability, if there is any unrestricted capability in
-        // capabilities, then the network capabilities is not restricted.
-        nc.removeCapability(NET_CAPABILITY_OEM_PAID);
-        nc.addCapability(NET_CAPABILITY_CBS);
-        assertFalse(nc.deduceRestrictedCapability());
-        // Except for the force restricted capability, the network capabilities will only be treated
-        // as restricted when there is no any unrestricted capability.
-        nc.removeCapability(NET_CAPABILITY_INTERNET);
-        assertTrue(nc.deduceRestrictedCapability());
-    }
-
     private void assertNoTransport(NetworkCapabilities nc) {
         for (int i = MIN_TRANSPORT; i <= MAX_TRANSPORT; i++) {
             assertFalse(nc.hasTransport(i));
@@ -1062,18 +1039,42 @@
         } catch (IllegalArgumentException e) { }
     }
 
-    private class TestTransportInfo implements TransportInfo {
+    /**
+     * Test TransportInfo to verify redaction mechanism.
+     */
+    private static class TestTransportInfo implements TransportInfo {
+        public final boolean locationRedacted;
+        public final boolean localMacAddressRedacted;
+        public final boolean settingsRedacted;
+
         TestTransportInfo() {
+            locationRedacted = false;
+            localMacAddressRedacted = false;
+            settingsRedacted = false;
+        }
+
+        TestTransportInfo(boolean locationRedacted,
+                boolean localMacAddressRedacted,
+                boolean settingsRedacted) {
+            this.locationRedacted = locationRedacted;
+            this.localMacAddressRedacted =
+                    localMacAddressRedacted;
+            this.settingsRedacted = settingsRedacted;
         }
 
         @Override
-        public TransportInfo makeCopy(boolean parcelLocationSensitiveFields) {
-            return this;
+        public TransportInfo makeCopy(@NetworkCapabilities.RedactionType long redactions) {
+            return new TestTransportInfo(
+                    (redactions & NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION) != 0,
+                    (redactions & REDACT_FOR_LOCAL_MAC_ADDRESS) != 0,
+                    (redactions & REDACT_FOR_NETWORK_SETTINGS) != 0
+            );
         }
 
         @Override
-        public boolean hasLocationSensitiveFields() {
-            return false;
+        public @NetworkCapabilities.RedactionType long getApplicableRedactions() {
+            return REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_LOCAL_MAC_ADDRESS
+                    | REDACT_FOR_NETWORK_SETTINGS;
         }
     }
 
@@ -1084,7 +1085,7 @@
         final int requestUid = 10100;
         final int[] administratorUids = {ownerUid, 10001};
         final TelephonyNetworkSpecifier specifier = new TelephonyNetworkSpecifier(1);
-        final TestTransportInfo transportInfo = new TestTransportInfo();
+        final TransportInfo transportInfo = new TransportInfo() {};
         final String ssid = "TEST_SSID";
         final String packageName = "com.google.test.networkcapabilities";
         final NetworkCapabilities nc = new NetworkCapabilities.Builder()
diff --git a/tests/net/common/java/android/net/NetworkProviderTest.kt b/tests/net/common/java/android/net/NetworkProviderTest.kt
index 340e6f9..7424157 100644
--- a/tests/net/common/java/android/net/NetworkProviderTest.kt
+++ b/tests/net/common/java/android/net/NetworkProviderTest.kt
@@ -198,4 +198,4 @@
         cb.expectCallback<OnUnavailable>() { nr.getNetworkSpecifier() == specifier }
         mCm.unregisterNetworkProvider(provider)
     }
-}
\ No newline at end of file
+}
diff --git a/tests/net/common/java/android/net/NetworkTest.java b/tests/net/common/java/android/net/NetworkTest.java
index 11d44b8..cd9da8e 100644
--- a/tests/net/common/java/android/net/NetworkTest.java
+++ b/tests/net/common/java/android/net/NetworkTest.java
@@ -22,11 +22,16 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
+import android.os.Build;
 import android.platform.test.annotations.AppModeFull;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
+
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -43,6 +48,9 @@
 public class NetworkTest {
     final Network mNetwork = new Network(99);
 
+    @Rule
+    public final DevSdkIgnoreRule mIgnoreRule = new DevSdkIgnoreRule();
+
     @Test
     public void testBindSocketOfInvalidFdThrows() throws Exception {
 
@@ -151,6 +159,23 @@
     }
 
     @Test
+    public void testFromNetworkHandle() {
+        final Network network = new Network(1234);
+        assertEquals(network.getNetId(),
+                Network.fromNetworkHandle(network.getNetworkHandle()).getNetId());
+    }
+
+    // Parsing private DNS bypassing handle was not supported until S
+    @Test @IgnoreUpTo(Build.VERSION_CODES.R)
+    public void testFromNetworkHandle_S() {
+        final Network network = new Network(1234, true);
+
+        final Network recreatedNetwork = Network.fromNetworkHandle(network.getNetworkHandle());
+        assertEquals(network.netId, recreatedNetwork.netId);
+        assertEquals(network.getNetIdForResolv(), recreatedNetwork.getNetIdForResolv());
+    }
+
+    @Test
     public void testGetPrivateDnsBypassingCopy() {
         final Network copy = mNetwork.getPrivateDnsBypassingCopy();
         assertEquals(mNetwork.netId, copy.netId);
diff --git a/tests/net/integration/src/android/net/TestNetworkStackClient.kt b/tests/net/integration/src/android/net/TestNetworkStackClient.kt
index 01eb514..61ef5bd 100644
--- a/tests/net/integration/src/android/net/TestNetworkStackClient.kt
+++ b/tests/net/integration/src/android/net/TestNetworkStackClient.kt
@@ -19,6 +19,7 @@
 import android.content.ComponentName
 import android.content.Context
 import android.content.Intent
+import android.net.networkstack.NetworkStackClientBase
 import android.os.IBinder
 import com.android.server.net.integrationtests.TestNetworkStackService
 import org.mockito.Mockito.any
@@ -29,28 +30,22 @@
 
 const val TEST_ACTION_SUFFIX = ".Test"
 
-class TestNetworkStackClient(context: Context) : NetworkStackClient(TestDependencies(context)) {
+class TestNetworkStackClient(private val context: Context) : NetworkStackClientBase() {
     // TODO: consider switching to TrackRecord for more expressive checks
     private val lastCallbacks = HashMap<Network, INetworkMonitorCallbacks>()
+    private val moduleConnector = ConnectivityModuleConnector { _, action, _, _ ->
+        val intent = Intent(action)
+        val serviceName = TestNetworkStackService::class.qualifiedName
+                ?: fail("TestNetworkStackService name not found")
+        intent.component = ComponentName(context.packageName, serviceName)
+        return@ConnectivityModuleConnector intent
+    }.also { it.init(context) }
 
-    private class TestDependencies(private val context: Context) : Dependencies {
-        override fun addToServiceManager(service: IBinder) = Unit
-        override fun checkCallerUid() = Unit
-
-        override fun getConnectivityModuleConnector(): ConnectivityModuleConnector {
-            return ConnectivityModuleConnector { _, _, _, inSystemProcess ->
-                getNetworkStackIntent(inSystemProcess)
-            }.also { it.init(context) }
-        }
-
-        private fun getNetworkStackIntent(inSystemProcess: Boolean): Intent? {
-            // Simulate out-of-system-process config: in-process service not found (null intent)
-            if (inSystemProcess) return null
-            val intent = Intent(INetworkStackConnector::class.qualifiedName + TEST_ACTION_SUFFIX)
-            val serviceName = TestNetworkStackService::class.qualifiedName
-                    ?: fail("TestNetworkStackService name not found")
-            intent.component = ComponentName(context.packageName, serviceName)
-            return intent
+    fun start() {
+        moduleConnector.startModuleService(
+                INetworkStackConnector::class.qualifiedName + TEST_ACTION_SUFFIX,
+                NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) { connector ->
+            onNetworkStackConnected(INetworkStackConnector.Stub.asInterface(connector))
         }
     }
 
diff --git a/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt b/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt
index db49e0b..e039ef0 100644
--- a/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt
+++ b/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt
@@ -73,7 +73,7 @@
 import kotlin.test.fail
 
 const val SERVICE_BIND_TIMEOUT_MS = 5_000L
-const val TEST_TIMEOUT_MS = 1_000L
+const val TEST_TIMEOUT_MS = 10_000L
 
 /**
  * Test that exercises an instrumented version of ConnectivityService against an instrumented
@@ -157,7 +157,6 @@
         doReturn(IntArray(0)).`when`(systemConfigManager).getSystemPermissionUids(anyString())
 
         networkStackClient = TestNetworkStackClient(realContext)
-        networkStackClient.init()
         networkStackClient.start()
 
         service = TestConnectivityService(makeDependencies())
diff --git a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java b/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java
index e2d43cb..6245e8542 100644
--- a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java
+++ b/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java
@@ -41,6 +41,7 @@
 import android.net.NetworkAgentConfig;
 import android.net.NetworkCapabilities;
 import android.net.NetworkProvider;
+import android.net.NetworkScore;
 import android.net.NetworkSpecifier;
 import android.net.QosFilter;
 import android.net.SocketKeepalive;
@@ -199,6 +200,11 @@
         }
     }
 
+    public void setScore(@NonNull final NetworkScore score) {
+        mScore = score.getLegacyInt();
+        mNetworkAgent.sendNetworkScore(score);
+    }
+
     public void adjustScore(int change) {
         mScore += change;
         mNetworkAgent.sendNetworkScore(mScore);
diff --git a/tests/net/java/android/net/ConnectivityManagerTest.java b/tests/net/java/android/net/ConnectivityManagerTest.java
index 6fc605e..6cbdd25 100644
--- a/tests/net/java/android/net/ConnectivityManagerTest.java
+++ b/tests/net/java/android/net/ConnectivityManagerTest.java
@@ -41,10 +41,10 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.anyBoolean;
 import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
@@ -64,6 +64,7 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.Messenger;
+import android.os.Process;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
@@ -219,8 +220,8 @@
         ArgumentCaptor<Messenger> captor = ArgumentCaptor.forClass(Messenger.class);
 
         // register callback
-        when(mService.requestNetwork(any(), anyInt(), captor.capture(), anyInt(), any(), anyInt(),
-                anyInt(), any(), nullable(String.class))).thenReturn(request);
+        when(mService.requestNetwork(anyInt(), any(), anyInt(), captor.capture(), anyInt(), any(),
+                anyInt(), anyInt(), any(), nullable(String.class))).thenReturn(request);
         manager.requestNetwork(request, callback, handler);
 
         // callback triggers
@@ -247,8 +248,8 @@
         ArgumentCaptor<Messenger> captor = ArgumentCaptor.forClass(Messenger.class);
 
         // register callback
-        when(mService.requestNetwork(any(), anyInt(), captor.capture(), anyInt(), any(), anyInt(),
-                anyInt(), any(), nullable(String.class))).thenReturn(req1);
+        when(mService.requestNetwork(anyInt(), any(), anyInt(), captor.capture(), anyInt(), any(),
+                anyInt(), anyInt(), any(), nullable(String.class))).thenReturn(req1);
         manager.requestNetwork(req1, callback, handler);
 
         // callback triggers
@@ -265,8 +266,8 @@
         verify(callback, timeout(100).times(0)).onLosing(any(), anyInt());
 
         // callback can be registered again
-        when(mService.requestNetwork(any(), anyInt(), captor.capture(), anyInt(), any(), anyInt(),
-                anyInt(), any(), nullable(String.class))).thenReturn(req2);
+        when(mService.requestNetwork(anyInt(), any(), anyInt(), captor.capture(), anyInt(), any(),
+                anyInt(), anyInt(), any(), nullable(String.class))).thenReturn(req2);
         manager.requestNetwork(req2, callback, handler);
 
         // callback triggers
@@ -289,8 +290,8 @@
         info.targetSdkVersion = VERSION_CODES.N_MR1 + 1;
 
         when(mCtx.getApplicationInfo()).thenReturn(info);
-        when(mService.requestNetwork(any(), anyInt(), any(), anyInt(), any(), anyInt(), anyInt(),
-                any(), nullable(String.class))).thenReturn(request);
+        when(mService.requestNetwork(anyInt(), any(), anyInt(), any(), anyInt(), any(), anyInt(),
+                anyInt(), any(), nullable(String.class))).thenReturn(request);
 
         Handler handler = new Handler(Looper.getMainLooper());
         manager.requestNetwork(request, callback, handler);
@@ -357,34 +358,40 @@
         final NetworkCallback callback = new ConnectivityManager.NetworkCallback();
 
         manager.requestNetwork(request, callback);
-        verify(mService).requestNetwork(eq(request.networkCapabilities),
+        verify(mService).requestNetwork(eq(Process.INVALID_UID), eq(request.networkCapabilities),
                 eq(REQUEST.ordinal()), any(), anyInt(), any(), eq(TYPE_NONE), anyInt(),
                 eq(testPkgName), eq(testAttributionTag));
         reset(mService);
 
         // Verify that register network callback does not calls requestNetwork at all.
         manager.registerNetworkCallback(request, callback);
-        verify(mService, never()).requestNetwork(any(), anyInt(), any(), anyInt(), any(), anyInt(),
-                anyInt(), any(), any());
+        verify(mService, never()).requestNetwork(anyInt(), any(), anyInt(), any(), anyInt(), any(),
+                anyInt(), anyInt(), any(), any());
         verify(mService).listenForNetwork(eq(request.networkCapabilities), any(), any(), anyInt(),
                 eq(testPkgName), eq(testAttributionTag));
         reset(mService);
 
+        Handler handler = new Handler(ConnectivityThread.getInstanceLooper());
+
         manager.registerDefaultNetworkCallback(callback);
-        verify(mService).requestNetwork(eq(null),
+        verify(mService).requestNetwork(eq(Process.INVALID_UID), eq(null),
                 eq(TRACK_DEFAULT.ordinal()), any(), anyInt(), any(), eq(TYPE_NONE), anyInt(),
                 eq(testPkgName), eq(testAttributionTag));
         reset(mService);
 
-        Handler handler = new Handler(ConnectivityThread.getInstanceLooper());
+        manager.registerDefaultNetworkCallbackAsUid(42, callback, handler);
+        verify(mService).requestNetwork(eq(42), eq(null),
+                eq(TRACK_DEFAULT.ordinal()), any(), anyInt(), any(), eq(TYPE_NONE), anyInt(),
+                eq(testPkgName), eq(testAttributionTag));
+
         manager.requestBackgroundNetwork(request, handler, callback);
-        verify(mService).requestNetwork(eq(request.networkCapabilities),
+        verify(mService).requestNetwork(eq(Process.INVALID_UID), eq(request.networkCapabilities),
                 eq(BACKGROUND_REQUEST.ordinal()), any(), anyInt(), any(), eq(TYPE_NONE), anyInt(),
                 eq(testPkgName), eq(testAttributionTag));
         reset(mService);
 
         manager.registerSystemDefaultNetworkCallback(callback, handler);
-        verify(mService).requestNetwork(eq(null),
+        verify(mService).requestNetwork(eq(Process.INVALID_UID), eq(null),
                 eq(TRACK_SYSTEM_DEFAULT.ordinal()), any(), anyInt(), any(), eq(TYPE_NONE), anyInt(),
                 eq(testPkgName), eq(testAttributionTag));
         reset(mService);
diff --git a/tests/net/java/android/net/VpnTransportInfoTest.java b/tests/net/java/android/net/VpnTransportInfoTest.java
index b7a42ec..fee65f0 100644
--- a/tests/net/java/android/net/VpnTransportInfoTest.java
+++ b/tests/net/java/android/net/VpnTransportInfoTest.java
@@ -16,6 +16,9 @@
 
 package android.net;
 
+import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS;
+import static android.net.NetworkCapabilities.REDACT_NONE;
+
 import static com.android.testutils.ParcelUtils.assertParcelSane;
 
 import static org.junit.Assert.assertEquals;
@@ -33,23 +36,33 @@
 
     @Test
     public void testParceling() {
-        VpnTransportInfo v = new VpnTransportInfo(VpnManager.TYPE_VPN_PLATFORM);
-        assertParcelSane(v, 1 /* fieldCount */);
+        VpnTransportInfo v = new VpnTransportInfo(VpnManager.TYPE_VPN_PLATFORM, "12345");
+        assertParcelSane(v, 2 /* fieldCount */);
     }
 
     @Test
     public void testEqualsAndHashCode() {
-        VpnTransportInfo v1 = new VpnTransportInfo(VpnManager.TYPE_VPN_PLATFORM);
-        VpnTransportInfo v2 = new VpnTransportInfo(VpnManager.TYPE_VPN_SERVICE);
-        VpnTransportInfo v3 = new VpnTransportInfo(VpnManager.TYPE_VPN_PLATFORM);
-        VpnTransportInfo v4 = new VpnTransportInfo(VpnManager.TYPE_VPN_LEGACY);
-        VpnTransportInfo v5 = new VpnTransportInfo(VpnManager.TYPE_VPN_OEM);
+        String session1 = "12345";
+        String session2 = "6789";
+        VpnTransportInfo v11 = new VpnTransportInfo(VpnManager.TYPE_VPN_PLATFORM, session1);
+        VpnTransportInfo v12 = new VpnTransportInfo(VpnManager.TYPE_VPN_SERVICE, session1);
+        VpnTransportInfo v13 = new VpnTransportInfo(VpnManager.TYPE_VPN_PLATFORM, session1);
+        VpnTransportInfo v14 = new VpnTransportInfo(VpnManager.TYPE_VPN_LEGACY, session1);
+        VpnTransportInfo v15 = new VpnTransportInfo(VpnManager.TYPE_VPN_OEM, session1);
+        VpnTransportInfo v21 = new VpnTransportInfo(VpnManager.TYPE_VPN_LEGACY, session2);
 
-        assertNotEquals(v1, v2);
-        assertNotEquals(v3, v4);
-        assertNotEquals(v4, v5);
+        VpnTransportInfo v31 = v11.makeCopy(REDACT_FOR_NETWORK_SETTINGS);
+        VpnTransportInfo v32 = v13.makeCopy(REDACT_FOR_NETWORK_SETTINGS);
 
-        assertEquals(v1, v3);
-        assertEquals(v1.hashCode(), v3.hashCode());
+        assertNotEquals(v11, v12);
+        assertNotEquals(v13, v14);
+        assertNotEquals(v14, v15);
+        assertNotEquals(v14, v21);
+
+        assertEquals(v11, v13);
+        assertEquals(v31, v32);
+        assertEquals(v11.hashCode(), v13.hashCode());
+        assertEquals(REDACT_FOR_NETWORK_SETTINGS, v32.getApplicableRedactions());
+        assertEquals(session1, v15.makeCopy(REDACT_NONE).sessionId);
     }
-}
\ No newline at end of file
+}
diff --git a/tests/net/java/android/net/util/KeepaliveUtilsTest.kt b/tests/net/java/android/net/util/KeepaliveUtilsTest.kt
index b62bdbc..5006d53 100644
--- a/tests/net/java/android/net/util/KeepaliveUtilsTest.kt
+++ b/tests/net/java/android/net/util/KeepaliveUtilsTest.kt
@@ -101,7 +101,7 @@
 
         // Check valid customization generates expected array.
         val validRes = arrayOf("0,3", "1,0", "4,4")
-        val expectedValidRes = intArrayOf(3, 0, 0, 0, 4, 0, 0, 0)
+        val expectedValidRes = intArrayOf(3, 0, 0, 0, 4, 0, 0, 0, 0)
 
         val mockContext = getMockedContextWithStringArrayRes(
                 R.array.config_networkSupportedKeepaliveCount,
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 0b31999..8254f6b3 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -30,10 +30,14 @@
 import static android.content.pm.PackageManager.PERMISSION_DENIED;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.net.ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN;
+import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_DATA_SAVER;
+import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_MASK;
+import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_USER_RESTRICTED;
+import static android.net.ConnectivityManager.BLOCKED_REASON_BATTERY_SAVER;
+import static android.net.ConnectivityManager.BLOCKED_REASON_NONE;
 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
 import static android.net.ConnectivityManager.EXTRA_NETWORK_INFO;
 import static android.net.ConnectivityManager.EXTRA_NETWORK_TYPE;
-import static android.net.ConnectivityManager.NETID_UNSET;
 import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF;
 import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
 import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME;
@@ -82,15 +86,16 @@
 import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_WIFI_P2P;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_XCAP;
+import static android.net.NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION;
+import static android.net.NetworkCapabilities.REDACT_FOR_LOCAL_MAC_ADDRESS;
+import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS;
+import static android.net.NetworkCapabilities.REDACT_NONE;
 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
 import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
 import static android.net.NetworkCapabilities.TRANSPORT_VPN;
 import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
 import static android.net.NetworkCapabilities.TRANSPORT_WIFI_AWARE;
-import static android.net.NetworkPolicyManager.BLOCKED_METERED_REASON_DATA_SAVER;
-import static android.net.NetworkPolicyManager.BLOCKED_METERED_REASON_USER_RESTRICTED;
-import static android.net.NetworkPolicyManager.BLOCKED_REASON_BATTERY_SAVER;
-import static android.net.NetworkPolicyManager.BLOCKED_REASON_NONE;
+import static android.net.NetworkScore.KEEP_CONNECTED_FOR_HANDOVER;
 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID;
 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK;
 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY;
@@ -212,7 +217,6 @@
 import android.net.NetworkScore;
 import android.net.NetworkSpecifier;
 import android.net.NetworkStack;
-import android.net.NetworkStackClient;
 import android.net.NetworkStateSnapshot;
 import android.net.NetworkTestResultParcelable;
 import android.net.OemNetworkPreferences;
@@ -232,12 +236,12 @@
 import android.net.VpnManager;
 import android.net.VpnTransportInfo;
 import android.net.metrics.IpConnectivityLog;
+import android.net.networkstack.NetworkStackClientBase;
 import android.net.resolv.aidl.Nat64PrefixEventParcel;
 import android.net.resolv.aidl.PrivateDnsValidationEventParcel;
 import android.net.shared.NetworkMonitorUtils;
 import android.net.shared.PrivateDnsConfig;
 import android.net.util.MultinetworkPolicyTracker;
-import android.net.wifi.WifiInfo;
 import android.os.BadParcelableException;
 import android.os.Binder;
 import android.os.Build;
@@ -263,6 +267,7 @@
 import android.system.Os;
 import android.telephony.TelephonyManager;
 import android.telephony.data.EpsBearerQosSessionAttributes;
+import android.telephony.data.NrQosSessionAttributes;
 import android.test.mock.MockContentResolver;
 import android.text.TextUtils;
 import android.util.ArraySet;
@@ -443,7 +448,7 @@
     @Mock NetworkStatsManager mStatsManager;
     @Mock IDnsResolver mMockDnsResolver;
     @Mock INetd mMockNetd;
-    @Mock NetworkStackClient mNetworkStack;
+    @Mock NetworkStackClientBase mNetworkStack;
     @Mock PackageManager mPackageManager;
     @Mock UserManager mUserManager;
     @Mock NotificationManager mNotificationManager;
@@ -712,6 +717,9 @@
         private int mProbesSucceeded;
         private String mNmValidationRedirectUrl = null;
         private boolean mNmProvNotificationRequested = false;
+        private Runnable mCreatedCallback;
+        private Runnable mUnwantedCallback;
+        private Runnable mDisconnectedCallback;
 
         private final ConditionVariable mNetworkStatusReceived = new ConditionVariable();
         // Contains the redirectUrl from networkStatus(). Before reading, wait for
@@ -766,6 +774,24 @@
                     mRedirectUrl = redirectUrl;
                     mNetworkStatusReceived.open();
                 }
+
+                @Override
+                public void onNetworkCreated() {
+                    super.onNetworkCreated();
+                    if (mCreatedCallback != null) mCreatedCallback.run();
+                }
+
+                @Override
+                public void onNetworkUnwanted() {
+                    super.onNetworkUnwanted();
+                    if (mUnwantedCallback != null) mUnwantedCallback.run();
+                }
+
+                @Override
+                public void onNetworkDestroyed() {
+                    super.onNetworkDestroyed();
+                    if (mDisconnectedCallback != null) mDisconnectedCallback.run();
+                }
             };
 
             assertEquals(na.getNetwork().netId, nmNetworkCaptor.getValue().netId);
@@ -967,6 +993,18 @@
             p.timestampMillis = DATA_STALL_TIMESTAMP;
             mNmCallbacks.notifyDataStallSuspected(p);
         }
+
+        public void setCreatedCallback(Runnable r) {
+            mCreatedCallback = r;
+        }
+
+        public void setUnwantedCallback(Runnable r) {
+            mUnwantedCallback = r;
+        }
+
+        public void setDisconnectedCallback(Runnable r) {
+            mDisconnectedCallback = r;
+        }
     }
 
     /**
@@ -974,8 +1012,6 @@
      * operations have been processed and test for them.
      */
     private static class MockNetworkFactory extends NetworkFactory {
-        private final ConditionVariable mNetworkStartedCV = new ConditionVariable();
-        private final ConditionVariable mNetworkStoppedCV = new ConditionVariable();
         private final AtomicBoolean mNetworkStarted = new AtomicBoolean(false);
 
         static class RequestEntry {
@@ -987,11 +1023,8 @@
             }
 
             static final class Add extends RequestEntry {
-                public final int factorySerialNumber;
-
-                Add(@NonNull final NetworkRequest request, final int factorySerialNumber) {
+                Add(@NonNull final NetworkRequest request) {
                     super(request);
-                    this.factorySerialNumber = factorySerialNumber;
                 }
             }
 
@@ -1000,6 +1033,11 @@
                     super(request);
                 }
             }
+
+            @Override
+            public String toString() {
+                return "RequestEntry [ " + getClass().getName() + " : " + request + " ]";
+            }
         }
 
         // History of received requests adds and removes.
@@ -1011,7 +1049,6 @@
             return obj;
         }
 
-
         public RequestEntry.Add expectRequestAdd() {
             return failIfNull((RequestEntry.Add) mRequestHistory.poll(TIMEOUT_MS,
                     it -> it instanceof RequestEntry.Add), "Expected request add");
@@ -1051,40 +1088,28 @@
 
         protected void startNetwork() {
             mNetworkStarted.set(true);
-            mNetworkStartedCV.open();
         }
 
         protected void stopNetwork() {
             mNetworkStarted.set(false);
-            mNetworkStoppedCV.open();
         }
 
         public boolean getMyStartRequested() {
             return mNetworkStarted.get();
         }
 
-        public ConditionVariable getNetworkStartedCV() {
-            mNetworkStartedCV.close();
-            return mNetworkStartedCV;
-        }
-
-        public ConditionVariable getNetworkStoppedCV() {
-            mNetworkStoppedCV.close();
-            return mNetworkStoppedCV;
-        }
 
         @Override
-        protected void handleAddRequest(NetworkRequest request, int score,
-                int factorySerialNumber) {
+        protected void needNetworkFor(NetworkRequest request) {
             mNetworkRequests.put(request.requestId, request);
-            super.handleAddRequest(request, score, factorySerialNumber);
-            mRequestHistory.add(new RequestEntry.Add(request, factorySerialNumber));
+            super.needNetworkFor(request);
+            mRequestHistory.add(new RequestEntry.Add(request));
         }
 
         @Override
-        protected void handleRemoveRequest(NetworkRequest request) {
+        protected void releaseNetworkFor(NetworkRequest request) {
             mNetworkRequests.remove(request.requestId);
-            super.handleRemoveRequest(request);
+            super.releaseNetworkFor(request);
             mRequestHistory.add(new RequestEntry.Remove(request));
         }
 
@@ -1175,11 +1200,6 @@
         }
 
         @Override
-        public int getNetId() {
-            return (mMockNetworkAgent == null) ? NETID_UNSET : mMockNetworkAgent.getNetwork().netId;
-        }
-
-        @Override
         public int getActiveVpnType() {
             return mVpnType;
         }
@@ -1195,18 +1215,20 @@
             if (mAgentRegistered) throw new IllegalStateException("already registered");
             updateState(NetworkInfo.DetailedState.CONNECTING, "registerAgent");
             mConfig = new VpnConfig();
+            mConfig.session = "MySession12345";
             setUids(uids);
             if (!isAlwaysMetered) mNetworkCapabilities.addCapability(NET_CAPABILITY_NOT_METERED);
             mInterface = VPN_IFNAME;
-            mNetworkCapabilities.setTransportInfo(new VpnTransportInfo(getActiveVpnType()));
+            mNetworkCapabilities.setTransportInfo(new VpnTransportInfo(getActiveVpnType(),
+                    mConfig.session));
             mMockNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_VPN, lp,
                     mNetworkCapabilities);
             mMockNetworkAgent.waitForIdle(TIMEOUT_MS);
 
-            verify(mMockNetd, times(1)).networkAddUidRanges(eq(mMockVpn.getNetId()),
+            verify(mMockNetd, times(1)).networkAddUidRanges(eq(mMockVpn.getNetwork().getNetId()),
                     eq(toUidRangeStableParcels(uids)));
             verify(mMockNetd, never())
-                    .networkRemoveUidRanges(eq(mMockVpn.getNetId()), any());
+                    .networkRemoveUidRanges(eq(mMockVpn.getNetwork().getNetId()), any());
             mAgentRegistered = true;
             updateState(NetworkInfo.DetailedState.CONNECTED, "registerAgent");
             mNetworkCapabilities.set(mMockNetworkAgent.getNetworkCapabilities());
@@ -1375,10 +1397,21 @@
     }
 
     private void mockUidNetworkingBlocked() {
-        doAnswer(i -> NetworkPolicyManager.isUidBlocked(mBlockedReasons, i.getArgument(1))
+        doAnswer(i -> isUidBlocked(mBlockedReasons, i.getArgument(1))
         ).when(mNetworkPolicyManager).isUidNetworkingBlocked(anyInt(), anyBoolean());
     }
 
+    private boolean isUidBlocked(int blockedReasons, boolean meteredNetwork) {
+        final int blockedOnAllNetworksReason = (blockedReasons & ~BLOCKED_METERED_REASON_MASK);
+        if (blockedOnAllNetworksReason != BLOCKED_REASON_NONE) {
+            return true;
+        }
+        if (meteredNetwork) {
+            return blockedReasons != BLOCKED_REASON_NONE;
+        }
+        return false;
+    }
+
     private void setBlockedReasonChanged(int blockedReasons) {
         mBlockedReasons = blockedReasons;
         mPolicyCallback.onUidBlockedReasonChanged(Process.myUid(), blockedReasons);
@@ -1448,6 +1481,23 @@
         });
     }
 
+    private interface ExceptionalRunnable {
+        void run() throws Exception;
+    }
+
+    private void withPermission(String permission, ExceptionalRunnable r) throws Exception {
+        if (mServiceContext.checkCallingOrSelfPermission(permission) == PERMISSION_GRANTED) {
+            r.run();
+            return;
+        }
+        try {
+            mServiceContext.setPermission(permission, PERMISSION_GRANTED);
+            r.run();
+        } finally {
+            mServiceContext.setPermission(permission, PERMISSION_DENIED);
+        }
+    }
+
     private static final int PRIMARY_USER = 0;
     private static final UidRange PRIMARY_UIDRANGE =
             UidRange.createForUser(UserHandle.of(PRIMARY_USER));
@@ -1556,7 +1606,7 @@
         doReturn(mNetworkStack).when(deps).getNetworkStack();
         doReturn(mSystemProperties).when(deps).getSystemProperties();
         doReturn(mock(ProxyTracker.class)).when(deps).makeProxyTracker(any(), any());
-        doReturn(true).when(deps).queryUserAccess(anyInt(), anyInt());
+        doReturn(true).when(deps).queryUserAccess(anyInt(), any(), any());
         doAnswer(inv -> {
             mPolicyTracker = new WrappedMultinetworkPolicyTracker(
                     inv.getArgument(0), inv.getArgument(1), inv.getArgument(2));
@@ -1564,25 +1614,26 @@
         }).when(deps).makeMultinetworkPolicyTracker(any(), any(), any());
         doReturn(true).when(deps).getCellular464XlatEnabled();
 
-        doReturn(60000).when(mResources).getInteger(
-                com.android.connectivity.resources.R.integer.config_networkTransitionTimeout);
-        doReturn("").when(mResources).getString(
-                com.android.connectivity.resources.R.string.config_networkCaptivePortalServerUrl);
+        doReturn(60000).when(mResources).getInteger(R.integer.config_networkTransitionTimeout);
+        doReturn("").when(mResources).getString(R.string.config_networkCaptivePortalServerUrl);
         doReturn(new String[]{ WIFI_WOL_IFNAME }).when(mResources).getStringArray(
-                com.android.connectivity.resources.R.array.config_wakeonlan_supported_interfaces);
+                R.array.config_wakeonlan_supported_interfaces);
         doReturn(new String[] { "0,1", "1,3" }).when(mResources).getStringArray(
-                com.android.connectivity.resources.R.array.config_networkSupportedKeepaliveCount);
-        doReturn(com.android.connectivity.resources.R.array.config_networkSupportedKeepaliveCount)
-                .when(mResources).getIdentifier(eq("config_networkSupportedKeepaliveCount"),
-                eq("array"), any());
-        doReturn(com.android.connectivity.resources.R.array.network_switch_type_name)
-                .when(mResources).getIdentifier(eq("network_switch_type_name"),
-                eq("array"), any());
-
+                R.array.config_networkSupportedKeepaliveCount);
+        doReturn(new String[0]).when(mResources).getStringArray(
+                R.array.config_networkNotifySwitches);
+        doReturn(new int[]{10, 11, 12, 14, 15}).when(mResources).getIntArray(
+                R.array.config_protectedNetworks);
         // We don't test the actual notification value strings, so just return an empty array.
         // It doesn't matter what the values are as long as it's not null.
         doReturn(new String[0]).when(mResources).getStringArray(R.array.network_switch_type_name);
 
+        doReturn(R.array.config_networkSupportedKeepaliveCount).when(mResources)
+                .getIdentifier(eq("config_networkSupportedKeepaliveCount"), eq("array"), any());
+        doReturn(R.array.network_switch_type_name).when(mResources)
+                .getIdentifier(eq("network_switch_type_name"), eq("array"), any());
+
+
         final ConnectivityResources connRes = mock(ConnectivityResources.class);
         doReturn(mResources).when(connRes).get();
         doReturn(connRes).when(deps).getResources(any());
@@ -2784,6 +2835,94 @@
     }
 
     @Test
+    public void testNetworkAgentCallbacks() throws Exception {
+        // Keeps track of the order of events that happen in this test.
+        final LinkedBlockingQueue<String> eventOrder = new LinkedBlockingQueue<>();
+
+        final NetworkRequest request = new NetworkRequest.Builder()
+                .addTransportType(TRANSPORT_WIFI).build();
+        final TestNetworkCallback callback = new TestNetworkCallback();
+        final AtomicReference<Network> wifiNetwork = new AtomicReference<>();
+        mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
+
+        // Expectations for state when various callbacks fire. These expectations run on the handler
+        // thread and not on the test thread because they need to prevent the handler thread from
+        // advancing while they examine state.
+
+        // 1. When onCreated fires, netd has been told to create the network.
+        mWiFiNetworkAgent.setCreatedCallback(() -> {
+            eventOrder.offer("onNetworkCreated");
+            wifiNetwork.set(mWiFiNetworkAgent.getNetwork());
+            assertNotNull(wifiNetwork.get());
+            try {
+                verify(mMockNetd).networkCreatePhysical(wifiNetwork.get().getNetId(),
+                        INetd.PERMISSION_NONE);
+            } catch (RemoteException impossible) {
+                fail();
+            }
+        });
+
+        // 2. onNetworkUnwanted isn't precisely ordered with respect to any particular events. Just
+        //    check that it is fired at some point after disconnect.
+        mWiFiNetworkAgent.setUnwantedCallback(() -> eventOrder.offer("onNetworkUnwanted"));
+
+        // 3. While the teardown timer is running, connectivity APIs report the network is gone, but
+        //    netd has not yet been told to destroy it.
+        final Runnable duringTeardown = () -> {
+            eventOrder.offer("timePasses");
+            assertNull(mCm.getLinkProperties(wifiNetwork.get()));
+            try {
+                verify(mMockNetd, never()).networkDestroy(wifiNetwork.get().getNetId());
+            } catch (RemoteException impossible) {
+                fail();
+            }
+        };
+
+        // 4. After onNetworkDisconnected is called, connectivity APIs report the network is gone,
+        // and netd has been told to destroy it.
+        mWiFiNetworkAgent.setDisconnectedCallback(() -> {
+            eventOrder.offer("onNetworkDisconnected");
+            assertNull(mCm.getLinkProperties(wifiNetwork.get()));
+            try {
+                verify(mMockNetd).networkDestroy(wifiNetwork.get().getNetId());
+            } catch (RemoteException impossible) {
+                fail();
+            }
+        });
+
+        // Connect a network, and file a request for it after it has come up, to ensure the nascent
+        // timer is cleared and the test does not have to wait for it. Filing the request after the
+        // network has come up is necessary because ConnectivityService does not appear to clear the
+        // nascent timer if the first request satisfied by the network was filed before the network
+        // connected.
+        // TODO: fix this bug, file the request before connecting, and remove the waitForIdle.
+        mWiFiNetworkAgent.connectWithoutInternet();
+        waitForIdle();
+        mCm.requestNetwork(request, callback);
+        callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
+
+        // Set teardown delay and make sure CS has processed it.
+        mWiFiNetworkAgent.getNetworkAgent().setTeardownDelayMs(300);
+        waitForIdle();
+
+        // Post the duringTeardown lambda to the handler so it fires while teardown is in progress.
+        // The delay must be long enough it will run after the unregisterNetworkCallback has torn
+        // down the network and started the teardown timer, and short enough that the lambda is
+        // scheduled to run before the teardown timer.
+        final Handler h = new Handler(mCsHandlerThread.getLooper());
+        h.postDelayed(duringTeardown, 150);
+
+        // Disconnect the network and check that events happened in the right order.
+        mCm.unregisterNetworkCallback(callback);
+        assertEquals("onNetworkCreated", eventOrder.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+        assertEquals("onNetworkUnwanted", eventOrder.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+        assertEquals("timePasses", eventOrder.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+        assertEquals("onNetworkDisconnected", eventOrder.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+
+        mCm.unregisterNetworkCallback(callback);
+    }
+
+    @Test
     public void testExplicitlySelected() throws Exception {
         NetworkRequest request = new NetworkRequest.Builder()
                 .clearCapabilities().addCapability(NET_CAPABILITY_INTERNET)
@@ -2903,25 +3042,23 @@
         handlerThread.start();
         final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(),
                 mServiceContext, "testFactory", filter, mCsHandlerThread);
-        testFactory.setScoreFilter(40);
-        ConditionVariable cv = testFactory.getNetworkStartedCV();
+        testFactory.setScoreFilter(45);
         testFactory.register();
-        testFactory.expectRequestAdd();
-        testFactory.assertRequestCountEquals(1);
-        int expectedRequestCount = 1;
-        NetworkCallback networkCallback = null;
-        // For non-INTERNET capabilities we cannot rely on the default request being present, so
-        // add one.
+
+        final NetworkCallback networkCallback;
         if (capability != NET_CAPABILITY_INTERNET) {
+            // If the capability passed in argument is part of the default request, then the
+            // factory will see the default request. Otherwise the filter will prevent the
+            // factory from seeing it. In that case, add a request so it can be tested.
             assertFalse(testFactory.getMyStartRequested());
             NetworkRequest request = new NetworkRequest.Builder().addCapability(capability).build();
             networkCallback = new NetworkCallback();
             mCm.requestNetwork(request, networkCallback);
-            expectedRequestCount++;
-            testFactory.expectRequestAdd();
+        } else {
+            networkCallback = null;
         }
-        waitFor(cv);
-        testFactory.assertRequestCountEquals(expectedRequestCount);
+        testFactory.expectRequestAdd();
+        testFactory.assertRequestCountEquals(1);
         assertTrue(testFactory.getMyStartRequested());
 
         // Now bring in a higher scored network.
@@ -2930,20 +3067,45 @@
         // own NetworkRequest during startup, just bump up the score to cancel out the
         // unvalidated penalty.
         testAgent.adjustScore(40);
-        cv = testFactory.getNetworkStoppedCV();
 
-        // When testAgent connects, ConnectivityService will re-send us all current requests with
-        // the new score. There are expectedRequestCount such requests, and we must wait for all of
-        // them.
+        // When testAgent connects, because of its 50 score (50 for cell + 40 adjustment score
+        // - 40 penalty for not being validated), it will beat the testFactory's offer, so
+        // the request will be removed.
         testAgent.connect(false);
         testAgent.addCapability(capability);
-        waitFor(cv);
-        testFactory.expectRequestAdds(expectedRequestCount);
-        testFactory.assertRequestCountEquals(expectedRequestCount);
+        testFactory.expectRequestRemove();
+        testFactory.assertRequestCountEquals(0);
         assertFalse(testFactory.getMyStartRequested());
 
+        // Add a request and make sure it's not sent to the factory, because the agent
+        // is satisfying it better.
+        final NetworkCallback cb = new ConnectivityManager.NetworkCallback();
+        mCm.requestNetwork(new NetworkRequest.Builder().addCapability(capability).build(), cb);
+        expectNoRequestChanged(testFactory);
+        testFactory.assertRequestCountEquals(0);
+        assertFalse(testFactory.getMyStartRequested());
+
+        // Make the test agent weak enough to have the exact same score as the
+        // factory (50 for cell + 40 adjustment -40 validation penalty - 5 adjustment). Make sure
+        // the factory doesn't see the request.
+        testAgent.adjustScore(-5);
+        expectNoRequestChanged(testFactory);
+        assertFalse(testFactory.getMyStartRequested());
+
+        // Make the test agent weak enough to see the two requests (the one that was just sent,
+        // and either the default one or the one sent at the top of this test if the default
+        // won't be seen).
+        testAgent.adjustScore(-45);
+        testFactory.expectRequestAdds(2);
+        testFactory.assertRequestCountEquals(2);
+        assertTrue(testFactory.getMyStartRequested());
+
+        // Now unregister and make sure the request is removed.
+        mCm.unregisterNetworkCallback(cb);
+        testFactory.expectRequestRemove();
+
         // Bring in a bunch of requests.
-        assertEquals(expectedRequestCount, testFactory.getMyRequestCount());
+        assertEquals(1, testFactory.getMyRequestCount());
         ConnectivityManager.NetworkCallback[] networkCallbacks =
                 new ConnectivityManager.NetworkCallback[10];
         for (int i = 0; i< networkCallbacks.length; i++) {
@@ -2953,24 +3115,28 @@
             mCm.requestNetwork(builder.build(), networkCallbacks[i]);
         }
         testFactory.expectRequestAdds(10);
-        testFactory.assertRequestCountEquals(10 + expectedRequestCount);
-        assertFalse(testFactory.getMyStartRequested());
+        testFactory.assertRequestCountEquals(11); // +1 for the default/test specific request
+        assertTrue(testFactory.getMyStartRequested());
 
         // Remove the requests.
         for (int i = 0; i < networkCallbacks.length; i++) {
             mCm.unregisterNetworkCallback(networkCallbacks[i]);
         }
         testFactory.expectRequestRemoves(10);
-        testFactory.assertRequestCountEquals(expectedRequestCount);
+        testFactory.assertRequestCountEquals(1);
+        assertTrue(testFactory.getMyStartRequested());
+
+        // Adjust the agent score up again. Expect the request to be withdrawn.
+        testAgent.adjustScore(50);
+        testFactory.expectRequestRemove();
+        testFactory.assertRequestCountEquals(0);
         assertFalse(testFactory.getMyStartRequested());
 
         // Drop the higher scored network.
-        cv = testFactory.getNetworkStartedCV();
         testAgent.disconnect();
-        waitFor(cv);
-        testFactory.expectRequestAdds(expectedRequestCount);
-        testFactory.assertRequestCountEquals(expectedRequestCount);
-        assertEquals(expectedRequestCount, testFactory.getMyRequestCount());
+        testFactory.expectRequestAdd();
+        testFactory.assertRequestCountEquals(1);
+        assertEquals(1, testFactory.getMyRequestCount());
         assertTrue(testFactory.getMyStartRequested());
 
         testFactory.terminate();
@@ -3000,9 +3166,34 @@
     }
 
     @Test
-    public void testNetworkFactoryUnregister() throws Exception {
+    public void testRegisterIgnoringScore() throws Exception {
+        mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
+        mWiFiNetworkAgent.adjustScore(30); // score = 60 (wifi) + 30 = 90
+        mWiFiNetworkAgent.connect(true /* validated */);
+
+        // Make sure the factory sees the default network
         final NetworkCapabilities filter = new NetworkCapabilities();
-        filter.clearAll();
+        filter.addCapability(NET_CAPABILITY_INTERNET);
+        filter.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED);
+        final HandlerThread handlerThread = new HandlerThread("testNetworkFactoryRequests");
+        handlerThread.start();
+        final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(),
+                mServiceContext, "testFactory", filter, mCsHandlerThread);
+        testFactory.registerIgnoringScore();
+        testFactory.expectRequestAdd();
+
+        mWiFiNetworkAgent.adjustScore(20); // exceed the maximum score
+        expectNoRequestChanged(testFactory); // still seeing the request
+
+        mWiFiNetworkAgent.disconnect();
+    }
+
+    @Test
+    public void testNetworkFactoryUnregister() throws Exception {
+        // Make sure the factory sees the default network
+        final NetworkCapabilities filter = new NetworkCapabilities();
+        filter.addCapability(NET_CAPABILITY_INTERNET);
+        filter.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED);
 
         final HandlerThread handlerThread = new HandlerThread("testNetworkFactoryRequests");
         handlerThread.start();
@@ -3810,8 +4001,9 @@
             NetworkCapabilities networkCapabilities = new NetworkCapabilities();
             networkCapabilities.addTransportType(TRANSPORT_WIFI)
                     .setNetworkSpecifier(new MatchAllNetworkSpecifier());
-            mService.requestNetwork(networkCapabilities, NetworkRequest.Type.REQUEST.ordinal(),
-                    null, 0, null, ConnectivityManager.TYPE_WIFI, NetworkCallback.FLAG_NONE,
+            mService.requestNetwork(Process.INVALID_UID, networkCapabilities,
+                    NetworkRequest.Type.REQUEST.ordinal(), null, 0, null,
+                    ConnectivityManager.TYPE_WIFI, NetworkCallback.FLAG_NONE,
                     mContext.getPackageName(), getAttributionTag());
         });
 
@@ -4040,7 +4232,7 @@
     }
 
     @Test
-    public void testRegisterSystemDefaultCallbackRequiresNetworkSettings() throws Exception {
+    public void testRegisterPrivilegedDefaultCallbacksRequireNetworkSettings() throws Exception {
         mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
         mCellNetworkAgent.connect(false /* validated */);
 
@@ -4049,12 +4241,19 @@
         assertThrows(SecurityException.class,
                 () -> mCm.registerSystemDefaultNetworkCallback(callback, handler));
         callback.assertNoCallback();
+        assertThrows(SecurityException.class,
+                () -> mCm.registerDefaultNetworkCallbackAsUid(APP1_UID, callback, handler));
+        callback.assertNoCallback();
 
         mServiceContext.setPermission(Manifest.permission.NETWORK_SETTINGS,
                 PERMISSION_GRANTED);
         mCm.registerSystemDefaultNetworkCallback(callback, handler);
         callback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent);
         mCm.unregisterNetworkCallback(callback);
+
+        mCm.registerDefaultNetworkCallbackAsUid(APP1_UID, callback, handler);
+        callback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent);
+        mCm.unregisterNetworkCallback(callback);
     }
 
     private void setCaptivePortalMode(int mode) {
@@ -4258,6 +4457,7 @@
         testFactory.register();
 
         try {
+            // Expect the factory to receive the default network request.
             testFactory.expectRequestAdd();
             testFactory.assertRequestCountEquals(1);
             assertTrue(testFactory.getMyStartRequested());
@@ -4266,25 +4466,44 @@
             mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
             // Score 60 - 40 penalty for not validated yet, then 60 when it validates
             mWiFiNetworkAgent.connect(true);
-            // Default request and mobile always on request
-            testFactory.expectRequestAdds(2);
+            // The network connects with a low score, so the offer can still beat it and
+            // nothing happens. Then the network validates, and the offer with its filter score
+            // of 40 can no longer beat it and the request is removed.
+            testFactory.expectRequestRemove();
+            testFactory.assertRequestCountEquals(0);
+
             assertFalse(testFactory.getMyStartRequested());
 
-            // Turn on mobile data always on. The factory starts looking again.
+            // Turn on mobile data always on. This request will not match the wifi request, so
+            // it will be sent to the test factory whose filters allow to see it.
             setAlwaysOnNetworks(true);
             testFactory.expectRequestAdd();
-            testFactory.assertRequestCountEquals(2);
+            testFactory.assertRequestCountEquals(1);
 
             assertTrue(testFactory.getMyStartRequested());
 
             // Bring up cell data and check that the factory stops looking.
             assertLength(1, mCm.getAllNetworks());
             mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
-            mCellNetworkAgent.connect(true);
-            cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
-            testFactory.expectRequestAdds(2); // Unvalidated and validated
-            testFactory.assertRequestCountEquals(2);
-            // The cell network outscores the factory filter, so start is not requested.
+            mCellNetworkAgent.connect(false);
+            cellNetworkCallback.expectAvailableCallbacks(mCellNetworkAgent, false, false, false,
+                    TEST_CALLBACK_TIMEOUT_MS);
+            // When cell connects, it will satisfy the "mobile always on request" right away
+            // by virtue of being the only network that can satisfy the request. However, its
+            // score is low (50 - 40 = 10) so the test factory can still hope to beat it.
+            expectNoRequestChanged(testFactory);
+
+            // Next, cell validates. This gives it a score of 50 and the test factory can't
+            // hope to beat that according to its filters. It will see the message that its
+            // offer is now unnecessary.
+            mCellNetworkAgent.setNetworkValid(true);
+            // Need a trigger point to let NetworkMonitor tell ConnectivityService that network is
+            // validated – see testPartialConnectivity.
+            mCm.reportNetworkConnectivity(mCellNetworkAgent.getNetwork(), true);
+            cellNetworkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mCellNetworkAgent);
+            testFactory.expectRequestRemove();
+            testFactory.assertRequestCountEquals(0);
+            // Accordingly, the factory shouldn't be started.
             assertFalse(testFactory.getMyStartRequested());
 
             // Check that cell data stays up.
@@ -4292,10 +4511,27 @@
             verifyActiveNetwork(TRANSPORT_WIFI);
             assertLength(2, mCm.getAllNetworks());
 
-            // Turn off mobile data always on and expect the request to disappear...
-            setAlwaysOnNetworks(false);
-            testFactory.expectRequestRemove();
+            // Cell disconnects. There is still the "mobile data always on" request outstanding,
+            // and the test factory should see it now that it isn't hopelessly outscored.
+            mCellNetworkAgent.disconnect();
+            cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
+            assertLength(1, mCm.getAllNetworks());
+            testFactory.expectRequestAdd();
+            testFactory.assertRequestCountEquals(1);
 
+            // Reconnect cell validated, see the request disappear again. Then withdraw the
+            // mobile always on request. This will tear down cell, and there shouldn't be a
+            // blip where the test factory briefly sees the request or anything.
+            mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
+            mCellNetworkAgent.connect(true);
+            cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
+            assertLength(2, mCm.getAllNetworks());
+            testFactory.expectRequestRemove();
+            testFactory.assertRequestCountEquals(0);
+            setAlwaysOnNetworks(false);
+            expectNoRequestChanged(testFactory);
+            testFactory.assertRequestCountEquals(0);
+            assertFalse(testFactory.getMyStartRequested());
             // ...  and cell data to be torn down after nascent network timeout.
             cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent,
                     mService.mNascentDelayMs + TEST_CALLBACK_TIMEOUT_MS);
@@ -4598,7 +4834,8 @@
         handlerThread.start();
         NetworkCapabilities filter = new NetworkCapabilities()
                 .addTransportType(TRANSPORT_WIFI)
-                .addCapability(NET_CAPABILITY_INTERNET);
+                .addCapability(NET_CAPABILITY_INTERNET)
+                .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED);
         final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(),
                 mServiceContext, "testFactory", filter, mCsHandlerThread);
         testFactory.setScoreFilter(40);
@@ -4607,32 +4844,43 @@
         testFactory.register();
         testFactory.expectRequestAdd();
 
-        // Now file the test request and expect it.
-        mCm.requestNetwork(nr, networkCallback);
-        final NetworkRequest newRequest = testFactory.expectRequestAdd().request;
+        try {
+            // Now file the test request and expect it.
+            mCm.requestNetwork(nr, networkCallback);
+            final NetworkRequest newRequest = testFactory.expectRequestAdd().request;
 
-        if (preUnregister) {
-            mCm.unregisterNetworkCallback(networkCallback);
+            if (preUnregister) {
+                mCm.unregisterNetworkCallback(networkCallback);
 
-            // Simulate the factory releasing the request as unfulfillable: no-op since
-            // the callback has already been unregistered (but a test that no exceptions are
-            // thrown).
-            testFactory.triggerUnfulfillable(newRequest);
-        } else {
-            // Simulate the factory releasing the request as unfulfillable and expect onUnavailable!
-            testFactory.triggerUnfulfillable(newRequest);
+                // The request has been released : the factory should see it removed
+                // immediately.
+                testFactory.expectRequestRemove();
 
-            networkCallback.expectCallback(CallbackEntry.UNAVAILABLE, (Network) null);
+                // Simulate the factory releasing the request as unfulfillable: no-op since
+                // the callback has already been unregistered (but a test that no exceptions are
+                // thrown).
+                testFactory.triggerUnfulfillable(newRequest);
+            } else {
+                // Simulate the factory releasing the request as unfulfillable and expect
+                // onUnavailable!
+                testFactory.triggerUnfulfillable(newRequest);
 
-            // unregister network callback - a no-op (since already freed by the
-            // on-unavailable), but should not fail or throw exceptions.
-            mCm.unregisterNetworkCallback(networkCallback);
+                networkCallback.expectCallback(CallbackEntry.UNAVAILABLE, (Network) null);
+
+                // Declaring a request unfulfillable releases it automatically.
+                testFactory.expectRequestRemove();
+
+                // unregister network callback - a no-op (since already freed by the
+                // on-unavailable), but should not fail or throw exceptions.
+                mCm.unregisterNetworkCallback(networkCallback);
+
+                // The factory should not see any further removal, as this request has
+                // already been removed.
+            }
+        } finally {
+            testFactory.terminate();
+            handlerThread.quit();
         }
-
-        testFactory.expectRequestRemove();
-
-        testFactory.terminate();
-        handlerThread.quit();
     }
 
     private static class TestKeepaliveCallback extends PacketKeepaliveCallback {
@@ -7254,6 +7502,20 @@
         mMockVpn.disconnect();
     }
 
+    private class DetailedBlockedStatusCallback extends TestNetworkCallback {
+        public void expectAvailableThenValidatedCallbacks(HasNetwork n, int blockedStatus) {
+            super.expectAvailableThenValidatedCallbacks(n.getNetwork(), blockedStatus, TIMEOUT_MS);
+        }
+        public void expectBlockedStatusCallback(HasNetwork n, int blockedStatus) {
+            // This doesn't work:
+            // super.expectBlockedStatusCallback(blockedStatus, n.getNetwork());
+            super.expectBlockedStatusCallback(blockedStatus, n.getNetwork(), TIMEOUT_MS);
+        }
+        public void onBlockedStatusChanged(Network network, int blockedReasons) {
+            getHistory().add(new CallbackEntry.BlockedStatusInt(network, blockedReasons));
+        }
+    }
+
     @Test
     public void testNetworkBlockedStatus() throws Exception {
         final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback();
@@ -7261,11 +7523,16 @@
                 .addTransportType(TRANSPORT_CELLULAR)
                 .build();
         mCm.registerNetworkCallback(cellRequest, cellNetworkCallback);
+        final DetailedBlockedStatusCallback detailedCallback = new DetailedBlockedStatusCallback();
+        mCm.registerNetworkCallback(cellRequest, detailedCallback);
+
         mockUidNetworkingBlocked();
 
         mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
         mCellNetworkAgent.connect(true);
         cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
+        detailedCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent,
+                BLOCKED_REASON_NONE);
         assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
         assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
         assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
@@ -7273,17 +7540,23 @@
 
         setBlockedReasonChanged(BLOCKED_REASON_BATTERY_SAVER);
         cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent);
+        detailedCallback.expectBlockedStatusCallback(mCellNetworkAgent,
+                BLOCKED_REASON_BATTERY_SAVER);
         assertNull(mCm.getActiveNetwork());
         assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
         assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
         assertExtraInfoFromCmBlocked(mCellNetworkAgent);
 
-        // ConnectivityService should cache it not to invoke the callback again.
+        // If blocked state does not change but blocked reason does, the boolean callback is called.
+        // TODO: investigate de-duplicating.
         setBlockedReasonChanged(BLOCKED_METERED_REASON_USER_RESTRICTED);
-        cellNetworkCallback.assertNoCallback();
+        cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent);
+        detailedCallback.expectBlockedStatusCallback(mCellNetworkAgent,
+                BLOCKED_METERED_REASON_USER_RESTRICTED);
 
         setBlockedReasonChanged(BLOCKED_REASON_NONE);
         cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent);
+        detailedCallback.expectBlockedStatusCallback(mCellNetworkAgent, BLOCKED_REASON_NONE);
         assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
         assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
         assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
@@ -7291,6 +7564,8 @@
 
         setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER);
         cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent);
+        detailedCallback.expectBlockedStatusCallback(mCellNetworkAgent,
+                BLOCKED_METERED_REASON_DATA_SAVER);
         assertNull(mCm.getActiveNetwork());
         assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
         assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
@@ -7300,6 +7575,8 @@
         mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED);
         cellNetworkCallback.expectCapabilitiesWith(NET_CAPABILITY_NOT_METERED, mCellNetworkAgent);
         cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent);
+        detailedCallback.expectCapabilitiesWith(NET_CAPABILITY_NOT_METERED, mCellNetworkAgent);
+        detailedCallback.expectBlockedStatusCallback(mCellNetworkAgent, BLOCKED_REASON_NONE);
         assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
         assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
         assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
@@ -7309,6 +7586,10 @@
         cellNetworkCallback.expectCapabilitiesWithout(NET_CAPABILITY_NOT_METERED,
                 mCellNetworkAgent);
         cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent);
+        detailedCallback.expectCapabilitiesWithout(NET_CAPABILITY_NOT_METERED,
+                mCellNetworkAgent);
+        detailedCallback.expectBlockedStatusCallback(mCellNetworkAgent,
+                BLOCKED_METERED_REASON_DATA_SAVER);
         assertNull(mCm.getActiveNetwork());
         assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
         assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
@@ -7316,6 +7597,7 @@
 
         setBlockedReasonChanged(BLOCKED_REASON_NONE);
         cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent);
+        detailedCallback.expectBlockedStatusCallback(mCellNetworkAgent, BLOCKED_REASON_NONE);
         assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
         assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
         assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
@@ -7323,10 +7605,13 @@
 
         setBlockedReasonChanged(BLOCKED_REASON_NONE);
         cellNetworkCallback.assertNoCallback();
+        detailedCallback.assertNoCallback();
 
         // Restrict background data. Networking is not blocked because the network is unmetered.
         setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER);
         cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent);
+        detailedCallback.expectBlockedStatusCallback(mCellNetworkAgent,
+                BLOCKED_METERED_REASON_DATA_SAVER);
         assertNull(mCm.getActiveNetwork());
         assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
         assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
@@ -7336,12 +7621,14 @@
 
         setBlockedReasonChanged(BLOCKED_REASON_NONE);
         cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent);
+        detailedCallback.expectBlockedStatusCallback(mCellNetworkAgent, BLOCKED_REASON_NONE);
         assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
         assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
         assertExtraInfoFromCmPresent(mCellNetworkAgent);
 
         setBlockedReasonChanged(BLOCKED_REASON_NONE);
         cellNetworkCallback.assertNoCallback();
+        detailedCallback.assertNoCallback();
         assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
         assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
         assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
@@ -7484,6 +7771,13 @@
         final NetworkRequest vpnUidRequest = new NetworkRequest.Builder().build();
         registerNetworkCallbackAsUid(vpnUidRequest, vpnUidCallback, VPN_UID);
 
+        final TestNetworkCallback vpnUidDefaultCallback = new TestNetworkCallback();
+        registerDefaultNetworkCallbackAsUid(vpnUidDefaultCallback, VPN_UID);
+
+        final TestNetworkCallback vpnDefaultCallbackAsUid = new TestNetworkCallback();
+        mCm.registerDefaultNetworkCallbackAsUid(VPN_UID, vpnDefaultCallbackAsUid,
+                new Handler(ConnectivityThread.getInstanceLooper()));
+
         final int uid = Process.myUid();
         final int userId = UserHandle.getUserId(uid);
         final ArrayList<String> allowList = new ArrayList<>();
@@ -7502,6 +7796,8 @@
         callback.expectAvailableCallbacksUnvalidatedAndBlocked(mWiFiNetworkAgent);
         defaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mWiFiNetworkAgent);
         vpnUidCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
+        vpnUidDefaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
+        vpnDefaultCallbackAsUid.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
         assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID));
         assertNull(mCm.getActiveNetwork());
         assertActiveNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED);
@@ -7514,6 +7810,8 @@
         callback.expectBlockedStatusCallback(false, mWiFiNetworkAgent);
         defaultCallback.expectBlockedStatusCallback(false, mWiFiNetworkAgent);
         vpnUidCallback.assertNoCallback();
+        vpnUidDefaultCallback.assertNoCallback();
+        vpnDefaultCallbackAsUid.assertNoCallback();
         expectNetworkRejectNonSecureVpn(inOrder, false, firstHalf, secondHalf);
         assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID));
         assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
@@ -7528,6 +7826,8 @@
         callback.assertNoCallback();
         defaultCallback.assertNoCallback();
         vpnUidCallback.assertNoCallback();
+        vpnUidDefaultCallback.assertNoCallback();
+        vpnDefaultCallbackAsUid.assertNoCallback();
 
         // The following requires that the UID of this test package is greater than VPN_UID. This
         // is always true in practice because a plain AOSP build with no apps installed has almost
@@ -7548,6 +7848,8 @@
         callback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent);
         defaultCallback.assertNoCallback();
         vpnUidCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent);
+        vpnUidDefaultCallback.assertNoCallback();
+        vpnDefaultCallbackAsUid.assertNoCallback();
         assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID));
         assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
         assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED);
@@ -7568,6 +7870,8 @@
         defaultCallback.expectBlockedStatusCallback(true, mWiFiNetworkAgent);
         assertBlockedCallbackInAnyOrder(callback, true, mWiFiNetworkAgent, mCellNetworkAgent);
         vpnUidCallback.assertNoCallback();
+        vpnUidDefaultCallback.assertNoCallback();
+        vpnDefaultCallbackAsUid.assertNoCallback();
         assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID));
         assertNull(mCm.getActiveNetwork());
         assertActiveNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED);
@@ -7579,6 +7883,8 @@
         defaultCallback.expectBlockedStatusCallback(false, mWiFiNetworkAgent);
         assertBlockedCallbackInAnyOrder(callback, false, mWiFiNetworkAgent, mCellNetworkAgent);
         vpnUidCallback.assertNoCallback();
+        vpnUidDefaultCallback.assertNoCallback();
+        vpnDefaultCallbackAsUid.assertNoCallback();
         assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID));
         assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
         assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED);
@@ -7593,6 +7899,8 @@
         callback.assertNoCallback();
         defaultCallback.assertNoCallback();
         vpnUidCallback.assertNoCallback();
+        vpnUidDefaultCallback.assertNoCallback();
+        vpnDefaultCallbackAsUid.assertNoCallback();
         assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID));
         assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
         assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED);
@@ -7604,6 +7912,8 @@
         callback.assertNoCallback();
         defaultCallback.assertNoCallback();
         vpnUidCallback.assertNoCallback();
+        vpnUidDefaultCallback.assertNoCallback();
+        vpnDefaultCallbackAsUid.assertNoCallback();
         assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID));
         assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
         assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED);
@@ -7616,6 +7926,8 @@
         defaultCallback.expectBlockedStatusCallback(true, mWiFiNetworkAgent);
         assertBlockedCallbackInAnyOrder(callback, true, mWiFiNetworkAgent, mCellNetworkAgent);
         vpnUidCallback.assertNoCallback();
+        vpnUidDefaultCallback.assertNoCallback();
+        vpnDefaultCallbackAsUid.assertNoCallback();
         assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID));
         assertNull(mCm.getActiveNetwork());
         assertActiveNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED);
@@ -7626,6 +7938,8 @@
         assertUidRangesUpdatedForMyUid(true);
         defaultCallback.expectAvailableThenValidatedCallbacks(mMockVpn);
         vpnUidCallback.assertNoCallback();  // vpnUidCallback has NOT_VPN capability.
+        vpnUidDefaultCallback.assertNoCallback();  // VPN does not apply to VPN_UID
+        vpnDefaultCallbackAsUid.assertNoCallback();
         assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetwork());
         assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID));
         assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED);
@@ -7636,11 +7950,16 @@
         mMockVpn.disconnect();
         defaultCallback.expectCallback(CallbackEntry.LOST, mMockVpn);
         defaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mWiFiNetworkAgent);
+        vpnUidCallback.assertNoCallback();
+        vpnUidDefaultCallback.assertNoCallback();
+        vpnDefaultCallbackAsUid.assertNoCallback();
         assertNull(mCm.getActiveNetwork());
 
         mCm.unregisterNetworkCallback(callback);
         mCm.unregisterNetworkCallback(defaultCallback);
         mCm.unregisterNetworkCallback(vpnUidCallback);
+        mCm.unregisterNetworkCallback(vpnUidDefaultCallback);
+        mCm.unregisterNetworkCallback(vpnDefaultCallbackAsUid);
     }
 
     private void setupLegacyLockdownVpn() {
@@ -8840,29 +9159,34 @@
         final NetworkCapabilities netCap = new NetworkCapabilities().setOwnerUid(ownerUid);
 
         return mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled(
-                netCap, includeLocationSensitiveInfo, callerUid,
+                netCap, includeLocationSensitiveInfo, Process.myUid(), callerUid,
                 mContext.getPackageName(), getAttributionTag())
                 .getOwnerUid();
     }
 
-    private void verifyWifiInfoCopyNetCapsPermission(
+    private void verifyTransportInfoCopyNetCapsPermission(
             int callerUid, boolean includeLocationSensitiveInfo,
             boolean shouldMakeCopyWithLocationSensitiveFieldsParcelable) {
-        final WifiInfo wifiInfo = mock(WifiInfo.class);
-        when(wifiInfo.hasLocationSensitiveFields()).thenReturn(true);
-        final NetworkCapabilities netCap = new NetworkCapabilities().setTransportInfo(wifiInfo);
+        final TransportInfo transportInfo = mock(TransportInfo.class);
+        when(transportInfo.getApplicableRedactions()).thenReturn(REDACT_FOR_ACCESS_FINE_LOCATION);
+        final NetworkCapabilities netCap =
+                new NetworkCapabilities().setTransportInfo(transportInfo);
 
         mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled(
-                netCap, includeLocationSensitiveInfo, callerUid,
+                netCap, includeLocationSensitiveInfo, Process.myPid(), callerUid,
                 mContext.getPackageName(), getAttributionTag());
-        verify(wifiInfo).makeCopy(eq(shouldMakeCopyWithLocationSensitiveFieldsParcelable));
+        if (shouldMakeCopyWithLocationSensitiveFieldsParcelable) {
+            verify(transportInfo).makeCopy(REDACT_NONE);
+        } else {
+            verify(transportInfo).makeCopy(REDACT_FOR_ACCESS_FINE_LOCATION);
+        }
     }
 
-    private void verifyOwnerUidAndWifiInfoNetCapsPermission(
+    private void verifyOwnerUidAndTransportInfoNetCapsPermission(
             boolean shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag,
             boolean shouldInclLocationSensitiveOwnerUidWithIncludeFlag,
-            boolean shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag,
-            boolean shouldInclLocationSensitiveWifiInfoWithIncludeFlag) {
+            boolean shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag,
+            boolean shouldInclLocationSensitiveTransportInfoWithIncludeFlag) {
         final int myUid = Process.myUid();
 
         final int expectedOwnerUidWithoutIncludeFlag =
@@ -8876,13 +9200,13 @@
         assertEquals(expectedOwnerUidWithIncludeFlag, getOwnerUidNetCapsPermission(
                 myUid, myUid, true /* includeLocationSensitiveInfo */));
 
-        verifyWifiInfoCopyNetCapsPermission(myUid,
+        verifyTransportInfoCopyNetCapsPermission(myUid,
                 false, /* includeLocationSensitiveInfo */
-                shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag);
+                shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag);
 
-        verifyWifiInfoCopyNetCapsPermission(myUid,
+        verifyTransportInfoCopyNetCapsPermission(myUid,
                 true, /* includeLocationSensitiveInfo */
-                shouldInclLocationSensitiveWifiInfoWithIncludeFlag);
+                shouldInclLocationSensitiveTransportInfoWithIncludeFlag);
 
     }
 
@@ -8892,15 +9216,15 @@
         setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION,
                 Manifest.permission.ACCESS_FINE_LOCATION);
 
-        verifyOwnerUidAndWifiInfoNetCapsPermission(
+        verifyOwnerUidAndTransportInfoNetCapsPermission(
                 // Ensure that we include owner uid even if the request asks to remove it since the
                 // app has necessary permissions and targetSdk < S.
                 true, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */
                 true, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */
-                false, /* shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag */
+                false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */
                 // Ensure that we remove location info if the request asks to remove it even if the
                 // app has necessary permissions.
-                true /* shouldInclLocationSensitiveWifiInfoWithIncludeFlag */
+                true /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */
         );
     }
 
@@ -8910,15 +9234,15 @@
         setupLocationPermissions(Build.VERSION_CODES.R, true, AppOpsManager.OPSTR_FINE_LOCATION,
                 Manifest.permission.ACCESS_FINE_LOCATION);
 
-        verifyOwnerUidAndWifiInfoNetCapsPermission(
+        verifyOwnerUidAndTransportInfoNetCapsPermission(
                 // Ensure that we include owner uid even if the request asks to remove it since the
                 // app has necessary permissions and targetSdk < S.
                 true, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */
                 true, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */
-                false, /* shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag */
+                false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */
                 // Ensure that we remove location info if the request asks to remove it even if the
                 // app has necessary permissions.
-                true /* shouldInclLocationSensitiveWifiInfoWithIncludeFlag */
+                true /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */
         );
     }
 
@@ -8929,15 +9253,15 @@
         setupLocationPermissions(Build.VERSION_CODES.S, true, AppOpsManager.OPSTR_FINE_LOCATION,
                 Manifest.permission.ACCESS_FINE_LOCATION);
 
-        verifyOwnerUidAndWifiInfoNetCapsPermission(
+        verifyOwnerUidAndTransportInfoNetCapsPermission(
                 // Ensure that we owner UID if the request asks us to remove it even if the app
                 // has necessary permissions since targetSdk >= S.
                 false, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */
                 true, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */
-                false, /* shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag */
+                false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */
                 // Ensure that we remove location info if the request asks to remove it even if the
                 // app has necessary permissions.
-                true /* shouldInclLocationSensitiveWifiInfoWithIncludeFlag */
+                true /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */
         );
     }
 
@@ -8947,15 +9271,15 @@
         setupLocationPermissions(Build.VERSION_CODES.P, true, AppOpsManager.OPSTR_COARSE_LOCATION,
                 Manifest.permission.ACCESS_COARSE_LOCATION);
 
-        verifyOwnerUidAndWifiInfoNetCapsPermission(
+        verifyOwnerUidAndTransportInfoNetCapsPermission(
                 // Ensure that we owner UID if the request asks us to remove it even if the app
                 // has necessary permissions since targetSdk >= S.
                 true, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */
                 true, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */
-                false, /* shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag */
+                false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */
                 // Ensure that we remove location info if the request asks to remove it even if the
                 // app has necessary permissions.
-                true /* shouldInclLocationSensitiveWifiInfoWithIncludeFlag */
+                true /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */
         );
     }
 
@@ -8965,11 +9289,11 @@
         setupLocationPermissions(Build.VERSION_CODES.Q, false, AppOpsManager.OPSTR_FINE_LOCATION,
                 Manifest.permission.ACCESS_FINE_LOCATION);
 
-        verifyOwnerUidAndWifiInfoNetCapsPermission(
+        verifyOwnerUidAndTransportInfoNetCapsPermission(
                 false, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */
                 false, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */
-                false, /* shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag */
-                false /* shouldInclLocationSensitiveWifiInfoWithIncludeFlag */
+                false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */
+                false /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */
         );
     }
 
@@ -8992,11 +9316,11 @@
         setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_COARSE_LOCATION,
                 Manifest.permission.ACCESS_COARSE_LOCATION);
 
-        verifyOwnerUidAndWifiInfoNetCapsPermission(
+        verifyOwnerUidAndTransportInfoNetCapsPermission(
                 false, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */
                 false, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */
-                false, /* shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag */
-                false /* shouldInclLocationSensitiveWifiInfoWithIncludeFlag */
+                false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */
+                false /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */
         );
     }
 
@@ -9006,14 +9330,193 @@
         // Test that not having fine location permission leads to sanitization.
         setupLocationPermissions(Build.VERSION_CODES.Q, true, null /* op */, null /* perm */);
 
-        verifyOwnerUidAndWifiInfoNetCapsPermission(
+        verifyOwnerUidAndTransportInfoNetCapsPermission(
                 false, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */
                 false, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */
-                false, /* shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag */
-                false /* shouldInclLocationSensitiveWifiInfoWithIncludeFlag */
+                false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */
+                false /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */
         );
     }
 
+    @Test
+    public void testCreateForCallerWithLocalMacAddressSanitizedWithLocalMacAddressPermission()
+            throws Exception {
+        mServiceContext.setPermission(Manifest.permission.LOCAL_MAC_ADDRESS, PERMISSION_GRANTED);
+
+        final TransportInfo transportInfo = mock(TransportInfo.class);
+        when(transportInfo.getApplicableRedactions())
+                .thenReturn(REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_LOCAL_MAC_ADDRESS);
+        final NetworkCapabilities netCap =
+                new NetworkCapabilities().setTransportInfo(transportInfo);
+
+        mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled(
+                netCap, false /* includeLocationSensitiveInfoInTransportInfo */,
+                Process.myPid(), Process.myUid(),
+                mContext.getPackageName(), getAttributionTag());
+        // don't redact MAC_ADDRESS fields, only location sensitive fields.
+        verify(transportInfo).makeCopy(REDACT_FOR_ACCESS_FINE_LOCATION);
+    }
+
+    @Test
+    public void testCreateForCallerWithLocalMacAddressSanitizedWithoutLocalMacAddressPermission()
+            throws Exception {
+        mServiceContext.setPermission(Manifest.permission.LOCAL_MAC_ADDRESS, PERMISSION_DENIED);
+
+        final TransportInfo transportInfo = mock(TransportInfo.class);
+        when(transportInfo.getApplicableRedactions())
+                .thenReturn(REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_LOCAL_MAC_ADDRESS);
+        final NetworkCapabilities netCap =
+                new NetworkCapabilities().setTransportInfo(transportInfo);
+
+        mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled(
+                netCap, false /* includeLocationSensitiveInfoInTransportInfo */,
+                Process.myPid(), Process.myUid(),
+                mContext.getPackageName(), getAttributionTag());
+        // redact both MAC_ADDRESS & location sensitive fields.
+        verify(transportInfo).makeCopy(REDACT_FOR_ACCESS_FINE_LOCATION
+                | REDACT_FOR_LOCAL_MAC_ADDRESS);
+    }
+
+    @Test
+    public void testCreateForCallerWithLocalMacAddressSanitizedWithSettingsPermission()
+            throws Exception {
+        mServiceContext.setPermission(Manifest.permission.NETWORK_SETTINGS, PERMISSION_GRANTED);
+
+        final TransportInfo transportInfo = mock(TransportInfo.class);
+        when(transportInfo.getApplicableRedactions())
+                .thenReturn(REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_NETWORK_SETTINGS);
+        final NetworkCapabilities netCap =
+                new NetworkCapabilities().setTransportInfo(transportInfo);
+
+        mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled(
+                netCap, false /* includeLocationSensitiveInfoInTransportInfo */,
+                Process.myPid(), Process.myUid(),
+                mContext.getPackageName(), getAttributionTag());
+        // don't redact NETWORK_SETTINGS fields, only location sensitive fields.
+        verify(transportInfo).makeCopy(REDACT_FOR_ACCESS_FINE_LOCATION);
+    }
+
+    @Test
+    public void testCreateForCallerWithLocalMacAddressSanitizedWithoutSettingsPermission()
+            throws Exception {
+        mServiceContext.setPermission(Manifest.permission.LOCAL_MAC_ADDRESS, PERMISSION_DENIED);
+
+        final TransportInfo transportInfo = mock(TransportInfo.class);
+        when(transportInfo.getApplicableRedactions())
+                .thenReturn(REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_NETWORK_SETTINGS);
+        final NetworkCapabilities netCap =
+                new NetworkCapabilities().setTransportInfo(transportInfo);
+
+        mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled(
+                netCap, false /* includeLocationSensitiveInfoInTransportInfo */,
+                Process.myPid(), Process.myUid(),
+                mContext.getPackageName(), getAttributionTag());
+        // redact both NETWORK_SETTINGS & location sensitive fields.
+        verify(transportInfo).makeCopy(
+                REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_NETWORK_SETTINGS);
+    }
+
+    /**
+     * Test TransportInfo to verify redaction mechanism.
+     */
+    private static class TestTransportInfo implements TransportInfo {
+        public final boolean locationRedacted;
+        public final boolean localMacAddressRedacted;
+        public final boolean settingsRedacted;
+
+        TestTransportInfo() {
+            locationRedacted = false;
+            localMacAddressRedacted = false;
+            settingsRedacted = false;
+        }
+
+        TestTransportInfo(boolean locationRedacted, boolean localMacAddressRedacted,
+                boolean settingsRedacted) {
+            this.locationRedacted = locationRedacted;
+            this.localMacAddressRedacted =
+                    localMacAddressRedacted;
+            this.settingsRedacted = settingsRedacted;
+        }
+
+        @Override
+        public TransportInfo makeCopy(@NetworkCapabilities.RedactionType long redactions) {
+            return new TestTransportInfo(
+                    (redactions & REDACT_FOR_ACCESS_FINE_LOCATION) != 0,
+                    (redactions & REDACT_FOR_LOCAL_MAC_ADDRESS) != 0,
+                    (redactions & REDACT_FOR_NETWORK_SETTINGS) != 0
+            );
+        }
+
+        @Override
+        public @NetworkCapabilities.RedactionType long getApplicableRedactions() {
+            return REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_LOCAL_MAC_ADDRESS
+                    | REDACT_FOR_NETWORK_SETTINGS;
+        }
+
+        @Override
+        public boolean equals(Object other) {
+            if (!(other instanceof TestTransportInfo)) return false;
+            TestTransportInfo that = (TestTransportInfo) other;
+            return that.locationRedacted == this.locationRedacted
+                    && that.localMacAddressRedacted == this.localMacAddressRedacted
+                    && that.settingsRedacted == this.settingsRedacted;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(locationRedacted, localMacAddressRedacted, settingsRedacted);
+        }
+    }
+
+    private void verifyNetworkCallbackLocationDataInclusionUsingTransportInfoAndOwnerUidInNetCaps(
+            @NonNull TestNetworkCallback wifiNetworkCallback, int actualOwnerUid,
+            @NonNull TransportInfo actualTransportInfo, int expectedOwnerUid,
+            @NonNull TransportInfo expectedTransportInfo) throws Exception {
+        when(mPackageManager.getTargetSdkVersion(anyString())).thenReturn(Build.VERSION_CODES.S);
+        final NetworkCapabilities ncTemplate =
+                new NetworkCapabilities()
+                        .addTransportType(TRANSPORT_WIFI)
+                        .setOwnerUid(actualOwnerUid);
+
+        final NetworkRequest wifiRequest = new NetworkRequest.Builder()
+                .addTransportType(TRANSPORT_WIFI).build();
+        mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback);
+
+        mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, new LinkProperties(),
+                ncTemplate);
+        mWiFiNetworkAgent.connect(false);
+
+        wifiNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
+
+        // Send network capabilities update with TransportInfo to trigger capabilities changed
+        // callback.
+        mWiFiNetworkAgent.setNetworkCapabilities(
+                ncTemplate.setTransportInfo(actualTransportInfo), true);
+
+        wifiNetworkCallback.expectCapabilitiesThat(mWiFiNetworkAgent,
+                nc -> Objects.equals(expectedOwnerUid, nc.getOwnerUid())
+                        && Objects.equals(expectedTransportInfo, nc.getTransportInfo()));
+
+    }
+
+    @Test
+    public void testVerifyLocationDataIsNotIncludedWhenInclFlagNotSet() throws Exception {
+        final TestNetworkCallback wifiNetworkCallack = new TestNetworkCallback();
+        final int ownerUid = Process.myUid();
+        final TransportInfo transportInfo = new TestTransportInfo();
+        // Even though the test uid holds privileged permissions, mask location fields since
+        // the callback did not explicitly opt-in to get location data.
+        final TransportInfo sanitizedTransportInfo = new TestTransportInfo(
+                true, /* locationRedacted */
+                true, /* localMacAddressRedacted */
+                true /* settingsRedacted */
+        );
+        // Should not expect location data since the callback does not set the flag for including
+        // location data.
+        verifyNetworkCallbackLocationDataInclusionUsingTransportInfoAndOwnerUidInNetCaps(
+                wifiNetworkCallack, ownerUid, transportInfo, INVALID_UID, sanitizedTransportInfo);
+    }
+
     private void setupConnectionOwnerUid(int vpnOwnerUid, @VpnManager.VpnType int vpnType)
             throws Exception {
         final Set<UidRange> vpnRange = Collections.singleton(PRIMARY_UIDRANGE);
@@ -9558,10 +10061,12 @@
         assertContainsExactly(exemptUidCaptor.getValue(), Process.VPN_UID, exemptUid);
 
         if (add) {
-            inOrder.verify(mMockNetd, times(1)).networkAddUidRanges(eq(mMockVpn.getNetId()),
+            inOrder.verify(mMockNetd, times(1))
+                    .networkAddUidRanges(eq(mMockVpn.getNetwork().getNetId()),
                     eq(toUidRangeStableParcels(vpnRanges)));
         } else {
-            inOrder.verify(mMockNetd, times(1)).networkRemoveUidRanges(eq(mMockVpn.getNetId()),
+            inOrder.verify(mMockNetd, times(1))
+                    .networkRemoveUidRanges(eq(mMockVpn.getNetwork().getNetId()),
                     eq(toUidRangeStableParcels(vpnRanges)));
         }
 
@@ -9602,13 +10107,90 @@
         for (int reqTypeInt : invalidReqTypeInts) {
             assertThrows("Expect throws for invalid request type " + reqTypeInt,
                     IllegalArgumentException.class,
-                    () -> mService.requestNetwork(nc, reqTypeInt, null, 0, null,
-                            ConnectivityManager.TYPE_NONE, NetworkCallback.FLAG_NONE,
+                    () -> mService.requestNetwork(Process.INVALID_UID, nc, reqTypeInt, null, 0,
+                            null, ConnectivityManager.TYPE_NONE, NetworkCallback.FLAG_NONE,
                             mContext.getPackageName(), getAttributionTag())
             );
         }
     }
 
+    @Test
+    public void testKeepConnected() throws Exception {
+        setAlwaysOnNetworks(false);
+        registerDefaultNetworkCallbacks();
+        final TestNetworkCallback allNetworksCb = new TestNetworkCallback();
+        final NetworkRequest allNetworksRequest = new NetworkRequest.Builder().clearCapabilities()
+                .build();
+        mCm.registerNetworkCallback(allNetworksRequest, allNetworksCb);
+
+        mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
+        mCellNetworkAgent.connect(true /* validated */);
+
+        mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
+        allNetworksCb.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
+
+        mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
+        mWiFiNetworkAgent.connect(true /* validated */);
+
+        mDefaultNetworkCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent);
+        // While the default callback doesn't see the network before it's validated, the listen
+        // sees the network come up and validate later
+        allNetworksCb.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
+        allNetworksCb.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
+        allNetworksCb.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
+        allNetworksCb.expectCallback(CallbackEntry.LOST, mCellNetworkAgent,
+                TEST_LINGER_DELAY_MS * 2);
+
+        // The cell network has disconnected (see LOST above) because it was outscored and
+        // had no requests (see setAlwaysOnNetworks(false) above)
+        mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
+        final NetworkScore score = new NetworkScore.Builder().setLegacyInt(30).build();
+        mCellNetworkAgent.setScore(score);
+        mCellNetworkAgent.connect(false /* validated */);
+
+        // The cell network gets torn down right away.
+        allNetworksCb.expectAvailableCallbacksUnvalidated(mCellNetworkAgent);
+        allNetworksCb.expectCallback(CallbackEntry.LOST, mCellNetworkAgent,
+                TEST_NASCENT_DELAY_MS * 2);
+        allNetworksCb.assertNoCallback();
+
+        // Now create a cell network with KEEP_CONNECTED_FOR_HANDOVER and make sure it's
+        // not disconnected immediately when outscored.
+        mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
+        final NetworkScore scoreKeepup = new NetworkScore.Builder().setLegacyInt(30)
+                .setKeepConnectedReason(KEEP_CONNECTED_FOR_HANDOVER).build();
+        mCellNetworkAgent.setScore(scoreKeepup);
+        mCellNetworkAgent.connect(true /* validated */);
+
+        allNetworksCb.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
+        mDefaultNetworkCallback.assertNoCallback();
+
+        mWiFiNetworkAgent.disconnect();
+
+        allNetworksCb.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+        mDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+        mDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent);
+
+        // Reconnect a WiFi network and make sure the cell network is still not torn down.
+        mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
+        mWiFiNetworkAgent.connect(true /* validated */);
+
+        allNetworksCb.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent);
+        mDefaultNetworkCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent);
+
+        // Now remove the reason to keep connected and make sure the network lingers and is
+        // torn down.
+        mCellNetworkAgent.setScore(new NetworkScore.Builder().setLegacyInt(30).build());
+        allNetworksCb.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent,
+                TEST_NASCENT_DELAY_MS * 2);
+        allNetworksCb.expectCallback(CallbackEntry.LOST, mCellNetworkAgent,
+                TEST_LINGER_DELAY_MS * 2);
+        mDefaultNetworkCallback.assertNoCallback();
+
+        mCm.unregisterNetworkCallback(allNetworksCb);
+        // mDefaultNetworkCallback will be unregistered by tearDown()
+    }
+
     private class QosCallbackMockHelper {
         @NonNull public final QosFilter mFilter;
         @NonNull public final IQosCallback mCallback;
@@ -9722,7 +10304,7 @@
                         && session.getSessionType() == QosSession.TYPE_EPS_BEARER), eq(attributes));
 
         mQosCallbackMockHelper.mAgentWrapper.getNetworkAgent()
-                .sendQosSessionLost(qosCallbackId, sessionId);
+                .sendQosSessionLost(qosCallbackId, sessionId, QosSession.TYPE_EPS_BEARER);
         waitForIdle();
         verify(mQosCallbackMockHelper.mCallback).onQosSessionLost(argThat(session ->
                 session.getSessionId() == sessionId
@@ -9730,6 +10312,36 @@
     }
 
     @Test
+    public void testNrQosCallbackAvailableAndLost() throws Exception {
+        mQosCallbackMockHelper = new QosCallbackMockHelper();
+        final int sessionId = 10;
+        final int qosCallbackId = 1;
+
+        when(mQosCallbackMockHelper.mFilter.validate())
+                .thenReturn(QosCallbackException.EX_TYPE_FILTER_NONE);
+        mQosCallbackMockHelper.registerQosCallback(
+                mQosCallbackMockHelper.mFilter, mQosCallbackMockHelper.mCallback);
+        waitForIdle();
+
+        final NrQosSessionAttributes attributes = new NrQosSessionAttributes(
+                1, 2, 3, 4, 5, 6, 7, new ArrayList<>());
+        mQosCallbackMockHelper.mAgentWrapper.getNetworkAgent()
+                .sendQosSessionAvailable(qosCallbackId, sessionId, attributes);
+        waitForIdle();
+
+        verify(mQosCallbackMockHelper.mCallback).onNrQosSessionAvailable(argThat(session ->
+                session.getSessionId() == sessionId
+                        && session.getSessionType() == QosSession.TYPE_NR_BEARER), eq(attributes));
+
+        mQosCallbackMockHelper.mAgentWrapper.getNetworkAgent()
+                .sendQosSessionLost(qosCallbackId, sessionId, QosSession.TYPE_NR_BEARER);
+        waitForIdle();
+        verify(mQosCallbackMockHelper.mCallback).onQosSessionLost(argThat(session ->
+                session.getSessionId() == sessionId
+                        && session.getSessionType() == QosSession.TYPE_NR_BEARER));
+    }
+
+    @Test
     public void testQosCallbackTooManyRequests() throws Exception {
         mQosCallbackMockHelper = new QosCallbackMockHelper();
 
@@ -10174,6 +10786,7 @@
         mCm.registerDefaultNetworkCallback(mDefaultNetworkCallback);
         registerDefaultNetworkCallbackAsUid(mProfileDefaultNetworkCallback,
                 TEST_WORK_PROFILE_APP_UID);
+        // TODO: test using ConnectivityManager#registerDefaultNetworkCallbackAsUid as well.
         mServiceContext.setPermission(
                 Manifest.permission.NETWORK_SETTINGS, PERMISSION_DENIED);
     }
@@ -10193,7 +10806,7 @@
     private void setupMultipleDefaultNetworksForOemNetworkPreferenceNotCurrentUidTest(
             @OemNetworkPreferences.OemNetworkPreference final int networkPrefToSetup)
             throws Exception {
-        final int testPackageNameUid = 123;
+        final int testPackageNameUid = TEST_PACKAGE_UID;
         final String testPackageName = "per.app.defaults.package";
         setupMultipleDefaultNetworksForOemNetworkPreferenceTest(
                 networkPrefToSetup, testPackageNameUid, testPackageName);
@@ -10329,6 +10942,11 @@
         mCm.registerDefaultNetworkCallback(defaultNetworkCallback);
         defaultNetworkCallback.assertNoCallback();
 
+        final TestNetworkCallback otherUidDefaultCallback = new TestNetworkCallback();
+        withPermission(Manifest.permission.NETWORK_SETTINGS, () ->
+                mCm.registerDefaultNetworkCallbackAsUid(TEST_PACKAGE_UID, otherUidDefaultCallback,
+                        new Handler(ConnectivityThread.getInstanceLooper())));
+
         // Setup the test process to use networkPref for their default network.
         setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref);
 
@@ -10339,19 +10957,22 @@
                 null,
                 mEthernetNetworkAgent.getNetwork());
 
-        // At this point with a restricted network used, the available callback should trigger
+        // At this point with a restricted network used, the available callback should trigger.
         defaultNetworkCallback.expectAvailableThenValidatedCallbacks(mEthernetNetworkAgent);
         assertEquals(defaultNetworkCallback.getLastAvailableNetwork(),
                 mEthernetNetworkAgent.getNetwork());
+        otherUidDefaultCallback.assertNoCallback();
 
         // Now bring down the default network which should trigger a LOST callback.
         setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false);
 
         // At this point, with no network is available, the lost callback should trigger
         defaultNetworkCallback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent);
+        otherUidDefaultCallback.assertNoCallback();
 
         // Confirm we can unregister without issues.
         mCm.unregisterNetworkCallback(defaultNetworkCallback);
+        mCm.unregisterNetworkCallback(otherUidDefaultCallback);
     }
 
     @Test
@@ -10369,6 +10990,11 @@
         mCm.registerDefaultNetworkCallback(defaultNetworkCallback);
         defaultNetworkCallback.assertNoCallback();
 
+        final TestNetworkCallback otherUidDefaultCallback = new TestNetworkCallback();
+        withPermission(Manifest.permission.NETWORK_SETTINGS, () ->
+                mCm.registerDefaultNetworkCallbackAsUid(TEST_PACKAGE_UID, otherUidDefaultCallback,
+                        new Handler(ConnectivityThread.getInstanceLooper())));
+
         // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID.
         // The active nai for the default is null at this point as this is a restricted network.
         setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true);
@@ -10380,15 +11006,19 @@
         defaultNetworkCallback.expectAvailableThenValidatedCallbacks(mEthernetNetworkAgent);
         assertEquals(defaultNetworkCallback.getLastAvailableNetwork(),
                 mEthernetNetworkAgent.getNetwork());
+        otherUidDefaultCallback.assertNoCallback();
 
         // Now bring down the default network which should trigger a LOST callback.
         setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false);
+        otherUidDefaultCallback.assertNoCallback();
 
         // At this point, with no network is available, the lost callback should trigger
         defaultNetworkCallback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent);
+        otherUidDefaultCallback.assertNoCallback();
 
         // Confirm we can unregister without issues.
         mCm.unregisterNetworkCallback(defaultNetworkCallback);
+        mCm.unregisterNetworkCallback(otherUidDefaultCallback);
     }
 
     @Test
@@ -10402,6 +11032,11 @@
         mCm.registerDefaultNetworkCallback(defaultNetworkCallback);
         defaultNetworkCallback.assertNoCallback();
 
+        final TestNetworkCallback otherUidDefaultCallback = new TestNetworkCallback();
+        withPermission(Manifest.permission.NETWORK_SETTINGS, () ->
+                mCm.registerDefaultNetworkCallbackAsUid(TEST_PACKAGE_UID, otherUidDefaultCallback,
+                        new Handler(ConnectivityThread.getInstanceLooper())));
+
         // Setup a process different than the test process to use the default network. This means
         // that the defaultNetworkCallback won't be tracked by the per-app policy.
         setupMultipleDefaultNetworksForOemNetworkPreferenceNotCurrentUidTest(networkPref);
@@ -10417,6 +11052,9 @@
         defaultNetworkCallback.assertNoCallback();
         assertDefaultNetworkCapabilities(userId /* no networks */);
 
+        // The other UID does have access, and gets a callback.
+        otherUidDefaultCallback.expectAvailableThenValidatedCallbacks(mEthernetNetworkAgent);
+
         // Bring up unrestricted cellular. This should now satisfy the default network.
         setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true);
         verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
@@ -10424,25 +11062,31 @@
                 mEthernetNetworkAgent.getNetwork());
 
         // At this point with an unrestricted network used, the available callback should trigger
+        // The other UID is unaffected and remains on the paid network.
         defaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
         assertEquals(defaultNetworkCallback.getLastAvailableNetwork(),
                 mCellNetworkAgent.getNetwork());
         assertDefaultNetworkCapabilities(userId, mCellNetworkAgent);
+        otherUidDefaultCallback.assertNoCallback();
 
         // Now bring down the per-app network.
         setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false);
 
-        // Since the callback didn't use the per-app network, no callback should fire.
+        // Since the callback didn't use the per-app network, only the other UID gets a callback.
+        // Because the preference specifies no fallback, it does not switch to cellular.
         defaultNetworkCallback.assertNoCallback();
+        otherUidDefaultCallback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent);
 
         // Now bring down the default network.
         setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false);
 
         // As this callback was tracking the default, this should now trigger.
         defaultNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
+        otherUidDefaultCallback.assertNoCallback();
 
         // Confirm we can unregister without issues.
         mCm.unregisterNetworkCallback(defaultNetworkCallback);
+        mCm.unregisterNetworkCallback(otherUidDefaultCallback);
     }
 
     /**
@@ -10906,6 +11550,115 @@
         // default callbacks will be unregistered in tearDown
     }
 
+    @Test
+    public void testNetworkFactoryRequestsWithMultilayerRequest()
+            throws Exception {
+        // First use OEM_PAID preference to create a multi-layer request : 1. listen for
+        // unmetered, 2. request network with cap OEM_PAID, 3, request the default network for
+        // fallback.
+        @OemNetworkPreferences.OemNetworkPreference final int networkPref =
+                OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID;
+        setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref);
+
+        final HandlerThread handlerThread = new HandlerThread("MockFactory");
+        handlerThread.start();
+        NetworkCapabilities internetFilter = new NetworkCapabilities()
+                .addCapability(NET_CAPABILITY_INTERNET)
+                .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED);
+        final MockNetworkFactory internetFactory = new MockNetworkFactory(handlerThread.getLooper(),
+                mServiceContext, "internetFactory", internetFilter, mCsHandlerThread);
+        internetFactory.setScoreFilter(40);
+        internetFactory.register();
+        // Default internet request & 3rd (fallback) request in OEM_PAID NRI. The unmetered request
+        // is never sent to factories (it's a LISTEN, not requestable) and the OEM_PAID request
+        // doesn't match the internetFactory filter.
+        internetFactory.expectRequestAdds(2);
+
+        NetworkCapabilities oemPaidFilter = new NetworkCapabilities()
+                .addCapability(NET_CAPABILITY_INTERNET)
+                .addCapability(NET_CAPABILITY_OEM_PAID)
+                .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
+                .removeCapability(NET_CAPABILITY_NOT_RESTRICTED);
+        final MockNetworkFactory oemPaidFactory = new MockNetworkFactory(handlerThread.getLooper(),
+                mServiceContext, "oemPaidFactory", oemPaidFilter, mCsHandlerThread);
+        oemPaidFactory.setScoreFilter(40);
+        oemPaidFactory.register();
+        oemPaidFactory.expectRequestAdd(); // Because nobody satisfies the request
+
+        mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
+        mCellNetworkAgent.connect(true);
+
+        // A network connected that satisfies the default internet request. For the OEM_PAID
+        // preference, this is not as good as an OEM_PAID network, so even if the score of
+        // the network is better than the factory announced, it still should try to bring up
+        // the network.
+        expectNoRequestChanged(oemPaidFactory);
+        oemPaidFactory.assertRequestCountEquals(1);
+        // The internet factory however is outscored, and should lose its requests.
+        internetFactory.expectRequestRemoves(2);
+        internetFactory.assertRequestCountEquals(0);
+
+        final NetworkCapabilities oemPaidNc = new NetworkCapabilities();
+        oemPaidNc.addCapability(NET_CAPABILITY_OEM_PAID);
+        oemPaidNc.removeCapability(NET_CAPABILITY_NOT_RESTRICTED);
+        final TestNetworkAgentWrapper oemPaidAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR,
+                new LinkProperties(), oemPaidNc);
+        oemPaidAgent.connect(true);
+
+        // The oemPaidAgent has score 50 (default for cell) so it beats what the oemPaidFactory can
+        // provide, therefore it loses the request.
+        oemPaidFactory.expectRequestRemove();
+        oemPaidFactory.assertRequestCountEquals(0);
+        expectNoRequestChanged(internetFactory);
+        internetFactory.assertRequestCountEquals(0);
+
+        oemPaidAgent.adjustScore(-30);
+        // Now the that the agent is weak, the oemPaidFactory can beat the existing network for the
+        // OEM_PAID request. The internet factory however can't beat a network that has OEM_PAID
+        // for the preference request, so it doesn't see the request.
+        oemPaidFactory.expectRequestAdd();
+        oemPaidFactory.assertRequestCountEquals(1);
+        expectNoRequestChanged(internetFactory);
+        internetFactory.assertRequestCountEquals(0);
+
+        mCellNetworkAgent.disconnect();
+        // The network satisfying the default internet request has disconnected, so the
+        // internetFactory sees the default request again. However there is a network with OEM_PAID
+        // connected, so the 2nd OEM_PAID req is already satisfied, so the oemPaidFactory doesn't
+        // care about networks that don't have OEM_PAID.
+        expectNoRequestChanged(oemPaidFactory);
+        oemPaidFactory.assertRequestCountEquals(1);
+        internetFactory.expectRequestAdd();
+        internetFactory.assertRequestCountEquals(1);
+
+        // Cell connects again, still with score 50. Back to the previous state.
+        mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
+        mCellNetworkAgent.connect(true);
+        expectNoRequestChanged(oemPaidFactory);
+        oemPaidFactory.assertRequestCountEquals(1);
+        internetFactory.expectRequestRemove();
+        internetFactory.assertRequestCountEquals(0);
+
+        // Now WiFi connects and it's unmetered, but it's weaker than cell.
+        mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
+        mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED);
+        mWiFiNetworkAgent.adjustScore(-30); // Not the best Internet network, but unmetered
+        mWiFiNetworkAgent.connect(true);
+
+        // The OEM_PAID preference prefers an unmetered network to an OEM_PAID network, so
+        // the oemPaidFactory can't beat this no matter how high its score.
+        oemPaidFactory.expectRequestRemove();
+        expectNoRequestChanged(internetFactory);
+
+        mCellNetworkAgent.disconnect();
+        // Now that the best internet network (cell, with its 50 score compared to 30 for WiFi
+        // at this point), the default internet request is satisfied by a network worse than
+        // the internetFactory announced, so it gets the request. However, there is still an
+        // unmetered network, so the oemPaidNetworkFactory still can't beat this.
+        expectNoRequestChanged(oemPaidFactory);
+        internetFactory.expectRequestAdd();
+    }
+
     /**
      * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK in the following order:
      * NET_CAPABILITY_NOT_METERED -> NET_CAPABILITY_OEM_PAID
@@ -11200,11 +11953,11 @@
         testFactory.setScoreFilter(40);
 
         try {
-            // Register the factory and expect it will see default request, because all requests
-            // are sent to all factories.
+            // Register the factory. It doesn't see the default request because its filter does
+            // not include INTERNET.
             testFactory.register();
-            testFactory.expectRequestAdd();
-            testFactory.assertRequestCountEquals(1);
+            expectNoRequestChanged(testFactory);
+            testFactory.assertRequestCountEquals(0);
             // The factory won't try to start the network since the default request doesn't
             // match the filter (no INTERNET capability).
             assertFalse(testFactory.getMyStartRequested());
@@ -11217,7 +11970,7 @@
                     bestMatchingCb, mCsHandlerThread.getThreadHandler());
             bestMatchingCb.assertNoCallback();
             expectNoRequestChanged(testFactory);
-            testFactory.assertRequestCountEquals(1);
+            testFactory.assertRequestCountEquals(0);
             assertFalse(testFactory.getMyStartRequested());
 
             // Fire a normal mms request, verify the factory will only see the request.
@@ -11226,13 +11979,13 @@
                     .addCapability(NET_CAPABILITY_MMS).build();
             mCm.requestNetwork(mmsRequest, mmsNetworkCallback);
             testFactory.expectRequestAdd();
-            testFactory.assertRequestCountEquals(2);
+            testFactory.assertRequestCountEquals(1);
             assertTrue(testFactory.getMyStartRequested());
 
             // Unregister best matching callback, verify factory see no change.
             mCm.unregisterNetworkCallback(bestMatchingCb);
             expectNoRequestChanged(testFactory);
-            testFactory.assertRequestCountEquals(2);
+            testFactory.assertRequestCountEquals(1);
             assertTrue(testFactory.getMyStartRequested());
         } finally {
             testFactory.terminate();
diff --git a/tests/net/java/com/android/server/connectivity/FullScoreTest.kt b/tests/net/java/com/android/server/connectivity/FullScoreTest.kt
index eb3b4df..2864bc7 100644
--- a/tests/net/java/com/android/server/connectivity/FullScoreTest.kt
+++ b/tests/net/java/com/android/server/connectivity/FullScoreTest.kt
@@ -18,6 +18,7 @@
 
 import android.net.NetworkAgentConfig
 import android.net.NetworkCapabilities
+import android.net.NetworkScore.KEEP_CONNECTED_NONE
 import android.text.TextUtils
 import android.util.ArraySet
 import androidx.test.filters.SmallTest
@@ -60,11 +61,11 @@
 
     @Test
     fun testGetLegacyInt() {
-        val ns = FullScore(50, 0L /* policy */)
+        val ns = FullScore(50, 0L /* policy */, KEEP_CONNECTED_NONE)
         assertEquals(10, ns.legacyInt) // -40 penalty for not being validated
         assertEquals(50, ns.legacyIntAsValidated)
 
-        val vpnNs = FullScore(101, 0L /* policy */).withPolicies(vpn = true)
+        val vpnNs = FullScore(101, 0L /* policy */, KEEP_CONNECTED_NONE).withPolicies(vpn = true)
         assertEquals(101, vpnNs.legacyInt) // VPNs are not subject to unvalidation penalty
         assertEquals(101, vpnNs.legacyIntAsValidated)
         assertEquals(101, vpnNs.withPolicies(validated = true).legacyInt)
@@ -83,7 +84,7 @@
 
     @Test
     fun testToString() {
-        val string = FullScore(10, 0L /* policy */)
+        val string = FullScore(10, 0L /* policy */, KEEP_CONNECTED_NONE)
                 .withPolicies(vpn = true, acceptUnvalidated = true).toString()
         assertTrue(string.contains("Score(10"), string)
         assertTrue(string.contains("ACCEPT_UNVALIDATED"), string)
@@ -107,7 +108,7 @@
 
     @Test
     fun testHasPolicy() {
-        val ns = FullScore(50, 0L /* policy */)
+        val ns = FullScore(50, 0L /* policy */, KEEP_CONNECTED_NONE)
         assertFalse(ns.hasPolicy(POLICY_IS_VALIDATED))
         assertFalse(ns.hasPolicy(POLICY_IS_VPN))
         assertFalse(ns.hasPolicy(POLICY_EVER_USER_SELECTED))
diff --git a/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java b/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java
index 8c5d1d6..8b072c4 100644
--- a/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java
+++ b/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java
@@ -22,7 +22,9 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
@@ -56,6 +58,7 @@
 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;
 
@@ -80,6 +83,12 @@
 
     IpConnectivityMetrics mService;
     NetdEventListenerService mNetdListener;
+    private static final NetworkCapabilities CAPABILITIES_WIFI = new NetworkCapabilities.Builder()
+            .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
+            .build();
+    private static final NetworkCapabilities CAPABILITIES_CELL = new NetworkCapabilities.Builder()
+            .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
+            .build();
 
     @Before
     public void setUp() {
@@ -263,14 +272,6 @@
         // TODO: instead of comparing textpb to textpb, parse textpb and compare proto to proto.
         IpConnectivityLog logger = new IpConnectivityLog(mService.impl);
 
-        NetworkCapabilities ncWifi = new NetworkCapabilities();
-        NetworkCapabilities ncCell = new NetworkCapabilities();
-        ncWifi.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
-        ncCell.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
-
-        when(mCm.getNetworkCapabilities(new Network(100))).thenReturn(ncWifi);
-        when(mCm.getNetworkCapabilities(new Network(101))).thenReturn(ncCell);
-
         ApfStats apfStats = new ApfStats.Builder()
                 .setDurationMs(45000)
                 .setReceivedRas(10)
@@ -584,11 +585,21 @@
         return buffer.toString();
     }
 
-    void connectEvent(int netid, int error, int latencyMs, String ipAddr) throws Exception {
-        mNetdListener.onConnectEvent(netid, error, latencyMs, ipAddr, 80, 1);
+    private void setCapabilities(int netId) {
+        final ArgumentCaptor<ConnectivityManager.NetworkCallback> networkCallback =
+                ArgumentCaptor.forClass(ConnectivityManager.NetworkCallback.class);
+        verify(mCm).registerNetworkCallback(any(), networkCallback.capture());
+        networkCallback.getValue().onCapabilitiesChanged(new Network(netId),
+                netId == 100 ? CAPABILITIES_WIFI : CAPABILITIES_CELL);
+    }
+
+    void connectEvent(int netId, int error, int latencyMs, String ipAddr) throws Exception {
+        setCapabilities(netId);
+        mNetdListener.onConnectEvent(netId, error, latencyMs, ipAddr, 80, 1);
     }
 
     void dnsEvent(int netId, int type, int result, int latency) throws Exception {
+        setCapabilities(netId);
         mNetdListener.onDnsEvent(netId, type, result, latency, "", null, 0, 0);
     }
 
diff --git a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
index 9ab60a4..116d755e 100644
--- a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
+++ b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
@@ -32,6 +32,7 @@
 import android.content.Context;
 import android.content.res.Resources;
 import android.net.ConnectivityManager;
+import android.net.ConnectivityResources;
 import android.net.IDnsResolver;
 import android.net.INetd;
 import android.net.LinkProperties;
@@ -47,10 +48,11 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
-import com.android.internal.R;
+import com.android.connectivity.resources.R;
 import com.android.server.ConnectivityService;
 import com.android.server.connectivity.NetworkNotificationManager.NotificationType;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -84,10 +86,16 @@
         MockitoAnnotations.initMocks(this);
         when(mCtx.getResources()).thenReturn(mResources);
         when(mCtx.getPackageName()).thenReturn("com.android.server.connectivity");
+        ConnectivityResources.setResourcesContextForTest(mCtx);
 
         mMonitor = new TestableLingerMonitor(mCtx, mNotifier, HIGH_DAILY_LIMIT, HIGH_RATE_LIMIT);
     }
 
+    @After
+    public void tearDown() {
+        ConnectivityResources.setResourcesContextForTest(null);
+    }
+
     @Test
     public void testTransitions() {
         setNotificationSwitch(transition(WIFI, CELLULAR));
diff --git a/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java b/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java
index 8ccea1a..50aaaee 100644
--- a/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java
+++ b/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java
@@ -23,8 +23,9 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.verify;
 
 import android.content.Context;
 import android.net.ConnectivityManager;
@@ -42,6 +43,7 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
 
 import java.io.FileOutputStream;
 import java.io.PrintWriter;
@@ -61,18 +63,16 @@
 
     NetdEventListenerService mService;
     ConnectivityManager mCm;
+    private static final NetworkCapabilities CAPABILITIES_WIFI = new NetworkCapabilities.Builder()
+            .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
+            .build();
+    private static final NetworkCapabilities CAPABILITIES_CELL = new NetworkCapabilities.Builder()
+            .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
+            .build();
 
     @Before
     public void setUp() {
-        NetworkCapabilities ncWifi = new NetworkCapabilities();
-        NetworkCapabilities ncCell = new NetworkCapabilities();
-        ncWifi.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
-        ncCell.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
-
         mCm = mock(ConnectivityManager.class);
-        when(mCm.getNetworkCapabilities(new Network(100))).thenReturn(ncWifi);
-        when(mCm.getNetworkCapabilities(new Network(101))).thenReturn(ncCell);
-
         mService = new NetdEventListenerService(mCm);
     }
 
@@ -470,7 +470,16 @@
         assertEquals(want, got);
     }
 
+    private void setCapabilities(int netId) {
+        final ArgumentCaptor<ConnectivityManager.NetworkCallback> networkCallback =
+                ArgumentCaptor.forClass(ConnectivityManager.NetworkCallback.class);
+        verify(mCm).registerNetworkCallback(any(), networkCallback.capture());
+        networkCallback.getValue().onCapabilitiesChanged(new Network(netId),
+                netId == 100 ? CAPABILITIES_WIFI : CAPABILITIES_CELL);
+    }
+
     Thread connectEventAction(int netId, int error, int latencyMs, String ipAddr) {
+        setCapabilities(netId);
         return new Thread(() -> {
             try {
                 mService.onConnectEvent(netId, error, latencyMs, ipAddr, 80, 1);
@@ -481,6 +490,7 @@
     }
 
     void dnsEvent(int netId, int type, int result, int latency) throws Exception {
+        setCapabilities(netId);
         mService.onDnsEvent(netId, type, result, latency, "", null, 0, 0);
     }
 
diff --git a/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java b/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java
index dde77b0..2f3ee68 100644
--- a/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java
+++ b/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java
@@ -50,9 +50,7 @@
 import com.android.server.connectivity.NetworkNotificationManager.NotificationType;
 
 import org.junit.After;
-import org.junit.AfterClass;
 import org.junit.Before;
-import org.junit.BeforeClass;
 import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -104,17 +102,6 @@
 
     NetworkNotificationManager mManager;
 
-
-    @BeforeClass
-    public static void setUpClass() {
-        Notification.DevFlags.sForceDefaults = true;
-    }
-
-    @AfterClass
-    public static void tearDownClass() {
-        Notification.DevFlags.sForceDefaults = false;
-    }
-
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
diff --git a/tests/net/java/com/android/server/connectivity/NetworkOfferTest.kt b/tests/net/java/com/android/server/connectivity/NetworkOfferTest.kt
new file mode 100644
index 0000000..409f8c3
--- /dev/null
+++ b/tests/net/java/com/android/server/connectivity/NetworkOfferTest.kt
@@ -0,0 +1,71 @@
+/*
+ * 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.connectivity
+
+import android.net.INetworkOfferCallback
+import android.net.NetworkCapabilities
+import android.net.NetworkRequest
+import android.net.NetworkScore.KEEP_CONNECTED_NONE
+import androidx.test.filters.SmallTest
+import androidx.test.runner.AndroidJUnit4
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.eq
+import org.mockito.Mockito.mock
+import org.mockito.Mockito.verify
+import kotlin.test.assertFalse
+import kotlin.test.assertTrue
+
+const val POLICY_NONE = 0L
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class NetworkOfferTest {
+    val mockCallback = mock(INetworkOfferCallback::class.java)
+
+    @Test
+    fun testOfferNeededUnneeded() {
+        val score = FullScore(50, POLICY_NONE, KEEP_CONNECTED_NONE)
+        val offer = NetworkOffer(score, NetworkCapabilities.Builder().build(), mockCallback,
+                1 /* providerId */)
+        val request1 = mock(NetworkRequest::class.java)
+        val request2 = mock(NetworkRequest::class.java)
+        offer.onNetworkNeeded(request1)
+        verify(mockCallback).onNetworkNeeded(eq(request1))
+        assertTrue(offer.neededFor(request1))
+        assertFalse(offer.neededFor(request2))
+
+        offer.onNetworkNeeded(request2)
+        verify(mockCallback).onNetworkNeeded(eq(request2))
+        assertTrue(offer.neededFor(request1))
+        assertTrue(offer.neededFor(request2))
+
+        // Note that the framework never calls onNetworkNeeded multiple times with the same
+        // request without calling onNetworkUnneeded first. It would be incorrect usage and the
+        // behavior would be undefined, so there is nothing to test.
+
+        offer.onNetworkUnneeded(request1)
+        verify(mockCallback).onNetworkUnneeded(eq(request1))
+        assertFalse(offer.neededFor(request1))
+        assertTrue(offer.neededFor(request2))
+
+        offer.onNetworkUnneeded(request2)
+        verify(mockCallback).onNetworkUnneeded(eq(request2))
+        assertFalse(offer.neededFor(request1))
+        assertFalse(offer.neededFor(request2))
+    }
+}
diff --git a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
index 9334e2c..eeeb4fb 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
@@ -89,6 +89,7 @@
 import android.net.NetworkStatsHistory;
 import android.net.NetworkTemplate;
 import android.net.UnderlyingNetworkInfo;
+import android.net.TelephonyNetworkSpecifier;
 import android.net.netstats.provider.INetworkStatsProviderCallback;
 import android.os.ConditionVariable;
 import android.os.Handler;
@@ -1280,6 +1281,77 @@
     }
 
     @Test
+    public void testDualVilteProviderStats() throws Exception {
+        // Pretend that network comes online.
+        expectDefaultSettings();
+        final int subId1 = 1;
+        final int subId2 = 2;
+        final NetworkStateSnapshot[] states = new NetworkStateSnapshot[]{
+                buildImsState(IMSI_1, subId1, TEST_IFACE),
+                buildImsState(IMSI_2, subId2, TEST_IFACE2)};
+        expectNetworkStatsSummary(buildEmptyStats());
+        expectNetworkStatsUidDetail(buildEmptyStats());
+
+        // Register custom provider and retrieve callback.
+        final TestableNetworkStatsProviderBinder provider =
+                new TestableNetworkStatsProviderBinder();
+        final INetworkStatsProviderCallback cb =
+                mService.registerNetworkStatsProvider("TEST", provider);
+        assertNotNull(cb);
+
+        mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states),
+                new UnderlyingNetworkInfo[0]);
+
+        // Verifies that one requestStatsUpdate will be called during iface update.
+        provider.expectOnRequestStatsUpdate(0 /* unused */);
+
+        // Create some initial traffic and report to the service.
+        incrementCurrentTime(HOUR_IN_MILLIS);
+        final String vtIface1 = NetworkStats.IFACE_VT + subId1;
+        final String vtIface2 = NetworkStats.IFACE_VT + subId2;
+        final NetworkStats expectedStats = new NetworkStats(0L, 1)
+                .addEntry(new NetworkStats.Entry(vtIface1, UID_RED, SET_DEFAULT,
+                        TAG_NONE, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_YES,
+                        128L, 2L, 128L, 2L, 1L))
+                .addEntry(new NetworkStats.Entry(vtIface2, UID_RED, SET_DEFAULT,
+                        TAG_NONE, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_YES,
+                        64L, 1L, 64L, 1L, 1L));
+        cb.notifyStatsUpdated(0 /* unused */, expectedStats, expectedStats);
+
+        // Make another empty mutable stats object. This is necessary since the new NetworkStats
+        // object will be used to compare with the old one in NetworkStatsRecoder, two of them
+        // cannot be the same object.
+        expectNetworkStatsUidDetail(buildEmptyStats());
+
+        forcePollAndWaitForIdle();
+
+        // Verifies that one requestStatsUpdate and setAlert will be called during polling.
+        provider.expectOnRequestStatsUpdate(0 /* unused */);
+        provider.expectOnSetAlert(MB_IN_BYTES);
+
+        // Verifies that service recorded history, does not verify uid tag part.
+        assertUidTotal(sTemplateImsi1, UID_RED, 128L, 2L, 128L, 2L, 1);
+
+        // Verifies that onStatsUpdated updates the stats accordingly.
+        NetworkStats stats = mSession.getSummaryForAllUid(
+                sTemplateImsi1, Long.MIN_VALUE, Long.MAX_VALUE, true);
+        assertEquals(1, stats.size());
+        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
+                DEFAULT_NETWORK_YES, 128L, 2L, 128L, 2L, 1L);
+
+        stats = mSession.getSummaryForAllUid(
+                sTemplateImsi2, Long.MIN_VALUE, Long.MAX_VALUE, true);
+        assertEquals(1, stats.size());
+        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
+                DEFAULT_NETWORK_YES, 64L, 1L, 64L, 1L, 1L);
+
+        // Verifies that unregister the callback will remove the provider from service.
+        cb.unregister();
+        forcePollAndWaitForIdle();
+        provider.assertNoCallback();
+    }
+
+    @Test
     public void testStatsProviderSetAlert() throws Exception {
         // Pretend that network comes online.
         expectDefaultSettings();
@@ -1616,6 +1688,20 @@
                 TYPE_MOBILE);
     }
 
+    private static NetworkStateSnapshot buildImsState(
+            String subscriberId, int subId, String ifaceName) {
+        final LinkProperties prop = new LinkProperties();
+        prop.setInterfaceName(ifaceName);
+        final NetworkCapabilities capabilities = new NetworkCapabilities();
+        capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, true);
+        capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, true);
+        capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_IMS, true);
+        capabilities.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
+        capabilities.setNetworkSpecifier(new TelephonyNetworkSpecifier(subId));
+        return new NetworkStateSnapshot(
+                MOBILE_NETWORK, capabilities, prop, subscriberId, TYPE_MOBILE);
+    }
+
     private long getElapsedRealtime() {
         return mElapsedRealtime;
     }
diff --git a/tests/utils/testutils/java/com/android/server/wm/test/filters/FrameworksTestsFilter.java b/tests/utils/testutils/java/com/android/server/wm/test/filters/FrameworksTestsFilter.java
index 8932892..bcd6ed7 100644
--- a/tests/utils/testutils/java/com/android/server/wm/test/filters/FrameworksTestsFilter.java
+++ b/tests/utils/testutils/java/com/android/server/wm/test/filters/FrameworksTestsFilter.java
@@ -59,9 +59,10 @@
             "android.view.RoundedCornersTest",
             "android.view.WindowMetricsTest",
             "android.view.PendingInsetsControllerTest",
-            "android.app.WindowContextTest",
+            "android.window.WindowContextTest",
             "android.window.WindowMetricsHelperTest",
-            "android.app.activity.ActivityThreadTest"
+            "android.app.activity.ActivityThreadTest",
+            "android.window.WindowContextControllerTest"
     };
 
     public FrameworksTestsFilter(Bundle testArgs) {
diff --git a/tests/vcn/java/android/net/vcn/VcnManagerTest.java b/tests/vcn/java/android/net/vcn/VcnManagerTest.java
index 7515971..516c206 100644
--- a/tests/vcn/java/android/net/vcn/VcnManagerTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnManagerTest.java
@@ -204,7 +204,7 @@
                 new VcnStatusCallbackBinder(INLINE_EXECUTOR, mMockStatusCallback);
 
         cbBinder.onVcnStatusChanged(VCN_STATUS_CODE_ACTIVE);
-        verify(mMockStatusCallback).onVcnStatusChanged(VCN_STATUS_CODE_ACTIVE);
+        verify(mMockStatusCallback).onStatusChanged(VCN_STATUS_CODE_ACTIVE);
 
         cbBinder.onGatewayConnectionError(
                 UNDERLYING_NETWORK_CAPABILITIES,
diff --git a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
index 814cad4..f15d420 100644
--- a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
+++ b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
@@ -19,6 +19,8 @@
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED;
 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
 import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
+import static android.telephony.TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
+import static android.telephony.TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
 
 import static com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot;
 import static com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionTrackerCallback;
@@ -32,9 +34,8 @@
 import static org.junit.Assert.fail;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.anyBoolean;
 import static org.mockito.Mockito.argThat;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doNothing;
@@ -48,7 +49,9 @@
 
 import android.annotation.NonNull;
 import android.app.AppOpsManager;
+import android.content.BroadcastReceiver;
 import android.content.Context;
+import android.content.Intent;
 import android.net.ConnectivityManager;
 import android.net.LinkProperties;
 import android.net.NetworkCapabilities;
@@ -239,9 +242,14 @@
         doReturn(Collections.singletonList(TEST_SUBSCRIPTION_INFO))
                 .when(mSubMgr)
                 .getSubscriptionsInGroup(any());
-        doReturn(isPrivileged)
+        doReturn(mTelMgr)
                 .when(mTelMgr)
-                .hasCarrierPrivileges(eq(TEST_SUBSCRIPTION_INFO.getSubscriptionId()));
+                .createForSubscriptionId(eq(TEST_SUBSCRIPTION_INFO.getSubscriptionId()));
+        doReturn(isPrivileged
+                        ? CARRIER_PRIVILEGE_STATUS_HAS_ACCESS
+                        : CARRIER_PRIVILEGE_STATUS_NO_ACCESS)
+                .when(mTelMgr)
+                .checkCarrierPrivilegesForPackage(eq(TEST_PACKAGE_NAME));
     }
 
     @Test
@@ -330,6 +338,13 @@
         return captor.getValue();
     }
 
+    private BroadcastReceiver getPackageChangeReceiver() {
+        final ArgumentCaptor<BroadcastReceiver> captor =
+                ArgumentCaptor.forClass(BroadcastReceiver.class);
+        verify(mMockContext).registerReceiver(captor.capture(), any(), any(), any());
+        return captor.getValue();
+    }
+
     private Vcn startAndGetVcnInstance(ParcelUuid uuid) {
         mVcnMgmtSvc.setVcnConfig(uuid, TEST_VCN_CONFIG, TEST_PACKAGE_NAME);
         return mVcnMgmtSvc.getAllVcns().get(uuid);
@@ -392,7 +407,7 @@
         mTestLooper.moveTimeForward(
                 VcnManagementService.CARRIER_PRIVILEGES_LOST_TEARDOWN_DELAY_MS / 2);
         mTestLooper.dispatchAll();
-        mVcnMgmtSvc.clearVcnConfig(TEST_UUID_2);
+        mVcnMgmtSvc.clearVcnConfig(TEST_UUID_2, TEST_PACKAGE_NAME);
         final Vcn newInstance = startAndGetVcnInstance(TEST_UUID_2);
 
         // Verify that new instance was different, and the old one was torn down
@@ -406,6 +421,42 @@
     }
 
     @Test
+    public void testPackageChangeListenerRegistered() throws Exception {
+        verify(mMockContext).registerReceiver(any(BroadcastReceiver.class), argThat(filter -> {
+            return filter.hasAction(Intent.ACTION_PACKAGE_ADDED)
+                    && filter.hasAction(Intent.ACTION_PACKAGE_REPLACED)
+                    && filter.hasAction(Intent.ACTION_PACKAGE_REMOVED);
+        }), any(), any());
+    }
+
+    @Test
+    public void testPackageChangeListener_packageAdded() throws Exception {
+        final BroadcastReceiver receiver = getPackageChangeReceiver();
+
+        verify(mMockContext).registerReceiver(any(), argThat(filter -> {
+            return filter.hasAction(Intent.ACTION_PACKAGE_ADDED)
+                    && filter.hasAction(Intent.ACTION_PACKAGE_REPLACED)
+                    && filter.hasAction(Intent.ACTION_PACKAGE_REMOVED);
+        }), any(), any());
+
+        receiver.onReceive(mMockContext, new Intent(Intent.ACTION_PACKAGE_ADDED));
+        verify(mSubscriptionTracker).handleSubscriptionsChanged();
+    }
+
+    @Test
+    public void testPackageChangeListener_packageRemoved() throws Exception {
+        final BroadcastReceiver receiver = getPackageChangeReceiver();
+
+        verify(mMockContext).registerReceiver(any(), argThat(filter -> {
+            return filter.hasAction(Intent.ACTION_PACKAGE_REMOVED)
+                    && filter.hasAction(Intent.ACTION_PACKAGE_REMOVED);
+        }), any(), any());
+
+        receiver.onReceive(mMockContext, new Intent(Intent.ACTION_PACKAGE_REMOVED));
+        verify(mSubscriptionTracker).handleSubscriptionsChanged();
+    }
+
+    @Test
     public void testSetVcnConfigRequiresNonSystemServer() throws Exception {
         doReturn(Process.SYSTEM_UID).when(mMockDeps).getBinderCallingUid();
 
@@ -493,7 +544,7 @@
         doReturn(Process.SYSTEM_UID).when(mMockDeps).getBinderCallingUid();
 
         try {
-            mVcnMgmtSvc.clearVcnConfig(TEST_UUID_1);
+            mVcnMgmtSvc.clearVcnConfig(TEST_UUID_1, TEST_PACKAGE_NAME);
             fail("Expected IllegalStateException exception for system server");
         } catch (IllegalStateException expected) {
         }
@@ -506,7 +557,7 @@
                 .getBinderCallingUid();
 
         try {
-            mVcnMgmtSvc.clearVcnConfig(TEST_UUID_1);
+            mVcnMgmtSvc.clearVcnConfig(TEST_UUID_1, TEST_PACKAGE_NAME);
             fail("Expected security exception for non system user");
         } catch (SecurityException expected) {
         }
@@ -517,15 +568,24 @@
         setupMockedCarrierPrivilege(false);
 
         try {
-            mVcnMgmtSvc.clearVcnConfig(TEST_UUID_1);
+            mVcnMgmtSvc.clearVcnConfig(TEST_UUID_1, TEST_PACKAGE_NAME);
             fail("Expected security exception for missing carrier privileges");
         } catch (SecurityException expected) {
         }
     }
 
     @Test
+    public void testClearVcnConfigMismatchedPackages() throws Exception {
+        try {
+            mVcnMgmtSvc.clearVcnConfig(TEST_UUID_1, "IncorrectPackage");
+            fail("Expected security exception due to mismatched packages");
+        } catch (SecurityException expected) {
+        }
+    }
+
+    @Test
     public void testClearVcnConfig() throws Exception {
-        mVcnMgmtSvc.clearVcnConfig(TEST_UUID_1);
+        mVcnMgmtSvc.clearVcnConfig(TEST_UUID_1, TEST_PACKAGE_NAME);
         assertTrue(mVcnMgmtSvc.getConfigs().isEmpty());
         verify(mConfigReadWriteHelper).writeToDisk(any(PersistableBundle.class));
     }
@@ -536,7 +596,7 @@
         mVcnMgmtSvc.registerVcnStatusCallback(TEST_UUID_2, mMockStatusCallback, TEST_PACKAGE_NAME);
         verify(mMockStatusCallback).onVcnStatusChanged(VcnManager.VCN_STATUS_CODE_ACTIVE);
 
-        mVcnMgmtSvc.clearVcnConfig(TEST_UUID_2);
+        mVcnMgmtSvc.clearVcnConfig(TEST_UUID_2, TEST_PACKAGE_NAME);
 
         verify(mMockStatusCallback).onVcnStatusChanged(VcnManager.VCN_STATUS_CODE_NOT_CONFIGURED);
     }
@@ -565,7 +625,7 @@
         verify(vcnInstance).updateConfig(TEST_VCN_CONFIG);
 
         // Verify Vcn is stopped if it was already started
-        mVcnMgmtSvc.clearVcnConfig(TEST_UUID_2);
+        mVcnMgmtSvc.clearVcnConfig(TEST_UUID_2, TEST_PACKAGE_NAME);
         verify(vcnInstance).teardownAsynchronously();
     }
 
@@ -656,7 +716,7 @@
                     .setNetworkSpecifier(new TelephonyNetworkSpecifier(TEST_SUBSCRIPTION_ID));
         } else if (transport == TRANSPORT_WIFI) {
             WifiInfo wifiInfo = mock(WifiInfo.class);
-            when(wifiInfo.makeCopy(anyBoolean())).thenReturn(wifiInfo);
+            when(wifiInfo.makeCopy(anyLong())).thenReturn(wifiInfo);
             when(mMockDeps.getSubIdForWifiInfo(eq(wifiInfo))).thenReturn(TEST_SUBSCRIPTION_ID);
 
             ncBuilder
@@ -782,7 +842,7 @@
         mVcnMgmtSvc.setVcnConfig(TEST_UUID_2, TEST_VCN_CONFIG, TEST_PACKAGE_NAME);
         mVcnMgmtSvc.addVcnUnderlyingNetworkPolicyListener(mMockPolicyListener);
 
-        mVcnMgmtSvc.clearVcnConfig(TEST_UUID_2);
+        mVcnMgmtSvc.clearVcnConfig(TEST_UUID_2, TEST_PACKAGE_NAME);
 
         verify(mMockPolicyListener).onPolicyChanged();
     }
diff --git a/tests/vcn/java/com/android/server/vcn/VcnTest.java b/tests/vcn/java/com/android/server/vcn/VcnTest.java
index 4fa63d4..c853fc5 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnTest.java
@@ -29,6 +29,7 @@
 import static org.mockito.Mockito.doAnswer;
 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;
 
@@ -139,8 +140,7 @@
         mTestLooper.dispatchAll();
     }
 
-    @Test
-    public void testSubscriptionSnapshotUpdatesVcnGatewayConnections() {
+    private void verifyUpdateSubscriptionSnapshotNotifiesConnectionGateways(boolean isActive) {
         final NetworkRequestListener requestListener = verifyAndGetRequestListener();
         startVcnGatewayWithCapabilities(requestListener, TEST_CAPS[0]);
 
@@ -150,14 +150,27 @@
         final TelephonySubscriptionSnapshot updatedSnapshot =
                 mock(TelephonySubscriptionSnapshot.class);
 
+        mVcn.setIsActive(isActive);
+
         mVcn.updateSubscriptionSnapshot(updatedSnapshot);
         mTestLooper.dispatchAll();
 
         for (final VcnGatewayConnection gateway : gatewayConnections) {
-            verify(gateway).updateSubscriptionSnapshot(eq(updatedSnapshot));
+            verify(gateway, isActive ? times(1) : never())
+                    .updateSubscriptionSnapshot(eq(updatedSnapshot));
         }
     }
 
+    @Test
+    public void testSubscriptionSnapshotUpdatesVcnGatewayConnections() {
+        verifyUpdateSubscriptionSnapshotNotifiesConnectionGateways(true /* isActive */);
+    }
+
+    @Test
+    public void testSubscriptionSnapshotUpdatesVcnGatewayConnectionsWhileInactive() {
+        verifyUpdateSubscriptionSnapshotNotifiesConnectionGateways(false /* isActive */);
+    }
+
     private void triggerVcnRequestListeners(NetworkRequestListener requestListener) {
         for (final int[] caps : TEST_CAPS) {
             startVcnGatewayWithCapabilities(requestListener, caps);
@@ -187,7 +200,6 @@
             NetworkRequestListener requestListener,
             Set<VcnGatewayConnection> expectedGatewaysTornDown) {
         assertFalse(mVcn.isActive());
-        assertTrue(mVcn.getVcnGatewayConnections().isEmpty());
         for (final VcnGatewayConnection gatewayConnection : expectedGatewaysTornDown) {
             verify(gatewayConnection).teardownAsynchronously();
         }
@@ -238,6 +250,51 @@
     }
 
     @Test
+    public void testGatewayQuitWhileInactive() {
+        final NetworkRequestListener requestListener = verifyAndGetRequestListener();
+        final Set<VcnGatewayConnection> gatewayConnections =
+                new ArraySet<>(startGatewaysAndGetGatewayConnections(requestListener));
+
+        mVcn.teardownAsynchronously();
+        mTestLooper.dispatchAll();
+
+        final VcnGatewayStatusCallback statusCallback = mGatewayStatusCallbackCaptor.getValue();
+        statusCallback.onQuit();
+        mTestLooper.dispatchAll();
+
+        // Verify that the VCN requests the networkRequests be resent
+        assertEquals(1, mVcn.getVcnGatewayConnections().size());
+        verify(mVcnNetworkProvider, never()).resendAllRequests(requestListener);
+    }
+
+    @Test
+    public void testUpdateConfigReevaluatesGatewayConnections() {
+        final NetworkRequestListener requestListener = verifyAndGetRequestListener();
+        startGatewaysAndGetGatewayConnections(requestListener);
+        assertEquals(2, mVcn.getVcnGatewayConnectionConfigMap().size());
+
+        // Create VcnConfig with only one VcnGatewayConnectionConfig so a gateway connection is torn
+        // down
+        final VcnGatewayConnectionConfig activeConfig =
+                VcnGatewayConnectionConfigTest.buildTestConfigWithExposedCaps(TEST_CAPS[0]);
+        final VcnGatewayConnectionConfig removedConfig =
+                VcnGatewayConnectionConfigTest.buildTestConfigWithExposedCaps(TEST_CAPS[1]);
+        final VcnConfig updatedConfig =
+                new VcnConfig.Builder(mContext).addGatewayConnectionConfig(activeConfig).build();
+
+        mVcn.updateConfig(updatedConfig);
+        mTestLooper.dispatchAll();
+
+        final VcnGatewayConnection activeGatewayConnection =
+                mVcn.getVcnGatewayConnectionConfigMap().get(activeConfig);
+        final VcnGatewayConnection removedGatewayConnection =
+                mVcn.getVcnGatewayConnectionConfigMap().get(removedConfig);
+        verify(activeGatewayConnection, never()).teardownAsynchronously();
+        verify(removedGatewayConnection).teardownAsynchronously();
+        verify(mVcnNetworkProvider).resendAllRequests(requestListener);
+    }
+
+    @Test
     public void testUpdateConfigExitsSafeMode() {
         final NetworkRequestListener requestListener = verifyAndGetRequestListener();
         final Set<VcnGatewayConnection> gatewayConnections =
@@ -261,8 +318,8 @@
         verify(mVcnNetworkProvider, times(2)).registerListener(eq(requestListener));
         assertTrue(mVcn.isActive());
         for (final int[] caps : TEST_CAPS) {
-            // Expect each gateway connection created on initial startup, and again with new configs
-            verify(mDeps, times(2))
+            // Expect each gateway connection created only on initial startup
+            verify(mDeps)
                     .newVcnGatewayConnection(
                             eq(mVcnContext),
                             eq(TEST_SUB_GROUP),
@@ -271,4 +328,14 @@
                             any());
         }
     }
+
+    @Test
+    public void testIgnoreNetworkRequestWhileInactive() {
+        mVcn.setIsActive(false /* isActive */);
+
+        final NetworkRequestListener requestListener = verifyAndGetRequestListener();
+        triggerVcnRequestListeners(requestListener);
+
+        verify(mDeps, never()).newVcnGatewayConnection(any(), any(), any(), any(), any());
+    }
 }
diff --git a/tools/aapt2/Debug.cpp b/tools/aapt2/Debug.cpp
index 82da249..351e420 100644
--- a/tools/aapt2/Debug.cpp
+++ b/tools/aapt2/Debug.cpp
@@ -256,53 +256,35 @@
 
 void Debug::PrintTable(const ResourceTable& table, const DebugPrintTableOptions& options,
                        Printer* printer) {
-  for (const auto& package : table.packages) {
-    ValueHeadlinePrinter headline_printer(package->name, printer);
-    ValueBodyPrinter body_printer(package->name, printer);
+  const auto table_view = table.GetPartitionedView();
+  for (const auto& package : table_view.packages) {
+    ValueHeadlinePrinter headline_printer(package.name, printer);
+    ValueBodyPrinter body_printer(package.name, printer);
 
     printer->Print("Package name=");
-    printer->Print(package->name);
-    if (package->id) {
-      printer->Print(StringPrintf(" id=%02x", package->id.value()));
+    printer->Print(package.name);
+    if (package.id) {
+      printer->Print(StringPrintf(" id=%02x", package.id.value()));
     }
     printer->Println();
 
     printer->Indent();
-    for (const auto& type : package->types) {
+    for (const auto& type : package.types) {
       printer->Print("type ");
-      printer->Print(to_string(type->type));
-      if (type->id) {
-        printer->Print(StringPrintf(" id=%02x", type->id.value()));
+      printer->Print(to_string(type.type));
+      if (type.id) {
+        printer->Print(StringPrintf(" id=%02x", type.id.value()));
       }
-      printer->Println(StringPrintf(" entryCount=%zd", type->entries.size()));
-
-      std::vector<const ResourceEntry*> sorted_entries;
-      for (const auto& entry : type->entries) {
-        auto iter = std::lower_bound(
-            sorted_entries.begin(), sorted_entries.end(), entry.get(),
-            [](const ResourceEntry* a, const ResourceEntry* b) -> bool {
-              if (a->id && b->id) {
-                return a->id.value() < b->id.value();
-              } else if (a->id) {
-                return true;
-              } else {
-                return false;
-              }
-            });
-        sorted_entries.insert(iter, entry.get());
-      }
+      printer->Println(StringPrintf(" entryCount=%zd", type.entries.size()));
 
       printer->Indent();
-      for (const ResourceEntry* entry : sorted_entries) {
-        const ResourceId id(package->id.value_or_default(0), type->id.value_or_default(0),
-                            entry->id.value_or_default(0));
-
+      for (const ResourceEntry* entry : type.entries) {
         printer->Print("resource ");
-        printer->Print(id.to_string());
+        printer->Print(entry->id.value_or_default(0).to_string());
         printer->Print(" ");
 
         // Write the name without the package (this is obvious and too verbose).
-        printer->Print(to_string(type->type));
+        printer->Print(to_string(type.type));
         printer->Print("/");
         printer->Print(entry->name);
 
diff --git a/tools/aapt2/LoadedApk.cpp b/tools/aapt2/LoadedApk.cpp
index e930b47..830bc5f 100644
--- a/tools/aapt2/LoadedApk.cpp
+++ b/tools/aapt2/LoadedApk.cpp
@@ -113,7 +113,7 @@
     }
 
     std::string error;
-    table = util::make_unique<ResourceTable>(/** validate_resources **/ false);
+    table = util::make_unique<ResourceTable>(ResourceTable::Validation::kDisabled);
     if (!DeserializeTableFromPb(pb_table, collection.get(), table.get(), &error)) {
       diag->Error(DiagMessage(source)
                   << "failed to deserialize " << kProtoResourceTablePath << ": " << error);
@@ -157,7 +157,7 @@
 
   io::IFile* table_file = collection->FindFile(kApkResourceTablePath);
   if (table_file != nullptr) {
-    table = util::make_unique<ResourceTable>(/** validate_resources **/ false);
+    table = util::make_unique<ResourceTable>(ResourceTable::Validation::kDisabled);
     std::unique_ptr<io::IData> data = table_file->OpenAsData();
     if (data == nullptr) {
       diag->Error(DiagMessage(source) << "failed to open " << kApkResourceTablePath);
diff --git a/tools/aapt2/Resource.h b/tools/aapt2/Resource.h
index 8fe0eb3..cf93870 100644
--- a/tools/aapt2/Resource.h
+++ b/tools/aapt2/Resource.h
@@ -138,7 +138,7 @@
   uint32_t id;
 
   ResourceId();
-  ResourceId(const ResourceId& rhs);
+  ResourceId(const ResourceId& rhs) = default;
   ResourceId(uint32_t res_id);  // NOLINT(google-explicit-constructor)
   ResourceId(uint8_t p, uint8_t t, uint16_t e);
 
@@ -222,8 +222,6 @@
 
 inline ResourceId::ResourceId() : id(0) {}
 
-inline ResourceId::ResourceId(const ResourceId& rhs) : id(rhs.id) {}
-
 inline ResourceId::ResourceId(uint32_t res_id) : id(res_id) {}
 
 inline ResourceId::ResourceId(uint8_t p, uint8_t t, uint16_t e)
diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp
index 3d9be59..24c60b7 100644
--- a/tools/aapt2/ResourceParser.cpp
+++ b/tools/aapt2/ResourceParser.cpp
@@ -42,6 +42,10 @@
 using android::idmap2::policy::kPolicyStringToFlag;
 
 namespace aapt {
+namespace {
+constexpr const char* kPublicGroupTag = "public-group";
+constexpr const char* kStagingPublicGroupTag = "staging-public-group";
+}  // namespace
 
 constexpr const char* sXliffNamespaceUri = "urn:oasis:names:tc:xliff:document:1.2";
 
@@ -102,6 +106,7 @@
 
   ResourceId id;
   Visibility::Level visibility_level = Visibility::Level::kUndefined;
+  bool staged_api = false;
   bool allow_new = false;
   Maybe<OverlayableItem> overlayable_item;
 
@@ -118,43 +123,44 @@
     res->comment = trimmed_comment.to_string();
   }
 
+  NewResourceBuilder res_builder(res->name);
   if (res->visibility_level != Visibility::Level::kUndefined) {
     Visibility visibility;
     visibility.level = res->visibility_level;
+    visibility.staged_api = res->staged_api;
     visibility.source = res->source;
     visibility.comment = res->comment;
-    if (!table->SetVisibilityWithId(res->name, visibility, res->id, diag)) {
-      return false;
-    }
+    res_builder.SetVisibility(visibility);
+  }
+
+  if (res->id.is_valid()) {
+    res_builder.SetId(res->id);
   }
 
   if (res->allow_new) {
     AllowNew allow_new;
     allow_new.source = res->source;
     allow_new.comment = res->comment;
-    if (!table->SetAllowNew(res->name, allow_new, diag)) {
-      return false;
-    }
+    res_builder.SetAllowNew(allow_new);
   }
 
   if (res->overlayable_item) {
-    if (!table->SetOverlayable(res->name, res->overlayable_item.value(), diag)) {
-      return false;
-    }
+    res_builder.SetOverlayable(res->overlayable_item.value());
   }
 
   if (res->value != nullptr) {
     // Attach the comment, source and config to the value.
     res->value->SetComment(std::move(res->comment));
     res->value->SetSource(std::move(res->source));
-
-    if (!table->AddResourceWithId(res->name, res->id, res->config, res->product,
-                                  std::move(res->value), diag)) {
-      return false;
-    }
+    res_builder.SetValue(std::move(res->value), res->config, res->product);
   }
 
   bool error = false;
+  if (!res->name.entry.empty()) {
+    if (!table->AddResource(res_builder.Build(), diag)) {
+      return false;
+    }
+  }
   for (ParsedResource& child : res->child_resources) {
     error |= !AddResourcesToTable(table, diag, &child);
   }
@@ -525,6 +531,7 @@
       {"plurals", std::mem_fn(&ResourceParser::ParsePlural)},
       {"public", std::mem_fn(&ResourceParser::ParsePublic)},
       {"public-group", std::mem_fn(&ResourceParser::ParsePublicGroup)},
+      {"staging-public-group", std::mem_fn(&ResourceParser::ParseStagingPublicGroup)},
       {"string-array", std::mem_fn(&ResourceParser::ParseStringArray)},
       {"style", std::bind(&ResourceParser::ParseStyle, std::placeholders::_1, ResourceType::kStyle,
                           std::placeholders::_2, std::placeholders::_3)},
@@ -653,7 +660,8 @@
     const auto bag_iter = elToBagMap.find(resource_type);
     if (bag_iter != elToBagMap.end()) {
       // Ensure we have a name (unless this is a <public-group> or <overlayable>).
-      if (resource_type != "public-group" && resource_type != "overlayable") {
+      if (resource_type != kPublicGroupTag && resource_type != kStagingPublicGroupTag &&
+          resource_type != "overlayable") {
         if (!maybe_name) {
           diag_->Error(DiagMessage(out_resource->source)
                        << "<" << parser->element_name() << "> missing 'name' attribute");
@@ -751,7 +759,7 @@
     // table.
     std::unique_ptr<Id> id = util::make_unique<Id>();
     id->SetSource(source_.WithLine(begin_xml_line));
-    table_->AddResource(name, {}, {}, std::move(id), diag_);
+    table_->AddResource(NewResourceBuilder(name).SetValue(std::move(id)).Build(), diag_);
   };
 
   // Process the raw value.
@@ -890,54 +898,45 @@
   return true;
 }
 
-bool ResourceParser::ParsePublicGroup(xml::XmlPullParser* parser, ParsedResource* out_resource) {
-  if (options_.visibility) {
-    diag_->Error(DiagMessage(out_resource->source)
-                 << "<public-group> tag not allowed with --visibility flag");
-    return false;
-  }
-
+template <typename Func>
+bool static ParseGroupImpl(xml::XmlPullParser* parser, ParsedResource* out_resource,
+                           const char* tag_name, IDiagnostics* diag, Func&& func) {
   if (out_resource->config != ConfigDescription::DefaultConfig()) {
-    diag_->Warn(DiagMessage(out_resource->source)
-                << "ignoring configuration '" << out_resource->config
-                << "' for <public-group> tag");
+    diag->Warn(DiagMessage(out_resource->source)
+               << "ignoring configuration '" << out_resource->config << "' for <" << tag_name
+               << "> tag");
   }
 
   Maybe<StringPiece> maybe_type = xml::FindNonEmptyAttribute(parser, "type");
   if (!maybe_type) {
-    diag_->Error(DiagMessage(out_resource->source)
-                 << "<public-group> must have a 'type' attribute");
+    diag->Error(DiagMessage(out_resource->source)
+                << "<" << tag_name << "> must have a 'type' attribute");
     return false;
   }
 
   const ResourceType* parsed_type = ParseResourceType(maybe_type.value());
   if (!parsed_type) {
-    diag_->Error(DiagMessage(out_resource->source) << "invalid resource type '"
-                                                   << maybe_type.value()
-                                                   << "' in <public-group>");
+    diag->Error(DiagMessage(out_resource->source)
+                << "invalid resource type '" << maybe_type.value() << "' in <" << tag_name << ">");
     return false;
   }
 
-  Maybe<StringPiece> maybe_id_str =
-      xml::FindNonEmptyAttribute(parser, "first-id");
+  Maybe<StringPiece> maybe_id_str = xml::FindNonEmptyAttribute(parser, "first-id");
   if (!maybe_id_str) {
-    diag_->Error(DiagMessage(out_resource->source)
-                 << "<public-group> must have a 'first-id' attribute");
+    diag->Error(DiagMessage(out_resource->source)
+                << "<" << tag_name << "> must have a 'first-id' attribute");
     return false;
   }
 
-  Maybe<ResourceId> maybe_id =
-      ResourceUtils::ParseResourceId(maybe_id_str.value());
+  Maybe<ResourceId> maybe_id = ResourceUtils::ParseResourceId(maybe_id_str.value());
   if (!maybe_id) {
-    diag_->Error(DiagMessage(out_resource->source) << "invalid resource ID '"
-                                                   << maybe_id_str.value()
-                                                   << "' in <public-group>");
+    diag->Error(DiagMessage(out_resource->source)
+                << "invalid resource ID '" << maybe_id_str.value() << "' in <" << tag_name << ">");
     return false;
   }
 
-  ResourceId next_id = maybe_id.value();
-
   std::string comment;
+  ResourceId next_id = maybe_id.value();
   bool error = false;
   const size_t depth = parser->depth();
   while (xml::XmlPullParser::NextChildNode(parser, depth)) {
@@ -949,53 +948,72 @@
       continue;
     }
 
-    const Source item_source = source_.WithLine(parser->line_number());
+    const Source item_source = out_resource->source.WithLine(parser->line_number());
     const std::string& element_namespace = parser->element_namespace();
     const std::string& element_name = parser->element_name();
     if (element_namespace.empty() && element_name == "public") {
-      Maybe<StringPiece> maybe_name =
-          xml::FindNonEmptyAttribute(parser, "name");
+      auto maybe_name = xml::FindNonEmptyAttribute(parser, "name");
       if (!maybe_name) {
-        diag_->Error(DiagMessage(item_source)
-                     << "<public> must have a 'name' attribute");
+        diag->Error(DiagMessage(item_source) << "<public> must have a 'name' attribute");
         error = true;
         continue;
       }
 
       if (xml::FindNonEmptyAttribute(parser, "id")) {
-        diag_->Error(DiagMessage(item_source)
-                     << "'id' is ignored within <public-group>");
+        diag->Error(DiagMessage(item_source) << "'id' is ignored within <" << tag_name << ">");
         error = true;
         continue;
       }
 
       if (xml::FindNonEmptyAttribute(parser, "type")) {
-        diag_->Error(DiagMessage(item_source)
-                     << "'type' is ignored within <public-group>");
+        diag->Error(DiagMessage(item_source) << "'type' is ignored within <" << tag_name << ">");
         error = true;
         continue;
       }
 
-      ParsedResource child_resource;
-      child_resource.name.type = *parsed_type;
-      child_resource.name.entry = maybe_name.value().to_string();
-      child_resource.id = next_id;
-      // NOLINTNEXTLINE(bugprone-use-after-move) move+reset comment
-      child_resource.comment = std::move(comment);
-      child_resource.source = item_source;
-      child_resource.visibility_level = Visibility::Level::kPublic;
-      out_resource->child_resources.push_back(std::move(child_resource));
+      ParsedResource& entry_res = out_resource->child_resources.emplace_back(ParsedResource{
+          .name = ResourceName{{}, *parsed_type, maybe_name.value().to_string()},
+          .source = item_source,
+          .id = next_id,
+          .comment = std::move(comment),
+      });
 
-      next_id.id += 1;
+      // Execute group specific code.
+      func(entry_res, next_id);
 
+      next_id.id++;
     } else if (!ShouldIgnoreElement(element_namespace, element_name)) {
-      diag_->Error(DiagMessage(item_source) << ":" << element_name << ">");
+      diag->Error(DiagMessage(item_source) << ":" << element_name << ">");
       error = true;
     }
   }
   return !error;
 }
 
+bool ResourceParser::ParseStagingPublicGroup(xml::XmlPullParser* parser,
+                                             ParsedResource* out_resource) {
+  return ParseGroupImpl(parser, out_resource, kStagingPublicGroupTag, diag_,
+                        [](ParsedResource& parsed_entry, ResourceId id) {
+                          parsed_entry.id = id;
+                          parsed_entry.staged_api = true;
+                          parsed_entry.visibility_level = Visibility::Level::kPublic;
+                        });
+}
+
+bool ResourceParser::ParsePublicGroup(xml::XmlPullParser* parser, ParsedResource* out_resource) {
+  if (options_.visibility) {
+    diag_->Error(DiagMessage(out_resource->source)
+                 << "<" << kPublicGroupTag << "> tag not allowed with --visibility flag");
+    return false;
+  }
+
+  return ParseGroupImpl(parser, out_resource, kPublicGroupTag, diag_,
+                        [](ParsedResource& parsed_entry, ResourceId id) {
+                          parsed_entry.id = id;
+                          parsed_entry.visibility_level = Visibility::Level::kPublic;
+                        });
+}
+
 bool ResourceParser::ParseSymbolImpl(xml::XmlPullParser* parser,
                                      ParsedResource* out_resource) {
   Maybe<StringPiece> maybe_type = xml::FindNonEmptyAttribute(parser, "type");
diff --git a/tools/aapt2/ResourceParser.h b/tools/aapt2/ResourceParser.h
index 9d3ecc8..af0db8c 100644
--- a/tools/aapt2/ResourceParser.h
+++ b/tools/aapt2/ResourceParser.h
@@ -99,6 +99,7 @@
 
   bool ParsePublic(xml::XmlPullParser* parser, ParsedResource* out_resource);
   bool ParsePublicGroup(xml::XmlPullParser* parser, ParsedResource* out_resource);
+  bool ParseStagingPublicGroup(xml::XmlPullParser* parser, ParsedResource* out_resource);
   bool ParseSymbolImpl(xml::XmlPullParser* parser, ParsedResource* out_resource);
   bool ParseSymbol(xml::XmlPullParser* parser, ParsedResource* out_resource);
   bool ParseOverlayable(xml::XmlPullParser* parser, ParsedResource* out_resource);
diff --git a/tools/aapt2/ResourceParser_test.cpp b/tools/aapt2/ResourceParser_test.cpp
index 9b70079..4a509be 100644
--- a/tools/aapt2/ResourceParser_test.cpp
+++ b/tools/aapt2/ResourceParser_test.cpp
@@ -831,25 +831,38 @@
 
   Maybe<ResourceTable::SearchResult> result = table_.FindResource(test::ParseNameOrDie("attr/foo"));
   ASSERT_TRUE(result);
-
-  ASSERT_TRUE(result.value().package->id);
-  ASSERT_TRUE(result.value().type->id);
   ASSERT_TRUE(result.value().entry->id);
-  ResourceId actual_id(result.value().package->id.value(),
-                       result.value().type->id.value(),
-                       result.value().entry->id.value());
-  EXPECT_THAT(actual_id, Eq(ResourceId(0x01010040)));
+  EXPECT_THAT(result.value().entry->id.value(), Eq(ResourceId(0x01010040)));
+
+  result = table_.FindResource(test::ParseNameOrDie("attr/bar"));
+  ASSERT_TRUE(result);
+  ASSERT_TRUE(result.value().entry->id);
+  EXPECT_THAT(result.value().entry->id.value(), Eq(ResourceId(0x01010041)));
+}
+
+TEST_F(ResourceParserTest, StagingPublicGroup) {
+  std::string input = R"(
+      <staging-public-group type="attr" first-id="0x01ff0049">
+        <public name="foo" />
+        <public name="bar" />
+      </staging-public-group>)";
+  ASSERT_TRUE(TestParse(input));
+
+  Maybe<ResourceTable::SearchResult> result = table_.FindResource(test::ParseNameOrDie("attr/foo"));
+  ASSERT_TRUE(result);
+
+  ASSERT_TRUE(result.value().entry->id);
+  EXPECT_THAT(result.value().entry->id.value(), Eq(ResourceId(0x01ff0049)));
+  EXPECT_THAT(result.value().entry->visibility.level, Eq(Visibility::Level::kPublic));
+  EXPECT_TRUE(result.value().entry->visibility.staged_api);
 
   result = table_.FindResource(test::ParseNameOrDie("attr/bar"));
   ASSERT_TRUE(result);
 
-  ASSERT_TRUE(result.value().package->id);
-  ASSERT_TRUE(result.value().type->id);
   ASSERT_TRUE(result.value().entry->id);
-  actual_id = ResourceId(result.value().package->id.value(),
-                         result.value().type->id.value(),
-                         result.value().entry->id.value());
-  EXPECT_THAT(actual_id, Eq(ResourceId(0x01010041)));
+  EXPECT_THAT(result.value().entry->id.value(), Eq(ResourceId(0x01ff004a)));
+  EXPECT_THAT(result.value().entry->visibility.level, Eq(Visibility::Level::kPublic));
+  EXPECT_TRUE(result.value().entry->visibility.staged_api);
 }
 
 TEST_F(ResourceParserTest, StrongestSymbolVisibilityWins) {
diff --git a/tools/aapt2/ResourceTable.cpp b/tools/aapt2/ResourceTable.cpp
index e0a9a31e..27f7bdd 100644
--- a/tools/aapt2/ResourceTable.cpp
+++ b/tools/aapt2/ResourceTable.cpp
@@ -18,20 +18,18 @@
 
 #include <algorithm>
 #include <memory>
-#include <string>
 #include <tuple>
 
 #include "android-base/logging.h"
-#include "android-base/stringprintf.h"
 #include "androidfw/ConfigDescription.h"
 #include "androidfw/ResourceTypes.h"
 
-#include "Debug.h"
 #include "NameMangler.h"
+#include "ResourceUtils.h"
 #include "ResourceValues.h"
 #include "ValueVisitor.h"
-#include "trace/TraceBuffer.h"
 #include "text/Unicode.h"
+#include "trace/TraceBuffer.h"
 #include "util/Util.h"
 
 using ::aapt::text::IsValidResourceEntryName;
@@ -43,135 +41,97 @@
 
 const char* Overlayable::kActorScheme = "overlay";
 
-static bool less_than_type_and_id(const std::unique_ptr<ResourceTableType>& lhs,
-                                  const std::pair<ResourceType, Maybe<uint8_t>>& rhs) {
-  return lhs->type < rhs.first || (lhs->type == rhs.first && rhs.second && lhs->id < rhs.second);
+namespace {
+bool less_than_type(const std::unique_ptr<ResourceTableType>& lhs, ResourceType rhs) {
+  return lhs->type < rhs;
 }
 
 template <typename T>
-static bool less_than_struct_with_name(const std::unique_ptr<T>& lhs, const StringPiece& rhs) {
+bool less_than_struct_with_name(const std::unique_ptr<T>& lhs, const StringPiece& rhs) {
   return lhs->name.compare(0, lhs->name.size(), rhs.data(), rhs.size()) < 0;
 }
 
 template <typename T>
-static bool less_than_struct_with_name_and_id(const std::unique_ptr<T>& lhs,
-                                              const std::pair<StringPiece, Maybe<uint16_t>>& rhs) {
-  int name_cmp = lhs->name.compare(0, lhs->name.size(), rhs.first.data(), rhs.first.size());
-  return name_cmp < 0 || (name_cmp == 0 && rhs.second && lhs->id < rhs.second);
+bool greater_than_struct_with_name(const StringPiece& lhs, const std::unique_ptr<T>& rhs) {
+  return rhs->name.compare(0, rhs->name.size(), lhs.data(), lhs.size()) > 0;
 }
 
-ResourceTablePackage* ResourceTable::FindPackage(const StringPiece& name) const {
-  const auto last = packages.end();
-  auto iter = std::lower_bound(packages.begin(), last, name,
-                               less_than_struct_with_name<ResourceTablePackage>);
-  if (iter != last && name == (*iter)->name) {
-    return iter->get();
+template <typename T>
+struct NameEqualRange {
+  bool operator()(const std::unique_ptr<T>& lhs, const StringPiece& rhs) const {
+    return less_than_struct_with_name<T>(lhs, rhs);
   }
-  return nullptr;
+  bool operator()(const StringPiece& lhs, const std::unique_ptr<T>& rhs) const {
+    return greater_than_struct_with_name<T>(lhs, rhs);
+  }
+};
+
+template <typename T, typename U>
+bool less_than_struct_with_name_and_id(const T& lhs,
+                                       const std::pair<std::string_view, Maybe<U>>& rhs) {
+  if (lhs.id != rhs.second) {
+    return lhs.id < rhs.second;
+  }
+  return lhs.name.compare(0, lhs.name.size(), rhs.first.data(), rhs.first.size()) < 0;
 }
 
-ResourceTablePackage* ResourceTable::FindPackageById(uint8_t id) const {
-  for (auto& package : packages) {
-    if (package->id && package->id.value() == id) {
-      return package.get();
-    }
-  }
-  return nullptr;
+template <typename T, typename Func, typename Elements>
+T* FindElementsRunAction(const android::StringPiece& name, Elements& entries, Func action) {
+  const auto iter =
+      std::lower_bound(entries.begin(), entries.end(), name, less_than_struct_with_name<T>);
+  const bool found = iter != entries.end() && name == (*iter)->name;
+  return action(found, iter);
 }
 
-ResourceTablePackage* ResourceTable::CreatePackage(const StringPiece& name, Maybe<uint8_t> id) {
-  TRACE_CALL();
-  ResourceTablePackage* package = FindOrCreatePackage(name);
-  if (id && !package->id) {
-    package->id = id;
-    return package;
-  }
+}  // namespace
 
-  if (id && package->id && package->id.value() != id.value()) {
-    return nullptr;
-  }
-  return package;
+ResourceTable::ResourceTable(ResourceTable::Validation validation) : validation_(validation) {
 }
 
-ResourceTablePackage* ResourceTable::CreatePackageAllowingDuplicateNames(const StringPiece& name,
-                                                                         const Maybe<uint8_t> id) {
-  const auto last = packages.end();
-  auto iter = std::lower_bound(packages.begin(), last, std::make_pair(name, id),
-                               less_than_struct_with_name_and_id<ResourceTablePackage>);
-
-  if (iter != last && name == (*iter)->name && id == (*iter)->id) {
-    return iter->get();
-  }
-
-  std::unique_ptr<ResourceTablePackage> new_package = util::make_unique<ResourceTablePackage>();
-  new_package->name = name.to_string();
-  new_package->id = id;
-  return packages.emplace(iter, std::move(new_package))->get();
+ResourceTablePackage* ResourceTable::FindPackage(const android::StringPiece& name) const {
+  return FindElementsRunAction<ResourceTablePackage>(
+      name, packages, [&](bool found, auto& iter) { return found ? iter->get() : nullptr; });
 }
 
-ResourceTablePackage* ResourceTable::FindOrCreatePackage(const StringPiece& name) {
-  const auto last = packages.end();
-  auto iter = std::lower_bound(packages.begin(), last, name,
-                               less_than_struct_with_name<ResourceTablePackage>);
-  if (iter != last && name == (*iter)->name) {
-    return iter->get();
-  }
-
-  std::unique_ptr<ResourceTablePackage> new_package = util::make_unique<ResourceTablePackage>();
-  new_package->name = name.to_string();
-  return packages.emplace(iter, std::move(new_package))->get();
+ResourceTablePackage* ResourceTable::FindOrCreatePackage(const android::StringPiece& name) {
+  return FindElementsRunAction<ResourceTablePackage>(name, packages, [&](bool found, auto& iter) {
+    return found ? iter->get() : packages.emplace(iter, new ResourceTablePackage(name))->get();
+  });
 }
 
-ResourceTableType* ResourceTablePackage::FindType(ResourceType type, const Maybe<uint8_t> id) {
-  const auto last = types.end();
-  auto iter = std::lower_bound(types.begin(), last, std::make_pair(type, id),
-                               less_than_type_and_id);
-  if (iter != last && (*iter)->type == type && (!id || id == (*iter)->id)) {
-    return iter->get();
-  }
-  return nullptr;
+template <typename Func, typename Elements>
+static ResourceTableType* FindTypeRunAction(ResourceType type, Elements& entries, Func action) {
+  const auto iter = std::lower_bound(entries.begin(), entries.end(), type, less_than_type);
+  const bool found = iter != entries.end() && type == (*iter)->type;
+  return action(found, iter);
 }
 
-ResourceTableType* ResourceTablePackage::FindOrCreateType(ResourceType type,
-                                                          const Maybe<uint8_t> id) {
-  const auto last = types.end();
-  auto iter = std::lower_bound(types.begin(), last, std::make_pair(type, id),
-                               less_than_type_and_id);
-  if (iter != last && (*iter)->type == type && (!id || id == (*iter)->id)) {
-    return iter->get();
-  }
-
-  auto new_type = new ResourceTableType(type);
-  new_type->id = id;
-  return types.emplace(iter, std::move(new_type))->get();
+ResourceTableType* ResourceTablePackage::FindType(ResourceType type) const {
+  return FindTypeRunAction(type, types,
+                           [&](bool found, auto& iter) { return found ? iter->get() : nullptr; });
 }
 
-ResourceEntry* ResourceTableType::FindEntry(const StringPiece& name, const Maybe<uint16_t> id) {
-  const auto last = entries.end();
-  auto iter = std::lower_bound(entries.begin(), last, std::make_pair(name, id),
-      less_than_struct_with_name_and_id<ResourceEntry>);
-  if (iter != last && name == (*iter)->name && (!id || id == (*iter)->id)) {
-    return iter->get();
-  }
-  return nullptr;
+ResourceTableType* ResourceTablePackage::FindOrCreateType(ResourceType type) {
+  return FindTypeRunAction(type, types, [&](bool found, auto& iter) {
+    return found ? iter->get() : types.emplace(iter, new ResourceTableType(type))->get();
+  });
 }
 
-ResourceEntry* ResourceTableType::FindOrCreateEntry(const StringPiece& name,
-                                                    const Maybe<uint16_t > id) {
-  auto last = entries.end();
-  auto iter = std::lower_bound(entries.begin(), last, std::make_pair(name, id),
-                               less_than_struct_with_name_and_id<ResourceEntry>);
-  if (iter != last && name == (*iter)->name && (!id || id == (*iter)->id)) {
-    return iter->get();
-  }
-
-  auto new_entry = new ResourceEntry(name);
-  new_entry->id = id;
-  return entries.emplace(iter, std::move(new_entry))->get();
+ResourceEntry* ResourceTableType::CreateEntry(const android::StringPiece& name) {
+  return FindElementsRunAction<ResourceEntry>(name, entries, [&](bool found, auto& iter) {
+    return entries.emplace(iter, new ResourceEntry(name))->get();
+  });
 }
 
-ResourceConfigValue* ResourceEntry::FindValue(const ConfigDescription& config) {
-  return FindValue(config, StringPiece());
+ResourceEntry* ResourceTableType::FindEntry(const android::StringPiece& name) const {
+  return FindElementsRunAction<ResourceEntry>(
+      name, entries, [&](bool found, auto& iter) { return found ? iter->get() : nullptr; });
+}
+
+ResourceEntry* ResourceTableType::FindOrCreateEntry(const android::StringPiece& name) {
+  return FindElementsRunAction<ResourceEntry>(name, entries, [&](bool found, auto& iter) {
+    return found ? iter->get() : entries.emplace(iter, new ResourceEntry(name))->get();
+  });
 }
 
 struct ConfigKey {
@@ -188,7 +148,20 @@
 }
 
 ResourceConfigValue* ResourceEntry::FindValue(const ConfigDescription& config,
-                                              const StringPiece& product) {
+                                              android::StringPiece product) {
+  auto iter = std::lower_bound(values.begin(), values.end(), ConfigKey{&config, product},
+                               lt_config_key_ref);
+  if (iter != values.end()) {
+    ResourceConfigValue* value = iter->get();
+    if (value->config == config && StringPiece(value->product) == product) {
+      return value;
+    }
+  }
+  return nullptr;
+}
+
+const ResourceConfigValue* ResourceEntry::FindValue(const android::ConfigDescription& config,
+                                                    android::StringPiece product) const {
   auto iter = std::lower_bound(values.begin(), values.end(), ConfigKey{&config, product},
                                lt_config_key_ref);
   if (iter != values.end()) {
@@ -323,303 +296,242 @@
   return CollisionResult::kConflict;
 }
 
-ResourceTable::CollisionResult ResourceTable::IgnoreCollision(Value* /** existing **/,
-                                                              Value* /** incoming **/) {
-  return CollisionResult::kKeepBoth;
-}
-
-static StringPiece ResourceNameValidator(const StringPiece& name) {
-  if (!IsValidResourceEntryName(name)) {
-    return name;
-  }
-  return {};
-}
-
-static StringPiece SkipNameValidator(const StringPiece& /*name*/) {
-  return {};
-}
-
-bool ResourceTable::AddResource(const ResourceNameRef& name,
-                                const ConfigDescription& config,
-                                const StringPiece& product,
-                                std::unique_ptr<Value> value,
-                                IDiagnostics* diag) {
-  return AddResourceImpl(name, ResourceId{}, config, product, std::move(value),
-                         (validate_resources_ ? ResourceNameValidator : SkipNameValidator),
-                         (validate_resources_ ? ResolveValueCollision : IgnoreCollision), diag);
-}
-
-bool ResourceTable::AddResourceWithId(const ResourceNameRef& name, const ResourceId& res_id,
-                                      const ConfigDescription& config, const StringPiece& product,
-                                      std::unique_ptr<Value> value, IDiagnostics* diag) {
-  return AddResourceImpl(name, res_id, config, product, std::move(value),
-                         (validate_resources_ ? ResourceNameValidator : SkipNameValidator),
-                         (validate_resources_ ? ResolveValueCollision : IgnoreCollision), diag);
-}
-
-bool ResourceTable::AddResourceMangled(const ResourceNameRef& name, const ConfigDescription& config,
-                                       const StringPiece& product, std::unique_ptr<Value> value,
-                                       IDiagnostics* diag) {
-  return AddResourceImpl(name, ResourceId{}, config, product, std::move(value), SkipNameValidator,
-                         (validate_resources_ ? ResolveValueCollision : IgnoreCollision), diag);
-}
-
-bool ResourceTable::AddResourceWithIdMangled(const ResourceNameRef& name, const ResourceId& id,
-                                             const ConfigDescription& config,
-                                             const StringPiece& product,
-                                             std::unique_ptr<Value> value, IDiagnostics* diag) {
-  return AddResourceImpl(name, id, config, product, std::move(value), SkipNameValidator,
-                         (validate_resources_ ? ResolveValueCollision : IgnoreCollision), diag);
-}
-
-bool ResourceTable::ValidateName(NameValidator name_validator, const ResourceNameRef& name,
-                                 const Source& source, IDiagnostics* diag) {
-  const StringPiece bad_char = name_validator(name.entry);
-  if (!bad_char.empty()) {
-    diag->Error(DiagMessage(source) << "resource '" << name << "' has invalid entry name '"
-                                    << name.entry << "'. Invalid character '" << bad_char << "'");
-    return false;
-  }
-  return true;
-}
-
-bool ResourceTable::AddResourceImpl(const ResourceNameRef& name, const ResourceId& res_id,
-                                    const ConfigDescription& config, const StringPiece& product,
-                                    std::unique_ptr<Value> value, NameValidator name_validator,
-                                    const CollisionResolverFunc& conflict_resolver,
-                                    IDiagnostics* diag) {
-  CHECK(value != nullptr);
-  CHECK(diag != nullptr);
-
-  const Source& source = value->GetSource();
-  if (!ValidateName(name_validator, name, source, diag)) {
-    return false;
+template <typename T, typename Comparer>
+struct SortedVectorInserter : public Comparer {
+  std::pair<bool, typename std::vector<T>::iterator> LowerBound(std::vector<T>& el,
+                                                                const T& value) {
+    auto it = std::lower_bound(el.begin(), el.end(), value, [&](auto& lhs, auto& rhs) {
+      return Comparer::operator()(lhs, rhs);
+    });
+    bool found =
+        it != el.end() && !Comparer::operator()(*it, value) && !Comparer::operator()(value, *it);
+    return std::make_pair(found, it);
   }
 
-  // Check for package names appearing twice with two different package ids
-  ResourceTablePackage* package = FindOrCreatePackage(name.package);
-  if (res_id.is_valid() && package->id && package->id.value() != res_id.package_id()) {
-    diag->Error(DiagMessage(source)
-                    << "trying to add resource '" << name << "' with ID " << res_id
-                    << " but package '" << package->name << "' already has ID "
-                    << StringPrintf("%02x", package->id.value()));
-    return false;
+  T* Insert(std::vector<T>& el, T&& value) {
+    auto [found, it] = LowerBound(el, value);
+    if (found) {
+      return &*it;
+    }
+    return &*el.insert(it, std::move(value));
   }
+};
 
-  // Whether or not to error on duplicate resources
-  bool check_id = validate_resources_ && res_id.is_valid();
-  // Whether or not to create a duplicate resource if the id does not match
-  bool use_id = !validate_resources_ && res_id.is_valid();
-
-  ResourceTableType* type = package->FindOrCreateType(name.type, use_id ? res_id.type_id()
-                                                                        : Maybe<uint8_t>());
-
-  // Check for types appearing twice with two different type ids
-  if (check_id && type->id && type->id.value() != res_id.type_id()) {
-    diag->Error(DiagMessage(source)
-                    << "trying to add resource '" << name << "' with ID " << res_id
-                    << " but type '" << type->type << "' already has ID "
-                    << StringPrintf("%02x", type->id.value()));
-    return false;
+struct PackageViewComparer {
+  bool operator()(const ResourceTablePackageView& lhs, const ResourceTablePackageView& rhs) {
+    return less_than_struct_with_name_and_id<ResourceTablePackageView, uint8_t>(
+        lhs, std::make_pair(rhs.name, rhs.id));
   }
+};
 
-  ResourceEntry* entry = type->FindOrCreateEntry(name.entry, use_id ? res_id.entry_id()
-                                                                    : Maybe<uint16_t>());
-
-  // Check for entries appearing twice with two different entry ids
-  if (check_id && entry->id && entry->id.value() != res_id.entry_id()) {
-    diag->Error(DiagMessage(source)
-                    << "trying to add resource '" << name << "' with ID " << res_id
-                    << " but resource already has ID "
-                    << ResourceId(package->id.value(), type->id.value(), entry->id.value()));
-    return false;
+struct TypeViewComparer {
+  bool operator()(const ResourceTableTypeView& lhs, const ResourceTableTypeView& rhs) {
+    return lhs.id != rhs.id ? lhs.id < rhs.id : lhs.type < rhs.type;
   }
+};
 
-  ResourceConfigValue* config_value = entry->FindOrCreateValue(config, product);
-  if (!config_value->value) {
-    // Resource does not exist, add it now.
-    config_value->value = std::move(value);
-  } else {
-    switch (conflict_resolver(config_value->value.get(), value.get())) {
-      case CollisionResult::kKeepBoth:
-        // Insert the value ignoring for duplicate configurations
-        entry->values.push_back(util::make_unique<ResourceConfigValue>(config, product));
-        entry->values.back()->value = std::move(value);
-        break;
+struct EntryViewComparer {
+  bool operator()(const ResourceEntry* lhs, const ResourceEntry* rhs) {
+    return less_than_struct_with_name_and_id<ResourceEntry, ResourceId>(
+        *lhs, std::make_pair(rhs->name, rhs->id));
+  }
+};
 
-      case CollisionResult::kTakeNew:
-        // Take the incoming value.
-        config_value->value = std::move(value);
-        break;
+ResourceTableView ResourceTable::GetPartitionedView() const {
+  ResourceTableView view;
+  SortedVectorInserter<ResourceTablePackageView, PackageViewComparer> package_inserter;
+  SortedVectorInserter<ResourceTableTypeView, TypeViewComparer> type_inserter;
+  SortedVectorInserter<const ResourceEntry*, EntryViewComparer> entry_inserter;
 
-      case CollisionResult::kConflict:
-        diag->Error(DiagMessage(source) << "duplicate value for resource '" << name << "' "
-                                        << "with config '" << config << "'");
-        diag->Error(DiagMessage(source) << "resource previously defined here");
-        return false;
+  for (const auto& package : packages) {
+    for (const auto& type : package->types) {
+      for (const auto& entry : type->entries) {
+        ResourceTablePackageView new_package{
+            package->name, entry->id ? entry->id.value().package_id() : Maybe<uint8_t>{}};
+        auto view_package = package_inserter.Insert(view.packages, std::move(new_package));
 
-      case CollisionResult::kKeepOriginal:
-        break;
+        ResourceTableTypeView new_type{type->type,
+                                       entry->id ? entry->id.value().type_id() : Maybe<uint8_t>{}};
+        auto view_type = type_inserter.Insert(view_package->types, std::move(new_type));
+
+        if (entry->visibility.level == Visibility::Level::kPublic) {
+          // Only mark the type visibility level as public, it doesn't care about being private.
+          view_type->visibility_level = Visibility::Level::kPublic;
+        }
+
+        entry_inserter.Insert(view_type->entries, entry.get());
+      }
     }
   }
 
-  if (res_id.is_valid()) {
-    package->id = res_id.package_id();
-    type->id = res_id.type_id();
-    entry->id = res_id.entry_id();
+  // The android runtime does not support querying resources when the there are multiple type ids
+  // for the same resource type within the same package. For this reason, if there are types with
+  // multiple type ids, each type needs to exist in its own package in order to be queried by name.
+  std::vector<ResourceTablePackageView> new_packages;
+  for (auto& package : view.packages) {
+    // If a new package was already created for a different type within this package, then
+    // we can reuse those packages for other types that need to be extracted from this package.
+    // `start_index` is the index of the first newly created package that can be reused.
+    const size_t start_index = new_packages.size();
+    std::map<ResourceType, size_t> type_new_package_index;
+    for (auto type_it = package.types.begin(); type_it != package.types.end();) {
+      auto& type = *type_it;
+      auto type_index_iter = type_new_package_index.find(type.type);
+      if (type_index_iter == type_new_package_index.end()) {
+        // First occurrence of the resource type in this package. Keep it in this package.
+        type_new_package_index.insert(type_index_iter, std::make_pair(type.type, start_index));
+        ++type_it;
+        continue;
+      }
+
+      // The resource type has already been seen for this package, so this type must be extracted to
+      // a new separate package.
+      const size_t index = type_index_iter->second;
+      if (new_packages.size() == index) {
+        new_packages.emplace_back(ResourceTablePackageView{package.name, package.id});
+        type_new_package_index[type.type] = index + 1;
+      }
+
+      // Move the type into a new package
+      auto& other_package = new_packages[index];
+      type_inserter.Insert(other_package.types, std::move(type));
+      type_it = package.types.erase(type_it);
+    }
   }
 
-  return true;
-}
-
-bool ResourceTable::GetValidateResources() {
-  return validate_resources_;
-}
-
-bool ResourceTable::SetVisibility(const ResourceNameRef& name, const Visibility& visibility,
-                                  IDiagnostics* diag) {
-  return SetVisibilityImpl(name, visibility, {}, ResourceNameValidator, diag);
-}
-
-bool ResourceTable::SetVisibilityWithId(const ResourceNameRef& name, const Visibility& visibility,
-                                        const ResourceId& res_id, IDiagnostics* diag) {
-  return SetVisibilityImpl(name, visibility, res_id, ResourceNameValidator, diag);
-}
-
-bool ResourceTable::SetVisibilityWithIdMangled(const ResourceNameRef& name,
-                                               const Visibility& visibility,
-                                               const ResourceId& res_id, IDiagnostics* diag) {
-  return SetVisibilityImpl(name, visibility, res_id, SkipNameValidator, diag);
-}
-
-bool ResourceTable::SetVisibilityImpl(const ResourceNameRef& name, const Visibility& visibility,
-                                      const ResourceId& res_id, NameValidator name_validator,
-                                      IDiagnostics* diag) {
-  CHECK(diag != nullptr);
-
-  const Source& source = visibility.source;
-  if (!ValidateName(name_validator, name, source, diag)) {
-    return false;
+  for (auto& new_package : new_packages) {
+    // Insert newly created packages after their original packages
+    auto [_, it] = package_inserter.LowerBound(view.packages, new_package);
+    view.packages.insert(++it, std::move(new_package));
   }
 
-  // Check for package names appearing twice with two different package ids
-  ResourceTablePackage* package = FindOrCreatePackage(name.package);
-  if (res_id.is_valid() && package->id && package->id.value() != res_id.package_id()) {
+  return view;
+}
+
+bool ResourceTable::AddResource(NewResource&& res, IDiagnostics* diag) {
+  CHECK(diag != nullptr) << "Diagnostic pointer is null";
+
+  const bool validate = validation_ == Validation::kEnabled;
+  const Source source = res.value ? res.value->GetSource() : Source{};
+  if (validate && !res.allow_mangled && !IsValidResourceEntryName(res.name.entry)) {
     diag->Error(DiagMessage(source)
-                    << "trying to add resource '" << name << "' with ID " << res_id
-                    << " but package '" << package->name << "' already has ID "
-                    << StringPrintf("%02x", package->id.value()));
+                << "resource '" << res.name << "' has invalid entry name '" << res.name.entry);
     return false;
   }
 
-  // Whether or not to error on duplicate resources
-  bool check_id = validate_resources_ && res_id.is_valid();
-  // Whether or not to create a duplicate resource if the id does not match
-  bool use_id = !validate_resources_ && res_id.is_valid();
-
-  ResourceTableType* type = package->FindOrCreateType(name.type, use_id ? res_id.type_id()
-                                                                        : Maybe<uint8_t>());
-
-  // Check for types appearing twice with two different type ids
-  if (check_id && type->id && type->id.value() != res_id.type_id()) {
-    diag->Error(DiagMessage(source)
-                    << "trying to add resource '" << name << "' with ID " << res_id
-                    << " but type '" << type->type << "' already has ID "
-                    << StringPrintf("%02x", type->id.value()));
+  if (res.id.has_value() && !res.id->first.is_valid()) {
+    diag->Error(DiagMessage(source) << "trying to add resource '" << res.name << "' with ID "
+                                    << res.id->first << " but that ID is invalid");
     return false;
   }
 
-  ResourceEntry* entry = type->FindOrCreateEntry(name.entry, use_id ? res_id.entry_id()
-                                                                    : Maybe<uint16_t>());
+  auto package = FindOrCreatePackage(res.name.package);
+  auto type = package->FindOrCreateType(res.name.type);
+  auto entry_it = std::equal_range(type->entries.begin(), type->entries.end(), res.name.entry,
+                                   NameEqualRange<ResourceEntry>{});
+  const size_t entry_count = std::distance(entry_it.first, entry_it.second);
 
-  // Check for entries appearing twice with two different entry ids
-  if (check_id && entry->id && entry->id.value() != res_id.entry_id()) {
-    diag->Error(DiagMessage(source)
-                    << "trying to add resource '" << name << "' with ID " << res_id
-                    << " but resource already has ID "
-                    << ResourceId(package->id.value(), type->id.value(), entry->id.value()));
-    return false;
+  ResourceEntry* entry;
+  if (entry_count == 0) {
+    // Adding a new resource
+    entry = type->CreateEntry(res.name.entry);
+  } else if (entry_count == 1) {
+    // Assume that the existing resource is being modified
+    entry = entry_it.first->get();
+  } else {
+    // Multiple resources with the same name exist in the resource table. The only way to
+    // distinguish between them is using resource id since each resource should have a unique id.
+    CHECK(res.id.has_value()) << "ambiguous modification of resource entry '" << res.name
+                              << "' without specifying a resource id.";
+    entry = entry_it.first->get();
+    for (auto it = entry_it.first; it != entry_it.second; ++it) {
+      CHECK((bool)(*it)->id) << "ambiguous modification of resource entry '" << res.name
+                             << "' with multiple entries without resource ids";
+      if ((*it)->id == res.id->first) {
+        entry = it->get();
+        break;
+      }
+    }
   }
 
-  if (res_id.is_valid()) {
-    package->id = res_id.package_id();
-    type->id = res_id.type_id();
-    entry->id = res_id.entry_id();
+  if (res.id.has_value()) {
+    if (entry->id && entry->id.value() != res.id->first) {
+      if (res.id->second != OnIdConflict::CREATE_ENTRY) {
+        diag->Error(DiagMessage(source)
+                    << "trying to add resource '" << res.name << "' with ID " << res.id->first
+                    << " but resource already has ID " << entry->id.value());
+        return false;
+      }
+      entry = type->CreateEntry(res.name.entry);
+    }
+    entry->id = res.id->first;
   }
 
-  // Only mark the type visibility level as public, it doesn't care about being private.
-  if (visibility.level == Visibility::Level::kPublic) {
-    type->visibility_level = Visibility::Level::kPublic;
+  if (res.visibility.has_value()) {
+    // Only mark the type visibility level as public, it doesn't care about being private.
+    if (res.visibility->level == Visibility::Level::kPublic) {
+      type->visibility_level = Visibility::Level::kPublic;
+    }
+
+    if (res.visibility->level > entry->visibility.level) {
+      // This symbol definition takes precedence, replace.
+      entry->visibility = res.visibility.value();
+    }
+
+    if (res.visibility->staged_api) {
+      entry->visibility.staged_api = entry->visibility.staged_api;
+    }
   }
 
-  if (visibility.level == Visibility::Level::kUndefined &&
-      entry->visibility.level != Visibility::Level::kUndefined) {
-    // We can't undefine a symbol (remove its visibility). Ignore.
-    return true;
+  if (res.overlayable.has_value()) {
+    if (entry->overlayable_item) {
+      diag->Error(DiagMessage(res.overlayable->source)
+                  << "duplicate overlayable declaration for resource '" << res.name << "'");
+      diag->Error(DiagMessage(entry->overlayable_item.value().source)
+                  << "previous declaration here");
+      return false;
+    }
+    entry->overlayable_item = res.overlayable.value();
   }
 
-  if (visibility.level < entry->visibility.level) {
-    // We can't downgrade public to private. Ignore.
-    return true;
+  if (res.allow_new.has_value()) {
+    entry->allow_new = res.allow_new.value();
   }
 
-  // This symbol definition takes precedence, replace.
-  entry->visibility = visibility;
-  return true;
-}
+  if (res.value != nullptr) {
+    auto config_value = entry->FindOrCreateValue(res.config, res.product);
+    if (!config_value->value) {
+      // Resource does not exist, add it now.
+      config_value->value = std::move(res.value);
+    } else {
+      // When validation is enabled, ensure that a resource cannot have multiple values defined for
+      // the same configuration.
+      auto result = validate ? ResolveValueCollision(config_value->value.get(), res.value.get())
+                             : CollisionResult::kKeepBoth;
+      switch (result) {
+        case CollisionResult::kKeepBoth:
+          // Insert the value ignoring for duplicate configurations
+          entry->values.push_back(util::make_unique<ResourceConfigValue>(res.config, res.product));
+          entry->values.back()->value = std::move(res.value);
+          break;
 
-bool ResourceTable::SetAllowNew(const ResourceNameRef& name, const AllowNew& allow_new,
-                                IDiagnostics* diag) {
-  return SetAllowNewImpl(name, allow_new, ResourceNameValidator, diag);
-}
+        case CollisionResult::kTakeNew:
+          // Take the incoming value.
+          config_value->value = std::move(res.value);
+          break;
 
-bool ResourceTable::SetAllowNewMangled(const ResourceNameRef& name, const AllowNew& allow_new,
-                                       IDiagnostics* diag) {
-  return SetAllowNewImpl(name, allow_new, SkipNameValidator, diag);
-}
+        case CollisionResult::kConflict:
+          diag->Error(DiagMessage(source) << "duplicate value for resource '" << res.name << "' "
+                                          << "with config '" << res.config << "'");
+          diag->Error(DiagMessage(source) << "resource previously defined here");
+          return false;
 
-bool ResourceTable::SetAllowNewImpl(const ResourceNameRef& name, const AllowNew& allow_new,
-                                    NameValidator name_validator, IDiagnostics* diag) {
-  CHECK(diag != nullptr);
-
-  if (!ValidateName(name_validator, name, allow_new.source, diag)) {
-    return false;
+        case CollisionResult::kKeepOriginal:
+          break;
+      }
+    }
   }
 
-  ResourceTablePackage* package = FindOrCreatePackage(name.package);
-  ResourceTableType* type = package->FindOrCreateType(name.type);
-  ResourceEntry* entry = type->FindOrCreateEntry(name.entry);
-  entry->allow_new = allow_new;
-  return true;
-}
-
-bool ResourceTable::SetOverlayable(const ResourceNameRef& name, const OverlayableItem& overlayable,
-                                   IDiagnostics* diag) {
-  return SetOverlayableImpl(name, overlayable, ResourceNameValidator, diag);
-}
-
-bool ResourceTable::SetOverlayableImpl(const ResourceNameRef& name,
-                                       const OverlayableItem& overlayable,
-                                       NameValidator name_validator, IDiagnostics *diag) {
-  CHECK(diag != nullptr);
-
-  if (!ValidateName(name_validator, name, overlayable.source, diag)) {
-    return false;
-  }
-
-  ResourceTablePackage* package = FindOrCreatePackage(name.package);
-  ResourceTableType* type = package->FindOrCreateType(name.type);
-  ResourceEntry* entry = type->FindOrCreateEntry(name.entry);
-
-  if (entry->overlayable_item) {
-    diag->Error(DiagMessage(overlayable.source)
-                << "duplicate overlayable declaration for resource '" << name << "'");
-    diag->Error(DiagMessage(entry->overlayable_item.value().source)
-                << "previous declaration here");
-    return false;
-  }
-
-  entry->overlayable_item = overlayable;
   return true;
 }
 
@@ -641,17 +553,38 @@
   return SearchResult{package, type, entry};
 }
 
+Maybe<ResourceTable::SearchResult> ResourceTable::FindResource(const ResourceNameRef& name,
+                                                               ResourceId id) const {
+  ResourceTablePackage* package = FindPackage(name.package);
+  if (package == nullptr) {
+    return {};
+  }
+
+  ResourceTableType* type = package->FindType(name.type);
+  if (type == nullptr) {
+    return {};
+  }
+
+  auto entry_it = std::equal_range(type->entries.begin(), type->entries.end(), name.entry,
+                                   NameEqualRange<ResourceEntry>{});
+  for (auto it = entry_it.first; it != entry_it.second; ++it) {
+    if ((*it)->id == id) {
+      return SearchResult{package, type, it->get()};
+    }
+  }
+  return {};
+}
+
 std::unique_ptr<ResourceTable> ResourceTable::Clone() const {
   std::unique_ptr<ResourceTable> new_table = util::make_unique<ResourceTable>();
   for (const auto& pkg : packages) {
-    ResourceTablePackage* new_pkg = new_table->CreatePackage(pkg->name, pkg->id);
+    ResourceTablePackage* new_pkg = new_table->FindOrCreatePackage(pkg->name);
     for (const auto& type : pkg->types) {
       ResourceTableType* new_type = new_pkg->FindOrCreateType(type->type);
-      new_type->id = type->id;
       new_type->visibility_level = type->visibility_level;
 
       for (const auto& entry : type->entries) {
-        ResourceEntry* new_entry = new_type->FindOrCreateEntry(entry->name);
+        ResourceEntry* new_entry = new_type->CreateEntry(entry->name);
         new_entry->id = entry->id;
         new_entry->visibility = entry->visibility;
         new_entry->allow_new = entry->allow_new;
@@ -668,4 +601,51 @@
   return new_table;
 }
 
+NewResourceBuilder::NewResourceBuilder(const ResourceNameRef& name) {
+  res_.name = name.ToResourceName();
+}
+
+NewResourceBuilder::NewResourceBuilder(const std::string& name) {
+  ResourceNameRef ref;
+  CHECK(ResourceUtils::ParseResourceName(name, &ref)) << "invalid resource name: " << name;
+  res_.name = ref.ToResourceName();
+}
+
+NewResourceBuilder& NewResourceBuilder::SetValue(std::unique_ptr<Value> value,
+                                                 android::ConfigDescription config,
+                                                 std::string product) {
+  res_.value = std::move(value);
+  res_.config = std::move(config);
+  res_.product = std::move(product);
+  return *this;
+}
+
+NewResourceBuilder& NewResourceBuilder::SetId(ResourceId id, OnIdConflict on_conflict) {
+  res_.id = std::make_pair(id, on_conflict);
+  return *this;
+}
+
+NewResourceBuilder& NewResourceBuilder::SetVisibility(Visibility visibility) {
+  res_.visibility = std::move(visibility);
+  return *this;
+}
+
+NewResourceBuilder& NewResourceBuilder::SetOverlayable(OverlayableItem overlayable) {
+  res_.overlayable = std::move(overlayable);
+  return *this;
+}
+NewResourceBuilder& NewResourceBuilder::SetAllowNew(AllowNew allow_new) {
+  res_.allow_new = std::move(allow_new);
+  return *this;
+}
+
+NewResourceBuilder& NewResourceBuilder::SetAllowMangled(bool allow_mangled) {
+  res_.allow_mangled = allow_mangled;
+  return *this;
+}
+
+NewResource NewResourceBuilder::Build() {
+  return std::move(res_);
+}
+
 }  // namespace aapt
diff --git a/tools/aapt2/ResourceTable.h b/tools/aapt2/ResourceTable.h
index 93a7a31..080ecc2 100644
--- a/tools/aapt2/ResourceTable.h
+++ b/tools/aapt2/ResourceTable.h
@@ -51,6 +51,11 @@
   Level level = Level::kUndefined;
   Source source;
   std::string comment;
+
+  // Indicates that the resource id may change across builds and that the public R.java identifier
+  // for this resource should not be final. This is set to `true` for resources in `staging-group`
+  // tags.
+  bool staged_api = false;
 };
 
 // Represents <add-resource> in an overlay.
@@ -109,7 +114,7 @@
   const std::string name;
 
   // The entry ID for this resource (the EEEE in 0xPPTTEEEE).
-  Maybe<uint16_t> id;
+  Maybe<ResourceId> id;
 
   // Whether this resource is public (and must maintain the same entry ID across builds).
   Visibility visibility;
@@ -124,10 +129,10 @@
 
   explicit ResourceEntry(const android::StringPiece& name) : name(name.to_string()) {}
 
-  ResourceConfigValue* FindValue(const android::ConfigDescription& config);
-
   ResourceConfigValue* FindValue(const android::ConfigDescription& config,
-                                 const android::StringPiece& product);
+                                 android::StringPiece product = {});
+  const ResourceConfigValue* FindValue(const android::ConfigDescription& config,
+                                       android::StringPiece product = {}) const;
 
   ResourceConfigValue* FindOrCreateValue(const android::ConfigDescription& config,
                                          const android::StringPiece& product);
@@ -156,9 +161,6 @@
   // The logical type of resource (string, drawable, layout, etc.).
   const ResourceType type;
 
-  // The type ID for this resource (the TT in 0xPPTTEEEE).
-  Maybe<uint8_t> id;
-
   // Whether this type is public (and must maintain the same type ID across builds).
   Visibility::Level visibility_level = Visibility::Level::kUndefined;
 
@@ -167,10 +169,9 @@
 
   explicit ResourceTableType(const ResourceType type) : type(type) {}
 
-  ResourceEntry* FindEntry(const android::StringPiece& name,
-                           Maybe<uint16_t> id = Maybe<uint16_t>());
-  ResourceEntry* FindOrCreateEntry(const android::StringPiece& name,
-                                   Maybe<uint16_t> id = Maybe<uint16_t>());
+  ResourceEntry* CreateEntry(const android::StringPiece& name);
+  ResourceEntry* FindEntry(const android::StringPiece& name) const;
+  ResourceEntry* FindOrCreateEntry(const android::StringPiece& name);
 
  private:
   DISALLOW_COPY_AND_ASSIGN(ResourceTableType);
@@ -180,70 +181,99 @@
  public:
   std::string name;
 
-  // The package ID (the PP in 0xPPTTEEEE).
-  Maybe<uint8_t> id;
-
   std::vector<std::unique_ptr<ResourceTableType>> types;
 
+  explicit ResourceTablePackage(const android::StringPiece& name) : name(name.to_string()) {
+  }
+
   ResourceTablePackage() = default;
-  ResourceTableType* FindType(ResourceType type, Maybe<uint8_t> id = Maybe<uint8_t>());
-  ResourceTableType* FindOrCreateType(const ResourceType type,
-                                      Maybe<uint8_t> id = Maybe<uint8_t>());
+  ResourceTableType* FindType(ResourceType type) const;
+  ResourceTableType* FindOrCreateType(ResourceType type);
 
  private:
   DISALLOW_COPY_AND_ASSIGN(ResourceTablePackage);
 };
 
+struct ResourceTableTypeView {
+  ResourceType type;
+  Maybe<uint8_t> id;
+  Visibility::Level visibility_level = Visibility::Level::kUndefined;
+
+  // Entries sorted in ascending entry id order. If ids have not been assigned, the entries are
+  //  // sorted lexicographically.
+  std::vector<const ResourceEntry*> entries;
+};
+
+struct ResourceTablePackageView {
+  std::string name;
+  Maybe<uint8_t> id;
+  // Types sorted in ascending type id order. If ids have not been assigned, the types are sorted by
+  // their declaration order in the ResourceType enum.
+  std::vector<ResourceTableTypeView> types;
+};
+
+struct ResourceTableView {
+  // Packages sorted in ascending package id order. If ids have not been assigned, the packages are
+  // sorted lexicographically.
+  std::vector<ResourceTablePackageView> packages;
+};
+
+enum class OnIdConflict {
+  // If the resource entry already exists but has a different resource id, the resource value will
+  // not be added to the table.
+  ERROR,
+
+  // If the resource entry already exists but has a different resource id, create a new resource
+  // with this resource name and id combination.
+  CREATE_ENTRY,
+};
+
+struct NewResource {
+  ResourceName name;
+  std::unique_ptr<Value> value;
+  android::ConfigDescription config;
+  std::string product;
+  std::optional<std::pair<ResourceId, OnIdConflict>> id;
+  std::optional<Visibility> visibility;
+  std::optional<OverlayableItem> overlayable;
+  std::optional<AllowNew> allow_new;
+  bool allow_mangled = false;
+};
+
+struct NewResourceBuilder {
+  explicit NewResourceBuilder(const ResourceNameRef& name);
+  explicit NewResourceBuilder(const std::string& name);
+  NewResourceBuilder& SetValue(std::unique_ptr<Value> value, android::ConfigDescription config = {},
+                               std::string product = {});
+  NewResourceBuilder& SetId(ResourceId id, OnIdConflict on_conflict = OnIdConflict::ERROR);
+  NewResourceBuilder& SetVisibility(Visibility id);
+  NewResourceBuilder& SetOverlayable(OverlayableItem overlayable);
+  NewResourceBuilder& SetAllowNew(AllowNew allow_new);
+  NewResourceBuilder& SetAllowMangled(bool allow_mangled);
+  NewResource Build();
+
+ private:
+  NewResource res_;
+};
+
 // The container and index for all resources defined for an app.
 class ResourceTable {
  public:
-  ResourceTable() = default;
-  explicit ResourceTable(bool validate_resources) : validate_resources_(validate_resources) {}
+  enum class Validation {
+    kEnabled,
+    kDisabled,
+  };
 
   enum class CollisionResult { kKeepBoth, kKeepOriginal, kConflict, kTakeNew };
 
-  using CollisionResolverFunc = std::function<CollisionResult(Value*, Value*)>;
+  ResourceTable() = default;
+  explicit ResourceTable(Validation validation);
 
-  // When a collision of resources occurs, this method decides which value to keep.
-  static CollisionResult ResolveValueCollision(Value* existing, Value* incoming);
+  bool AddResource(NewResource&& res, IDiagnostics* diag);
 
-  // When a collision of resources occurs, this method keeps both values
-  static CollisionResult IgnoreCollision(Value* existing, Value* incoming);
-
-  bool AddResource(const ResourceNameRef& name, const android::ConfigDescription& config,
-                   const android::StringPiece& product, std::unique_ptr<Value> value,
-                   IDiagnostics* diag);
-
-  bool AddResourceWithId(const ResourceNameRef& name, const ResourceId& res_id,
-                         const android::ConfigDescription& config,
-                         const android::StringPiece& product, std::unique_ptr<Value> value,
-                         IDiagnostics* diag);
-
-  // Same as AddResource, but doesn't verify the validity of the name. This is used
-  // when loading resources from an existing binary resource table that may have mangled names.
-  bool AddResourceMangled(const ResourceNameRef& name, const android::ConfigDescription& config,
-                          const android::StringPiece& product, std::unique_ptr<Value> value,
-                          IDiagnostics* diag);
-
-  bool AddResourceWithIdMangled(const ResourceNameRef& name, const ResourceId& id,
-                                const android::ConfigDescription& config,
-                                const android::StringPiece& product, std::unique_ptr<Value> value,
-                                IDiagnostics* diag);
-
-  bool GetValidateResources();
-
-  bool SetVisibility(const ResourceNameRef& name, const Visibility& visibility, IDiagnostics* diag);
-  bool SetVisibilityWithId(const ResourceNameRef& name, const Visibility& visibility,
-                           const ResourceId& res_id, IDiagnostics* diag);
-  bool SetVisibilityWithIdMangled(const ResourceNameRef& name, const Visibility& visibility,
-                                  const ResourceId& res_id, IDiagnostics* diag);
-
-  bool SetOverlayable(const ResourceNameRef& name, const OverlayableItem& overlayable,
-                      IDiagnostics *diag);
-
-  bool SetAllowNew(const ResourceNameRef& name, const AllowNew& allow_new, IDiagnostics* diag);
-  bool SetAllowNewMangled(const ResourceNameRef& name, const AllowNew& allow_new,
-                          IDiagnostics* diag);
+  // Retrieves a sorted a view of the packages, types, and entries sorted in ascending resource id
+  // order.
+  ResourceTableView GetPartitionedView() const;
 
   struct SearchResult {
     ResourceTablePackage* package;
@@ -252,23 +282,19 @@
   };
 
   Maybe<SearchResult> FindResource(const ResourceNameRef& name) const;
+  Maybe<SearchResult> FindResource(const ResourceNameRef& name, ResourceId id) const;
 
   // Returns the package struct with the given name, or nullptr if such a package does not
   // exist. The empty string is a valid package and typically is used to represent the
   // 'current' package before it is known to the ResourceTable.
   ResourceTablePackage* FindPackage(const android::StringPiece& name) const;
-
-  ResourceTablePackage* FindPackageById(uint8_t id) const;
-
-  ResourceTablePackage* CreatePackage(const android::StringPiece& name, Maybe<uint8_t> id = {});
-
-  // Attempts to find a package having the specified name and ID. If not found, a new package
-  // of the specified parameters is created and returned.
-  ResourceTablePackage* CreatePackageAllowingDuplicateNames(const android::StringPiece& name,
-                                                            const Maybe<uint8_t> id);
+  ResourceTablePackage* FindOrCreatePackage(const android::StringPiece& name);
 
   std::unique_ptr<ResourceTable> Clone() const;
 
+  // When a collision of resources occurs, this method decides which value to keep.
+  static CollisionResult ResolveValueCollision(Value* existing, Value* incoming);
+
   // The string pool used by this resource table. Values that reference strings must use
   // this pool to create their strings.
   // NOTE: `string_pool` must come before `packages` so that it is destroyed after.
@@ -286,36 +312,9 @@
   std::map<size_t, std::string> included_packages_;
 
  private:
-  // The function type that validates a symbol name. Returns a non-empty StringPiece representing
-  // the offending character (which may be more than one byte in UTF-8). Returns an empty string
-  // if the name was valid.
-  using NameValidator = android::StringPiece(const android::StringPiece&);
-
-  ResourceTablePackage* FindOrCreatePackage(const android::StringPiece& name);
-
-  bool ValidateName(NameValidator validator, const ResourceNameRef& name, const Source& source,
-                    IDiagnostics* diag);
-
-  bool AddResourceImpl(const ResourceNameRef& name, const ResourceId& res_id,
-                       const android::ConfigDescription& config,
-                       const android::StringPiece& product, std::unique_ptr<Value> value,
-                       NameValidator name_validator, const CollisionResolverFunc& conflict_resolver,
-                       IDiagnostics* diag);
-
-  bool SetVisibilityImpl(const ResourceNameRef& name, const Visibility& visibility,
-                         const ResourceId& res_id, NameValidator name_validator,
-                         IDiagnostics* diag);
-
-  bool SetAllowNewImpl(const ResourceNameRef& name, const AllowNew& allow_new,
-                       NameValidator name_validator, IDiagnostics* diag);
-
-  bool SetOverlayableImpl(const ResourceNameRef &name, const OverlayableItem& overlayable,
-                          NameValidator name_validator, IDiagnostics *diag);
-
-  // Controls whether the table validates resource names and prevents duplicate resource names
-  bool validate_resources_ = true;
-
   DISALLOW_COPY_AND_ASSIGN(ResourceTable);
+
+  Validation validation_ = Validation::kEnabled;
 };
 
 }  // namespace aapt
diff --git a/tools/aapt2/ResourceTable_test.cpp b/tools/aapt2/ResourceTable_test.cpp
index 9271a7e..38391c9 100644
--- a/tools/aapt2/ResourceTable_test.cpp
+++ b/tools/aapt2/ResourceTable_test.cpp
@@ -37,31 +37,32 @@
 TEST(ResourceTableTest, FailToAddResourceWithBadName) {
   ResourceTable table;
 
-  EXPECT_FALSE(table.AddResource(
-      test::ParseNameOrDie("android:id/hey,there"), ConfigDescription{}, "",
-      test::ValueBuilder<Id>().SetSource("test.xml", 21u).Build(),
-      test::GetDiagnostics()));
+  EXPECT_FALSE(
+      table.AddResource(NewResourceBuilder(test::ParseNameOrDie("android:id/hey,there")).Build(),
+                        test::GetDiagnostics()));
 
-  EXPECT_FALSE(table.AddResource(
-      test::ParseNameOrDie("android:id/hey:there"), ConfigDescription{}, "",
-      test::ValueBuilder<Id>().SetSource("test.xml", 21u).Build(),
-      test::GetDiagnostics()));
+  EXPECT_FALSE(
+      table.AddResource(NewResourceBuilder(test::ParseNameOrDie("android:id/hey:there")).Build(),
+                        test::GetDiagnostics()));
 }
 
 TEST(ResourceTableTest, AddResourceWithWeirdNameWhenAddingMangledResources) {
   ResourceTable table;
 
-  EXPECT_TRUE(table.AddResourceMangled(
-      test::ParseNameOrDie("android:id/heythere       "), ConfigDescription{}, "",
-      test::ValueBuilder<Id>().SetSource("test.xml", 21u).Build(), test::GetDiagnostics()));
+  EXPECT_TRUE(
+      table.AddResource(NewResourceBuilder(test::ParseNameOrDie("android:id/heythere       "))
+                            .SetAllowMangled(true)
+                            .Build(),
+                        test::GetDiagnostics()));
 }
 
 TEST(ResourceTableTest, AddOneResource) {
   ResourceTable table;
 
   EXPECT_TRUE(table.AddResource(
-      test::ParseNameOrDie("android:attr/id"), ConfigDescription{}, "",
-      test::ValueBuilder<Id>().SetSource("test/path/file.xml", 23u).Build(),
+      NewResourceBuilder(test::ParseNameOrDie("android:attr/id"))
+          .SetValue(test::ValueBuilder<Id>().SetSource("test/path/file.xml", 23u).Build())
+          .Build(),
       test::GetDiagnostics()));
 
   EXPECT_THAT(test::GetValue<Id>(&table, "android:attr/id"), NotNull());
@@ -70,32 +71,36 @@
 TEST(ResourceTableTest, AddMultipleResources) {
   ResourceTable table;
 
-  ConfigDescription config;
   ConfigDescription language_config;
   memcpy(language_config.language, "pl", sizeof(language_config.language));
 
   EXPECT_TRUE(table.AddResource(
-      test::ParseNameOrDie("android:attr/layout_width"), config, "",
-      test::ValueBuilder<Id>().SetSource("test/path/file.xml", 10u).Build(),
-      test::GetDiagnostics()));
-
-  EXPECT_TRUE(table.AddResource(
-      test::ParseNameOrDie("android:attr/id"), config, "",
-      test::ValueBuilder<Id>().SetSource("test/path/file.xml", 12u).Build(),
-      test::GetDiagnostics()));
-
-  EXPECT_TRUE(table.AddResource(
-      test::ParseNameOrDie("android:string/ok"), config, "",
-      test::ValueBuilder<Id>().SetSource("test/path/file.xml", 14u).Build(),
-      test::GetDiagnostics()));
-
-  EXPECT_TRUE(table.AddResource(
-      test::ParseNameOrDie("android:string/ok"), language_config, "",
-      test::ValueBuilder<BinaryPrimitive>(android::Res_value{})
-          .SetSource("test/path/file.xml", 20u)
+      NewResourceBuilder(test::ParseNameOrDie("android:attr/layout_width"))
+          .SetValue(test::ValueBuilder<Id>().SetSource("test/path/file.xml", 10u).Build())
           .Build(),
       test::GetDiagnostics()));
 
+  EXPECT_TRUE(table.AddResource(
+      NewResourceBuilder(test::ParseNameOrDie("android:attr/id"))
+          .SetValue(test::ValueBuilder<Id>().SetSource("test/path/file.xml", 12u).Build())
+          .Build(),
+      test::GetDiagnostics()));
+
+  EXPECT_TRUE(table.AddResource(
+      NewResourceBuilder(test::ParseNameOrDie("android:string/ok"))
+          .SetValue(test::ValueBuilder<Id>().SetSource("test/path/file.xml", 14u).Build())
+          .Build(),
+      test::GetDiagnostics()));
+
+  EXPECT_TRUE(
+      table.AddResource(NewResourceBuilder(test::ParseNameOrDie("android:string/ok"))
+                            .SetValue(test::ValueBuilder<BinaryPrimitive>(android::Res_value{})
+                                          .SetSource("test/path/file.xml", 20u)
+                                          .Build(),
+                                      language_config)
+                            .Build(),
+                        test::GetDiagnostics()));
+
   EXPECT_THAT(test::GetValue<Id>(&table, "android:attr/layout_width"), NotNull());
   EXPECT_THAT(test::GetValue<Id>(&table, "android:attr/id"), NotNull());
   EXPECT_THAT(test::GetValue<Id>(&table, "android:string/ok"), NotNull());
@@ -104,17 +109,19 @@
 
 TEST(ResourceTableTest, OverrideWeakResourceValue) {
   ResourceTable table;
-
-  ASSERT_TRUE(table.AddResource(test::ParseNameOrDie("android:attr/foo"), ConfigDescription{}, "",
-                                test::AttributeBuilder().SetWeak(true).Build(),
+  ASSERT_TRUE(table.AddResource(NewResourceBuilder(test::ParseNameOrDie("android:attr/foo"))
+                                    .SetValue(test::AttributeBuilder().SetWeak(true).Build())
+                                    .Build(),
                                 test::GetDiagnostics()));
 
   Attribute* attr = test::GetValue<Attribute>(&table, "android:attr/foo");
   ASSERT_THAT(attr, NotNull());
   EXPECT_TRUE(attr->IsWeak());
 
-  ASSERT_TRUE(table.AddResource(test::ParseNameOrDie("android:attr/foo"), ConfigDescription{}, "",
-                                util::make_unique<Attribute>(), test::GetDiagnostics()));
+  ASSERT_TRUE(table.AddResource(NewResourceBuilder(test::ParseNameOrDie("android:attr/foo"))
+                                    .SetValue(util::make_unique<Attribute>())
+                                    .Build(),
+                                test::GetDiagnostics()));
 
   attr = test::GetValue<Attribute>(&table, "android:attr/foo");
   ASSERT_THAT(attr, NotNull());
@@ -130,23 +137,27 @@
   Attribute attr_two(android::ResTable_map::TYPE_STRING | android::ResTable_map::TYPE_REFERENCE);
   attr_two.SetWeak(true);
 
-  ASSERT_TRUE(table.AddResource(name, ConfigDescription{}, "",
-                                util::make_unique<Attribute>(attr_one), test::GetDiagnostics()));
-  ASSERT_TRUE(table.AddResource(name, ConfigDescription{}, "",
-                                util::make_unique<Attribute>(attr_two), test::GetDiagnostics()));
+  ASSERT_TRUE(table.AddResource(
+      NewResourceBuilder(name).SetValue(util::make_unique<Attribute>(attr_one)).Build(),
+      test::GetDiagnostics()));
+  ASSERT_TRUE(table.AddResource(
+      NewResourceBuilder(name).SetValue(util::make_unique<Attribute>(attr_two)).Build(),
+      test::GetDiagnostics()));
 }
 
 TEST(ResourceTableTest, ProductVaryingValues) {
   ResourceTable table;
+  ASSERT_TRUE(table.AddResource(
+      NewResourceBuilder(test::ParseNameOrDie("android:string/foo"))
+          .SetValue(util::make_unique<Id>(), test::ParseConfigOrDie("land"), "tablet")
+          .Build(),
+      test::GetDiagnostics()));
 
-  EXPECT_TRUE(table.AddResource(test::ParseNameOrDie("android:string/foo"),
-                                test::ParseConfigOrDie("land"), "tablet",
-                                util::make_unique<Id>(),
-                                test::GetDiagnostics()));
-  EXPECT_TRUE(table.AddResource(test::ParseNameOrDie("android:string/foo"),
-                                test::ParseConfigOrDie("land"), "phone",
-                                util::make_unique<Id>(),
-                                test::GetDiagnostics()));
+  ASSERT_TRUE(table.AddResource(
+      NewResourceBuilder(test::ParseNameOrDie("android:string/foo"))
+          .SetValue(util::make_unique<Id>(), test::ParseConfigOrDie("land"), "phone")
+          .Build(),
+      test::GetDiagnostics()));
 
   EXPECT_THAT(test::GetValueForConfigAndProduct<Id>(&table, "android:string/foo",test::ParseConfigOrDie("land"), "tablet"), NotNull());
   EXPECT_THAT(test::GetValueForConfigAndProduct<Id>(&table, "android:string/foo",test::ParseConfigOrDie("land"), "phone"), NotNull());
@@ -203,22 +214,26 @@
   Visibility visibility;
   visibility.level = Visibility::Level::kPrivate;
   visibility.comment = "private";
-  ASSERT_TRUE(table.SetVisibility(name, visibility, test::GetDiagnostics()));
+  ASSERT_TRUE(table.AddResource(NewResourceBuilder(name).SetVisibility(visibility).Build(),
+                                test::GetDiagnostics()));
   ASSERT_TRUE(VisibilityOfResource(table, name, Level::kPrivate, "private"));
 
   visibility.level = Visibility::Level::kUndefined;
   visibility.comment = "undefined";
-  ASSERT_TRUE(table.SetVisibility(name, visibility, test::GetDiagnostics()));
+  ASSERT_TRUE(table.AddResource(NewResourceBuilder(name).SetVisibility(visibility).Build(),
+                                test::GetDiagnostics()));
   ASSERT_TRUE(VisibilityOfResource(table, name, Level::kPrivate, "private"));
 
   visibility.level = Visibility::Level::kPublic;
   visibility.comment = "public";
-  ASSERT_TRUE(table.SetVisibility(name, visibility, test::GetDiagnostics()));
+  ASSERT_TRUE(table.AddResource(NewResourceBuilder(name).SetVisibility(visibility).Build(),
+                                test::GetDiagnostics()));
   ASSERT_TRUE(VisibilityOfResource(table, name, Level::kPublic, "public"));
 
   visibility.level = Visibility::Level::kPrivate;
   visibility.comment = "private";
-  ASSERT_TRUE(table.SetVisibility(name, visibility, test::GetDiagnostics()));
+  ASSERT_TRUE(table.AddResource(NewResourceBuilder(name).SetVisibility(visibility).Build(),
+                                test::GetDiagnostics()));
   ASSERT_TRUE(VisibilityOfResource(table, name, Level::kPublic, "public"));
 }
 
@@ -230,14 +245,16 @@
   Maybe<ResourceTable::SearchResult> result;
 
   allow_new.comment = "first";
-  ASSERT_TRUE(table.SetAllowNew(name, allow_new, test::GetDiagnostics()));
+  ASSERT_TRUE(table.AddResource(NewResourceBuilder(name).SetAllowNew(allow_new).Build(),
+                                test::GetDiagnostics()));
   result = table.FindResource(name);
   ASSERT_TRUE(result);
   ASSERT_TRUE(result.value().entry->allow_new);
   ASSERT_THAT(result.value().entry->allow_new.value().comment, StrEq("first"));
 
   allow_new.comment = "second";
-  ASSERT_TRUE(table.SetAllowNew(name, allow_new, test::GetDiagnostics()));
+  ASSERT_TRUE(table.AddResource(NewResourceBuilder(name).SetAllowNew(allow_new).Build(),
+                                test::GetDiagnostics()));
   result = table.FindResource(name);
   ASSERT_TRUE(result);
   ASSERT_TRUE(result.value().entry->allow_new);
@@ -255,7 +272,8 @@
   overlayable_item.source = Source("res/values/overlayable.xml", 42);
 
   const ResourceName name = test::ParseNameOrDie("android:string/foo");
-  ASSERT_TRUE(table.SetOverlayable(name, overlayable_item, test::GetDiagnostics()));
+  ASSERT_TRUE(table.AddResource(NewResourceBuilder(name).SetOverlayable(overlayable_item).Build(),
+                                test::GetDiagnostics()));
   Maybe<ResourceTable::SearchResult> search_result = table.FindResource(name);
 
   ASSERT_TRUE(search_result);
@@ -280,17 +298,20 @@
   auto group = std::make_shared<Overlayable>("Name", "overlay://theme");
   OverlayableItem overlayable(group);
   overlayable.policies = PolicyFlags::PRODUCT_PARTITION;
-  ASSERT_TRUE(table.SetOverlayable(foo, overlayable, test::GetDiagnostics()));
+  ASSERT_TRUE(table.AddResource(NewResourceBuilder(foo).SetOverlayable(overlayable).Build(),
+                                test::GetDiagnostics()));
 
   const ResourceName bar = test::ParseNameOrDie("android:string/bar");
   OverlayableItem overlayable2(group);
   overlayable2.policies = PolicyFlags::PRODUCT_PARTITION;
-  ASSERT_TRUE(table.SetOverlayable(bar, overlayable2, test::GetDiagnostics()));
+  ASSERT_TRUE(table.AddResource(NewResourceBuilder(bar).SetOverlayable(overlayable2).Build(),
+                                test::GetDiagnostics()));
 
   const ResourceName baz = test::ParseNameOrDie("android:string/baz");
   OverlayableItem overlayable3(group);
   overlayable3.policies = PolicyFlags::VENDOR_PARTITION;
-  ASSERT_TRUE(table.SetOverlayable(baz, overlayable3, test::GetDiagnostics()));
+  ASSERT_TRUE(table.AddResource(NewResourceBuilder(baz).SetOverlayable(overlayable3).Build(),
+                                test::GetDiagnostics()));
 }
 
 TEST(ResourceTableTest, SetOverlayableDifferentResourcesDifferentName) {
@@ -299,12 +320,14 @@
   const ResourceName foo = test::ParseNameOrDie("android:string/foo");
   OverlayableItem overlayable_item(std::make_shared<Overlayable>("Name", "overlay://theme"));
   overlayable_item.policies = PolicyFlags::PRODUCT_PARTITION;
-  ASSERT_TRUE(table.SetOverlayable(foo, overlayable_item, test::GetDiagnostics()));
+  ASSERT_TRUE(table.AddResource(NewResourceBuilder(foo).SetOverlayable(overlayable_item).Build(),
+                                test::GetDiagnostics()));
 
   const ResourceName bar = test::ParseNameOrDie("android:string/bar");
   OverlayableItem overlayable_item2(std::make_shared<Overlayable>("Name2",  "overlay://theme"));
   overlayable_item2.policies = PolicyFlags::PRODUCT_PARTITION;
-  ASSERT_TRUE(table.SetOverlayable(bar, overlayable_item2, test::GetDiagnostics()));
+  ASSERT_TRUE(table.AddResource(NewResourceBuilder(bar).SetOverlayable(overlayable_item2).Build(),
+                                test::GetDiagnostics()));
 }
 
 TEST(ResourceTableTest, SetOverlayableSameResourcesFail) {
@@ -313,10 +336,12 @@
 
   auto overlayable = std::make_shared<Overlayable>("Name", "overlay://theme");
   OverlayableItem overlayable_item(overlayable);
-  ASSERT_TRUE(table.SetOverlayable(name, overlayable_item, test::GetDiagnostics()));
+  ASSERT_TRUE(table.AddResource(NewResourceBuilder(name).SetOverlayable(overlayable_item).Build(),
+                                test::GetDiagnostics()));
 
   OverlayableItem overlayable_item2(overlayable);
-  ASSERT_FALSE(table.SetOverlayable(name, overlayable_item2, test::GetDiagnostics()));
+  ASSERT_FALSE(table.AddResource(NewResourceBuilder(name).SetOverlayable(overlayable_item2).Build(),
+                                 test::GetDiagnostics()));
 }
 
 TEST(ResourceTableTest,  SetOverlayableSameResourcesDifferentNameFail) {
@@ -325,51 +350,38 @@
 
   auto overlayable = std::make_shared<Overlayable>("Name", "overlay://theme");
   OverlayableItem overlayable_item(overlayable);
-  ASSERT_TRUE(table.SetOverlayable(name, overlayable_item, test::GetDiagnostics()));
+  ASSERT_TRUE(table.AddResource(NewResourceBuilder(name).SetOverlayable(overlayable_item).Build(),
+                                test::GetDiagnostics()));
 
   auto overlayable2 = std::make_shared<Overlayable>("Other", "overlay://theme");
   OverlayableItem overlayable_item2(overlayable2);
-  ASSERT_FALSE(table.SetOverlayable(name, overlayable_item2, test::GetDiagnostics()));
+  ASSERT_FALSE(table.AddResource(NewResourceBuilder(name).SetOverlayable(overlayable_item2).Build(),
+                                 test::GetDiagnostics()));
 }
 
-TEST(ResourceTableTest, AllowDuplictaeResourcesNames) {
-  ResourceTable table(/* validate_resources */ false);
+TEST(ResourceTableTest, ConflictingIds) {
+  ResourceTable table;
+  const ResourceName name = test::ParseNameOrDie("android:string/foo");
+  ASSERT_TRUE(table.AddResource(NewResourceBuilder(name).SetId(0x01010000).Build(),
+                                test::GetDiagnostics()));
+  ASSERT_FALSE(table.AddResource(NewResourceBuilder(name).SetId(0x01010001).Build(),
+                                 test::GetDiagnostics()));
+}
 
-  const ResourceName foo_name = test::ParseNameOrDie("android:bool/foo");
-  ASSERT_TRUE(table.AddResourceWithId(foo_name, ResourceId(0x7f0100ff), ConfigDescription{} , "",
-                                      test::BuildPrimitive(android::Res_value::TYPE_INT_BOOLEAN, 0),
-                                      test::GetDiagnostics()));
-  ASSERT_TRUE(table.AddResourceWithId(foo_name, ResourceId(0x7f010100), ConfigDescription{} , "",
-                                      test::BuildPrimitive(android::Res_value::TYPE_INT_BOOLEAN, 1),
-                                      test::GetDiagnostics()));
+TEST(ResourceTableTest, ConflictingIdsCreateEntry) {
+  ResourceTable table;
+  const ResourceName name = test::ParseNameOrDie("android:string/foo");
+  ASSERT_TRUE(table.AddResource(
+      NewResourceBuilder(name).SetId(0x01010000, OnIdConflict::CREATE_ENTRY).Build(),
+      test::GetDiagnostics()));
+  ASSERT_TRUE(table.AddResource(
+      NewResourceBuilder(name).SetId(0x01010001, OnIdConflict::CREATE_ENTRY).Build(),
+      test::GetDiagnostics()));
 
-  ASSERT_TRUE(table.SetVisibilityWithId(foo_name, Visibility{Visibility::Level::kPublic},
-                                        ResourceId(0x7f0100ff), test::GetDiagnostics()));
-  ASSERT_TRUE(table.SetVisibilityWithId(foo_name, Visibility{Visibility::Level::kPrivate},
-                                        ResourceId(0x7f010100), test::GetDiagnostics()));
-
-  auto package = table.FindPackageById(0x7f);
-  ASSERT_THAT(package, NotNull());
-  auto type = package->FindType(ResourceType::kBool);
-  ASSERT_THAT(type, NotNull());
-
-  auto entry1 = type->FindEntry("foo", 0x00ff);
-  ASSERT_THAT(entry1, NotNull());
-  ASSERT_THAT(entry1->id, Eq(0x00ff));
-  ASSERT_THAT(entry1->values[0], NotNull());
-  ASSERT_THAT(entry1->values[0]->value, NotNull());
-  ASSERT_THAT(ValueCast<BinaryPrimitive>(entry1->values[0]->value.get()), NotNull());
-  ASSERT_THAT(ValueCast<BinaryPrimitive>(entry1->values[0]->value.get())->value.data, Eq(0u));
-  ASSERT_THAT(entry1->visibility.level, Visibility::Level::kPublic);
-
-  auto entry2 = type->FindEntry("foo", 0x0100);
-  ASSERT_THAT(entry2, NotNull());
-  ASSERT_THAT(entry2->id, Eq(0x0100));
-  ASSERT_THAT(entry2->values[0], NotNull());
-  ASSERT_THAT(entry1->values[0]->value, NotNull());
-  ASSERT_THAT(ValueCast<BinaryPrimitive>(entry2->values[0]->value.get()), NotNull());
-  ASSERT_THAT(ValueCast<BinaryPrimitive>(entry2->values[0]->value.get())->value.data, Eq(1u));
-  ASSERT_THAT(entry2->visibility.level, Visibility::Level::kPrivate);
+  // Non-ambiguous query
+  ASSERT_TRUE(table.AddResource(
+      NewResourceBuilder(name).SetId(0x01010001).SetValue(std::make_unique<Id>()).Build(),
+      test::GetDiagnostics()));
 }
 
 }  // namespace aapt
diff --git a/tools/aapt2/Resources.proto b/tools/aapt2/Resources.proto
index b1e1a77..4247ec5 100644
--- a/tools/aapt2/Resources.proto
+++ b/tools/aapt2/Resources.proto
@@ -132,6 +132,11 @@
 
   // The comment associated with the <public> tag.
   string comment = 3;
+
+  // Indicates that the resource id may change across builds and that the public R.java identifier
+  // for this resource should not be final. This is set to `true` for resources in `staging-group`
+  // tags.
+  bool staged_api = 4;
 }
 
 // Whether a resource comes from a compile-time overlay and is explicitly allowed to not overlay an
diff --git a/tools/aapt2/cmd/Compile.cpp b/tools/aapt2/cmd/Compile.cpp
index ff54fcc..cd5015e 100644
--- a/tools/aapt2/cmd/Compile.cpp
+++ b/tools/aapt2/cmd/Compile.cpp
@@ -190,17 +190,6 @@
     }
   }
 
-  // Ensure we have the compilation package at least.
-  table.CreatePackage(context->GetCompilationPackage());
-
-  // Assign an ID to any package that has resources.
-  for (auto& pkg : table.packages) {
-    if (!pkg->id) {
-      // If no package ID was set while parsing (public identifiers), auto assign an ID.
-      pkg->id = context->GetPackageId();
-    }
-  }
-
   // Create the file/zip entry.
   if (!writer->StartEntry(output_path, 0)) {
     context->GetDiagnostics()->Error(DiagMessage(output_path) << "failed to open");
diff --git a/tools/aapt2/cmd/Compile_test.cpp b/tools/aapt2/cmd/Compile_test.cpp
index 8cbd998..8975713 100644
--- a/tools/aapt2/cmd/Compile_test.cpp
+++ b/tools/aapt2/cmd/Compile_test.cpp
@@ -217,6 +217,7 @@
   }, compiled_files_dir, &diag));
 
   std::unique_ptr<LoadedApk> apk = LoadedApk::LoadApkFromPath(out_apk, &diag);
+  ASSERT_NE(apk, nullptr);
 
   ResourceTable* table = apk->GetResourceTable();
   ASSERT_NE(table, nullptr);
diff --git a/tools/aapt2/cmd/Diff.cpp b/tools/aapt2/cmd/Diff.cpp
index d56994e..0bb044e 100644
--- a/tools/aapt2/cmd/Diff.cpp
+++ b/tools/aapt2/cmd/Diff.cpp
@@ -95,17 +95,17 @@
   return false;
 }
 
-static bool EmitResourceConfigValueDiff(IAaptContext* context, LoadedApk* apk_a,
-                                        ResourceTablePackage* pkg_a, ResourceTableType* type_a,
-                                        ResourceEntry* entry_a, ResourceConfigValue* config_value_a,
-                                        LoadedApk* apk_b, ResourceTablePackage* pkg_b,
-                                        ResourceTableType* type_b, ResourceEntry* entry_b,
-                                        ResourceConfigValue* config_value_b) {
+static bool EmitResourceConfigValueDiff(
+    IAaptContext* context, LoadedApk* apk_a, const ResourceTablePackageView& pkg_a,
+    const ResourceTableTypeView& type_a, const ResourceEntry* entry_a,
+    const ResourceConfigValue* config_value_a, LoadedApk* apk_b,
+    const ResourceTablePackageView& pkg_b, const ResourceTableTypeView& type_b,
+    const ResourceEntry* entry_b, const ResourceConfigValue* config_value_b) {
   Value* value_a = config_value_a->value.get();
   Value* value_b = config_value_b->value.get();
   if (!value_a->Equals(value_b)) {
     std::stringstream str_stream;
-    str_stream << "value " << pkg_a->name << ":" << type_a->type << "/" << entry_a->name
+    str_stream << "value " << pkg_a.name << ":" << type_a.type << "/" << entry_a->name
                << " config=" << config_value_a->config << " does not match:\n";
     value_a->Print(&str_stream);
     str_stream << "\n vs \n";
@@ -117,16 +117,17 @@
 }
 
 static bool EmitResourceEntryDiff(IAaptContext* context, LoadedApk* apk_a,
-                                  ResourceTablePackage* pkg_a, ResourceTableType* type_a,
-                                  ResourceEntry* entry_a, LoadedApk* apk_b,
-                                  ResourceTablePackage* pkg_b, ResourceTableType* type_b,
-                                  ResourceEntry* entry_b) {
+                                  const ResourceTablePackageView& pkg_a,
+                                  const ResourceTableTypeView& type_a, const ResourceEntry* entry_a,
+                                  LoadedApk* apk_b, const ResourceTablePackageView& pkg_b,
+                                  const ResourceTableTypeView& type_b,
+                                  const ResourceEntry* entry_b) {
   bool diff = false;
-  for (std::unique_ptr<ResourceConfigValue>& config_value_a : entry_a->values) {
-    ResourceConfigValue* config_value_b = entry_b->FindValue(config_value_a->config);
+  for (const std::unique_ptr<ResourceConfigValue>& config_value_a : entry_a->values) {
+    auto config_value_b = entry_b->FindValue(config_value_a->config);
     if (!config_value_b) {
       std::stringstream str_stream;
-      str_stream << "missing " << pkg_a->name << ":" << type_a->type << "/" << entry_a->name
+      str_stream << "missing " << pkg_a.name << ":" << type_a.type << "/" << entry_a->name
                  << " config=" << config_value_a->config;
       EmitDiffLine(apk_b->GetSource(), str_stream.str());
       diff = true;
@@ -138,35 +139,47 @@
   }
 
   // Check for any newly added config values.
-  for (std::unique_ptr<ResourceConfigValue>& config_value_b : entry_b->values) {
-    ResourceConfigValue* config_value_a = entry_a->FindValue(config_value_b->config);
+  for (const std::unique_ptr<ResourceConfigValue>& config_value_b : entry_b->values) {
+    auto config_value_a = entry_a->FindValue(config_value_b->config);
     if (!config_value_a) {
       std::stringstream str_stream;
-      str_stream << "new config " << pkg_b->name << ":" << type_b->type << "/" << entry_b->name
+      str_stream << "new config " << pkg_b.name << ":" << type_b.type << "/" << entry_b->name
                  << " config=" << config_value_b->config;
       EmitDiffLine(apk_b->GetSource(), str_stream.str());
       diff = true;
     }
   }
-  return false;
+  return diff;
 }
 
 static bool EmitResourceTypeDiff(IAaptContext* context, LoadedApk* apk_a,
-                                 ResourceTablePackage* pkg_a, ResourceTableType* type_a,
-                                 LoadedApk* apk_b, ResourceTablePackage* pkg_b,
-                                 ResourceTableType* type_b) {
+                                 const ResourceTablePackageView& pkg_a,
+                                 const ResourceTableTypeView& type_a, LoadedApk* apk_b,
+                                 const ResourceTablePackageView& pkg_b,
+                                 const ResourceTableTypeView& type_b) {
   bool diff = false;
-  for (std::unique_ptr<ResourceEntry>& entry_a : type_a->entries) {
-    ResourceEntry* entry_b = type_b->FindEntry(entry_a->name);
-    if (!entry_b) {
+  auto entry_a_iter = type_a.entries.begin();
+  auto entry_b_iter = type_b.entries.begin();
+  while (entry_a_iter != type_a.entries.end() || entry_b_iter != type_b.entries.end()) {
+    if (entry_b_iter == type_b.entries.end()) {
+      // Type A contains a type that type B does not have.
       std::stringstream str_stream;
-      str_stream << "missing " << pkg_a->name << ":" << type_a->type << "/" << entry_a->name;
+      str_stream << "missing " << pkg_a.name << ":" << type_a.type << "/" << (*entry_a_iter)->name;
+      EmitDiffLine(apk_a->GetSource(), str_stream.str());
+      diff = true;
+    } else if (entry_a_iter == type_a.entries.end()) {
+      // Type B contains a type that type A does not have.
+      std::stringstream str_stream;
+      str_stream << "new entry " << pkg_b.name << ":" << type_b.type << "/"
+                 << (*entry_b_iter)->name;
       EmitDiffLine(apk_b->GetSource(), str_stream.str());
       diff = true;
     } else {
+      const auto& entry_a = *entry_a_iter;
+      const auto& entry_b = *entry_a_iter;
       if (IsSymbolVisibilityDifferent(entry_a->visibility, entry_b->visibility)) {
         std::stringstream str_stream;
-        str_stream << pkg_a->name << ":" << type_a->type << "/" << entry_a->name
+        str_stream << pkg_a.name << ":" << type_a.type << "/" << entry_a->name
                    << " has different visibility (";
         if (entry_b->visibility.level == Visibility::Level::kPublic) {
           str_stream << "PUBLIC";
@@ -185,7 +198,7 @@
       } else if (IsIdDiff(entry_a->visibility.level, entry_a->id, entry_b->visibility.level,
                           entry_b->id)) {
         std::stringstream str_stream;
-        str_stream << pkg_a->name << ":" << type_a->type << "/" << entry_a->name
+        str_stream << pkg_a.name << ":" << type_a.type << "/" << entry_a->name
                    << " has different public ID (";
         if (entry_b->id) {
           str_stream << "0x" << std::hex << entry_b->id.value();
@@ -202,46 +215,43 @@
         EmitDiffLine(apk_b->GetSource(), str_stream.str());
         diff = true;
       }
-      diff |= EmitResourceEntryDiff(context, apk_a, pkg_a, type_a, entry_a.get(), apk_b, pkg_b,
-                                    type_b, entry_b);
-    }
-  }
-
-  // Check for any newly added entries.
-  for (std::unique_ptr<ResourceEntry>& entry_b : type_b->entries) {
-    ResourceEntry* entry_a = type_a->FindEntry(entry_b->name);
-    if (!entry_a) {
-      std::stringstream str_stream;
-      str_stream << "new entry " << pkg_b->name << ":" << type_b->type << "/" << entry_b->name;
-      EmitDiffLine(apk_b->GetSource(), str_stream.str());
-      diff = true;
+      diff |= EmitResourceEntryDiff(context, apk_a, pkg_a, type_a, entry_a, apk_b, pkg_b, type_b,
+                                    entry_b);
     }
   }
   return diff;
 }
 
 static bool EmitResourcePackageDiff(IAaptContext* context, LoadedApk* apk_a,
-                                    ResourceTablePackage* pkg_a, LoadedApk* apk_b,
-                                    ResourceTablePackage* pkg_b) {
+                                    const ResourceTablePackageView& pkg_a, LoadedApk* apk_b,
+                                    const ResourceTablePackageView& pkg_b) {
   bool diff = false;
-  for (std::unique_ptr<ResourceTableType>& type_a : pkg_a->types) {
-    ResourceTableType* type_b = pkg_b->FindType(type_a->type);
-    if (!type_b) {
+  auto type_a_iter = pkg_a.types.begin();
+  auto type_b_iter = pkg_b.types.begin();
+  while (type_a_iter != pkg_a.types.end() || type_b_iter != pkg_b.types.end()) {
+    if (type_b_iter == pkg_b.types.end()) {
+      // Type A contains a type that type B does not have.
       std::stringstream str_stream;
-      str_stream << "missing " << pkg_a->name << ":" << type_a->type;
+      str_stream << "missing " << pkg_a.name << ":" << type_a_iter->type;
       EmitDiffLine(apk_a->GetSource(), str_stream.str());
       diff = true;
+    } else if (type_a_iter == pkg_a.types.end()) {
+      // Type B contains a type that type A does not have.
+      std::stringstream str_stream;
+      str_stream << "new type " << pkg_b.name << ":" << type_b_iter->type;
+      EmitDiffLine(apk_b->GetSource(), str_stream.str());
+      diff = true;
     } else {
-      if (type_a->visibility_level != type_b->visibility_level) {
+      if (type_a_iter->visibility_level != type_b_iter->visibility_level) {
         std::stringstream str_stream;
-        str_stream << pkg_a->name << ":" << type_a->type << " has different visibility (";
-        if (type_b->visibility_level == Visibility::Level::kPublic) {
+        str_stream << pkg_a.name << ":" << type_a_iter->type << " has different visibility (";
+        if (type_b_iter->visibility_level == Visibility::Level::kPublic) {
           str_stream << "PUBLIC";
         } else {
           str_stream << "PRIVATE";
         }
         str_stream << " vs ";
-        if (type_a->visibility_level == Visibility::Level::kPublic) {
+        if (type_a_iter->visibility_level == Visibility::Level::kPublic) {
           str_stream << "PUBLIC";
         } else {
           str_stream << "PRIVATE";
@@ -249,18 +259,18 @@
         str_stream << ")";
         EmitDiffLine(apk_b->GetSource(), str_stream.str());
         diff = true;
-      } else if (IsIdDiff(type_a->visibility_level, type_a->id, type_b->visibility_level,
-                          type_b->id)) {
+      } else if (IsIdDiff(type_a_iter->visibility_level, type_a_iter->id,
+                          type_b_iter->visibility_level, type_b_iter->id)) {
         std::stringstream str_stream;
-        str_stream << pkg_a->name << ":" << type_a->type << " has different public ID (";
-        if (type_b->id) {
-          str_stream << "0x" << std::hex << type_b->id.value();
+        str_stream << pkg_a.name << ":" << type_a_iter->type << " has different public ID (";
+        if (type_b_iter->id) {
+          str_stream << "0x" << std::hex << type_b_iter->id.value();
         } else {
           str_stream << "none";
         }
         str_stream << " vs ";
-        if (type_a->id) {
-          str_stream << "0x " << std::hex << type_a->id.value();
+        if (type_a_iter->id) {
+          str_stream << "0x " << std::hex << type_a_iter->id.value();
         } else {
           str_stream << "none";
         }
@@ -268,47 +278,44 @@
         EmitDiffLine(apk_b->GetSource(), str_stream.str());
         diff = true;
       }
-      diff |= EmitResourceTypeDiff(context, apk_a, pkg_a, type_a.get(), apk_b, pkg_b, type_b);
-    }
-  }
-
-  // Check for any newly added types.
-  for (std::unique_ptr<ResourceTableType>& type_b : pkg_b->types) {
-    ResourceTableType* type_a = pkg_a->FindType(type_b->type);
-    if (!type_a) {
-      std::stringstream str_stream;
-      str_stream << "new type " << pkg_b->name << ":" << type_b->type;
-      EmitDiffLine(apk_b->GetSource(), str_stream.str());
-      diff = true;
+      diff |= EmitResourceTypeDiff(context, apk_a, pkg_a, *type_a_iter, apk_b, pkg_b, *type_b_iter);
     }
   }
   return diff;
 }
 
 static bool EmitResourceTableDiff(IAaptContext* context, LoadedApk* apk_a, LoadedApk* apk_b) {
-  ResourceTable* table_a = apk_a->GetResourceTable();
-  ResourceTable* table_b = apk_b->GetResourceTable();
+  const auto table_a = apk_a->GetResourceTable()->GetPartitionedView();
+  const auto table_b = apk_b->GetResourceTable()->GetPartitionedView();
 
   bool diff = false;
-  for (std::unique_ptr<ResourceTablePackage>& pkg_a : table_a->packages) {
-    ResourceTablePackage* pkg_b = table_b->FindPackage(pkg_a->name);
-    if (!pkg_b) {
+  auto package_a_iter = table_a.packages.begin();
+  auto package_b_iter = table_b.packages.begin();
+  while (package_a_iter != table_a.packages.end() || package_b_iter != table_b.packages.end()) {
+    if (package_b_iter == table_b.packages.end()) {
+      // Table A contains a package that table B does not have.
       std::stringstream str_stream;
-      str_stream << "missing package " << pkg_a->name;
+      str_stream << "missing package " << package_a_iter->name;
+      EmitDiffLine(apk_a->GetSource(), str_stream.str());
+      diff = true;
+    } else if (package_a_iter == table_a.packages.end()) {
+      // Table B contains a package that table A does not have.
+      std::stringstream str_stream;
+      str_stream << "new package " << package_b_iter->name;
       EmitDiffLine(apk_b->GetSource(), str_stream.str());
       diff = true;
     } else {
-      if (pkg_a->id != pkg_b->id) {
+      if (package_a_iter->id != package_b_iter->id) {
         std::stringstream str_stream;
-        str_stream << "package '" << pkg_a->name << "' has different id (";
-        if (pkg_b->id) {
-          str_stream << "0x" << std::hex << pkg_b->id.value();
+        str_stream << "package '" << package_a_iter->name << "' has different id (";
+        if (package_b_iter->id) {
+          str_stream << "0x" << std::hex << package_b_iter->id.value();
         } else {
           str_stream << "none";
         }
         str_stream << " vs ";
-        if (pkg_a->id) {
-          str_stream << "0x" << std::hex << pkg_a->id.value();
+        if (package_a_iter->id) {
+          str_stream << "0x" << std::hex << package_b_iter->id.value();
         } else {
           str_stream << "none";
         }
@@ -316,20 +323,10 @@
         EmitDiffLine(apk_b->GetSource(), str_stream.str());
         diff = true;
       }
-      diff |= EmitResourcePackageDiff(context, apk_a, pkg_a.get(), apk_b, pkg_b);
+      diff |= EmitResourcePackageDiff(context, apk_a, *package_a_iter, apk_b, *package_b_iter);
     }
   }
 
-  // Check for any newly added packages.
-  for (std::unique_ptr<ResourceTablePackage>& pkg_b : table_b->packages) {
-    ResourceTablePackage* pkg_a = table_a->FindPackage(pkg_b->name);
-    if (!pkg_a) {
-      std::stringstream str_stream;
-      str_stream << "new package " << pkg_b->name;
-      EmitDiffLine(apk_b->GetSource(), str_stream.str());
-      diff = true;
-    }
-  }
   return diff;
 }
 
diff --git a/tools/aapt2/cmd/Link.cpp b/tools/aapt2/cmd/Link.cpp
index 13e090d..ee6a764 100644
--- a/tools/aapt2/cmd/Link.cpp
+++ b/tools/aapt2/cmd/Link.cpp
@@ -25,6 +25,7 @@
 #include <vector>
 
 #include "android-base/errors.h"
+#include "android-base/expected.h"
 #include "android-base/file.h"
 #include "android-base/stringprintf.h"
 #include "androidfw/Locale.h"
@@ -74,10 +75,25 @@
 using ::aapt::io::FileInputStream;
 using ::android::ConfigDescription;
 using ::android::StringPiece;
+using ::android::base::expected;
 using ::android::base::StringPrintf;
+using ::android::base::unexpected;
 
 namespace aapt {
 
+namespace {
+
+expected<ResourceTablePackage*, const char*> GetStaticLibraryPackage(ResourceTable* table) {
+  // Resource tables built by aapt2 always contain one package. This is a post condition of
+  // VerifyNoExternalPackages.
+  if (table->packages.size() != 1u) {
+    return unexpected("static library contains more than one package");
+  }
+  return table->packages.back().get();
+}
+
+}  // namespace
+
 constexpr uint8_t kAndroidPackageId = 0x01;
 
 class LinkContext : public IAaptContext {
@@ -633,13 +649,18 @@
               const ResourceFile& file = doc->file;
               dst_path = ResourceUtils::BuildResourceFileName(file, context_->GetNameMangler());
 
-              std::unique_ptr<FileReference> file_ref =
+              auto file_ref =
                   util::make_unique<FileReference>(table->string_pool.MakeRef(dst_path));
               file_ref->SetSource(doc->file.source);
+
               // Update the output format of this XML file.
               file_ref->type = XmlFileTypeForOutputFormat(options_.output_format);
-              if (!table->AddResourceMangled(file.name, file.config, {}, std::move(file_ref),
-                                             context_->GetDiagnostics())) {
+              bool result = table->AddResource(NewResourceBuilder(file.name)
+                                                   .SetValue(std::move(file_ref), file.config)
+                                                   .SetAllowMangled(true)
+                                                   .Build(),
+                                               context_->GetDiagnostics());
+              if (!result) {
                 return false;
               }
             }
@@ -842,18 +863,15 @@
         ResourceTable* table = static_apk->GetResourceTable();
 
         // If we are using --no-static-lib-packages, we need to rename the package of this table to
-        // our compilation package.
-        if (options_.no_static_lib_packages) {
-          // Since package names can differ, and multiple packages can exist in a ResourceTable,
-          // we place the requirement that all static libraries are built with the package
-          // ID 0x7f. So if one is not found, this is an error.
-          if (ResourceTablePackage* pkg = table->FindPackageById(kAppPackageId)) {
-            pkg->name = context_->GetCompilationPackage();
-          } else {
-            context_->GetDiagnostics()->Error(DiagMessage(path)
-                                              << "no package with ID 0x7f found in static library");
+        // our compilation package so the symbol package name does not get mangled into the entry
+        // name.
+        if (options_.no_static_lib_packages && !table->packages.empty()) {
+          auto lib_package_result = GetStaticLibraryPackage(table);
+          if (!lib_package_result.has_value()) {
+            context_->GetDiagnostics()->Error(DiagMessage(path) << lib_package_result.error());
             return false;
           }
+          lib_package_result.value()->name = context_->GetCompilationPackage();
         }
 
         context_->GetExternalSymbols()->AppendSource(
@@ -982,8 +1000,7 @@
   // stripped, or there is an error and false is returned.
   bool VerifyNoExternalPackages() {
     auto is_ext_package_func = [&](const std::unique_ptr<ResourceTablePackage>& pkg) -> bool {
-      return context_->GetCompilationPackage() != pkg->name || !pkg->id ||
-             pkg->id.value() != context_->GetPackageId();
+      return context_->GetCompilationPackage() != pkg->name;
     };
 
     bool error = false;
@@ -1027,19 +1044,11 @@
   bool VerifyNoIdsSet() {
     for (const auto& package : final_table_.packages) {
       for (const auto& type : package->types) {
-        if (type->id) {
-          context_->GetDiagnostics()->Error(DiagMessage() << "type " << type->type << " has ID "
-                                                          << StringPrintf("%02x", type->id.value())
-                                                          << " assigned");
-          return false;
-        }
-
         for (const auto& entry : type->entries) {
           if (entry->id) {
             ResourceNameRef res_name(package->name, type->type, entry->name);
-            context_->GetDiagnostics()->Error(
-                DiagMessage() << "entry " << res_name << " has ID "
-                              << StringPrintf("%02x", entry->id.value()) << " assigned");
+            context_->GetDiagnostics()->Error(DiagMessage() << "resource " << res_name << " has ID "
+                                                            << entry->id.value() << " assigned");
             return false;
           }
         }
@@ -1313,12 +1322,17 @@
     }
 
     ResourceTable* table = apk->GetResourceTable();
-    ResourceTablePackage* pkg = table->FindPackageById(kAppPackageId);
-    if (!pkg) {
-      context_->GetDiagnostics()->Error(DiagMessage(input) << "static library has no package");
+    if (table->packages.empty()) {
+      return true;
+    }
+
+    auto lib_package_result = GetStaticLibraryPackage(table);
+    if (!lib_package_result.has_value()) {
+      context_->GetDiagnostics()->Error(DiagMessage(input) << lib_package_result.error());
       return false;
     }
 
+    ResourceTablePackage* pkg = lib_package_result.value();
     bool result;
     if (options_.no_static_lib_packages) {
       // Merge all resources as if they were in the compilation package. This is the old behavior
@@ -1365,11 +1379,11 @@
         res_name = mangled_name.value();
       }
 
-      std::unique_ptr<Id> id = util::make_unique<Id>();
+      auto id = util::make_unique<Id>();
       id->SetSource(source.WithLine(exported_symbol.line));
-      bool result =
-          final_table_.AddResourceMangled(res_name, ConfigDescription::DefaultConfig(),
-                                          std::string(), std::move(id), context_->GetDiagnostics());
+      bool result = final_table_.AddResource(
+          NewResourceBuilder(res_name).SetValue(std::move(id)).SetAllowMangled(true).Build(),
+          context_->GetDiagnostics());
       if (!result) {
         return false;
       }
@@ -1750,7 +1764,7 @@
     // anything else being generated, which includes the Java classes.
     // If required, the package name is modifed before flattening, and then modified back
     // to its original name.
-    ResourceTablePackage* package_to_rewrite = nullptr;
+    std::optional<ResourceTablePackageView> package_to_rewrite;
     // Pre-O, the platform treats negative resource IDs [those with a package ID of 0x80
     // or higher] as invalid. In order to work around this limitation, we allow the use
     // of traditionally reserved resource IDs [those between 0x02 and 0x7E]. Allow the
@@ -1764,10 +1778,11 @@
       // The base APK is included, and this is a feature split. If the base package is
       // the same as this package, then we are building an old style Android Instant Apps feature
       // split and must apply this workaround to avoid requiring namespaces support.
-      package_to_rewrite = table->FindPackage(context_->GetCompilationPackage());
-      if (package_to_rewrite != nullptr) {
+      auto table_view = table->GetPartitionedView();
+      if (!table_view.packages.empty() &&
+          table_view.packages.back().name == context_->GetCompilationPackage()) {
+        package_to_rewrite = std::move(table_view.packages.back());
         CHECK_EQ(1u, table->packages.size()) << "can't change name of package when > 1 package";
-
         std::string new_package_name =
             StringPrintf("%s.%s", package_to_rewrite->name.c_str(),
                          app_info_.split_name.value_or_default("feature").c_str());
@@ -1783,7 +1798,7 @@
 
     bool success = FlattenTable(table, options_.output_format, writer);
 
-    if (package_to_rewrite != nullptr) {
+    if (package_to_rewrite.has_value()) {
       // Change the name back.
       package_to_rewrite->name = context_->GetCompilationPackage();
       if (package_to_rewrite->id) {
@@ -1925,8 +1940,7 @@
             for (auto& entry : type->entries) {
               ResourceName name(package->name, type->type, entry->name);
               // The IDs are guaranteed to exist.
-              options_.stable_id_map[std::move(name)] =
-                  ResourceId(package->id.value(), type->id.value(), entry->id.value());
+              options_.stable_id_map[std::move(name)] = entry->id.value();
             }
           }
         }
diff --git a/tools/aapt2/cmd/Link_test.cpp b/tools/aapt2/cmd/Link_test.cpp
index 73072a9..dfdac6b 100644
--- a/tools/aapt2/cmd/Link_test.cpp
+++ b/tools/aapt2/cmd/Link_test.cpp
@@ -25,6 +25,7 @@
 using testing::Eq;
 using testing::HasSubstr;
 using testing::Ne;
+using testing::NotNull;
 
 namespace aapt {
 
@@ -47,6 +48,8 @@
   // Load the binary xml tree
   android::ResXMLTree tree;
   std::unique_ptr<LoadedApk> apk = LoadedApk::LoadApkFromPath(out_apk, &diag);
+  ASSERT_THAT(apk, Ne(nullptr));
+
   std::unique_ptr<io::IData> data = OpenFileAsData(apk.get(), "res/xml/test.xml");
   ASSERT_THAT(data, Ne(nullptr));
   AssertLoadXml(apk.get(), data.get(), &tree);
@@ -73,6 +76,8 @@
   // Load the binary xml tree
   android::ResXMLTree tree;
   std::unique_ptr<LoadedApk> apk = LoadedApk::LoadApkFromPath(out_apk, &diag);
+  ASSERT_THAT(apk, Ne(nullptr));
+
   std::unique_ptr<io::IData> data = OpenFileAsData(apk.get(), "res/xml/test.xml");
   ASSERT_THAT(data, Ne(nullptr));
   AssertLoadXml(apk.get(), data.get(), &tree);
@@ -208,6 +213,8 @@
   ASSERT_TRUE(Link(link_args, compiled_files_dir, &diag));
 
   std::unique_ptr<LoadedApk> apk = LoadedApk::LoadApkFromPath(out_apk, &diag);
+  ASSERT_THAT(apk, Ne(nullptr));
+
   const Style* actual_style = test::GetValue<Style>(
       apk->GetResourceTable(), std::string(kDefaultPackageName) + ":style/MyStyle");
   ASSERT_NE(actual_style, nullptr);
@@ -250,6 +257,8 @@
   ASSERT_TRUE(Link(link_args, compiled_files_dir, &diag));
 
   std::unique_ptr<LoadedApk> apk = LoadedApk::LoadApkFromPath(out_apk, &diag);
+  ASSERT_THAT(apk, Ne(nullptr));
+
   const Style* actual_style = test::GetValue<Style>(
       apk->GetResourceTable(), std::string(kDefaultPackageName) + ":style/MyStyle");
   ASSERT_NE(actual_style, nullptr);
@@ -392,4 +401,127 @@
   EXPECT_THAT(client_r_contents, HasSubstr(" com.example.lib.R.attr.foo, 0x7f010000"));
 }
 
+TEST_F(LinkTest, StagedAndroidApi) {
+  StdErrDiagnostics diag;
+  const std::string android_values =
+      R"(<resources>
+          <public type="attr" name="finalized_res" id="0x01010001"/>
+
+          <!-- S staged attributes (support staged resources in the same type id) -->
+          <staging-public-group type="attr" first-id="0x01010050">
+            <public name="staged_s_res" />
+          </staging-public-group>
+
+          <!-- SV2 staged attributes (support staged resources in a separate type id) -->
+          <staging-public-group type="attr" first-id="0x01ff0049">
+            <public name="staged_s2_res" />
+          </staging-public-group>
+
+          <!-- T staged attributes (support staged resources in multiple separate type ids) -->
+          <staging-public-group type="attr" first-id="0x01fe0063">
+            <public name="staged_t_res" />
+          </staging-public-group>
+
+          <staging-public-group type="string" first-id="0x01fd0072">
+            <public name="staged_t_string" />
+          </staging-public-group>
+
+          <attr name="finalized_res" />
+          <attr name="staged_s_res" />
+          <attr name="staged_s2_res" />
+          <attr name="staged_t_res" />
+          <string name="staged_t_string">Hello</string>
+         </resources>)";
+
+  const std::string app_values =
+      R"(<resources xmlns:android="http://schemas.android.com/apk/res/android">
+           <attr name="bar" />
+           <declare-styleable name="ClientStyleable">
+             <attr name="android:finalized_res" />
+             <attr name="android:staged_s_res" />
+             <attr name="bar" />
+           </declare-styleable>
+         </resources>)";
+
+  const std::string android_res = GetTestPath("android-res");
+  ASSERT_TRUE(
+      CompileFile(GetTestPath("res/values/values.xml"), android_values, android_res, &diag));
+
+  const std::string android_apk = GetTestPath("android.apk");
+  const std::string android_java = GetTestPath("android_java");
+  // clang-format off
+  auto android_manifest = ManifestBuilder(this)
+      .SetPackageName("android")
+      .Build();
+
+  auto android_link_args = LinkCommandBuilder(this)
+      .SetManifestFile(android_manifest)
+      .AddParameter("--private-symbols", "com.android.internal")
+      .AddParameter("--java", android_java)
+      .AddCompiledResDir(android_res, &diag)
+      .Build(android_apk);
+  // clang-format on
+  ASSERT_TRUE(Link(android_link_args, &diag));
+
+  const std::string android_r_java = android_java + "/android/R.java";
+  std::string android_r_contents;
+  ASSERT_TRUE(android::base::ReadFileToString(android_r_java, &android_r_contents));
+  EXPECT_THAT(android_r_contents, HasSubstr(" public static final int finalized_res=0x01010001;"));
+  EXPECT_THAT(android_r_contents, HasSubstr(" public static int staged_s_res=0x01010050;"));
+  EXPECT_THAT(android_r_contents, HasSubstr(" public static int staged_s2_res=0x01ff0049;"));
+  EXPECT_THAT(android_r_contents, HasSubstr(" public static int staged_t_res=0x01fe0063;"));
+  EXPECT_THAT(android_r_contents, HasSubstr(" public static int staged_t_string=0x01fd0072;"));
+
+  // Build an app that uses the framework attribute in a declare-styleable
+  const std::string client_res = GetTestPath("app-res");
+  ASSERT_TRUE(CompileFile(GetTestPath("res/values/values.xml"), app_values, client_res, &diag));
+
+  const std::string app_apk = GetTestPath("app.apk");
+  const std::string app_java = GetTestPath("app_java");
+  // clang-format off
+  auto app_manifest = ManifestBuilder(this)
+      .SetPackageName("com.example.app")
+      .Build();
+
+  auto app_link_args = LinkCommandBuilder(this)
+      .SetManifestFile(app_manifest)
+      .AddParameter("--java", app_java)
+      .AddParameter("-I", android_apk)
+      .AddCompiledResDir(client_res, &diag)
+      .Build(app_apk);
+  // clang-format on
+  ASSERT_TRUE(Link(app_link_args, &diag));
+
+  const std::string client_r_java = app_java + "/com/example/app/R.java";
+  std::string client_r_contents;
+  ASSERT_TRUE(android::base::ReadFileToString(client_r_java, &client_r_contents));
+  EXPECT_THAT(client_r_contents, HasSubstr(" 0x01010001, android.R.attr.staged_s_res, 0x7f010000"));
+
+  // Test that the resource ids of staged and non-staged resource can be retrieved
+  android::AssetManager2 am;
+  auto android_asset = android::ApkAssets::Load(android_apk);
+  ASSERT_THAT(android_asset, NotNull());
+  ASSERT_TRUE(am.SetApkAssets({android_asset.get()}));
+
+  auto result = am.GetResourceId("android:attr/finalized_res");
+  ASSERT_TRUE(result.has_value());
+  EXPECT_THAT(*result, Eq(0x01010001));
+
+  result = am.GetResourceId("android:attr/staged_s_res");
+  ASSERT_TRUE(result.has_value());
+  EXPECT_THAT(*result, Eq(0x01010050));
+
+  result = am.GetResourceId("android:attr/staged_s2_res");
+  ASSERT_TRUE(result.has_value());
+  EXPECT_THAT(*result, Eq(0x01ff0049));
+
+  result = am.GetResourceId("android:attr/staged_t_res");
+  ASSERT_TRUE(result.has_value());
+  EXPECT_THAT(*result, Eq(0x01fe0063));
+
+  result = am.GetResourceId("android:string/staged_t_string");
+  ASSERT_TRUE(result.has_value());
+  EXPECT_THAT(*result, Eq(0x01fd0072));
+}
+
 }  // namespace aapt
diff --git a/tools/aapt2/compile/IdAssigner.cpp b/tools/aapt2/compile/IdAssigner.cpp
index 17c22c5..9a50b26 100644
--- a/tools/aapt2/compile/IdAssigner.cpp
+++ b/tools/aapt2/compile/IdAssigner.cpp
@@ -17,76 +17,135 @@
 #include "compile/IdAssigner.h"
 
 #include <map>
+#include <unordered_map>
 
+#include "android-base/expected.h"
 #include "android-base/logging.h"
 
 #include "ResourceTable.h"
 #include "process/IResourceTableConsumer.h"
 #include "util/Util.h"
 
+using android::base::expected;
+using android::base::unexpected;
+
 namespace aapt {
 
-/**
- * Assigns the intended ID to the ResourceTablePackage, ResourceTableType, and
- * ResourceEntry,
- * as long as there is no existing ID or the ID is the same.
- */
-static bool AssignId(IDiagnostics* diag, const ResourceId& id,
-                     const ResourceName& name, ResourceTablePackage* pkg,
-                     ResourceTableType* type, ResourceEntry* entry) {
-  if (pkg->id.value() == id.package_id()) {
-    if (!type->id || type->id.value() == id.type_id()) {
-      type->id = id.type_id();
+namespace {
+template <typename T>
+using Result = expected<T, std::string>;
 
-      if (!entry->id || entry->id.value() == id.entry_id()) {
-        entry->id = id.entry_id();
-        return true;
-      }
-    }
+template <typename Id, typename Key>
+struct NextIdFinder {
+  explicit NextIdFinder(Id start_id = 0u) : next_id_(start_id){};
+
+  // Attempts to reserve an identifier for the specified key.
+  // If the identifier is already reserved by a different key, an error message is returned.
+  // Reserving identifiers must be completed before `NextId` is called for the first time.
+  Result<Id> ReserveId(Key key, Id id);
+
+  // Retrieves the next available identifier that has not been reserved.
+  std::optional<Id> NextId();
+
+ private:
+  // Attempts to set `next_id_` to the next available identifier that has not been reserved.
+  // Returns whether there were any available identifiers.
+  std::optional<Id> SkipToNextAvailableId();
+
+  Id next_id_;
+  bool next_id_called_ = false;
+  bool exhausted_ = false;
+  std::map<Id, Key> pre_assigned_ids_;
+  typename std::map<Id, Key>::iterator next_preassigned_id_;
+};
+
+struct TypeGroup {
+  explicit TypeGroup(uint8_t package_id, uint8_t type_id)
+      : package_id_(package_id), type_id_(type_id){};
+
+  // Attempts to reserve the resource id for the specified resource name.
+  // If the id is already reserved by a different name, an error message is returned.
+  // Reserving identifiers must be completed before `NextId` is called for the first time.
+  Result<std::monostate> ReserveId(const ResourceName& name, ResourceId id);
+
+  // Retrieves the next available resource id that has not been reserved.
+  Result<ResourceId> NextId();
+
+ private:
+  uint8_t package_id_;
+  uint8_t type_id_;
+  NextIdFinder<uint16_t, ResourceName> next_entry_id_;
+};
+
+struct ResourceTypeKey {
+  ResourceType type;
+  uint8_t id;
+
+  bool operator<(const ResourceTypeKey& other) const {
+    return (type != other.type) ? type < other.type : id < other.id;
   }
 
-  const ResourceId existing_id(pkg->id.value(), type->id ? type->id.value() : 0,
-                               entry->id ? entry->id.value() : 0);
-  diag->Error(DiagMessage() << "can't assign ID " << id << " to resource "
-                            << name << " with conflicting ID " << existing_id);
-  return false;
+  bool operator==(const ResourceTypeKey& other) const {
+    return type == other.type && id == other.id;
+  }
+
+  bool operator!=(const ResourceTypeKey& other) const {
+    return !(*this == other);
+  }
+};
+
+::std::ostream& operator<<(::std::ostream& out, const ResourceTypeKey& type) {
+  return out << type.type;
 }
 
+struct IdAssignerContext {
+  IdAssignerContext(std::string package_name, uint8_t package_id)
+      : package_name_(std::move(package_name)), package_id_(package_id) {
+  }
+
+  // Attempts to reserve the resource id for the specified resource name.
+  // Returns whether the id was reserved successfully.
+  // Reserving identifiers must be completed before `NextId` is called for the first time.
+  bool ReserveId(const ResourceName& name, ResourceId id, const Visibility& visibility,
+                 IDiagnostics* diag);
+
+  // Retrieves the next available resource id that has not been reserved.
+  std::optional<ResourceId> NextId(const ResourceName& name, IDiagnostics* diag);
+
+ private:
+  std::string package_name_;
+  uint8_t package_id_;
+  std::map<ResourceTypeKey, TypeGroup> types_;
+  std::map<ResourceType, uint8_t> non_staged_type_ids_;
+  NextIdFinder<uint8_t, ResourceTypeKey> type_id_finder_ =
+      NextIdFinder<uint8_t, ResourceTypeKey>(1);
+};
+
+}  // namespace
+
 bool IdAssigner::Consume(IAaptContext* context, ResourceTable* table) {
-  std::map<ResourceId, ResourceName> assigned_ids;
-
+  IdAssignerContext assigned_ids(context->GetCompilationPackage(), context->GetPackageId());
   for (auto& package : table->packages) {
-    CHECK(bool(package->id)) << "packages must have manually assigned IDs";
-
     for (auto& type : package->types) {
       for (auto& entry : type->entries) {
         const ResourceName name(package->name, type->type, entry->name);
+        if (entry->id) {
+          if (!assigned_ids.ReserveId(name, entry->id.value(), entry->visibility,
+                                      context->GetDiagnostics())) {
+            return false;
+          }
+        }
 
         if (assigned_id_map_) {
           // Assign the pre-assigned stable ID meant for this resource.
           const auto iter = assigned_id_map_->find(name);
           if (iter != assigned_id_map_->end()) {
             const ResourceId assigned_id = iter->second;
-            const bool result =
-                AssignId(context->GetDiagnostics(), assigned_id, name,
-                         package.get(), type.get(), entry.get());
-            if (!result) {
+            if (!assigned_ids.ReserveId(name, assigned_id, entry->visibility,
+                                        context->GetDiagnostics())) {
               return false;
             }
-          }
-        }
-
-        if (package->id && type->id && entry->id) {
-          // If the ID is set for this resource, then reserve it.
-          ResourceId resource_id(package->id.value(), type->id.value(),
-                                 entry->id.value());
-          auto result = assigned_ids.insert({resource_id, name});
-          const ResourceName& existing_name = result.first->second;
-          if (!result.second) {
-            context->GetDiagnostics()->Error(
-                DiagMessage() << "resource " << name << " has same ID "
-                              << resource_id << " as " << existing_name);
-            return false;
+            entry->id = assigned_id;
           }
         }
       }
@@ -94,125 +153,185 @@
   }
 
   if (assigned_id_map_) {
-    // Reserve all the IDs mentioned in the stable ID map. That way we won't
-    // assign
-    // IDs that were listed in the map if they don't exist in the table.
+    // Reserve all the IDs mentioned in the stable ID map. That way we won't assig IDs that were
+    // listed in the map if they don't exist in the table.
     for (const auto& stable_id_entry : *assigned_id_map_) {
       const ResourceName& pre_assigned_name = stable_id_entry.first;
       const ResourceId& pre_assigned_id = stable_id_entry.second;
-      auto result = assigned_ids.insert({pre_assigned_id, pre_assigned_name});
-      const ResourceName& existing_name = result.first->second;
-      if (!result.second && existing_name != pre_assigned_name) {
-        context->GetDiagnostics()->Error(
-            DiagMessage() << "stable ID " << pre_assigned_id << " for resource "
-                          << pre_assigned_name
-                          << " is already taken by resource " << existing_name);
+      if (!assigned_ids.ReserveId(pre_assigned_name, pre_assigned_id, {},
+                                  context->GetDiagnostics())) {
         return false;
       }
     }
   }
 
-  // Assign any resources without IDs the next available ID. Gaps will be filled
-  // if possible,
+  // Assign any resources without IDs the next available ID. Gaps will be filled if possible,
   // unless those IDs have been reserved.
-
-  const auto assigned_ids_iter_end = assigned_ids.end();
   for (auto& package : table->packages) {
-    CHECK(bool(package->id)) << "packages must have manually assigned IDs";
-
-    // Build a half filled ResourceId object, which will be used to find the
-    // closest matching
-    // reserved ID in the assignedId map. From that point the next available
-    // type ID can be
-    // found.
-    ResourceId resource_id(package->id.value(), 0, 0);
-    uint8_t next_expected_type_id = 1;
-
-    // Find the closest matching ResourceId that is <= the one with only the
-    // package set.
-    auto next_type_iter = assigned_ids.lower_bound(resource_id);
     for (auto& type : package->types) {
-      if (!type->id) {
-        // We need to assign a type ID. Iterate over the reserved IDs until we
-        // find
-        // some type ID that is a distance of 2 greater than the last one we've
-        // seen.
-        // That means there is an available type ID between these reserved IDs.
-        while (next_type_iter != assigned_ids_iter_end) {
-          if (next_type_iter->first.package_id() != package->id.value()) {
-            break;
-          }
-
-          const uint8_t type_id = next_type_iter->first.type_id();
-          if (type_id > next_expected_type_id) {
-            // There is a gap in the type IDs, so use the missing one.
-            type->id = next_expected_type_id++;
-            break;
-          }
-
-          // Set our expectation to be the next type ID after the reserved one
-          // we
-          // just saw.
-          next_expected_type_id = type_id + 1;
-
-          // Move to the next reserved ID.
-          ++next_type_iter;
-        }
-
-        if (!type->id) {
-          // We must have hit the end of the reserved IDs and not found a gap.
-          // That means the next ID is available.
-          type->id = next_expected_type_id++;
-        }
-      }
-
-      resource_id = ResourceId(package->id.value(), type->id.value(), 0);
-      uint16_t next_expected_entry_id = 0;
-
-      // Find the closest matching ResourceId that is <= the one with only the
-      // package
-      // and type set.
-      auto next_entry_iter = assigned_ids.lower_bound(resource_id);
       for (auto& entry : type->entries) {
-        if (!entry->id) {
-          // We need to assign an entry ID. Iterate over the reserved IDs until
-          // we find
-          // some entry ID that is a distance of 2 greater than the last one
-          // we've seen.
-          // That means there is an available entry ID between these reserved
-          // IDs.
-          while (next_entry_iter != assigned_ids_iter_end) {
-            if (next_entry_iter->first.package_id() != package->id.value() ||
-                next_entry_iter->first.type_id() != type->id.value()) {
-              break;
-            }
-
-            const uint16_t entry_id = next_entry_iter->first.entry_id();
-            if (entry_id > next_expected_entry_id) {
-              // There is a gap in the entry IDs, so use the missing one.
-              entry->id = next_expected_entry_id++;
-              break;
-            }
-
-            // Set our expectation to be the next type ID after the reserved one
-            // we
-            // just saw.
-            next_expected_entry_id = entry_id + 1;
-
-            // Move to the next reserved entry ID.
-            ++next_entry_iter;
-          }
-
-          if (!entry->id) {
-            // We must have hit the end of the reserved IDs and not found a gap.
-            // That means the next ID is available.
-            entry->id = next_expected_entry_id++;
-          }
+        const ResourceName name(package->name, type->type, entry->name);
+        if (entry->id) {
+          continue;
         }
+        auto id = assigned_ids.NextId(name, context->GetDiagnostics());
+        if (!id.has_value()) {
+          return false;
+        }
+        entry->id = id.value();
       }
     }
   }
   return true;
 }
 
+namespace {
+template <typename Id, typename Key>
+Result<Id> NextIdFinder<Id, Key>::ReserveId(Key key, Id id) {
+  CHECK(!next_id_called_) << "ReserveId cannot be called after NextId";
+  auto assign_result = pre_assigned_ids_.emplace(id, key);
+  if (!assign_result.second && assign_result.first->second != key) {
+    std::stringstream error;
+    error << "ID is already assigned to " << assign_result.first->second;
+    return unexpected(error.str());
+  }
+  return id;
+}
+
+template <typename Id, typename Key>
+std::optional<Id> NextIdFinder<Id, Key>::NextId() {
+  if (!next_id_called_) {
+    next_id_called_ = true;
+    next_preassigned_id_ = pre_assigned_ids_.begin();
+  }
+  return SkipToNextAvailableId();
+}
+
+template <typename Id, typename Key>
+std::optional<Id> NextIdFinder<Id, Key>::SkipToNextAvailableId() {
+  if (exhausted_) {
+    return {};
+  }
+  while (next_preassigned_id_ != pre_assigned_ids_.end()) {
+    if (next_preassigned_id_->first == next_id_) {
+      if (next_id_ == std::numeric_limits<Id>::max()) {
+        // The last identifier was reserved so there are no more available identifiers.
+        exhausted_ = true;
+        return {};
+      }
+      ++next_id_;
+      ++next_preassigned_id_;
+      continue;
+    }
+    CHECK(next_preassigned_id_->first > next_id_) << "Preassigned IDs are not in sorted order";
+    break;
+  }
+  if (next_id_ == std::numeric_limits<Id>::max()) {
+    // There are no more identifiers after this one, but this one is still available so return it.
+    exhausted_ = true;
+  }
+  return next_id_++;
+}
+
+Result<std::monostate> TypeGroup::ReserveId(const ResourceName& name, ResourceId id) {
+  if (type_id_ != id.type_id()) {
+    // Currently there cannot be multiple type ids for a single type.
+    std::stringstream error;
+    error << "type '" << name.type << "' already has ID " << std::hex << (int)id.type_id();
+    return unexpected(error.str());
+  }
+
+  auto assign_result = next_entry_id_.ReserveId(name, id.entry_id());
+  if (!assign_result.has_value()) {
+    std::stringstream error;
+    error << "entry " << assign_result.error();
+    return unexpected(error.str());
+  }
+  return {};
+}
+
+Result<ResourceId> TypeGroup::NextId() {
+  auto entry_id = next_entry_id_.NextId();
+  if (!entry_id.has_value()) {
+    std::stringstream error;
+    error << "resource type ID has exceeded the maximum number of resource entries ("
+          << (std::numeric_limits<uint16_t>::max() + 1u) << ")";
+    return unexpected(error.str());
+  }
+  return ResourceId(package_id_, type_id_, entry_id.value());
+}
+
+bool IdAssignerContext::ReserveId(const ResourceName& name, ResourceId id,
+                                  const Visibility& visibility, IDiagnostics* diag) {
+  if (package_id_ != id.package_id()) {
+    diag->Error(DiagMessage() << "can't assign ID " << id << " to resource " << name
+                              << " because package already has ID " << std::hex
+                              << (int)id.package_id());
+    return false;
+  }
+
+  auto key = ResourceTypeKey{name.type, id.type_id()};
+  auto type = types_.find(key);
+  if (type == types_.end()) {
+    // The type has not been assigned an id yet. Ensure that the specified id is not being used by
+    // another type.
+    auto assign_result = type_id_finder_.ReserveId(key, id.type_id());
+    if (!assign_result.has_value()) {
+      diag->Error(DiagMessage() << "can't assign ID " << id << " to resource " << name
+                                << " because type " << assign_result.error());
+      return false;
+    }
+    type = types_.emplace(key, TypeGroup(package_id_, id.type_id())).first;
+  }
+
+  if (!visibility.staged_api) {
+    // Ensure that non-staged resources can only exist in one type ID.
+    auto non_staged_type = non_staged_type_ids_.emplace(name.type, id.type_id());
+    if (!non_staged_type.second && non_staged_type.first->second != id.type_id()) {
+      diag->Error(DiagMessage() << "can't assign ID " << id << " to resource " << name
+                                << " because type already has ID " << std::hex
+                                << (int)id.type_id());
+      return false;
+    }
+  }
+
+  auto assign_result = type->second.ReserveId(name, id);
+  if (!assign_result.has_value()) {
+    diag->Error(DiagMessage() << "can't assign ID " << id << " to resource " << name << " because "
+                              << assign_result.error());
+    return false;
+  }
+
+  return true;
+}
+
+std::optional<ResourceId> IdAssignerContext::NextId(const ResourceName& name, IDiagnostics* diag) {
+  // The package name is not known during the compile stage.
+  // Resources without a package name are considered a part of the app being linked.
+  CHECK(name.package.empty() || name.package == package_name_);
+
+  // Find the type id for non-staged resources of this type.
+  auto non_staged_type = non_staged_type_ids_.find(name.type);
+  if (non_staged_type == non_staged_type_ids_.end()) {
+    auto next_type_id = type_id_finder_.NextId();
+    CHECK(next_type_id.has_value()) << "resource type IDs allocated have exceeded maximum (256)";
+    non_staged_type = non_staged_type_ids_.emplace(name.type, *next_type_id).first;
+  }
+
+  ResourceTypeKey key{name.type, non_staged_type->second};
+  auto type = types_.find(key);
+  if (type == types_.end()) {
+    type = types_.emplace(key, TypeGroup(package_id_, key.id)).first;
+  }
+
+  auto assign_result = type->second.NextId();
+  if (!assign_result.has_value()) {
+    diag->Error(DiagMessage() << "can't assign resource ID to resource " << name << " because "
+                              << assign_result.error());
+    return {};
+  }
+  return assign_result.value();
+}
+}  // namespace
+
 }  // namespace aapt
diff --git a/tools/aapt2/compile/IdAssigner_test.cpp b/tools/aapt2/compile/IdAssigner_test.cpp
index 5cff004..6637766 100644
--- a/tools/aapt2/compile/IdAssigner_test.cpp
+++ b/tools/aapt2/compile/IdAssigner_test.cpp
@@ -20,42 +20,40 @@
 
 namespace aapt {
 
+struct IdAssignerTests : public ::testing::Test {
+  void SetUp() override {
+    context = test::ContextBuilder().SetCompilationPackage("android").SetPackageId(0x01).Build();
+  }
+  std::unique_ptr<IAaptContext> context;
+};
+
 ::testing::AssertionResult VerifyIds(ResourceTable* table);
 
-TEST(IdAssignerTest, AssignIds) {
-  std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder()
-                                             .AddSimple("android:attr/foo")
-                                             .AddSimple("android:attr/bar")
-                                             .AddSimple("android:id/foo")
-                                             .SetPackageId("android", 0x01)
-                                             .Build();
-
-  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
+TEST_F(IdAssignerTests, AssignIds) {
+  auto table = test::ResourceTableBuilder()
+                   .AddSimple("android:attr/foo")
+                   .AddSimple("android:attr/bar")
+                   .AddSimple("android:id/foo")
+                   .Build();
   IdAssigner assigner;
 
   ASSERT_TRUE(assigner.Consume(context.get(), table.get()));
   ASSERT_TRUE(VerifyIds(table.get()));
 }
 
-TEST(IdAssignerTest, AssignIdsWithReservedIds) {
-  std::unique_ptr<ResourceTable> table =
-      test::ResourceTableBuilder()
-          .AddSimple("android:id/foo", ResourceId(0x01010000))
-          .AddSimple("android:dimen/two")
-          .AddSimple("android:integer/three")
-          .AddSimple("android:string/five")
-          .AddSimple("android:attr/fun", ResourceId(0x01040000))
-          .AddSimple("android:attr/foo", ResourceId(0x01040006))
-          .AddSimple("android:attr/bar")
-          .AddSimple("android:attr/baz")
-          .AddSimple("app:id/biz")
-          .SetPackageId("android", 0x01)
-          .SetPackageId("app", 0x7f)
-          .Build();
+TEST_F(IdAssignerTests, AssignIdsWithReservedIds) {
+  auto table = test::ResourceTableBuilder()
+                   .AddSimple("android:id/foo", ResourceId(0x01010000))
+                   .AddSimple("android:dimen/two")
+                   .AddSimple("android:integer/three")
+                   .AddSimple("android:string/five")
+                   .AddSimple("android:attr/fun", ResourceId(0x01040000))
+                   .AddSimple("android:attr/foo", ResourceId(0x01040006))
+                   .AddSimple("android:attr/bar")
+                   .AddSimple("android:attr/baz")
+                   .Build();
 
-  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
   IdAssigner assigner;
-
   ASSERT_TRUE(assigner.Consume(context.get(), table.get()));
   ASSERT_TRUE(VerifyIds(table.get()));
 
@@ -65,12 +63,12 @@
 
   maybe_result = table->FindResource(test::ParseNameOrDie("android:dimen/two"));
   ASSERT_TRUE(maybe_result);
-  EXPECT_EQ(make_value<uint8_t>(2), maybe_result.value().type->id);
+  EXPECT_EQ(make_value<ResourceId>(0x01020000), maybe_result.value().entry->id);
 
   maybe_result =
       table->FindResource(test::ParseNameOrDie("android:integer/three"));
   ASSERT_TRUE(maybe_result);
-  EXPECT_EQ(make_value<uint8_t>(3), maybe_result.value().type->id);
+  EXPECT_EQ(make_value<ResourceId>(0x01030000), maybe_result.value().entry->id);
 
   // Expect to bypass the reserved 0x0104XXXX IDs and use the next 0x0105XXXX
   // IDs.
@@ -78,107 +76,133 @@
   maybe_result =
       table->FindResource(test::ParseNameOrDie("android:string/five"));
   ASSERT_TRUE(maybe_result);
-  EXPECT_EQ(make_value<uint8_t>(5), maybe_result.value().type->id);
+  EXPECT_EQ(make_value<ResourceId>(0x01050000), maybe_result.value().entry->id);
 
   // Expect to fill in the gaps between 0x01040000 and 0x01040006.
 
   maybe_result = table->FindResource(test::ParseNameOrDie("android:attr/bar"));
   ASSERT_TRUE(maybe_result);
-  EXPECT_EQ(make_value<uint16_t>(1), maybe_result.value().entry->id);
+  EXPECT_EQ(make_value<ResourceId>(0x01040001), maybe_result.value().entry->id);
 
   maybe_result = table->FindResource(test::ParseNameOrDie("android:attr/baz"));
   ASSERT_TRUE(maybe_result);
-  EXPECT_EQ(make_value<uint16_t>(2), maybe_result.value().entry->id);
+  EXPECT_EQ(make_value<ResourceId>(0x01040002), maybe_result.value().entry->id);
 }
 
-TEST(IdAssignerTest, FailWhenNonUniqueIdsAssigned) {
-  std::unique_ptr<ResourceTable> table =
-      test::ResourceTableBuilder()
-          .AddSimple("android:attr/foo", ResourceId(0x01040006))
-          .AddSimple("android:attr/bar", ResourceId(0x01040006))
-          .SetPackageId("android", 0x01)
-          .SetPackageId("app", 0x7f)
-          .Build();
-
-  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
+TEST_F(IdAssignerTests, FailWhenNonUniqueIdsAssigned) {
+  auto table = test::ResourceTableBuilder()
+                   .AddSimple("android:attr/foo", ResourceId(0x01040006))
+                   .AddSimple("android:attr/bar", ResourceId(0x01040006))
+                   .Build();
   IdAssigner assigner;
-
   ASSERT_FALSE(assigner.Consume(context.get(), table.get()));
 }
 
-TEST(IdAssignerTest, AssignIdsWithIdMap) {
-  std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder()
-                                             .AddSimple("android:attr/foo")
-                                             .AddSimple("android:attr/bar")
-                                             .SetPackageId("android", 0x01)
-                                             .Build();
+TEST_F(IdAssignerTests, FailWhenNonUniqueTypeIdsAssigned) {
+  auto table = test::ResourceTableBuilder()
+                   .AddSimple("android:string/foo", ResourceId(0x01040000))
+                   .AddSimple("android:attr/bar", ResourceId(0x01040006))
+                   .Build();
+  IdAssigner assigner;
+  ASSERT_FALSE(assigner.Consume(context.get(), table.get()));
+}
 
-  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
+TEST_F(IdAssignerTests, FailWhenTypeHasTwoNonStagedIds) {
+  auto table = test::ResourceTableBuilder()
+                   .AddSimple("android:attr/foo", ResourceId(0x01050000))
+                   .AddSimple("android:attr/bar", ResourceId(0x01040006))
+                   .Build();
+  IdAssigner assigner;
+  ASSERT_FALSE(assigner.Consume(context.get(), table.get()));
+}
+
+TEST_F(IdAssignerTests, FailWhenTypeHasTwoNonStagedIdsRegardlessOfStagedId) {
+  auto table = test::ResourceTableBuilder()
+                   .AddSimple("android:attr/foo", ResourceId(0x01050000))
+                   .AddSimple("android:attr/bar", ResourceId(0x01ff0006))
+                   .Add(NewResourceBuilder("android:attr/staged_baz")
+                            .SetId(0x01ff0000)
+                            .SetVisibility({.staged_api = true})
+                            .Build())
+                   .Build();
+  IdAssigner assigner;
+  ASSERT_FALSE(assigner.Consume(context.get(), table.get()));
+}
+
+TEST_F(IdAssignerTests, AssignIdsWithIdMap) {
+  auto table = test::ResourceTableBuilder()
+                   .AddSimple("android:attr/foo")
+                   .AddSimple("android:attr/bar")
+                   .Build();
   std::unordered_map<ResourceName, ResourceId> id_map = {
       {test::ParseNameOrDie("android:attr/foo"), ResourceId(0x01010002)}};
   IdAssigner assigner(&id_map);
   ASSERT_TRUE(assigner.Consume(context.get(), table.get()));
   ASSERT_TRUE(VerifyIds(table.get()));
-  Maybe<ResourceTable::SearchResult> result =
-      table->FindResource(test::ParseNameOrDie("android:attr/foo"));
+  auto result = table->FindResource(test::ParseNameOrDie("android:attr/foo"));
   ASSERT_TRUE(result);
 
   const ResourceTable::SearchResult& search_result = result.value();
-  EXPECT_EQ(make_value<uint8_t>(0x01), search_result.package->id);
-  EXPECT_EQ(make_value<uint8_t>(0x01), search_result.type->id);
-  EXPECT_EQ(make_value<uint16_t>(0x0002), search_result.entry->id);
+  EXPECT_EQ(make_value<ResourceId>(0x01010002), search_result.entry->id);
+}
+
+TEST_F(IdAssignerTests, UseAllEntryIds) {
+  ResourceTable table;
+  const size_t max_entry_id = std::numeric_limits<uint16_t>::max();
+  for (size_t i = 0; i <= max_entry_id; i++) {
+    ASSERT_TRUE(
+        table.AddResource(NewResourceBuilder("android:attr/res" + std::to_string(i)).Build(),
+                          context->GetDiagnostics()));
+  }
+  IdAssigner assigner;
+  ASSERT_TRUE(assigner.Consume(context.get(), &table));
+}
+
+TEST_F(IdAssignerTests, ExaustEntryIds) {
+  ResourceTable table;
+  const size_t max_entry_id = std::numeric_limits<uint16_t>::max() + 1u;
+  for (size_t i = 0; i <= max_entry_id; i++) {
+    ASSERT_TRUE(
+        table.AddResource(NewResourceBuilder("android:attr/res" + std::to_string(i)).Build(),
+                          context->GetDiagnostics()));
+  }
+  IdAssigner assigner;
+  ASSERT_FALSE(assigner.Consume(context.get(), &table));
+}
+
+TEST_F(IdAssignerTests, ExaustEntryIdsLastIdIsPublic) {
+  ResourceTable table;
+  ASSERT_TRUE(table.AddResource(NewResourceBuilder("android:attr/res").SetId(0x0101ffff).Build(),
+                                context->GetDiagnostics()));
+  const size_t max_entry_id = std::numeric_limits<uint16_t>::max();
+  for (size_t i = 0; i <= max_entry_id; i++) {
+    ASSERT_TRUE(
+        table.AddResource(NewResourceBuilder("android:attr/res" + std::to_string(i)).Build(),
+                          context->GetDiagnostics()));
+  }
+  IdAssigner assigner;
+  ASSERT_FALSE(assigner.Consume(context.get(), &table));
 }
 
 ::testing::AssertionResult VerifyIds(ResourceTable* table) {
-  std::set<uint8_t> package_ids;
+  std::set<ResourceId> seen_ids;
   for (auto& package : table->packages) {
-    if (!package->id) {
-      return ::testing::AssertionFailure() << "package " << package->name
-                                           << " has no ID";
-    }
-
-    if (!package_ids.insert(package->id.value()).second) {
-      return ::testing::AssertionFailure()
-             << "package " << package->name << " has non-unique ID " << std::hex
-             << (int)package->id.value() << std::dec;
-    }
-  }
-
-  for (auto& package : table->packages) {
-    std::set<uint8_t> type_ids;
     for (auto& type : package->types) {
-      if (!type->id) {
-        return ::testing::AssertionFailure() << "type " << type->type
-                                             << " of package " << package->name
-                                             << " has no ID";
-      }
-
-      if (!type_ids.insert(type->id.value()).second) {
-        return ::testing::AssertionFailure()
-               << "type " << type->type << " of package " << package->name
-               << " has non-unique ID " << std::hex << (int)type->id.value()
-               << std::dec;
-      }
-    }
-
-    for (auto& type : package->types) {
-      std::set<uint16_t> entry_ids;
       for (auto& entry : type->entries) {
         if (!entry->id) {
           return ::testing::AssertionFailure()
-                 << "entry " << entry->name << " of type " << type->type
-                 << " of package " << package->name << " has no ID";
+                 << "resource " << ResourceNameRef(package->name, type->type, entry->name)
+                 << " has no ID";
         }
-
-        if (!entry_ids.insert(entry->id.value()).second) {
+        if (!seen_ids.insert(entry->id.value()).second) {
           return ::testing::AssertionFailure()
-                 << "entry " << entry->name << " of type " << type->type
-                 << " of package " << package->name << " has non-unique ID "
-                 << std::hex << (int)entry->id.value() << std::dec;
+                 << "resource " << ResourceNameRef(package->name, type->type, entry->name)
+                 << " has a non-unique ID" << std::hex << entry->id.value() << std::dec;
         }
       }
     }
   }
+
   return ::testing::AssertionSuccess() << "all IDs are unique and assigned";
 }
 
diff --git a/tools/aapt2/compile/PseudolocaleGenerator_test.cpp b/tools/aapt2/compile/PseudolocaleGenerator_test.cpp
index e816c86..432d7bf 100644
--- a/tools/aapt2/compile/PseudolocaleGenerator_test.cpp
+++ b/tools/aapt2/compile/PseudolocaleGenerator_test.cpp
@@ -236,13 +236,14 @@
 
 TEST(PseudolocaleGeneratorTest, PluralsArePseudolocalized) {
   std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
-  std::unique_ptr<ResourceTable> table =
-      test::ResourceTableBuilder().SetPackageId("com.pkg", 0x7F).Build();
+  std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder().Build();
   std::unique_ptr<Plural> plural = util::make_unique<Plural>();
   plural->values = {util::make_unique<String>(table->string_pool.MakeRef("zero")),
                     util::make_unique<String>(table->string_pool.MakeRef("one"))};
-  ASSERT_TRUE(table->AddResource(test::ParseNameOrDie("com.pkg:plurals/foo"), ConfigDescription{},
-                                 {}, std::move(plural), context->GetDiagnostics()));
+  ASSERT_TRUE(table->AddResource(NewResourceBuilder(test::ParseNameOrDie("com.pkg:plurals/foo"))
+                                     .SetValue(std::move(plural))
+                                     .Build(),
+                                 context->GetDiagnostics()));
   std::unique_ptr<Plural> expected = util::make_unique<Plural>();
   expected->values = {util::make_unique<String>(table->string_pool.MakeRef("[žéŕö one]")),
                       util::make_unique<String>(table->string_pool.MakeRef("[öñé one]"))};
@@ -252,6 +253,7 @@
 
   const auto* actual = test::GetValueForConfig<Plural>(table.get(), "com.pkg:plurals/foo",
                                                        test::ParseConfigOrDie("en-rXA"));
+  ASSERT_NE(nullptr, actual);
   EXPECT_TRUE(actual->Equals(expected.get()));
 }
 
@@ -273,11 +275,14 @@
     auto string = util::make_unique<String>(table->string_pool.MakeRef(original_style.str));
     string->untranslatable_sections.push_back(UntranslatableSection{6u, 11u});
 
-    ASSERT_TRUE(table->AddResource(test::ParseNameOrDie("android:string/foo"), ConfigDescription{},
-                                   {} /* product */, std::move(styled_string),
+    ASSERT_TRUE(table->AddResource(NewResourceBuilder(test::ParseNameOrDie("android:string/foo"))
+                                       .SetValue(std::move(styled_string))
+                                       .Build(),
                                    context->GetDiagnostics()));
-    ASSERT_TRUE(table->AddResource(test::ParseNameOrDie("android:string/bar"), ConfigDescription{},
-                                   {} /* product */, std::move(string), context->GetDiagnostics()));
+    ASSERT_TRUE(table->AddResource(NewResourceBuilder(test::ParseNameOrDie("android:string/bar"))
+                                       .SetValue(std::move(string))
+                                       .Build(),
+                                   context->GetDiagnostics()));
   }
 
   PseudolocaleGenerator generator;
diff --git a/tools/aapt2/dump/DumpManifest.cpp b/tools/aapt2/dump/DumpManifest.cpp
index cc1cf7f..f29c918 100644
--- a/tools/aapt2/dump/DumpManifest.cpp
+++ b/tools/aapt2/dump/DumpManifest.cpp
@@ -191,18 +191,14 @@
                          const ConfigDescription& config = DefaultConfig()) {
       if (table) {
         for (auto& package : table->packages) {
-          if (package->id && package->id.value() == res_id.package_id()) {
             for (auto& type : package->types) {
-              if (type->id && type->id.value() == res_id.type_id()) {
-                for (auto& entry : type->entries) {
-                  if (entry->id && entry->id.value() == res_id.entry_id()) {
-                    if (auto value = BestConfigValue(entry.get(), config)) {
-                      return value;
-                    }
+              for (auto& entry : type->entries) {
+                if (entry->id && entry->id.value() == res_id.id) {
+                  if (auto value = BestConfigValue(entry.get(), config)) {
+                    return value;
                   }
                 }
               }
-            }
           }
         }
       }
diff --git a/tools/aapt2/format/binary/BinaryResourceParser.cpp b/tools/aapt2/format/binary/BinaryResourceParser.cpp
index cccd9fa..bfb8d58 100644
--- a/tools/aapt2/format/binary/BinaryResourceParser.cpp
+++ b/tools/aapt2/format/binary/BinaryResourceParser.cpp
@@ -192,8 +192,7 @@
   std::u16string package_name = strcpy16_dtoh((const char16_t*)package_header->name,
                                               arraysize(package_header->name));
 
-  ResourceTablePackage* package =
-      table_->CreatePackage(util::Utf16ToUtf8(package_name), static_cast<uint8_t>(package_id));
+  ResourceTablePackage* package = table_->FindOrCreatePackage(util::Utf16ToUtf8(package_name));
   if (!package) {
     diag_->Error(DiagMessage(source_)
                  << "incompatible package '" << package_name << "' with ID " << package_id);
@@ -232,13 +231,13 @@
         break;
 
       case android::RES_TABLE_TYPE_SPEC_TYPE:
-        if (!ParseTypeSpec(package, parser.chunk())) {
+        if (!ParseTypeSpec(package, parser.chunk(), package_id)) {
           return false;
         }
         break;
 
       case android::RES_TABLE_TYPE_TYPE:
-        if (!ParseType(package, parser.chunk())) {
+        if (!ParseType(package, parser.chunk(), package_id)) {
           return false;
         }
         break;
@@ -276,7 +275,7 @@
 }
 
 bool BinaryResourceParser::ParseTypeSpec(const ResourceTablePackage* package,
-                                         const ResChunk_header* chunk) {
+                                         const ResChunk_header* chunk, uint8_t package_id) {
   if (type_pool_.getError() != NO_ERROR) {
     diag_->Error(DiagMessage(source_) << "missing type string pool");
     return false;
@@ -317,14 +316,14 @@
   const uint32_t* type_spec_flags = reinterpret_cast<const uint32_t*>(
       reinterpret_cast<uintptr_t>(type_spec) + util::DeviceToHost16(type_spec->header.headerSize));
   for (size_t i = 0; i < entry_count; i++) {
-    ResourceId id(package->id.value_or_default(0x0), type_spec->id, static_cast<size_t>(i));
+    ResourceId id(package_id, type_spec->id, static_cast<size_t>(i));
     entry_type_spec_flags_[id] = util::DeviceToHost32(type_spec_flags[i]);
   }
   return true;
 }
 
 bool BinaryResourceParser::ParseType(const ResourceTablePackage* package,
-                                     const ResChunk_header* chunk) {
+                                     const ResChunk_header* chunk, uint8_t package_id) {
   if (type_pool_.getError() != NO_ERROR) {
     diag_->Error(DiagMessage(source_) << "missing type string pool");
     return false;
@@ -354,13 +353,9 @@
   const std::string type_str = util::GetString(type_pool_, type->id - 1);
   const ResourceType* parsed_type = ParseResourceType(type_str);
   if (!parsed_type) {
-    // Be lenient on the name of the type if the table is lenient on resource validation.
-    bool log_error = table_->GetValidateResources();
-    if (log_error) {
-      diag_->Error(DiagMessage(source_) << "invalid type name '" << type_str
-                                        << "' for type with ID " << type->id);
-    }
-    return !log_error;
+    diag_->Warn(DiagMessage(source_)
+                << "invalid type name '" << type_str << "' for type with ID " << type->id);
+    return true;
   }
 
   TypeVariant tv(type);
@@ -372,7 +367,7 @@
 
     const ResourceName name(package->name, *parsed_type,
                             util::GetString(key_pool_, util::DeviceToHost32(entry->key.index)));
-    const ResourceId res_id(package->id.value(), type->id, static_cast<uint16_t>(it.index()));
+    const ResourceId res_id(package_id, type->id, static_cast<uint16_t>(it.index()));
 
     std::unique_ptr<Value> resource_value;
     if (entry->flags & ResTable_entry::FLAG_COMPLEX) {
@@ -392,17 +387,13 @@
       return false;
     }
 
-    if (!table_->AddResourceWithIdMangled(name, res_id, config, {}, std::move(resource_value),
-                                          diag_)) {
-      return false;
-    }
+    NewResourceBuilder res_builder(name);
+    res_builder.SetValue(std::move(resource_value), config)
+        .SetId(res_id, OnIdConflict::CREATE_ENTRY)
+        .SetAllowMangled(true);
 
     if (entry->flags & ResTable_entry::FLAG_PUBLIC) {
-      Visibility visibility;
-      visibility.level = Visibility::Level::kPublic;
-      if (!table_->SetVisibilityWithIdMangled(name, visibility, res_id, diag_)) {
-        return false;
-      }
+      res_builder.SetVisibility(Visibility{Visibility::Level::kPublic});
 
       // Erase the ID from the map once processed, so that we don't mark the same symbol more than
       // once.
@@ -415,6 +406,10 @@
     if (cache_iter == id_index_.end()) {
       id_index_.insert({res_id, name});
     }
+
+    if (!table_->AddResource(res_builder.Build(), diag_)) {
+      return false;
+    }
   }
   return true;
 }
@@ -472,7 +467,12 @@
 
         OverlayableItem overlayable_item(overlayable);
         overlayable_item.policies = policy_header->policy_flags;
-        if (!table_->SetOverlayable(iter->second, overlayable_item, diag_)) {
+        if (!table_->AddResource(NewResourceBuilder(iter->second)
+                                     .SetId(res_id, OnIdConflict::CREATE_ENTRY)
+                                     .SetOverlayable(std::move(overlayable_item))
+                                     .SetAllowMangled(true)
+                                     .Build(),
+                                 diag_)) {
           return false;
         }
       }
diff --git a/tools/aapt2/format/binary/BinaryResourceParser.h b/tools/aapt2/format/binary/BinaryResourceParser.h
index a2eee50..13dd982 100644
--- a/tools/aapt2/format/binary/BinaryResourceParser.h
+++ b/tools/aapt2/format/binary/BinaryResourceParser.h
@@ -51,8 +51,10 @@
 
   bool ParseTable(const android::ResChunk_header* chunk);
   bool ParsePackage(const android::ResChunk_header* chunk);
-  bool ParseTypeSpec(const ResourceTablePackage* package, const android::ResChunk_header* chunk);
-  bool ParseType(const ResourceTablePackage* package, const android::ResChunk_header* chunk);
+  bool ParseTypeSpec(const ResourceTablePackage* package, const android::ResChunk_header* chunk,
+                     uint8_t package_id);
+  bool ParseType(const ResourceTablePackage* package, const android::ResChunk_header* chunk,
+                 uint8_t package_id);
   bool ParseLibrary(const android::ResChunk_header* chunk);
   bool ParseOverlayable(const android::ResChunk_header* chunk);
 
diff --git a/tools/aapt2/format/binary/TableFlattener.cpp b/tools/aapt2/format/binary/TableFlattener.cpp
index 4b90b4f..17d11a6 100644
--- a/tools/aapt2/format/binary/TableFlattener.cpp
+++ b/tools/aapt2/format/binary/TableFlattener.cpp
@@ -59,35 +59,35 @@
   dst[i] = 0;
 }
 
-static bool cmp_style_entries(const Style::Entry& a, const Style::Entry& b) {
-  if (a.key.id) {
-    if (b.key.id) {
-      return cmp_ids_dynamic_after_framework(a.key.id.value(), b.key.id.value());
+static bool cmp_style_entries(const Style::Entry* a, const Style::Entry* b) {
+  if (a->key.id) {
+    if (b->key.id) {
+      return cmp_ids_dynamic_after_framework(a->key.id.value(), b->key.id.value());
     }
     return true;
-  } else if (!b.key.id) {
-    return a.key.name.value() < b.key.name.value();
+  } else if (!b->key.id) {
+    return a->key.name.value() < b->key.name.value();
   }
   return false;
 }
 
 struct FlatEntry {
-  ResourceEntry* entry;
-  Value* value;
+  const ResourceEntry* entry;
+  const Value* value;
 
   // The entry string pool index to the entry's name.
   uint32_t entry_key;
 };
 
-class MapFlattenVisitor : public ValueVisitor {
+class MapFlattenVisitor : public ConstValueVisitor {
  public:
-  using ValueVisitor::Visit;
+  using ConstValueVisitor::Visit;
 
   MapFlattenVisitor(ResTable_entry_ext* out_entry, BigBuffer* buffer)
       : out_entry_(out_entry), buffer_(buffer) {
   }
 
-  void Visit(Attribute* attr) override {
+  void Visit(const Attribute* attr) override {
     {
       Reference key = Reference(ResourceId(ResTable_map::ATTR_TYPE));
       BinaryPrimitive val(Res_value::TYPE_INT_DEC, attr->type_mask);
@@ -106,13 +106,13 @@
       FlattenEntry(&key, &val);
     }
 
-    for (Attribute::Symbol& s : attr->symbols) {
+    for (const Attribute::Symbol& s : attr->symbols) {
       BinaryPrimitive val(s.type, s.value);
       FlattenEntry(&s.symbol, &val);
     }
   }
 
-  void Visit(Style* style) override {
+  void Visit(const Style* style) override {
     if (style->parent) {
       const Reference& parent_ref = style->parent.value();
       CHECK(bool(parent_ref.id)) << "parent has no ID";
@@ -120,21 +120,26 @@
     }
 
     // Sort the style.
-    std::sort(style->entries.begin(), style->entries.end(), cmp_style_entries);
+    std::vector<const Style::Entry*> sorted_entries;
+    for (const auto& entry : style->entries) {
+      sorted_entries.emplace_back(&entry);
+    }
 
-    for (Style::Entry& entry : style->entries) {
-      FlattenEntry(&entry.key, entry.value.get());
+    std::sort(sorted_entries.begin(), sorted_entries.end(), cmp_style_entries);
+
+    for (const Style::Entry* entry : sorted_entries) {
+      FlattenEntry(&entry->key, entry->value.get());
     }
   }
 
-  void Visit(Styleable* styleable) override {
+  void Visit(const Styleable* styleable) override {
     for (auto& attr_ref : styleable->entries) {
       BinaryPrimitive val(Res_value{});
       FlattenEntry(&attr_ref, &val);
     }
   }
 
-  void Visit(Array* array) override {
+  void Visit(const Array* array) override {
     const size_t count = array->elements.size();
     for (size_t i = 0; i < count; i++) {
       Reference key(android::ResTable_map::ATTR_MIN + i);
@@ -142,7 +147,7 @@
     }
   }
 
-  void Visit(Plural* plural) override {
+  void Visit(const Plural* plural) override {
     const size_t count = plural->values.size();
     for (size_t i = 0; i < count; i++) {
       if (!plural->values[i]) {
@@ -196,16 +201,16 @@
  private:
   DISALLOW_COPY_AND_ASSIGN(MapFlattenVisitor);
 
-  void FlattenKey(Reference* key, ResTable_map* out_entry) {
+  void FlattenKey(const Reference* key, ResTable_map* out_entry) {
     CHECK(bool(key->id)) << "key has no ID";
     out_entry->name.ident = util::HostToDevice32(key->id.value().id);
   }
 
-  void FlattenValue(Item* value, ResTable_map* out_entry) {
+  void FlattenValue(const Item* value, ResTable_map* out_entry) {
     CHECK(value->Flatten(&out_entry->value)) << "flatten failed";
   }
 
-  void FlattenEntry(Reference* key, Item* value) {
+  void FlattenEntry(const Reference* key, Item* value) {
     ResTable_map* out_entry = buffer_->NextBlock<ResTable_map>();
     FlattenKey(key, out_entry);
     FlattenValue(value, out_entry);
@@ -226,7 +231,7 @@
 
 class PackageFlattener {
  public:
-  PackageFlattener(IAaptContext* context, ResourceTablePackage* package,
+  PackageFlattener(IAaptContext* context, const ResourceTablePackageView& package,
                    const std::map<size_t, std::string>* shared_libs, bool use_sparse_entries,
                    bool collapse_key_stringpool,
                    const std::set<ResourceName>& name_collapse_exemptions)
@@ -243,20 +248,20 @@
     TRACE_CALL();
     ChunkWriter pkg_writer(buffer);
     ResTable_package* pkg_header = pkg_writer.StartChunk<ResTable_package>(RES_TABLE_PACKAGE_TYPE);
-    pkg_header->id = util::HostToDevice32(package_->id.value());
+    pkg_header->id = util::HostToDevice32(package_.id.value());
 
     // AAPT truncated the package name, so do the same.
     // Shared libraries require full package names, so don't truncate theirs.
     if (context_->GetPackageType() != PackageType::kApp &&
-        package_->name.size() >= arraysize(pkg_header->name)) {
-      diag_->Error(DiagMessage() << "package name '" << package_->name
+        package_.name.size() >= arraysize(pkg_header->name)) {
+      diag_->Error(DiagMessage() << "package name '" << package_.name
                                  << "' is too long. "
                                     "Shared libraries cannot have truncated package names");
       return false;
     }
 
     // Copy the package name in device endianness.
-    strcpy16_htod(pkg_header->name, arraysize(pkg_header->name), util::Utf8ToUtf16(package_->name));
+    strcpy16_htod(pkg_header->name, arraysize(pkg_header->name), util::Utf8ToUtf16(package_.name));
 
     // Serialize the types. We do this now so that our type and key strings
     // are populated. We write those first.
@@ -273,7 +278,7 @@
     buffer->AppendBuffer(std::move(type_buffer));
 
     // If there are libraries (or if the package ID is 0x00), encode a library chunk.
-    if (package_->id.value() == 0x00 || !shared_libs_->empty()) {
+    if (package_.id.value() == 0x00 || !shared_libs_->empty()) {
       FlattenLibrarySpec(buffer);
     }
 
@@ -315,7 +320,7 @@
   }
 
   bool FlattenValue(FlatEntry* entry, BigBuffer* buffer) {
-    if (Item* item = ValueCast<Item>(entry->value)) {
+    if (const Item* item = ValueCast<Item>(entry->value)) {
       WriteEntry<ResTable_entry, true>(entry, buffer);
       Res_value* outValue = buffer->NextBlock<Res_value>();
       CHECK(item->Flatten(outValue)) << "flatten failed";
@@ -329,7 +334,7 @@
     return true;
   }
 
-  bool FlattenConfig(const ResourceTableType* type, const ConfigDescription& config,
+  bool FlattenConfig(const ResourceTableTypeView& type, const ConfigDescription& config,
                      const size_t num_total_entries, std::vector<FlatEntry>* entries,
                      BigBuffer* buffer) {
     CHECK(num_total_entries != 0);
@@ -337,7 +342,7 @@
 
     ChunkWriter type_writer(buffer);
     ResTable_type* type_header = type_writer.StartChunk<ResTable_type>(RES_TABLE_TYPE_TYPE);
-    type_header->id = type->id.value();
+    type_header->id = type.id.value();
     type_header->config = config;
     type_header->config.swapHtoD();
 
@@ -346,12 +351,12 @@
 
     BigBuffer values_buffer(512);
     for (FlatEntry& flat_entry : *entries) {
-      CHECK(static_cast<size_t>(flat_entry.entry->id.value()) < num_total_entries);
-      offsets[flat_entry.entry->id.value()] = values_buffer.size();
+      CHECK(static_cast<size_t>(flat_entry.entry->id.value().entry_id()) < num_total_entries);
+      offsets[flat_entry.entry->id.value().entry_id()] = values_buffer.size();
       if (!FlattenValue(&flat_entry, &values_buffer)) {
         diag_->Error(DiagMessage()
                      << "failed to flatten resource '"
-                     << ResourceNameRef(package_->name, type->type, flat_entry.entry->name)
+                     << ResourceNameRef(package_.name, type.type, flat_entry.entry->name)
                      << "' for configuration '" << config << "'");
         return false;
       }
@@ -399,55 +404,27 @@
     return true;
   }
 
-  std::vector<ResourceTableType*> CollectAndSortTypes() {
-    std::vector<ResourceTableType*> sorted_types;
-    for (auto& type : package_->types) {
-      if (type->type == ResourceType::kStyleable) {
-        // Styleables aren't real Resource Types, they are represented in the
-        // R.java file.
-        continue;
-      }
-
-      CHECK(bool(type->id)) << "type must have an ID set";
-
-      sorted_types.push_back(type.get());
-    }
-    std::sort(sorted_types.begin(), sorted_types.end(), cmp_ids<ResourceTableType>);
-    return sorted_types;
-  }
-
-  std::vector<ResourceEntry*> CollectAndSortEntries(ResourceTableType* type) {
-    // Sort the entries by entry ID.
-    std::vector<ResourceEntry*> sorted_entries;
-    for (auto& entry : type->entries) {
-      CHECK(bool(entry->id)) << "entry must have an ID set";
-      sorted_entries.push_back(entry.get());
-    }
-    std::sort(sorted_entries.begin(), sorted_entries.end(), cmp_ids<ResourceEntry>);
-    return sorted_entries;
-  }
-
   bool FlattenOverlayable(BigBuffer* buffer) {
     std::set<ResourceId> seen_ids;
     std::map<std::string, OverlayableChunk> overlayable_chunks;
 
-    CHECK(bool(package_->id)) << "package must have an ID set when flattening <overlayable>";
-    for (auto& type : package_->types) {
-      CHECK(bool(type->id)) << "type must have an ID set when flattening <overlayable>";
-      for (auto& entry : type->entries) {
-        CHECK(bool(type->id)) << "entry must have an ID set when flattening <overlayable>";
+    CHECK(bool(package_.id)) << "package must have an ID set when flattening <overlayable>";
+    for (auto& type : package_.types) {
+      CHECK(bool(type.id)) << "type must have an ID set when flattening <overlayable>";
+      for (auto& entry : type.entries) {
+        CHECK(bool(type.id)) << "entry must have an ID set when flattening <overlayable>";
         if (!entry->overlayable_item) {
           continue;
         }
 
-        OverlayableItem& item = entry->overlayable_item.value();
+        const OverlayableItem& item = entry->overlayable_item.value();
 
         // Resource ids should only appear once in the resource table
-        ResourceId id = android::make_resid(package_->id.value(), type->id.value(),
-                                            entry->id.value());
+        ResourceId id =
+            android::make_resid(package_.id.value(), type.id.value(), entry->id.value().entry_id());
         CHECK(seen_ids.find(id) == seen_ids.end())
             << "multiple overlayable definitions found for resource "
-            << ResourceName(package_->name, type->type, entry->name).to_string();
+            << ResourceName(package_.name, type.type, entry->name).to_string();
         seen_ids.insert(id);
 
         // Find the overlayable chunk with the specified name
@@ -542,14 +519,14 @@
     return true;
   }
 
-  bool FlattenTypeSpec(ResourceTableType* type, std::vector<ResourceEntry*>* sorted_entries,
-                       BigBuffer* buffer) {
+  bool FlattenTypeSpec(const ResourceTableTypeView& type,
+                       const std::vector<const ResourceEntry*>& sorted_entries, BigBuffer* buffer) {
     ChunkWriter type_spec_writer(buffer);
     ResTable_typeSpec* spec_header =
         type_spec_writer.StartChunk<ResTable_typeSpec>(RES_TABLE_TYPE_SPEC_TYPE);
-    spec_header->id = type->id.value();
+    spec_header->id = type.id.value();
 
-    if (sorted_entries->empty()) {
+    if (sorted_entries.empty()) {
       type_spec_writer.Finish();
       return true;
     }
@@ -557,7 +534,7 @@
     // We can't just take the size of the vector. There may be holes in the
     // entry ID space.
     // Since the entries are sorted by ID, the last one will be the biggest.
-    const size_t num_entries = sorted_entries->back()->id.value() + 1;
+    const size_t num_entries = sorted_entries.back()->id.value().entry_id() + 1;
 
     spec_header->entryCount = util::HostToDevice32(num_entries);
 
@@ -565,21 +542,23 @@
     // show for which configuration axis the resource changes.
     uint32_t* config_masks = type_spec_writer.NextBlock<uint32_t>(num_entries);
 
-    const size_t actual_num_entries = sorted_entries->size();
-    for (size_t entryIndex = 0; entryIndex < actual_num_entries; entryIndex++) {
-      ResourceEntry* entry = sorted_entries->at(entryIndex);
+    for (const ResourceEntry* entry : sorted_entries) {
+      const uint16_t entry_id = entry->id.value().entry_id();
 
       // Populate the config masks for this entry.
+      uint32_t& entry_config_masks = config_masks[entry_id];
       if (entry->visibility.level == Visibility::Level::kPublic) {
-        config_masks[entry->id.value()] |= util::HostToDevice32(ResTable_typeSpec::SPEC_PUBLIC);
+        entry_config_masks |= util::HostToDevice32(ResTable_typeSpec::SPEC_PUBLIC);
+      }
+      if (entry->visibility.staged_api) {
+        entry_config_masks |= util::HostToDevice32(ResTable_typeSpec::SPEC_STAGED_API);
       }
 
       const size_t config_count = entry->values.size();
       for (size_t i = 0; i < config_count; i++) {
         const ConfigDescription& config = entry->values[i]->config;
         for (size_t j = i + 1; j < config_count; j++) {
-          config_masks[entry->id.value()] |=
-              util::HostToDevice32(config.diff(entry->values[j]->config));
+          config_masks[entry_id] |= util::HostToDevice32(config.diff(entry->values[j]->config));
         }
       }
     }
@@ -590,32 +569,31 @@
   bool FlattenTypes(BigBuffer* buffer) {
     // Sort the types by their IDs. They will be inserted into the StringPool in
     // this order.
-    std::vector<ResourceTableType*> sorted_types = CollectAndSortTypes();
 
     size_t expected_type_id = 1;
-    for (ResourceTableType* type : sorted_types) {
+    for (const ResourceTableTypeView& type : package_.types) {
+      if (type.type == ResourceType::kStyleable) {
+        // Styleables aren't real Resource Types, they are represented in the R.java file.
+        continue;
+      }
+
       // If there is a gap in the type IDs, fill in the StringPool
       // with empty values until we reach the ID we expect.
-      while (type->id.value() > expected_type_id) {
+      while (type.id.value() > expected_type_id) {
         std::stringstream type_name;
         type_name << "?" << expected_type_id;
         type_pool_.MakeRef(type_name.str());
         expected_type_id++;
       }
       expected_type_id++;
-      type_pool_.MakeRef(to_string(type->type));
+      type_pool_.MakeRef(to_string(type.type));
 
-      std::vector<ResourceEntry*> sorted_entries = CollectAndSortEntries(type);
-      if (sorted_entries.empty()) {
-        continue;
-      }
-
-      if (!FlattenTypeSpec(type, &sorted_entries, buffer)) {
+      if (!FlattenTypeSpec(type, type.entries, buffer)) {
         return false;
       }
 
       // Since the entries are sorted by ID, the last ID will be the largest.
-      const size_t num_entries = sorted_entries.back()->id.value() + 1;
+      const size_t num_entries = type.entries.back()->id.value().entry_id() + 1;
 
       // The binary resource table lists resource entries for each
       // configuration.
@@ -628,9 +606,9 @@
       // hardcoded string uses characters which make it an invalid resource name
       const std::string obfuscated_resource_name = "0_resource_name_obfuscated";
 
-      for (ResourceEntry* entry : sorted_entries) {
+      for (const ResourceEntry* entry : type.entries) {
         uint32_t local_key_index;
-        ResourceName resource_name({}, type->type, entry->name);
+        ResourceName resource_name({}, type.type, entry->name);
         if (!collapse_key_stringpool_ ||
             name_collapse_exemptions_.find(resource_name) != name_collapse_exemptions_.end()) {
           local_key_index = (uint32_t)key_pool_.MakeRef(entry->name).index();
@@ -660,17 +638,17 @@
     ResTable_lib_header* lib_header =
         lib_writer.StartChunk<ResTable_lib_header>(RES_TABLE_LIBRARY_TYPE);
 
-    const size_t num_entries = (package_->id.value() == 0x00 ? 1 : 0) + shared_libs_->size();
+    const size_t num_entries = (package_.id.value() == 0x00 ? 1 : 0) + shared_libs_->size();
     CHECK(num_entries > 0);
 
     lib_header->count = util::HostToDevice32(num_entries);
 
     ResTable_lib_entry* lib_entry = buffer->NextBlock<ResTable_lib_entry>(num_entries);
-    if (package_->id.value() == 0x00) {
+    if (package_.id.value() == 0x00) {
       // Add this package
       lib_entry->packageId = util::HostToDevice32(0x00);
       strcpy16_htod(lib_entry->packageName, arraysize(lib_entry->packageName),
-                    util::Utf8ToUtf16(package_->name));
+                    util::Utf8ToUtf16(package_.name));
       ++lib_entry;
     }
 
@@ -685,7 +663,7 @@
 
   IAaptContext* context_;
   IDiagnostics* diag_;
-  ResourceTablePackage* package_;
+  const ResourceTablePackageView package_;
   const std::map<size_t, std::string>* shared_libs_;
   bool use_sparse_entries_;
   StringPool type_pool_;
@@ -709,9 +687,10 @@
   });
 
   // Write the ResTable header.
+  const auto& table_view = table->GetPartitionedView();
   ChunkWriter table_writer(buffer_);
   ResTable_header* table_header = table_writer.StartChunk<ResTable_header>(RES_TABLE_TYPE);
-  table_header->packageCount = util::HostToDevice32(table->packages.size());
+  table_header->packageCount = util::HostToDevice32(table_view.packages.size());
 
   // Flatten the values string pool.
   StringPool::FlattenUtf8(table_writer.buffer(), table->string_pool,
@@ -720,24 +699,25 @@
   BigBuffer package_buffer(1024);
 
   // Flatten each package.
-  for (auto& package : table->packages) {
+  for (auto& package : table_view.packages) {
     if (context->GetPackageType() == PackageType::kApp) {
       // Write a self mapping entry for this package if the ID is non-standard (0x7f).
-      const uint8_t package_id = package->id.value();
+      CHECK((bool)package.id) << "Resource ids have not been assigned before flattening the table";
+      const uint8_t package_id = package.id.value();
       if (package_id != kFrameworkPackageId && package_id != kAppPackageId) {
-        auto result = table->included_packages_.insert({package_id, package->name});
-        if (!result.second && result.first->second != package->name) {
+        auto result = table->included_packages_.insert({package_id, package.name});
+        if (!result.second && result.first->second != package.name) {
           // A mapping for this package ID already exists, and is a different package. Error!
           context->GetDiagnostics()->Error(
               DiagMessage() << android::base::StringPrintf(
                   "can't map package ID %02x to '%s'. Already mapped to '%s'", package_id,
-                  package->name.c_str(), result.first->second.c_str()));
+                  package.name.c_str(), result.first->second.c_str()));
           return false;
         }
       }
     }
 
-    PackageFlattener flattener(context, package.get(), &table->included_packages_,
+    PackageFlattener flattener(context, package, &table->included_packages_,
                                options_.use_sparse_entries, options_.collapse_key_stringpool,
                                options_.name_collapse_exemptions);
     if (!flattener.FlattenPackage(&package_buffer)) {
diff --git a/tools/aapt2/format/binary/TableFlattener_test.cpp b/tools/aapt2/format/binary/TableFlattener_test.cpp
index f8b8a1c..f5fe5e3 100644
--- a/tools/aapt2/format/binary/TableFlattener_test.cpp
+++ b/tools/aapt2/format/binary/TableFlattener_test.cpp
@@ -155,7 +155,6 @@
 TEST_F(TableFlattenerTest, FlattenFullyLinkedTable) {
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .SetPackageId("com.app.test", 0x7f)
           .AddSimple("com.app.test:id/one", ResourceId(0x7f020000))
           .AddSimple("com.app.test:id/two", ResourceId(0x7f020001))
           .AddValue("com.app.test:id/three", ResourceId(0x7f020002),
@@ -204,7 +203,6 @@
 TEST_F(TableFlattenerTest, FlattenEntriesWithGapsInIds) {
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .SetPackageId("com.app.test", 0x7f)
           .AddSimple("com.app.test:id/one", ResourceId(0x7f020001))
           .AddSimple("com.app.test:id/three", ResourceId(0x7f020003))
           .Build();
@@ -225,7 +223,6 @@
   attr.max_int = 23;
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .SetPackageId("android", 0x01)
           .AddValue("android:attr/foo", ResourceId(0x01010000), util::make_unique<Attribute>(attr))
           .Build();
 
@@ -248,7 +245,6 @@
                                                                2u));
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .SetPackageId("android", 0x01)
           .AddValue("android:array/foo", ResourceId(0x01010000), std::move(array))
           .Build();
 
@@ -300,7 +296,6 @@
     IAaptContext* context, const ConfigDescription& sparse_config, float load) {
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .SetPackageId(context->GetCompilationPackage(), context->GetPackageId())
           .Build();
 
   // Add regular entries.
@@ -311,15 +306,20 @@
     const ResourceId resid(context->GetPackageId(), 0x02, static_cast<uint16_t>(i));
     const auto value =
         util::make_unique<BinaryPrimitive>(Res_value::TYPE_INT_DEC, static_cast<uint32_t>(i));
-    CHECK(table->AddResourceWithId(name, resid, ConfigDescription::DefaultConfig(), "",
-                                   std::unique_ptr<Value>(value->Clone(nullptr)),
-                                   context->GetDiagnostics()));
+    CHECK(table->AddResource(NewResourceBuilder(name)
+                                 .SetId(resid)
+                                 .SetValue(std::unique_ptr<Value>(value->Clone(nullptr)))
+                                 .Build(),
+                             context->GetDiagnostics()));
 
     // Every few entries, write out a sparse_config value. This will give us the desired load.
     if (i % stride == 0) {
-      CHECK(table->AddResourceWithId(name, resid, sparse_config, "",
-                                     std::unique_ptr<Value>(value->Clone(nullptr)),
-                                     context->GetDiagnostics()));
+      CHECK(table->AddResource(
+          NewResourceBuilder(name)
+              .SetId(resid)
+              .SetValue(std::unique_ptr<Value>(value->Clone(nullptr)), sparse_config)
+              .Build(),
+          context->GetDiagnostics()));
     }
   }
   return table;
@@ -417,7 +417,6 @@
       test::ContextBuilder().SetCompilationPackage("lib").SetPackageId(0x00).Build();
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .SetPackageId("lib", 0x00)
           .AddValue("lib:id/foo", ResourceId(0x00010000), util::make_unique<Id>())
           .Build();
   ResourceTable result;
@@ -426,7 +425,7 @@
   Maybe<ResourceTable::SearchResult> search_result =
       result.FindResource(test::ParseNameOrDie("lib:id/foo"));
   ASSERT_TRUE(search_result);
-  EXPECT_EQ(0x00u, search_result.value().package->id.value());
+  EXPECT_EQ(0x00u, search_result.value().entry->id.value().package_id());
 
   auto iter = result.included_packages_.find(0x00);
   ASSERT_NE(result.included_packages_.end(), iter);
@@ -438,7 +437,6 @@
       test::ContextBuilder().SetCompilationPackage("lib").SetPackageId(0x00).Build();
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .SetPackageId("lib", 0x00)
           .AddValue("lib:style/Theme",
                     ResourceId(0x00030001),
                     test::StyleBuilder()
@@ -458,9 +456,7 @@
   Maybe<ResourceTable::SearchResult> search_result =
       result.FindResource(test::ParseNameOrDie("lib:style/Theme"));
   ASSERT_TRUE(search_result);
-  EXPECT_EQ(0x00u, search_result.value().package->id.value());
-  EXPECT_EQ(0x03u, search_result.value().type->id.value());
-  EXPECT_EQ(0x01u, search_result.value().entry->id.value());
+  EXPECT_EQ(0x00030001u, search_result.value().entry->id.value());
   ASSERT_EQ(1u, search_result.value().entry->values.size());
   Value* value = search_result.value().entry->values[0]->value.get();
   Style* style = ValueCast<Style>(value);
@@ -479,7 +475,6 @@
       test::ContextBuilder().SetCompilationPackage("app").SetPackageId(0x7f).Build();
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .SetPackageId("app", 0x7f)
           .AddValue("app:id/foo", ResourceId(0x7f010000),
                     test::BuildReference("lib_one:id/foo", ResourceId(0x02010000)))
           .AddValue("app:id/bar", ResourceId(0x7f010001),
@@ -509,7 +504,6 @@
   std::unique_ptr<IAaptContext> context =
       test::ContextBuilder().SetCompilationPackage("app").SetPackageId(0x80).Build();
   std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder()
-                                             .SetPackageId("app", 0x80)
                                              .AddSimple("app:id/foo", ResourceId(0x80010000))
                                              .Build();
 
@@ -532,7 +526,6 @@
       test::ContextBuilder().SetCompilationPackage(kPackageName).SetPackageId(0x7f).Build();
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .SetPackageId(kPackageName, 0x7f)
           .AddSimple(kPackageName + ":id/foo", ResourceId(0x7f010000))
           .Build();
 
@@ -553,7 +546,6 @@
                                               .Build();
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .SetPackageId(kPackageName, 0x7f)
           .AddSimple(kPackageName + ":id/foo", ResourceId(0x7f010000))
           .Build();
 
@@ -564,7 +556,6 @@
 TEST_F(TableFlattenerTest, ObfuscatingResourceNamesNoNameCollapseExemptionsSucceeds) {
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .SetPackageId("com.app.test", 0x7f)
           .AddSimple("com.app.test:id/one", ResourceId(0x7f020000))
           .AddSimple("com.app.test:id/two", ResourceId(0x7f020001))
           .AddValue("com.app.test:id/three", ResourceId(0x7f020002),
@@ -618,7 +609,6 @@
 TEST_F(TableFlattenerTest, ObfuscatingResourceNamesWithNameCollapseExemptionsSucceeds) {
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .SetPackageId("com.app.test", 0x7f)
           .AddSimple("com.app.test:id/one", ResourceId(0x7f020000))
           .AddSimple("com.app.test:id/two", ResourceId(0x7f020001))
           .AddValue("com.app.test:id/three", ResourceId(0x7f020002),
@@ -680,7 +670,6 @@
   std::string name = "com.app.test:integer/overlayable";
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .SetPackageId("com.app.test", 0x7f)
           .AddSimple(name, ResourceId(0x7f020000))
           .SetOverlayable(name, overlayable_item)
           .Build();
@@ -717,7 +706,6 @@
 
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .SetPackageId("com.app.test", 0x7f)
           .AddSimple(name_zero, ResourceId(0x7f020000))
           .SetOverlayable(name_zero, overlayable_item_zero)
           .AddSimple(name_one, ResourceId(0x7f020001))
@@ -780,7 +768,6 @@
 
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .SetPackageId("com.app.test", 0x7f)
           .AddSimple(name_zero, ResourceId(0x7f020000))
           .SetOverlayable(name_zero, overlayable_item_zero)
           .AddSimple(name_one, ResourceId(0x7f020001))
@@ -842,7 +829,6 @@
 
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .SetPackageId("com.app.test", 0x7f)
           .AddSimple(name_zero, ResourceId(0x7f020000))
           .SetOverlayable(name_zero, overlayable_item_zero)
           .Build();
diff --git a/tools/aapt2/format/proto/ProtoDeserialize.cpp b/tools/aapt2/format/proto/ProtoDeserialize.cpp
index 06ac9e5..498d5a2 100644
--- a/tools/aapt2/format/proto/ProtoDeserialize.cpp
+++ b/tools/aapt2/format/proto/ProtoDeserialize.cpp
@@ -425,15 +425,9 @@
                                      io::IFileCollection* files,
                                      const std::vector<std::shared_ptr<Overlayable>>& overlayables,
                                      ResourceTable* out_table, std::string* out_error) {
-  Maybe<uint8_t> id;
-  if (pb_package.has_package_id()) {
-    id = static_cast<uint8_t>(pb_package.package_id().id());
-  }
-
   std::map<ResourceId, ResourceNameRef> id_index;
 
-  ResourceTablePackage* pkg =
-      out_table->CreatePackageAllowingDuplicateNames(pb_package.package_name(), id);
+  ResourceTablePackage* pkg = out_table->FindOrCreatePackage(pb_package.package_name());
   for (const pb::Type& pb_type : pb_package.type()) {
     const ResourceType* res_type = ParseResourceType(pb_type.name());
     if (res_type == nullptr) {
@@ -444,17 +438,15 @@
     }
 
     ResourceTableType* type = pkg->FindOrCreateType(*res_type);
-    if (pb_type.has_type_id()) {
-      type->id = static_cast<uint8_t>(pb_type.type_id().id());
-    }
 
     for (const pb::Entry& pb_entry : pb_type.entry()) {
-      ResourceEntry* entry;
-      if (pb_entry.has_entry_id()) {
-        auto entry_id = static_cast<uint16_t>(pb_entry.entry_id().id());
-        entry = type->FindOrCreateEntry(pb_entry.name(), entry_id);
-      } else {
-        entry = type->FindOrCreateEntry(pb_entry.name());
+      ResourceEntry* entry = type->CreateEntry(pb_entry.name());
+      const ResourceId resource_id(
+          pb_package.has_package_id() ? static_cast<uint8_t>(pb_package.package_id().id()) : 0u,
+          pb_type.has_type_id() ? static_cast<uint8_t>(pb_type.type_id().id()) : 0u,
+          pb_entry.has_entry_id() ? static_cast<uint16_t>(pb_entry.entry_id().id()) : 0u);
+      if (resource_id.id != 0u) {
+        entry->id = resource_id;
       }
 
       // Deserialize the symbol status (public/private with source and comments).
@@ -464,6 +456,7 @@
           DeserializeSourceFromPb(pb_visibility.source(), src_pool, &entry->visibility.source);
         }
         entry->visibility.comment = pb_visibility.comment();
+        entry->visibility.staged_api = pb_visibility.staged_api();
 
         const Visibility::Level level = DeserializeVisibilityFromPb(pb_visibility.level());
         entry->visibility.level = level;
diff --git a/tools/aapt2/format/proto/ProtoSerialize.cpp b/tools/aapt2/format/proto/ProtoSerialize.cpp
index 98c5175..f13f82d 100644
--- a/tools/aapt2/format/proto/ProtoSerialize.cpp
+++ b/tools/aapt2/format/proto/ProtoSerialize.cpp
@@ -345,28 +345,29 @@
   pb_fingerprint->set_version(util::GetToolFingerprint());
 
   std::vector<Overlayable*> overlayables;
-  for (const std::unique_ptr<ResourceTablePackage>& package : table.packages) {
+  auto table_view = table.GetPartitionedView();
+  for (const auto& package : table_view.packages) {
     pb::Package* pb_package = out_table->add_package();
-    if (package->id) {
-      pb_package->mutable_package_id()->set_id(package->id.value());
+    if (package.id) {
+      pb_package->mutable_package_id()->set_id(package.id.value());
     }
-    pb_package->set_package_name(package->name);
+    pb_package->set_package_name(package.name);
 
-    for (const std::unique_ptr<ResourceTableType>& type : package->types) {
+    for (const auto& type : package.types) {
       pb::Type* pb_type = pb_package->add_type();
-      if (type->id) {
-        pb_type->mutable_type_id()->set_id(type->id.value());
+      if (type.id) {
+        pb_type->mutable_type_id()->set_id(type.id.value());
       }
-      pb_type->set_name(to_string(type->type).to_string());
+      pb_type->set_name(to_string(type.type).to_string());
 
       // hardcoded string uses characters which make it an invalid resource name
       static const char* obfuscated_resource_name = "0_resource_name_obfuscated";
-      for (const std::unique_ptr<ResourceEntry>& entry : type->entries) {
+      for (const auto& entry : type.entries) {
         pb::Entry* pb_entry = pb_type->add_entry();
         if (entry->id) {
-          pb_entry->mutable_entry_id()->set_id(entry->id.value());
+          pb_entry->mutable_entry_id()->set_id(entry->id.value().entry_id());
         }
-        ResourceName resource_name({}, type->type, entry->name);
+        ResourceName resource_name({}, type.type, entry->name);
         if (options.collapse_key_stringpool &&
             options.name_collapse_exemptions.find(resource_name) ==
             options.name_collapse_exemptions.end()) {
@@ -377,6 +378,7 @@
 
         // Write the Visibility struct.
         pb::Visibility* pb_visibility = pb_entry->mutable_visibility();
+        pb_visibility->set_staged_api(entry->visibility.staged_api);
         pb_visibility->set_level(SerializeVisibilityToPb(entry->visibility.level));
         if (source_pool != nullptr) {
           SerializeSourceToPb(entry->visibility.source, source_pool.get(),
diff --git a/tools/aapt2/format/proto/ProtoSerialize_test.cpp b/tools/aapt2/format/proto/ProtoSerialize_test.cpp
index fe4c8aa..591ba149 100644
--- a/tools/aapt2/format/proto/ProtoSerialize_test.cpp
+++ b/tools/aapt2/format/proto/ProtoSerialize_test.cpp
@@ -40,18 +40,67 @@
   MOCK_METHOD0(GetDirSeparator, char());
 };
 
-ResourceEntry* GetEntry(ResourceTable* table, const ResourceNameRef& res_name,
-                   uint32_t id) {
-  ResourceTablePackage* package = table->FindPackage(res_name.package);
-  ResourceTableType* type = package->FindType(res_name.type);
-  return  type->FindEntry(res_name.entry, id);
+ResourceEntry* GetEntry(ResourceTable* table, const ResourceNameRef& res_name) {
+  auto result = table->FindResource(res_name);
+  return (result) ? result.value().entry : nullptr;
+}
+
+ResourceEntry* GetEntry(ResourceTable* table, const ResourceNameRef& res_name, ResourceId id) {
+  auto result = table->FindResource(res_name, id);
+  return (result) ? result.value().entry : nullptr;
+}
+
+TEST(ProtoSerializeTest, SerializeVisibility) {
+  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
+  std::unique_ptr<ResourceTable> table =
+      test::ResourceTableBuilder()
+          .Add(NewResourceBuilder("com.app.a:bool/foo")
+                   .SetVisibility({Visibility::Level::kUndefined})
+                   .Build())
+          .Add(NewResourceBuilder("com.app.a:bool/bar")
+                   .SetVisibility({Visibility::Level::kPrivate})
+                   .Build())
+          .Add(NewResourceBuilder("com.app.a:bool/baz")
+                   .SetVisibility({Visibility::Level::kPublic})
+                   .Build())
+          .Add(NewResourceBuilder("com.app.a:bool/fiz")
+                   .SetVisibility({.level = Visibility::Level::kPublic, .staged_api = true})
+                   .Build())
+          .Build();
+
+  ResourceTable new_table;
+  pb::ResourceTable pb_table;
+  MockFileCollection files;
+  std::string error;
+  SerializeTableToPb(*table, &pb_table, context->GetDiagnostics());
+  ASSERT_TRUE(DeserializeTableFromPb(pb_table, &files, &new_table, &error));
+  EXPECT_THAT(error, IsEmpty());
+
+  auto search_result = new_table.FindResource(test::ParseNameOrDie("com.app.a:bool/foo"));
+  ASSERT_TRUE(search_result);
+  EXPECT_THAT(search_result.value().entry->visibility.level, Eq(Visibility::Level::kUndefined));
+  EXPECT_FALSE(search_result.value().entry->visibility.staged_api);
+
+  search_result = new_table.FindResource(test::ParseNameOrDie("com.app.a:bool/bar"));
+  ASSERT_TRUE(search_result);
+  EXPECT_THAT(search_result.value().entry->visibility.level, Eq(Visibility::Level::kPrivate));
+  EXPECT_FALSE(search_result.value().entry->visibility.staged_api);
+
+  search_result = new_table.FindResource(test::ParseNameOrDie("com.app.a:bool/baz"));
+  ASSERT_TRUE(search_result);
+  EXPECT_THAT(search_result.value().entry->visibility.level, Eq(Visibility::Level::kPublic));
+  EXPECT_FALSE(search_result.value().entry->visibility.staged_api);
+
+  search_result = new_table.FindResource(test::ParseNameOrDie("com.app.a:bool/fiz"));
+  ASSERT_TRUE(search_result);
+  EXPECT_THAT(search_result.value().entry->visibility.level, Eq(Visibility::Level::kPublic));
+  EXPECT_TRUE(search_result.value().entry->visibility.staged_api);
 }
 
 TEST(ProtoSerializeTest, SerializeSinglePackage) {
   std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .SetPackageId("com.app.a", 0x7f)
           .AddFileReference("com.app.a:layout/main", ResourceId(0x7f020000), "res/layout/main.xml")
           .AddReference("com.app.a:layout/other", ResourceId(0x7f020001), "com.app.a:layout/main")
           .AddString("com.app.a:string/text", {}, "hi")
@@ -60,11 +109,11 @@
                           true /*allow_new*/)
           .Build();
 
-  Visibility public_symbol;
-  public_symbol.level = Visibility::Level::kPublic;
-  ASSERT_TRUE(table->SetVisibilityWithId(test::ParseNameOrDie("com.app.a:layout/main"),
-                                         public_symbol, ResourceId(0x7f020000),
-                                         context->GetDiagnostics()));
+  ASSERT_TRUE(table->AddResource(NewResourceBuilder(test::ParseNameOrDie("com.app.a:layout/main"))
+                                     .SetId(0x7f020000)
+                                     .SetVisibility({Visibility::Level::kPublic})
+                                     .Build(),
+                                 context->GetDiagnostics()));
 
   Id* id = test::GetValue<Id>(table.get(), "com.app.a:id/foo");
   ASSERT_THAT(id, NotNull());
@@ -72,25 +121,35 @@
   // Make a plural.
   std::unique_ptr<Plural> plural = util::make_unique<Plural>();
   plural->values[Plural::One] = util::make_unique<String>(table->string_pool.MakeRef("one"));
-  ASSERT_TRUE(table->AddResource(test::ParseNameOrDie("com.app.a:plurals/hey"), ConfigDescription{},
-                                 {}, std::move(plural), context->GetDiagnostics()));
+  ASSERT_TRUE(table->AddResource(NewResourceBuilder(test::ParseNameOrDie("com.app.a:plurals/hey"))
+                                     .SetValue(std::move(plural))
+                                     .Build(),
+                                 context->GetDiagnostics()));
 
   // Make a styled string.
   StyleString style_string;
   style_string.str = "hello";
   style_string.spans.push_back(Span{"b", 0u, 4u});
-  ASSERT_TRUE(
-      table->AddResource(test::ParseNameOrDie("com.app.a:string/styled"), ConfigDescription{}, {},
-                         util::make_unique<StyledString>(table->string_pool.MakeRef(style_string)),
-                         context->GetDiagnostics()));
+  ASSERT_TRUE(table->AddResource(
+      NewResourceBuilder(test::ParseNameOrDie("com.app.a:string/styled"))
+          .SetValue(util::make_unique<StyledString>(table->string_pool.MakeRef(style_string)))
+          .Build(),
+      context->GetDiagnostics()));
 
   // Make a resource with different products.
-  ASSERT_TRUE(table->AddResource(
-      test::ParseNameOrDie("com.app.a:integer/one"), test::ParseConfigOrDie("land"), {},
-      test::BuildPrimitive(android::Res_value::TYPE_INT_DEC, 123u), context->GetDiagnostics()));
-  ASSERT_TRUE(table->AddResource(
-      test::ParseNameOrDie("com.app.a:integer/one"), test::ParseConfigOrDie("land"), "tablet",
-      test::BuildPrimitive(android::Res_value::TYPE_INT_HEX, 321u), context->GetDiagnostics()));
+  ASSERT_TRUE(
+      table->AddResource(NewResourceBuilder(test::ParseNameOrDie("com.app.a:integer/one"))
+                             .SetValue(test::BuildPrimitive(android::Res_value::TYPE_INT_DEC, 123u),
+                                       test::ParseConfigOrDie("land"))
+                             .Build(),
+                         context->GetDiagnostics()));
+
+  ASSERT_TRUE(
+      table->AddResource(NewResourceBuilder(test::ParseNameOrDie("com.app.a:integer/one"))
+                             .SetValue(test::BuildPrimitive(android::Res_value::TYPE_INT_HEX, 321u),
+                                       test::ParseConfigOrDie("land"), "tablet")
+                             .Build(),
+                         context->GetDiagnostics()));
 
   // Make a reference with both resource name and resource ID.
   // The reference should point to a resource outside of this table to test that both name and id
@@ -98,16 +157,20 @@
   Reference expected_ref;
   expected_ref.name = test::ParseNameOrDie("android:layout/main");
   expected_ref.id = ResourceId(0x01020000);
-  ASSERT_TRUE(table->AddResource(
-      test::ParseNameOrDie("com.app.a:layout/abc"), ConfigDescription::DefaultConfig(), {},
-      util::make_unique<Reference>(expected_ref), context->GetDiagnostics()));
+  ASSERT_TRUE(table->AddResource(NewResourceBuilder(test::ParseNameOrDie("com.app.a:layout/abc"))
+                                     .SetValue(util::make_unique<Reference>(expected_ref))
+                                     .Build(),
+                                 context->GetDiagnostics()));
 
   // Make an overlayable resource.
   OverlayableItem overlayable_item(std::make_shared<Overlayable>(
       "OverlayableName", "overlay://theme", Source("res/values/overlayable.xml", 40)));
   overlayable_item.source = Source("res/values/overlayable.xml", 42);
-  ASSERT_TRUE(table->SetOverlayable(test::ParseNameOrDie("com.app.a:integer/overlayable"),
-                                    overlayable_item, test::GetDiagnostics()));
+  ASSERT_TRUE(
+      table->AddResource(NewResourceBuilder(test::ParseNameOrDie("com.app.a:integer/overlayable"))
+                             .SetOverlayable(overlayable_item)
+                             .Build(),
+                         context->GetDiagnostics()));
 
   pb::ResourceTable pb_table;
   SerializeTableToPb(*table, &pb_table, context->GetDiagnostics());
@@ -680,7 +743,6 @@
   std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .SetPackageId("com.app.test", 0x7f)
           .AddSimple("com.app.test:id/one", ResourceId(id_one_id))
           .AddSimple("com.app.test:id/two", ResourceId(id_two_id))
           .AddValue("com.app.test:id/three", ResourceId(id_three_id),
@@ -714,7 +776,7 @@
 
   ResourceName real_id_resource(
       "com.app.test", ResourceType::kId, "one");
-  EXPECT_THAT(GetEntry(&new_table, real_id_resource, id_one_id), IsNull());
+  EXPECT_THAT(GetEntry(&new_table, real_id_resource), IsNull());
 
   ResourceName obfuscated_id_resource(
       "com.app.test", ResourceType::kId, "0_resource_name_obfuscated");
@@ -767,7 +829,6 @@
   std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .SetPackageId("com.app.test", 0x7f)
           .AddSimple("com.app.test:id/one", ResourceId(id_one_id))
           .AddSimple("com.app.test:id/two", ResourceId(id_two_id))
           .AddValue("com.app.test:id/three", ResourceId(id_three_id),
diff --git a/tools/aapt2/java/ClassDefinition.h b/tools/aapt2/java/ClassDefinition.h
index 995495a..d3648c8 100644
--- a/tools/aapt2/java/ClassDefinition.h
+++ b/tools/aapt2/java/ClassDefinition.h
@@ -59,8 +59,9 @@
 template <typename T>
 class PrimitiveMember : public ClassMember {
  public:
-  PrimitiveMember(const android::StringPiece& name, const T& val)
-      : name_(name.to_string()), val_(val) {}
+  PrimitiveMember(const android::StringPiece& name, const T& val, bool staged_api = false)
+      : name_(name.to_string()), val_(val), staged_api_(staged_api) {
+  }
 
   bool empty() const override {
     return false;
@@ -77,7 +78,7 @@
     ClassMember::Print(final, printer, strip_api_annotations);
 
     printer->Print("public static ");
-    if (final) {
+    if (final && !staged_api_) {
       printer->Print("final ");
     }
     printer->Print("int ").Print(name_).Print("=").Print(to_string(val_)).Print(";");
@@ -88,14 +89,16 @@
 
   std::string name_;
   T val_;
+  bool staged_api_;
 };
 
 // Specialization for strings so they get the right type and are quoted with "".
 template <>
 class PrimitiveMember<std::string> : public ClassMember {
  public:
-  PrimitiveMember(const android::StringPiece& name, const std::string& val)
-      : name_(name.to_string()), val_(val) {}
+  PrimitiveMember(const android::StringPiece& name, const std::string& val, bool staged_api = false)
+      : name_(name.to_string()), val_(val) {
+  }
 
   bool empty() const override {
     return false;
diff --git a/tools/aapt2/java/JavaClassGenerator.cpp b/tools/aapt2/java/JavaClassGenerator.cpp
index 59dd481..e1e2e01 100644
--- a/tools/aapt2/java/JavaClassGenerator.cpp
+++ b/tools/aapt2/java/JavaClassGenerator.cpp
@@ -460,7 +460,8 @@
 
   const std::string field_name = TransformToFieldName(name.entry);
   if (out_class_def != nullptr) {
-    auto resource_member = util::make_unique<ResourceMember>(field_name, real_id);
+    auto resource_member =
+        util::make_unique<ResourceMember>(field_name, real_id, entry.visibility.staged_api);
 
     // Build the comments and annotations for this entry.
     AnnotationProcessor* processor = resource_member->GetCommentBuilder();
@@ -542,8 +543,8 @@
 
     // Create an ID if there is one (static libraries don't need one).
     ResourceId id;
-    if (package.id && type.id && entry->id) {
-      id = ResourceId(package.id.value(), type.id.value(), entry->id.value());
+    if (entry->id) {
+      id = entry->id.value();
     }
 
     // We need to make sure we hide the fact that we are generating kAttrPrivate attributes.
diff --git a/tools/aapt2/java/JavaClassGenerator_test.cpp b/tools/aapt2/java/JavaClassGenerator_test.cpp
index ec5b415..8bb3ee9 100644
--- a/tools/aapt2/java/JavaClassGenerator_test.cpp
+++ b/tools/aapt2/java/JavaClassGenerator_test.cpp
@@ -34,7 +34,6 @@
 TEST(JavaClassGeneratorTest, FailWhenEntryIsJavaKeyword) {
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .SetPackageId("android", 0x01)
           .AddSimple("android:id/class", ResourceId(0x01020000))
           .Build();
 
@@ -54,7 +53,6 @@
 TEST(JavaClassGeneratorTest, TransformInvalidJavaIdentifierCharacter) {
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .SetPackageId("android", 0x01)
           .AddSimple("android:id/hey-man", ResourceId(0x01020000))
           .AddValue("android:attr/cool.attr", ResourceId(0x01010000),
                     test::AttributeBuilder().Build())
@@ -84,7 +82,6 @@
 TEST(JavaClassGeneratorTest, CorrectPackageNameIsUsed) {
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .SetPackageId("android", 0x01)
           .AddSimple("android:id/one", ResourceId(0x01020000))
           .AddSimple("android:id/com.foo$two", ResourceId(0x01020001))
           .Build();
@@ -110,8 +107,6 @@
 TEST(JavaClassGeneratorTest, StyleableAttributesWithDifferentPackageName) {
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .SetPackageId("android", 0x01)
-          .SetPackageId("app", 0x7f)
           .AddValue("app:attr/foo", ResourceId(0x7f010000),
                     test::AttributeBuilder().Build())
           .AddValue("app:attr/bar", ResourceId(0x7f010001),
@@ -159,7 +154,6 @@
 TEST(JavaClassGeneratorTest, AttrPrivateIsWrittenAsAttr) {
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .SetPackageId("android", 0x01)
           .AddSimple("android:attr/two", ResourceId(0x01010001))
           .AddSimple("android:^attr-private/one", ResourceId(0x01010000))
           .Build();
@@ -184,7 +178,6 @@
   StdErrDiagnostics diag;
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .SetPackageId("android", 0x01)
           .AddSimple("android:id/one", ResourceId(0x01020000))
           .AddSimple("android:id/two", ResourceId(0x01020001))
           .AddSimple("android:id/three", ResourceId(0x01020002))
@@ -276,8 +269,6 @@
 TEST(JavaClassGeneratorTest, EmitOtherPackagesAttributesInStyleable) {
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .SetPackageId("android", 0x01)
-          .SetPackageId("com.lib", 0x02)
           .AddValue("android:attr/bar", ResourceId(0x01010000), test::AttributeBuilder().Build())
           .AddValue("com.lib:attr/bar", ResourceId(0x02010000), test::AttributeBuilder().Build())
           .AddValue("android:styleable/foo", ResourceId(0x01030000),
@@ -306,7 +297,6 @@
 TEST(JavaClassGeneratorTest, CommentsForSimpleResourcesArePresent) {
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .SetPackageId("android", 0x01)
           .AddSimple("android:id/foo", ResourceId(0x01010000))
           .Build();
   test::GetValue<Id>(table.get(), "android:id/foo")
@@ -346,7 +336,6 @@
 
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .SetPackageId("android", 0x01)
           .AddValue("android:attr/one", util::make_unique<Attribute>(attr))
           .AddValue("android:styleable/Container",
                     std::unique_ptr<Styleable>(styleable.Clone(nullptr)))
@@ -384,7 +373,6 @@
 
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .SetPackageId("android", 0x01)
           .AddValue("android:attr/one", util::make_unique<Attribute>(attr))
           .AddValue("android:styleable/Container",
                     std::unique_ptr<Styleable>(styleable.Clone(nullptr)))
@@ -415,7 +403,6 @@
 TEST(JavaClassGeneratorTest, StyleableAndIndicesAreColocated) {
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .SetPackageId("android", 0x01)
           .AddValue("android:attr/layout_gravity", util::make_unique<Attribute>())
           .AddValue("android:attr/background", util::make_unique<Attribute>())
           .AddValue("android:styleable/ActionBar",
@@ -467,7 +454,6 @@
 
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .SetPackageId("android", 0x01)
           .AddValue("android:attr/one", util::make_unique<Attribute>(attr))
           .Build();
 
@@ -499,7 +485,6 @@
 TEST(JavaClassGeneratorTest, GenerateOnResourcesLoadedCallbackForSharedLibrary) {
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .SetPackageId("android", 0x00)
           .AddValue("android:attr/foo", ResourceId(0x00010000), util::make_unique<Attribute>())
           .AddValue("android:id/foo", ResourceId(0x00020000), util::make_unique<Id>())
           .AddValue(
@@ -536,7 +521,6 @@
 TEST(JavaClassGeneratorTest, OnlyGenerateRText) {
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .SetPackageId("android", 0x01)
           .AddValue("android:attr/foo", ResourceId(0x01010000), util::make_unique<Attribute>())
           .AddValue("android:styleable/hey.dude", ResourceId(0x01020000),
                     test::StyleableBuilder()
@@ -554,8 +538,6 @@
 TEST(JavaClassGeneratorTest, SortsDynamicAttributesAfterFrameworkAttributes) {
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .SetPackageId("android", 0x01)
-          .SetPackageId("lib", 0x00)
           .AddValue("android:attr/framework_attr", ResourceId(0x01010000),
                     test::AttributeBuilder().Build())
           .AddValue("lib:attr/dynamic_attr", ResourceId(0x00010000),
diff --git a/tools/aapt2/java/ProguardRules_test.cpp b/tools/aapt2/java/ProguardRules_test.cpp
index c7ae0b6..b7dfec3 100644
--- a/tools/aapt2/java/ProguardRules_test.cpp
+++ b/tools/aapt2/java/ProguardRules_test.cpp
@@ -247,8 +247,10 @@
 
   ResourceTable table;
   StdErrDiagnostics errDiagnostics;
-  table.AddResource(bar_layout->file.name, ConfigDescription::DefaultConfig(), "",
-                    util::make_unique<FileReference>(), &errDiagnostics);
+  table.AddResource(NewResourceBuilder(bar_layout->file.name)
+                        .SetValue(util::make_unique<FileReference>())
+                        .Build(),
+                    &errDiagnostics);
 
   std::unique_ptr<IAaptContext> context =
       test::ContextBuilder()
diff --git a/tools/aapt2/link/AutoVersioner_test.cpp b/tools/aapt2/link/AutoVersioner_test.cpp
index 1117472..02fd00b 100644
--- a/tools/aapt2/link/AutoVersioner_test.cpp
+++ b/tools/aapt2/link/AutoVersioner_test.cpp
@@ -54,7 +54,6 @@
 TEST(AutoVersionerTest, VersionStylesForTable) {
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .SetPackageId("app", 0x7f)
           .AddValue(
               "app:style/Foo", test::ParseConfigOrDie("v4"),
               ResourceId(0x7f020000),
diff --git a/tools/aapt2/link/NoDefaultResourceRemover_test.cpp b/tools/aapt2/link/NoDefaultResourceRemover_test.cpp
index d129c9a..3179fef 100644
--- a/tools/aapt2/link/NoDefaultResourceRemover_test.cpp
+++ b/tools/aapt2/link/NoDefaultResourceRemover_test.cpp
@@ -21,10 +21,9 @@
 namespace aapt {
 
 TEST(NoDefaultResourceRemoverTest, RemoveEntryWithNoDefaultAndOnlyLocales) {
-  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
+  std::unique_ptr<IAaptContext> context = test::ContextBuilder().SetPackageId(0x01).Build();
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .SetPackageId("android", 0x01)
           .AddSimple("android:string/foo")
           .AddSimple("android:string/foo", test::ParseConfigOrDie("en-rGB"))
           .AddSimple("android:string/foo", test::ParseConfigOrDie("fr-rFR"))
@@ -47,10 +46,10 @@
 }
 
 TEST(NoDefaultResourceRemoverTest, KeepEntryWithLocalesAndDensities) {
-  std::unique_ptr<IAaptContext> context = test::ContextBuilder().SetMinSdkVersion(26).Build();
+  std::unique_ptr<IAaptContext> context =
+      test::ContextBuilder().SetPackageId(0x01).SetMinSdkVersion(26).Build();
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .SetPackageId("android", 0x01)
           .AddSimple("android:drawable/keep1", test::ParseConfigOrDie("mdpi")) // v4
           .AddSimple("android:drawable/keep1", test::ParseConfigOrDie("en-rGB"))
           .AddSimple("android:drawable/keep1", test::ParseConfigOrDie("fr-rFR"))
@@ -71,10 +70,10 @@
 }
 
 TEST(NoDefaultResourceRemoverTest, RemoveEntryWithLocalesAndDensitiesLowVersion) {
-  std::unique_ptr<IAaptContext> context = test::ContextBuilder().SetMinSdkVersion(3).Build();
+  std::unique_ptr<IAaptContext> context =
+      test::ContextBuilder().SetPackageId(0x01).SetMinSdkVersion(3).Build();
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .SetPackageId("android", 0x01)
           .AddSimple("android:drawable/remove1", test::ParseConfigOrDie("mdpi")) // v4
           .AddSimple("android:drawable/remove1", test::ParseConfigOrDie("en-rGB"))
           .AddSimple("android:drawable/remove1", test::ParseConfigOrDie("fr-rFR"))
@@ -87,10 +86,10 @@
 }
 
 TEST(NoDefaultResourceRemoverTest, KeepEntryWithVersion) {
-  std::unique_ptr<IAaptContext> context = test::ContextBuilder().SetMinSdkVersion(8).Build();
+  std::unique_ptr<IAaptContext> context =
+      test::ContextBuilder().SetPackageId(0x01).SetMinSdkVersion(8).Build();
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .SetPackageId("android", 0x01)
           .AddSimple("android:drawable/keep1", test::ParseConfigOrDie("v8"))
           .AddSimple("android:drawable/keep1", test::ParseConfigOrDie("en-rGB"))
           .AddSimple("android:drawable/keep1", test::ParseConfigOrDie("fr-rFR"))
diff --git a/tools/aapt2/link/ProductFilter_test.cpp b/tools/aapt2/link/ProductFilter_test.cpp
index dd47674..4f78bbc 100644
--- a/tools/aapt2/link/ProductFilter_test.cpp
+++ b/tools/aapt2/link/ProductFilter_test.cpp
@@ -30,21 +30,29 @@
 
   ResourceTable table;
   ASSERT_TRUE(table.AddResource(
-      test::ParseNameOrDie("android:string/one"), land, "",
-      test::ValueBuilder<Id>().SetSource(Source("land/default.xml")).Build(),
-      context->GetDiagnostics()));
-  ASSERT_TRUE(table.AddResource(
-      test::ParseNameOrDie("android:string/one"), land, "tablet",
-      test::ValueBuilder<Id>().SetSource(Source("land/tablet.xml")).Build(),
+      NewResourceBuilder(test::ParseNameOrDie("android:string/one"))
+          .SetValue(test::ValueBuilder<Id>().SetSource(Source("land/default.xml")).Build(), land)
+          .Build(),
       context->GetDiagnostics()));
 
   ASSERT_TRUE(table.AddResource(
-      test::ParseNameOrDie("android:string/one"), port, "",
-      test::ValueBuilder<Id>().SetSource(Source("port/default.xml")).Build(),
+      NewResourceBuilder(test::ParseNameOrDie("android:string/one"))
+          .SetValue(test::ValueBuilder<Id>().SetSource(Source("land/tablet.xml")).Build(), land,
+                    "tablet")
+          .Build(),
       context->GetDiagnostics()));
+
   ASSERT_TRUE(table.AddResource(
-      test::ParseNameOrDie("android:string/one"), port, "tablet",
-      test::ValueBuilder<Id>().SetSource(Source("port/tablet.xml")).Build(),
+      NewResourceBuilder(test::ParseNameOrDie("android:string/one"))
+          .SetValue(test::ValueBuilder<Id>().SetSource(Source("port/default.xml")).Build(), port)
+          .Build(),
+      context->GetDiagnostics()));
+
+  ASSERT_TRUE(table.AddResource(
+      NewResourceBuilder(test::ParseNameOrDie("android:string/one"))
+          .SetValue(test::ValueBuilder<Id>().SetSource(Source("port/tablet.xml")).Build(), port,
+                    "tablet")
+          .Build(),
       context->GetDiagnostics()));
 
   ProductFilter filter({"tablet"});
@@ -65,15 +73,17 @@
 
   ResourceTable table;
   ASSERT_TRUE(table.AddResource(
-      test::ParseNameOrDie("android:string/one"),
-      ConfigDescription::DefaultConfig(), "",
-      test::ValueBuilder<Id>().SetSource(Source("default.xml")).Build(),
+      NewResourceBuilder(test::ParseNameOrDie("android:string/one"))
+          .SetValue(test::ValueBuilder<Id>().SetSource(Source("default.xml")).Build())
+          .Build(),
       context->GetDiagnostics()));
+
   ASSERT_TRUE(table.AddResource(
-      test::ParseNameOrDie("android:string/one"),
-      ConfigDescription::DefaultConfig(), "tablet",
-      test::ValueBuilder<Id>().SetSource(Source("tablet.xml")).Build(),
+      NewResourceBuilder(test::ParseNameOrDie("android:string/one"))
+          .SetValue(test::ValueBuilder<Id>().SetSource(Source("tablet.xml")).Build(), {}, "tablet")
+          .Build(),
       context->GetDiagnostics()));
+  ;
 
   ProductFilter filter(std::unordered_set<std::string>{});
   ASSERT_TRUE(filter.Consume(context.get(), &table));
@@ -91,19 +101,22 @@
 
   ResourceTable table;
   ASSERT_TRUE(table.AddResource(
-      test::ParseNameOrDie("android:string/one"),
-      ConfigDescription::DefaultConfig(), "",
-      test::ValueBuilder<Id>().SetSource(Source("default.xml")).Build(),
+      NewResourceBuilder(test::ParseNameOrDie("android:string/one"))
+          .SetValue(test::ValueBuilder<Id>().SetSource(Source("default.xml")).Build())
+          .Build(),
       context->GetDiagnostics()));
+
   ASSERT_TRUE(table.AddResource(
-      test::ParseNameOrDie("android:string/one"),
-      ConfigDescription::DefaultConfig(), "tablet",
-      test::ValueBuilder<Id>().SetSource(Source("tablet.xml")).Build(),
+      NewResourceBuilder(test::ParseNameOrDie("android:string/one"))
+          .SetValue(test::ValueBuilder<Id>().SetSource(Source("tablet.xml")).Build(), {}, "tablet")
+          .Build(),
       context->GetDiagnostics()));
+
   ASSERT_TRUE(table.AddResource(
-      test::ParseNameOrDie("android:string/one"),
-      ConfigDescription::DefaultConfig(), "no-sdcard",
-      test::ValueBuilder<Id>().SetSource(Source("no-sdcard.xml")).Build(),
+      NewResourceBuilder(test::ParseNameOrDie("android:string/one"))
+          .SetValue(test::ValueBuilder<Id>().SetSource(Source("no-sdcard.xml")).Build(), {},
+                    "no-sdcard")
+          .Build(),
       context->GetDiagnostics()));
 
   ProductFilter filter({"tablet", "no-sdcard"});
@@ -114,15 +127,17 @@
   std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
 
   ResourceTable table;
+  ASSERT_TRUE(
+      table.AddResource(NewResourceBuilder(test::ParseNameOrDie("android:string/one"))
+                            .SetValue(test::ValueBuilder<Id>().SetSource(Source(".xml")).Build())
+                            .Build(),
+                        context->GetDiagnostics()));
+
   ASSERT_TRUE(table.AddResource(
-      test::ParseNameOrDie("android:string/one"),
-      ConfigDescription::DefaultConfig(), "",
-      test::ValueBuilder<Id>().SetSource(Source(".xml")).Build(),
-      context->GetDiagnostics()));
-  ASSERT_TRUE(table.AddResource(
-      test::ParseNameOrDie("android:string/one"),
-      ConfigDescription::DefaultConfig(), "default",
-      test::ValueBuilder<Id>().SetSource(Source("default.xml")).Build(),
+      NewResourceBuilder(test::ParseNameOrDie("android:string/one"))
+          .SetValue(test::ValueBuilder<Id>().SetSource(Source("default.xml")).Build(), {},
+                    "default")
+          .Build(),
       context->GetDiagnostics()));
 
   ProductFilter filter(std::unordered_set<std::string>{});
diff --git a/tools/aapt2/link/ReferenceLinker_test.cpp b/tools/aapt2/link/ReferenceLinker_test.cpp
index a31ce94..228c5bd74 100644
--- a/tools/aapt2/link/ReferenceLinker_test.cpp
+++ b/tools/aapt2/link/ReferenceLinker_test.cpp
@@ -28,7 +28,6 @@
 TEST(ReferenceLinkerTest, LinkSimpleReferences) {
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .SetPackageId("com.app.test", 0x7f)
           .AddReference("com.app.test:string/foo", ResourceId(0x7f020000),
                         "com.app.test:string/bar")
 
@@ -75,7 +74,6 @@
 TEST(ReferenceLinkerTest, LinkStyleAttributes) {
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .SetPackageId("com.app.test", 0x7f)
           .AddValue("com.app.test:style/Theme",
                     test::StyleBuilder()
                         .SetParent("android:style/Theme.Material")
@@ -155,7 +153,6 @@
 
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .SetPackageId("com.app.test", 0x7f)
           .AddValue("com.app.test:style/Theme", ResourceId(0x7f020000),
                     test::StyleBuilder()
                         .AddItem("com.android.support:attr/foo",
@@ -176,7 +173,6 @@
 TEST(ReferenceLinkerTest, FailToLinkPrivateSymbols) {
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .SetPackageId("com.app.test", 0x7f)
           .AddReference("com.app.test:string/foo", ResourceId(0x7f020000),
                         "android:string/hidden")
           .Build();
@@ -201,7 +197,6 @@
 TEST(ReferenceLinkerTest, FailToLinkPrivateMangledSymbols) {
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .SetPackageId("com.app.test", 0x7f)
           .AddReference("com.app.test:string/foo", ResourceId(0x7f020000),
                         "com.app.lib:string/hidden")
           .Build();
@@ -229,7 +224,6 @@
 TEST(ReferenceLinkerTest, FailToLinkPrivateStyleAttributes) {
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .SetPackageId("com.app.test", 0x7f)
           .AddValue("com.app.test:style/Theme",
                     test::StyleBuilder()
                         .AddItem("android:attr/hidden",
diff --git a/tools/aapt2/link/TableMerger.cpp b/tools/aapt2/link/TableMerger.cpp
index ad56092..4ef2882 100644
--- a/tools/aapt2/link/TableMerger.cpp
+++ b/tools/aapt2/link/TableMerger.cpp
@@ -33,8 +33,7 @@
                          const TableMergerOptions& options)
     : context_(context), main_table_(out_table), options_(options) {
   // Create the desired package that all tables will be merged into.
-  main_package_ =
-      main_table_->CreatePackage(context_->GetCompilationPackage(), context_->GetPackageId());
+  main_package_ = main_table_->FindOrCreatePackage(context_->GetCompilationPackage());
   CHECK(main_package_ != nullptr) << "package name or ID already taken";
 }
 
@@ -85,20 +84,9 @@
 
 static bool MergeType(IAaptContext* context, const Source& src, ResourceTableType* dst_type,
                       ResourceTableType* src_type) {
-  if (src_type->visibility_level > dst_type->visibility_level) {
+  if (src_type->visibility_level >= dst_type->visibility_level) {
     // The incoming type's visibility is stronger, so we should override the visibility.
-    if (src_type->visibility_level == Visibility::Level::kPublic) {
-      // Only copy the ID if the source is public, or else the ID is meaningless.
-      dst_type->id = src_type->id;
-    }
     dst_type->visibility_level = src_type->visibility_level;
-  } else if (dst_type->visibility_level == Visibility::Level::kPublic &&
-             src_type->visibility_level == Visibility::Level::kPublic && dst_type->id &&
-             src_type->id && dst_type->id.value() != src_type->id.value()) {
-    // Both types are public and have different IDs.
-    context->GetDiagnostics()->Error(DiagMessage(src) << "cannot merge type '" << src_type->type
-                                                      << "': conflicting public IDs");
-    return false;
   }
   return true;
 }
@@ -347,7 +335,7 @@
   file_ref->type = file_desc.type;
   file_ref->file = file;
 
-  ResourceTablePackage* pkg = table.CreatePackage(file_desc.name.package, 0x0);
+  ResourceTablePackage* pkg = table.FindOrCreatePackage(file_desc.name.package);
   pkg->FindOrCreateType(file_desc.name.type)
       ->FindOrCreateEntry(file_desc.name.entry)
       ->FindOrCreateValue(file_desc.config, {})
diff --git a/tools/aapt2/link/TableMerger_test.cpp b/tools/aapt2/link/TableMerger_test.cpp
index 69cf5ee..4358fb5 100644
--- a/tools/aapt2/link/TableMerger_test.cpp
+++ b/tools/aapt2/link/TableMerger_test.cpp
@@ -55,16 +55,13 @@
 TEST_F(TableMergerTest, SimpleMerge) {
   std::unique_ptr<ResourceTable> table_a =
       test::ResourceTableBuilder()
-          .SetPackageId("com.app.a", 0x7f)
           .AddReference("com.app.a:id/foo", "com.app.a:id/bar")
           .AddReference("com.app.a:id/bar", "com.app.b:id/foo")
-          .AddValue(
-              "com.app.a:styleable/view",
-              test::StyleableBuilder().AddItem("com.app.b:id/foo").Build())
+          .AddValue("com.app.a:styleable/view",
+                    test::StyleableBuilder().AddItem("com.app.b:id/foo").Build())
           .Build();
 
   std::unique_ptr<ResourceTable> table_b = test::ResourceTableBuilder()
-                                               .SetPackageId("com.app.b", 0x7f)
                                                .AddSimple("com.app.b:id/foo")
                                                .Build();
 
@@ -129,12 +126,10 @@
 
   std::unique_ptr<ResourceTable> table_a =
       test::ResourceTableBuilder()
-          .SetPackageId("com.app.a", 0x7f)
           .AddFileReference("com.app.a:xml/file", "res/xml/file.xml", &file_a)
           .Build();
   std::unique_ptr<ResourceTable> table_b =
       test::ResourceTableBuilder()
-          .SetPackageId("com.app.b", 0x7f)
           .AddFileReference("com.app.b:xml/file", "res/xml/file.xml", &file_b)
           .Build();
 
@@ -158,12 +153,10 @@
 TEST_F(TableMergerTest, OverrideResourceWithOverlay) {
   std::unique_ptr<ResourceTable> base =
       test::ResourceTableBuilder()
-          .SetPackageId("", 0x00)
           .AddValue("bool/foo", ResourceUtils::TryParseBool("true"))
           .Build();
   std::unique_ptr<ResourceTable> overlay =
       test::ResourceTableBuilder()
-          .SetPackageId("", 0x00)
           .AddValue("bool/foo", ResourceUtils::TryParseBool("false"))
           .Build();
 
@@ -194,14 +187,12 @@
 
   std::unique_ptr<ResourceTable> base =
       test::ResourceTableBuilder()
-          .SetPackageId("", 0x00)
           .AddValue("bool/foo", std::move(foo_original))
           .AddValue("bool/bar", std::move(bar_original))
           .Build();
 
   std::unique_ptr<ResourceTable> overlay =
       test::ResourceTableBuilder()
-          .SetPackageId("", 0x00)
           .AddValue("bool/foo", std::move(foo_overlay))
           .AddValue("bool/bar", std::move(bar_overlay))
           .AddValue("bool/baz", std::move(baz_overlay))
@@ -226,12 +217,10 @@
 TEST_F(TableMergerTest, OverrideSameResourceIdsWithOverlay) {
   std::unique_ptr<ResourceTable> base =
       test::ResourceTableBuilder()
-          .SetPackageId("", 0x7f)
           .SetSymbolState("bool/foo", ResourceId(0x7f, 0x01, 0x0001), Visibility::Level::kPublic)
           .Build();
   std::unique_ptr<ResourceTable> overlay =
       test::ResourceTableBuilder()
-          .SetPackageId("", 0x7f)
           .SetSymbolState("bool/foo", ResourceId(0x7f, 0x01, 0x0001), Visibility::Level::kPublic)
           .Build();
 
@@ -247,12 +236,10 @@
 TEST_F(TableMergerTest, FailToOverrideConflictingTypeIdsWithOverlay) {
   std::unique_ptr<ResourceTable> base =
       test::ResourceTableBuilder()
-          .SetPackageId("", 0x7f)
           .SetSymbolState("bool/foo", ResourceId(0x7f, 0x01, 0x0001), Visibility::Level::kPublic)
           .Build();
   std::unique_ptr<ResourceTable> overlay =
       test::ResourceTableBuilder()
-          .SetPackageId("", 0x7f)
           .SetSymbolState("bool/foo", ResourceId(0x7f, 0x02, 0x0001), Visibility::Level::kPublic)
           .Build();
 
@@ -268,12 +255,10 @@
 TEST_F(TableMergerTest, FailToOverrideConflictingEntryIdsWithOverlay) {
   std::unique_ptr<ResourceTable> base =
       test::ResourceTableBuilder()
-          .SetPackageId("", 0x7f)
           .SetSymbolState("bool/foo", ResourceId(0x7f, 0x01, 0x0001), Visibility::Level::kPublic)
           .Build();
   std::unique_ptr<ResourceTable> overlay =
       test::ResourceTableBuilder()
-          .SetPackageId("", 0x7f)
           .SetSymbolState("bool/foo", ResourceId(0x7f, 0x01, 0x0002), Visibility::Level::kPublic)
           .Build();
 
@@ -289,12 +274,10 @@
 TEST_F(TableMergerTest, FailConflictingVisibility) {
   std::unique_ptr<ResourceTable> base =
       test::ResourceTableBuilder()
-          .SetPackageId("", 0x7f)
           .SetSymbolState("bool/foo", ResourceId(0x7f, 0x01, 0x0001), Visibility::Level::kPublic)
           .Build();
   std::unique_ptr<ResourceTable> overlay =
       test::ResourceTableBuilder()
-          .SetPackageId("", 0x7f)
           .SetSymbolState("bool/foo", ResourceId(0x7f, 0x01, 0x0001), Visibility::Level::kPrivate)
           .Build();
 
@@ -318,11 +301,9 @@
 }
 
 TEST_F(TableMergerTest, MergeAddResourceFromOverlay) {
-  std::unique_ptr<ResourceTable> table_a =
-      test::ResourceTableBuilder().SetPackageId("", 0x7f).Build();
+  std::unique_ptr<ResourceTable> table_a = test::ResourceTableBuilder().Build();
   std::unique_ptr<ResourceTable> table_b =
       test::ResourceTableBuilder()
-          .SetPackageId("", 0x7f)
           .SetSymbolState("bool/foo", {}, Visibility::Level::kUndefined, true /*allow new overlay*/)
           .AddValue("bool/foo", ResourceUtils::TryParseBool("true"))
           .Build();
@@ -337,11 +318,9 @@
 }
 
 TEST_F(TableMergerTest, MergeAddResourceFromOverlayWithAutoAddOverlay) {
-  std::unique_ptr<ResourceTable> table_a =
-      test::ResourceTableBuilder().SetPackageId("", 0x7f).Build();
+  std::unique_ptr<ResourceTable> table_a = test::ResourceTableBuilder().Build();
   std::unique_ptr<ResourceTable> table_b =
       test::ResourceTableBuilder()
-          .SetPackageId("", 0x7f)
           .AddValue("bool/foo", ResourceUtils::TryParseBool("true"))
           .Build();
 
@@ -355,11 +334,9 @@
 }
 
 TEST_F(TableMergerTest, FailToMergeNewResourceWithoutAutoAddOverlay) {
-  std::unique_ptr<ResourceTable> table_a =
-      test::ResourceTableBuilder().SetPackageId("", 0x7f).Build();
+  std::unique_ptr<ResourceTable> table_a = test::ResourceTableBuilder().Build();
   std::unique_ptr<ResourceTable> table_b =
       test::ResourceTableBuilder()
-          .SetPackageId("", 0x7f)
           .AddValue("bool/foo", ResourceUtils::TryParseBool("true"))
           .Build();
 
@@ -375,7 +352,6 @@
 TEST_F(TableMergerTest, OverlaidStyleablesAndStylesShouldBeMerged) {
   std::unique_ptr<ResourceTable> table_a =
       test::ResourceTableBuilder()
-          .SetPackageId("com.app.a", 0x7f)
           .AddValue("com.app.a:styleable/Foo",
                     test::StyleableBuilder()
                         .AddItem("com.app.a:attr/bar")
@@ -391,7 +367,6 @@
 
   std::unique_ptr<ResourceTable> table_b =
       test::ResourceTableBuilder()
-          .SetPackageId("com.app.a", 0x7f)
           .AddValue("com.app.a:styleable/Foo", test::StyleableBuilder()
                                                    .AddItem("com.app.a:attr/bat")
                                                    .AddItem("com.app.a:attr/foo")
@@ -441,7 +416,6 @@
 TEST_F(TableMergerTest, OverrideStyleInsteadOfOverlaying) {
   std::unique_ptr<ResourceTable> table_a =
       test::ResourceTableBuilder()
-          .SetPackageId("com.app.a", 0x7f)
           .AddValue(
               "com.app.a:styleable/MyWidget",
               test::StyleableBuilder().AddItem("com.app.a:attr/foo", ResourceId(0x1234)).Build())
@@ -452,7 +426,6 @@
           .Build();
   std::unique_ptr<ResourceTable> table_b =
       test::ResourceTableBuilder()
-          .SetPackageId("com.app.a", 0x7f)
           .AddValue(
               "com.app.a:styleable/MyWidget",
               test::StyleableBuilder().AddItem("com.app.a:attr/bar", ResourceId(0x5678)).Build())
@@ -494,13 +467,11 @@
 
   std::unique_ptr<ResourceTable> table_a =
       test::ResourceTableBuilder()
-          .SetPackageId("com.app.a", 0x7f)
           .SetOverlayable("bool/foo", overlayable_item)
           .Build();
 
   std::unique_ptr<ResourceTable> table_b =
       test::ResourceTableBuilder()
-          .SetPackageId("com.app.a", 0x7f)
           .AddSimple("bool/foo")
           .Build();
 
@@ -527,7 +498,6 @@
                                                   "overlay://customization");
   std::unique_ptr<ResourceTable> table_a =
       test::ResourceTableBuilder()
-          .SetPackageId("com.app.a", 0x7f)
           .AddSimple("bool/foo")
           .Build();
 
@@ -536,7 +506,6 @@
   overlayable_item.policies |= PolicyFlags::SYSTEM_PARTITION;
   std::unique_ptr<ResourceTable> table_b =
       test::ResourceTableBuilder()
-          .SetPackageId("com.app.a", 0x7f)
           .SetOverlayable("bool/foo", overlayable_item)
           .Build();
 
@@ -565,7 +534,6 @@
   overlayable_item_first.policies |= PolicyFlags::PRODUCT_PARTITION;
   std::unique_ptr<ResourceTable> table_a =
       test::ResourceTableBuilder()
-          .SetPackageId("com.app.a", 0x7f)
           .SetOverlayable("bool/foo", overlayable_item_first)
           .Build();
 
@@ -575,7 +543,6 @@
   overlayable_item_second.policies |= PolicyFlags::PRODUCT_PARTITION;
   std::unique_ptr<ResourceTable> table_b =
       test::ResourceTableBuilder()
-          .SetPackageId("com.app.a", 0x7f)
           .SetOverlayable("bool/foo", overlayable_item_second)
           .Build();
 
@@ -594,7 +561,6 @@
   overlayable_item_first.policies |= PolicyFlags::PRODUCT_PARTITION;
   std::unique_ptr<ResourceTable> table_a =
       test::ResourceTableBuilder()
-          .SetPackageId("com.app.a", 0x7f)
           .SetOverlayable("bool/foo", overlayable_item_first)
           .Build();
 
@@ -604,7 +570,6 @@
   overlayable_item_second.policies |= PolicyFlags::PRODUCT_PARTITION;
   std::unique_ptr<ResourceTable> table_b =
       test::ResourceTableBuilder()
-          .SetPackageId("com.app.a", 0x7f)
           .SetOverlayable("bool/foo", overlayable_item_second)
           .Build();
 
@@ -623,7 +588,6 @@
   overlayable_item_first.policies |= PolicyFlags::PRODUCT_PARTITION;
   std::unique_ptr<ResourceTable> table_a =
       test::ResourceTableBuilder()
-          .SetPackageId("com.app.a", 0x7f)
           .SetOverlayable("bool/foo", overlayable_item_first)
           .Build();
 
@@ -633,7 +597,6 @@
   overlayable_item_second.policies |= PolicyFlags::SIGNATURE;
   std::unique_ptr<ResourceTable> table_b =
       test::ResourceTableBuilder()
-          .SetPackageId("com.app.a", 0x7f)
           .SetOverlayable("bool/foo", overlayable_item_second)
           .Build();
 
@@ -653,7 +616,6 @@
   overlayable_item_first.policies |= PolicyFlags::PRODUCT_PARTITION;
   std::unique_ptr<ResourceTable> table_a =
       test::ResourceTableBuilder()
-          .SetPackageId("com.app.a", 0x7f)
           .SetOverlayable("bool/foo", overlayable_item_first)
           .Build();
 
@@ -661,7 +623,6 @@
   overlayable_item_second.policies |= PolicyFlags::PRODUCT_PARTITION;
   std::unique_ptr<ResourceTable> table_b =
       test::ResourceTableBuilder()
-          .SetPackageId("com.app.a", 0x7f)
           .SetOverlayable("bool/foo", overlayable_item_second)
           .Build();
 
diff --git a/tools/aapt2/process/SymbolTable.cpp b/tools/aapt2/process/SymbolTable.cpp
index 98ee63d..d385267 100644
--- a/tools/aapt2/process/SymbolTable.cpp
+++ b/tools/aapt2/process/SymbolTable.cpp
@@ -197,9 +197,10 @@
   std::unique_ptr<SymbolTable::Symbol> symbol = util::make_unique<SymbolTable::Symbol>();
   symbol->is_public = (sr.entry->visibility.level == Visibility::Level::kPublic);
 
-  if (sr.package->id && sr.type->id && sr.entry->id) {
-    symbol->id = ResourceId(sr.package->id.value(), sr.type->id.value(), sr.entry->id.value());
-    symbol->is_dynamic = (sr.package->id.value() == 0);
+  if (sr.entry->id) {
+    symbol->id = sr.entry->id.value();
+    symbol->is_dynamic =
+        (sr.entry->id.value().package_id() == 0) || sr.entry->visibility.staged_api;
   }
 
   if (name.type == ResourceType::kAttr || name.type == ResourceType::kAttrPrivate) {
@@ -374,7 +375,8 @@
 
   if (s) {
     s->is_public = (type_spec_flags & android::ResTable_typeSpec::SPEC_PUBLIC) != 0;
-    s->is_dynamic = IsPackageDynamic(ResourceId(res_id).package_id(), real_name.package);
+    s->is_dynamic = IsPackageDynamic(ResourceId(res_id).package_id(), real_name.package) ||
+                    (type_spec_flags & android::ResTable_typeSpec::SPEC_STAGED_API) != 0;
     return s;
   }
   return {};
@@ -421,7 +423,8 @@
 
   if (s) {
     s->is_public = (*flags & android::ResTable_typeSpec::SPEC_PUBLIC) != 0;
-    s->is_dynamic = IsPackageDynamic(ResourceId(id).package_id(), name.package);
+    s->is_dynamic = IsPackageDynamic(ResourceId(id).package_id(), name.package) ||
+                    (*flags & android::ResTable_typeSpec::SPEC_STAGED_API) != 0;
     return s;
   }
   return {};
diff --git a/tools/aapt2/split/TableSplitter.cpp b/tools/aapt2/split/TableSplitter.cpp
index 6a67271..2f319b1 100644
--- a/tools/aapt2/split/TableSplitter.cpp
+++ b/tools/aapt2/split/TableSplitter.cpp
@@ -185,7 +185,7 @@
     // Initialize all packages for splits.
     for (size_t idx = 0; idx < split_count; idx++) {
       ResourceTable* split_table = splits_[idx].get();
-      split_table->CreatePackage(pkg->name, pkg->id);
+      split_table->FindOrCreatePackage(pkg->name);
     }
 
     for (auto& type : pkg->types) {
@@ -241,10 +241,7 @@
             // not have actual values for each type/entry.
             ResourceTablePackage* split_pkg = split_table->FindPackage(pkg->name);
             ResourceTableType* split_type = split_pkg->FindOrCreateType(type->type);
-            if (!split_type->id) {
-              split_type->id = type->id;
-              split_type->visibility_level = type->visibility_level;
-            }
+            split_type->visibility_level = type->visibility_level;
 
             ResourceEntry* split_entry = split_type->FindOrCreateEntry(entry->name);
             if (!split_entry->id) {
diff --git a/tools/aapt2/split/TableSplitter_test.cpp b/tools/aapt2/split/TableSplitter_test.cpp
index cdf0738..c6a2ff3 100644
--- a/tools/aapt2/split/TableSplitter_test.cpp
+++ b/tools/aapt2/split/TableSplitter_test.cpp
@@ -193,15 +193,23 @@
   ResourceTable table;
 
   const ResourceName foo = test::ParseNameOrDie("android:string/foo");
-  ASSERT_TRUE(table.AddResource(foo, test::ParseConfigOrDie("land-hdpi"), {},
-                                util::make_unique<Id>(),
-                                test::GetDiagnostics()));
-  ASSERT_TRUE(table.AddResource(foo, test::ParseConfigOrDie("land-xhdpi"), {},
-                                util::make_unique<Id>(),
-                                test::GetDiagnostics()));
-  ASSERT_TRUE(table.AddResource(foo, test::ParseConfigOrDie("land-xxhdpi"), {},
-                                util::make_unique<Id>(),
-                                test::GetDiagnostics()));
+  ASSERT_TRUE(
+      table.AddResource(NewResourceBuilder(foo)
+                            .SetValue(util::make_unique<Id>(), test::ParseConfigOrDie("land-hdpi"))
+                            .Build(),
+                        test::GetDiagnostics()));
+
+  ASSERT_TRUE(
+      table.AddResource(NewResourceBuilder(foo)
+                            .SetValue(util::make_unique<Id>(), test::ParseConfigOrDie("land-xhdpi"))
+                            .Build(),
+                        test::GetDiagnostics()));
+
+  ASSERT_TRUE(table.AddResource(
+      NewResourceBuilder(foo)
+          .SetValue(util::make_unique<Id>(), test::ParseConfigOrDie("land-xxhdpi"))
+          .Build(),
+      test::GetDiagnostics()));
 
   std::vector<SplitConstraints> constraints;
   constraints.push_back(
diff --git a/tools/aapt2/test/Builders.cpp b/tools/aapt2/test/Builders.cpp
index 9a93f2a..4816596 100644
--- a/tools/aapt2/test/Builders.cpp
+++ b/tools/aapt2/test/Builders.cpp
@@ -34,13 +34,6 @@
 namespace aapt {
 namespace test {
 
-ResourceTableBuilder& ResourceTableBuilder::SetPackageId(const StringPiece& package_name,
-                                                         uint8_t id) {
-  ResourceTablePackage* package = table_->CreatePackage(package_name, id);
-  CHECK(package != nullptr);
-  return *this;
-}
-
 ResourceTableBuilder& ResourceTableBuilder::AddSimple(const StringPiece& name,
                                                       const ResourceId& id) {
   return AddValue(name, id, util::make_unique<Id>());
@@ -118,8 +111,13 @@
                                                      const ResourceId& id,
                                                      std::unique_ptr<Value> value) {
   ResourceName res_name = ParseNameOrDie(name);
-  CHECK(table_->AddResourceWithIdMangled(res_name, id, config, {}, std::move(value),
-                                         GetDiagnostics()));
+  NewResourceBuilder builder(res_name);
+  builder.SetValue(std::move(value), config).SetAllowMangled(true);
+  if (id.id != 0U) {
+    builder.SetId(id);
+  }
+
+  CHECK(table_->AddResource(builder.Build(), GetDiagnostics()));
   return *this;
 }
 
@@ -128,10 +126,13 @@
                                                            Visibility::Level level,
                                                            bool allow_new) {
   ResourceName res_name = ParseNameOrDie(name);
-  Visibility visibility;
-  visibility.level = level;
-  CHECK(table_->SetVisibilityWithIdMangled(res_name, visibility, id, GetDiagnostics()));
-  CHECK(table_->SetAllowNewMangled(res_name, AllowNew{}, GetDiagnostics()));
+  NewResourceBuilder builder(res_name);
+  builder.SetVisibility({level}).SetAllowNew({}).SetAllowMangled(true);
+  if (id.id != 0U) {
+    builder.SetId(id);
+  }
+
+  CHECK(table_->AddResource(builder.Build(), GetDiagnostics()));
   return *this;
 }
 
@@ -139,7 +140,14 @@
                                                            const OverlayableItem& overlayable) {
 
   ResourceName res_name = ParseNameOrDie(name);
-  CHECK(table_->SetOverlayable(res_name, overlayable, GetDiagnostics()));
+  CHECK(table_->AddResource(
+      NewResourceBuilder(res_name).SetOverlayable(overlayable).SetAllowMangled(true).Build(),
+      GetDiagnostics()));
+  return *this;
+}
+
+ResourceTableBuilder& ResourceTableBuilder::Add(NewResource&& res) {
+  CHECK(table_->AddResource(std::move(res), GetDiagnostics()));
   return *this;
 }
 
diff --git a/tools/aapt2/test/Builders.h b/tools/aapt2/test/Builders.h
index c971a1b..3ff955d 100644
--- a/tools/aapt2/test/Builders.h
+++ b/tools/aapt2/test/Builders.h
@@ -39,7 +39,6 @@
  public:
   ResourceTableBuilder() = default;
 
-  ResourceTableBuilder& SetPackageId(const android::StringPiece& package_name, uint8_t id);
   ResourceTableBuilder& AddSimple(const android::StringPiece& name, const ResourceId& id = {});
   ResourceTableBuilder& AddSimple(const android::StringPiece& name,
                                   const android::ConfigDescription& config,
@@ -75,6 +74,7 @@
                                        Visibility::Level level, bool allow_new = false);
   ResourceTableBuilder& SetOverlayable(const android::StringPiece& name,
                                        const OverlayableItem& overlayable);
+  ResourceTableBuilder& Add(NewResource&& res);
 
   StringPool* string_pool();
   std::unique_ptr<ResourceTable> Build();
diff --git a/tools/codegen/src/com/android/codegen/FieldInfo.kt b/tools/codegen/src/com/android/codegen/FieldInfo.kt
index 02ebaef..74392dd 100644
--- a/tools/codegen/src/com/android/codegen/FieldInfo.kt
+++ b/tools/codegen/src/com/android/codegen/FieldInfo.kt
@@ -220,11 +220,12 @@
             isBinder(FieldInnerType!!) -> "BinderList"
             else -> "ParcelableList"
         }
+        isStrongBinder(Type) -> "StrongBinder"
         isIInterface(Type) -> "StrongInterface"
-        isBinder(Type) -> "StrongBinder"
         else -> "TypedObject"
     }.capitalize()
 
+    private fun isStrongBinder(type: String) = type == "Binder" || type == "IBinder"
     private fun isBinder(type: String) = type == "Binder" || type == "IBinder" || isIInterface(type)
     private fun isIInterface(type: String) = type.length >= 2 && type[0] == 'I' && type[1].isUpperCase()
 }
\ No newline at end of file
diff --git a/tools/codegen/src/com/android/codegen/SharedConstants.kt b/tools/codegen/src/com/android/codegen/SharedConstants.kt
index d9ad649..4da4019 100644
--- a/tools/codegen/src/com/android/codegen/SharedConstants.kt
+++ b/tools/codegen/src/com/android/codegen/SharedConstants.kt
@@ -1,7 +1,7 @@
 package com.android.codegen
 
 const val CODEGEN_NAME = "codegen"
-const val CODEGEN_VERSION = "1.0.22"
+const val CODEGEN_VERSION = "1.0.23"
 
 const val CANONICAL_BUILDER_CLASS = "Builder"
 const val BASE_BUILDER_CLASS = "BaseBuilder"
diff --git a/wifi/java/src/android/net/wifi/nl80211/WifiNl80211Manager.java b/wifi/java/src/android/net/wifi/nl80211/WifiNl80211Manager.java
index c64f4bc..da0571ba 100644
--- a/wifi/java/src/android/net/wifi/nl80211/WifiNl80211Manager.java
+++ b/wifi/java/src/android/net/wifi/nl80211/WifiNl80211Manager.java
@@ -101,6 +101,7 @@
 
     // Cached wificond binder handlers.
     private IWificond mWificond;
+    private WificondEventHandler mWificondEventHandler = new WificondEventHandler();
     private HashMap<String, IClientInterface> mClientInterfaces = new HashMap<>();
     private HashMap<String, IApInterface> mApInterfaces = new HashMap<>();
     private HashMap<String, IWifiScannerImpl> mWificondScanners = new HashMap<>();
@@ -114,6 +115,18 @@
     private AtomicBoolean mSendMgmtFrameInProgress = new AtomicBoolean(false);
 
     /**
+     * Interface used to listen country code event
+     */
+    public interface CountryCodeChangeListener {
+        /**
+         * Called when country code changed.
+         *
+         * @param countryCode A new country code which is 2-Character alphanumeric.
+         */
+        void onChanged(@NonNull String countryCode);
+    }
+
+    /**
      * Interface used when waiting for scans to be completed (with results).
      */
     public interface ScanEventCallback {
@@ -147,6 +160,46 @@
         void onPnoRequestFailed();
     }
 
+    /** @hide */
+    @VisibleForTesting
+    public class WificondEventHandler extends IWificondEventCallback.Stub {
+        private Map<CountryCodeChangeListener, Executor> mCountryCodeChangeListenerHolder =
+                new HashMap<>();
+
+        /**
+         * Register CountryCodeChangeListener with pid.
+         *
+         * @param executor The Executor on which to execute the callbacks.
+         * @param listener listener for country code changed events.
+         */
+        public void registerCountryCodeChangeListener(Executor executor,
+                CountryCodeChangeListener listener) {
+            mCountryCodeChangeListenerHolder.put(listener, executor);
+        }
+
+        /**
+         * Unregister CountryCodeChangeListener with pid.
+         *
+         * @param listener listener which registered country code changed events.
+         */
+        public void unregisterCountryCodeChangeListener(CountryCodeChangeListener listener) {
+            mCountryCodeChangeListenerHolder.remove(listener);
+        }
+
+        @Override
+        public void OnRegDomainChanged(String countryCode) {
+            Log.d(TAG, "OnRegDomainChanged " + countryCode);
+            final long token = Binder.clearCallingIdentity();
+            try {
+                mCountryCodeChangeListenerHolder.forEach((listener, executor) -> {
+                    executor.execute(() -> listener.onChanged(countryCode));
+                });
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+    }
+
     private class ScanEventHandler extends IScanEvent.Stub {
         private Executor mExecutor;
         private ScanEventCallback mCallback;
@@ -347,6 +400,12 @@
         mWificond = wificond;
     }
 
+    /** @hide */
+    @VisibleForTesting
+    public WificondEventHandler getWificondEventHandler() {
+        return mWificondEventHandler;
+    }
+
     private class PnoScanEventHandler extends IPnoScanEvent.Stub {
         private Executor mExecutor;
         private ScanEventCallback mCallback;
@@ -574,6 +633,7 @@
         }
         try {
             mWificond.asBinder().linkToDeath(() -> binderDied(), 0);
+            mWificond.registerWificondEventCallback(mWificondEventHandler);
         } catch (RemoteException e) {
             Log.e(TAG, "Failed to register death notification for wificond");
             // The remote has already died.
@@ -1174,6 +1234,34 @@
     }
 
     /**
+     * Register the provided listener for country code event.
+     *
+     * @param executor The Executor on which to execute the callbacks.
+     * @param listener listener for country code changed events.
+     * @return true on success, false on failure.
+     */
+    public boolean registerCountryCodeChangeListener(@NonNull @CallbackExecutor Executor executor,
+            @NonNull CountryCodeChangeListener listener) {
+        if (!retrieveWificondAndRegisterForDeath()) {
+            return false;
+        }
+        Log.d(TAG, "registerCountryCodeEventListener called");
+        mWificondEventHandler.registerCountryCodeChangeListener(executor, listener);
+        return true;
+    }
+
+
+    /**
+     * Unregister CountryCodeChangeListener with pid.
+     *
+     * @param listener listener which registered country code changed events.
+     */
+    public void unregisterCountryCodeChangeListener(@NonNull CountryCodeChangeListener listener) {
+        Log.d(TAG, "unregisterCountryCodeEventListener called");
+        mWificondEventHandler.unregisterCountryCodeChangeListener(listener);
+    }
+
+    /**
      * Register the provided callback handler for SoftAp events. The interface must first be created
      * using {@link #setupInterfaceForSoftApMode(String)}. The callback registration is valid until
      * the interface is deleted using {@link #tearDownSoftApInterface(String)} (no deregistration
diff --git a/wifi/tests/src/android/net/wifi/nl80211/WifiNl80211ManagerTest.java b/wifi/tests/src/android/net/wifi/nl80211/WifiNl80211ManagerTest.java
index 4b03a49..98a0042 100644
--- a/wifi/tests/src/android/net/wifi/nl80211/WifiNl80211ManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/nl80211/WifiNl80211ManagerTest.java
@@ -30,6 +30,7 @@
 import static org.mockito.Mockito.doThrow;
 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.verifyNoMoreInteractions;
@@ -97,14 +98,20 @@
     @Mock
     private WifiNl80211Manager.PnoScanRequestCallback mPnoScanRequestCallback;
     @Mock
+    private WifiNl80211Manager.CountryCodeChangeListener mCountryCodeChangeListener;
+    @Mock
+    private WifiNl80211Manager.CountryCodeChangeListener mCountryCodeChangeListener2;
+    @Mock
     private Context mContext;
     private TestLooper mLooper;
     private TestAlarmManager mTestAlarmManager;
     private AlarmManager mAlarmManager;
     private WifiNl80211Manager mWificondControl;
+    private WifiNl80211Manager.WificondEventHandler mWificondEventHandler;
     private static final String TEST_INTERFACE_NAME = "test_wlan_if";
     private static final String TEST_INTERFACE_NAME1 = "test_wlan_if1";
     private static final String TEST_INVALID_INTERFACE_NAME = "asdf";
+    private static final String TEST_COUNTRY_CODE = "US";
     private static final byte[] TEST_SSID =
             new byte[]{'G', 'o', 'o', 'g', 'l', 'e', 'G', 'u', 'e', 's', 't'};
     private static final byte[] TEST_PSK =
@@ -182,6 +189,7 @@
         when(mClientInterface.getWifiScannerImpl()).thenReturn(mWifiScannerImpl);
         when(mClientInterface.getInterfaceName()).thenReturn(TEST_INTERFACE_NAME);
         mWificondControl = new WifiNl80211Manager(mContext, mWificond);
+        mWificondEventHandler = mWificondControl.getWificondEventHandler();
         assertEquals(true,
                 mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, Runnable::run,
                         mNormalScanCallback, mPnoScanCallback));
@@ -760,6 +768,28 @@
     }
 
     /**
+     * Ensures callback works after register CountryCodeChangeListener.
+     */
+    @Test
+    public void testCountryCodeChangeListenerInvocation() throws Exception {
+        assertTrue(mWificondControl.registerCountryCodeChangeListener(
+                Runnable::run, mCountryCodeChangeListener));
+        assertTrue(mWificondControl.registerCountryCodeChangeListener(
+                Runnable::run, mCountryCodeChangeListener2));
+
+        mWificondEventHandler.OnRegDomainChanged(TEST_COUNTRY_CODE);
+        verify(mCountryCodeChangeListener).onChanged(TEST_COUNTRY_CODE);
+        verify(mCountryCodeChangeListener2).onChanged(TEST_COUNTRY_CODE);
+
+        reset(mCountryCodeChangeListener);
+        reset(mCountryCodeChangeListener2);
+        mWificondControl.unregisterCountryCodeChangeListener(mCountryCodeChangeListener2);
+        mWificondEventHandler.OnRegDomainChanged(TEST_COUNTRY_CODE);
+        verify(mCountryCodeChangeListener).onChanged(TEST_COUNTRY_CODE);
+        verify(mCountryCodeChangeListener2, never()).onChanged(TEST_COUNTRY_CODE);
+    }
+
+    /**
      * Verifies registration and invocation of wificond death handler.
      */
     @Test